pear-electron 1.7.19 → 1.7.21

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
@@ -2,13 +2,22 @@
2
2
 
3
3
  > Pear User-Interface Library for Electron
4
4
 
5
- ## Installation
5
+ ## Installation <a name="installation"></a>
6
6
 
7
7
  ```sh
8
8
  npm install pear-electron
9
9
  ```
10
10
 
11
11
  ## Usage
12
+ Ensure the `package.json` `pear` configuration object contains a `pre` field pointing to `pear-electron/pre`.
13
+
14
+ ```js
15
+ {
16
+ "pear": {
17
+ "pre": "pear-electron/pre"
18
+ }
19
+ }
20
+ ```
12
21
 
13
22
  Instantiate a `pear-electron` runtime instance from a Pear Application's entrypoint JavaScript file:
14
23
 
@@ -29,117 +38,177 @@ Call `runtime.start` to open the UI.
29
38
 
30
39
  > NOTE: naming the import `Runtime` instead of `PearElectron` is intentional, for two reasons. The `pear-electron` import resolves to a runtime start library or a User Interface library depending on environment and using `Runtime` and `ui` as assigned names means switching out `pear-electron` with an equivalent alternative only involves changing the two `pear-electron` import specifiers.
31
40
 
32
- ## Initialization API
41
+ Given an `index.html` containing `<script src="./app.js"></script>` in `app.js` import `pear-electron` User Interface API:
42
+
43
+ ```js
44
+ import ui from 'pear-electron'
45
+
33
46
 
34
- ### `new Runtime() -> runtime`
47
+ ```
48
+
49
+ ## Application Configuration <a name="application-configuration"></a>
50
+
51
+ Set the [`pear.pre`](https://docs.pears.com/configuration#pear-pre) to `pear-electron/pre` (or ensure that it's imported at the top of any alternative pre script).
52
+
53
+
54
+ ```json
55
+ {
56
+ "pear": {
57
+ "pre": "pear-electron/pre"
58
+ }
59
+ }
60
+
61
+ ```
62
+
63
+ Prior to run from disk and prior to run from key, the `pear-electron/pre` script automatically adjusts application configuration to include runtime binary [`pear.assets`](https://docs.pears.com/configuration#pear-assets) as well as adding statically analyzed script tags as [`pear.stage.entrypoints`](https://docs.pears.com/configuration#pear-stage-entrypoints) from the [`pear.gui.main`](#pear-gui-main) HTML entrypoint.
64
+
65
+ The application `package.json` `pear` field can also define its own [`pear.assets`](https://docs.pears.com/configuration#pear-assets).
66
+
67
+ ## Initialization API <a name="initialization-api"></a>
68
+
69
+ ### `new Runtime() -> runtime` <a name="new-runtime"></a>
35
70
 
36
71
  Create the runtime instances with `new Runtime()`.
37
72
 
38
- ### `runtime.ready()`
73
+ ### `runtime.ready()` <a name="runtime-ready"></a>
39
74
 
40
75
  Prepare the runtime, runtime binaries for the runtime version may be bootstrapped peer-to-peer at this point. This only runs once per version and any prior bootstraps can be reused for subsequent versions where state hasn't changed. In a production scenario any bootstrapping would be performed in advance by the application distributable.
41
76
 
42
- ### `runtime.start(opts)`
77
+ ### `runtime.start(opts)` <a name="runtime-start"></a>
43
78
 
44
79
  Opens the UI.
45
80
 
46
81
  #### Options
47
82
 
48
- * `bridge` - An instance of `pear-bridge`.
83
+ * `bridge` - An instance of [`pear-bridge`](https://github.com/holepunchto/pear-bridge).
49
84
 
50
- ## User-Interface API
85
+ ## User-Interface API <a name="user-interface-api"></a>
51
86
 
52
- Inside the pear-electron runtime desktop application, pear-electron resolves to a UI control API.
87
+ Inside the `pear-electron` runtime desktop application, pear-electron resolves to a UI control API.
53
88
 
54
89
  **index.html**:
55
90
  ```html
56
- <script src="./app.js" type="module">
91
+ <script src="./app.js" type="module"><script>
57
92
  ```
58
93
 
59
94
  **app.js**:
60
95
  ```js
61
96
  import ui from 'pear-electron'
97
+ // do something with ui:
98
+ setTimeout(async () => { await ui.app.focus({ steal: true }) })
62
99
  ```
63
100
 
64
101
  > NOTE: naming the import `ui` instead of `PearElectron` is intentional, for two reasons. The `pear-electron` import resolves to a runtime start library or a User Interface library depending on environment and using `Runtime` and `ui` as assigned names means switching out `pear-electron` with an equivalent alternative only involves changing the two `pear-electron` import specifiers.
65
102
 
66
- ### `ui.app <Object>`
103
+ ### `ui.app <Object>` <a name="ui-app"></a>
67
104
 
68
105
  UI Application controls
69
106
 
70
- ### `const success = await app.focus()`
107
+ ### `const success = await ui.app.focus([options <Object>])` <a name="ui-app-focus"></a>
71
108
 
72
109
  Resolves to: `<Boolean>`
73
110
 
74
- Focus current view or window.
111
+ Foreground current view or window.
112
+
113
+ **Options**
114
+
115
+ * `steal` Default: `false` - focus input as well as foregrounding
75
116
 
76
- ### `const success = await app.blur()`
117
+ ### `const success = await ui.app.blur()` <a name="ui-app-blur"></a>
77
118
 
78
119
  Resolves to: `<Boolean>`
79
120
 
80
121
  Blur current view or window.
81
122
 
82
- ### `const success = await app.show()`
123
+ ### `const success = await ui.app.show()` <a name="ui-app-show"></a>
83
124
 
84
125
  Resolves to: `<Boolean>`
85
126
 
86
127
  Show current view or window.
87
128
 
88
- ### `const success = await app.hide()`
129
+ ### `const success = await ui.app.hide()` <a name="ui-app-hide"></a>
89
130
 
90
131
  Resolves to: `<Boolean>`
91
132
 
92
133
  Hide current view or window.
93
134
 
94
- ### `const sourceId = await app.getMediaSourceId()`
135
+ #### `const success = await ui.app.badge(count <Integer|null>)` <a name="ui-app-badge"></a>
95
136
 
96
- Get the sourceId of the current window or view.
137
+ Resolves to: `<Boolean>`
138
+
139
+ Set the badge number for the application on desktop for Linux & MacOS. Setting the `count` to `0` will hide the badge while `null` will display a plain dot on MacOS only.
140
+
141
+ Returns a `Boolean` promise for whether the call succeeded.
142
+
143
+ #### `const untray = await ui.app.tray(options <Object>[, listener <Function>])` <a name="ui-app-tray"></a>
144
+
145
+ Resolves to: `<Function>`
97
146
 
98
- **References**
147
+ Configure a tray icon for the application.
99
148
 
100
- * [win.getMediaSourceId()](const-sourceId--await-wingetMediaSourceId)
149
+ This method will return a promise which resolves to an `untray()` function for removing the tray.
101
150
 
151
+ The `listener` function is triggered whenever a menu item or the tray icon is clicked. It receives a single argument `key` that represents the menu item `key` that was clicked or the special value of `'click'` for when the menu icon itself was clicked. If no `listener` function is provided, a default listener will show the application window when triggered with `'click'` or `'show'` and quits with `'quit'`.
102
152
 
103
- ### `const success = await app.minimize()`
153
+ A Pear application should set `pear.gui.closeHide` option to `true` in `package.json` `pear` options object when using `ui.app.tray`.
154
+
155
+ WARNING: Linux tray support varies which can cause scenarios where the application's tray doesn't work and closing the app will be hidden and inaccessible. Using a tray and `closeHide` on Linux is not recommended. Set `pear.gui.linux.closeHide` option to `false` in `package.json` `pear` options object.
156
+
157
+ **Options**
158
+
159
+ * `icon <String>` Default: The Pear icon - The path for icon for the tray
160
+ relative to the project root. Supported formats: PNG & JPEG
161
+ * `menu <Object>` Default: ``{ show: `Show ${Pear.app.name}`, quit: 'Quit' }`` - The
162
+ tray menu items. Each property of the object is the `key` passed to the
163
+ `listener` and whose value is the text displayed in the menu.
164
+ * `os <Object>` Default: `{ win32: true, linux: true, darwin: true }` - which
165
+ platforms support using the tray menu. The platform is checked via the
166
+ `process.platform` value.
167
+
168
+ ### `const sourceId = await ui.app.getMediaSourceId()` <a name="ui-app-getmediasourceid"></a>
169
+
170
+ Get the sourceId of the current window or view.
171
+
172
+ ### `const success = await ui.app.minimize()` <a name="ui-app-minimize"></a>
104
173
 
105
174
  Resolves to: `<Boolean>`
106
175
 
107
176
  Minimize current window.
108
177
 
109
- ### `const success = await app.maximize()`
178
+ ### `const success = await ui.app.maximize()` <a name="ui-app-maximize"></a>
110
179
 
111
180
  Resolves to: `<Boolean>`
112
181
 
113
182
  Maximize current window.
114
183
 
115
- ### `const success = await app.restore()`
184
+ ### `const success = await ui.app.restore()` <a name="ui-app-restore"></a>
116
185
 
117
186
  Resolves to: `<Boolean>`
118
187
 
119
188
  Unmaximize/unminimize the current window if it is currently maximized/minimized.
120
189
 
121
- ### `const success = await app.close()`
190
+ ### `const success = await ui.app.close()` <a name="ui-app-close"></a>
122
191
 
123
192
  Resolves to: `<Boolean>`
124
193
 
125
194
  Closes the current view or window.
126
195
 
127
196
 
128
- ### `const isVisible = await app.isVisible()`
197
+ ### `const isVisible = await ui.app.isVisible()` <a name="ui-app-isvisible"></a>
129
198
 
130
199
  Resolves to: `<Boolean>`
131
200
 
132
201
  Whether the current window or view is visible.
133
202
 
134
- ### `const isMaximized = await app.isMaximized()`
203
+ ### `const isMaximized = await ui.app.isMaximized()` <a name="ui-app-ismaximized"></a>
135
204
 
136
205
  Resolves to: `<Boolean>`
137
206
 
138
- ### `const isMinimized = await app.isMinimized()`
207
+ ### `const isMinimized = await ui.app.isMinimized()` <a name="ui-app-isminimized"></a>
139
208
 
140
209
  Resolves to: `<Boolean>`
141
210
 
142
- ### `const found = await app.find(options <Object>)`
211
+ ### `const found = await ui.app.find(options <Object>)` <a name="ui-app-find"></a>
143
212
 
144
213
  Resolves to: `<Found> extends <streamx.Readable>`
145
214
 
@@ -150,28 +219,27 @@ Find and select text, emit matches as data events.
150
219
  * forward `<Boolean>` - search forward (`true`) or backward (`false`). Defaults `true`.
151
220
  * matchCase `<Boolean>` - case-sensitivity. Default `false`.
152
221
 
153
- #### `await found.proceed()`
222
+ #### `await found.proceed()` <a name="found-proceed"></a>
154
223
 
155
224
  Find & select next match, emit result as stream data.
156
225
 
157
- #### `await found.clear()`
226
+ #### `await found.clear()` <a name="found-clear"></a>
158
227
 
159
228
  Stop search and clear matching text selection. Implies destroy.
160
229
 
161
- #### `await found.keep()`
230
+ #### `await found.keep()` <a name="found-keep"></a>
162
231
 
163
232
  Stop search and convert matching text selection to text highlight. Implies destroy.
164
233
 
165
- #### `await found.activate()`
234
+ #### `await found.activate()` <a name="found-activate"></a>
166
235
 
167
236
  Stop search and simulate a click event on the selected match. Implies destroy.
168
237
 
169
-
170
- ### `ui.media <Object>`
238
+ ### `ui.media <Object>` <a name="ui-media"></a>
171
239
 
172
240
  Media interface
173
241
 
174
- #### `const status = await ui.media.status.microphone()`
242
+ #### `const status = await ui.media.status.microphone()` <a name="ui-media-status-microphone"></a>
175
243
 
176
244
  Resolves to: `<String>`
177
245
 
@@ -179,7 +247,7 @@ If access to the microphone is available, resolved value will be `'granted'`.
179
247
 
180
248
  Any other string indicates lack of permission. Possible values are `'granted'`, `'not-determined'`, `'denied'`, `'restricted'`, `'unknown'`.
181
249
 
182
- #### `const status = await ui.media.status.camera()`
250
+ #### `const status = await ui.media.status.camera()` <a name="ui-media-status-camera"></a>
183
251
 
184
252
  Resolves to: `<String>`
185
253
 
@@ -187,7 +255,7 @@ If access to the camera is available, resolved value will be `'granted'`.
187
255
 
188
256
  Any other string indicates lack of permission. Possible values are `'granted'`, `'not-determined'`, `'denied'`, `'restricted'`, `'unknown'`.
189
257
 
190
- #### `const status = await ui.media.status.screen()`
258
+ #### `const status = await ui.media.status.screen()` <a name="ui-media-status-screen"></a>
191
259
 
192
260
  Resolves to: `<String>`
193
261
 
@@ -195,25 +263,25 @@ If access to the screen is available, resolved value will be `'granted'`.
195
263
 
196
264
  Any other string indicates lack of permission. Possible values are `'granted'`, `'not-determined'`, `'denied'`, `'restricted'`, `'unknown'`.
197
265
 
198
- #### `const success = await ui.media.access.microphone()`
266
+ #### `const success = await ui.media.access.microphone()` <a name="ui-media-access-microphone"></a>
199
267
 
200
268
  Resolves to: `<Boolean>`
201
269
 
202
270
  Request access to the microphone. Resolves to `true` if permission is granted.
203
271
 
204
- #### `const success = await ui.media.access.camera()`
272
+ #### `const success = await ui.media.access.camera()` <a name="ui-media-access-camera"></a>
205
273
 
206
274
  Resolves to: `<Boolean>`
207
275
 
208
276
  Request access to the camera. Resolves to `true` if permission is granted.
209
277
 
210
- #### `const success = await ui.media.access.screen()`
278
+ #### `const success = await ui.media.access.screen()` <a name="ui-media-access-screen"></a>
211
279
 
212
280
  Resolves to: `<Boolean>`
213
281
 
214
282
  Request access to screen sharing. Resolves to `true` if permission is granted.
215
283
 
216
- #### `const sources = await ui.media.desktopSources(options <Object>)`
284
+ #### `const sources = await ui.media.desktopSources(options <Object>)` <a name="ui-media-desktopsources"></a>
217
285
 
218
286
  Captures available desktop sources. Resolves to an array of objects with shape `{ id <String>, name <String>, thumbnail <NativeImage>, display_id <String>, appIcon <NativeImage> }`. The `id` is the window or screen identifier. The `name` is the window title or `'Screen <index>'` in multiscreen scenarios or else `Entire Screen`. The `display_id` identifies the screen. The thumbnail is a scaled down screen capture of the window/screen.
219
287
 
@@ -223,19 +291,19 @@ Captures available desktop sources. Resolves to an array of objects with shape `
223
291
  * `thumbnailSize <Object>` - Default: `{width: 150, height: 150}`. Set thumbnail scaling (pixels)
224
292
  * `fetchWindowIcons <Boolean>` - Default: `false`. Populate `appIcon` with Window icons, or else `null`.
225
293
 
226
- **References**
294
+ **See Also**
227
295
 
228
- * [win.getMediaSourceId()](#const-sourceid--await-wingetmediasourceid)
229
- * [view.getMediaSourceId()](#const-sourceid--await-viewgetmediasourceid)
230
- * [self.getMediaSourceId()](#const-sourceid--await-selfgetmediasourceid)
231
- * [parent.getMediaSourceId()](#const-sourceid--await-parentgetmediasourceid)
296
+ * [app.getMediaSourceId()](#app-getmediasourceid)
297
+ * [view.getMediaSourceId()](#view-getmediasourceid)
298
+ * [win.getMediaSourceId()](#win-getmediasourceid)
299
+ * [parent.getMediaSourceId()](#parent-getmediasourceid)
232
300
  * https://www.electronjs.org/docs/latest/api/desktop-capturer#desktopcapturergetsourcesoptions
233
301
  * https://www.electronjs.org/docs/latest/api/structures/desktop-capturer-source
234
302
  * [`<NativeImage>`](https://www.electronjs.org/docs/latest/api/native-image)
235
303
 
236
304
  Exits the process with the provided exit code.
237
305
 
238
- ### `const win = new ui.Window(entry <String>, options <Object>)`
306
+ ### `const win = new ui.Window(entry <String>, options <Object>)` <a name="ui-window"></a>
239
307
 
240
308
  Desktop Applications only.
241
309
 
@@ -269,16 +337,12 @@ Create a new `Window` instance.
269
337
  * `transparent <Boolean>` - Set window transparency
270
338
  * `backgroundColor <String>` Default: `'#FFF'` - window default background color. Hex, RGB, RGBA, HSL HSLA, CSS color
271
339
 
272
- ### `win.on[ce]('message', (...args) => { })`
340
+ ### `win.on[ce]('message', (...args) => { })` <a name="win-recieve-messages"></a>
273
341
  ### `for await (const [ ...args ] of win)`
274
342
 
275
343
  Receive a message from the window. The received `args` array is deserialized via `JSON.parse`.
276
344
 
277
- **References**
278
-
279
- * [`win.send()`](#await-winsendargs)
280
-
281
- ### `const success = await win.open(options <Object>)`
345
+ ### `const success = await win.open(options <Object>)` <a name="win-open">
282
346
 
283
347
  Resolves to: `<Boolean>`
284
348
 
@@ -312,25 +376,25 @@ Open the window.
312
376
  * `transparent <Boolean>` - Set window transparency
313
377
  * `backgroundColor <String>` Default: `'#FFF'` - window default background color. Hex, RGB, RGBA, HSL HSLA, CSS color
314
378
 
315
- ### `const success = await win.close()`
379
+ ### `const success = await win.close()` <a name="win-close"></a>
316
380
 
317
381
  Resolves to: `<Boolean>`
318
382
 
319
383
  Close the window.
320
384
 
321
- ### `const success = await win.show()`
385
+ ### `const success = await win.show()` <a name="win-show"></a>
322
386
 
323
387
  Resolves to: `<Boolean>`
324
388
 
325
389
  Show the window.
326
390
 
327
- ### `const success = await win.hide()`
391
+ ### `const success = await win.hide()` <a name="win-hide"></a>
328
392
 
329
393
  Resolves to: `<Boolean>`
330
394
 
331
395
  Hide the window.
332
396
 
333
- ### `const success = await win.focus(options <Object>)`
397
+ ### `const success = await win.focus([options <Object>])` <a name="win-focus"></a>
334
398
 
335
399
  Resolves to: `<Boolean>`
336
400
 
@@ -338,48 +402,43 @@ Focus the window.
338
402
 
339
403
  **Options**
340
404
 
341
- * `steal` Default: `true` - brings the window to the foreground and attempts to take focus, even if another application is currently active, or the window is hidden or minimized.
405
+ * `steal` Default: `true` -
342
406
 
343
- ### `const success = await win.blur()`
407
+ ### `const success = await win.blur()` <a name="win-blur"></a>
344
408
 
345
409
  Resolves to: `<Boolean>`
346
410
 
347
411
  Blur the window.
348
412
 
349
- ### `const success = await win.minimize()`
413
+ ### `const success = await win.minimize()` <a name="win-minimize"></a>
350
414
 
351
415
  Resolves to: `<Boolean>`
352
416
 
353
417
  Minimize the window.
354
418
 
355
- ### `const success = await win.maximize()`
419
+ ### `const success = await win.maximize()` <a name="win-maximize"></a>
356
420
 
357
421
  Resolves to: `<Boolean>`
358
422
 
359
423
  Maximize the window.
360
424
 
361
- ### `const success = await win.restore()`
425
+ ### `const success = await win.restore()` <a name="win-restore"></a>
362
426
 
363
427
  Resolves to: `<Boolean>`
364
428
 
365
429
  Unmaximize/unminimize the window if it is currently maximized/minimized.
366
430
 
367
- ### `const sourceId = await win.getMediaSourceId()`
431
+ ### `const sourceId = await win.getMediaSourceId()` <a name="win-getmediasourceid"></a>
368
432
 
369
433
  Resolves to: `<String>`
370
434
 
371
- Correlates to the `id` property of objects in the array returned from [ui.media.desktopSources](#const-sources---await-appmediadesktopsources-options).
435
+ Correlates to the `id` property of objects in the array returned from [ui.media.desktopSources](#ui-media-desktopsources).
372
436
 
373
- **References**
374
-
375
- * [ui.media.desktopSources](#const-sources--await-appmediadesktopsourcesoptions-object)
376
- * https://www.electronjs.org/docs/latest/api/browser-window#wingetmediasourceid
377
-
378
- ### `await win.send(...args)`
437
+ ### `await win.send(...args)` <a name="win-send"></a>
379
438
 
380
439
  Send arguments to the window. They will be serialized with `JSON.stringify`.
381
440
 
382
- ### `const found = await win.find(options <Object>)`
441
+ ### `const found = await win.find(options <Object>)` <a name="win-find"></a>
383
442
 
384
443
  Resolves to: `<Found> extends <streamx.Readable>`
385
444
 
@@ -390,24 +449,25 @@ Find and select text, emit matches as data events.
390
449
  * forward `<Boolean>` - search forward (`true`) or backward (`false`). Defaults `true`.
391
450
  * matchCase `<Boolean>` - case-sensitivity. Default `false`.
392
451
 
393
- #### `await found.proceed()`
452
+ #### `await found.proceed()` <a name="win-find-found-proceed"></a>
394
453
 
395
454
  Find & select next match, emit result as stream data.
396
455
 
397
- #### `await found.clear()`
456
+ #### `await found.clear()` <a name="win-find-found-clear"></a>
398
457
 
399
458
  Stop search and clear matching text selection. Implies destroy.
400
459
 
401
- #### `await found.keep()`
460
+ #### `await found.keep()` <a name="win-find-found-keep"></a>
402
461
 
403
462
  Stop search and convert matching text selection to text highlight. Implies destroy.
404
463
 
405
- #### `await found.activate()`
464
+ #### `await found.activate()` <a name="win-find-found-activate"></a>
406
465
 
407
466
  Stop search and simulate a click event on the selected match. Implies destroy.
408
467
 
468
+ ### `const dimensions = await win.dimensions([options <Object>])` <a name="win-dimensions"></a>
409
469
 
410
- ### `const dimensions = await win.dimensions()`
470
+ When options object is not provided, behaves as a getter and resolves to a a bounds object.
411
471
 
412
472
  Resolves to: `{x <Integer>, y <Integer>, width <Integer>, height <Integer>} | null`.
413
473
 
@@ -417,11 +477,7 @@ All units are (pixels)
417
477
 
418
478
  If the window is closed this will resolve to `null`.
419
479
 
420
- **References**
421
-
422
- * [await win.dimensions(options)](#await-windimensionsoptions-object)
423
-
424
- ### `await win.dimensions(options <Object>)`
480
+ When options object is provided, behaves as a setter and resolves to `undefined`.
425
481
 
426
482
  ```js
427
483
  const win = new ui.Window('./some.html', {
@@ -455,36 +511,31 @@ Sets the dimensions of the window.
455
511
  * `animate <Boolean>` Default: `false` - animate the dimensional change. MacOS only, ignored on other OS's.
456
512
  * `position <String>` - may be `'center'` to set the window in the center of the screen or else `undefined`.
457
513
 
458
- **References**
459
-
460
- * [const dimensions = await win.dimensions()](#const-dimensions-await-windimensions)
461
-
462
-
463
- ### `const visible = await win.isVisible()`
514
+ ### `const visible = await win.isVisible()` <a name="win-isvisible"></a>
464
515
 
465
516
  Resolves to: `<Boolean>`
466
517
 
467
518
  Whether the window is visible.
468
519
 
469
- ### `const minimized = await win.isMinimized()`
520
+ ### `const minimized = await win.isMinimized()` <a name="win-isminimized"></a>
470
521
 
471
522
  Resolves to: `<Boolean>`
472
523
 
473
524
  Whether the window is minimized.
474
525
 
475
- ### `const maximized = await win.isMaximized()`
526
+ ### `const maximized = await win.isMaximized()` <a name="win-ismaximized"></a>
476
527
 
477
528
  Resolves to: `<Boolean>`
478
529
 
479
530
  Whether the window is maximized.
480
531
 
481
- ### `const closed = await win.isClosed()`
532
+ ### `const closed = await win.isClosed()` <a name="win-isclosed"></a>
482
533
 
483
534
  Resolves to: `<Boolean>`
484
535
 
485
536
  Whether the window is closed.
486
537
 
487
- ### `const view = new ui.View(options <Object>)`
538
+ ### `const view = new ui.View(options <Object>)` <a name="ui-view"></a>
488
539
 
489
540
  Desktop Applications only.
490
541
 
@@ -499,21 +550,17 @@ Create a new `View` instance. Views provide isolated content views. Frameless, c
499
550
  * `backgroundColor <String>` Default: `'#FFF'` - view default background color. Hex, RGB, RGBA, HSL HSLA, CSS color
500
551
  * `autoresize <Object>` Default `{ width=true, height=true, vertical=false, horizontal=false }` - dimensions for the view to autoresize alongside. For example, if `width` is `true` and the view container increases/decreases in width, the view will increase/decrease in width at the same rate.
501
552
 
502
- **References**
503
553
 
504
- * https://www.electronjs.org/docs/latest/api/browser-view#viewsetautoresizeoptions-experimental
505
554
  * https://www.electronjs.org/docs/latest/api/browser-view#viewsetbackgroundcolorcolor-experimental
506
555
 
507
- ### `view.on[ce]('message', (...args) => { })`
556
+ ### `view.on[ce]('message', (...args) => { })` <a name="view-recieve-messages"></a>
508
557
  ### `for await (const [ ...args ] of view)`
509
558
 
510
559
  Receive a message from the view. The received `args` array is deserialized via `JSON.parse`.
511
560
 
512
- **References**
513
561
 
514
- * [`view.send()`](#await-viewsendargs)
515
562
 
516
- ### `const success = await view.open(options <Object>)`
563
+ ### `const success = await view.open(options <Object>)` <a name="view-open"></a>
517
564
 
518
565
  Resolves to: `<Boolean>`
519
566
 
@@ -528,79 +575,81 @@ Open the view.
528
575
  * `backgroundColor <String>` Default: `'#FFF'` - view default background color. Hex, RGB, RGBA, HSL HSLA, CSS color
529
576
  * `autoresize <Object>` Default `{ width=true, height=true, vertical=false, horizontal=false }` - dimensions for the view to autoresize alongside. For example, if `width` is `true` and the view container increases/decreases in width, the view will increase/decrease in width at the same rate.
530
577
 
531
- ### `const success = await view.close()`
578
+ ### `const success = await view.close()` <a name="view-close"></a>
532
579
 
533
580
  Resolves to: `<Boolean>`
534
581
 
535
582
  Close the view.
536
583
 
537
- ### `const success = await view.show()`
584
+ ### `const success = await view.show()` <a name="view-show"></a>
538
585
 
539
586
  Resolves to: `<Boolean>`
540
587
 
541
588
  Show the view.
542
589
 
543
- ### `const success = await view.hide()`
590
+ ### `const success = await view.hide()` <a name="view-hide"></a>
544
591
 
545
592
  Resolves to: `<Boolean>`
546
593
 
547
594
  Hide the view.
548
595
 
549
- ### `const success = await view.focus()`
596
+ ### `const success = await view.focus([options <Object>])` <a name="view-focus"></a>
550
597
 
551
598
  Resolves to: `<Boolean>`
552
599
 
553
- Focus the view.
600
+ Foreground the view.
601
+
602
+ **Options**
603
+
604
+ * `steal` Default: `false` - focus input as well as foregrounding
554
605
 
555
- ### `const success = await view.blur()`
606
+ ### `const success = await view.blur()` <a name="view-blur"></a>
556
607
 
557
608
  Resolves to: `<Boolean>`
558
609
 
559
610
  Blur the view.
560
611
 
561
- ### `const sourceId = await view.getMediaSourceId()`
612
+ ### `const sourceId = await view.getMediaSourceId()` <a name="view-getmediasourceid"></a>
562
613
 
563
614
  Resolves to: `<String>`
564
615
 
565
- Supplies the `id` property of objects in the array returned from [ui.media.desktopSources](#const-sources---await-appmediadesktopsources-options).
616
+ Supplies the `id` property of objects in the array returned from [ui.media.desktopSources](#ui-media-desktopsources).
566
617
 
567
- **References**
568
-
569
- * [ui.media.desktopSources](#const-sources---await-appmediadesktopsources-options)
570
- * https://www.electronjs.org/docs/latest/api/browser-window#wingetmediasourceid
571
-
572
- ### `await view.send(...args)`
618
+ ### `await view.send(...args)` <a name="view-send"></a>
573
619
 
574
620
  Send arguments to the view. They will be serialized with `JSON.stringify`.
575
621
 
576
- ### `const found = await win.find(options <Object>)`
622
+ ### `const found = await view.find(options <Object>)` <a name="view-find"></a>
577
623
 
578
624
  Resolves to: `<Found> extends <streamx.Readable>`
579
625
 
580
626
  Find and select text, emit matches as data events.
581
627
 
582
628
  **Options**
629
+
583
630
  * text `<String>` - search term
584
631
  * forward `<Boolean>` - search forward (`true`) or backward (`false`). Defaults `true`.
585
632
  * matchCase `<Boolean>` - case-sensitivity. Default `false`.
586
633
 
587
- #### `await found.proceed()`
634
+ #### `await found.proceed()` <a name="view-find-found-proceed"></a>
588
635
 
589
636
  Find & select next match, emit result as stream data.
590
637
 
591
- #### `await found.clear()`
638
+ #### `await found.clear()` <a name="view-find-found-clear"></a>
592
639
 
593
640
  Stop search and clear matching text selection. Implies destroy.
594
641
 
595
- #### `await found.keep()`
642
+ #### `await found.keep()` <a name="view-find-found-keep"></a>
596
643
 
597
644
  Stop search and convert matching text selection to text highlight. Implies destroy.
598
645
 
599
- #### `await found.activate()`
646
+ #### `await found.activate()` <a name="view-find-found-activate"></a>
600
647
 
601
648
  Stop search and simulate a click event on the selected match. Implies destroy.
602
649
 
603
- ### `const dimensions = await view.dimensions()`
650
+ ### `const dimensions = await view.dimensions([options <Object>])` <a name="view-dimensions"></a>
651
+
652
+ When options object is not provided, behaves as a getter and resolves to a a bounds object.
604
653
 
605
654
  Resolves to: `{x <Integer>, y <Integer>, width <Integer>, height <Integer>} | null`.
606
655
 
@@ -608,13 +657,9 @@ The height, width, horizontal (`x`), vertical (`y`) position of the window relat
608
657
 
609
658
  All units are (pixels)
610
659
 
611
- If the Window is closed this will resolve to `null`.
612
-
613
- **References**
614
-
615
- * [await view.dimensions(options)](#await-viewdimensionsoptions-object)
660
+ If the parent window is closed this will resolve to `null`.
616
661
 
617
- ### `await view.dimensions(options <Object>)`
662
+ When options object is provided, behaves as a setter and resolves to `undefined`.
618
663
 
619
664
  ```js
620
665
  const view = new ui.View('./some.html', {
@@ -645,72 +690,98 @@ Sets the dimensions of the view.
645
690
  * `height <Integer>` - the height of the window (pixels)
646
691
 
647
692
 
648
- **References**
693
+ ```js
694
+ const view = new ui.View('./some.html', {
695
+ x: 10,
696
+ y: 450,
697
+ width: 300,
698
+ height: 350
699
+ })
649
700
 
650
- * [const dimensions = await view.dimensions()](#const-dimensions--await-viewdimensions)
701
+ await view.open()
702
+ await new Promise((resolve) => setTimeout(resolve, 1000))
651
703
 
652
- ### `const visible = await view.isVisible()`
704
+ await view.dimensions({
705
+ x: 20,
706
+ y: 50,
707
+ width: 550,
708
+ height: 300
709
+ })
710
+ ```
711
+
712
+ Sets the dimensions of the view.
713
+
714
+ **Options**
715
+
716
+ * `x <Integer>` - the horizontal position of left side of the window (pixels)
717
+ * `y <Integer>` - the vertical position of the top of the window (pixels)
718
+ * `width <Integer>` - the width of the window (pixels)
719
+ * `height <Integer>` - the height of the window (pixels)
720
+
721
+ ### `const visible = await view.isVisible()` <a name="view-isvisible"></a>
653
722
 
654
723
  Resolves to: `<Boolean>`
655
724
 
656
725
  Whether the view is visible.
657
726
 
658
- ### `const closed = await view.isClosed()`
727
+ ### `const closed = await view.isClosed()` <a name="view-isclosed"></a>
659
728
 
660
729
  Resolves to: `<Boolean>`
661
730
 
662
731
  Whether the view is closed.
663
732
 
664
- ### `const { self } = ui.Window` `const { self } = ui.View`
733
+ ### `const { self } = ui.Window` `const { self } = ui.View` <a name="deprecated-self"></a>
665
734
 
666
735
  > DEPRECATED use `ui.app`.
667
736
 
668
- ### `const { parent } = ui.Window` `const { parent } = ui.View`
737
+ ### `const { parent } = ui.Window` `const { parent } = ui.View` <a name="parent"></a>
669
738
 
670
- ### `parent.on[ce]('message', (...args) => { })`
739
+ ### `parent.on[ce]('message', (...args) => { })` <a name="parent-receive-messages"></a>
671
740
  ### `for await (const [ ...args ] of parent)`
672
741
 
673
742
  Receive a message from the parent window or view. The received `args` array is deserialized via `JSON.parse`.
674
743
 
675
- ### `await parent.send(...args)`
744
+ ### `await parent.send(...args)` <a name="parent-send"></a>
676
745
 
677
746
  Send arguments to the parent view or window. They will be serialized with `JSON.stringify`.
678
747
 
679
748
 
680
- ### `const success = await parent.focus()`
749
+ ### `const success = await parent.focus([options <Object>])` <a name="parent-focus"></a>
681
750
 
682
751
  Resolves to: `<Boolean>`
683
752
 
684
- Focus parent view or window.
753
+ Foreground parent view or window.
754
+
755
+ **Options**
756
+
757
+ * `steal` Default: `false` - focus input as well as foregrounding
685
758
 
686
- ### `const success = await parent.blur()`
759
+ ### `const success = await parent.blur()` <a name="parent-blur"></a>
687
760
 
688
761
  Resolves to: `<Boolean>`
689
762
 
690
763
  Blur parent view or window.
691
764
 
692
- ### `const success = await parent.show()`
765
+ ### `const success = await parent.show()` <a name="parent-show"></a>
693
766
 
694
767
  Resolves to: `<Boolean>`
695
768
 
696
769
  Show parent view or window.
697
770
 
698
- ### `const success = await parent.hide()`
771
+ ### `const success = await parent.hide()` <a name="parent-hide"></a>
699
772
 
700
773
  Resolves to: `<Boolean>`
701
774
 
702
775
  Hide parent view or window.
703
776
 
704
- ### `const sourceId = await parent.getMediaSourceId()`
777
+ ### `const sourceId = await parent.getMediaSourceId()` <a name="parent-getmediasourceid"></a>
705
778
 
706
779
  Get the sourceId of the parent window or view.
707
780
 
708
- **References**
709
781
 
710
- * [win.getMediaSourceId()](#const-sourceId--await-wingetMediaSourceId)
711
782
 
712
783
 
713
- ### `const success = await parent.minimize()`
784
+ ### `const success = await parent.minimize()` <a name="parent-minimize"></a>
714
785
 
715
786
  Resolves to: `<Boolean>`
716
787
 
@@ -718,7 +789,7 @@ Minimize parent window.
718
789
 
719
790
  Throws a `TypeError` if `parent` is a view.
720
791
 
721
- ### `const success = await parent.maximize()`
792
+ ### `const success = await parent.maximize()` <a name="parent-maximize"></a>
722
793
 
723
794
  Resolves to: `<Boolean>`
724
795
 
@@ -726,7 +797,7 @@ Maximize parent window.
726
797
 
727
798
  Throws a `TypeError` if `parent` is a view.
728
799
 
729
- ### `const success = await parent.restore()`
800
+ ### `const success = await parent.restore()` <a name="parent-restore"></a>
730
801
 
731
802
  Resolves to: `<Boolean>`
732
803
 
@@ -734,31 +805,31 @@ Unmaximize/unminimize the parent window if it is currently maximized/minimized.
734
805
 
735
806
  Throws a `TypeError` if `parent` is a view.
736
807
 
737
- ### `const success = await parent.close()`
808
+ ### `const success = await parent.close()` <a name="parent-close"></a>
738
809
 
739
810
  Resolves to: `<Boolean>`
740
811
 
741
812
  Closes the parent view or window.
742
813
 
743
- ### `const isVisible = await parent.isVisible()`
814
+ ### `const isVisible = await parent.isVisible()` <a name="parent-isvisible"></a>
744
815
 
745
816
  Resolves to: `<Boolean>`
746
817
 
747
818
  Whether the parent window or view is visible.
748
819
 
749
- ### `const isMaximized = await parent.isMaximized()`
820
+ ### `const isMaximized = await parent.isMaximized()` <a name="parent-ismaximized"></a>
750
821
  Resolves to: `<Boolean>`
751
822
 
752
823
  Whether the parent window is maximized. Throws a `TypeError` if `parent` is a view.
753
824
 
754
825
 
755
- ### `const isMinimized = await parent.isMinimized()`
826
+ ### `const isMinimized = await parent.isMinimized()` <a name="parent-isminimized"></a>
756
827
 
757
828
  Resolves to: `<Boolean>`
758
829
 
759
830
  Whether the parent window is minimized. Throws a `TypeError` if `parent` is a view.
760
831
 
761
- ### `const found = await parent.find(options <Object>)`
832
+ ### `const found = await parent.find(options <Object>)` <a name="parent-find"></a>
762
833
 
763
834
  Resolves to: `<Found> extends <streamx.Readable>`
764
835
 
@@ -769,119 +840,166 @@ Find and select text, emit matches as data events.
769
840
  * forward `<Boolean>` - search forward (`true`) or backward (`false`). Defaults `true`.
770
841
  * matchCase `<Boolean>` - case-sensitivity. Default `false`.
771
842
 
772
- #### `await found.proceed()`
843
+ #### `await found.proceed()` <a name="parent-find-found-proceed"></a>
773
844
 
774
845
  Find & select next match, emit result as stream data.
775
846
 
776
- #### `await found.clear()`
847
+ #### `await found.clear()` <a name="parent-find-found-clear"></a>
777
848
 
778
849
  Stop search and clear matching text selection. Implies destroy.
779
850
 
780
- #### `await found.keep()`
851
+ #### `await found.keep()` <a name="parent-find-found-keep"></a>
781
852
 
782
853
  Stop search and convert matching text selection to text highlight. Implies destroy.
783
854
 
784
- #### `await found.activate()`
855
+ #### `await found.activate()` <a name="parent-find-found-activate"></a>
785
856
 
786
857
  Stop search and simulate a click event on the selected match. Implies destroy.
787
858
 
788
- ## Graphical User Interface Options
859
+ ## Graphical User Interface Options <a name="pear-gui"></a>
789
860
 
790
861
  GUI options for an application are set in the application `package.json` `pear.gui` field.
791
862
 
792
- ### `width <Number>`
863
+ Example `package.json`:
864
+
865
+ ```json
866
+ {
867
+ "name": "my-app",
868
+ "pear": {
869
+ "gui": {
870
+ "width": 800,
871
+ "height": 600
872
+ }
873
+ }
874
+ }
875
+ ```
876
+
877
+ ### `pear.gui.width <Number>` <a name="pear-gui-width"></a>
793
878
 
794
879
  Window width (pixels).
795
880
 
796
- ### `height <Number>`
881
+ ### `pear.gui.height <Number>` <a name="pear-gui-height"></a>
797
882
 
798
883
  Window height (pixels).
799
884
 
800
- ### `x <Number>`
885
+ ### `pear.gui.x <Number>` <a name="pear-gui-x"></a>
801
886
 
802
887
  Horizontal window position (pixels).
803
888
 
804
- ### `y <Number>`
889
+ ### `pear.gui.y <Number>` <a name="pear-gui-y"></a>
805
890
 
806
891
  Vertical window position (pixels).
807
892
 
808
- ### `minWidth <Number>`
893
+ ### `pear.gui.minWidth <Number>` <a name="pear-gui-minwidth"></a>
809
894
 
810
895
  Window minimum width (pixels).
811
896
 
812
- ### `minHeight <Number>`
897
+ ### `pear.gui.minHeight <Number>` <a name="pear-gui-minheight"></a>
813
898
 
814
899
  Window minimum height (pixels).
815
900
 
816
- ### `maxWidth <Number>`
901
+ ### `pear.gui.maxWidth <Number>` <a name="pear-gui-maxwidth"></a>
817
902
 
818
903
  Window maximum width (pixels).
819
904
 
820
- ### `maxHeight <Number>`
905
+ ### `pear.gui.maxHeight <Number>` <a name="pear-gui-maxheight"></a>
821
906
 
822
907
  Window maximum height (pixels).
823
908
 
824
- ### `center <Boolean>` (default: `false`)
909
+ ### `pear.gui.center <Boolean>` (default: `false`) <a name="pear-gui-center"></a>
825
910
 
826
911
  Center window.
827
912
 
828
- ### `resizable <Boolean>` (default: `true`)
913
+ ### `pear.gui.resizable <Boolean>` (default: `true`) <a name="pear-gui-resizable"></a>
829
914
 
830
915
  Window resizability.
831
916
 
832
- ### `movable <Boolean>` (default: `true`)
917
+ ### `pear.gui.movable <Boolean>` (default: `true`) <a name="pear-gui-movable"></a>
833
918
 
834
919
  Window movability.
835
920
 
836
- ### `minimizable <Boolean>` (default: `true`)
921
+ ### `pear.gui.minimizable <Boolean>` (default: `true`) <a name="pear-gui-minimizable"></a>
837
922
 
838
923
  Window minimizability.
839
924
 
840
- ### `maximizable <Boolean>` (default: `true`)
925
+ ### `pear.gui.maximizable <Boolean>` (default: `true`) <a name="pear-gui-maximizable"></a>
841
926
 
842
927
  Window maximizability.
843
928
 
844
- ### `closable <Boolean>` (default: `true`)
929
+ ### `pear.gui.closable <Boolean>` (default: `true`) <a name="pear-gui-closable"></a>
845
930
 
846
931
  Window closability.
847
932
 
848
- ### `focusable <Boolean>` (default: `true`)
933
+ ### `pear.gui.focusable <Boolean>` (default: `true`) <a name="pear-gui-focusable"></a>
849
934
 
850
935
  Window focusability.
851
936
 
852
- ### `alwaysOnTop <Boolean>` (default: `false`)
937
+ #### `pear.gui.closeHides <Boolean>` (default: `false`) <a name="pear-gui-closehides"></a>
938
+
939
+ Keep app running when all windows are closed.
940
+
941
+ WARNING: Linux tray support varies which can cause scenarios where the application's tray doesn't work and closing the app will be hidden and inaccessible. Using a tray and `closeHides` on Linux is not recommended.
942
+
943
+ ### `pear.gui.alwaysOnTop <Boolean>` (default: `false`) <a name="pear-gui-alwaysontop"></a>
853
944
 
854
945
  Set window to always be on top.
855
946
 
856
- ### `fullscreen <Boolean>` (default: `false`)
947
+ ### `pear.gui.fullscreen <Boolean>` (default: `false`) <a name="pear-gui-fullscreen"></a>
857
948
 
858
949
  Set window to fullscreen on start.
859
950
 
860
- ### `kiosk <Boolean>` (default: `false`)
951
+ ### `pear.gui.kiosk <Boolean>` (default: `false`) <a name="pear-gui-kiosk"></a>
861
952
 
862
953
  Set window to enter kiosk mode on start.
863
954
 
864
- ### `autoHideMenuBar <Boolean>` (default: `false`)
955
+ ### `pear.gui.autoHideMenuBar <Boolean>` (default: `false`) <a name="pear-gui-autohidemenubar"></a>
865
956
 
866
957
  Hide menu bar unless Alt key is pressed (Linux, Windows).
867
958
 
868
- ### `hasShadow <Boolean>` (default: `true`)
959
+ ### `pear.gui.hasShadow <Boolean>` (default: `true`) <a name="pear-gui-hasshadow"></a>
869
960
 
870
961
  Window shadow.
871
962
 
872
- ### `opacity <Number>` (default: `1`)
963
+ ### `pear.gui.opacity <Number>` (default: `1`) <a name="pear-gui-opacity"></a>
873
964
 
874
965
  Set window opacity (0.0 - 1.0) (Windows, macOS).
875
966
 
876
- ### `transparent <Boolean>` (default: `false`)
967
+ ### `pear.gui.transparent <Boolean>` (default: `false`) <a name="pear-gui-transparent"></a>
877
968
 
878
969
  Enable transparency. Must be set for opacity to work.
879
970
 
880
- ### `backgroundColor <String>` (default: "#000" non-transparent, "#00000000" transparent)
971
+ ### `pear.gui.backgroundColor <String>` (default: "#000" non-transparent, "#00000000" transparent) <a name="pear-gui-backgroundcolor"></a>
881
972
 
882
973
  Background color (Hex, RGB, RGBA, HSL, HSLA, CSS color).
883
974
 
884
- ## Web APIs
975
+ ### `pear.gui.userAgent <string>` <a name="pear-gui-useragent"></a>
976
+
977
+ User Agent override to use when electron makes web requests.
978
+
979
+ #### `pear.gui[platform] <Object>` <a name="pear-gui-platform"></a>
980
+
981
+ Platform specific options can be set by nesting options under the platform name. For example the following sets the macOS version to not be resizable:
982
+
983
+ ```json
984
+ {
985
+ "pear": {
986
+ "gui": {
987
+ "darwin": {
988
+ "resizable": false
989
+ }
990
+ }
991
+ }
992
+ }
993
+ ```
994
+
995
+ The following `platform`s are supported:
996
+
997
+ - `darwin`
998
+ - `linux`
999
+ - `win32`
1000
+
1001
+
1002
+ ## Web APIs <a name="web-apis"></a>
885
1003
 
886
1004
  Most [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) will work as-is.
887
1005
 
@@ -897,7 +1015,7 @@ With `pear-electron` UI Library, `window.open` loads the URL in the **default sy
897
1015
 
898
1016
  Therefore Pear's `window.open` only supports a single URL argument. The `target` and `windowFeatures` parameters that browsers support are discarded.
899
1017
 
900
- ### Scripts and Modules
1018
+ ### Scripts and Modules <a name="scripts-and-modules"></a>
901
1019
 
902
1020
  Like browsers, there is no support for CommonJS (e.g. the `require` function as used by Node.js is not supported in Pear Applications).
903
1021
 
@@ -907,24 +1025,41 @@ Use `<script type="module" src="path/to/my-file.js">` to load a JavaScript Modul
907
1025
 
908
1026
  Use `<script src="path/to/my-file.js">` to load a JavaScript Script.
909
1027
 
910
- ## Libraries
1028
+ ## Development <a name="development"></a>
911
1029
 
912
- ### `pear-electron/api`
1030
+ The `pear-electron` library is a Pear User Interface Runtime Library, providing multiple capabilities:
913
1031
 
914
- Function that takes a base Pear API class and extends it with pear-electron APIs. Only really useful when working with spoofed/mock Pear global in ui tests.
1032
+ * When loaded into a pear entrypoint JS file, `pear-electron` exports `runtime.js`, the runtime initializor.
1033
+ * When loaded into electron, `pear-electron` exports a UI library that is injected via `Pear[Pear.constructor.UI]` inside the runtime build that becomes the asset defined on `pear.assets.ui` configuration.
1034
+ * The `pear-electron/pre` script provides autoconfiguration, it sets `pear.assets.ui` on the application per `pear.assets.ui` in the `pear-electron/package.json`.
915
1035
 
1036
+ The `pear-electron` repo is self-bootstrapping and generates the runtime drive with `by-arch`, `prebuilds` and `boot.bundle`, which can then be staged with Pear.
916
1037
 
917
- ## Development
1038
+ ```sh
1039
+ npm run prestage
1040
+ ```
1041
+
1042
+ ```sh
1043
+ pear stage dev
1044
+ ```
918
1045
 
919
- The `pear-electron` library is a Pear User Interface Runtime Library, as such `pear-electron` (and any Pear UI Lib.) is multifaceted and behaves differently depending on context.
1046
+ Set the `package.json` `pear.assets.ui.link` to the versioned pear link (`pear://<fork>.<length>.<key>`) of the staged application. This means the `pear-electron/pre` of the next publish of `pear-electron` will autoconfigure the applications `pear.assets.ui` to the updated versioned pear link. This effectively locks runtime builds for a given SemVer to a specific runtime drive checkout.
920
1047
 
921
- * When loaded into a UI, `pear-electron` is the UI API
922
- * When loaded into non-UI (i.e app entrypoint js file), `pear-electron` is the runtime initializor
923
- * When there is no runtime binary on the system, `pear-electron` performs bootstrapping of the UI runtime executable, into `<pear-dir>/interfaces/pear-electron/<semver>`
924
- * The `pear-electron` repo is also self-bootstrapping and generates the runtime drive (with `by-arch`, `prebuilds` and `boot.bundle`), which can then be staged with Pear. The pear link for the staged `pear-electron` contents in `pear-electron` `package.json` `pear.gui.runtime` field is then set, with fork and length included. This locks runtime builds for a given semver to a specific runtime drive checkout.
925
- * This is what `pear-electron` bootstraps from during `runtime.ready()`.
1048
+ To check a change with an application, use `npm pack` to get `tar.gz` archive and then install that archive into an application:
926
1049
 
1050
+ ```sh
1051
+ cd pear-electron
1052
+ npm pack
1053
+ cd ../some-pear-app
1054
+ npm i ../pear-electron/name-of-the-tar.gz
1055
+ ```
1056
+
1057
+ Then run the app with the `-d` (development) and `--pre-io` flag (to see any output from the `pear-electron/pre` script).
1058
+
1059
+ ```sh
1060
+ pear run --pre-io -d .
1061
+ ```
927
1062
 
928
- # LICENSE
1063
+ # LICENSE <a name="license"></a>
929
1064
 
930
1065
  Apache 2.0
package/api.js CHANGED
@@ -331,7 +331,7 @@ module.exports = (api) => {
331
331
  this.constructor.DECAL = {
332
332
  ipc,
333
333
  'hypercore-id-encoding': require('hypercore-id-encoding'),
334
- 'pear-api/constants': require('pear-api/constants')
334
+ 'pear-constants': require('pear-constants')
335
335
  }
336
336
  }
337
337
  }
package/bootstrap.js ADDED
@@ -0,0 +1,15 @@
1
+ 'use strict'
2
+ const pack = require('pear-pack')
3
+ const Module = require('bare-module')
4
+ const AppDrive = require('pear-appdrive')
5
+
6
+ const drive = new AppDrive()
7
+ const target = ['darwin-arm64', 'darwin-x64', 'linux-arm64', 'linux-x64', 'win32-x64']
8
+ const builtins = [
9
+ 'electron', 'net', 'assert', 'console', 'events', 'fs', 'fs/promises', 'http', 'https', 'os',
10
+ 'path', 'child_process', 'repl', 'url', 'tty', 'module', 'process', 'timers', 'inspector'
11
+ ]
12
+ const entry = '/node_modules/pear-electron/bootstrap.js'
13
+ const { bundle, prebuilds } = await pack(drive, { entry, target, builtins })
14
+
15
+ // TODO: setup module to consume bundle
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pear-electron",
3
- "version": "1.7.19",
3
+ "version": "1.7.21",
4
4
  "description": "Pear User-Interface Library for Electron",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -17,6 +17,14 @@
17
17
  "pre.js",
18
18
  "api.js"
19
19
  ],
20
+ "imports": {
21
+ "fs": {
22
+ "bare": "bare-fs"
23
+ },
24
+ "path": {
25
+ "bare": "bare-path"
26
+ }
27
+ },
20
28
  "pear": {
21
29
  "assets": {
22
30
  "ui": {
@@ -69,14 +77,22 @@
69
77
  "bare-path": "^3.0.0",
70
78
  "bare-subprocess": "^5.0.2",
71
79
  "compact-encoding": "^2.16.1",
72
- "hypercore-crypto": "^3.6.1",
73
- "hypercore-id-encoding": "^1.3.0",
74
- "iambus": "^1.0.3",
75
80
  "localdrive": "^1.12.1",
76
81
  "paparam": "^1.6.1",
77
- "pear-api": "^1.28.6",
82
+ "pear-api": "^1.29.1",
83
+ "pear-cmd": "^1.0.0",
84
+ "pear-constants": "^1.0.0",
85
+ "pear-crasher": "^1.0.1",
86
+ "pear-errors": "^1.0.0",
87
+ "pear-gunk": "^1.0.0",
78
88
  "pear-ipc": "^6.4.0",
79
- "pear-pipe": "^1.0.1",
89
+ "pear-link": "^4.1.0",
90
+ "pear-logger": "^1.0.0",
91
+ "pear-pipe": "^1.0.2",
92
+ "pear-run": "^1.0.0",
93
+ "pear-state": "^1.0.2",
94
+ "pear-terminal": "^1.0.0",
95
+ "pear-tryboot": "^1.0.0",
80
96
  "script-linker": "^2.5.3",
81
97
  "streamx": "^2.20.2",
82
98
  "url-file-url": "^1.0.4",
package/runtime.js CHANGED
@@ -8,17 +8,17 @@ const env = require('bare-env')
8
8
  const { command } = require('paparam')
9
9
  const { isLinux, isWindows, isMac } = require('which-runtime')
10
10
  const { pathToFileURL } = require('url-file-url')
11
- const constants = require('pear-api/constants')
12
- const plink = require('pear-api/link')
13
- const Logger = require('pear-api/logger')
14
- const { ERR_INVALID_APPLING, ERR_INVALID_PROJECT_DIR, ERR_INVALID_CONFIG } = require('pear-api/errors')
11
+ const constants = require('pear-constants')
12
+ const plink = require('pear-link')
13
+ const Logger = require('pear-logger')
14
+ const { ERR_INVALID_APPLING, ERR_INVALID_PROJECT_DIR, ERR_INVALID_CONFIG } = require('pear-errors')
15
15
 
16
16
  // cutover stops replaying & relaying subscriber streams between clients
17
17
  // set to false to stop run flow from auto cutover, so we can cutover at end of ui init
18
18
  Pear.constructor.CUTOVER = false
19
19
 
20
- const run = require('pear-api/cmd/run')
21
- const pear = require('pear-api/cmd')
20
+ const pear = require('pear-cmd')
21
+ const run = require('pear-cmd/run')
22
22
  const pkg = require('./package.json')
23
23
 
24
24
  const bin = (name) => {