flow: renaming, cjs, rollup, etc.
This commit is contained in:
parent
45a5e311a1
commit
9cceaa6d3a
430
comm/cjs/index.js
Normal file
430
comm/cjs/index.js
Normal file
|
@ -0,0 +1,430 @@
|
|||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var events = require('events');
|
||||
var net = require('net');
|
||||
var D = _interopDefault(require('debug'));
|
||||
|
||||
const debugActionIgnore = (process.env.DEBUG_ACTION_IGNORE || '').split(',');
|
||||
|
||||
function createDebugAction(debug, action) {
|
||||
if (!debug.enabled || -1 !== debugActionIgnore.indexOf(action.type)) {
|
||||
return undefined;
|
||||
}
|
||||
const debugAction = {type: action.type, payload: {...action.payload}};
|
||||
if (!process.env.SILLY_DEBUG) {
|
||||
for (const i in debugAction.payload) {
|
||||
// Exceptions...
|
||||
if (
|
||||
// Invocation hook.
|
||||
-1 !== ['@truss/invoke', '@truss/invoke-flat'] && i !== 'hook'
|
||||
) {
|
||||
debugAction.payload[i] = '[...]';
|
||||
}
|
||||
}
|
||||
}
|
||||
return debugAction;
|
||||
}
|
||||
|
||||
function pack(action) { return JSON.stringify(action); }
|
||||
function unpack (serial) { return JSON.parse(serial); }
|
||||
|
||||
let clientId = 0;
|
||||
|
||||
class IpcClient extends events.EventEmitter {
|
||||
|
||||
constructor(service) {
|
||||
super();
|
||||
|
||||
this.id = clientId;
|
||||
|
||||
process.send({
|
||||
type: 'connect',
|
||||
payload: {
|
||||
clientId: this.id,
|
||||
service,
|
||||
},
|
||||
});
|
||||
|
||||
const messageListener = ({type, payload}) => {
|
||||
|
||||
switch (type) {
|
||||
|
||||
case 'connection_to':
|
||||
|
||||
if (payload.clientId !== this.id) { return; }
|
||||
|
||||
this.connection = payload.connection;
|
||||
this.to = payload.to;
|
||||
|
||||
setTimeout(() => {
|
||||
this.emit('ready');
|
||||
}, 0);
|
||||
|
||||
break;
|
||||
|
||||
case 'connection_error':
|
||||
|
||||
if (payload.clientId !== this.id) { return; }
|
||||
|
||||
process.off('message', messageListener);
|
||||
|
||||
setTimeout(() => {
|
||||
this.emit('error', {code: 'ENOTFOUND'});
|
||||
}, 0);
|
||||
|
||||
break;
|
||||
|
||||
case 'client_recv':
|
||||
|
||||
if (payload.clientId !== this.id) { return; }
|
||||
|
||||
process.off('message', messageListener);
|
||||
|
||||
setTimeout(() => {
|
||||
this.emit('data', payload.data);
|
||||
this.emit('end');
|
||||
}, 0);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
process.on('message', messageListener);
|
||||
|
||||
clientId++;
|
||||
}
|
||||
|
||||
end() {}
|
||||
|
||||
setEncoding() {}
|
||||
|
||||
write(data) {
|
||||
|
||||
process.send({
|
||||
type: 'client_send',
|
||||
payload: {
|
||||
clientId: this.id,
|
||||
data,
|
||||
to: this.to,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function client(address) {
|
||||
return new IpcClient(address);
|
||||
}
|
||||
|
||||
class IpcSocket extends events.EventEmitter {
|
||||
|
||||
constructor(clientId, to) {
|
||||
super();
|
||||
|
||||
return {
|
||||
|
||||
emit: this.emit,
|
||||
|
||||
end() {
|
||||
this.emit('end');
|
||||
},
|
||||
|
||||
on: this.on,
|
||||
|
||||
setEncoding() {},
|
||||
|
||||
write(data) {
|
||||
|
||||
process.send({
|
||||
type: 'server_send',
|
||||
payload: {
|
||||
clientId,
|
||||
data,
|
||||
to,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class IpcServer extends events.EventEmitter {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const connections = {};
|
||||
|
||||
return {
|
||||
|
||||
emit: this.emit,
|
||||
|
||||
listen() {
|
||||
|
||||
process.send({
|
||||
type: 'listening',
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.emit('listening');
|
||||
}, 0);
|
||||
|
||||
process.on('message', ({type, payload}) => {
|
||||
|
||||
switch (type) {
|
||||
|
||||
case 'connection_from':
|
||||
|
||||
const socket = new IpcSocket(payload.clientId, payload.from);
|
||||
connections[payload.clientId] = socket;
|
||||
this.emit('connection', socket);
|
||||
|
||||
socket.on('end', () => {
|
||||
delete connections[payload.clientId];
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case 'server_recv':
|
||||
|
||||
if (connections[payload.clientId]) {
|
||||
connections[payload.clientId].emit('data', payload.data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
on: this.on,
|
||||
|
||||
setEncoding() {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function server() {
|
||||
return new IpcServer();
|
||||
}
|
||||
|
||||
const port = process.env.DISPATCHER_PORT || 43170;
|
||||
|
||||
function client$1(address) {
|
||||
return net.createConnection(port, address);
|
||||
}
|
||||
|
||||
function server$1() {
|
||||
const server = net.createServer();
|
||||
const originalListen = server.listen;
|
||||
server.listen = () => {
|
||||
return originalListen.call(server, port);
|
||||
};
|
||||
return server;
|
||||
}
|
||||
|
||||
const debug = D('truss:comm:dispatcher');
|
||||
|
||||
class Dispatcher {
|
||||
|
||||
constructor(actions = (() => ({})), hooks = (() => ({}))) {
|
||||
this.args = [];
|
||||
this.lookup = {actions, hooks};
|
||||
}
|
||||
|
||||
connect() {
|
||||
|
||||
const server$$1 = process.env.TRUSS_IPC ? server() : server$1();
|
||||
|
||||
server$$1.on('connection', (socket) => {
|
||||
socket.on('error', (error) => { this.handleError(error); });
|
||||
|
||||
socket.setEncoding('utf8');
|
||||
socket.on('data', (chunk) => {
|
||||
|
||||
let action = undefined;
|
||||
try { action = unpack(chunk); }
|
||||
catch (error) { return this.handleError(error); }
|
||||
|
||||
const actions = this.createActions();
|
||||
if (!(action.type in actions)) {
|
||||
debug(`discarding ${JSON.stringify(action, null, ' ')}!`);
|
||||
return;
|
||||
}
|
||||
|
||||
const debugAction = createDebugAction(debug, action);
|
||||
if (debugAction) {
|
||||
debug(`dispatching ${JSON.stringify(debugAction, null, ' ')}`);
|
||||
}
|
||||
const actionPromise = actions[action.type](action);
|
||||
Promise.resolve(actionPromise).then((result) => {
|
||||
if ('undefined' === typeof result) {
|
||||
debug(`undefined result from ${action.type} not forwarded!`);
|
||||
}
|
||||
else {
|
||||
socket.write(pack(result));
|
||||
}
|
||||
socket.end();
|
||||
}).catch((error) => { this.handleError(error); });
|
||||
});
|
||||
});
|
||||
|
||||
server$$1.on('listening', () => {
|
||||
debug(`dispatcher listening...`);
|
||||
});
|
||||
|
||||
server$$1.listen();
|
||||
|
||||
return server$$1;
|
||||
}
|
||||
|
||||
createActions() {
|
||||
|
||||
const actions = this.lookup.actions(...this.args);
|
||||
const hooks = this.lookup.hooks(...this.args);
|
||||
|
||||
// builtin hook plumbing
|
||||
actions['@truss/hook'] = (action) => {
|
||||
if (!(action.payload.hook in hooks)) { return undefined; }
|
||||
return hooks[action.payload.hook](...action.payload.args);
|
||||
};
|
||||
|
||||
// builtin schema
|
||||
const originalSchema = actions['@truss/schema'] || (() => ({}));
|
||||
actions['@truss/schema'] = (action) => {
|
||||
return {...originalSchema(action), hooks: Object.keys(hooks)};
|
||||
};
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
lookupActions(lookup) { this.lookup.actions = lookup; }
|
||||
|
||||
lookupHooks(lookup) { this.lookup.hooks = lookup; }
|
||||
|
||||
setArgs(...args) { this.args = args; }
|
||||
}
|
||||
|
||||
const debug$1 = D('truss:comm');
|
||||
|
||||
function createDispatcher(...args) {
|
||||
|
||||
if (0 === args.length) {
|
||||
return new Dispatcher();
|
||||
}
|
||||
|
||||
if ('function' !== typeof args[0]) {
|
||||
const value = args[0];
|
||||
args[0] = () => value;
|
||||
}
|
||||
|
||||
if (1 === args.length) {
|
||||
return new Dispatcher(args[0]);
|
||||
}
|
||||
|
||||
if ('function' !== typeof args[1]) {
|
||||
const value = args[1];
|
||||
args[1] = () => value;
|
||||
}
|
||||
|
||||
if (2 === args.length) {
|
||||
return new Dispatcher(args[0], args[1]);
|
||||
}
|
||||
}
|
||||
function invokeHook(hook, ...args) {
|
||||
return sendActionToService({
|
||||
type: '@truss/invoke', payload: {hook, args},
|
||||
}, 'gateway');
|
||||
}
|
||||
function invokeHookFlat(hook, ...args) {
|
||||
return sendActionToService({
|
||||
type: '@truss/invoke-flat', payload: {hook, args},
|
||||
}, 'gateway');
|
||||
}
|
||||
function invokeHookReduce(hook, rhs, ...args) {
|
||||
return servicesImplementingHook(hook).then((services) => {
|
||||
return services.reduce((promise, service) => {
|
||||
return promise.then((rhs) => {
|
||||
return invokeServiceHook(service, hook, rhs, ...args);
|
||||
});
|
||||
}, Promise.resolve(rhs));
|
||||
});
|
||||
}
|
||||
function invokeServiceHook(service, hook, ...args) {
|
||||
return sendActionToService({
|
||||
type: '@truss/hook', payload: {hook, args},
|
||||
}, service);
|
||||
}
|
||||
function sendActionToService(action, service) {
|
||||
|
||||
const createClient = process.env.TRUSS_IPC ? client : client$1;
|
||||
const client$$1 = createClient(service);
|
||||
client$$1.setEncoding('utf8');
|
||||
|
||||
client$$1.on('ready', writeClientPacket);
|
||||
|
||||
let response = '';
|
||||
client$$1.on('data', (chunk) => {
|
||||
response += chunk;
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
client$$1.on('error', (error) => {
|
||||
// try try again...
|
||||
if (-1 !== ['ECONNREFUSED', 'ENOTFOUND'].indexOf(error.code)) {
|
||||
debug$1(`Can't connect to ${service}, retrying in 1 second...`);
|
||||
return resolve(tryAgain());
|
||||
}
|
||||
reject(error);
|
||||
});
|
||||
client$$1.on('end', () => {
|
||||
try {
|
||||
resolve(response ? unpack(response) : undefined);
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function tryAgain() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(sendActionToService(action, service));
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function writeClientPacket() {
|
||||
const debugAction = createDebugAction(debug$1, action);
|
||||
if (debugAction) {
|
||||
debug$1(`sendActionToService(${
|
||||
JSON.stringify(debugAction, null, ' ')
|
||||
}, '${service}')`);
|
||||
}
|
||||
client$$1.write(pack(action));
|
||||
}
|
||||
}
|
||||
|
||||
function servicesImplementingHook(hook) {
|
||||
return sendActionToService({
|
||||
type: '@truss/hook-services', payload: {hook},
|
||||
}, 'gateway');
|
||||
}
|
||||
|
||||
exports.createDispatcher = createDispatcher;
|
||||
exports.invokeHook = invokeHook;
|
||||
exports.invokeHookFlat = invokeHookFlat;
|
||||
exports.invokeHookReduce = invokeHookReduce;
|
||||
exports.invokeServiceHook = invokeServiceHook;
|
||||
exports.sendActionToService = sendActionToService;
|
||||
exports.servicesImplementingHook = servicesImplementingHook;
|
||||
exports.createDebugAction = createDebugAction;
|
|
@ -10,7 +10,7 @@ export function createDebugAction(debug, action) {
|
|||
// Exceptions...
|
||||
if (
|
||||
// Invocation hook.
|
||||
-1 !== ['truss/invoke', 'truss/invoke-flat'] && i !== 'hook'
|
||||
-1 !== ['@truss/invoke', '@truss/invoke-flat'] && i !== 'hook'
|
||||
) {
|
||||
debugAction.payload[i] = '[...]';
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
const {createDebugAction} = require('./debug');
|
||||
const {pack, unpack} = require('./packer');
|
||||
import {createDebugAction} from './debug';
|
||||
import {pack, unpack} from './packer';
|
||||
import {server as createIpcServer} from './socket.ipc';
|
||||
import {server as createNetServer} from './socket.net';
|
||||
|
||||
const debug = require('debug')('truss:comm:dispatcher');
|
||||
import D from 'debug';
|
||||
const debug = D('truss:comm:dispatcher');
|
||||
|
||||
export class Dispatcher {
|
||||
|
||||
|
@ -12,9 +15,9 @@ export class Dispatcher {
|
|||
|
||||
connect() {
|
||||
|
||||
const netServer = require('./socket.ipc').server();
|
||||
const server = process.env.TRUSS_IPC ? createIpcServer() : createNetServer();
|
||||
|
||||
netServer.on('connection', (socket) => {
|
||||
server.on('connection', (socket) => {
|
||||
socket.on('error', (error) => { this.handleError(error); });
|
||||
|
||||
socket.setEncoding('utf8');
|
||||
|
@ -47,13 +50,13 @@ export class Dispatcher {
|
|||
});
|
||||
});
|
||||
|
||||
netServer.on('listening', () => {
|
||||
server.on('listening', () => {
|
||||
debug(`dispatcher listening...`);
|
||||
});
|
||||
|
||||
netServer.listen();
|
||||
server.listen();
|
||||
|
||||
return netServer;
|
||||
return server;
|
||||
}
|
||||
|
||||
createActions() {
|
||||
|
@ -62,14 +65,14 @@ export class Dispatcher {
|
|||
const hooks = this.lookup.hooks(...this.args);
|
||||
|
||||
// builtin hook plumbing
|
||||
actions['truss/hook'] = (action) => {
|
||||
actions['@truss/hook'] = (action) => {
|
||||
if (!(action.payload.hook in hooks)) { return undefined; }
|
||||
return hooks[action.payload.hook](...action.payload.args);
|
||||
}
|
||||
|
||||
// builtin schema
|
||||
const originalSchema = actions['truss/schema'] || (() => ({}));
|
||||
actions['truss/schema'] = (action) => {
|
||||
const originalSchema = actions['@truss/schema'] || (() => ({}));
|
||||
actions['@truss/schema'] = (action) => {
|
||||
return {...originalSchema(action), hooks: Object.keys(hooks)};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
const {createDebugAction} = require('./debug');
|
||||
const {pack, unpack} = require('./packer');
|
||||
const {Dispatcher} = require('./dispatcher');
|
||||
import {createDebugAction} from './debug';
|
||||
import {pack, unpack} from './packer';
|
||||
import {Dispatcher} from './dispatcher';
|
||||
import {client as createIpcClient} from './socket.ipc';
|
||||
import {client as createNetClient} from './socket.net';
|
||||
|
||||
const debug = require('debug')('truss:comm');
|
||||
import D from 'debug';
|
||||
const debug = D('truss:comm');
|
||||
|
||||
export function createDispatcher(...args) {
|
||||
|
||||
|
@ -31,17 +34,17 @@ export function createDispatcher(...args) {
|
|||
|
||||
export function invokeHook(hook, ...args) {
|
||||
return sendActionToService({
|
||||
type: 'truss/invoke', payload: {hook, args},
|
||||
type: '@truss/invoke', payload: {hook, args},
|
||||
}, 'gateway');
|
||||
};
|
||||
|
||||
export function invokeHookFlat(hook, ...args) {
|
||||
return sendActionToService({
|
||||
type: 'truss/invoke-flat', payload: {hook, args},
|
||||
type: '@truss/invoke-flat', payload: {hook, args},
|
||||
}, 'gateway');
|
||||
};
|
||||
|
||||
export function invokeHookSerial(hook, rhs, ...args) {
|
||||
export function invokeHookReduce(hook, rhs, ...args) {
|
||||
return servicesImplementingHook(hook).then((services) => {
|
||||
return services.reduce((promise, service) => {
|
||||
return promise.then((rhs) => {
|
||||
|
@ -53,13 +56,14 @@ export function invokeHookSerial(hook, rhs, ...args) {
|
|||
|
||||
export function invokeServiceHook(service, hook, ...args) {
|
||||
return sendActionToService({
|
||||
type: 'truss/hook', payload: {hook, args},
|
||||
type: '@truss/hook', payload: {hook, args},
|
||||
}, service);
|
||||
};
|
||||
|
||||
export function sendActionToService(action, service) {
|
||||
|
||||
const client = require('./socket.ipc').client(service);
|
||||
const createClient = process.env.TRUSS_IPC ? createIpcClient : createNetClient;
|
||||
const client = createClient(service);
|
||||
client.setEncoding('utf8');
|
||||
|
||||
client.on('ready', writeClientPacket);
|
||||
|
@ -109,7 +113,7 @@ export function sendActionToService(action, service) {
|
|||
|
||||
export function servicesImplementingHook(hook) {
|
||||
return sendActionToService({
|
||||
type: 'truss/hook-services', payload: {hook},
|
||||
type: '@truss/hook-services', payload: {hook},
|
||||
}, 'gateway');
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{
|
||||
"name": "@truss/comm",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"main": "./cjs",
|
||||
"module": "./index",
|
||||
"author": "cha0s",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const {EventEmitter} = require('events');
|
||||
import {EventEmitter} from 'events';
|
||||
|
||||
let clientId = 0;
|
||||
|
||||
|
@ -84,7 +84,7 @@ class IpcClient extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
exports.client = function(address) {
|
||||
export function client(address) {
|
||||
return new IpcClient(address);
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,6 @@ class IpcServer extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
exports.server = function() {
|
||||
export function server() {
|
||||
return new IpcServer();
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
const net = require('net');
|
||||
import {createConnection, createServer} from 'net';
|
||||
|
||||
const port = process.env.DISPATCHER_PORT || 43170;
|
||||
|
||||
exports.client = (address) => {
|
||||
return net.createConnection(port, address);
|
||||
};
|
||||
|
||||
exports.server = () => {
|
||||
const server = net.createServer();
|
||||
export function client(address) {
|
||||
return createConnection(port, address);
|
||||
}
|
||||
|
||||
export function server() {
|
||||
const server = createServer();
|
||||
const originalListen = server.listen;
|
||||
server.listen = () => {
|
||||
return originalListen.call(server, port);
|
||||
}
|
||||
|
||||
return server;
|
||||
};
|
||||
}
|
||||
|
|
9
core/cjs/index.js
Normal file
9
core/cjs/index.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
exports.servicesList = () => {
|
||||
const services = process.env.SERVICES.split(',');
|
||||
if (-1 === services.indexOf('gateway')) {
|
||||
services.unshift('gateway');
|
||||
}
|
||||
return services;
|
||||
};
|
|
@ -2,7 +2,8 @@
|
|||
"name": "@truss/core",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"main": "./cjs",
|
||||
"module": "./index",
|
||||
"author": "cha0s",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
|
|
74
docker/cjs/index.js
Normal file
74
docker/cjs/index.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
'use strict';
|
||||
|
||||
// Core.
|
||||
const fs = require('fs');
|
||||
// 3rd-party.
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
exports.emitComposeFile = function(services) {
|
||||
return emitString(emitObject(services));
|
||||
};
|
||||
|
||||
function emitString(object) {
|
||||
return yaml.safeDump(object);
|
||||
}
|
||||
|
||||
function emitObject(services) {
|
||||
const composeFile = {
|
||||
version: '3',
|
||||
services: {},
|
||||
};
|
||||
const cwd = process.cwd();
|
||||
for (const service of services) {
|
||||
composeFile.services[service] = emitService(service);
|
||||
const modulePath = `${cwd}/services/${service}/compose`;
|
||||
try {
|
||||
require(modulePath)(composeFile.services[service], composeFile);
|
||||
}
|
||||
catch (error) {
|
||||
if (`Cannot find module '${modulePath}'` !== error.message) {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return composeFile;
|
||||
}
|
||||
|
||||
function emitService(service) {
|
||||
const definition = {};
|
||||
if ('production' === process.env.NODE_ENV) {
|
||||
definition.image = 'docker.i12e.cha0s.io/cha0s6983/truss-production';
|
||||
}
|
||||
else {
|
||||
definition.image = 'docker.i12e.cha0s.io/cha0s6983/truss-dev';
|
||||
}
|
||||
if ('production' === process.env.NODE_ENV) {
|
||||
definition.env_file = [
|
||||
'.env',
|
||||
];
|
||||
}
|
||||
else {
|
||||
definition.env_file = [
|
||||
'.common.env', `.dev.env`, '.env',
|
||||
];
|
||||
}
|
||||
if ('production' === process.env.NODE_ENV) {
|
||||
definition.volumes = [
|
||||
`./${service}:/var/node/dist`,
|
||||
];
|
||||
}
|
||||
else {
|
||||
definition.volumes = [
|
||||
`./services/${service}:/var/node/src`,
|
||||
`./dist/dev/${service}:/var/node/dist`,
|
||||
];
|
||||
// Add individual lib entries.
|
||||
const cwd = process.cwd();
|
||||
const entries = fs.readdirSync(`${cwd}/lib`);
|
||||
for (const entry of entries) {
|
||||
definition.volumes.push(`./lib/${entry}:/var/node/lib/${entry}`);
|
||||
}
|
||||
}
|
||||
return definition;
|
||||
}
|
|
@ -2,7 +2,8 @@
|
|||
"name": "@truss/docker",
|
||||
"version": "1.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"main": "./cjs",
|
||||
"module": "./index",
|
||||
"author": "cha0s",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
|
|
35
emitters/cjs/index.js
Normal file
35
emitters/cjs/index.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
'use strict';
|
||||
|
||||
// 2nd.
|
||||
const {sendActionToService} = require('@truss/comm');
|
||||
const debug = require('debug')('truss:emitters');
|
||||
exports.ActionEmitter = class ActionEmitter {
|
||||
|
||||
constructor(executors, listeners) {
|
||||
this.executors = executors;
|
||||
this.listeners = listeners;
|
||||
}
|
||||
onExecutorResponse(res, eres) {
|
||||
}
|
||||
|
||||
onNoExecutor(res) {
|
||||
}
|
||||
|
||||
processAction(action, res) {
|
||||
debug(`Processing ${action.type}...`);
|
||||
// listeners...
|
||||
for (service of this.listeners[action.type] || []) {
|
||||
sendActionToService(action, service).done();
|
||||
}
|
||||
// executor
|
||||
if (!(action.type in this.executors)) {
|
||||
debug(`No executor for ${action.type}!`);
|
||||
this.onNoExecutor(action, res);
|
||||
return;
|
||||
}
|
||||
sendActionToService(action, this.executors[action.type]).then((eres) => {
|
||||
this.onExecutorResponse(action, res, eres);
|
||||
}).catch(console.error);
|
||||
}
|
||||
|
||||
};
|
85
emitters/http.js
Normal file
85
emitters/http.js
Normal file
|
@ -0,0 +1,85 @@
|
|||
const {createServer} = require('http');
|
||||
const bodyParser = require('body-parser');
|
||||
const {invokeHookReduce} = require('@truss/comm');
|
||||
const {ActionEmitter} = require('./index');
|
||||
const debug = require('debug')('truss:emitters:http');
|
||||
const parser = bodyParser.json();
|
||||
|
||||
module.exports = class HttpActionEmitter extends ActionEmitter {
|
||||
|
||||
constructor(executors, listeners) {
|
||||
super(executors, listeners);
|
||||
this.server = createServer();
|
||||
}
|
||||
|
||||
listen() {
|
||||
const port = process.env.GATEWAY_PORT || 8000;
|
||||
this.server.listen(port);
|
||||
this.server.on('listening', () => {
|
||||
debug(`listening on port ${port}...`);
|
||||
})
|
||||
this.server.on('request', (req, res) => { parser(req, res, () => {
|
||||
const method = req.method.toLowerCase();
|
||||
const url = req.url;
|
||||
debug(`${method} ${url}`);
|
||||
// map to action
|
||||
const headers = {
|
||||
...req.headers,
|
||||
...{
|
||||
connection: undefined,
|
||||
host: undefined,
|
||||
}
|
||||
};
|
||||
const action = {
|
||||
type: undefined,
|
||||
payload: {
|
||||
headers: headers,
|
||||
method: method,
|
||||
url: url,
|
||||
}
|
||||
};
|
||||
switch (method) {
|
||||
case 'post':
|
||||
// truss action
|
||||
if (url.startsWith('/truss/action/')) {
|
||||
action.type = url.substr('/truss/action/'.length);
|
||||
}
|
||||
// @truss/http-post
|
||||
else {
|
||||
action.type = '@truss/http-post';
|
||||
}
|
||||
action.payload = req.body;
|
||||
break;
|
||||
default:
|
||||
// @truss/http-(get|delete|...)
|
||||
action.type = `@truss/http-${method}`;
|
||||
break;
|
||||
}
|
||||
this.processAction(action, res);
|
||||
})});
|
||||
}
|
||||
|
||||
onExecutorResponse(action, res, eres) {
|
||||
const {payload: {headers: actionHeaders}} = action;
|
||||
const {status, headers, response} = eres;
|
||||
const reduced$ = invokeHookReduce(
|
||||
'@truss/emitters/http', eres, actionHeaders
|
||||
);
|
||||
reduced$.then(({status, headers, response}) => {
|
||||
res.writeHead(status || 200, headers);
|
||||
res.end(response);
|
||||
});
|
||||
}
|
||||
|
||||
onNoExecutor(action, res) {
|
||||
res.writeHead(501);
|
||||
res.end(
|
||||
'<!DOCTYPE html><html><body><h1>501 Not Implemented</h1></body></html>'
|
||||
);
|
||||
}
|
||||
|
||||
unlisten() {
|
||||
this.server.close();
|
||||
}
|
||||
}
|
||||
|
33
emitters/index.js
Normal file
33
emitters/index.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
// 2nd.
|
||||
const {sendActionToService} = require('@truss/comm');
|
||||
const debug = require('debug')('truss:emitters');
|
||||
exports.ActionEmitter = class ActionEmitter {
|
||||
|
||||
constructor(executors, listeners) {
|
||||
this.executors = executors;
|
||||
this.listeners = listeners;
|
||||
}
|
||||
onExecutorResponse(res, eres) {
|
||||
}
|
||||
|
||||
onNoExecutor(res) {
|
||||
}
|
||||
|
||||
processAction(action, res) {
|
||||
debug(`Processing ${action.type}...`);
|
||||
// listeners...
|
||||
for (service of this.listeners[action.type] || []) {
|
||||
sendActionToService(action, service).done();
|
||||
}
|
||||
// executor
|
||||
if (!(action.type in this.executors)) {
|
||||
debug(`No executor for ${action.type}!`);
|
||||
this.onNoExecutor(action, res);
|
||||
return;
|
||||
}
|
||||
sendActionToService(action, this.executors[action.type]).then((eres) => {
|
||||
this.onExecutorResponse(action, res, eres);
|
||||
}).catch(console.error);
|
||||
}
|
||||
|
||||
}
|
16
emitters/package.json
Normal file
16
emitters/package.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "@truss/emitters",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "./cjs",
|
||||
"module": "./index",
|
||||
"author": "cha0s",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.i12e.cha0s.io"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "3.1.0",
|
||||
"supports-color": "5.4.0"
|
||||
}
|
||||
}
|
9
rollup.sh
Executable file
9
rollup.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
cwd=$(pwd)
|
||||
for path in *; do
|
||||
if [ -d "$path" ]; then
|
||||
echo "rollup $path..."
|
||||
cd $path
|
||||
rollup index.js -o cjs/index.js -f cjs
|
||||
cd "$cwd"
|
||||
fi
|
||||
done
|
2
webpack/cjs/index.js
Normal file
2
webpack/cjs/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
'use strict';
|
||||
|
|
@ -17,7 +17,10 @@ function defaultConfig() {
|
|||
const config = {
|
||||
mode: 'production' !== process.env.NODE_ENV ? 'development' : 'production',
|
||||
entry: {
|
||||
index: path.join(SOURCE_PATH, 'index.js'),
|
||||
index: [
|
||||
'@babel/polyfill',
|
||||
path.join(SOURCE_PATH, 'index.js'),
|
||||
]
|
||||
},
|
||||
target: 'node',
|
||||
output: {
|
||||
|
@ -85,6 +88,7 @@ function defaultConfig() {
|
|||
],
|
||||
resolve: {
|
||||
alias: {},
|
||||
mainFields: ['module', 'main'],
|
||||
modules: [path.join(OUTPUT_PATH, 'node_modules')],
|
||||
},
|
||||
resolveLoader: {
|
||||
|
@ -109,8 +113,6 @@ function defaultConfig() {
|
|||
config.externals = [];
|
||||
}
|
||||
|
||||
config.resolve.alias['./socket.ipc'] = './socket.net';
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user