electron-snapora 1.0.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.es.md +79 -0
  4. package/README.ja.md +79 -0
  5. package/README.ko.md +79 -0
  6. package/README.md +392 -0
  7. package/README.zh-CN.md +79 -0
  8. package/dist/core/index.cjs +184 -0
  9. package/dist/core/index.cjs.map +1 -0
  10. package/dist/core/index.d.cts +97 -0
  11. package/dist/core/index.d.ts +97 -0
  12. package/dist/core/index.mjs +150 -0
  13. package/dist/core/index.mjs.map +1 -0
  14. package/dist/main/index.cjs +1637 -0
  15. package/dist/main/index.cjs.map +1 -0
  16. package/dist/main/index.d.cts +283 -0
  17. package/dist/main/index.d.ts +283 -0
  18. package/dist/main/index.mjs +1599 -0
  19. package/dist/main/index.mjs.map +1 -0
  20. package/dist/messages-DYY0MpGh.d.ts +76 -0
  21. package/dist/messages-ifub9bae.d.cts +76 -0
  22. package/dist/overlay/assets/index-7dVRGn83.css +1 -0
  23. package/dist/overlay/assets/index-CJf5iC1U.js +2 -0
  24. package/dist/overlay/assets/index-CJf5iC1U.js.map +1 -0
  25. package/dist/overlay/index.html +316 -0
  26. package/dist/overlay/preload.cjs +97 -0
  27. package/dist/overlay/preload.cjs.map +1 -0
  28. package/dist/overlay/preload.d.cts +16 -0
  29. package/dist/overlay/preload.d.ts +16 -0
  30. package/dist/overlay/preload.mjs +80 -0
  31. package/dist/overlay/preload.mjs.map +1 -0
  32. package/dist/preload/auto.cjs +24 -0
  33. package/dist/preload/auto.cjs.map +1 -0
  34. package/dist/preload/auto.d.cts +2 -0
  35. package/dist/preload/auto.d.ts +2 -0
  36. package/dist/preload/auto.mjs +22 -0
  37. package/dist/preload/auto.mjs.map +1 -0
  38. package/dist/preload/index.cjs +46 -0
  39. package/dist/preload/index.cjs.map +1 -0
  40. package/dist/preload/index.d.cts +18 -0
  41. package/dist/preload/index.d.ts +18 -0
  42. package/dist/preload/index.mjs +19 -0
  43. package/dist/preload/index.mjs.map +1 -0
  44. package/dist/types/index.cjs +19 -0
  45. package/dist/types/index.cjs.map +1 -0
  46. package/dist/types/index.d.cts +92 -0
  47. package/dist/types/index.d.ts +92 -0
  48. package/dist/types/index.mjs +1 -0
  49. package/dist/types/index.mjs.map +1 -0
  50. package/package.json +158 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.0.1] - 2026-08-20
6
+
7
+ ### Added
8
+
9
+ - Reusable Electron screenshot lifecycle with an isolated Overlay and typed IPC.
10
+ - Region selection, six annotation tools, undo/redo, PNG export, clipboard copy, and native save output.
11
+ - ESM/CommonJS entry points and bundled Preloads.
12
+ - One-call `setupElectronSnapora()` integration and a task-oriented README quick start.
13
+ - English, Simplified Chinese, Japanese, Korean, and Spanish documentation entry points.
14
+
15
+ ### Security
16
+
17
+ - Top-level sender authorization, strict IPC validation, resource limits, and isolated Overlay execution.
18
+
19
+ ### Compatibility
20
+
21
+ - Node.js 20 or newer and Electron 42–43.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 electron-tools contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.es.md ADDED
@@ -0,0 +1,79 @@
1
+ # electron-snapora — Capturas y anotaciones para Electron
2
+
3
+ [English](https://github.com/electron-tools/electron-snapora/blob/main/README.md) | [简体中文](https://github.com/electron-tools/electron-snapora/blob/main/README.zh-CN.md) | [日本語](https://github.com/electron-tools/electron-snapora/blob/main/README.ja.md) | [한국어](https://github.com/electron-tools/electron-snapora/blob/main/README.ko.md) | Español
4
+
5
+ Añade captura por región, selección interactiva, anotaciones, copia al portapapeles y exportación PNG a aplicaciones Electron.
6
+
7
+ ## Funciones
8
+
9
+ - Captura de regiones rectangulares mediante una superposición interactiva.
10
+ - Anotaciones con rectángulos, elipses, flechas, pincel, texto y mosaico.
11
+ - Deshacer, rehacer, copiar al portapapeles y guardar PNG de forma nativa.
12
+ - Compatible con TypeScript, ESM y CommonJS.
13
+ - Sin complementos nativos ni compilación posterior a la instalación.
14
+
15
+ ## Inicio rápido
16
+
17
+ Requisitos: Node.js 20 o posterior y Electron `>=42 <44`.
18
+
19
+ ### 1. Instalar
20
+
21
+ ```bash
22
+ npm install electron-snapora
23
+ ```
24
+
25
+ Mantén el paquete en las `dependencies` de producción de la aplicación.
26
+
27
+ ### 2. Configurar el proceso principal
28
+
29
+ ```ts
30
+ import { app, BrowserWindow, ipcMain } from 'electron';
31
+ import { setupElectronSnapora } from 'electron-snapora/main';
32
+
33
+ app.whenReady().then(() => {
34
+ const snapora = setupElectronSnapora({ ipcMain });
35
+ const mainWindow = new BrowserWindow({
36
+ webPreferences: {
37
+ preload: snapora.preloadPath,
38
+ contextIsolation: true,
39
+ sandbox: true,
40
+ },
41
+ });
42
+
43
+ mainWindow.loadFile('index.html');
44
+ app.once('before-quit', snapora.unregister);
45
+ });
46
+ ```
47
+
48
+ ### 3. Capturar desde el Renderer
49
+
50
+ ```ts
51
+ const result = await window.electronSnapora.capture({ display: 'cursor' });
52
+
53
+ if (result.status === 'completed') {
54
+ console.log(result.data, result.bounds, result.output);
55
+ }
56
+ ```
57
+
58
+ `result.data` contiene los bytes PNG. Una cancelación devuelve `cancelled` y un error devuelve `failed`.
59
+
60
+ ## Aplicaciones con un Preload existente
61
+
62
+ Expón la API desde el Preload de la aplicación y empaqueta ese Preload con la herramienta de compilación del host.
63
+
64
+ ```ts
65
+ import { contextBridge, ipcRenderer } from 'electron';
66
+ import { exposeScreenshotApi } from 'electron-snapora/preload';
67
+
68
+ exposeScreenshotApi({ contextBridge, ipcRenderer });
69
+ ```
70
+
71
+ ## Empaquetado
72
+
73
+ Al empaquetar el proceso principal de Electron, mantén `electron-snapora` como external y como dependencia de producción. Así se instalarán los archivos HTML, CSS y Preload del Overlay junto con la aplicación.
74
+
75
+ Consulta la [documentación completa en inglés](https://github.com/electron-tools/electron-snapora/blob/main/README.md) para temas, localización, validación del origen IPC, cola de concurrencia, diagnóstico y configuración de empaquetadores.
76
+
77
+ Repositorio: [github.com/electron-tools/electron-snapora](https://github.com/electron-tools/electron-snapora)
78
+
79
+ Licencia: [MIT](https://github.com/electron-tools/electron-snapora/blob/main/LICENSE)
package/README.ja.md ADDED
@@ -0,0 +1,79 @@
1
+ # electron-snapora — Electron向けスクリーンショット・注釈ツール
2
+
3
+ [English](https://github.com/electron-tools/electron-snapora/blob/main/README.md) | [简体中文](https://github.com/electron-tools/electron-snapora/blob/main/README.zh-CN.md) | 日本語 | [한국어](https://github.com/electron-tools/electron-snapora/blob/main/README.ko.md) | [Español](https://github.com/electron-tools/electron-snapora/blob/main/README.es.md)
4
+
5
+ Electronアプリに範囲キャプチャ、インタラクティブな選択、画像注釈、クリップボードへのコピー、PNG保存を追加します。
6
+
7
+ ## 機能
8
+
9
+ - 矩形範囲のキャプチャとインタラクティブなオーバーレイ。
10
+ - 四角形、楕円、矢印、ブラシ、テキスト、モザイク注釈。
11
+ - 元に戻す、やり直し、クリップボードへのコピー、ネイティブPNG保存。
12
+ - TypeScript、ESM、CommonJSをサポート。
13
+ - ネイティブアドオンやインストール後のコンパイルは不要。
14
+
15
+ ## クイックスタート
16
+
17
+ 要件:Node.js 20以降、Electron `>=42 <44`。
18
+
19
+ ### 1. インストール
20
+
21
+ ```bash
22
+ npm install electron-snapora
23
+ ```
24
+
25
+ 本パッケージは本番用の `dependencies` に含めてください。
26
+
27
+ ### 2. メインプロセスを設定
28
+
29
+ ```ts
30
+ import { app, BrowserWindow, ipcMain } from 'electron';
31
+ import { setupElectronSnapora } from 'electron-snapora/main';
32
+
33
+ app.whenReady().then(() => {
34
+ const snapora = setupElectronSnapora({ ipcMain });
35
+ const mainWindow = new BrowserWindow({
36
+ webPreferences: {
37
+ preload: snapora.preloadPath,
38
+ contextIsolation: true,
39
+ sandbox: true,
40
+ },
41
+ });
42
+
43
+ mainWindow.loadFile('index.html');
44
+ app.once('before-quit', snapora.unregister);
45
+ });
46
+ ```
47
+
48
+ ### 3. Rendererからキャプチャ
49
+
50
+ ```ts
51
+ const result = await window.electronSnapora.capture({ display: 'cursor' });
52
+
53
+ if (result.status === 'completed') {
54
+ console.log(result.data, result.bounds, result.output);
55
+ }
56
+ ```
57
+
58
+ `result.data` はPNGのバイトデータです。キャンセル時は `cancelled`、失敗時は `failed` が返ります。
59
+
60
+ ## 既存のPreloadを使用する場合
61
+
62
+ アプリ独自のPreloadからAPIを公開し、そのPreloadをホスト側のビルドツールでバンドルしてください。
63
+
64
+ ```ts
65
+ import { contextBridge, ipcRenderer } from 'electron';
66
+ import { exposeScreenshotApi } from 'electron-snapora/preload';
67
+
68
+ exposeScreenshotApi({ contextBridge, ipcRenderer });
69
+ ```
70
+
71
+ ## パッケージング
72
+
73
+ Electronのメインプロセスをバンドルする際は `electron-snapora` をexternalにし、本番用依存関係に含めてください。これによりOverlayのHTML、CSS、Preloadファイルがアプリに同梱されます。
74
+
75
+ テーマ、ローカライズ、IPC送信元の検証、同時実行キュー、診断、各種バンドラー設定については[英語の完全版ドキュメント](https://github.com/electron-tools/electron-snapora/blob/main/README.md)を参照してください。
76
+
77
+ リポジトリ:[github.com/electron-tools/electron-snapora](https://github.com/electron-tools/electron-snapora)
78
+
79
+ ライセンス:[MIT](https://github.com/electron-tools/electron-snapora/blob/main/LICENSE)
package/README.ko.md ADDED
@@ -0,0 +1,79 @@
1
+ # electron-snapora — Electron 스크린샷 및 주석 도구
2
+
3
+ [English](https://github.com/electron-tools/electron-snapora/blob/main/README.md) | [简体中文](https://github.com/electron-tools/electron-snapora/blob/main/README.zh-CN.md) | [日本語](https://github.com/electron-tools/electron-snapora/blob/main/README.ja.md) | 한국어 | [Español](https://github.com/electron-tools/electron-snapora/blob/main/README.es.md)
4
+
5
+ Electron 애플리케이션에 영역 캡처, 대화형 선택 영역, 이미지 주석, 클립보드 복사 및 PNG 저장 기능을 추가합니다.
6
+
7
+ ## 기능
8
+
9
+ - 사각형 영역 캡처와 대화형 오버레이.
10
+ - 사각형, 타원, 화살표, 브러시, 텍스트 및 모자이크 주석.
11
+ - 실행 취소, 다시 실행, 클립보드 복사 및 네이티브 PNG 저장.
12
+ - TypeScript, ESM 및 CommonJS 지원.
13
+ - 네이티브 애드온과 설치 후 컴파일이 필요하지 않음.
14
+
15
+ ## 빠른 시작
16
+
17
+ 요구 사항: Node.js 20 이상, Electron `>=42 <44`.
18
+
19
+ ### 1. 설치
20
+
21
+ ```bash
22
+ npm install electron-snapora
23
+ ```
24
+
25
+ 이 패키지는 애플리케이션의 프로덕션 `dependencies`에 포함해야 합니다.
26
+
27
+ ### 2. 메인 프로세스 설정
28
+
29
+ ```ts
30
+ import { app, BrowserWindow, ipcMain } from 'electron';
31
+ import { setupElectronSnapora } from 'electron-snapora/main';
32
+
33
+ app.whenReady().then(() => {
34
+ const snapora = setupElectronSnapora({ ipcMain });
35
+ const mainWindow = new BrowserWindow({
36
+ webPreferences: {
37
+ preload: snapora.preloadPath,
38
+ contextIsolation: true,
39
+ sandbox: true,
40
+ },
41
+ });
42
+
43
+ mainWindow.loadFile('index.html');
44
+ app.once('before-quit', snapora.unregister);
45
+ });
46
+ ```
47
+
48
+ ### 3. Renderer에서 캡처
49
+
50
+ ```ts
51
+ const result = await window.electronSnapora.capture({ display: 'cursor' });
52
+
53
+ if (result.status === 'completed') {
54
+ console.log(result.data, result.bounds, result.output);
55
+ }
56
+ ```
57
+
58
+ `result.data`는 PNG 바이트 데이터입니다. 사용자가 취소하면 `cancelled`, 실패하면 `failed`가 반환됩니다.
59
+
60
+ ## 기존 Preload를 사용하는 애플리케이션
61
+
62
+ 애플리케이션의 Preload에서 API를 노출하고 해당 Preload를 호스트 빌드 도구로 번들링하세요.
63
+
64
+ ```ts
65
+ import { contextBridge, ipcRenderer } from 'electron';
66
+ import { exposeScreenshotApi } from 'electron-snapora/preload';
67
+
68
+ exposeScreenshotApi({ contextBridge, ipcRenderer });
69
+ ```
70
+
71
+ ## 패키징
72
+
73
+ Electron 메인 프로세스를 번들링할 때 `electron-snapora`를 external로 유지하고 프로덕션 의존성에 포함하세요. 그래야 Overlay HTML, CSS 및 Preload 파일이 애플리케이션과 함께 설치됩니다.
74
+
75
+ 테마, 현지화, IPC 발신자 검증, 동시 실행 큐, 진단 및 번들러 설정은 [영문 전체 문서](https://github.com/electron-tools/electron-snapora/blob/main/README.md)를 참조하세요.
76
+
77
+ 저장소: [github.com/electron-tools/electron-snapora](https://github.com/electron-tools/electron-snapora)
78
+
79
+ 라이선스: [MIT](https://github.com/electron-tools/electron-snapora/blob/main/LICENSE)
package/README.md ADDED
@@ -0,0 +1,392 @@
1
+ # electron-snapora — Electron screenshot and annotation toolkit
2
+
3
+ [English](https://github.com/electron-tools/electron-snapora/blob/main/README.md) | [简体中文](https://github.com/electron-tools/electron-snapora/blob/main/README.zh-CN.md) | [日本語](https://github.com/electron-tools/electron-snapora/blob/main/README.ja.md) | [한국어](https://github.com/electron-tools/electron-snapora/blob/main/README.ko.md) | [Español](https://github.com/electron-tools/electron-snapora/blob/main/README.es.md)
4
+
5
+ Add region screenshot capture, a snipping overlay, annotations, clipboard copy, and PNG export to Electron applications.
6
+
7
+ ## Features
8
+
9
+ - Electron screenshot and screen capture.
10
+ - Region capture with an interactive snipping overlay.
11
+ - Screenshot editing with rectangle, ellipse, arrow, brush, text, and mosaic annotations.
12
+ - Clipboard copy and native PNG save.
13
+ - TypeScript, ESM, and CommonJS support.
14
+
15
+ Repository: [github.com/electron-tools/electron-snapora](https://github.com/electron-tools/electron-snapora)
16
+
17
+ ## Quick start
18
+
19
+ Requirements: Node.js 20 or newer and Electron `>=42 <44`.
20
+
21
+ ### 1. Install
22
+
23
+ ```bash
24
+ npm install electron-snapora
25
+ ```
26
+
27
+ Keep the package in the application's production `dependencies`. It contains the screenshot UI and
28
+ Preload files needed by the packaged application.
29
+
30
+ ### 2. Set up the main process
31
+
32
+ `setupElectronSnapora()` creates the screenshot manager, registers IPC, and gives the window a
33
+ ready-to-use Preload path:
34
+
35
+ ```ts
36
+ import { app, BrowserWindow, ipcMain } from 'electron';
37
+ import { setupElectronSnapora } from 'electron-snapora/main';
38
+
39
+ app.whenReady().then(() => {
40
+ const snapora = setupElectronSnapora({ ipcMain });
41
+ const mainWindow = new BrowserWindow({
42
+ webPreferences: {
43
+ preload: snapora.preloadPath,
44
+ contextIsolation: true,
45
+ sandbox: true,
46
+ },
47
+ });
48
+
49
+ mainWindow.loadFile('index.html');
50
+ app.once('before-quit', snapora.unregister);
51
+ });
52
+ ```
53
+
54
+ That is the complete default integration. Keep `electron-snapora` external when bundling the Electron
55
+ main process so its packaged HTML, CSS, and Preload files remain beside the library entry point. See
56
+ [Bundling and packaging](#bundling-and-packaging) for electron-vite, Webpack, electron-builder, and
57
+ Forge examples.
58
+
59
+ ### 3. Capture from the renderer
60
+
61
+ ```ts
62
+ const result = await window.electronSnapora.capture({ display: 'cursor' });
63
+
64
+ if (result.status === 'completed') {
65
+ // PNG bytes for upload, preview, or other host application logic.
66
+ console.log(result.data, result.bounds, result.output);
67
+ }
68
+ ```
69
+
70
+ The screenshot overlay lets the user select a region, draw rectangles, ellipses, arrows, brush
71
+ strokes, text, or mosaic, then copy or save the final PNG. `Escape` cancels. The result is always one
72
+ of `completed`, `cancelled`, or `failed`, so callers do not need exception-based control flow for
73
+ normal user actions.
74
+
75
+ Cancel an active task from the same renderer with:
76
+
77
+ ```ts
78
+ await window.electronSnapora.cancel();
79
+ ```
80
+
81
+ For TypeScript, declare the injected renderer API once in the host application:
82
+
83
+ ```ts
84
+ import type { ScreenshotRendererApi } from 'electron-snapora/types';
85
+
86
+ declare global {
87
+ interface Window {
88
+ electronSnapora: ScreenshotRendererApi;
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## Applications with an existing Preload
94
+
95
+ Keep the main-process setup, ignore `snapora.preloadPath`, and expose the API from the application's
96
+ own bundled Preload:
97
+
98
+ ```ts
99
+ import { contextBridge, ipcRenderer } from 'electron';
100
+ import { exposeScreenshotApi } from 'electron-snapora/preload';
101
+
102
+ exposeScreenshotApi({ contextBridge, ipcRenderer });
103
+ ```
104
+
105
+ Sandboxed Preload scripts cannot load arbitrary npm modules at runtime, so an existing host Preload
106
+ must be bundled. Applications without an existing Preload should use the package-provided path from
107
+ the quick start and need no extra Preload configuration.
108
+
109
+ ## Custom page origins
110
+
111
+ For safety, screenshot IPC accepts only top-level pages loaded with `BrowserWindow.loadFile()` by
112
+ default and always rejects iframe calls. If the host uses a custom protocol or local development
113
+ server, allow only the exact trusted origins:
114
+
115
+ ```ts
116
+ const snapora = setupElectronSnapora({
117
+ ipcMain,
118
+ validateSender(event) {
119
+ const senderUrl = event.senderFrame?.url;
120
+ if (!senderUrl) return false;
121
+
122
+ const url = new URL(senderUrl);
123
+ return (
124
+ url.protocol === 'app:' ||
125
+ (process.env.NODE_ENV === 'development' && url.origin === 'http://localhost:5173')
126
+ );
127
+ },
128
+ });
129
+ ```
130
+
131
+ Snapora still enforces the top-level-frame rule. It also parses capture options again in the main
132
+ process and returns `INVALID_REQUEST` before screen capture for unknown or invalid values.
133
+
134
+ ## Package entry points
135
+
136
+ Most applications need only `electron-snapora/main` and the injected `window.electronSnapora` API.
137
+ The other entry points support custom Preloads and advanced integrations:
138
+
139
+ ```ts
140
+ import { setupElectronSnapora } from 'electron-snapora/main';
141
+ import { exposeScreenshotApi } from 'electron-snapora/preload';
142
+ import { normalizeRect } from 'electron-snapora/core';
143
+ ```
144
+
145
+ The default package has no native addon and no post-install compilation.
146
+
147
+ ## Advanced configuration
148
+
149
+ Pass manager settings through `setupElectronSnapora()` so the simple integration shape stays the
150
+ same as requirements grow.
151
+
152
+ ### Theme and localization
153
+
154
+ The overlay defaults to English (`en-US`) and a dark toolbar. A capture can select the built-in
155
+ Chinese locale, override individual messages, and provide semantic theme colors:
156
+
157
+ ```ts
158
+ await window.electronSnapora.capture({
159
+ locale: 'zh-CN',
160
+ messages: {
161
+ confirm: '复制到聊天框',
162
+ copied: '截图已复制',
163
+ },
164
+ theme: {
165
+ mode: 'light',
166
+ accentColor: '#6750a4',
167
+ accentForegroundColor: '#ffffff',
168
+ toolbarBackground: 'rgb(250 250 250 / 96%)',
169
+ toolbarForeground: '#1d1b20',
170
+ tooltipBackground: '#27272a',
171
+ warningColor: '#f59e0b',
172
+ },
173
+ });
174
+ ```
175
+
176
+ Message resolution is deterministic: English baseline, selected built-in locale, then host
177
+ overrides. This means a partial `messages` object always falls back to a complete accessible
178
+ label set. Unknown message or theme keys, empty messages, and unsupported modes are rejected at
179
+ the main-process IPC boundary.
180
+
181
+ Theme styling uses three layers: internal base colors, public semantic colors, and private
182
+ component aliases. `ScreenshotTheme` only changes semantic values, so applications do not depend
183
+ on overlay DOM or CSS class names. In addition to the example above it supports mask, toolbar
184
+ border/hover, tooltip foreground, destructive/warning actions, warning foreground, and
185
+ selection-handle colors.
186
+
187
+ ### Host policy injection
188
+
189
+ Applications with a custom capture source, storage policy, or overlay host can pass those
190
+ dependencies without changing the setup flow:
191
+
192
+ ```ts
193
+ const snapora = setupElectronSnapora({
194
+ ipcMain,
195
+ managerOptions: {
196
+ captureAdapter: myCaptureAdapter,
197
+ outputAdapter: myOutputAdapter,
198
+ createOverlay: (display) => myOverlayFactory.create(display),
199
+ overlayReadyTimeoutMs: 15_000,
200
+ },
201
+ });
202
+ ```
203
+
204
+ `captureAdapter`, `outputAdapter`, `createOverlay`, `overlayOptions`, and `ipcMain` are high-level
205
+ injection points. `runner` remains available only for applications that need to replace the entire
206
+ session lifecycle; when it is supplied, the other default-runner options are ignored.
207
+
208
+ Custom capture adapters may implement the optional synchronous
209
+ `resolveTargetDisplay(options)` method. When present, Snapora loads the still-hidden Overlay in
210
+ parallel with `capture()` and only primes or reveals it after the captured frame is ready. The
211
+ resolved display must match the first frame returned by the following `capture()` call. Adapters
212
+ that omit this method keep the compatible capture-then-load sequence.
213
+
214
+ Resource limits can be lowered per host application:
215
+
216
+ ```ts
217
+ const snapora = setupElectronSnapora({
218
+ ipcMain,
219
+ managerOptions: {
220
+ resourceLimits: {
221
+ maxCapturePixels: 32 * 1024 * 1024,
222
+ maxCaptureDataUrlBytes: 96 * 1024 * 1024,
223
+ maxOutputBytes: 32 * 1024 * 1024,
224
+ },
225
+ },
226
+ });
227
+ ```
228
+
229
+ Defaults allow 64 Mi pixels, a 192 MiB capture Data URL, and a 64 MiB PNG result. Absolute hard
230
+ ceilings are 128 Mi pixels / 256 MiB / 256 MiB. Invalid configuration fails during manager
231
+ construction; oversized capture adapters and Overlay output are rejected with
232
+ `RESOURCE_LIMIT_EXCEEDED` or `INVALID_REQUEST` before clipboard or disk processing.
233
+
234
+ ## Bundling and packaging
235
+
236
+ Keep `electron-snapora` in the application's production `dependencies` and externalize it from the
237
+ Electron main-process bundle. Its main entry locates sibling Overlay HTML, CSS, and Preload files
238
+ inside the installed package; inlining that entry changes `__dirname` and breaks the resource
239
+ relationship.
240
+
241
+ electron-vite 5 externalizes production dependencies by default. An explicit rule is useful when
242
+ the application overrides dependency handling:
243
+
244
+ ```ts
245
+ export default defineConfig({
246
+ main: {
247
+ build: {
248
+ rollupOptions: {
249
+ external: [/^electron-snapora(?:\/.*)?$/],
250
+ },
251
+ },
252
+ },
253
+ });
254
+ ```
255
+
256
+ Webpack applications should configure the main-process build similarly:
257
+
258
+ ```js
259
+ module.exports = {
260
+ target: 'electron-main',
261
+ externals: {
262
+ 'electron-snapora/main': 'commonjs electron-snapora/main',
263
+ },
264
+ };
265
+ ```
266
+
267
+ electron-builder can package the complete dependency inside ASAR; these JavaScript, HTML, and CSS
268
+ resources do not require `asarUnpack`. If a bundler inlines the package or packaging excludes part
269
+ of `dist`, resource resolution throws an `[electron-snapora] Packaged resource missing` error with
270
+ the expected path instead of waiting on a blank Overlay.
271
+
272
+ For Electron Forge, keep the package in `dependencies`; add the same external rule to the Forge
273
+ Vite or Webpack main-process config. Forge projects that use pnpm should use a hoisted
274
+ `node_modules` layout because Forge discovers production dependencies from the physical dependency
275
+ tree.
276
+
277
+ ### Published package contents
278
+
279
+ The npm package contains only the compiled ESM/CommonJS entry points, TypeScript declarations,
280
+ Preloads, Overlay HTML/CSS/JavaScript, package metadata, README, changelog, and license. Source files,
281
+ tests, demos, repository documentation, CI configuration, and release scripts are not published.
282
+
283
+ ## Support baseline
284
+
285
+ The npm peer range is intentionally limited to Electron `>=42 <44`. The package is built for a
286
+ Node.js 20 baseline and has passed the real capture/Overlay lifecycle on Windows 11 x64 with
287
+ Electron 42.8.0 and 43.3.0.
288
+
289
+ | Environment | Status |
290
+ | ------------------------------------------------ | ------------------------------------------------------- |
291
+ | Windows 11 x64, Electron 42.8/43.3 | Automated and manually exercised |
292
+ | Windows ARM64 | Pending hardware validation |
293
+ | macOS, Retina and signed app | Code/tests complete; signed hardware validation pending |
294
+ | Linux X11 / XWayland / native Wayland / PipeWire | Not yet declared supported |
295
+
296
+ Electron officially supports only its latest three stable major lines. This package does not claim
297
+ compatibility with an Electron version merely because installation succeeds; the peer range is
298
+ expanded only after its capture, Overlay, preload, and packaging matrix passes. Native Wayland is
299
+ especially not assumed equivalent to X11 because Electron documents limitations in its Screen API.
300
+
301
+ ### macOS permission
302
+
303
+ macOS 10.15 and later requires Screen Recording consent. When the operating system reports
304
+ `denied` or `restricted`, capture returns `PERMISSION_DENIED`; the user must enable the signed host
305
+ application under System Settings → Privacy & Security → Screen Recording and restart it. Test the
306
+ permission using the signed application identity, not only Electron launched from a terminal.
307
+
308
+ Add a screen-capture purpose string to the packaged host. For electron-builder:
309
+
310
+ ```json
311
+ {
312
+ "build": {
313
+ "mac": {
314
+ "hardenedRuntime": true,
315
+ "extendInfo": {
316
+ "NSScreenCaptureUsageDescription": "Capture a selected screen region for sharing."
317
+ }
318
+ }
319
+ }
320
+ }
321
+ ```
322
+
323
+ With `display: 'cursor'`, Snapora resolves the display under the pointer once at task start and keeps
324
+ that display ID through capture and Overlay creation. If the monitor is disconnected or its geometry
325
+ or scale changes during startup, the task fails with `DISPLAY_NOT_FOUND` and should be retried instead
326
+ of displaying a screenshot on the wrong monitor.
327
+
328
+ ### Lifecycle and concurrency
329
+
330
+ A `ScreenshotManager` always runs one global Overlay task at a time. Its default `reject` policy
331
+ keeps existing behavior: a second call immediately resolves with `CAPTURE_BUSY`. Applications with
332
+ multiple host windows can opt into a bounded FIFO queue:
333
+
334
+ ```ts
335
+ const snapora = setupElectronSnapora({
336
+ ipcMain,
337
+ managerOptions: {
338
+ busyPolicy: 'queue',
339
+ maxQueuedCaptures: 4,
340
+ },
341
+ });
342
+ ```
343
+
344
+ Only different host renderers are queued. A renderer cannot create a second active or queued task,
345
+ so repeated button clicks still return `CAPTURE_BUSY`; a full queue does the same. Cancelling a
346
+ renderer task or destroying that `WebContents` removes its queued request before an Overlay can be
347
+ opened. `queuedCaptureCount` exposes the current queue length for diagnostics.
348
+
349
+ Use one setup for one application-wide screenshot lane, or separate managers only when the
350
+ application intentionally supports independent capture lanes. `snapora.manager.queuedCaptureCount`
351
+ exposes the queue length, and `snapora.unregister()` cleans up IPC during shutdown or main-process
352
+ hot reload. Active-task completion, cancellation, and failure all advance the queue and release
353
+ Overlay listeners and windows.
354
+
355
+ ### Main-process diagnostics
356
+
357
+ Use the optional structured hook to feed application logs or performance telemetry:
358
+
359
+ ```ts
360
+ const snapora = setupElectronSnapora({
361
+ ipcMain,
362
+ managerOptions: {
363
+ onDiagnostic(event) {
364
+ logger.debug('electron-snapora', event);
365
+ },
366
+ },
367
+ });
368
+ ```
369
+
370
+ Events cover queue wait, complete session, capture, Overlay creation/loading/readiness, frame
371
+ preparation, and output. Start events carry a timestamp; completion, cancellation, and error events
372
+ also carry `durationMs`. Failures include the public error code and message. A missing packaged
373
+ Overlay resource additionally reports its label and resolved path in `context.missingResources`.
374
+
375
+ The hook runs only in the main process and accepts serializable scalar/array context values; no
376
+ `BrowserWindow`, `WebContents`, `NativeImage`, IPC event, or captured PNG is exposed. Exceptions
377
+ thrown by the application's logger are isolated and never change the screenshot result.
378
+
379
+ ### Error results
380
+
381
+ | Code | Meaning |
382
+ | ------------------------- | ---------------------------------------------------------------- |
383
+ | `CAPTURE_BUSY` | The lane, sender mutex, or configured queue capacity is busy. |
384
+ | `INVALID_REQUEST` | Host/Overlay IPC origin, options, or payload failed validation. |
385
+ | `RESOURCE_LIMIT_EXCEEDED` | Capture or PNG data exceeded a configured limit. |
386
+ | `PERMISSION_DENIED` | The OS denied screen capture permission. |
387
+ | `DISPLAY_NOT_FOUND` | The requested display or matching capture source is unavailable. |
388
+ | `CAPTURE_FAILED` | Electron could not produce a usable captured frame. |
389
+ | `OVERLAY_LOAD_FAILED` | Packaged resources, Renderer startup, or preparation failed. |
390
+ | `EXPORT_FAILED` | Clipboard, save dialog, PNG encoding, or file output failed. |
391
+ | `INVALID_RESULT` | The Overlay returned an invalid result or lifecycle message. |
392
+ | `UNSUPPORTED_PLATFORM` | The current OS/display protocol is explicitly unsupported. |