Skip to content

Latest commit

 

History

History
688 lines (464 loc) · 22.5 KB

api.md

File metadata and controls

688 lines (464 loc) · 22.5 KB

API documentation

Back to overview


Table of contents


enigma.create(config)

Returns a session.

See Configuration for the configuration options.

Example:

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);

Back to top

Configuration

This section describes the configuration object that is sent into enigma.create(config).

Property Type Optional Default Description
schema Object No Object containing the specification for the API to generate. Corresponds to a specific version of the QIX Engine API.
url String No String containing a proper websocket URL to QIX Engine.
createSocket Function In browser A function to use when instantiating the WebSocket, mandatory for Node.js.
Promise Promise Yes Promise ES6-compatible Promise library.
suspendOnClose Boolean Yes false Set to true if the session should be suspended instead of closed when the websocket is closed.
mixins Array Yes [] Mixins to extend/augment the QIX Engine API. See Mixins section for more information how each entry in this array should look like. Mixins are applied in the array order.
requestInterceptors Array Yes   [] Interceptors for augmenting requests before they are sent to QIX Engine. See Interceptors section for more information how each entry in this array should look like. Interceptors are applied in the array order.
responseInterceptors Array Yes   [] Interceptors for augmenting responses before they are passed into mixins and end-users. See Interceptors section for more information how each entry in this array should look like. Interceptors are applied in the array order.
protocol Object Yes {} An object containing additional JSON-RPC request parameters.
protocol.delta Boolean Yes true Set to false to disable the use of the bandwidth-reducing delta protocol.

Example:

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);
});

Back to top

Mixins

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.

mixin.init(args)

This function will be executed for each generated API.

See below what args contains.

Property Type Description
config Object A reference to the enigma.js configuration object, including default values.
api Object The newly generated API instance.

mixin.extend.myNonExistingMethod(param1, param2, ...)

mixin.extend is an object containing methods to extend the generated API with. These method names cannot already exist or enigma.js will throw an error.

mixin.override.someExistingMethod(base, param1, param2, ...)

mixin.override is an object containing methods that overrides existing API methods. These method names needs to exist already* or engima.js will throw an error. Be careful when overriding, you may break expected behaviors in other mixins or your application.

base is a reference to the previous mixin method, can be used to invoke the mixin chain before this mixin method.

Back to top

Interceptors

Interceptors is a concept similar to mixins, but run 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 runs 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.

See the Interceptor examples on how to use it, below is an outline of what the interceptor API consists of.

Requests

interceptor.onFulfilled(session, request)

This method is invoked when a request is about to be sent to QIX Engine.

session refers to the session executing the interceptor.

request is the JSON-RPC request that will be sent.

Back to top

Responses

interceptor.onRejected(session, request, error)

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.

session refers to the session executing the interceptor.

request is the JSON-RPC request resulting in this error. You may use .retry() to retry sending it to QIX Engine.

error is whatever the previous interceptor rejected with.

interceptor.onFulfilled(session, request, result)

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.

session refers to the session executing the interceptor.

request is the JSON-RPC request resulting in this response.

result is whatever the previous interceptor resolved with.

Back to top

Session API

You retrieve a session by calling enigma.create(config).

session.config

The session.config property contains a reference to the configuration object used by the session. Default values for optional parameters will be filled in.

session.open()

Returns a promise.

Establishes the websocket against the configured URL. Eventually resolved with the QIX global interface when the connection has been established.

Example:

session.open().then((global) => {
  global.openDoc('my-document.qvf');
});

Back to top

session.close()

Returns a promise.

Closes the websocket and cleans up internal caches, also triggers the closed event on all generated APIs. Eventually resolved when the websocket has been closed.

Note: you need to manually invoke this when you want to close a session and config.suspendOnClose is true.

Example:

session.close().then(() => console.log('Session was properly closed'));

Back to top

session.suspend([code=4000, reason=''])

Returns a promise.

Suspends the enigma.js session by closing the websocket and rejecting all method calls until it has been resumed again.

Example:

session.suspend().then(() => console.log('We are now suspended'));

Back to top

session.resume([onlyIfAttached=false])

Returns a promise.

Resume a previously suspended enigma.js session by re-creating the websocket and, if possible, re-open the document as well as refreshing the internal caches. 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.

onlyIfAttached can be used to only allow resuming if the QIX Engine session was reattached properly.

Eventually resolved when the websocket (and potentially the previously opened document, and generated APIs) has been restored, rejected when it fails any of those steps, or when onlyIfAttached is true and a new QIX Engine session was created.

Example:

// assuming suspended state:
doc.on('changed', () => console.log('Document was restored'));
object.on('changed', () => console.log('model1 was restored'));
sessionObject.on('closed', () => console.log('Session object could not be restored (new QIX Engine session)'));
session.resume().then(() => console.log('Session was properly resumed'));

Back to top

Event: opened

Handle opened state. This event is triggered whenever the websocket is connected and ready for communication.

Example:

session.on('opened', () => console.log('We are connected'));

Event: closed

Handle closed state. This event is triggered when the underlying websocket is closed and config.suspendOnClose is false.

Example:

session.on('closed', () => console.log('The session was closed'));

Back to top

Event: suspended

Handle suspended state. This event is triggered in two cases (listed below). It is useful in scenarios where you for example want to block interaction in your application until you are resumed again.

Example:

session.on('suspended', (evt) => console.log(evt.initiator));

The evt.initiator value is a string indicating what triggered the suspended state. Possible values: network, manual.

Back to top

Event: resumed

Handle resumed state. This event is triggered when the session was properly resumed. It is useful in scenarios where you for example can close blocking modal dialogs and allow the user to interact with your application again.

Example:

session.on('resumed', () => console.log('The session was resumed'));

Back to top

Event: notification:<name>

Handle a specific JSON-RPC notification event. These events depend on the product you use QIX Engine from.

Example:

session.on('notification:OnConnected', (data) => console.log(data));

Read more:

Back to top

Event: notification:*

Handle all JSON-RPC notification events.

Example:

session.on('notification:*', (eventName, data) => console.log(eventName, data));

Back to top

Event: traffic:sent

Handle outgoing websocket messages.

Generally used in debugging purposes.

Example:

session.on('traffic:sent', (req) => console.log(req));

Back to top

Event: traffic:received

Handle incoming websocket messages.

Generally used in debugging purposes.

Example:

session.on('traffic:received', (res) => console.log(res));

Back to top

Event: traffic:*

Handle all websocket messages.

Generally used in debugging purposes.

Example:

session.on('traffic:*', (direction, msg) => console.log(direction, msg));

Back to top

Generated API

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 which are either resolved or rejected depending on how the QIX Engine responds.

Read more: Generic object model

Example:

global.openDoc('my-document.qvf').then((doc) => {
  doc.createObject({ qInfo: { qType: 'my-object' } }).then(api => { /* do something with api */ });
  doc.getObject('object-id').then(api => { /* do something with api */ });
  doc.getBookmark('bookmark-id').then(api => { /* do something with api */ });
});

Back to top

promise.requestId

The requestId property is injected onto promises that enigma.js returns to give you better control in scenarios like cancelling heavy calculation requests and the like.

Read more: JSON-RPC protocol

Example of cancelling a request:

const request = doc.evaluate('SUM([myfield]');
global.cancelRequest(request.requestId);
request.catch(() => {
  console.log('Evaluation was cancelled.');
});

Back to top

api.id

This property contains the unique identifier for this API.

Example:

doc.getObject('object-id').then((api) => {
   // api.id === 'object-id'
});

Back to top

api.type

This property contains the schema class name for this API.

Example:

doc.getObject('object-id').then((api) => {
   // api.type === 'GenericObject'
});

Back to top

api.genericType

Despite the name, this property corresponds to the qInfo.qType property on your generic object's properties object.

Example:

doc.getObject('object-id').then((api) => {
   // api.genericType === 'linechart'
});

Back to top

api.session

This property contains a reference to the session that this API belongs to.

Example:

doc.session.suspend();

Back to top

api.handle

This property contains the handle QIX Engine assigned to the API. Used internally in enigma.js for caches and JSON-RPC requests.

Example:

doc.getObject('object-id').then((api) => {
   // typeof api.handle === 'number'
});

Back to top

Event: changed

Handle 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.

Example:

api.on('changed', () => {
  api.getLayout().then(layout => /* do something with the new layout */);
});

Back to top

Event: closed

Handle closed API. The closed event is triggered whenever QIX Engine considers an API closed. It usually means that it no longer exist in the QIX Engine document or session.

Example:

api.on('closed', () => {
  /* do something in your application, perhaps route your user to an overview page */
});

Back to top

Event: traffic:sent

Handle outgoing websocket messages for a specific generated API.

Generally used in debugging purposes.

Example:

api.on('traffic:sent', (req) => console.log(req));

Back to top

Event: traffic:received

Handle incoming websocket messages for a specific generated API.

Generally used in debugging purposes.

Example:

api.on('traffic:received', (res) => console.log(res));

Back to top

Event: traffic:*

Handle all websocket messages for a specific generated API.

Generally used in debugging purposes.

Example:

api.on('traffic:*', (direction, msg) => console.log(direction, msg));

Back to top

Sense utilities API

The Sense Utilities API is a standalone module delivered with enigma.js. It can be used to generate Qlik Sense websocket URLs using a configuration, similar to how enigma.js worked in version 1.

Configuration

This section describes the configuration object that is sent into SenseUtilities.buildUrl(config).

Property Type Optional Default Description
host String Yes localhost
port Number Yes 443 or 80 Default depends on secure.
secure Boolean Yes true Set to false to use an unsecure WebSocket connection (ws://).
urlParams Object Yes {} Additional parameters to be added to WebSocket URL.
prefix String Yes  Absolute base path to use when connecting, used for proxy prefixes.
appId String Yes The ID of the app intended to be opened in the session.
route String Yes Initial route to open the WebSocket against, default is app/engineData.
subpath String Yes Subpath to use, used to connect to dataprepservice in a server environment.
identity String Yes Identity (session ID) to use.
ttl Number Yes A value in seconds that QIX Engine should keep the session alive after socket disconnect (only works if QIX Engine supports it).

Back to top

SenseUtilities.buildUrl(config)

Returns a string (websocket URL).

See Configuration for the configuration options.

Example in browser (commonjs syntax):

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 });

Back to top

Error handling

There are multiple types of errors that can occur, native WebSocket errors (See CloseEvent), QIX errors and native enigma.js errors. For the enigma.js errors, you can import enigma.js/error-codes.js or refer to the list below. All native enigma.js errors have the property Error.enigmaError = true. These may occur thrown or in rejected promises.

Property Code Description
NOT_CONNECTED -1 You're trying to send data on a socket that's not created
OBJECT_NOT_FOUND -2 The object you're trying to fetch does not exist
EXPECTED_ARRAY_OF_PATCHES -3 Unexpected RPC response, expected array of patches
PATCH_HAS_NO_PARENT -4 Patchee is not an object we can patch
ENTRY_ALREADY_DEFINED -5 This entry is already defined with another key
NO_CONFIG_SUPPLIED -6 You need to supply a configuration
PROMISE_REQUIRED -7 There's no promise object available (polyfill required?)
SCHEMA_STRUCT_TYPE_NOT_FOUND -8 The schema struct type you requested does not exist
SCHEMA_MIXIN_CANT_OVERRIDE_FUNCTION -9 Can't override this function
SCHEMA_MIXIN_EXTEND_NOT_ALLOWED -10 Extend is not allowed for this mixin
SESSION_SUSPENDED -11 Session suspended - no interaction allowed
SESSION_NOT_ATTACHED -12 onlyIfAttached supplied, but you got SESSION_CREATED

Back to top


Back to overview