edge-core-js
Version:
Edge account & wallet management library
122 lines (86 loc) • 3.35 kB
JavaScript
function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }import { navigateDisklet } from 'disklet'
import { makeLog } from '../log/log'
const allPlugins = {}
let allPluginsLocked = false
const onPluginsAdded = []
const onPluginsLocked = []
/**
* Adds plugins to the core.
*/
export function addEdgeCorePlugins(plugins) {
if (allPluginsLocked) {
throw new Error('The Edge core plugin list has already been locked')
}
// Save the new plugins:
for (const pluginId of Object.keys(plugins)) {
allPlugins[pluginId] = plugins[pluginId]
}
// Update already-booted contexts:
for (const f of onPluginsAdded) f(plugins)
}
/**
* Finalizes the core plugin list, so no further plugins are expected.
*/
export function lockEdgeCorePlugins() {
allPluginsLocked = true
for (const f of onPluginsLocked) f()
}
/**
* Subscribes a context object to the core plugin list.
*/
export function watchPlugins(
ios,
infoCache,
logBackend,
pluginsInit,
dispatch
) {
const { io, nativeIo } = ios
const legacyIo = { ...io, console }
function pluginsAdded(plugins) {
const out = {}
for (const pluginId of Object.keys(plugins)) {
const plugin = plugins[pluginId]
const log = makeLog(logBackend, pluginId)
const initOptions = pluginsInit[pluginId]
if (initOptions === false || initOptions == null) continue
// Figure out what kind of object this is:
try {
if (typeof plugin === 'function') {
const opts = {
infoPayload: _nullishCoalesce(_optionalChain([infoCache, 'access', _ => _.corePlugins, 'optionalAccess', _2 => _2[pluginId]]), () => ( {})),
initOptions: typeof initOptions === 'object' ? initOptions : {},
io: legacyIo,
log,
nativeIo,
pluginDisklet: navigateDisklet(io.disklet, 'plugins/' + pluginId)
}
out[pluginId] = plugin(opts)
} else if (typeof plugin === 'object' && plugin != null) {
out[pluginId] = plugin
} else {
throw new TypeError(
`Plugins must be functions or objects, got ${typeof plugin}`
)
}
} catch (error) {
// Show the error but keep going:
log.error(error)
}
}
dispatch({ type: 'CORE_PLUGINS_ADDED', payload: out })
}
function pluginsLocked() {
dispatch({ type: 'CORE_PLUGINS_LOCKED', payload: pluginsInit })
}
// Add any plugins currently available:
pluginsAdded(allPlugins)
if (allPluginsLocked) pluginsLocked()
// Save the callbacks:
onPluginsAdded.push(pluginsAdded)
onPluginsLocked.push(pluginsLocked)
return () => {
onPluginsAdded.filter(f => f !== pluginsAdded)
onPluginsLocked.filter(f => f !== pluginsLocked)
}
}