react-native-firebase/tests-new/bridge/env/node/vm.js

229 lines
5.5 KiB
JavaScript
Raw Normal View History

2018-03-24 02:02:59 +00:00
const url = require('url');
const http = require('http');
const invariant = require('assert');
const { createContext, Script } = require('vm');
const ws = require('./ws');
let currentContext = null;
let scriptCached = null;
// this is a dummy file path - without a file name the source map is not used in the vm
const TEMP_BUNDLE_PATH = '/tmp/bridge/react-native.js';
/**
*
* @param replyId
* @param result
*/
function sendResult(replyID, result) {
ws.send(
JSON.stringify({
replyID,
result,
})
);
}
/**
2018-03-24 05:53:49 +00:00
* TODO
2018-03-24 02:02:59 +00:00
* @param message
*/
2018-03-24 05:53:49 +00:00
function sendError(error) {
console.log('error');
throw error;
2018-03-24 02:02:59 +00:00
}
/**
*
* @param src
* @param callback
*/
function getScript(src, callback) {
if (scriptCached) return callback(null, scriptCached);
return http
.get(src, res => {
let buff = '';
res.setEncoding('utf8');
res.on('data', chunk => {
buff += chunk;
});
res.on('end', () => {
scriptCached = new Script(buff, {
// lineOffset: -1,
// columnOffset: -1,
timeout: 120000,
displayErrors: true,
produceCachedData: true,
filename: TEMP_BUNDLE_PATH,
});
callback(null, scriptCached);
});
})
.on('error', err => {
callback(err);
});
}
2018-03-24 05:53:49 +00:00
function consoleShim() {
return {
...console,
log(...args) {
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Running application "')
) {
return;
}
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Deprecated')
) {
return;
}
console.log(...args);
},
warn(...args) {
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Running application "')
) {
return;
}
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Deprecated')
) {
return;
}
console.log(...args);
},
};
}
2018-03-24 02:02:59 +00:00
process.on('ws-message', request => {
// console.log(request.method);
switch (request.method) {
case 'prepareJSRuntime':
2018-03-24 05:53:49 +00:00
if (currentContext) {
try {
for (const name in currentContext.__fbBatchedBridge) {
currentContext.__fbBatchedBridge[name] = undefined;
delete currentContext.__fbBatchedBridge[name];
}
for (const name in currentContext.__fbGenNativeModule) {
currentContext.__fbGenNativeModule[name] = undefined;
delete currentContext.__fbGenNativeModule[name];
}
for (const name in currentContext.__fbBatchedBridgeConfig) {
currentContext.__fbBatchedBridgeConfig[name] = undefined;
delete currentContext.__fbBatchedBridgeConfig[name];
}
for (const name in currentContext) {
currentContext[name] = undefined;
delete currentContext[name];
}
} catch (e) {
console.error(e);
}
}
2018-03-24 02:02:59 +00:00
currentContext = undefined;
currentContext = createContext({
2018-03-24 05:53:49 +00:00
console: consoleShim(),
2018-03-24 02:02:59 +00:00
__bridgeNode: {
ready() {
process.emit('rn-ready');
},
provideReactNativeModule(rnModule) {
global.bridge.rn = undefined;
global.bridge.rn = rnModule;
},
provideModule(moduleExports) {
global.bridge.module = undefined;
global.bridge.module = moduleExports;
},
provideReload(reloadFn) {
global.bridge.reload = undefined;
global.bridge.reload = reloadFn;
},
provideRoot(rootComponent) {
global.bridge.root = undefined;
global.bridge.root = rootComponent;
},
},
});
sendResult(request.id);
return;
case 'executeApplicationScript':
// Modify the URL to make sure we get the inline source map.
const parsedUrl = url.parse(request.url, /* parseQueryString */ true);
invariant(parsedUrl.query);
parsedUrl.query.inlineSourceMap = true;
delete parsedUrl.search;
// $FlowIssue url.format() does not accept what url.parse() returns.
const scriptUrl = url.format(parsedUrl);
getScript(scriptUrl, (err, script) => {
if (err != null) {
sendError(`Failed to get script from packager: ${err.message}`);
return;
}
if (currentContext == null) {
sendError('JS runtime not prepared');
return;
}
if (request.inject) {
for (const name in request.inject) {
currentContext[name] = JSON.parse(request.inject[name]);
}
}
try {
script.runInContext(currentContext, TEMP_BUNDLE_PATH);
} catch (e) {
2018-03-24 05:53:49 +00:00
sendError(e);
2018-03-24 02:02:59 +00:00
}
sendResult(request.id);
});
return;
default:
let returnValue = [[], [], [], 0];
try {
if (
currentContext != null &&
typeof currentContext.__fbBatchedBridge === 'object'
) {
returnValue = currentContext.__fbBatchedBridge[request.method].apply(
null,
request.arguments
);
}
} catch (e) {
2018-03-24 05:53:49 +00:00
if (request.method !== '$disconnected') {
sendError(
`Failed while making a call ${request.method}:::${e.message}`
);
}
2018-03-24 02:02:59 +00:00
} finally {
sendResult(request.id, JSON.stringify(returnValue));
}
}
});