UNPKG

vigour-wrapper-bridge

Version:

the bridge over which JavaScript talks to Native in apps wrapped by vigour-wrapper

183 lines (173 loc) 5.58 kB
'use strict' var Observable = require('vigour-observable') // var Event = require('vigour-event') var set = require('lodash.set') var nameSpace = require('./util/namespace') var bridge = module.exports = exports = new Observable({ properties: { plugins: { val: {} }, readies: { val: {} }, nativeReadies: { val: {} } }, define: { send (pluginId, fnName, opts, cb) { // console.log('\n\n>>>>>>>>>>>>>>> bridge.send') // console.log('pluginId', pluginId) // console.log('fnName', fnName) // console.log('opts', opts) // console.log('\n\n') if (!cb) { cb = opts opts = null } if (bridge.platform) { // console.log('platform found') let plugin = bridge.readies[pluginId] if (plugin) { // console.log('plugin ready') var cbId = callbackId callbackId += 1 callbackMap[cbId] = { plugin: plugin, cb: cb } try { bridge.platform.send(pluginId, fnName, opts, cbId, function (err) { cb(err) delete callbackMap[cbId] }) // console.log('bridge.platform.sent!') } catch (e) { console.error('`send` called failed', e) cb(e) } } else { // console.warn('plugin not ready') if (!pending[pluginId]) { pending[pluginId] = [] } pending[pluginId].push(arguments) } } else { console.error('`send` platform not available') cb(new Error('could not find platform integration')) } }, ready (err, response, pluginId) { // console.log('\n\n<<<<<<<<<<<<<<< bridge.ready', arguments) if (pluginId) { pluginId = nameSpace(pluginId) // console.log('pluginId', pluginId) // console.log('err', err) // console.log('response', response) // console.log('pluginId', pluginId) // console.log('\n\n') let bridgePlugin = bridge.plugins[pluginId] bridge.nativeReadies[pluginId] = true if (bridgePlugin) { if (err) { bridgePlugin.emit('error', err) } else { // console.log('--- set platform ready!', pluginId, bridgePlugin) if (!bridgePlugin.parent) { throw Error('bridgePlugin ' + pluginId + ' has no parent!') } if (!bridgePlugin.parent.ready) { throw Error('bridgePlugin.parent' + pluginId + ' has no ready!') } bridgePlugin.ready.val = true bridge.readies[pluginId] = bridgePlugin let pendingSends = pending[pluginId] if (pendingSends) { let tosend while ((tosend = pendingSends.shift())) { this.send.apply(this, tosend) } } } } else { // this will always happen the first time now... // console.error('could not find that plugin', pluginId) } } else { if (err) { bridge.emit('error', err) } else { bridge.emit('ready', response) } } }, result (cbId, err, response) { try { response = JSON.parse(response) } catch (unimportantErr) { // console.log('could not parse', response) } // console.log('\n\n<<<<<<<<<<<<<<< bridge.result') // console.log('cbId', cbId) // console.log('err', err) // console.log('response', response) // console.log('\n\n') var caller = callbackMap[cbId] if (!caller) { let errorMessage = 'could not find callback ' + cbId console.error(errorMessage) bridge.emit('error', new Error(errorMessage)) } else { if (err) { caller.plugin.emit('error', {err, response}) } if (caller.cb) { caller.cb(err, response) } delete callbackMap[cbId] } }, receive (eventType, data, pluginId) { // console.log('\n\n<<<<<<<<<<<<<<< bridge.receive') // console.log('eventType', eventType) // console.log('data', data) if (pluginId) { pluginId = nameSpace(pluginId) // console.log('pluginId', pluginId) // console.log('\n\n') var plugin = bridge.plugins[pluginId] if (!plugin) { let errorMessage = 'could not emit on Plugin: ' + pluginId console.log(errorMessage) bridge.emit('error', new Error(errorMessage)) } else { if (typeof data === 'string') { try { data = JSON.parse(data) } catch (err) { // console.log('data string cannot be `JSON.parse`d', err) } } // passing events now always blocks listeners? // var ev = new Event('data') // ev.stamp = 'bridge' // plugin.emit(eventType, data, ev) // console.log('emitting', eventType, data) plugin.emit(eventType, data) } } else { // console.log('no pluginId!', pluginId) bridge.emit(eventType, data) } } } }) // TODO Eliminate code for other platforms during build process bridge.platform = require('./platform') var callbackMap = {} var callbackId = 0 var pending = {} if (typeof window !== 'undefined') { set(window, 'vigour.native.bridge', bridge) } bridge.platform.emit('bridgeReady')