The thorin Intent

The thorin intent is the object that encapsulates abstracts any incoming events or request to your application. They are usually created at the transport layer when a request containing a valid payload is captured. In Thorin, requests do not have querystring, body or url parameters, as they are all merged together into a single input object. This approach makes it easier for your application to handle and validate any input data as a single source of truth.

Using this approach, you will essentially write functions that process input data and end up having a output response, be it an error, a JSON or plain html. This adds portability, as you no longer depend on a single transport layer (eg. express in traditional apps) and can seamlessly process actions from other transport sources (eg. websockets)

The default representation of a successful result object is

{
   "type": "{actionType}",
   "result": {},     // the result object
   "meta": {}        // any additional metadata
}

The default representation of an error object is

{
   "error": {
      "code": "{error code in full caps}",
      "ns": "{error namespace}",
      "message": "Additional error message",
      "data": {}, // additional information about the error
      "status": 400  // the status code of the error.
   }
}

The core intent class is under thorin.Intent and can be extended by other thorin components, using the pattern below:

'use strict';
const CoreIntent = thorin.Intent;
thorin.Intent = class ThorinIntent extends CoreIntent {
   constructor(name) {
      super(name);
      // your custom functionality
   }
}
Functionality
Properties
  • completed boolean, false Is the intent completed
  • actionstring the action name that it addresses.
  • authorizationstring the authorization value by default, the Authorization header
  • authorizationSourcestring the authorization source, by default TOKEN
  • aliasstring the alias that matched the action, if any
  • rawInputobject the raw merged input object that contains all the payload keys
  • tooknumber the number of milliseconds it took for the intent to complete.
intentObj.input(key, val)
A thorin intent has two objects that hold data: the rawInput field that holds all incoming fields and the input() one that holds only curated input fields (fields defined by your action when using input()). This acts both as a getter and as a setter. The initial input object is set by the dispatcher after it has sanitized the input data. When requesting a non-existing input key, null will be returned.
  • keystring the name of the key we wish to access in the curated input object
  • valany the value we want to associate to the particular input key, if any.
intentObj.data(key, val)
You can attach additional data to your intent by using this function. Actually, this is the preferred way of sending data from one middleware to another. It acts both as a setter and as a getter
  • keystring | object the key of the data field we want to get or set
  • valany the value of the data field we want to set, if any.
intentObj.result(key, val)
Sets or gets the result object of the intent. Usually, the result is an object that will later be converted to JSON by the transport layer. When calling this function with an object, it will first try to use it's toJSON() function, if available.
  • keystring | object the key we want to access or set.
  • valany when using the key as string, it should hold the value of the key.
This can be used as follows:
  • intentObj.result({"my": "object"})
  • intentObj.result("myKey", "myValue")
  • intentObj.result() //returns full result object
  • intentObj.result("myKey")// returns myKey from the result object.
intentObj.setMeta(key, val)
Set metadata information for the intent's result. This will create a meta key in the final result object and should contain metadata information such as pagination
  • keystring the key name we want to access or modify
  • valany the value we want to set to the given key.
intentObj.error(err)
Attaches an error to the intent object. When the matched action detects that the intent has an error, it will stop the call stack and send the error back to the transport layer.
  • errinstance of thorin.error the error we encountered.
intentObj.send(obj)
Finalizes the current intent, marking it complete and ignoring any other handler in the matched action's call stack. This will send to the transport layer the result or error attached to the intent.
  • objobject | instance of thorin.error manually set a result or an error right before sending.
intentObj.client(key, val)
Sets or gets specific client information that is set at the transport layer. As an example, the HTTP transport will have ip and headers as available client information.
  • keystring the key name we want to access or modify
  • valany the value we want to set to the given key.
intentObj.hasError(): bool
Checks if the input has any generated error.
intentObj.hasResult(): bool
Checks if the input has any generated result.
intentObj.hasRawResult(): bool
Checks if the input has any raw result attached. By default, the intent's result should be a JSON. Raw results can be anything from strings to buffers.
intentObj.rawResult(val)
When used, in stead of the regular JSON response, it will set the given value as the raw result of the intent and it will be treated by the transport layer. This can be used together with resultHeaders
  • valany the raw result, array, buffer, string, etc.
intentObj.resultHeaders(name, val)
Manually set or get custom result headers that will be sent in the response data, by the transport layer.
  • namestring | object the name of the header, or an object containing key-value headers
  • valstring when used with a string name, the value of the header.
You can call this function as follows:
  • intentObj.resultHeaders("X-Some-Header", "someValue");
  • intentObj.resultHeaders({"X-Some-Header": "some value"});
  • intentObj.resultHeaders() // returns the result headers object
  • intentObj.resultHeaders("X-Some-Header")// returns the value of the given header or null.
intentObj.on(event, fn)
Listens for specific events triggered by the intent. Currently only end is supported
  • eventstring the event name
  • fnfunction the function to call when the event occurs.
intentObj.proxy(fn)
An intent's send() function can be proxied and called before the action send() function is called to send the output back to the transport layer. It can usually alter errors or result structure.
  • fnfunction the callback function to use when proxying.
When proxying an intent, you must call the send() function at some point, otherwise it will not finalize and can provoke memory leaks. Example:
intentObj.proxy(function(obj) {
                  console.log("proxied result", obj);
                  this.send({something: "else"});
                  });
intentObj.runCreate(fn)
When an intent is triggered by the dispatcher, this function is called asynchronously, enabling other components to handle any kind of functionality, before the intent reaches an action by overriding the function.
  • fnfunction the function to call when creating an intent.
intentObj.__setRawInput(obj)
Sets the raw input object of the intent. This is usually done at the transport layer that has access to the incoming payload.
  • objobject a key-value object containing all raw input data.
intentObj._setAuthorization(source, id)
Sets the authorization information for this intent. It is usually set at the transport level that has access to the raw request headers or authorization source.
  • sourcestring the source type, values may be: TOKEN, SESSION, etc
  • idstring the authorization raw content
intentObj.destroy()
This is called by the transport layer once the intent has completed, so that it can manually clean up all its references.
Do you have a question or is something missing?

You can always create a new issue on GitHub or contact one of the core founders by chat.