Skip to content

holepunchto/pear-electron

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pear-electron

Pear User-Interface Library for Electron

Status: WIP

Installation

npm install pear-electron

Usage

Instantiate a pear-electron runtime instance from a Pear Application's entrypoint JavaScript file:

import Runtime from 'pear-electron'
import Bridge from 'pear-bridge'

const runtime = new Runtime()
await runtime.ready()

const bridge = new Bridge()
await bridge.ready()

const pipe = runtime.start(bridge.info())
Pear.teardown(() => pipe.end())

Call runtime.start to open the UI.

Initialization API

new Runtime() -> runtime

Create the runtime instances with new Runtime().

runtime.ready()

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.

runtime.start(info <String>)

Opens the UI. The info string is passed as a --runtime-info flag to the UI executable. The pear-api/state integration library then includes this flag value as state.runtimeInfo which can then be used by pear-electron. The info string by convention is a JSON string, with the shape, { type, data }.

In the usage example, bridge.info() is passed to runtime.start(), pear-electron later uses this to determine the bridge localhost address to load with electron.

User-Interface API

const ui = require('pear-electron')

ui.media <Object>

Media interface

const status = await ui.media.status.microphone()

Resolves to: <String>

If access to the microphone is available, resolved value will be 'granted'.

Any other string indicates lack of permission. Possible values are 'granted', 'not-determined', 'denied', 'restricted', 'unknown'.

const status = await ui.media.status.camera()

Resolves to: <String>

If access to the camera is available, resolved value will be 'granted'.

Any other string indicates lack of permission. Possible values are 'granted', 'not-determined', 'denied', 'restricted', 'unknown'.

const status = await ui.media.status.screen()

Resolves to: <String>

If access to the screen is available, resolved value will be 'granted'.

Any other string indicates lack of permission. Possible values are 'granted', 'not-determined', 'denied', 'restricted', 'unknown'.

const success = await ui.media.access.microphone()

Resolves to: <Boolean>

Request access to the microphone. Resolves to true if permission is granted.

const success = await ui.media.access.camera()

Resolves to: <Boolean>

Request access to the camera. Resolves to true if permission is granted.

const success = await ui.media.access.screen()

Resolves to: <Boolean>

Request access to screen sharing. Resolves to true if permission is granted.

const sources = await ui.media.desktopSources(options <Object>)

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.

Options

  • types <Array<String>> - Default: ['screen', 'window']. Filter by types. Types are 'screen' and 'window'.
  • thumbnailSize <Object> - Default: {width: 150, height: 150}. Set thumbnail scaling (pixels)
  • fetchWindowIcons <Boolean> - Default: false. Populate appIcon with Window icons, or else null.

References

Exits the process with the provided exit code.

const win = new ui.Window(entry <String>, options <Object>)

Desktop Applications only.

Create a new Window instance.

Options

  • show <Boolean> Default: true - show the window as soon as it has been opened
  • x <Integer> - the horizontal position of left side of the window (pixels)
  • y <Integer> - vertical window position (pixels)
  • width <Integer> - the width of the window (pixels)
  • height <Integer> - the height of the window (pixels)
  • animate <Boolean> Default: false - animate the dimensional change. MacOS only, ignored on other OS's.
  • center <Boolean - center the window upon opening
  • minWidth <Integer> - window minimum width (pixels)
  • minHeight <Integer> - window minimum height (pixels)
  • maxWidth <Integer> - window maximum width (pixels)
  • maxHeight <Integer> - window maximum height (pixels)
  • resizable <Boolean> - window resizability
  • movable <Boolean> - window movability
  • minimizable <Boolean> - window minimizability
  • maximizable <Boolean> - window maximizability
  • closable <Boolean> - window closability
  • focusable <Boolean> - window focusability
  • alwaysOnTop <Boolean> - Set window to always be on top
  • fullscreen <Boolean> - Set window to fullscreen upon open
  • kiosk <Boolean> - Set window to enter kiosk mode upon open
  • autoHideMenuBar <Boolean> - Hide menu bar unless Alt key is pressed (Linux, Windows)
  • hasShadow <Boolean> - Set window shadow
  • opacity <Number> - Set window opacity (0.0 - 1.0) (Windows, macOS)
  • transparent <Boolean> - Set window transparency
  • backgroundColor <String> Default: '#FFF' - window default background color. Hex, RGB, RGBA, HSL HSLA, CSS color

win.on[ce]('message', (...args) => { })

for await (const [ ...args ] of win)

Receive a message from the window. The received args array is deserialized via JSON.parse.

References

const success = await win.open(options <Object>)

Resolves to: <Boolean>

Open the window.

Options

  • show Default: true - show the window as soon as it has been opened
  • x <Integer> - the horizontal position of left side of the window (pixels)
  • y <Integer> - vertical window position (pixels)
  • width <Integer> - the width of the window (pixels)
  • height <Integer> - the height of the window (pixels)
  • animate <Boolean> Default: false - animate the dimensional change. MacOS only, ignored on other OS's.
  • center <Boolean - center the window upon opening
  • minWidth <Integer> - window minimum width (pixels)
  • minHeight <Integer> - window minimum height (pixels)
  • maxWidth <Integer> - window maximum width (pixels)
  • maxHeight <Integer> - window maximum height (pixels)
  • resizable <Boolean> - window resizability
  • movable <Boolean> - window movability
  • minimizable <Boolean> - window minimizability
  • maximizable <Boolean> - window maximizability
  • closable <Boolean> - window closability
  • focusable <Boolean> - window focusability
  • alwaysOnTop <Boolean> - Set window to always be on top
  • fullscreen <Boolean> - Set window to fullscreen upon open
  • kiosk <Boolean> - Set window to enter kiosk mode upon open
  • autoHideMenuBar <Boolean> - Hide menu bar unless Alt key is pressed (Linux, Windows)
  • hasShadow <Boolean> - Set window shadow
  • opacity <Number> - Set window opacity (0.0 - 1.0) (Windows, macOS)
  • transparent <Boolean> - Set window transparency
  • backgroundColor <String> Default: '#FFF' - window default background color. Hex, RGB, RGBA, HSL HSLA, CSS color

const success = await win.close()

Resolves to: <Boolean>

Close the window.

const success = await win.show()

Resolves to: <Boolean>

Show the window.

const success = await win.hide()

Resolves to: <Boolean>

Hide the window.

const success = await win.focus()

Resolves to: <Boolean>

Focus the window.

const success = await win.blur()

Resolves to: <Boolean>

Blur the window.

const success = await win.minimize()

Resolves to: <Boolean>

Minimize the window.

const success = await win.maximize()

Resolves to: <Boolean>

Maximize the window.

const success = await win.restore()

Resolves to: <Boolean>

Unmaximize/unminimize the window if it is currently maximized/minimized.

await win.send(...args)

Send arguments to the window. They will be serialized with JSON.stringify.

const sourceId = await win.getMediaSourceId()

Resolves to: <String>

Correlates to the id property of objects in the array returned from ui.media.desktopSources.

References

const dimensions = await win.dimensions()

Resolves to: {x <Integer>, y <Integer>, width <Integer>, height <Integer>} | null.

The height, width, horizontal (x), vertical (y) position of the window relative to the screen.

All units are (pixels)

If the window is closed this will resolve to null.

References

await win.dimensions(options <Object>)

const win = new ui.Window('./some.html', {
  x: 10,
  y: 450,
  width: 300,
  height: 350
})

await win.open()
await new Promise((resolve) => setTimeout(resolve, 1000))

await win.dimensions({
  x: 20,
  y: 50,
  width: 550,
  height: 300,
  animate: true // only has an effect on macOS
})

Sets the dimensions of the window.

Options

  • x <Integer> - the horizontal position of left side of the window (pixels)
  • y <Integer> - the vertical position of the top of the window (pixels)
  • width <Integer> - the width of the window (pixels)
  • height <Integer> - the height of the window (pixels)
  • animate <Boolean> Default: false - animate the dimensional change. MacOS only, ignored on other OS's.
  • position <String> - may be 'center' to set the window in the center of the screen or else undefined.

References

const visible = await win.isVisible()

Resolves to: <Boolean>

Whether the window is visible.

const minimized = await win.isMinimized()

Resolves to: <Boolean>

Whether the window is minimized.

const maximized = await win.isMaximized()

Resolves to: <Boolean>

Whether the window is maximized.

const closed = await win.isClosed()

Resolves to: <Boolean>

Whether the window is closed.

const view = new ui.View(options <Object>)

Desktop Applications only.

Create a new View instance. Views provide isolated content views. Frameless, chromeless windows that can be embedded inside other windows and views.

Options

  • x <Integer> - the horizontal position of left side of the view (pixels)
  • y <Integer> - vertical view position (pixels)
  • width <Integer> - the width of the view (pixels)
  • height <Integer> - the height of the view (pixels)
  • backgroundColor <String> Default: '#FFF' - view default background color. Hex, RGB, RGBA, HSL HSLA, CSS color
  • 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.

References

view.on[ce]('message', (...args) => { })

for await (const [ ...args ] of view)

Receive a message from the view. The received args array is deserialized via JSON.parse.

References

const success = await view.open(options <Object>)

Resolves to: <Boolean>

Open the view.

Options

  • x <Integer> - the horizontal position of left side of the view (pixels)
  • y <Integer> - vertical view position (pixels)
  • width <Integer> - the width of the view (pixels)
  • height <Integer> - the height of the view (pixels)
  • backgroundColor <String> Default: '#FFF' - view default background color. Hex, RGB, RGBA, HSL HSLA, CSS color
  • 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.

const success = await view.close()

Resolves to: <Boolean>

Close the view.

const success = await view.show()

Resolves to: <Boolean>

Show the view.

const success = await view.hide()

Resolves to: <Boolean>

Hide the view.

const success = await view.focus()

Resolves to: <Boolean>

Focus the view.

const success = await view.blur()

Resolves to: <Boolean>

Blur the view.

await view.send(...args)

Send arguments to the view. They will be serialized with JSON.stringify.

const sourceId = await view.getMediaSourceId()

Resolves to: <String>

Supplies the id property of objects in the array returned from ui.media.desktopSources.

References

const dimensions = await view.dimensions()

Resolves to: {x <Integer>, y <Integer>, width <Integer>, height <Integer>} | null.

The height, width, horizontal (x), vertical (y) position of the window relative to the screen.

All units are (pixels)

If the Window is closed this will resolve to null.

References

await view.dimensions(options <Object>)

const view = new ui.View('./some.html', {
  x: 10,
  y: 450,
  width: 300,
  height: 350
})

await view.open()
await new Promise((resolve) => setTimeout(resolve, 1000))

await view.dimensions({
  x: 20,
  y: 50,
  width: 550,
  height: 300
})

Sets the dimensions of the view.

Options

  • x <Integer> - the horizontal position of left side of the window (pixels)
  • y <Integer> - the vertical position of the top of the window (pixels)
  • width <Integer> - the width of the window (pixels)
  • height <Integer> - the height of the window (pixels)

References

const visible = await view.isVisible()

Resolves to: <Boolean>

Whether the view is visible.

const closed = await view.isClosed()

Resolves to: <Boolean>

Whether the view is closed.

const { self } = ui.Window const { self } = ui.View

const success = await self.focus()

Resolves to: <Boolean>

Focus current view or window.

const success = await self.blur()

Resolves to: <Boolean>

Blur current view or window.

const success = await self.show()

Resolves to: <Boolean>

Show current view or window.

const success = await self.hide()

Resolves to: <Boolean>

Hide current view or window.

const sourceId = await self.getMediaSourceId()

Get the sourceId of the current window or view.

References

const success = await self.minimize()

Resolves to: <Boolean>

Minimize current window.

Throws a TypeError if self is a view.

const success = await self.maximize()

Resolves to: <Boolean>

Maximize current window.

Throws a TypeError if self is a view.

const success = await self.restore()

Resolves to: <Boolean>

Unmaximize/unminimize the current window if it is currently maximized/minimized.

Throws a TypeError if self is a view.

const success = await self.close()

Resolves to: <Boolean>

Closes the current view or window.

const isVisible = await self.isVisible()

Resolves to: <Boolean>

Whether the current window or view is visible.

const isMaximized = await self.isMaximized()

Resolves to: <Boolean>

Whether the current window is maximized. Throws a TypeError if self is a view.

const isMinimized = await self.isMinimized()

Resolves to: <Boolean>

Whether the current window is minimized. Throws a TypeError if self is a view.

const { parent } = ui.Window const { parent } = ui.View

parent.on[ce]('message', (...args) => { })

for await (const [ ...args ] of parent)

Receive a message from the parent window or view. The received args array is deserialized via JSON.parse.

await parent.send(...args)

Send arguments to the parent view or window. They will be serialized with JSON.stringify.

const success = await parent.focus()

Resolves to: <Boolean>

Focus parent view or window.

const success = await parent.blur()

Resolves to: <Boolean>

Blur parent view or window.

const success = await parent.show()

Resolves to: <Boolean>

Show parent view or window.

const success = await parent.hide()

Resolves to: <Boolean>

Hide parent view or window.

const sourceId = await parent.getMediaSourceId()

Get the sourceId of the parent window or view.

References

const success = await parent.minimize()

Resolves to: <Boolean>

Minimize parent window.

Throws a TypeError if parent is a view.

const success = await parent.maximize()

Resolves to: <Boolean>

Maximize parent window.

Throws a TypeError if parent is a view.

const success = await parent.restore()

Resolves to: <Boolean>

Unmaximize/unminimize the parent window if it is currently maximized/minimized.

Throws a TypeError if parent is a view.

const success = await parent.close()

Resolves to: <Boolean>

Closes the parent view or window.

const isVisible = await parent.isVisible()

Resolves to: <Boolean>

Whether the parent window or view is visible.

const isMaximized = await parent.isMaximized()

Resolves to: <Boolean>

Whether the parent window is maximized. Throws a TypeError if parent is a view.

const isMinimized = await parent.isMinimized()

Resolves to: <Boolean>

Whether the parent window is minimized. Throws a TypeError if parent is a view.

Web APIs

Most Web APIs will work as-is.

This section details deviations in behavior from and notable aspects of Web APIs as they relate to pear-electron.

window.open

The window.open Web API function will ignore all arguments except for the URL parameter.

In browsers, window.open opens a new browser window. The opened window belongs to the same browser from which window.open is called.

With pear-electron UI Library, window.open loads the URL in the default system browser. It does not create a new application window (use Pear.Window to create application windows).

Therefore Pear's window.open only supports a single URL argument. The target and windowFeatures parameters that browsers support are discarded.

Scripts and Modules

Like browsers, there is no support for CommonJS (e.g. the require function as used by Node.js is not supported in Pear Applications).

Like browsers, there is support for native EcmaScript Modules (ESM). A JavaScript Script has no module capabilities. A JavaScript Module has ESM capabilities.

Use <script type="module" src="path/to/my-file.js"> to load a JavaScript Module.

Use <script src="path/to/my-file.js"> to load a JavaScript Script.

Graphical User Interface Options

GUI options for an application are set in the application package.json pear.gui field.

width <Number>

Window width (pixels).

height <Number>

Window height (pixels).

x <Number>

Horizontal window position (pixels).

y <Number>

Vertical window position (pixels).

minWidth <Number>

Window minimum width (pixels).

minHeight <Number>

Window minimum height (pixels).

maxWidth <Number>

Window maximum width (pixels).

maxHeight <Number>

Window maximum height (pixels).

center <Boolean> (default: false)

Center window.

resizable <Boolean> (default: true)

Window resizability.

movable <Boolean> (default: true)

Window movability.

minimizable <Boolean> (default: true)

Window minimizability.

maximizable <Boolean> (default: true)

Window maximizability.

closable <Boolean> (default: true)

Window closability.

focusable <Boolean> (default: true)

Window focusability.

alwaysOnTop <Boolean> (default: false)

Set window to always be on top.

fullscreen <Boolean> (default: false)

Set window to fullscreen on start.

kiosk <Boolean> (default: false)

Set window to enter kiosk mode on start.

autoHideMenuBar <Boolean> (default: false)

Hide menu bar unless Alt key is pressed (Linux, Windows).

hasShadow <Boolean> (default: true)

Window shadow.

opacity <Number> (default: 1)

Set window opacity (0.0 - 1.0) (Windows, macOS).

transparent <Boolean> (default: false)

Enable transparency. Must be set for opacity to work.

backgroundColor <String> (default: "#000" non-transparent, "#00000000" transparent)

Background color (Hex, RGB, RGBA, HSL, HSLA, CSS color).

Development

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.

  • When loaded into a UI, pear-electron is the UI API
  • When loaded into non-UI (i.e app entrypoint js file), pear-electron is the runtime initializor
    • 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>
  • 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.ui.runtime field is then set, with fork and length included. This locks runtime builds for a given semver to a specific runtime drive checkout.
    • This is what pear-electron bootstraps from during runtime.ready().

LICENSE

Apache 2.0

About

Pear User-Interface Library for Electron

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •