copious-transitions
Version:
Framework for working with frameworks
296 lines (267 loc) • 8.96 kB
JavaScript
/**
* The objects that represent transitions are tagged transition..
* These are used for global defintions of particular transition type.
*
* The global definitions are useful in short micro service modules. However, the aim is a generalization
* which will be further developed. One aspect of the generalization will be that some application modules
* will not use the global variable tagged transitions, but operations will be selected out of session keyed
* data objects such as state machines. Or, a way of looking at it, might be that one type of tagged transition
* will operate a number of state transitions where the data structure will track unamed transitions.
*
* Applications that implement custom descendant methods of the general modules
* may branch on types of transitions by querying the *tagged* method of the transition object.
*
* Specific data reference fields will be provided via the transition object.
* A worker queue is part of every tagged transition. Transition engines may access the worker queue.
*
* Another feature of the tagged transition is the use of modules. The array of cases can be have module keys.
* If a module is used, a transition will be identified if the request asks for the transition type in conjunction with
* the module.
*
* Most of the methods provided are normalizers for fields that go into queries or that set data aside, etc.
*
* @memberof base
*/
class TaggedTransition {
//
constructor(in_tag) {
this.tag = in_tag
this.worker_queue = []
this.cases = []
}
initialize(conf) {}
/**
* seeking_endpoint_paths
*
* Included for special cases
* @returns Array
*/
seeking_endpoint_paths() {
return []
}
/**
* set_messenger
*
* @param {string} path
* @param {object} messenger -- communication object
*/
set_messenger(path,messenger) {
}
/**
* This check if a transition object has a particular tag.
*
* This is useful in application code for branching on the requester's transition.
*
* For instance, code might have a global variable, g_user_check. Then, code can check if operations relating to the user
* check might be used:
* ```
* if ( g_user_check.tagged(transition) ) {
* // do things for this type of transition
* } else if ( .... ) // do things for another type of transition
* ```
* Code that is more general might check in other ways. E.g `let tagged_op = transition_map[transition]; tagged_op(req_body)`
*
* Some of the short applications already written use global variable custom transitions.
*
* If a module is used, a transition will be identified if the request asks for the transition type in conjunction with
* the module.
*
* @param {string} tag
* @param {string} module
* @returns {boolean}
*/
tagged(tag,module) {
let cases = (this.tag === tag)
if ( module !== undefined ) {
if ( this.cases.length ) {
let handled = (this.cases.indexOf(module) >= 0)
cases = (cases && handled)
}
}
return(cases)
}
/**
* The string representing the tag type. The string returned is part of the requesting client vocabulary of transitions with repsect to the application.
* @returns {string} - the tag of this transition type
*/
tag() {
return this.tag
}
/**
* Modules may be added.
*
* @param {string} module
*/
addModule(module) {
this.cases.push(module)
}
/**
* A number of transition types may enqueue work to be done after a request has returned or between rewuests, etc.
* The transtion context marker (the global variable in the basic case) can call up work in different contexts
* and do the work when the context is encountered. Or, the context may be on a separate thread.
*
* This method enqueues a data object that
*
*
* @param {object} data
*/
enqueue(data) {
this.worker_queue.push(data)
}
/**
* Check to see if the work queue is empty or not.
*
* @returns {boolean} - true if empty
*/
empty_queue() {
return( this.worker_queue.length === 0)
}
/**
* Pull a work descriptor off the worker queue.
*
* @returns {object}
*/
get_work() {
let work = this.worker_queue.shift()
return(work)
}
/**
* This method is set asside for applications to make small changes to body data for special cases.
* For instance, sometimes the ID coming in from the client won't be in a field recognizable by the rest of the system.
*
* @param {object} data
* @returns {object}
*/
update(data) {
return(data)
}
/**
* This method is made to produce an object that will be used as the query to a database
* to check for the existence of a user.
*
* @param {object} udata
* @returns {object}
*/
existence_query(udata) {
return(udata)
}
/**
* Returns true if the kind of mime type requested requires a seondary action
* in order to finalize delivery to the client.
*
*
* @param {string} asset_type
* @returns {boolean}
*/
has_secondary_action(asset_type) {
return(true)
}
/**
* Returns true if the type of transition takes information from cache DB rather than other DB.
*
* @returns {boolean}
*/
from_cache() {
return(false)
}
/**
* Returns the key that is used in identifying an object for a DB query.
* Different types of transitions may have different key fields.
*
* @returns {string}
*/
primary_key() {
return("ID")
}
/**
* the appliation's name of the field use to search previous/parent relationships belonging to data objects
* @returns {string}
*/
back_ref() {
return('_back_ref_field') // if anything is being stored, assume some data field (most likely not implemented)
}
/**
* Each type of transition may use a specific field in order to query the DB for an object.
*
* @returns {string}
*/
kv_store_key() {
return("kvid")
}
/**
* This is a field in a data object that is used to perform a match test, often in the match method of the session manager.
* @returns {string}
*/
match_key() {
return('match')
}
/**
* This is a key found in a request body and is used to determine that a session is going for a particular user.
*
* @returns {string}
*/
session_key() {
return("token")
}
/**
* An application and transition specific prefix for a uuid's that may be used to identify objects.
* @returns {string}
*/
uuid_prefix() {
return('nonce+')
}
/**
* An application and transition specific prefix for a more general hash that may be used to identify objects.
* @returns {string}
*/
hash_id_prefix() {
return('nonce+')
}
/**
* Some transition types may govern a set of actions which can be requested seperately during a transition action.
* @param {string} action
* @returns {boolean|string} - will be a governing string if the action is supported, false otherwise
*/
action_selector(action) {
return(false)
}
/**
* This method allows for less special code to call on the application's version of file naming
* during certain transition actions.
*
* @param {string} file_name
* @returns {string}
*/
transform_file_name(file_name) {
return(file_name)
}
/**
* This method lets applications use a particular kind of name for certain kinds of files
* and allow for the file name to be individualized for different files (no overwrite)
* by changing the name or appending a suffix, such as the date.
*
* @param {string} file_key
* @returns {string}
*/
file_entry_id(file_key) {
return("_" + file_key + "_" + Date.now())
}
/**
* Provides a way to prepare the object representing the file entry in a database prior to
* moving the file from some default place (determined by a framework) to an application
* specific place.
*
* @param {object} entry_obj
*/
update_file_db_entry(entry_obj) {}
/**
* In node.js this defaults to the directory the script is running from.
* But, this method can be overridden by applications to fix a particular directory
* @returns {string}
*/
dir() {
return(__dirname)
}
//
}
module.exports = TaggedTransition