@push.rocks/smartbrowser 2.0.11 → 4.0.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.
@@ -0,0 +1,3 @@
1
+ export { LiveBrowserCanvasRenderer } from './classes.livebrowsercanvasrenderer.js';
2
+ export type * from './interfaces.livebrowsercanvas.js';
3
+ export type { ILiveBrowserError, ILiveBrowserErrorEvent, ILiveBrowserFrame, ILiveBrowserFrameAcknowledgement, ILiveBrowserFrameAcknowledgementRequest, ILiveBrowserFrameEvent, ILiveBrowserInputBase, ILiveBrowserInsertTextInput, ILiveBrowserKeyInput, ILiveBrowserModifierState, ILiveBrowserMouseInput, ILiveBrowserScreencastMetadata, ILiveBrowserState, ILiveBrowserStateEvent, ILiveBrowserTabState, ILiveBrowserViewport, ILiveBrowserWheelInput, TLiveBrowserEvent, TLiveBrowserEventListener, TLiveBrowserImageFormat, TLiveBrowserStatus, TLiveBrowserTabStatus, } from '@push.rocks/smartpuppeteer';
@@ -0,0 +1,2 @@
1
+ export { LiveBrowserCanvasRenderer } from './classes.livebrowsercanvasrenderer.js';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c193ZWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sd0NBQXdDLENBQUMifQ==
@@ -0,0 +1,41 @@
1
+ import type { ILiveBrowserFrame, ILiveBrowserFrameAcknowledgement, ILiveBrowserFrameAcknowledgementRequest, ILiveBrowserInsertTextInput, ILiveBrowserKeyInput, ILiveBrowserMouseInput, ILiveBrowserState, ILiveBrowserViewport, ILiveBrowserWheelInput, TLiveBrowserEventListener } from '@push.rocks/smartpuppeteer';
2
+ /**
3
+ * Transport adapter for one renderer. Frame events must use strictly increasing
4
+ * sequence values for each onEvent subscription/renderer run.
5
+ */
6
+ export interface ILiveBrowserCanvasClient {
7
+ getState(): ILiveBrowserState;
8
+ onEvent(listenerArg: TLiveBrowserEventListener): () => void;
9
+ /**
10
+ * A fulfilled result, including accepted: false, settles the local attempt.
11
+ * It does not prove that the upstream frame was retired.
12
+ */
13
+ acknowledgeFrame(requestArg: ILiveBrowserFrameAcknowledgementRequest, optionsArg: ILiveBrowserCanvasOperationOptions): Promise<ILiveBrowserFrameAcknowledgement>;
14
+ setViewport(viewportArg: ILiveBrowserViewport, optionsArg: ILiveBrowserCanvasOperationOptions): Promise<void>;
15
+ dispatchMouse(inputArg: ILiveBrowserMouseInput, optionsArg: ILiveBrowserCanvasOperationOptions): Promise<void>;
16
+ dispatchWheel(inputArg: ILiveBrowserWheelInput, optionsArg: ILiveBrowserCanvasOperationOptions): Promise<void>;
17
+ dispatchKey(inputArg: ILiveBrowserKeyInput, optionsArg: ILiveBrowserCanvasOperationOptions): Promise<void>;
18
+ insertText(inputArg: ILiveBrowserInsertTextInput, optionsArg: ILiveBrowserCanvasOperationOptions): Promise<void>;
19
+ }
20
+ export interface ILiveBrowserCanvasOperationOptions {
21
+ /** Adapters must propagate this signal and reject promptly when it aborts. */
22
+ signal: AbortSignal;
23
+ }
24
+ export type TLiveBrowserCanvasErrorCode = 'frame_acknowledgement_failed' | 'frame_render_failed' | 'input_dispatch_failed' | 'input_queue_capacity_exceeded' | 'remote_browser_error' | 'renderer_callback_failed' | 'renderer_cleanup_failed' | 'viewport_update_failed';
25
+ export interface ILiveBrowserCanvasError {
26
+ code: TLiveBrowserCanvasErrorCode;
27
+ message: string;
28
+ cause?: unknown;
29
+ frame?: ILiveBrowserFrame;
30
+ }
31
+ export interface ILiveBrowserCanvasRendererOptions {
32
+ canvas: HTMLCanvasElement;
33
+ client: ILiveBrowserCanvasClient;
34
+ focusTarget?: HTMLElement;
35
+ resizeTarget?: Element;
36
+ getDeviceScaleFactor?: () => number;
37
+ operationTimeoutMs?: number;
38
+ frameDecodeTimeoutMs?: number;
39
+ onError?: (errorArg: ILiveBrowserCanvasError) => void;
40
+ onFrameRendered?: (frameArg: ILiveBrowserFrame) => void;
41
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5saXZlYnJvd3NlcmNhbnZhcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3dlYi9pbnRlcmZhY2VzLmxpdmVicm93c2VyY2FudmFzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
package/license.md ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2016 Task Venture Capital GmbH <hello@task.vc>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/package.json CHANGED
@@ -1,49 +1,56 @@
1
1
  {
2
2
  "name": "@push.rocks/smartbrowser",
3
- "version": "2.0.11",
3
+ "version": "4.0.0",
4
4
  "description": "A simplified Puppeteer wrapper for easy automation and testing tasks.",
5
5
  "main": "dist_ts/index.js",
6
6
  "typings": "dist_ts/index.d.ts",
7
7
  "type": "module",
8
- "scripts": {
9
- "test": "(tstest test/ --web)",
10
- "build": "(tsbuild --web)",
11
- "buildDocs": "tsdoc"
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist_ts/index.js",
11
+ "types": "./dist_ts/index.d.ts"
12
+ },
13
+ "./web": {
14
+ "import": "./dist_ts_web/index.js",
15
+ "types": "./dist_ts_web/index.d.ts"
16
+ }
17
+ },
18
+ "engines": {
19
+ "node": ">=22.12.0"
12
20
  },
13
21
  "repository": {
14
22
  "type": "git",
15
23
  "url": "https://code.foss.global/push.rocks/smartbrowser.git"
16
24
  },
17
- "author": "Lossless GmbH",
25
+ "author": "Task Venture Capital GmbH <hello@task.vc>",
18
26
  "license": "MIT",
19
27
  "bugs": {
20
- "url": "https://gitlab.com/pushrocks/smartbrowser/issues"
28
+ "url": "https://code.foss.global/push.rocks/smartbrowser/issues"
21
29
  },
22
30
  "homepage": "https://code.foss.global/push.rocks/smartbrowser",
23
31
  "dependencies": {
24
- "@push.rocks/smartdelay": "^3.0.5",
25
- "@push.rocks/smartpdf": "^4.2.0",
26
- "@push.rocks/smartpuppeteer": "^2.0.5",
27
- "@push.rocks/smartunique": "^3.0.9"
32
+ "@push.rocks/smartdelay": "^3.1.0",
33
+ "@push.rocks/smartpdf": "^5.0.1",
34
+ "@push.rocks/smartpuppeteer": "^2.4.0",
35
+ "@push.rocks/smartunique": "^3.0.10"
28
36
  },
29
37
  "devDependencies": {
30
- "@git.zone/tsbuild": "^4.3.0",
31
- "@git.zone/tsrun": "^2.0.1",
32
- "@git.zone/tstest": "^3.3.1",
33
- "@push.rocks/tapbundle": "^6.0.3",
34
- "@types/node": "^25.3.5"
38
+ "@git.zone/tsbuild": "^4.4.2",
39
+ "@git.zone/tsrun": "^2.0.6",
40
+ "@git.zone/tstest": "^4.0.0",
41
+ "@types/node": "^26.2.0"
35
42
  },
36
43
  "private": false,
37
44
  "files": [
38
45
  "ts/**/*",
39
46
  "ts_web/**/*",
40
- "dist/**/*",
41
47
  "dist_*/**/*",
42
48
  "dist_ts/**/*",
43
49
  "dist_ts_web/**/*",
44
50
  "assets/**/*",
45
51
  "cli.js",
46
- "npmextra.json",
52
+ ".smartconfig.json",
53
+ "license.md",
47
54
  "readme.md"
48
55
  ],
49
56
  "browserslist": [
@@ -57,5 +64,10 @@
57
64
  "screenshot",
58
65
  "web scraping",
59
66
  "browser automation"
60
- ]
61
- }
67
+ ],
68
+ "scripts": {
69
+ "test": "tstest test/",
70
+ "build": "tsbuild tsfolders",
71
+ "buildDocs": "tsdoc"
72
+ }
73
+ }
package/readme.hints.md CHANGED
@@ -1,16 +1,30 @@
1
- # Smartbrowser Hints
1
+ # SmartBrowser Hints
2
2
 
3
- ## Dependencies (as of 2026-03-09)
4
- - `@push.rocks/smartpdf` v4.2.x: Has `SmartPdf.create()` factory method, but `new SmartPdf()` + `start(browser)` still works. Lazy init pattern used.
5
- - `@push.rocks/smartpuppeteer` v2.x: `getEnvAwareBrowserInstance()` main entry point
6
- - `@push.rocks/tapbundle` v6.x: No longer exports `expectAsync`, only `tap`, `expect`, `TapWrap`, `webhelpers`
7
- - `@git.zone/tsbuild` v4.x: No `--allowimplicitany` flag (defaults to `noImplicitAny: false`), `--web` flag still passed but ignored if no ts_web
8
- - `@git.zone/tstest` v3.3.x: Still supports `--web` flag, file suffix conventions changed (`.chromium.ts` for browser tests)
9
- - `@types/node` v25.x: Latest Node.js type definitions
3
+ ## Dependencies (as of 2026-08-15)
4
+ - `@push.rocks/smartpdf` v5.x uses SmartPuppeteer 2/Puppeteer 25 browser types. `SmartPdf` remains lazy and starts only for PDF methods.
5
+ - `@push.rocks/smartpuppeteer` v2.4 owns `LiveBrowserSession`, the canonical transport-neutral live browser contracts, and bounded CDP frame acknowledgement flow.
6
+ - Tests import `@git.zone/tstest/tapbundle`; browser tests use the `.chromium.ts` suffix.
7
+ - The Node.js entry requires Node.js 22.12 or newer. This repository uses pnpm 11.20 for development and release tooling.
10
8
  - Puppeteer `page.screenshot({ encoding: 'binary' })` returns `Uint8Array`, not `Buffer` - wrap with `Buffer.from()`
11
9
 
12
10
  ## Build
13
- - `pnpm build` uses `tsbuild --web`
14
- - `pnpm test` uses `tstest test/ --web`
15
- - No ts_web directory exists in this project
16
- - Duplicate dayjs versions in transitive deps cause build errors; fix with `pnpm dedupe`
11
+ - `pnpm run build` uses `tsbuild tsfolders` and emits both `dist_ts` and `dist_ts_web`.
12
+ - `@push.rocks/smartbrowser/web` must remain runtime-isolated from Puppeteer, SmartPDF, Buffer, and Node.js built-ins. Only type imports from SmartPuppeteer are allowed.
13
+ - `pnpm test` runs Node and Chromium files through tstest 4.
14
+
15
+ ## Canvas Renderer Invariants
16
+ - The client facade is transport-neutral. Authentication, authorization, binary wire encoding, session ownership, and egress policy belong to the consuming adapter.
17
+ - Input always carries the identity of the actually displayed frame, never merely the newest state event.
18
+ - Cached state may lag a new frame generation. A state identity ahead of the displayed frame invalidates it; same-identity metadata updates do not.
19
+ - One frame may decode while only the newest subsequent frame waits. Active-run frames must pass full static validation and then have a sequence strictly above the per-run high-water value. Duplicate and out-of-order frames suspend without acknowledgement; resume resets the high-water value.
20
+ - The renderer makes at most one acknowledgement request for each valid drawn, stale, superseded, or decode-failed frame while its run remains active. Interrupted and invalid-protocol frames do not start acknowledgement work. An acknowledgement that throws, rejects, or times out suspends the run; `{ accepted: false }` settles the local attempt and does not prove upstream retirement.
21
+ - Every asynchronous client method receives `ILiveBrowserCanvasOperationOptions` with a renderer-owned `AbortSignal`. Operation deadline, run suspension, and stop all abort the signal; adapters must propagate it through the underlying transport.
22
+ - Renderer starts, suspensions, resumes, and stops are serialized by run epoch. Suspension aborts owned work and drops state, frames, queued input, pressed state, and old-generation recovery. Resume creates a fresh epoch and requires newly read state plus a newly displayed frame before input.
23
+ - Native `createImageBitmap()` jobs are tracked outside per-run cleanup. A new start or resume waits for every prior raw decode to settle, and late bitmaps are closed after timeout or interruption. Start or resume can remain pending indefinitely if the browser never settles native decode work.
24
+ - Acknowledgement failures, input-release failures, capacity exhaustion, and client/decode timeouts suspend only the current run. Malformed, oversized, or inconsistent frame protocol and deterministic decode-integrity failures are also terminal to that run. Recovery is explicit through `resume()`; none of these paths retries automatically.
25
+ - Internal renderer ceilings are 16 pending acknowledgements; 12,288 per frame dimension and 8,294,400 frame pixels; 34,226,176 encoded bytes; and a 4,096 x 4,096 viewport, device scale factor 3, and 8,294,400 physical pixels.
26
+ - Repeated blur, visibility, and pointer-loss resets coalesce into one bounded reset operation.
27
+ - During an active run, pressed input is retained until release succeeds, with one retry for transient release failures. Input remains blocked while a release is unresolved. Suspension discards pressed state without dispatching releases into a later run.
28
+ - Resize uses a caller-supplied stable CSS element. Requests are latest-only and serialized; input is released before resizing and remains blocked until a frame meeting the target revision fence is drawn.
29
+ - Intrinsic canvas dimensions come from encoded frame dimensions. Pointer coordinates map to the frame's logical CSS viewport.
30
+ - Pointer and wheel listeners remain on the canvas. Keyboard and composition listeners use `focusTarget`, which defaults to the canvas. Call `insertText()` for text committed by an external IME or dedicated input control.
package/readme.md CHANGED
@@ -1,17 +1,21 @@
1
1
  # @push.rocks/smartbrowser
2
2
  A simplified Puppeteer wrapper for easy browser automation, PDF generation, screenshots, and page evaluation.
3
3
 
4
+ The package also provides an isolated browser-side entry at `@push.rocks/smartbrowser/web`. Its `LiveBrowserCanvasRenderer` displays SmartPuppeteer live-session frames in a canvas and maps local input back to transport-neutral browser commands without bundling Puppeteer or Node.js code into the web application.
5
+
6
+ ## Issue Reporting and Security
7
+
8
+ For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
9
+
4
10
  ## Install
5
11
 
6
- To install `@push.rocks/smartbrowser`, use the following command with your preferred package manager:
12
+ Install the package with pnpm:
7
13
 
8
14
  ```bash
9
- npm install @push.rocks/smartbrowser
10
- # or
11
- pnpm install @push.rocks/smartbrowser
15
+ pnpm add @push.rocks/smartbrowser
12
16
  ```
13
17
 
14
- This module works with Node.js and requires a Chromium-compatible browser available in the environment. It uses `@push.rocks/smartpuppeteer` under the hood, which automatically detects your environment and configures the browser accordingly (including CI/Docker scenarios).
18
+ The Node.js entry requires Node.js 22.12 or newer and a Chromium-compatible browser. It uses SmartPuppeteer 2.4, Puppeteer 25, and SmartPDF 5. SmartPuppeteer detects common local, CI, and container environments and configures Chromium accordingly.
15
19
 
16
20
  ## Usage
17
21
 
@@ -98,6 +102,86 @@ import { smartpuppeteer } from '@push.rocks/smartbrowser';
98
102
  const browser = await smartpuppeteer.getEnvAwareBrowserInstance();
99
103
  ```
100
104
 
105
+ ## Live Browser Canvas
106
+
107
+ Import the browser-only renderer from `@push.rocks/smartbrowser/web`. The Node.js root entry is intentionally separate and must not be imported into a frontend bundle.
108
+
109
+ The renderer receives a caller-provided `ILiveBrowserCanvasClient`. An application adapter implements that interface using its authenticated transport and keeps the latest `ILiveBrowserState` available through `getState()`. The adapter must emit frame events with strictly increasing `frame.sequence` values for each `onEvent()` subscription/renderer run. SmartBrowser does not prescribe TypedSocket, WebSocket framing, base64 conversion, authentication, authorization, or session ownership.
110
+
111
+ ```typescript
112
+ import {
113
+ LiveBrowserCanvasRenderer,
114
+ type ILiveBrowserCanvasClient,
115
+ } from '@push.rocks/smartbrowser/web';
116
+
117
+ export async function mountLiveBrowser(client: ILiveBrowserCanvasClient) {
118
+ const viewport = document.querySelector<HTMLElement>('[data-live-browser-viewport]')!;
119
+ const canvas = viewport.querySelector<HTMLCanvasElement>('canvas')!;
120
+
121
+ const renderer = new LiveBrowserCanvasRenderer({
122
+ canvas,
123
+ client,
124
+ // Observe a stable CSS-sized element, not the canvas backing bitmap.
125
+ resizeTarget: viewport,
126
+ onError: (error) => console.error(error.code, error.message),
127
+ });
128
+
129
+ await renderer.start();
130
+ return async () => {
131
+ // Stop the renderer before closing its transport so cancellation reaches the adapter.
132
+ await renderer.stop();
133
+ };
134
+ }
135
+ ```
136
+
137
+ A minimal host keeps CSS sizing independent from the canvas's encoded backing dimensions:
138
+
139
+ ```html
140
+ <div data-live-browser-viewport style="width: 100%; height: 600px; overflow: hidden">
141
+ <canvas style="display: block; width: 100%; height: 100%"></canvas>
142
+ </div>
143
+ ```
144
+
145
+ `ILiveBrowserCanvasClient` exposes the renderer-facing subset of the canonical SmartPuppeteer live-session API:
146
+
147
+ - Cached state and events: `getState()` and `onEvent()`
148
+ - Frame flow control: `acknowledgeFrame()`
149
+ - Viewport synchronization: `setViewport()`
150
+ - Input: `dispatchMouse()`, `dispatchWheel()`, `dispatchKey()`, and `insertText()`
151
+
152
+ Every asynchronous client method receives a required second `ILiveBrowserCanvasOperationOptions` argument containing `signal: AbortSignal`. Adapters must pass that signal through to their transport operation and reject promptly when it aborts. The renderer aborts it at the operation deadline and when the current run is suspended or stopped. There is no compatibility path for adapters that omit cancellation.
153
+
154
+ The renderer keeps at most one frame decoding and one newest frame queued. For an active run it validates the complete static frame protocol before requiring `frame.sequence` to be strictly greater than that run's high-water sequence. Duplicate or out-of-order frames are terminal `frame_render_failed` protocol errors and are not acknowledged. A resumed run creates a new subscription and resets the high-water sequence by design.
155
+
156
+ The renderer makes one acknowledgement attempt after a valid frame is drawn, deliberately dropped, found stale, superseded, or fails decoding while its run remains active. SmartPuppeteer may fulfill an acknowledgement with `{ accepted: false }` for stale, retired, duplicate, or identity-mismatched frames. That result settles the renderer's local attempt without suspending or retrying, and it does not prove upstream retirement. Only an acknowledgement operation that throws, rejects, or times out suspends the run; reaching acknowledgement capacity does the same. Input identity always comes from the frame actually displayed, so tab, generation, and viewport changes block stale clicks and keystrokes. Encoded `frame.width` and `frame.height` set the canvas backing bitmap, while pointer coordinates map through the displayed canvas rectangle into the frame's logical CSS viewport.
157
+
158
+ Call `suspend()` when the adapter observes a transport interruption, then call `resume()` after the adapter has established a fresh transport. Suspension aborts active work, removes listeners, drops queued input and pressed-input recovery, and clears state and the displayed frame. `resume()` creates a new renderer run generation, re-subscribes to events, reads state again, and keeps input blocked until a new matching frame is displayed. Old input and release transitions are never replayed into the new generation. Operation timeouts request this same suspended lifecycle, so one transient acknowledgement timeout does not permanently poison the renderer instance.
159
+
160
+ Malformed frame identities, metadata, viewport values, formats, MIME pairings, dimensions, pixel areas, byte lengths, and deterministic image decode or dimension-integrity failures are terminal to the current run. Decoded dimensions are checked before supersession and currentness, so a mismatched decoded bitmap remains terminal even when a newer frame arrived during decoding. These failures are reported as `frame_render_failed` and require an explicit `resume()`; the renderer does not retry them automatically. The renderer only schedules rendering, acknowledgements, viewport synchronization, and direct input. Navigation scheduling remains the responsibility of the server runtime and application adapter.
161
+
162
+ The renderer's fixed internal protocol ceilings are 16 pending frame acknowledgement operations; frame dimensions of at most 12,288 on either axis and 8,294,400 pixels; encoded frame data of at most 34,226,176 bytes; and viewports of at most 4,096 x 4,096 CSS pixels, device scale factor 3, and 8,294,400 physical pixels (`width * height * deviceScaleFactor^2`).
163
+
164
+ Browser-native `createImageBitmap()` work is not abortable. After a wrapper timeout or run interruption, the renderer closes a bitmap that resolves late and waits for all prior raw decode jobs to settle before `start()` or `resume()` starts another run. Consequently, `start()` or `resume()` can remain pending indefinitely if the browser platform never settles a prior `createImageBitmap()` call.
165
+
166
+ Pointer and wheel input are captured from the canvas. Keyboard and best-effort `compositionend` input are captured from `focusTarget`, which defaults to the canvas and receives focus on pointer down. The renderer temporarily makes an unfocusable focus target focusable and restores its prior `tabindex` on stop. Applications with a dedicated text or IME control can call `renderer.insertText(text)` explicitly.
167
+
168
+ When `resizeTarget` is supplied, resize updates are deduplicated, serialized, and fenced by viewport revision. The target must have stable CSS dimensions that do not depend on `canvas.width` or `canvas.height`; this prevents intrinsic canvas updates from causing resize feedback.
169
+
170
+ `ILiveBrowserCanvasRendererOptions` supports:
171
+
172
+ - `canvas` and `client`: required rendering and transport-adapter dependencies.
173
+ - `focusTarget`: optional keyboard and composition event target; defaults to `canvas`.
174
+ - `resizeTarget`: optional stable CSS-sized element observed for remote viewport updates.
175
+ - `getDeviceScaleFactor`: optional scale provider; defaults to `window.devicePixelRatio` and is useful when the application controls remote scaling explicitly.
176
+ - `operationTimeoutMs`: deadline for client acknowledgements, viewport updates, and input operations; defaults to 10 seconds. Reaching it aborts the operation signal and suspends the run.
177
+ - `frameDecodeTimeoutMs`: image decode wrapper deadline; defaults to `operationTimeoutMs`. Reaching it suspends the run and closes the decoded bitmap if it completes late, but cannot force the browser's native decode job to settle.
178
+ - `onError`: receives typed `ILiveBrowserCanvasError` values without interrupting renderer cleanup.
179
+ - `onFrameRendered`: called after a current frame has been drawn.
180
+
181
+ The renderer exposes `start()`, `suspend()`, `resume()`, `stop()`, `insertText()`, `syncViewport()`, and the `isRunning` and `isSuspended` getters. `start()` begins a stopped renderer, while `resume()` is required for a suspended renderer. `syncViewport()` requests a fresh measurement of the configured `resizeTarget`; it is a no-op when no target is configured or the renderer is not running. An explicitly stopped renderer can be started again. The `/web` entry also exports `ILiveBrowserCanvasClient`, `ILiveBrowserCanvasOperationOptions`, `ILiveBrowserCanvasRendererOptions`, `ILiveBrowserCanvasError`, `TLiveBrowserCanvasErrorCode`, and the canonical SmartPuppeteer live-browser contract types.
182
+
183
+ `LiveBrowserCanvasRenderer` is not a security boundary. The application adapter must authenticate viewers, authorize control, restrict navigation, enforce browser-session ownership, and apply network/egress policy before forwarding commands. The renderer displays webpage viewport pixels only. It does not provide native Chrome UI, audio, extensions, file transfer, clipboard, camera, microphone, or touch emulation.
184
+
101
185
  ### Shutting Down
102
186
 
103
187
  Always stop the browser instance when done to free resources:
@@ -139,19 +223,21 @@ main();
139
223
 
140
224
  ## License and Legal Information
141
225
 
142
- This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
226
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](license.md) file.
143
227
 
144
228
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
145
229
 
146
230
  ### Trademarks
147
231
 
148
- This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
232
+ This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
233
+
234
+ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
149
235
 
150
236
  ### Company Information
151
237
 
152
- Task Venture Capital GmbH
153
- Registered at District court Bremen HRB 35230 HB, Germany
238
+ Task Venture Capital GmbH<br>
239
+ Registered at District Court Bremen HRB 35230 HB, Germany
154
240
 
155
- For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
241
+ For any legal inquiries or further information, please contact us via email at hello@task.vc.
156
242
 
157
243
  By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartbrowser',
6
- version: '2.0.11',
6
+ version: '4.0.0',
7
7
  description: 'A simplified Puppeteer wrapper for easy automation and testing tasks.'
8
8
  }
package/ts/index.ts CHANGED
@@ -6,8 +6,8 @@ import * as interfaces from './interfaces/index.js';
6
6
  * SmartBrowser
7
7
  */
8
8
  export class SmartBrowser {
9
- public headlessBrowser: plugins.smartpuppeteer.puppeteer.Browser;
10
- public smartpdf: plugins.smartpdf.SmartPdf;
9
+ public headlessBrowser!: plugins.smartpuppeteer.puppeteer.Browser;
10
+ public smartpdf: plugins.smartpdf.SmartPdf | null = null;
11
11
 
12
12
  /**
13
13
  * start the SmartBrowser instance
@@ -20,11 +20,12 @@ export class SmartBrowser {
20
20
  /**
21
21
  * ensure SmartPdf is initialized (lazy)
22
22
  */
23
- private async ensureSmartPdf() {
23
+ private async ensureSmartPdf(): Promise<plugins.smartpdf.SmartPdf> {
24
24
  if (!this.smartpdf) {
25
25
  this.smartpdf = new plugins.smartpdf.SmartPdf();
26
26
  await this.smartpdf.start(this.headlessBrowser);
27
27
  }
28
+ return this.smartpdf;
28
29
  }
29
30
 
30
31
  /**
@@ -43,8 +44,8 @@ export class SmartBrowser {
43
44
  * @param urlArg
44
45
  */
45
46
  public async pdfFromPage(urlArg: string): Promise<plugins.smartpdf.IPdf> {
46
- await this.ensureSmartPdf();
47
- const result = await this.smartpdf.getFullWebsiteAsSinglePdf(urlArg);
47
+ const smartpdf = await this.ensureSmartPdf();
48
+ const result = await smartpdf.getFullWebsiteAsSinglePdf(urlArg);
48
49
  return result;
49
50
  }
50
51
 
@@ -90,4 +91,4 @@ export class SmartBrowser {
90
91
  }
91
92
 
92
93
  import { smartpuppeteer } from './smartbrowser.plugins.js';
93
- export { smartpuppeteer };
94
+ export { smartpuppeteer };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * autocreated commitinfo by @push.rocks/commitinfo
3
+ */
4
+ export const commitinfo = {
5
+ name: '@push.rocks/smartbrowser',
6
+ version: '4.0.0',
7
+ description: 'A simplified Puppeteer wrapper for easy automation and testing tasks.'
8
+ }