enigma.js
JavaScript library for consuming Qlik backend services, commonly used with nebula.js. Consider using the qlik-embed toolkit for an easier embedding experience, whilst building on the same core technologies.
Function used to create a QIX session.
Parameters
- config ConfigurationRequired
The configuration object for the QIX session.
config properties
- schema ObjectRequired
Object containing the specification for the API to generate. Corresponds to a specific version of the QIX Engine API.
- url stringRequired
String containing a proper websocket URL to QIX Engine.
- createSocket function
A function to use when instantiating the WebSocket, mandatory for Node.js.
- Promise Object
ES6-compatible Promise library.
- suspendOnClose boolean
Set to true if the session should be suspended instead of closed when the websocket is closed.
- mixins Array< Mixin >
Mixins to extend/augment the QIX Engine API. Mixins are applied in the array order.
- requestInterceptors Array
Interceptors for augmenting requests before they are sent to QIX Engine. Interceptors are applied in the array order.
- responseInterceptors Array
Interceptors for augmenting responses before they are passed into mixins and end-users. Interceptors are applied in the array order.
- protocol object
An object containing additional JSON-RPC request parameters.
protocol properties
- delta boolean
Set to false to disable the use of the bandwidth-reducing delta protocol.
-
-
Returns
- Required
Returns a new QIX session.
properties
- close() functionRequired
Closes the websocket and cleans up internal caches. Also triggers the closed event on all generated APIs. Note that you have to manually invoke this when you want to close a session and config.suspendOnClose is true.
Parameters- code number
The reason code for closing the connection.
- reason string
The human readable string describing why the connection is closed.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
- open() functionRequired
Establishes the websocket against the configured URL and returns the Global instance.
Returns- Promise < Object >Required
Eventually resolved if the connection was successful.
-
- resume() functionRequired
Resumes a previously suspended enigma.js session by recreating the websocket and, if possible, reopen the document as well as refreshing the internal cashes. If successful, changed events will be triggered on all generated APIs, and on the ones it was unable to restore, the closed event will be triggered.
Parameters- onlyIfAttached booleanRequired
If true, resume only if the session was reattached properly.
Returns- Promise < Object >Required
Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored; it is rejected when it fails any of those steps, or when onlyIfAttached is true and a new session was created.
-
- send() functionRequired
Function used to send data on the RPC socket.
Parameters- request ObjectRequired
The request to be sent. (data and some meta info)
Returns- ObjectRequired
Returns a promise instance.
-
- suspend() functionRequired
Suspends the enigma.js session by closing the websocket and rejecting all method calls until it is has resumed again.
Parameters- code number
The reason code for suspending the connection.
- reason string
The human readable string describing why the connection is suspended.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
-
Enigma.create
Example minimal session creation
const enigma = require('enigma.js');
const schema = require('enigma.js/schemas/12.20.0.json');
const WebSocket = require('ws');
const config = {
schema,
url: 'ws://localhost:9076/app/engineData',
createSocket: url => new WebSocket(url),
};
const session = enigma.create(config);
This is a list of error codes that can be thrown from enigma.js API calls.
Properties
- NOT_CONNECTED numberRequired
You're trying to send data on a socket that's not connected.
- OBJECT_NOT_FOUND numberRequired
The object you're trying to fetch does not exist.
- EXPECTED_ARRAY_OF_PATCHES numberRequired
Unexpected RPC response, expected array of patches.
- PATCH_HAS_NO_PARENT numberRequired
Not an object that can be patched.
- ENTRY_ALREADY_DEFINED numberRequired
This entry is already defined with another key.
- NO_CONFIG_SUPPLIED numberRequired
You need to supply a configuration.
- PROMISE_REQUIRED numberRequired
There's no promise object available (polyfill required?).
- SCHEMA_STRUCT_TYPE_NOT_FOUND numberRequired
The schema struct type you requested does not exist.
- SCHEMA_MIXIN_CANT_OVERRIDE_FUNCTION numberRequired
Can't override this function.
- SCHEMA_MIXIN_EXTEND_NOT_ALLOWED numberRequired
Extend is not allowed for this mixin.
- SESSION_SUSPENDED numberRequired
Session suspended - no interaction allowed.
- SESSION_NOT_ATTACHED numberRequired
onlyIfAttached supplied, but you got SESSION_CREATED.
errorCodes
Handling an enigma.js error
const { NOT_CONNECTED } = require('enigma.js/error-codes');
try {
const layout = await model.getLayout();
} catch (err) {
if (err.code === NOT_CONNECTED) {
console.log('Tried to communicate on a session that is closed');
}
}
Function used to build a URL.
Parameters
- urlConfig SenseConfigurationRequired
The URL configuration object.
urlConfig properties
- appId string
The app ID. If omitted, only the global object is returned. Otherwise both global and app object are returned.
- noData boolean
Whether to open the app without data.
- secure boolean
Set to false if an unsecure WebSocket should be used.
- host string
Host address.
- port number
Port to connect to.
- prefix string
The absolute base path to use when connecting. Used for proxy prefixes.
- subpath string
The subpath.
- route string
Used to instruct Proxy to route to the correct receiver.
- identity string
Identity to use.
- urlParams Object
Used to add parameters to the WebSocket URL.
- ttl number
A value in seconds that QIX Engine should keep the session alive after socket disconnect (only works if QIX Engine supports it).
-
Returns
- stringRequired
Returns the websocket URL.
SenseUtilities.buildUrl
Example of building and using a Qlik Sense-compatible WebSocket URL
const enigma = require('enigma.js');
const schema = require('enigma.js/schemas/12.20.0.json');
const SenseUtilities = require('enigma.js/sense-utilities');
const url = SenseUtilities.buildUrl({ host: 'my-sense-host', appId: 'some-app' });
const session = enigma.create({ schema, url });
The API for generated APIs depends on the QIX Engine schema you pass into your Configuration, and on what QIX struct the API has.
All API calls made using the generated APIs will return promises that are either resolved or rejected depending on how the QIX Engine responds.
Properties
- id stringRequired
Contains the unique identifier for this API.
- type stringRequired
Contains the schema class name for this API.
- genericType stringRequired
Corresponds to the qInfo.qType property on the generic object's properties object.
- session SessionRequired
Contains a reference to the session that this API belongs to.
session properties
- close() functionRequired
Closes the websocket and cleans up internal caches. Also triggers the closed event on all generated APIs. Note that you have to manually invoke this when you want to close a session and config.suspendOnClose is true.
Parameters- code number
The reason code for closing the connection.
- reason string
The human readable string describing why the connection is closed.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
- open() functionRequired
Establishes the websocket against the configured URL and returns the Global instance.
Returns- Promise < Object >Required
Eventually resolved if the connection was successful.
-
- resume() functionRequired
Resumes a previously suspended enigma.js session by recreating the websocket and, if possible, reopen the document as well as refreshing the internal cashes. If successful, changed events will be triggered on all generated APIs, and on the ones it was unable to restore, the closed event will be triggered.
Parameters- onlyIfAttached booleanRequired
If true, resume only if the session was reattached properly.
Returns- Promise < Object >Required
Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored; it is rejected when it fails any of those steps, or when onlyIfAttached is true and a new session was created.
-
- send() functionRequired
Function used to send data on the RPC socket.
Parameters- request ObjectRequired
The request to be sent. (data and some meta info)
Returns- ObjectRequired
Returns a promise instance.
-
- suspend() functionRequired
Suspends the enigma.js session by closing the websocket and rejecting all method calls until it is has resumed again.
Parameters- code number
The reason code for suspending the connection.
- reason string
The human readable string describing why the connection is suspended.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
-
- handle numberRequired
Contains the handle QIX Engine assigned to the API. Used interally in enigma.js for caches and JSON-RPC requests.
API
Example using `global` and `generic object` struct APIs
global.openDoc('my-document.qvf').then((doc) => {
doc.createObject({ qInfo: { qType: 'my-object' } }).then(api => { });
doc.getObject('object-id').then(api => { });
doc.getBookmark('bookmark-id').then(api => { });
});
Handles changes on the API. The changed event is triggered whenever enigma.js or QIX Engine has identified potential changes on the underlying properties or hypercubes and you should re-fetch your data.
changed
Bind the `changed` event
api.on('changed', () => {
api.getLayout().then(layout => { });
});
Handles closed API. The closed event is triggered whenever QIX Engine considers an API closed. It usually means that it no longer exists in the QIX Engine document or session.
closed
Bind the `closed` event
api.on('closed', () => {
console.log(api.id, 'was closed');
});
Handles JSON-RPC requests/responses for this API. Generally used in debugging purposes.
traffic:*
will handle all websocket messages, traffic:sent
will handle outgoing messages
and traffic:received
will handle incoming messages.
traffic
Bind the traffic events
// bind both in- and outbound traffic to console.log:
api.on('traffic:*', console.log);
// bind outbound traffic to console.log:
api.on('traffic:sent', console.log);
// bind inbound traffic to console.log:
api.on('traffic:received', console.log);
The enigma.js configuration object.
Properties
- schema ObjectRequired
Object containing the specification for the API to generate. Corresponds to a specific version of the QIX Engine API.
- url stringRequired
String containing a proper websocket URL to QIX Engine.
- createSocket function
A function to use when instantiating the WebSocket, mandatory for Node.js.
- Promise Object
ES6-compatible Promise library.
- suspendOnClose boolean
Set to true if the session should be suspended instead of closed when the websocket is closed.
- mixins Array< Mixin >
Mixins to extend/augment the QIX Engine API. Mixins are applied in the array order.
- requestInterceptors Array
Interceptors for augmenting requests before they are sent to QIX Engine. Interceptors are applied in the array order.
- responseInterceptors Array
Interceptors for augmenting responses before they are passed into mixins and end-users. Interceptors are applied in the array order.
- protocol object
An object containing additional JSON-RPC request parameters.
protocol properties
- delta boolean
Set to false to disable the use of the bandwidth-reducing delta protocol.
-
Configuration
Example defining a configuration object
const enigma = require('enigma.js');
const WebSocket = require('ws');
const bluebird = require('bluebird');
const schema = require('enigma.js/schemas/12.20.0.json');
const config = {
schema,
url: 'ws://localhost:4848/app/engineData',
createSocket: url => new WebSocket(url),
Promise: bluebird,
suspendOnClose: true,
mixins: [{ types: ['Global'], init: () => console.log('Mixin ran') }],
protocol: { delta: false },
};
enigma.create(config).open().then((global) => {
// global === QIX global interface
process.exit(0);
});
Error containing a custom error code.
Properties
- code numberRequired
The error code as defined by
errorCodes
. - enigmaError booleanRequired
Interceptor is a concept similar to mixins, but runs on a lower level. The interceptor concept can augment either the requests (i.e. before sent to QIX Engine), or the responses (i.e. after QIX Engine has sent a response). The interceptor promises run in parallel to the regular promises used in enigma.js, which means that it can be really useful when you want to normalize behaviors in your application.
InterceptorRequest
Implement a request interceptor
const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');
const session = enigma.create({
schema,
url: 'ws://localhost:9076/app/engineData',
createSocket: (url) => new WebSocket(url),
requestInterceptors: [{
onFulfilled: function logRequest(sessionReference, request) {
console.log('Request being sent', request);
return request;
}
},
});
This method is invoked when a request is about to be sent to QIX Engine.
Parameters
- session SessionRequired
The session executing the interceptor.
session properties
- close() functionRequired
Closes the websocket and cleans up internal caches. Also triggers the closed event on all generated APIs. Note that you have to manually invoke this when you want to close a session and config.suspendOnClose is true.
Parameters- code number
The reason code for closing the connection.
- reason string
The human readable string describing why the connection is closed.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
- open() functionRequired
Establishes the websocket against the configured URL and returns the Global instance.
Returns- Promise < Object >Required
Eventually resolved if the connection was successful.
-
- resume() functionRequired
Resumes a previously suspended enigma.js session by recreating the websocket and, if possible, reopen the document as well as refreshing the internal cashes. If successful, changed events will be triggered on all generated APIs, and on the ones it was unable to restore, the closed event will be triggered.
Parameters- onlyIfAttached booleanRequired
If true, resume only if the session was reattached properly.
Returns- Promise < Object >Required
Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored; it is rejected when it fails any of those steps, or when onlyIfAttached is true and a new session was created.
-
- send() functionRequired
Function used to send data on the RPC socket.
Parameters- request ObjectRequired
The request to be sent. (data and some meta info)
Returns- ObjectRequired
Returns a promise instance.
-
- suspend() functionRequired
Suspends the enigma.js session by closing the websocket and rejecting all method calls until it is has resumed again.
Parameters- code number
The reason code for suspending the connection.
- reason string
The human readable string describing why the connection is suspended.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
-
- request ObjectRequired
The JSON-RPC request that will be sent.
InterceptorResponse
Implement a request interceptor
const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');
const session = enigma.create({
schema,
url: 'ws://localhost:9076/app/engineData',
createSocket: (url) => new WebSocket(url),
responseInterceptors: [{
onRejected: function logError(sessionReference, request, error) {
console.log('Error returned from QIX engine', error, 'Originating request:', request);
// throw error so it's continued to be rejected:
throw error;
}
},
});
This method is invoked when a promise has been successfully resolved; use this to modify the result or reject the promise chain before it is sent to mixins.
Parameters
- session SessionRequired
The session executing the interceptor.
session properties
- close() functionRequired
Closes the websocket and cleans up internal caches. Also triggers the closed event on all generated APIs. Note that you have to manually invoke this when you want to close a session and config.suspendOnClose is true.
Parameters- code number
The reason code for closing the connection.
- reason string
The human readable string describing why the connection is closed.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
- open() functionRequired
Establishes the websocket against the configured URL and returns the Global instance.
Returns- Promise < Object >Required
Eventually resolved if the connection was successful.
-
- resume() functionRequired
Resumes a previously suspended enigma.js session by recreating the websocket and, if possible, reopen the document as well as refreshing the internal cashes. If successful, changed events will be triggered on all generated APIs, and on the ones it was unable to restore, the closed event will be triggered.
Parameters- onlyIfAttached booleanRequired
If true, resume only if the session was reattached properly.
Returns- Promise < Object >Required
Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored; it is rejected when it fails any of those steps, or when onlyIfAttached is true and a new session was created.
-
- send() functionRequired
Function used to send data on the RPC socket.
Parameters- request ObjectRequired
The request to be sent. (data and some meta info)
Returns- ObjectRequired
Returns a promise instance.
-
- suspend() functionRequired
Suspends the enigma.js session by closing the websocket and rejecting all method calls until it is has resumed again.
Parameters- code number
The reason code for suspending the connection.
- reason string
The human readable string describing why the connection is suspended.
Returns- Promise < Object >Required
Eventually resolved when the websocket has been closed.
-
-
- request ObjectRequired
The JSON-RPC request resulting in this response.
- result ObjectRequired
Whatever the previous interceptor is resolved with.
This method is invoked when a previous interceptor has rejected the promise; use this to handle, for example, errors before they are sent into mixins.
Parameters
- session SessionRequired
The session executing the interceptor. You may use .retry() to retry sending it to QIX Engine.
- request ObjectRequired
The JSON-RPC request resulting in this error.
- error ObjectRequired
Whatever the previous interceptor is rejected with.
The mixin concept allows you to add or override QIX Engine API functionality. A mixin is basically a JavaScript object describing which types it modifies, and a list of functions for extending and overriding the API for those types.
QIX Engine types like, for example, GenericObject, Doc, GenericBookmark, are supported but also custom GenericObject types such as barchart, story and myCustomType. An API will get both their generic type as well as custom type mixins applied.
Mixins that are bound to several different types can find the current API type in the
genericType
or type
members. this.type
would, for instance, return GenericObject
and
this.genericType
would return barchart
.
See the Mixins examples on how to use it. Below is an outline of what the mixin API consists of.
Properties
- types string | Array< string >Required
String or array of strings containing the API-types that will be mixed in.
- extend Object
Object literal containing the methods that will be extended on the specified API.
- override Object
Object literal containing the methods to override existing methods.
- init function
Init function that, if defined, will run when an API is instantiated. It runs with Promise and API object as parameters.
This object describes the configuration that is sent into buildUrl(config)
.
Properties
- appId string
The app ID. If omitted, only the global object is returned. Otherwise both global and app object are returned.
- noData boolean
Whether to open the app without data.
- secure boolean
Set to false if an unsecure WebSocket should be used.
- host string
Host address.
- port number
Port to connect to.
- prefix string
The absolute base path to use when connecting. Used for proxy prefixes.
- subpath string
The subpath.
- route string
Used to instruct Proxy to route to the correct receiver.
- identity string
Identity to use.
- urlParams Object
Used to add parameters to the WebSocket URL.
- ttl number
A value in seconds that QIX Engine should keep the session alive after socket disconnect (only works if QIX Engine supports it).
Closes the websocket and cleans up internal caches. Also triggers the closed event on all generated APIs. Note that you have to manually invoke this when you want to close a session and config.suspendOnClose is true.
Parameters
- code number
The reason code for closing the connection.
- reason string
The human readable string describing why the connection is closed.
Returns
- Promise < Object >Required
Eventually resolved when the websocket has been closed.
close
Closing a session
session.close().then(() => {
console.log('Session was closed');
});
Establishes the websocket against the configured URL and returns the Global instance.
Returns
- Promise < Object >Required
Eventually resolved if the connection was successful.
open
Opening a sesssion
session.open().then(() => {
console.log('Session was opened');
});
Resumes a previously suspended enigma.js session by recreating the websocket and, if possible, reopen the document as well as refreshing the internal cashes. If successful, changed events will be triggered on all generated APIs, and on the ones it was unable to restore, the closed event will be triggered.
Parameters
- onlyIfAttached booleanRequired
If true, resume only if the session was reattached properly.
Returns
- Promise < Object >Required
Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored; it is rejected when it fails any of those steps, or when onlyIfAttached is true and a new session was created.
resume
Resuming a session
session.resume(true).then(() => {
console.log('Session was resumed by re-attaching');
});
Function used to send data on the RPC socket.
Parameters
- request ObjectRequired
The request to be sent. (data and some meta info)
Returns
- ObjectRequired
Returns a promise instance.
Suspends the enigma.js session by closing the websocket and rejecting all method calls until it is has resumed again.
Parameters
- code number
The reason code for suspending the connection.
- reason string
The human readable string describing why the connection is suspended.
Returns
- Promise < Object >Required
Eventually resolved when the websocket has been closed.
suspend
Suspending a session
session.suspend().then(() => {
console.log('Session was suspended');
});
Handles closed state. This event is triggered when the underlying websocket is closed and config.suspendOnClose is false.
closed
Handling session closed
session.on('closed', () => {
console.log('Session was closed, clean up!');
});
Handles all JSON-RPC notification events, 'notification:* or handles a specific JSON-RPC notification event, 'notification:OnConnected'. These events depend on the product from which you use QIX Engine.
notification
Bind the notification events
// bind all notifications to console.log:
session.on('notification:*', console.log);
// bind a specific notification to console.log:
session.on('notification:OnConnected', console.log);
Handles opened state. This event is triggered whenever the websocket is connected and ready for communication.
opened
Bind the session opened event
session.on('opened', () => {
console.log('Session was opened');
});
Handles resumed state. This event is triggered when the session was properly resumed. It is useful in scenarios where, for example, you can close blocking modal dialogs and allow the user to interact with your application again.
resumed
Handling session resumed
session.on('resumed', () => {
console.log('Session was resumed, we can close that "reconnecting" dialog now');
});
Handles suspended state. This event is triggered in two cases (listed below). It is useful in scenarios where, for example, you want to block interaction with your application until you resume again. Or, if config.suspendOnClose is true and there was a network disconnect (socket closed) or if you ran session.suspend().
Parameters
- evt objectRequired
Event object.
evt properties
- initiator stringRequired
String indication what triggered the suspended state. Possible values network, manual.
-
suspended
Handling session suspended
session.on('suspended', () => {
console.log('Session was suspended, retrying...');
session.resume();
});
Handles websocket messages. Generally used for debugging purposes. traffic:*
will handle all
websocket messages, traffic:sent
will handle outgoing messages, and traffic:received
will
handle incoming messages.
traffic
Bind the traffic events
// bind both in- and outbound traffic to console.log:
session.on('traffic:*', console.log);
// bind outbound traffic to console.log:
session.on('traffic:sent', console.log);
// bind inbound traffic to console.log:
session.on('traffic:received', console.log);