Giter Site home page Giter Site logo

enigma.js's Introduction

CircleCI Coverage Status

enigma.js is a library that helps you communicate with Qlik QIX Engine. Examples of use may be building your own browser-based analytics tools, back-end services, or command-line scripts.



Getting started

Prerequisites

Before continuing, make sure that you have these tools installed:

  • Node.js >= 4.0
  • Git bash if on Windows

And know of at least some of these web technologies:

  • JavaScript
  • Promises
  • Websockets

Schemas

enigma.js use schemas as a source when generating the QIX Engine API. The exact version of the schema you need is based on the QIX Engine version you want to communicate with, as well as what you plan on using in the QIX Engine API.

Keep in mind that before version 12.20.0 the schema version corresponds to the Qlik Sense Enterprise version, and from 12.20.0 and forward, the schema version is mapped to the QIX Engine API version.

Read more:

Usage

First off, install enigma.js and a WebSocket library:

npm i -S enigma.js ws

Next, create a new file called my-file.js and put the following code into it:

const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

// create a new session:
const session = enigma.create({
  schema,
  url: 'ws://localhost:9076/app/engineData',
  createSocket: url => new WebSocket(url),
});

// bind traffic events to log what is sent and received on the socket:
session.on('traffic:sent', data => console.log('sent:', data));
session.on('traffic:received', data => console.log('received:', data));

// open the socket and eventually receive the QIX global API, and then close
// the session:
session.open()
  .then((/*global*/) => console.log('We are connected!'))
  .then(() => session.close())
  .then(() => console.log('Session closed'))
  .catch(err => console.log('Something went wrong :(', err));

And then run it:

node my-file.js

You may need to adjust the code so the URL points towards your running QIX Engine.

/getting-started.gif

You may also use a service like unpkg to test enigma.js directly in your browser without using Node.js for development purposes.

Create a HTML file index.html and insert the following example content:

<script src="https://unpkg.com/enigma.js/enigma.min.js"></script>
<script>
  fetch('https://unpkg.com/enigma.js/schemas/12.34.11.json')
    .then(response => response.json())
    .then(schema => {
      const session = enigma.create({
        schema,
        // Change the url to point to your QIX instance
        url: 'ws://localhost:9076/app/engineData',
        createSocket: url => new WebSocket(url)
      })

      session.open()
        .then(global => global.engineVersion())
        .then(result => document.body.innerHTML = result.qComponentVersion)
        .then(() => session.close())
    });
</script>

enigma.js's People

Contributors

ahmednuaman avatar aihazm avatar axelssonhakan avatar caele avatar carlhannes avatar carlioth avatar chrismanley avatar dechabot avatar dependabot[bot] avatar egilsster avatar fkabinoff avatar gabbaxx avatar greenkeeper[bot] avatar janmiderback avatar joakim-ronning avatar magikcypress avatar marcusoffesson avatar mindspank avatar miralemd avatar niekvanstaveren avatar nilzona avatar peol avatar renovate[bot] avatar simonmcmillan avatar stefanwalther avatar stoffeastrom avatar t-wizard avatar thomashaenig avatar websy85 avatar wennmo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

enigma.js's Issues

Enable users to opt-into a debug/logging mode

We have had several discussions (internally and externally) how to best debug an implementation of enigma.js and we always end up monkey-patching the enigma.js source code to log out e.g. the traffic.

Let's design and implement a good way of allowing users to toggle on debugging/logging.

Produce an unminified version

With the new rollup build system, we only produce a minified dist/enigma.js which is not super-friendly to use when debugging. We previously provided two files:

enigma.js - transpiled, concatenated, unminified
enigma.min.js - transpiled, concatenated, minified

There should be sourcemaps provided for both.

The rollup-plugin-uglify module we use today doesn't support piping the minified content to another file, but switching to rollup-plugin-minify should enable us to do that.

Default port incorrectly documented

Description

The docs states that session.port should default to 4747 however it does not.

Steps to Reproduce

const enigma = require('enigma.js');
const qixSchema = require('../node_modules/enigma.js/schemas/qix/3.1/schema.json');
const WebSocket = require('ws');

const config = {
    schema: qixSchema,
    session: {
        unsecure: true
    },
    createSocket: (url) => {
        console.log(url)
        return new WebSocket(url)
    }
};

enigma.getService('qix', config).catch(err => console.log(err))
Expected behavior

I expected the port to default to 4747

Actual behavior

It omits port completely

Environment

Library
  • Node.js
  • Browser
Operating system
  • Windows
  • OSX
  • Linux
Qlik Sense
  • Desktop
  • Enterprise

Versions

  • Node.js: 6.7.0
  • Browser: Chrome
  • Qlik Sense: 3.1 SR3
  • Operating system: Windows

find a way to pass parameters to mixins

Description

I have not found yet a way to pass parameters to mixins. Of course it is possible to pass parameters to the mixin functions, but not to the whole mixin.

It would be nice to have for instance the enigma config to be passed as a parameter of the init function

Steps to Reproduce

var mixin = {
    types: ['Doc'],
    init: (args) => {
        console.log(args.enigmaConfig); // <-- config injected here
        mixin.enigmaConfig = args.enigmaConfig // config saved in the mixin object so that it can be reused in the extend functions
    },
    extend: { ... }
}

What do you think?

Best

Simplify/avoid config object

Over time, the config object has become bloated and we would like to simplify it in version 2.

Preferably, the "connect"-methods should have a single URL parameter and no config object at all. This might be hard (impossible?) to achieve, given that it should be possible to register listeners, etc. before a connection is established. Ideas and comments are welcome!

Expose qix types on qix models

When applying a qix mixin you can define the type(s) you want the mixin to be applied to, but if the mixin needs logic depending on the type there is no way of knowing which qix type the generated model has that the mixin gets applied to.

A generated model should expose both the Qix Type and the Custom Type ( qInfo/qType in GenericObject).

Clean up/update dependencies

This is a meta issue describes smaller tasks we want to do in relation to our current dependencies.

Investigate greenkeeper integration to keep us up-to-date

Before enabling, we need to:

  • Switch default branch from v1.x to master
  • Update our current dependencies as baseline
  • Update support for lockfile

Outcome: Greenkeeper enabled in #109

Investigate running source files in tests

We are currently transpiling in-memory today, it is not a big problem but it would be nice if we could rely on source files only -- this would likely lock us to use Node >= 8 in dev environments.

Outcome: Not feasible yet.

Use eslint-airbnb-base instead

We are not using the react stuff so we should be able to use the base configuration instead.

Outcome: Fixed in #109

Investigate using native EventEmitter class instead of dependency

Outcome: Transpiling the native event emitter adds ~12% gzip size and adds no real value.

Add `config.url` and remove URL generation

Due to the many uses of Engine, having an opinionated URL schema generated by enigma.js doesn't cut it. We either need to support more URL generation, or drop it (which we propose here).

Instead of a gigantic configuration object, the user can pass in the exact websocket URL to enigma.js (e.g. ws://localhost:4848/app/foo.qvf, and handle URL generation in their own context.

Error: Global of undefined - QS Extension creating session app

Description

I'm trying to create a session app with enigma.js in a Qlik Sense extension. But when I call getService('qix',enigmaConfig) I get this error:
image
And if I step in to the code, this is where it happens:
image

Steps to Reproduce

enigma = '../.././external/qlik/enigma'
qixSchema = 'text!../.././external/qlik/qix/3.2/schema.json'
'ng!$q' = $q
'qlik' = qlik
app = qlik.currApp();

var enigmaConfig = {
Promise: $q,
appId: app.id,
schema: qixSchema,
session: {
host: $window.location.host,
secure: $window.location.protocol === 'https:'
}
};
enigma.getService('qix', enigmaConfig).then(function (qix) {
console.log('qix', qix);
});

Versions

  • Enigma.js: 1.1.1
  • Browser: Chrome 58.0.3029.110 (64-bit)
  • Qlik Sense: 3.2 SR2
  • Operating system: Windows 10

New entry API

In lieu of the other changes in v2, we wanted to make a better API for fetching enigma.js instances.

The new API would be:

// create instance, will not create a websocket directly:
const session = enigma.create({ url: 'ws://localhost:9076' });

// bind any timing-sensitive events:
session.on('notification:OnAuthenticationInfo', (evt) => console.log(evt));
session.on('traffic:in', (data) => console.log('<-', data));
session.on('traffic:out', (data) => console.log('->', data));

// connect/create the websocket, which in turn returns a QIX Global instance:
session.open()
 .then(global => global.openDoc('foo.qvf'))
 .then(doc => doc.doReload());

// or, if you're not interested in the events:
enigma.create({ url: 'ws://localhost:9076' }).open()
 .then(global => global.openDoc('foo.qvf'))
 .then(doc => doc.doReload());

No QIX session/socket caching

Today, the qix service caches sessions and sockets. Multiple calls to enigma.getService('qix', config) will return a cached session if the config object results in a previously opened URL.

This behavior is somewhat unexpected and unpredictable (see #17) and in version 2, no session/socket caching will be implemented. This means that clients will have to implement such caching themselves.

qix.global.getDocList() is not giving any result

Description

I m trying to follow the List Apps example. My programme has connected to engine successfully after that qix.global.getDocList() promise is throwing error

Steps to Reproduce

I ran the following code.
NodeExample.txt

Error and Output

image

Kindly can anyone reconfirm that qix.global.getDocList() is working as mention in List Apps example.

QIX service, document request id

In order to cancel outstanding requests (QIX method CancelRequest), the request id is needed. The client can access the request id as enigma.js adds it to the returned promise but this is highly undocumented! Make sure it's in the v2 docs. ๐Ÿ‘

Refactor delta handling

Today, the ApiCache creates a delta cache for each API it stores and manages a few APIs related to adding/updating/removing entries. This is then only used by Intercept#processDeltaInterceptor.

We should refactor these implementations into a delta-interceptor.js file or similar, keeping the implementation in one place.

QIX service, handle multiple output params

Some QIX methods (e.g. CreateSessionApp) have multiple out parameters (i.e. it returns both a qResult and an out parameter).

Today, there is no way to access the out parameters without sending raw RPC request. We need to figure out a way to handle return out parameters to the client.

Replace config.handleLog with traffic:* events

The current way of handle logging (of traffic) is a bit unintuitive.

For the upcoming major version we should use the event approach instead (which we already use for e.g. notification:* and notification:foo:

session.on('traffic:send', (data) => {
  // data is the raw JSONRPC request
});

session.on('traffic:receive', (data) => {
  // data is the raw JSONRPC response
});

session.on('traffic:*', (direction, data) => {
  // data is depending on direction (send or receive)
});

QIX service, openDoc should not open a new WebSocket

In enigma v1, openDoc will open a new WebSocket (leaving the global instance "stateless").

In v2, this will be changed so that the openDoc call is performed without opening a new WebSocket. This will provide better symmetry with the other methods that opens/creates documents (namely createSessionApp{FromApp} and getActiveDoc) without creating a new WebSocket.

(Also, the enigma-defined openApp method should be removed.)

npm build run on windows / linebreakstyle

Description

error on npm build run on windows.

... error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style

please add to the .eslintrc
linebreak-style: ["warn", "unix"]
this means that the sytem just warn and doesn't produce an error.
I see no issue out of the different linebreakstyle

Steps to Reproduce

  1. git clone
  2. npm install
  3. npm build run
Expected behavior

thats working, maximal warnings

Actual behavior

build fail

Environment

Library
  • [ x] Node.js
  • Browser
Operating system
  • [x ] Windows
  • OSX
  • Linux
Qlik Sense
  • Desktop
  • Enterprise

Versions

  • Node.js: 7.6.0
  • Browser: -
  • Qlik Sense: -
  • Operating system: Windows 10

App reload doesn't work

Description

I've created an app reload script using enigma.js that should open the app and reload it. I receive successful connection and responses, however the data in the app doesn't reload. I can look up the app in the QMC and see the last reload timestamp matches when I ran my script, but the app doesn't have new data. The app does have new data if I run a reload Task for the specific app in the QMC.
My script is attached at the bottom of this text block

Steps to Reproduce

  1. Use attached node script to reload an app by supplying it with an app id. E.g. node reloadApp.js {appId}
  2. Check if new data was added to app in qlik. (fails)
  3. Check last reload time in QMC for the app. Should match when you ran the reloadApp script.
Expected behavior

Reload app data.

Actual behavior

Data was not reloaded.

Environment

Library
  • [ x] Node.js
  • Browser
Operating system
  • Windows
  • OSX
  • [x ] Linux
Qlik Sense
  • Desktop
  • [x ] Enterprise

Versions

  • Node.js:
  • Browser:
  • Qlik Sense:
  • Operating system:
  • [Other relevant versions]

reloadApp.txt

Not clear how to authenticate

Hi,

I see no documentation about how to authenticate? an example for certificates and header would be nice.

thanks

Make / optional in prefix

Description

Currently session.prefix needs a mandatory preceding /

Steps to Reproduce

See this fiddle: https://jsfiddle.net/mindspank/w3uah9Lj/

enigma.getService('qix', {
    appId: 'b82e6aa9-04a3-4573-b3da-201cab14dfca',
    session: {
      host: 'branch.qlik.com',
      prefix: 'anon'
    }
})

produces

WebSocket connection to 'wss://branch.qlik.comanonapp/b82e6aa9-04a3-4573-b3da-201cab14dfca?reloadUri=' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED
Expected behavior

I expected / to be optional as it is in fact not part of my proxy prefix.

Library
  • Node.js
  • Browser
Operating system
  • Windows
  • OSX
  • Linux
Qlik Sense
  • Desktop
  • Enterprise

Versions

  • Browser: Chrome
  • Qlik Sense: 3.1

Provide hosted builds

It would have been nice to host the latest build of the master branch on a CDN or through some other means so we can easily use the library with services such as jsfiddle or jsbin.

This would allow us to create a larger eco-system of examples and snippets to drive adoption.

enable mixin init to wait upon completion of a promise

Description

A mixin could take time to initialize. It would be great if we could return a promise from within the init function to wait upon.

Steps to Reproduce

init: function(args) {
    return args.api.getAppLayout().then((layout) => {
        args.api.layout = layout;
    });
}

Thanks

Best

No clear documentation on how to authenticate

It would be nice if you can make a default flowchart and example code on how to authenticate for the most common scenarios. Example image:
image

Step to authenticate (if you use ticketing)

  1. Fetch a ticket
  2. Consume the ticket. You consume a ticket by issuing a http get to a proxy resource with qlikTicket=<value> attached to the url. You can supply the ticket in the session.urlParams object.
  3. You are authenticated, do whatever you want
{
  session: {
    urlParams: {
      qlikTicket: 'poop'
    }
  }
}

slack message

Remove REST service

Main reasons:

  • swagger-client released version 3.0 covering all features we aimed to support through enigma.js (including a way of extending the APIs)
  • Bloated library (the REST service adds a lot of file size to enigma.js)
  • Streamline the scope of the library to work against QIX Engine
  • Low usage
  • Less build complexity

We intend to remove this enigma.js service in the next upcoming major version.

Question: Timeout and disconnect strategy

Today we can listen for Proxy notifications and reading the source it looks like we can also listen for websocket events such as when the socket is closing etc.

How would one approach a re-connecting strategy, polling to avoid timeouts and reconnecting in such events. Do we perform socket checks before attempting to send a message etc.

Most of these things could (should?) be built by the implementer of enigma but do we want to allow for some opt-in defaults?

enigma.js v2

This epic is used to collect ideas for a future version 2 of enigma.js!

Error thrown if undefined handle passed to getApi

Description

If an undefined handle is passed into the getApi function it throws a toString not defined error. This should either return undefined or a more appropriate error message.

Looking at the code it seems that generally we expected a possible undefined value coming back from this call (if the api isn't found) which would be the case here.

Steps to Reproduce

  1. Use the getApi call with an 'undefined' handle
Expected behavior

This should return undefined as a result

Actual behavior

It throws an exception because handle.toString() is not defined.

Expose services with better granularity

in enigma version 1.1 support for rest services was introduced. That made the package size grow from approximately 70k to 1M.

If I only intend to use the qix services with enigma I would like to do something like:

import {qix} from 'enigma.js';
qix.getService(theConfig);

And then I would only read the 70k javascript needed for that service.

Investigate support for named parameters

The Engine RPC protocol supports two ways of calling a method:

// The parameters are provided by name through an object:

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "DestroyChild",
  "handle": 2,
  "params": {
    "qId": "LB02"
    }
}

// The parameters are provided by position through an array:

{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "DestroyChild",
  "handle": 2,
  "params": [
    "LB02"
  ]
}

We currently only support the array approach, but let's see if we can find a way of supporting both, and normalize the object approach into array before sending the parameters to any mixins.

npm install enigma.js does not include 3.2 schema.json file

Description

enigma.js from npm is 1.0.1. This version does not appear to include the 3.2 schema

Steps to Reproduce

  1. npm install enigma.js
  2. Review the schemas in node_modules/enigma.js/qix folder and see no 3.2 schema.
Expected behavior

the 3.2 schema to be there.

Actual behavior

the 3.2 schema is missing

[What actually happened]

Environment

Visual Studio Code

Library
  • Node.js
  • Browser
Operating system
  • Windows
  • OSX
  • Linux
Qlik Sense
  • Desktop
  • Enterprise

Using the engima along with node authentication

Description

Hi,
First of all, It is a question, not an issue.
[Description of the question]
Can I use node authentication then further engima snippets mentioned in usage to get the data out of Qlik Sense app as my node programme output?
[What I am trying to do ]

  1. I authenticated the node programme to login to Qlik Sense, since I am not a javascript developer I followed https://www.youtube.com/watch?v=NHa7IvtHV2A and achieved ticketing with Qlik

Perfectly working code is here
Step1.txt

  1. Now since authentication is happened (at least I assumed). Now added following code to see that my programme has connected to global instance

const enigma = require('enigma.js');
const qixSchema = require('./node_modules/enigma.js/schemas/qix/3.1/schema.json');
const config = {
schema: qixSchema,
session: {
host: 'hosatname' /* original code has real host name */
}
};
enigma.getService('qix', config).then((qix) => {
const g = qix.global;
console.log('Got the global instance');

});

Result:

Here I got a result of following error message:
image

Environment

Versions

  • Qlik Sense: QlikSense Enterprise 3.1

Kindly help me. I am ready to provide if you need further details

unexpected behaviour when getting QIX service with 2 different configs

Description

When getting the qix service with two different config objects, for instance different mixins, the second enigma instance gets mixins from the first instance. Disabling caching solves the issue.

Steps to Reproduce

var config = {
    schema: qixSchema,
    host: 'https://localhost',
    session: {
        route: 'app/engineData',
        host: 'localhost',
        port: 4747,
        unsecure: false
    },
    mixins: [{
        types: ['Doc'],
        init: (args) => {},
        extend: {
            test1: function() {
                console.log('test1');
                return 1;
            }
    }],
    createSocket(url) {
        [...]
    },
};

enigma.getService('qix', config).then((qix) => {
    return qix.global.getDocList().then((docList) => {
        return promise.all(
            docList.map((doc) => {
                return qix.global.openDoc(doc.qDocId).then(app => {
                    return app.test1();
                });
            })
        );
    });
});

// Prints test1 for each available doc on the platform

config = {
    schema: qixSchema,
    host: 'https://localhost',
    session: {
        route: 'app/engineData',
        host: 'localhost',
        port: 4747,
        unsecure: false
    },
    mixins: [{
        types: ['Doc'],
        init: (args) => {},
        extend: {
            test2: function() {
                console.log('test2');
                return 2;
            }
    }],
    createSocket(url) {
        [...]
    },
};

return enigma.getService('qix', config).then((qix) => {
    return qix.global.getDocList().then((docList) => {
        return promise.all(
            docList.map((doc) => {
                return qix.global.openDoc(doc.qDocId).then(app => {
                    return app.test2();
                });
            })
        );
    });
});

// Fails because test2 is not a function
// In fact test2 is not defined on "app" because the openDoc function returned
// a cached session from first step
Expected behavior

I would expect cached sockets to be private to enigma instances (meaning not shared)

Actual behavior

Cache is shared

Environment

Library
  • Node.js
  • Browser
Operating system
  • Windows
  • OSX
  • Linux
Qlik Sense
  • Desktop
  • Enterprise

Undocumented methods included in the QIX schema

Description

There are multiple methods exposed via the schema that are un-documented (and potentially un-supported) according to the official Engine api documentation at help.qlik.com

Two examples would be ReduceData and RemoveAllData on the Doc class
https://github.com/qlik-oss/enigma.js/blob/master/schemas/qix/3.1/schema.json#L556

I'd propose we either purge them from the schema or make sure we document the methods included in the schema to avoid confusion.

Consolidate documentation for 2.0

Since we're dropping the REST service (and service concept in general), as well as other changes in APIs, we need to consolidate and refresh the documentation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.