From 4394dd61ee3105a61d236f043d32d0502f77fb5b Mon Sep 17 00:00:00 2001 From: Richard Rodger Date: Thu, 6 Jun 2024 17:41:28 +0100 Subject: [PATCH] initial --- README.md | 229 +++++++++++++++++++++++++++----------------------- package.json | 8 +- test/quick.js | 23 +++++ 3 files changed, 152 insertions(+), 108 deletions(-) create mode 100644 test/quick.js diff --git a/README.md b/README.md index 20d4ee6..47c1492 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,15 @@ -# @seneca/config +# @seneca/batch-processor -> _Seneca Config_ is a plugin for [Seneca](http://senecajs.org) +> _Seneca BatchProcessor_ is a plugin for [Seneca](http://senecajs.org) -Live configuration plugin for the Seneca framework. +INTRO -Unlike static configuration, this plugin lets you store keyed -configuration in your deployed persistent storage so that you can -change it on the live system. This is useful for things like currency -exchange rates, feature flags, A/B testing etc. - - -[![npm version](https://img.shields.io/npm/v/@seneca/config.svg)](https://npmjs.com/package/@seneca/config) -[![build](https://github.com/senecajs/SenecaConfig/actions/workflows/build.yml/badge.svg)](https://github.com/senecajs/SenecaConfig/actions/workflows/build.yml) -[![Coverage Status](https://coveralls.io/repos/github/senecajs/SenecaConfig/badge.svg?branch=main)](https://coveralls.io/github/senecajs/SenecaConfig?branch=main) -[![Known Vulnerabilities](https://snyk.io/test/github/senecajs/SenecaConfig/badge.svg)](https://snyk.io/test/github/senecajs/SenecaConfig) +[![npm version](https://img.shields.io/npm/v/@seneca/batch-processor.svg)](https://npmjs.com/package/@seneca/batch-processor) +[![build](https://github.com/senecajs/SenecaBatchProcessor/actions/workflows/build.yml/badge.svg)](https://github.com/senecajs/SenecaBatchProcessor/actions/workflows/build.yml) +[![Coverage Status](https://coveralls.io/repos/github/senecajs/SenecaBatchProcessor/badge.svg?branch=main)](https://coveralls.io/github/senecajs/SenecaBatchProcessor?branch=main) +[![Known Vulnerabilities](https://snyk.io/test/github/senecajs/SenecaBatchProcessor/badge.svg)](https://snyk.io/test/github/senecajs/SenecaBatchProcessor) [![DeepScan grade](https://deepscan.io/api/teams/5016/projects/26547/branches/846930/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=5016&pid=26547&bid=846930) -[![Maintainability](https://api.codeclimate.com/v1/badges/3e5e5c11a17dbfbdd894/maintainability)](https://codeclimate.com/github/senecajs/SenecaConfig/maintainability) +[![Maintainability](https://api.codeclimate.com/v1/badges/3e5e5c11a17dbfbdd894/maintainability)](https://codeclimate.com/github/senecajs/SenecaBatchProcessor/maintainability) | ![Voxgig](https://www.voxgig.com/res/img/vgt01r.png) | This open source module is sponsored and supported by [Voxgig](https://www.voxgig.com). | | ---------------------------------------------------- | --------------------------------------------------------------------------------------- | @@ -23,124 +17,151 @@ exchange rates, feature flags, A/B testing etc. ## Install ```sh -$ npm install @seneca/Config +$ npm install @seneca/batch-processor ``` + ## Quick Example ```js -seneca.use('Config', {}) - -const initRes = await seneca.post('sys:config,init:val,key:a,val:1') -// === { ok: true, key: 'a', val: 1, entry: { key: 'a', val: 1 } } -const getRes = await seneca.post('sys:config,get:val,key:a') -// === { ok: true, key: 'a', val: 1, entry: { key: 'a', val: 1 } } - -const setRes = await seneca.post('sys:config,set:val,key:a,val:2') -// === { ok: true, key: 'a', val: 1, entry: { key: 'a', val: 2 } } +// Seneca setup script: + +seneca.use('BatchProcessor', { + send: { + mode: 'async', // wait for transition, global setting + }, + where: { + 'aim:foo,color:red': { + match: { // on out + 'ok:true': { + send: [ // zero or more next messages + { + msg: { + aim: 'bar', + color: 'blue', + planet: 'out~planet' // dot path ref (see npm package `inks`) + order: 'ctx~place.order~Number' // Gubu validation expression + } + }, + { + mode: 'sync', // use .act, don't await + msg: 'aim:bar,color:green,planet:out~planet', + body: { // msg has precedence + order: 'ctx~place.order~Number' + } + } + ] + } + } + } + } +}) + + +// Within aim:foo,color:red action script: + +const process = seneca.export('BatchProcessor/process') + +let out = {ok:true,planet:'mars'} +let ctx = {place:{order:1}} // for data not returned by message action +out = await process(seneca, ctx, out) +// send = [{aim:bar,color:blue,planet:mars,order:1}, {aim:bar,color:green,planet:mars,order:1}] +// out = {ok:true,planet:'mars',batch:BATCHID,run:RUNID} ``` -## More Examples - -Review the [unit tests](test/Config.test.ts) for more examples. - - - - - - -## Options - -* `debug` : boolean -* `numparts` : number -* `canon` : object -* `init$` : boolean - - - - - - - -## Action Patterns - -* [sys:config,get:val](#-sysconfiggetval-) -* [sys:config,init:val](#-sysconfiginitval-) -* [sys:config,list:val](#-sysconfiglistval-) -* [sys:config,map:val](#-sysconfigmapval-) -* [sys:config,set:val](#-sysconfigsetval-) - - - - - - +The message send operations are executed by the plugin with code equivalent to: -## Action Descriptions - -### « `sys:config,get:val` » - -Get a config value by key. - - -#### Parameters - - -* __key__ : _string_ - - ----------- -### « `sys:config,init:val` » - -Initialise a config value by key (must not exist). - - -#### Parameters - - -* __key__ : _string_ -* __existing__ : _boolean_ (optional, default: `false`) - - ----------- -### « `sys:config,list:val` » - -List config values by query. - - -#### Parameters +```js +await seneca.post({aim:'bar',color:'blue',planet:'mars',order:1}) +seneca.act({aim:bar,color:green,planet:mars,order:1}) +``` -* __q__ : _object_ (optional, default: `{}`) +## More Examples ----------- -### « `sys:config,map:val` » +```js -Get a map of config values by key prefix (dot separated). +// Seneca setup script: + +seneca.use('BatchProcessor', { + send: { + mode: 'async', // wait for transition, global setting + }, + where: { + 'aim:foo,color:red': { + match: { + '*': { // catch all if no other patterns match + // Create BatchMonitor entry if ctx.BatchMonitorEntry$ defined + entry: 'fail' // entry state, entry.info={why:'batch-process-no-match'} + }, + 'ok:false': { + entry: { state: 'fail', info: { why: 'out~why' } }, + send: { // if single msg, no array needed + // ctx has original message in msg$ + // out~ means entire contents of out object + msg: 'aim:monitor,fail:msg,msg:ctx~msg$,out:out~' + } + }, + 'ok:true': { // matches are in same Patrun set, so usual Seneca pattern rules apply + entry: 'done', // only created after all msgs sent + send: [ // zero or more next messages + { + msg: { + aim: 'bar', + color: 'blue', + planet: 'out~planet' // dot path ref + order: 'ctx~place.order~Number' // Gubu validation expression + } + }, + { + mode: 'sync', // use .act, don't await + msg: 'aim:bar,color:green,planet:out~planet', + body: { // msg has precedence + order: 'ctx~place.order~Number' + } + } + ] + } + } + } + } +}) + + +// Within aim:foo,color:red action script: + +const process = seneca.export('BatchProcessor/process') +const bme = seneca.BatchMonitor(...).entry(...) + +let out = {ok:true,planet:'mars'} +let ctx = {place:{order:1},BatchMonitorEntry$:bme} +out = await process(seneca, ctx, out) +// send = [{aim:bar,color:blue,planet:mars,order:1}, {aim:bar,color:green,planet:mars,order:1}] +// out = {ok:true,planet:'mars',batch:BATCHID,run:RUNID} + +// The ctx object is used for returning additional information, such as send msg results. +// ctx = {place:{order:1}, result$:[{msg:,out:,bgn:,end:,dur:},...]} +``` -#### Parameters -* __prefix__ : _string_ +Review the [unit tests](test/BatchProcessor.test.ts) for more examples. ----------- -### « `sys:config,set:val` » -Set a config value by key (must exist). + -#### Parameters -* __key__ : _string_ + + ----------- diff --git a/package.json b/package.json index d68d047..1edfcc8 100644 --- a/package.json +++ b/package.json @@ -42,13 +42,13 @@ "@seneca/doc": "^7.2.0", "@seneca/maintain": "^0.1.0", "@types/jest": "^29.5.12", - "@types/node": "^20.11.21", - "esbuild": "^0.20.1", + "@types/node": "^20.14.2", + "esbuild": "^0.21.4", "esbuild-jest": "^0.5.0", "jest": "^29.7.0", - "prettier": "3.2.5", + "prettier": "3.3.1", "seneca-msg-test": "^4.1.0", - "typescript": "^5.3.3" + "typescript": "^5.4.5" }, "peerDependencies": { "@seneca/entity-util": ">=2", diff --git a/test/quick.js b/test/quick.js new file mode 100644 index 0000000..d40722e --- /dev/null +++ b/test/quick.js @@ -0,0 +1,23 @@ + + +const Seneca = require('seneca') + + +run() + +async function run() { + const s0 = + Seneca() + .test() + .message('a:1', async function a1(msg, meta) { + console.log('meta',meta) + console.log('pact',this.private$) + + return {x:msg.x} + }) + + console.log(await s0.post('a:1,x:1')) + +} + +