Skip to content

Commit

Permalink
feat(utils): new utilities for transfer, forward & logging
Browse files Browse the repository at this point in the history
affects: @tao.js/utils

new utilities added to utils package for:
- transfering 1 AC to another
- forwarding 1 AC to another
- easily logging ACs
  • Loading branch information
eudaimos committed Mar 9, 2024
1 parent aeb42f9 commit d71ef74
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 0 deletions.
85 changes: 85 additions & 0 deletions packages/tao-utils/src/forward-chain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { AppCtx, INTERCEPT, ASYNC, INLINE } from '@tao.js/core';
import { transferToAppCtx } from './transfer';

function forward(kernel, from, to, type, opts) {
const { t, term, a, action, o, orient } = to;
const handler = (tao, data) => transferToAppCtx(tao, data, to, opts);
kernel[`add${type}Handler`](from, handler);
handler.remove = () => kernel[`remove${type}Handler`](from, handler);
return handler;
}

/**
* Convenience function that strictly copies the Incoming (from) Application Context to the defined Outgoing (to)
* Application Context to chain it along using an `InlineHandler` setting the data as:
* - from.t => to.t
* - from.a => to.a
* - from.o => to.o
*
* Returns the created handler function as well as a .remove() function on the handler to
* automatically remove it from the kernel that was passed in
*
* @export
* @param {any} kernel a TAO Kernel (TAO) that can attach handlers and receive TAO signals
* @param {any} from trigram representing the Application Context to chain from
* @param {any} to trigram representing the Application Context to chain to
* @param {{
* transformTerm: function,
* transformAction: function,
* transformOrient: function,
* }} opts optional functions to transform the datagrams in the new AppCtx
* @return {function} the handler so that it can be removed from the kernel if needed
*/
export function forwardInline(kernel, from, to, opts) {
return forward(kernel, from, to, INLINE, opts);
}

/**
* Convenience function that strictly copies the Incoming (from) Application Context to the defined Outgoing (to)
* Application Context to chain it along using an `AsyncHandler` setting the data as:
* - from.t => to.t
* - from.a => to.a
* - from.o => to.o
*
* Returns the created handler function as well as a .remove() function on the handler to
* automatically remove it from the kernel that was passed in
*
* @export
* @param {any} kernel a TAO Kernel (TAO) that can attach handlers and receive TAO signals
* @param {any} from trigram representing the Application Context to chain from
* @param {any} to trigram representing the Application Context to chain to
* @param {{
* transformTerm: function,
* transformAction: function,
* transformOrient: function,
* }} opts optional functions to transform the datagrams in the new AppCtx
* @return {function} the handler so that it can be removed from the kernel if needed
*/
export function forwardAsync(kernel, from, to, opts) {
return forward(kernel, from, to, ASYNC, opts);
}

/**
* Convenience function that strictly copies the Incoming (from) Application Context to the defined Outgoing (to)
* Application Context to chain it along using an `InterceptHandler` setting the data as:
* - from.t => to.t
* - from.a => to.a
* - from.o => to.o
*
* Returns the created handler function as well as a .remove() function on the handler to
* automatically remove it from the kernel that was passed in
*
* @export
* @param {any} kernel a TAO Kernel (TAO) that can attach handlers and receive TAO signals
* @param {any} from trigram representing the Application Context to chain from
* @param {any} to trigram representing the Application Context to chain to
* @param {{
* transformTerm: function,
* transformAction: function,
* transformOrient: function,
* }} opts optional functions to transform the datagrams in the new AppCtx
* @return {function} the handler so that it can be removed from the kernel if needed
*/
export function forwardIntercept(kernel, from, to, opts) {
return forward(kernel, from, to, INTERCEPT, opts);
}
3 changes: 3 additions & 0 deletions packages/tao-utils/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ import Transponder from './Transponder';
import Transceiver from './Transceiver';
import seive from './seive';
export * from './bridge';
export * from './transfer';
export * from './forward-chain';
export * from './logger';

export { trigramFilter, Channel, Source, Transponder, Transceiver, seive };
57 changes: 57 additions & 0 deletions packages/tao-utils/src/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { inspect } from 'util';

function inspectObject(obj, depth) {
return inspect(obj, false, depth, true);
}

export function TaoLogger(
doLogging = true,
{ verbose = false, depth = 0, group = false, logger = console } = {}
) {
let inspector = null;
if (!depth && depth !== null) {
inspector = obj => obj;
} else {
inspector = obj => inspectObject(obj, depth);
}
return {
handler: (tao, data) => {
if (!doLogging) {
return;
}
if (!group) {
logger.info(`☯{${tao.t}, ${tao.a}, ${tao.o}}:`);
if (!verbose) {
return;
}
} else {
logger.groupCollapsed(`☯{${tao.t}, ${tao.a}, ${tao.o}}:`);
}
logger.info(`${tao.t}:\n`, inspector(data[tao.t]));
logger.info(`${tao.a}:\n`, inspector(data[tao.a]));
logger.info(`${tao.o}:\n`, inspector(data[tao.o]));
if (group) {
logger.groupEnd();
}
},
doLogging: v => {
doLogging = !!v;
},
verbose: v => {
verbose = !!v;
},
depth: v => {
if (!v && !v === null) {
inspector = obj => obj;
} else {
inspector = obj => inspectObject(obj, v);
}
},
group: v => {
group = !!v;
},
setLogger: l => {
logger = l;
}
};
}
94 changes: 94 additions & 0 deletions packages/tao-utils/src/transfer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { AppCtx } from '@tao.js/core';

const IDENTITY = val => val;

/**
* Transfer the trigram and datagrams into a new Signal as an AppCtx
*
* @param {*} tao signal trigram that you want to transfer from
* @param {*} data signal datagram that you want to transfer from
* @param {*} to signal trigram that you want to transfer to - any missing trigram (t, a, or o) will use the value from the `tao` argument
* @param {{
* transformTerm: function,
* transformAction: function,
* transformOrient: function,
* }} options optional functions to transform the datagrams in the new AppCtx
* @returns AppCtx with the trigram of the `to` argument and the data from the `data` argument
*/
export function transferToAppCtx(
tao,
data,
to,
{
transformTerm = IDENTITY,
transformAction = IDENTITY,
transformOrient = IDENTITY
} = {}
) {
const { t, term, a, action, o, orient } = to;
return new AppCtx(
t || term || tao.t,
a || action || tao.a,
o || orient || tao.o,
transformTerm(data[tao.t]),
transformAction(data[tao.a]),
transformOrient(data[tao.o])
);
}

function buildErrorDatagram(tao, data, error) {
const fail = {
reason: typeof error === 'string' ? error : error.message,
a: tao.a,
[tao.a]: data[tao.a]
};
if (typeof error !== 'string') {
fail.error = error;
}
if (error.response && error.response.data) {
fail.response = error.response.data;
}
return fail;
}

/**
* Transfer the trigram, datagrams and an error into a new AppCtx that
* signals the Error
*
* @param {*} tao signal trigram that you want to transfer from
* @param {*} data signal datagram that you want to transfer from
* @param {error | string} error error that is either an Error or a String message
* @param {{
* action: string,
* transformTerm: function,
* transformAction: function,
* transformOrient: function,
* }} options optional functions to transform the datagrams in the new AppCtx
* @returns AppCtx with the trigram of the { `tao.t`, `action` [`'fail'`], `tao.o` }
* argument and the datagrams from the `data` argument with the error
*/
export function transferError(
tao,
data,
error,
{
action = 'fail',
transformTerm = IDENTITY,
transformAction = IDENTITY,
transformOrient = IDENTITY
} = {}
) {
return transferToAppCtx(
tao,
data,
{ action },
{
transformTerm,
transformAction: () => {
const fail = buildErrorDatagram(tao, data, error);
return transformAction(fail);
},
transformOrient
}
);
}

0 comments on commit d71ef74

Please sign in to comment.