recordable 0.3.0 → 0.5.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.
- package/README.md +198 -44
- package/dist/actions.d.ts +8 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +11 -5
- package/dist/actions.js.map +1 -1
- package/dist/audio/track.d.ts +10 -0
- package/dist/audio/track.d.ts.map +1 -1
- package/dist/audio/track.js +19 -0
- package/dist/audio/track.js.map +1 -1
- package/dist/browser/cursor.d.ts +8 -6
- package/dist/browser/cursor.d.ts.map +1 -1
- package/dist/browser/cursor.js +32 -21
- package/dist/browser/cursor.js.map +1 -1
- package/dist/browser/dom.d.ts +33 -13
- package/dist/browser/dom.d.ts.map +1 -1
- package/dist/browser/dom.js +158 -56
- package/dist/browser/dom.js.map +1 -1
- package/dist/browser/page-zoom.d.ts +11 -0
- package/dist/browser/page-zoom.d.ts.map +1 -0
- package/dist/browser/page-zoom.js +37 -0
- package/dist/browser/page-zoom.js.map +1 -0
- package/dist/browser/play-button.d.ts.map +1 -1
- package/dist/browser/play-button.js.map +1 -1
- package/dist/browser/runtime.d.ts +1 -0
- package/dist/browser/runtime.d.ts.map +1 -1
- package/dist/browser/runtime.js +22 -14
- package/dist/browser/runtime.js.map +1 -1
- package/dist/browser/targets.d.ts.map +1 -0
- package/dist/{targets.js → browser/targets.js} +3 -2
- package/dist/browser/targets.js.map +1 -0
- package/dist/compose/boundaries.d.ts +13 -0
- package/dist/compose/boundaries.d.ts.map +1 -0
- package/dist/compose/boundaries.js +49 -0
- package/dist/compose/boundaries.js.map +1 -0
- package/dist/compose/mix.d.ts +3 -2
- package/dist/compose/mix.d.ts.map +1 -1
- package/dist/compose/mix.js +9 -4
- package/dist/compose/mix.js.map +1 -1
- package/dist/compose/recordable.d.ts +28 -3
- package/dist/compose/recordable.d.ts.map +1 -1
- package/dist/compose/recordable.js +75 -18
- package/dist/compose/recordable.js.map +1 -1
- package/dist/compose/session.d.ts +20 -8
- package/dist/compose/session.d.ts.map +1 -1
- package/dist/compose/session.js +120 -38
- package/dist/compose/session.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -3
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/ffmpeg.d.ts +3 -0
- package/dist/ffmpeg.d.ts.map +1 -1
- package/dist/ffmpeg.js +22 -4
- package/dist/ffmpeg.js.map +1 -1
- package/dist/formats/json.d.ts +2 -1
- package/dist/formats/json.d.ts.map +1 -1
- package/dist/formats/json.js.map +1 -1
- package/dist/formats/markdown/method.d.ts.map +1 -1
- package/dist/formats/markdown/method.js +4 -3
- package/dist/formats/markdown/method.js.map +1 -1
- package/dist/fs.d.ts +16 -0
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +33 -4
- package/dist/fs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +3 -1
- package/dist/logger.js.map +1 -1
- package/dist/result.d.ts +30 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +8 -0
- package/dist/result.js.map +1 -0
- package/dist/timing.d.ts +2 -0
- package/dist/timing.d.ts.map +1 -1
- package/dist/timing.js +10 -4
- package/dist/timing.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +11 -10
- package/dist/validate.js.map +1 -1
- package/dist/video/recorder.d.ts +26 -3
- package/dist/video/recorder.d.ts.map +1 -1
- package/dist/video/recorder.js +50 -32
- package/dist/video/recorder.js.map +1 -1
- package/dist/video/stitch.js +3 -17
- package/dist/video/stitch.js.map +1 -1
- package/dist/voiceover/compile.d.ts.map +1 -1
- package/dist/voiceover/compile.js +42 -24
- package/dist/voiceover/compile.js.map +1 -1
- package/dist/voiceover/elevenlabs.d.ts.map +1 -1
- package/dist/voiceover/elevenlabs.js +41 -11
- package/dist/voiceover/elevenlabs.js.map +1 -1
- package/dist/voiceover/mock.d.ts.map +1 -1
- package/dist/voiceover/mock.js +38 -15
- package/dist/voiceover/mock.js.map +1 -1
- package/package.json +20 -6
- package/recordable.schema.json +81 -0
- package/dist/targets.d.ts.map +0 -1
- package/dist/targets.js.map +0 -1
- /package/dist/{targets.d.ts → browser/targets.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# recordable
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/recordable)
|
|
4
|
+
|
|
3
5
|
Programmatic, repeatable browser screen recording. Describe a session as a fluent
|
|
4
6
|
chain of actions — `visit`, `click`, `type`, `zoom`, `scroll` — and `recordable`
|
|
5
7
|
drives a real [Puppeteer](https://pptr.dev/) browser and captures a clean MP4,
|
|
@@ -22,12 +24,14 @@ await new Recordable({ typingSpeed: 120 })
|
|
|
22
24
|
.scroll("bottom")
|
|
23
25
|
.resetZoom()
|
|
24
26
|
.wait(1500)
|
|
25
|
-
.run(); // finalises automatically —
|
|
27
|
+
.run(); // finalises automatically — bookends are optional
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
Recording is **on by default** and finalises when `.run()` ends
|
|
29
|
-
`
|
|
30
|
-
|
|
30
|
+
Recording is **on by default** and finalises when `.run()` ends. Use `pause()` /
|
|
31
|
+
`resume()` to carve out anything you don't want on camera; every captured segment
|
|
32
|
+
is stitched into one seamless MP4. Need explicit bookends or several output files?
|
|
33
|
+
`start()` / `end()` / `split()` move the file boundaries (see
|
|
34
|
+
[Multiple output files](#multiple-output-files-start--end--split)).
|
|
31
35
|
|
|
32
36
|
## Features
|
|
33
37
|
|
|
@@ -45,9 +49,10 @@ want on camera; every captured segment is stitched into one seamless MP4.
|
|
|
45
49
|
- **Manual steps / logins** — `resumeOnPlay()` waits for an in-page ▶ Play button
|
|
46
50
|
(see below), so you can sign in by hand before recording.
|
|
47
51
|
- **Auto-scroll** to bring elements into view before interacting.
|
|
48
|
-
- **Declarative JSON
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
- **Declarative scripts (JSON _or_ Markdown) + CLI** — author a recording as data,
|
|
53
|
+
not code, and run it with `npx recordable demo.json` / `demo.md`, no install or
|
|
54
|
+
TypeScript required. JSON ships a published schema for editor autocomplete;
|
|
55
|
+
Markdown adds prose narration for voiceover.
|
|
51
56
|
|
|
52
57
|
## Install
|
|
53
58
|
|
|
@@ -57,7 +62,7 @@ npm install recordable
|
|
|
57
62
|
|
|
58
63
|
Frames are captured via the Chrome DevTools Protocol and encoded with **FFmpeg** —
|
|
59
64
|
there's no external screen-recorder dependency. The ffmpeg binary ships via
|
|
60
|
-
[
|
|
65
|
+
[`ffmpeg-static`](https://www.npmjs.com/package/ffmpeg-static),
|
|
61
66
|
so there's nothing else to install (a system `ffmpeg` on your `PATH` is used as a
|
|
62
67
|
fallback).
|
|
63
68
|
|
|
@@ -93,27 +98,132 @@ local copy) and your editor gives you autocomplete, required-key checking, and
|
|
|
93
98
|
typo catching for every action — no TypeScript needed. The schema is published as
|
|
94
99
|
`recordable.schema.json`.
|
|
95
100
|
|
|
96
|
-
Run a script from code
|
|
101
|
+
Run a JSON script from code by handing it to a `Recordable` — a parsed object or
|
|
102
|
+
the raw file string both work:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { readFileSync } from "node:fs";
|
|
106
|
+
import { Recordable } from "recordable";
|
|
107
|
+
|
|
108
|
+
const script = readFileSync("./demo.json", "utf8");
|
|
109
|
+
await new Recordable({ baseDir: "." }).fromJSON(script).run();
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`baseDir` is the script's folder — `recordable` resolves relative `visit` URLs
|
|
113
|
+
and a relative `outputDir` against it. (Standalone `runScript` / `fromJSON`
|
|
114
|
+
helpers are also exported if you prefer a single call.)
|
|
115
|
+
|
|
116
|
+
## Declarative scripts (Markdown)
|
|
117
|
+
|
|
118
|
+
Markdown is the richest authoring surface — the **same actions as JSON**, written
|
|
119
|
+
as backtick method-call spans, with optional narration prose woven around them for
|
|
120
|
+
voiceover. YAML frontmatter carries the [config](#configuration); an optional
|
|
121
|
+
`voiceover` block opts into narration audio (`voiceover: true` reads provider /
|
|
122
|
+
voice from the environment, or pass an object to set them inline).
|
|
123
|
+
|
|
124
|
+
Two flavours, mixable in one document:
|
|
125
|
+
|
|
126
|
+
**1. A fenced action list** — one call per line, no prose. The closest Markdown
|
|
127
|
+
gets to JSON; compiles to the exact same actions:
|
|
128
|
+
|
|
129
|
+
````md
|
|
130
|
+
---
|
|
131
|
+
viewport: { width: 1280, height: 800 }
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
pause()
|
|
136
|
+
visit("./index.html")
|
|
137
|
+
resume()
|
|
138
|
+
zoom(1.4, { origin: "#email" })
|
|
139
|
+
type("#email", "hello@example.com")
|
|
140
|
+
click("text:Sign up", { waitForNav: true })
|
|
141
|
+
waitFor("text:Thanks", { state: "visible" })
|
|
142
|
+
resetZoom()
|
|
143
|
+
```
|
|
144
|
+
````
|
|
145
|
+
|
|
146
|
+
**2. Inline markers in prose** — drop call spans into narration; each fires at its
|
|
147
|
+
position in the spoken line. With `voiceover` on, the prose is read aloud and waits
|
|
148
|
+
are timed to the narration:
|
|
149
|
+
|
|
150
|
+
```md
|
|
151
|
+
---
|
|
152
|
+
typingSpeed: 16
|
|
153
|
+
voiceover: true
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
`visit("./signin.html")` Welcome — first we sign in with our work account
|
|
157
|
+
`type("#email", "maya@example.com")` then our password
|
|
158
|
+
`type("#password", "•••••")` `click("#signInBtn", { waitForNav: true })` — and
|
|
159
|
+
we're straight into the dashboard.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Each backtick span holds exactly one call; its arguments are the method's
|
|
163
|
+
arguments, identical to the chainable API and the JSON `action` keys. Whole-line
|
|
164
|
+
`//` comments are stripped before parsing, so toggle-comment in your editor is
|
|
165
|
+
safe. Run a Markdown file through the [CLI](#cli) (`npx recordable demo.md`) or
|
|
166
|
+
from code:
|
|
97
167
|
|
|
98
168
|
```ts
|
|
99
|
-
import {
|
|
100
|
-
import
|
|
169
|
+
import { readFileSync } from "node:fs";
|
|
170
|
+
import { Recordable } from "recordable";
|
|
101
171
|
|
|
102
|
-
|
|
172
|
+
const md = readFileSync("./demo.md", "utf8");
|
|
173
|
+
await new Recordable({ baseDir: "." }).fromMarkdown(md).run();
|
|
103
174
|
```
|
|
104
175
|
|
|
105
|
-
|
|
176
|
+
## Voiceover
|
|
106
177
|
|
|
107
|
-
|
|
178
|
+
A Markdown script can narrate itself. The prose around your inline markers becomes
|
|
179
|
+
spoken audio (text-to-speech), and the markers are **timed to the narration** — each
|
|
180
|
+
action fires at its position in the spoken line, so the demo and the voice stay in
|
|
181
|
+
sync without hand-tuned `wait`s.
|
|
182
|
+
|
|
183
|
+
Opt in from frontmatter. With credentials in the environment, `voiceover: true` is
|
|
184
|
+
all a document needs; spell out a `voiceover` object to set provider / voice / model
|
|
185
|
+
inline (it overrides the environment):
|
|
186
|
+
|
|
187
|
+
```yaml
|
|
188
|
+
voiceover: true
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```yaml
|
|
192
|
+
voiceover:
|
|
193
|
+
provider: elevenlabs # or `mock` for silent, offline audio
|
|
194
|
+
voiceId: EXAVITQu4vr4xnSDxMaL
|
|
195
|
+
modelId: eleven_multilingual_v2
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Credentials & defaults** come from a `.env` loaded automatically from **beside the
|
|
199
|
+
document** (copy [`.env.example`](.env.example)):
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
ELEVENLABS_API_KEY=... # required for real synthesis
|
|
203
|
+
RECORDABLE_TTS_PROVIDER=elevenlabs # or `mock` for silent, offline audio
|
|
204
|
+
RECORDABLE_VOICE_ID=... # default voice when frontmatter omits it
|
|
205
|
+
RECORDABLE_MODEL_ID=eleven_multilingual_v2
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Generated audio is written to the `assetsDir` (default `assets/`, beside the output)
|
|
209
|
+
and cached, so re-running an unchanged script doesn't re-synthesize. Validate a
|
|
210
|
+
voiceover script without hitting the TTS API — or a browser — with `recordable
|
|
211
|
+
demo.md --check`. For a music bed or a hand-recorded narration file, drop it straight
|
|
212
|
+
onto the timeline with `audio(path, opts?)` (see the [API](#recording)).
|
|
213
|
+
|
|
214
|
+
## CLI
|
|
215
|
+
|
|
216
|
+
Run a JSON **or** Markdown file directly — **no install required** via `npx`:
|
|
108
217
|
|
|
109
218
|
```sh
|
|
110
219
|
npx recordable demo.json
|
|
220
|
+
npx recordable demo.md
|
|
111
221
|
```
|
|
112
222
|
|
|
113
223
|
```
|
|
114
|
-
recordable <script.json> [options]
|
|
224
|
+
recordable <script.json | script.md> [options]
|
|
115
225
|
|
|
116
|
-
--check Validate the script and exit (no browser, no recording)
|
|
226
|
+
--check Validate the script and exit (no browser, no audio, no recording)
|
|
117
227
|
--headless Run without a visible browser window
|
|
118
228
|
--silent Suppress recorder console output
|
|
119
229
|
--out-dir <dir> Output directory (overrides the script's config)
|
|
@@ -195,8 +305,9 @@ new Recordable()
|
|
|
195
305
|
```
|
|
196
306
|
|
|
197
307
|
No `pause()`/`resume()` needed — `insert` seals the current segment and recording
|
|
198
|
-
resumes into a fresh one on the next action automatically. (Audio on the
|
|
199
|
-
currently dropped
|
|
308
|
+
resumes into a fresh one on the next action automatically. (Audio on the inserted
|
|
309
|
+
clip itself is currently dropped — narration voiceover is a separate, supported
|
|
310
|
+
feature, authored in [Markdown](#declarative-scripts-markdown).)
|
|
200
311
|
|
|
201
312
|
**Cross-fades.** Pass `fadeIn` / `fadeOut` (ms) to dissolve rather than hard-cut.
|
|
202
313
|
A fade blends the clip with the **neighbouring recorded footage** (a true
|
|
@@ -206,6 +317,39 @@ on `fadeOut`, while an outro's `fadeOut` dissolves down to black. Omit them for
|
|
|
206
317
|
hard cut. A cross-fade of _d_ ms overlaps the two pieces by _d_, shortening the
|
|
207
318
|
timeline by that much at each faded boundary.
|
|
208
319
|
|
|
320
|
+
## Multiple output files (`start` / `end` / `split`)
|
|
321
|
+
|
|
322
|
+
`pause()`/`resume()` carve off-camera gaps **within one file**. To produce
|
|
323
|
+
**separate files**, move the file boundaries with `start()` / `end()` / `split()`:
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
await new Recordable({ outputName: "demo" })
|
|
327
|
+
.start("intro") // open the first file (content before it is off-camera)
|
|
328
|
+
.visit("https://example.com")
|
|
329
|
+
.click("text:Get started")
|
|
330
|
+
.split("checkout") // close "intro", open the next — camera keeps rolling
|
|
331
|
+
.click("text:Buy")
|
|
332
|
+
.end() // close "checkout"; the teardown below runs off-camera
|
|
333
|
+
.click("text:Sign out")
|
|
334
|
+
.run(); // → demo-intro.mp4, demo-checkout.mp4
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
- **Boundaries default to the script edges.** With no `start()`, recording opens
|
|
338
|
+
at the top; with no `end()`, it closes at the bottom — so a plain script is one
|
|
339
|
+
file, exactly as before. Add only the bookend you need.
|
|
340
|
+
- **`pause`/`resume` ≠ `start`/`end`.** `resume()` continues the _same_ file (the
|
|
341
|
+
gap is stitched out); `start()`/`split()` open a _new_ file. `split() ≡ end() +
|
|
342
|
+
start()` fused with no gap; for two files _with_ an off-camera gap between them,
|
|
343
|
+
use `end()` … `start()`.
|
|
344
|
+
- **Naming.** Each file is `${outputName}-${label ?? index}.mp4`; a label always
|
|
345
|
+
wins. A single unlabelled file stays `${outputName}.mp4`.
|
|
346
|
+
- **Audio is per-file** — each output is standalone with its own zero-based
|
|
347
|
+
timeline; a clip is assigned to the file containing its start.
|
|
348
|
+
|
|
349
|
+
`run()` resolves to a `RecordableResult` — `{ status, files: [{ path, label,
|
|
350
|
+
index, durationMs, bytes }], outputDir, durationMs, elapsedMs, warnings }` — so
|
|
351
|
+
you can find every file that was written. Hard failures throw instead.
|
|
352
|
+
|
|
209
353
|
## API
|
|
210
354
|
|
|
211
355
|
Create an instance with optional [config](#configuration), chain actions, then
|
|
@@ -213,16 +357,22 @@ Create an instance with optional [config](#configuration), chain actions, then
|
|
|
213
357
|
|
|
214
358
|
### Recording
|
|
215
359
|
|
|
216
|
-
Recording is on by default and finalises automatically on `.run()
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
| `
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
360
|
+
Recording is on by default and finalises automatically on `.run()`, which resolves
|
|
361
|
+
to a [`RecordableResult`](#multiple-output-files-start--end--split). `pause`/`resume`
|
|
362
|
+
control what lands on camera _within_ a file; `start`/`end`/`split` move the file
|
|
363
|
+
boundaries to produce [separate files](#multiple-output-files-start--end--split):
|
|
364
|
+
|
|
365
|
+
| Method | Description |
|
|
366
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
367
|
+
| `pause()` | Stop capturing; the chain keeps running off-camera. |
|
|
368
|
+
| `resume()` | Resume capturing in a fresh segment, immediately. |
|
|
369
|
+
| `start(name?)` | Open an output file (opening boundary); content before the first `start()` is off-camera. `name` labels the file. |
|
|
370
|
+
| `end()` | Close the current output file (closing boundary); content after it runs off-camera. |
|
|
371
|
+
| `split(name?)` | Close the current file and open the next in one move, camera still rolling — `end()` + `start()` with no gap. |
|
|
372
|
+
| `waitForPlay(message?)` | Block until the user clicks the in-page ▶ Play button (or presses Enter); leaves recording state untouched. |
|
|
373
|
+
| `resumeOnPlay(message?)` | Wait for ▶ Play, then resume capturing — `waitForPlay().resume()`. |
|
|
374
|
+
| `insert(path, opts?)` | Splice an external clip (intro / outro / mid-roll) into the timeline; `opts.fadeIn`/`fadeOut` (ms) cross-fade it. |
|
|
375
|
+
| `audio(path, opts?)` | Lay an existing audio file (mp3/wav) onto the timeline here — narration, music bed, SFX. Blocks until the clip ends by default (`opts.wait: false` plays it over following actions); `opts.volume` gains it. |
|
|
226
376
|
|
|
227
377
|
### Navigation & waiting
|
|
228
378
|
|
|
@@ -234,15 +384,15 @@ what lands on camera:
|
|
|
234
384
|
|
|
235
385
|
### Interactions
|
|
236
386
|
|
|
237
|
-
| Method
|
|
238
|
-
|
|
|
387
|
+
| Method | Description |
|
|
388
|
+
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
239
389
|
| `click(target, { waitForNav?, followNewTab? })` | Click an element. Returns immediately by default; pass `{ waitForNav: true }` when the click triggers a full-page navigation, or `{ followNewTab: true }` to keep recording in a tab the click opens (see notes below). |
|
|
240
|
-
| `hover(target)`
|
|
241
|
-
| `type(target, text, { duration? })`
|
|
242
|
-
| `clear(target)`
|
|
243
|
-
| `select(target, value)`
|
|
244
|
-
| `key(key)`
|
|
245
|
-
| `mouse(target \| {x, y})`
|
|
390
|
+
| `hover(target)` | Move onto an element to reveal `:hover` state (no click). |
|
|
391
|
+
| `type(target, text, { duration? })` | Type into a field with human-like timing; `duration` (ms) spreads keystrokes evenly with no jitter. |
|
|
392
|
+
| `clear(target)` | Select-all + delete the contents of a field. |
|
|
393
|
+
| `select(target, value)` | Choose an option in a native `<select>` by `value`, or by `:option-index(N)` / `:option-label(Text)` (see note below; OS-drawn list isn't captured). |
|
|
394
|
+
| `key(key)` | Press a key, e.g. `"Escape"`, `"Enter"`, `"Tab"`. |
|
|
395
|
+
| `mouse(target \| {x, y})` | Move the cursor to an element or coordinates. |
|
|
246
396
|
|
|
247
397
|
> The browser draws an open `<select>`'s option list with the OS, outside the page,
|
|
248
398
|
> so the screencast can't capture it — `select()` shows the cursor and the value
|
|
@@ -267,12 +417,12 @@ what lands on camera:
|
|
|
267
417
|
|
|
268
418
|
### Camera
|
|
269
419
|
|
|
270
|
-
| Method
|
|
271
|
-
|
|
|
272
|
-
| `scroll(target, { duration? })`
|
|
273
|
-
| `zoom(level, { origin?, duration? })`
|
|
274
|
-
| `resetZoom({ duration? })`
|
|
275
|
-
| `setConfig(config)`
|
|
420
|
+
| Method | Description |
|
|
421
|
+
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
422
|
+
| `scroll(target, { container?, duration? })` | Smooth-scroll to `"top"`/`"bottom"`, a selector, or a Y position. `container` scrolls a named overflow pane (modal, sidebar, list) instead of the window. |
|
|
423
|
+
| `zoom(level, { origin?, duration? })` | Smoothly scale from an origin (keyword, `%`, or selector). |
|
|
424
|
+
| `resetZoom({ duration? })` | Smoothly return to 1×. |
|
|
425
|
+
| `setConfig(config)` | Merge config mid-sequence (takes effect at that point). |
|
|
276
426
|
|
|
277
427
|
### Targeting
|
|
278
428
|
|
|
@@ -305,11 +455,13 @@ new Recordable({
|
|
|
305
455
|
viewport: { width: 1920, height: 1080 },
|
|
306
456
|
pageZoom: 1, // browser page zoom (Ctrl +/−); <1 reflows to fit more on screen
|
|
307
457
|
fps: 30,
|
|
308
|
-
outputDir: "
|
|
458
|
+
outputDir: "output", // relative paths resolve against baseDir
|
|
309
459
|
outputName: "recordable",
|
|
310
460
|
outputTimestamp: true, // prepend an ISO timestamp to the filename
|
|
461
|
+
assetsDir: "assets", // where generated voiceover audio is written (relative to baseDir)
|
|
311
462
|
headless: false,
|
|
312
|
-
|
|
463
|
+
launchArgs: [], // extra Chromium flags, e.g. ["--no-sandbox"] for CI/containers
|
|
464
|
+
language: "", // BCP-47 locale, e.g. "fr-FR" (--lang + --accept-lang + Accept-Language); "" = system
|
|
313
465
|
typingSpeed: 7, // characters per second
|
|
314
466
|
videoCrf: 18, // lower = better quality, larger file
|
|
315
467
|
videoCodec: "libx264",
|
|
@@ -323,6 +475,7 @@ new Recordable({
|
|
|
323
475
|
scrollDuration: 1200, // ms for the scroll action's transition
|
|
324
476
|
cursor: true, // show the animated cursor overlay
|
|
325
477
|
visitTimeout: 30_000, // ms for navigation / waitFor
|
|
478
|
+
baseDir: "", // dir that relative visit URLs, outputDir & assetsDir resolve against; "" = cwd
|
|
326
479
|
});
|
|
327
480
|
```
|
|
328
481
|
|
|
@@ -336,6 +489,7 @@ npm test # unit + ffmpeg I/O tests
|
|
|
336
489
|
npm run test:e2e # opt-in end-to-end pipeline run (launches a browser)
|
|
337
490
|
npx tsx my-script.ts # run a recording script directly
|
|
338
491
|
node dist/cli.js demo.json # run a JSON script through the CLI locally
|
|
492
|
+
node dist/cli.js demo.md # run a Markdown script through the CLI locally
|
|
339
493
|
```
|
|
340
494
|
|
|
341
495
|
The JSON action set and its schema are both generated from one manifest in
|
package/dist/actions.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ import * as z from "zod";
|
|
|
4
4
|
* discriminator). strictObject so an unknown key (a typo) fails validation.
|
|
5
5
|
*/
|
|
6
6
|
declare const ACTIONS: {
|
|
7
|
+
start: z.ZodObject<{
|
|
8
|
+
name: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strict>;
|
|
10
|
+
end: z.ZodObject<{}, z.core.$strict>;
|
|
11
|
+
split: z.ZodObject<{
|
|
12
|
+
name: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strict>;
|
|
7
14
|
pause: z.ZodObject<{}, z.core.$strict>;
|
|
8
15
|
resume: z.ZodObject<{}, z.core.$strict>;
|
|
9
16
|
waitForPlay: z.ZodObject<{
|
|
@@ -100,6 +107,7 @@ declare const ACTIONS: {
|
|
|
100
107
|
}, z.core.$strict>;
|
|
101
108
|
scroll: z.ZodObject<{
|
|
102
109
|
target: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
110
|
+
container: z.ZodOptional<z.ZodString>;
|
|
103
111
|
duration: z.ZodOptional<z.ZodNumber>;
|
|
104
112
|
}, z.core.$strict>;
|
|
105
113
|
zoom: z.ZodObject<{
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAezB;;;GAGG;AACH,QAAA,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAezB;;;GAGG;AACH,QAAA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmE0B,CAAC;AAcxC,sEAAsE;AACtE,MAAM,MAAM,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAuChE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAgBjD;AAED;;;;;;GAMG;AACH,iBAAS,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAcxD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAkD3E;AAED,wEAAwE;AACxE,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB,iFAAiF;AACjF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/actions.js
CHANGED
|
@@ -16,6 +16,9 @@ const XY = z.strictObject({ x: z.number(), y: z.number() });
|
|
|
16
16
|
*/
|
|
17
17
|
const ACTIONS = {
|
|
18
18
|
// Recording control
|
|
19
|
+
start: z.strictObject({ name: z.string().optional() }),
|
|
20
|
+
end: z.strictObject({}),
|
|
21
|
+
split: z.strictObject({ name: z.string().optional() }),
|
|
19
22
|
pause: z.strictObject({}),
|
|
20
23
|
resume: z.strictObject({}),
|
|
21
24
|
waitForPlay: z.strictObject({ message: z.string().optional() }),
|
|
@@ -63,6 +66,7 @@ const ACTIONS = {
|
|
|
63
66
|
// Scrolling / zoom
|
|
64
67
|
scroll: z.strictObject({
|
|
65
68
|
target: z.union([z.string(), z.number()]),
|
|
69
|
+
container: z.string().optional(),
|
|
66
70
|
duration: z.number().optional(),
|
|
67
71
|
}),
|
|
68
72
|
zoom: z.strictObject({
|
|
@@ -80,6 +84,8 @@ const ACTIONS = {
|
|
|
80
84
|
* fact not derivable from the schema.
|
|
81
85
|
*/
|
|
82
86
|
const POSITIONAL_OPTIONAL = {
|
|
87
|
+
start: ["name"],
|
|
88
|
+
split: ["name"],
|
|
83
89
|
waitForPlay: ["message"],
|
|
84
90
|
resumeOnPlay: ["message"],
|
|
85
91
|
};
|
|
@@ -155,7 +161,7 @@ function buildArgs(step, name) {
|
|
|
155
161
|
export function callToAction(name, args) {
|
|
156
162
|
const schema = ACTIONS[name];
|
|
157
163
|
if (!schema) {
|
|
158
|
-
throw new
|
|
164
|
+
throw new RecordableError("CONFIG_INVALID", `Unknown action "${name}" — valid actions: ${Object.keys(ACTIONS).join(", ")}`);
|
|
159
165
|
}
|
|
160
166
|
const step = { action: name };
|
|
161
167
|
let i = 0;
|
|
@@ -163,23 +169,23 @@ export function callToAction(name, args) {
|
|
|
163
169
|
if (i < args.length)
|
|
164
170
|
step[key] = args[i++];
|
|
165
171
|
else if (!isOptional(name, key))
|
|
166
|
-
throw new
|
|
172
|
+
throw new RecordableError("CONFIG_INVALID", `Action "${name}" is missing required "${key}"`);
|
|
167
173
|
}
|
|
168
174
|
const bag = bagKeys(name);
|
|
169
175
|
if (i < args.length && bag.length) {
|
|
170
176
|
const obj = args[i++];
|
|
171
177
|
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
172
|
-
throw new
|
|
178
|
+
throw new RecordableError("CONFIG_INVALID", `Action "${name}": expected a trailing options object, got ${JSON.stringify(obj)}`);
|
|
173
179
|
}
|
|
174
180
|
for (const [k, v] of Object.entries(obj)) {
|
|
175
181
|
if (!bag.includes(k)) {
|
|
176
|
-
throw new
|
|
182
|
+
throw new RecordableError("CONFIG_INVALID", `Action "${name}": unknown key "${k}" — valid keys: ${bag.join(", ")}`);
|
|
177
183
|
}
|
|
178
184
|
step[k] = v;
|
|
179
185
|
}
|
|
180
186
|
}
|
|
181
187
|
if (i < args.length) {
|
|
182
|
-
throw new
|
|
188
|
+
throw new RecordableError("CONFIG_INVALID", `Action "${name}": too many arguments (expected at most ${i}, got ${args.length})`);
|
|
183
189
|
}
|
|
184
190
|
validateAction(step);
|
|
185
191
|
return step;
|
package/dist/actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/audio/track.d.ts
CHANGED
|
@@ -24,6 +24,16 @@ export declare class AudioTrack {
|
|
|
24
24
|
durationMs: number;
|
|
25
25
|
}>;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Partition clips across a run's output files (ROADMAP §6: per-file audio). A
|
|
29
|
+
* clip is assigned to the file *containing its start* — the last file whose
|
|
30
|
+
* global `startMs` is at or before the clip — then rebased to that file's own
|
|
31
|
+
* zero-based timeline. A clip overrunning its file's end is left for the mixer
|
|
32
|
+
* to trim (and warn). Returns one clip list per file, aligned to `files`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function partitionAudioByFiles(clips: readonly AudioClip[], files: readonly {
|
|
35
|
+
startMs: number;
|
|
36
|
+
}[]): AudioClip[][];
|
|
27
37
|
/**
|
|
28
38
|
* Build the `filter_complex` chain that delays each clip to its `startMs`,
|
|
29
39
|
* applies volume, and mixes them. Input index `i+1` (input 0 is the video).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/audio/track.ts"],"names":[],"mappings":"AAYA,oEAAoE;AACpE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;uEACuE;AACvE,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IAEzC,oCAAoC;IACpC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,kEAAkE;IAClE,IAAI,IAAI,SAAS,SAAS,EAAE;IAI5B;;;OAGG;IACG,GAAG,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAChC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"track.d.ts","sourceRoot":"","sources":["../../src/audio/track.ts"],"names":[],"mappings":"AAYA,oEAAoE;AACpE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;uEACuE;AACvE,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IAEzC,oCAAoC;IACpC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,kEAAkE;IAClE,IAAI,IAAI,SAAS,SAAS,EAAE;IAI5B;;;OAGG;IACG,GAAG,CACP,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAChC,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAUpD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,KAAK,EAAE,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,GACpC,SAAS,EAAE,EAAE,CAUf;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG;IAC7D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAeA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,OAAO,EAAE,MAAM,EACf,KAAK,SAAK,GACT;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,CAOpC"}
|
package/dist/audio/track.js
CHANGED
|
@@ -25,6 +25,25 @@ export class AudioTrack {
|
|
|
25
25
|
return { startMs, durationMs };
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Partition clips across a run's output files (ROADMAP §6: per-file audio). A
|
|
30
|
+
* clip is assigned to the file *containing its start* — the last file whose
|
|
31
|
+
* global `startMs` is at or before the clip — then rebased to that file's own
|
|
32
|
+
* zero-based timeline. A clip overrunning its file's end is left for the mixer
|
|
33
|
+
* to trim (and warn). Returns one clip list per file, aligned to `files`.
|
|
34
|
+
*/
|
|
35
|
+
export function partitionAudioByFiles(clips, files) {
|
|
36
|
+
const groups = files.map(() => []);
|
|
37
|
+
for (const c of clips) {
|
|
38
|
+
let idx = 0;
|
|
39
|
+
for (let i = 0; i < files.length; i++)
|
|
40
|
+
if (files[i].startMs <= c.startMs)
|
|
41
|
+
idx = i;
|
|
42
|
+
if (groups[idx])
|
|
43
|
+
groups[idx].push({ ...c, startMs: c.startMs - files[idx].startMs });
|
|
44
|
+
}
|
|
45
|
+
return groups;
|
|
46
|
+
}
|
|
28
47
|
/**
|
|
29
48
|
* Build the `filter_complex` chain that delays each clip to its `startMs`,
|
|
30
49
|
* applies volume, and mixes them. Input index `i+1` (input 0 is the video).
|
package/dist/audio/track.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track.js","sourceRoot":"","sources":["../../src/audio/track.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAkB/C;uEACuE;AACvE,MAAM,OAAO,UAAU;IACJ,KAAK,GAAgB,EAAE,CAAC;IAEzC,oCAAoC;IACpC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,kEAAkE;IAClE,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CACP,IAAY,EACZ,OAAe,EACf,UAA+B,EAAE;QAEjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnB,MAAM,IAAI,eAAe,
|
|
1
|
+
{"version":3,"file":"track.js","sourceRoot":"","sources":["../../src/audio/track.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAkB/C;uEACuE;AACvE,MAAM,OAAO,UAAU;IACJ,KAAK,GAAgB,EAAE,CAAC;IAEzC,oCAAoC;IACpC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,kEAAkE;IAClE,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CACP,IAAY,EACZ,OAAe,EACf,UAA+B,EAAE;QAEjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACnB,MAAM,IAAI,eAAe,CACvB,gBAAgB,EAChB,0BAA0B,IAAI,EAAE,CACjC,CAAC;QACJ,MAAM,UAAU,GAAG,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QACpD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACvE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IACjC,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAA2B,EAC3B,KAAqC;IAErC,MAAM,MAAM,GAAkB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;YACnC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO;gBAAE,GAAG,GAAG,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,GAAG,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA2B;IAI1D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,KAAK,CAAC,MAAM,oBAAoB,CAClE,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAA2B,EAC3B,OAAe,EACf,KAAK,GAAG,EAAE;IAEV,MAAM,IAAI,GAAuC,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC;QAC9D,IAAI,MAAM,GAAG,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/browser/cursor.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare class Cursor {
|
|
|
17
17
|
park(): void;
|
|
18
18
|
/** Restore the parked position (if any) and re-inject — called on resume so the
|
|
19
19
|
* new segment opens with the cursor where the previous one ended. */
|
|
20
|
-
unpark(page: Page, zoom?: ZoomState
|
|
20
|
+
unpark(page: Page, zoom?: ZoomState): Promise<void>;
|
|
21
21
|
/**
|
|
22
22
|
* Ensure the cursor overlay exists and sits at the carried position, then sync
|
|
23
23
|
* the real mouse there. Safe to call repeatedly: it creates the overlay if the
|
|
@@ -25,18 +25,20 @@ export declare class Cursor {
|
|
|
25
25
|
* repositions it — so a resume() can restore the cursor even when the overlay
|
|
26
26
|
* survived the off-camera gap.
|
|
27
27
|
*/
|
|
28
|
-
inject(page: Page, zoom?: ZoomState
|
|
28
|
+
inject(page: Page, zoom?: ZoomState): Promise<void>;
|
|
29
29
|
/** Ease the overlay (and the real mouse) to viewport coords `toX,toY`. */
|
|
30
|
-
moveTo(page: Page, toX: number, toY: number, zoom: ZoomState
|
|
30
|
+
moveTo(page: Page, toX: number, toY: number, zoom: ZoomState): Promise<void>;
|
|
31
31
|
/**
|
|
32
32
|
* Convert viewport coords → document coords for the overlay's transform.
|
|
33
33
|
* When documentElement has a CSS transform (zoom), position:fixed children
|
|
34
34
|
* are positioned relative to that ancestor (not the viewport) and scroll with
|
|
35
35
|
* the page, so we add scroll and apply the inverse zoom transform.
|
|
36
36
|
*
|
|
37
|
-
* `pageZoom`
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* Note: the `pageZoom` config (genuine browser zoom via chrome.tabs.setZoom)
|
|
38
|
+
* needs no handling here. Page zoom rescales the CSS pixel itself, so the
|
|
39
|
+
* overlay, the content, and Puppeteer's `boundingBox()`/`mouse` coords all share
|
|
40
|
+
* one post-zoom coordinate space — feeding the overlay those raw coords keeps it
|
|
41
|
+
* aligned with the target automatically.
|
|
40
42
|
*/
|
|
41
43
|
private _toDocCoords;
|
|
42
44
|
/** Briefly scale the cursor down to signal a press. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/browser/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/browser/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAiBtC,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;GAIG;AACH,qBAAa,MAAM;IAIjB,OAAO,CAAC,GAAG,CAAkB;IAK7B,OAAO,CAAC,MAAM,CAAyC;IAEvD,4EAA4E;IAC5E,IAAI,IAAI,IAAI;IAIZ;0EACsE;IAChE,MAAM,CACV,IAAI,EAAE,IAAI,EACV,IAAI,GAAE,SAAkC,GACvC,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;;;OAMG;IACG,MAAM,CACV,IAAI,EAAE,IAAI,EACV,IAAI,GAAE,SAAkC,GACvC,OAAO,CAAC,IAAI,CAAC;IA2EhB,0EAA0E;IACpE,MAAM,CACV,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,GACd,OAAO,CAAC,IAAI,CAAC;IAoChB;;;;;;;;;;;OAWG;YACW,YAAY;IAa1B,uDAAuD;IACjD,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAa7C"}
|