fable 3.1.58 → 3.1.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fable.js +33 -8
- package/dist/fable.js.map +1 -1
- package/dist/fable.min.js +2 -2
- package/dist/fable.min.js.map +1 -1
- package/package.json +3 -3
- package/source/services/Fable-Service-ExpressionParser/Fable-Service-ExpressionParser-ExpressionTokenizer.js +62 -0
- package/source/services/Fable-Service-ExpressionParser.js +22 -5
- package/test/ExpressionParser_Recompose_tests.js +194 -0
package/dist/fable.js
CHANGED
|
@@ -1753,7 +1753,13 @@ this.elementHashes[pDescriptor.Hash]=pAddress;}else{pDescriptor.Hash=pAddress;}r
|
|
|
1753
1753
|
* Beginning of Object Manipulation (read & write) Functions
|
|
1754
1754
|
*/// Check if an element exists by its hash
|
|
1755
1755
|
checkAddressExistsByHash(pObject,pHash){return this.checkAddressExists(pObject,this.resolveHashAddress(pHash));}// Check if an element exists at an address
|
|
1756
|
-
checkAddressExists(pObject,pAddress){return this.objectAddressCheckAddressExists.checkAddressExists(pObject,pAddress);}
|
|
1756
|
+
checkAddressExists(pObject,pAddress){return this.objectAddressCheckAddressExists.checkAddressExists(pObject,pAddress);}/**
|
|
1757
|
+
* Check what role a string plays in this manifest -- whether it is a Hash, an Address, both or neither.
|
|
1758
|
+
*
|
|
1759
|
+
* @param {string} pString - The string to check.
|
|
1760
|
+
*
|
|
1761
|
+
* @return {{ IsHash: boolean, IsAddress: boolean, ResolvedAddress: string|undefined }} The role of the string.
|
|
1762
|
+
*/checkStringRole(pString){if(typeof pString!=='string'||pString.length===0){return{IsHash:false,IsAddress:false,ResolvedAddress:undefined};}let tmpIsAddress=pString in this.elementDescriptors;let tmpIsHash=pString in this.elementHashes;let tmpResolvedAddress=tmpIsHash?this.elementHashes[pString]:undefined;return{IsHash:tmpIsHash,IsAddress:tmpIsAddress,ResolvedAddress:tmpResolvedAddress};}// Turn a hash into an address, factoring in the translation table.
|
|
1757
1763
|
resolveHashAddress(pHash){let tmpAddress=undefined;let tmpInElementHashTable=pHash in this.elementHashes;let tmpInTranslationTable=pHash in this.hashTranslations.translationTable;// The most straightforward: the hash exists, no translations.
|
|
1758
1764
|
if(tmpInElementHashTable&&!tmpInTranslationTable){tmpAddress=this.elementHashes[pHash];}// There is a translation from one hash to another, and, the elementHashes contains the pointer end
|
|
1759
1765
|
else if(tmpInTranslationTable&&this.hashTranslations.translate(pHash)in this.elementHashes){tmpAddress=this.elementHashes[this.hashTranslations.translate(pHash)];}// Use the level of indirection only in the Translation Table
|
|
@@ -3196,7 +3202,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
3196
3202
|
// presumably different callback function.
|
|
3197
3203
|
// This makes sure that own properties are retained, so that
|
|
3198
3204
|
// decorations and such are not lost along the way.
|
|
3199
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.
|
|
3205
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],148:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],149:[function(require,module,exports){module.exports={"name":"fable","version":"3.1.59","description":"A service dependency injection, configuration and logging library.","main":"source/Fable.js","scripts":{"start":"node source/Fable.js","coverage":"./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec","test":"./node_modules/.bin/mocha -u tdd -R spec","build":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t fable-image:local","docker-dev-run":"docker run -it -d --name fable-dev -p 30001:8080 -p 38086:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/fable\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" fable-image:local","docker-dev-shell":"docker exec -it fable-dev /bin/bash","tests":"./node_modules/mocha/bin/_mocha -u tdd --exit -R spec --grep"},"mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"browser":{"./source/service/Fable-Service-EnvironmentData.js":"./source/service/Fable-Service-EnvironmentData-Web.js","./source/service/Fable-Service-FilePersistence.js":"./source/service/Fable-Service-FilePersistence-Web.js"},"repository":{"type":"git","url":"https://github.com/stevenvelozo/fable.git"},"keywords":["entity","behavior"],"author":"Steven Velozo <steven@velozo.com> (http://velozo.com/)","license":"MIT","bugs":{"url":"https://github.com/stevenvelozo/fable/issues"},"homepage":"https://github.com/stevenvelozo/fable","devDependencies":{"quackage":"^1.0.56"},"dependencies":{"async.eachlimit":"^0.5.2","async.waterfall":"^0.5.2","big.js":"^7.0.1","cachetrax":"^1.0.5","cookie":"^1.1.1","data-arithmatic":"^1.0.7","dayjs":"^1.11.19","fable-log":"^3.0.17","fable-serviceproviderbase":"^3.0.18","fable-settings":"^3.0.15","fable-uuid":"^3.0.12","manyfest":"^1.0.47","simple-get":"^4.0.1"}};},{}],150:[function(require,module,exports){/**
|
|
3200
3206
|
* Fable Application Services Support Library
|
|
3201
3207
|
* @author <steven@velozo.com>
|
|
3202
3208
|
*/// Pre-init services
|
|
@@ -3788,6 +3794,11 @@ this.LogNoisiness='LogNoisiness'in this.fable?this.fable.LogNoisiness:0;}/**
|
|
|
3788
3794
|
* @param {object} pResultObject - The result object to store the tokenized expression.
|
|
3789
3795
|
* @returns {object} - The tokenized expression.
|
|
3790
3796
|
*/tokenize(pExpression,pResultObject){return this.Tokenizer.tokenize(pExpression,pResultObject);}/**
|
|
3797
|
+
* Recompose an expression string from an array of token strings.
|
|
3798
|
+
*
|
|
3799
|
+
* @param {Array<string>} pTokens - The array of token strings to recompose.
|
|
3800
|
+
* @returns {string} - The recomposed expression string.
|
|
3801
|
+
*/recompose(pTokens){return this.Tokenizer.recompose(pTokens);}/**
|
|
3791
3802
|
* Lints a tokenized expression.
|
|
3792
3803
|
*
|
|
3793
3804
|
* @param {Array} pTokenizedExpression - The tokenized expression to lint.
|
|
@@ -3820,11 +3831,12 @@ this.LogNoisiness='LogNoisiness'in this.fable?this.fable.LogNoisiness:0;}/**
|
|
|
3820
3831
|
*/solvePostfixedExpression(pPostfixedExpression,pDataDestinationObject,pResultObject,pManifest){return this.Solver.solvePostfixedExpression(pPostfixedExpression,pDataDestinationObject,pResultObject,pManifest);}/**
|
|
3821
3832
|
* Add a function to the solver.
|
|
3822
3833
|
*
|
|
3823
|
-
* @param {string} pFunctionName
|
|
3824
|
-
* @param {string} pFunctionAddress
|
|
3825
|
-
* @param {string} pFunctionComment
|
|
3826
|
-
|
|
3827
|
-
|
|
3834
|
+
* @param {string} pFunctionName
|
|
3835
|
+
* @param {string} pFunctionAddress
|
|
3836
|
+
* @param {string} pFunctionComment
|
|
3837
|
+
* @param {Array<number>} [pAddressParameterIndices] - Optional array of parameter indices that contain addresses/hashes.
|
|
3838
|
+
*/addSolverFunction(pFunctionName,pFunctionAddress,pFunctionComment,pAddressParameterIndices){let tmpFunctionName=(pFunctionName||'').trim().toLowerCase();if(this.functionMap.hasOwnProperty(tmpFunctionName)){this.log.warn(`PictDynamicFormsInformary: Function ${tmpFunctionName} already exists in the solver, overwriting with address [${pFunctionAddress}].`);//return false;
|
|
3839
|
+
}let tmpFunctionEntry={Name:pFunctionComment||`Autogenerated function ${tmpFunctionName}`,Address:pFunctionAddress};if(Array.isArray(pAddressParameterIndices)&&pAddressParameterIndices.length>0){tmpFunctionEntry.AddressParameterIndices=pAddressParameterIndices;}this.functionMap[tmpFunctionName]=tmpFunctionEntry;}/**
|
|
3828
3840
|
* Prepares the parameters for a SERIES directive by substituting values and applying defaults.
|
|
3829
3841
|
*
|
|
3830
3842
|
* @param {Array} pParameters
|
|
@@ -3918,7 +3930,20 @@ tmpResults.SolverDirectiveTokens=tmpResults.RawTokens.slice(tmpDirectiveTokenSta
|
|
|
3918
3930
|
tmpResults.RawTokens.splice(0,tmpDirectiveTokenEndIndex+1);// Further parsing based on directive type could go here
|
|
3919
3931
|
// e.g. parseSeriesDirective for SERIES, etc.
|
|
3920
3932
|
switch(tmpToken){case'SERIES':tmpResults.SolverDirectives=this.parseSeriesDirective(tmpResults.SolverDirectiveTokens);break;case'MONTECARLO':tmpResults.SolverDirectives=this.parseMonteCarloDirective(tmpResults.SolverDirectiveTokens);break;case'MAP':tmpResults.SolverDirectives=this.parseMapDirective(tmpResults.SolverDirectiveTokens);break;default:// No further parsing needed
|
|
3921
|
-
break;}}}}return tmpResults.SolverDirectives;}}module.exports=ExpressionTokenizerDirectiveMutation;},{"./Fable-Service-ExpressionParser-Base.js":159}],161:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionTokenizer extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Tokenizer';}
|
|
3933
|
+
break;}}}}return tmpResults.SolverDirectives;}}module.exports=ExpressionTokenizerDirectiveMutation;},{"./Fable-Service-ExpressionParser-Base.js":159}],161:[function(require,module,exports){const libExpressionParserOperationBase=require('./Fable-Service-ExpressionParser-Base.js');class ExpressionTokenizer extends libExpressionParserOperationBase{constructor(pFable,pOptions,pServiceHash){super(pFable,pOptions,pServiceHash);this.serviceType='ExpressionParser-Tokenizer';}/**
|
|
3934
|
+
* Recompose an expression string from an array of tokens.
|
|
3935
|
+
*
|
|
3936
|
+
* This is the inverse of tokenize -- it takes an array of token strings
|
|
3937
|
+
* and reconstructs a valid expression string with appropriate spacing.
|
|
3938
|
+
*
|
|
3939
|
+
* @param {Array<string>} pTokens - The array of token strings to recompose.
|
|
3940
|
+
* @return {string} The recomposed expression string.
|
|
3941
|
+
*/recompose(pTokens){if(!Array.isArray(pTokens)||pTokens.length===0){return'';}let tmpResult='';for(let i=0;i<pTokens.length;i++){let tmpToken=pTokens[i];if(i>0){let tmpPreviousToken=pTokens[i-1];// Determine if we need a space before this token
|
|
3942
|
+
let tmpNeedSpace=true;// No space after opening paren
|
|
3943
|
+
if(tmpPreviousToken==='('){tmpNeedSpace=false;}// No space before closing paren
|
|
3944
|
+
if(tmpToken===')'){tmpNeedSpace=false;}// No space before opening paren when it follows a function name (not an operator or closing paren)
|
|
3945
|
+
if(tmpToken==='('&&!(tmpPreviousToken in this.ExpressionParser.tokenMap)){tmpNeedSpace=false;}// No space before comma
|
|
3946
|
+
if(tmpToken===','){tmpNeedSpace=false;}if(tmpNeedSpace){tmpResult+=' ';}}tmpResult+=tmpToken;}return tmpResult;}tokenize(pExpression,pResultObject){let tmpResults=typeof pResultObject==='object'?pResultObject:{ExpressionParserLog:[]};tmpResults.RawExpression=pExpression;tmpResults.SolverDirectives={};tmpResults.RawTokens=[];tmpResults.ExpressionParserLog=[];if(typeof pExpression!=='string'){this.log.warn('ExpressionParser.tokenize was passed a non-string expression.');return tmpResults.RawTokens;}/* Tokenize the expression
|
|
3922
3947
|
*
|
|
3923
3948
|
* Current token types:
|
|
3924
3949
|
* - Value
|