@tangle/strategy
Advanced tools
+13
| module.exports = function Schema (composition) { | ||
| const schema = { | ||
| type: 'object', | ||
| properties: {}, | ||
| additionalProperties: false | ||
| } | ||
| for (const field in composition) { | ||
| schema.properties[field] = composition[field].schema | ||
| } | ||
| return schema | ||
| } |
| const test = require('tape') | ||
| const overwrite = require('@tangle/overwrite')() | ||
| const simpleSet = require('@tangle/simple-set')() | ||
| const Validator = require('is-my-json-valid') | ||
| const Schema = require('../schema') | ||
| test('strategy.schema', t => { | ||
| const schema = Schema({ | ||
| title: overwrite, | ||
| attendees: simpleSet | ||
| }) | ||
| t.deepEqual( | ||
| schema, | ||
| { | ||
| type: 'object', | ||
| properties: { | ||
| title: overwrite.schema, | ||
| attendees: simpleSet.schema | ||
| }, | ||
| additionalProperties: false | ||
| }, | ||
| 'basic schema' | ||
| ) | ||
| const isValid = Validator(schema) | ||
| const Ts = [ | ||
| { | ||
| title: { set: 'boop' } | ||
| }, | ||
| { | ||
| attendees: { | ||
| mixmix: 2 | ||
| } | ||
| } | ||
| ] | ||
| Ts.forEach(T => { | ||
| t.true(isValid(T), `isValid : ${JSON.stringify(T)}`) | ||
| if (isValid.error) console.log(isValid.error) | ||
| }) | ||
| t.end() | ||
| }) |
+4
-5
@@ -5,9 +5,8 @@ module.exports = function Concat (composition) { | ||
| return function (a, b) { | ||
| var c = {} | ||
| const c = {} | ||
| // TODO change as this won't work for falsey values ! | ||
| Object.entries(composition).forEach(([field, strategy]) => { | ||
| if (!a[field] && !b[field]) return // eslint-disable-line | ||
| else if (!a[field]) c[field] = b[field] | ||
| else if (!b[field]) c[field] = a[field] | ||
| if (!(field in a) && !(field in b)) return // eslint-disable-line | ||
| else if (!(field in a)) c[field] = b[field] | ||
| else if (!(field in b)) c[field] = a[field] | ||
| else { | ||
@@ -14,0 +13,0 @@ c[field] = strategy.concat(a[field], b[field]) |
+10
-33
@@ -0,1 +1,3 @@ | ||
| const Validator = require('is-my-json-valid') | ||
| const Schema = require('./schema') | ||
| const Concat = require('./concat') | ||
@@ -7,6 +9,2 @@ const HumanToTransform = require('./human-to-transform') | ||
| class Strategy { | ||
| // TODO validate each strategy | ||
| // - does each one have required methods? | ||
| // - perhaps leave that to each sub-method to define | ||
| constructor (composition) { | ||
@@ -16,3 +14,5 @@ validate(composition) | ||
| this.composition = composition | ||
| this.pureTransformation = PureTransformation(composition) | ||
| this.schema = Schema(composition) | ||
| this.isValid = Validator(this.schema, { verbose: true }) | ||
| this.concat = Concat(composition) | ||
@@ -24,24 +24,16 @@ this.reify = Reify(composition) | ||
| /* Methods */ | ||
| isValid (T) { | ||
| const problems = [] | ||
| pureTransformation (t) { | ||
| const T = {} | ||
| Object.entries(this.composition).forEach(([field, strategy]) => { | ||
| if (field in T) { | ||
| if (!strategy.isValid(T[field])) problems.push(field) | ||
| } | ||
| T[field] = t[field] || strategy.identity() | ||
| }) | ||
| if (!problems.length) { | ||
| this.isValid.error = null | ||
| return true | ||
| } | ||
| this.isValid.error = new Error(`invalid transformation, see fields: ${problems.join(', ')}`) | ||
| return false | ||
| return T | ||
| } | ||
| identity () { return this.pureTransformation({}) } | ||
| // isValid | ||
| // concat | ||
| // reify | ||
| // humanToTransform | ||
| // pureTransformation | ||
@@ -69,17 +61,2 @@ /* Getters */ | ||
| function PureTransformation (composition) { | ||
| return function (T) { | ||
| // take an Object T, which may have supurflous or missing transformation fields | ||
| // and creates from it a clean + explicit transformation, fullT | ||
| var fullT = {} | ||
| Object.entries(composition).forEach(([field, strategy]) => { | ||
| fullT[field] = T[field] || strategy.identity() | ||
| }) | ||
| return fullT | ||
| } | ||
| } | ||
| /* WIP */ | ||
@@ -86,0 +63,0 @@ |
@@ -7,3 +7,5 @@ const isEqual = require('lodash.isequal') | ||
| if (typeof strategy.isValid !== 'function') errors.push('must have an isValid method') | ||
| if (typeof strategy.schema !== 'object') errors.push('must have an schema') | ||
| // if (typeof strategy.isValid !== 'function') errors.push('must have an isValid method') | ||
| if (typeof strategy.reify !== 'function') errors.push('must have a reify method') | ||
@@ -10,0 +12,0 @@ if (typeof strategy.concat !== 'function') errors.push('must have a concat method') |
+5
-4
| { | ||
| "name": "@tangle/strategy", | ||
| "version": "1.3.1", | ||
| "version": "1.4.0", | ||
| "description": "a toolkit for composing tangle reducing strategies", | ||
@@ -21,5 +21,5 @@ "main": "index.js", | ||
| "devDependencies": { | ||
| "@tangle/complex-set": "^1.1.1", | ||
| "@tangle/overwrite": "^1.1.1", | ||
| "@tangle/simple-set": "^1.1.0", | ||
| "@tangle/complex-set": "^1.2.1", | ||
| "@tangle/overwrite": "^1.2.0", | ||
| "@tangle/simple-set": "^1.2.0", | ||
| "standard": "^15.0.1", | ||
@@ -30,4 +30,5 @@ "tap-spec": "^5.0.0", | ||
| "dependencies": { | ||
| "is-my-json-valid": "^2.20.5", | ||
| "lodash.isequal": "^4.5.0" | ||
| } | ||
| } |
+11
-6
@@ -7,3 +7,3 @@ # @tangle/strategy | ||
| - `identity` *Function* - an getter which return an element which represents the identity-transformation. | ||
| - `isValid` *Function* - takes a transformation and tells you whether it is a valid for this strategy | ||
| - `schema` *Object* - a JSON schema which can be used to validate a transformation | ||
| - `concat` *Function* - takes two transformations `(a, b)` and concatenates (applies) `b` to `a`. Note order matters | ||
@@ -69,2 +69,8 @@ - `reify` *Function* - takes a transformation and maps it into a "real" state which can be used in e.g. human interfaces | ||
| ### `strategy.schema` | ||
| A getter which returns a JSON schema on which `isValid` was built. | ||
| Useful for building higher order schema (e.g. see ssb-crut) | ||
| ### `strategy.concat(A, B) => C` | ||
@@ -104,8 +110,7 @@ | ||
| ### `strategy.pureTransform(messyT) => T` | ||
| ### `strategy.pureTransform(t) => T` | ||
| A helper which takes a on Object `messyT` and returns an Object with only | ||
| the fields of your Strategy cares about. | ||
| - leaves out additional fields that might be in the Object | ||
| - replaces any missing fields with the Identity for that field | ||
| Takes an Object `t`, which may have supurflous or missing transformation fields | ||
| and creates from it a clean + explicit transformation, `T`. | ||
| Replaces any missing fields with the Identity for that field | ||
@@ -112,0 +117,0 @@ |
+1
-1
@@ -9,3 +9,3 @@ const isEqual = require('lodash.isequal') | ||
| var result = {} | ||
| const result = {} | ||
@@ -12,0 +12,0 @@ Object.entries(composition) |
@@ -24,3 +24,3 @@ const test = require('tape') | ||
| t.false(strategy.isValid(Tbroke), 'is not Valid') | ||
| t.match(strategy.isValid.error.message, /invalid transformation/) | ||
| t.match(strategy.isValid.error, /data.attendees is the wrong type/) | ||
@@ -32,3 +32,3 @@ t.true(strategy.isValid({}), 'isValid (empty)') | ||
| t.equal(strategy.isValid.error, null, 'error') | ||
| t.equal(strategy.isValid.error, '', 'error') | ||
@@ -35,0 +35,0 @@ const T3 = strategy.concat(T1, T2) |
@@ -7,3 +7,3 @@ const test = require('tape') | ||
| test('reify', t => { | ||
| test('strategy.reify', t => { | ||
| const reify = Reify({ | ||
@@ -10,0 +10,0 @@ title: Overwrite(), |
16219
4.11%14
16.67%388
8.99%140
3.7%2
100%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added