ewvjs 1.0.0 → 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.
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
  - 🖱️ **Context Menus**: Customizable native right-click context menus.
13
13
  - 📦 **Packaging**: Built-in CLI tool to package your app into a standalone executable.
14
14
  - 🔧 **Native Bindings**: High-performance C# bindings via `node-api-dotnet`.
15
- - 🖼️ **Customization**: Support for frameless windows, transparency, dark mode, and more.
15
+ - 🖼️ **Customization**: Support for frameless windows, transparency, vibrancy, and more.
16
16
 
17
17
  ## Installation
18
18
 
@@ -83,6 +83,17 @@ Creates a new WebView window.
83
83
  * `url` (string): The URL to load (http/https) or path to a local HTML file or HTML string.
84
84
  * `options` (object): Configuration options.
85
85
 
86
+ ### `start()`
87
+
88
+ Starts the application event loop. This keeps the Node.js process alive until all windows are closed.
89
+
90
+ ### `expose(name, callback)`
91
+
92
+ Exposes a Node.js function to the frontend.
93
+
94
+ * `name` (string): The name of the function as it will appear in `window.ewvjs.api`.
95
+ * `callback` (function): The Node.js function to execute. Can be async.
96
+
86
97
  ### Window Options
87
98
 
88
99
  ```typescript
@@ -137,7 +148,22 @@ Once a window is created, you can control it using the returned `Window` instanc
137
148
 
138
149
  ### Custom Context Menus
139
150
 
140
- Define native context menus using `on_context_menu`:
151
+ Define native context menus using `on_context_menu`. It should return an array of `ContextMenuItem` objects.
152
+
153
+ #### ContextMenuItem Interface
154
+
155
+ ```typescript
156
+ interface ContextMenuItem {
157
+ label?: string;
158
+ type?: 'normal' | 'separator' | 'checkbox' | 'submenu';
159
+ checked?: boolean;
160
+ enabled?: boolean;
161
+ submenu?: ContextMenuItem[];
162
+ click?: () => void;
163
+ }
164
+ ```
165
+
166
+ Example:
141
167
 
142
168
  ```javascript
143
169
  win.on_context_menu = (params) => {
@@ -149,19 +175,122 @@ win.on_context_menu = (params) => {
149
175
  };
150
176
  ```
151
177
 
152
- ## CLI & Packaging
178
+ ## CLI Reference
179
+
180
+ `ewvjs` provides a command-line interface for creating and packaging applications.
181
+
182
+ ### Installation
183
+
184
+ The CLI is included with the `ewvjs` package and can be run using `npx`:
185
+
186
+ ```bash
187
+ npx ewvjs <command> [options]
188
+ ```
189
+
190
+ ### Commands
191
+
192
+ #### `init` - Initialize a New Project
193
+
194
+ Create a new ewvjs project with a sample application structure.
195
+
196
+ **Usage:**
197
+ ```bash
198
+ npx ewvjs init [name]
199
+ ```
200
+
201
+ **Arguments:**
202
+ * `name` - Project name (default: `my-ewvjs-app`)
203
+
204
+ **Example:**
205
+ ```bash
206
+ npx ewvjs init my-awesome-app
207
+ cd my-awesome-app
208
+ npm install
209
+ npm start
210
+ ```
211
+
212
+ This creates:
213
+ * `package.json` - Project configuration with scripts
214
+ * `app.js` - Sample application with Node.js integration
215
+ * `assets/` - Directory for static assets
216
+ * `README.md` - Project documentation
217
+
218
+ ---
219
+
220
+ #### `package` - Package Application
153
221
 
154
- `ewvjs` comes with a CLI tool to package your application into a standalone executable.
222
+ Package your ewvjs application into a standalone executable.
155
223
 
224
+ **Usage:**
156
225
  ```bash
157
- npx ewvjs package app.js --output myapp.exe --icon icon.ico
226
+ npx ewvjs package <entry> [options]
158
227
  ```
159
228
 
229
+ **Arguments:**
230
+ * `entry` - Entry point JavaScript file (required, e.g., `app.js`)
231
+
160
232
  **Options:**
161
- * `--output, -o`: Output filename.
162
- * `--icon, -i`: Path to application icon (.ico).
163
- * `--assets, -a`: Directory of assets to copy.
164
- * `--target, -t`: Target platform (default: node18-win-x64).
233
+
234
+ | Option | Alias | Description | Default |
235
+ |--------|-------|-------------|---------|
236
+ | `--output <name>` | `-o` | Output executable name (without .exe) | `app` |
237
+ | `--name <name>` | `-n` | Application name | `My App` |
238
+ | `--icon <file>` | `-i` | Path to application icon (.ico file) | None |
239
+ | `--assets <dir>` | `-a` | Assets directory to include in package | `./assets` |
240
+ | `--target <target>` | `-t` | Target platform | `node18-win-x64` |
241
+ | `--modules <modules>` | `-m` | Additional node modules to bundle (comma-separated) | None |
242
+ | `--compress` | | Compress executable with UPX | `false` |
243
+ | `--no-native` | | Skip bundling native DLLs (if already included) | Includes by default |
244
+
245
+ **Examples:**
246
+
247
+ Basic packaging:
248
+ ```bash
249
+ npx ewvjs package app.js
250
+ ```
251
+
252
+ Full customization:
253
+ ```bash
254
+ npx ewvjs package app.js \
255
+ --output myapp \
256
+ --name "My Application" \
257
+ --icon icon.ico \
258
+ --assets ./public \
259
+ --modules axios,lodash \
260
+ --compress
261
+ ```
262
+
263
+ Package with custom target:
264
+ ```bash
265
+ npx ewvjs package app.js -o myapp -t node20-win-x64
266
+ ```
267
+
268
+ **Output:**
269
+
270
+ The packaged application will be created in the `dist/` directory with:
271
+ * `<output>.exe` - Standalone executable
272
+ * Native WebView2 dependencies (unless `--no-native` is used)
273
+ * Bundled assets from the specified directory
274
+
275
+ **Notes:**
276
+ * Icon file must be in `.ico` format
277
+ * Additional modules should be listed without spaces: `axios,lodash,express`
278
+ * The `--compress` option requires UPX to be installed and available in PATH
279
+ * Default target `node18-win-x64` works with Node.js 18+ on 64-bit Windows
280
+
281
+ ### Getting Help
282
+
283
+ Display available commands and options:
284
+ ```bash
285
+ npx ewvjs --help
286
+ npx ewvjs package --help
287
+ npx ewvjs init --help
288
+ ```
289
+
290
+ Display version:
291
+ ```bash
292
+ npx ewvjs --version
293
+ ```
165
294
 
166
295
  ## License
167
296
 
package/dist/webview.d.ts CHANGED
@@ -9,6 +9,7 @@ export declare class WebView {
9
9
  private _startPromise;
10
10
  private _resolveStart;
11
11
  private _heartbeat;
12
+ private _resolveOnce;
12
13
  constructor();
13
14
  create_window(title: string, url_or_html?: string, options?: Partial<WindowOptions>): Window;
14
15
  start(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"webview.d.ts","sourceRoot":"","sources":["../src/webview.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,qBAAa,OAAO;IAChB,QAAQ,EAAE,GAAG,CAAC;IACd,iBAAiB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAM;IACpD,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAA+B;;IAUjD,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,MAAW,EAAE,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,MAAM;IAgB9F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B,OAAO,CAAC,QAAQ;IAgBhB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAIpC,eAAe,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,OAAO,CAAC,mBAAmB;CA2B9B"}
1
+ {"version":3,"file":"webview.d.ts","sourceRoot":"","sources":["../src/webview.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,qBAAa,OAAO;IAChB,QAAQ,EAAE,GAAG,CAAC;IACd,iBAAiB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAM;IACpD,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,YAAY,CAAkB;;IAUtC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,MAAW,EAAE,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,MAAM;IAgB9F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B,OAAO,CAAC,QAAQ;IAkBhB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI;IAIpC,eAAe,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,OAAO,CAAC,mBAAmB;CA2B9B"}
package/dist/webview.js CHANGED
@@ -19,6 +19,7 @@ class WebView {
19
19
  this._startPromise = null;
20
20
  this._resolveStart = null;
21
21
  this._heartbeat = null;
22
+ this._resolveOnce = false;
22
23
  if (process.platform === 'win32') {
23
24
  this.platform = new windows_1.WindowsPlatform();
24
25
  }
@@ -57,12 +58,15 @@ class WebView {
57
58
  }
58
59
  if (this._resolveStart) {
59
60
  this._resolveStart();
61
+ this._resolveOnce = true;
60
62
  this._resolveStart = null;
61
63
  }
62
64
  // Force exit after a short delay to ensure cleanup completes
63
- setTimeout(() => {
64
- process.exit(0);
65
- }, 100);
65
+ if (this._resolveOnce) {
66
+ setTimeout(() => {
67
+ process.exit(0);
68
+ }, 100);
69
+ }
66
70
  }
67
71
  expose(name, func) {
68
72
  this.exposed_functions[name] = func;
package/dist/window.d.ts CHANGED
@@ -7,11 +7,13 @@ export declare class Window {
7
7
  private _resolveClosed;
8
8
  private _menuCallbacks;
9
9
  private _exposedFunctions;
10
+ private _isClosed;
10
11
  on_context_menu: (items: any[]) => ContextMenuItem[] | null | Promise<ContextMenuItem[] | null>;
11
12
  constructor(platform: any, options: WindowOptions, exposedFunctions: {
12
13
  [key: string]: Function;
13
14
  });
14
15
  get closed(): Promise<void>;
16
+ get is_closed(): boolean;
15
17
  run(): Promise<any>;
16
18
  private _call;
17
19
  evaluate_js(script: string): Promise<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../src/window.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGzD,qBAAa,MAAM;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,aAAa,CAAC;IAEvB,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,iBAAiB,CAA8B;IAEvD,eAAe,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,eAAe,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAc;gBAEjG,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE;IAiBhG,IAAI,MAAM,kBAET;IAEK,GAAG;YAkBK,KAAK;IAgBb,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAItC,KAAK;IAIL,OAAO;IAKP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,IAAI;IAGJ,OAAO;IACP,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAGrC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIpC,WAAW;IACX,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAGhC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAIzB,YAAY;IACZ,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAIjC,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAK5B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAM7B,QAAQ,CAAC,KAAK,EAAE,MAAM;IAGtB,SAAS,CAAC,KAAK,EAAE,MAAM;IAKvB,aAAa;IACb,aAAa;IAGb,OAAO,CAAC,QAAQ,EAAE,MAAM;IAKxB,WAAW;IACX,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,EAAE,IAAI,GAAE,MAAY;IAG/E,aAAa;YAEL,WAAW;IAqCzB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,gBAAgB;YAOV,kBAAkB;YAUlB,sBAAsB;YAmBtB,oBAAoB;YAMpB,kBAAkB;IAMhC,OAAO,CAAC,YAAY;CAkBvB"}
1
+ {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../src/window.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGzD,qBAAa,MAAM;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,OAAO,EAAE,aAAa,CAAC;IAEvB,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,SAAS,CAAkB;IAEnC,eAAe,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,eAAe,EAAE,GAAG,IAAI,GAAG,OAAO,CAAC,eAAe,EAAE,GAAG,IAAI,CAAC,CAAc;gBAEjG,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE;IAiBhG,IAAI,MAAM,kBAET;IAED,IAAI,SAAS,YAEZ;IAEK,GAAG;YAkBK,KAAK;IA+Bb,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIzC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAItC,KAAK;IAQL,OAAO;IAKP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,IAAI;IAGJ,OAAO;IACP,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAGrC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIpC,WAAW;IACX,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAGhC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAIzB,YAAY;IACZ,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAIjC,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAK5B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAM7B,QAAQ,CAAC,KAAK,EAAE,MAAM;IAGtB,SAAS,CAAC,KAAK,EAAE,MAAM;IAKvB,aAAa;IACb,aAAa;IAGb,OAAO,CAAC,QAAQ,EAAE,MAAM;IAKxB,WAAW;IACX,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAW,EAAE,IAAI,GAAE,MAAY;IAG/E,aAAa;YAEL,WAAW;IAsCzB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,gBAAgB;YAOV,kBAAkB;YAUlB,sBAAsB;YAmBtB,oBAAoB;YAMpB,kBAAkB;IAMhC,OAAO,CAAC,YAAY;CAkBvB"}
package/dist/window.js CHANGED
@@ -14,6 +14,7 @@ const utils_1 = require("./utils");
14
14
  class Window {
15
15
  constructor(platform, options, exposedFunctions) {
16
16
  this._menuCallbacks = new Map();
17
+ this._isClosed = false;
17
18
  this.on_context_menu = () => null;
18
19
  this.platform = platform;
19
20
  this.options = Object.assign({}, options);
@@ -32,6 +33,9 @@ class Window {
32
33
  get closed() {
33
34
  return this._closedPromise;
34
35
  }
36
+ get is_closed() {
37
+ return this._isClosed;
38
+ }
35
39
  run() {
36
40
  return __awaiter(this, void 0, void 0, function* () {
37
41
  this.controller = yield this.platform.createWindow(this.options);
@@ -50,16 +54,31 @@ class Window {
50
54
  }
51
55
  _call(method_1) {
52
56
  return __awaiter(this, arguments, void 0, function* (method, payload = null) {
57
+ if (this._isClosed) {
58
+ console.warn(`Cannot call ${method}: Window is closed`);
59
+ return null;
60
+ }
53
61
  if (!this.controller || !this.controller[method]) {
54
62
  throw new Error(`Window not running or ${method} not supported`);
55
63
  }
56
- const result = this.controller[method](payload);
57
- // Check if method returns a Promise (node-api-dotnet JSCallback style)
58
- if (result && typeof result.then === 'function') {
59
- return result;
64
+ try {
65
+ const result = this.controller[method](payload);
66
+ // Check if method returns a Promise (node-api-dotnet JSCallback style)
67
+ if (result && typeof result.then === 'function') {
68
+ return result;
69
+ }
70
+ else {
71
+ return result;
72
+ }
60
73
  }
61
- else {
62
- return result;
74
+ catch (err) {
75
+ // If window was closed mid-operation, mark as closed and return null
76
+ if (err && err.message && err.message.includes('Window not initialized')) {
77
+ this._isClosed = true;
78
+ console.warn(`Window was closed during ${method} call`);
79
+ return null;
80
+ }
81
+ throw err;
63
82
  }
64
83
  });
65
84
  }
@@ -76,7 +95,12 @@ class Window {
76
95
  }
77
96
  close() {
78
97
  return __awaiter(this, void 0, void 0, function* () {
79
- return this._call('close');
98
+ if (this._isClosed)
99
+ return;
100
+ this._isClosed = true;
101
+ const result = yield this._call('close');
102
+ this._resolveClosed();
103
+ return result;
80
104
  });
81
105
  }
82
106
  destroy() {
@@ -201,6 +225,7 @@ class Window {
201
225
  const params = this._parseParams(rawParams);
202
226
  // Handle special messages
203
227
  if (funcName === 'closed') {
228
+ this._isClosed = true;
204
229
  this._resolveClosed();
205
230
  return null;
206
231
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ewvjs",
3
- "version": "1.0.0",
4
- "description": "Embedded WebView for JavaScript - Windows WebView2 bindings for Node.js",
3
+ "version": "1.0.1",
4
+ "description": "Embedded WebView for JavaScript - Edge WebView2 bindings for Node.js",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "bin": {
@@ -39,19 +39,23 @@
39
39
  ],
40
40
  "author": "miukyo",
41
41
  "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/miukyo/ewvjs"
45
+ },
42
46
  "type": "commonjs",
43
47
  "os": [
44
48
  "win32"
45
49
  ],
46
50
  "devDependencies": {
47
51
  "@types/node": "^25.2.0",
48
- "@yao-pkg/pkg": "^6.12.0",
49
52
  "typescript": "^5.9.3"
50
53
  },
51
54
  "dependencies": {
55
+ "@yao-pkg/pkg": "^6.12.0",
52
56
  "archiver": "^7.0.1",
53
57
  "commander": "^12.1.0",
54
58
  "node-api-dotnet": "^0.9.19",
55
59
  "resedit": "^2.0.2"
56
60
  }
57
- }
61
+ }