UNPKG

@jaxolotl/wdclib

Version:

Required Library to bridge javascript with Tableau. Use the scripts below to create the combined shim library. i.e. npm run-script build_and_copy

243 lines (202 loc) 7.51 kB
import { applyEnums } from './Enums'; import Table from './Table'; /** * This class represents the shared parts of the javascript * library which do not have any dependence on whether we are running in * the simulator, in Tableau, or anywhere else */ class Shared { /** * * @param {Object} tableauApiObj - The already created tableau API object (usually window.tableau) * @param {Object} privateApiObj - The already created private API object (usually window._tableau) * @param {Object} globalObj - The global object to attach things to (usually window) */ constructor (tableauApiObj, privateApiObj, globalObj) { this.privateApiObj = privateApiObj; this.globalObj = globalObj; this._hasAlreadyThrownErrorSoDontThrowAgain = false; this.changeTableauApiObj(tableauApiObj); } /** * @returns {Undefined} */ init () { console.log('Initializing shared WDC'); this.globalObj.onerror = this._errorHandler.bind(this); // Initialize the functions which will be invoked by the native code this._initTriggerFunctions(); // Assign the deprecated functions which aren't availible in this version of the API this._initDeprecatedFunctions(); } /** * * @param {Object} tableauApiObj * @returns {Undefined} */ changeTableauApiObj (tableauApiObj) { this.tableauApiObj = tableauApiObj; // Assign our make & register functions right away because a connector can use // them immediately, even before bootstrapping has completed this.tableauApiObj.makeConnector = this._makeConnector.bind(this); this.tableauApiObj.registerConnector = this._registerConnector.bind(this); applyEnums(this.tableauApiObj); } /** * * @param {String} message * @param {String} file * @param {String} line * @param {String} column * @param {Object} errorObj * @returns {Boolean} */ _errorHandler (message, file, line, column, errorObj) { // print error for debugging in the browser console.error(errorObj); if (this._hasAlreadyThrownErrorSoDontThrowAgain) { console.log('Error already thrown'); return true; } let msg = message; if (errorObj) { msg += ' stack:' + errorObj.stack; } else { msg += ' file: ' + file; msg += ' line: ' + line; } if (this.tableauApiObj && this.tableauApiObj.abortWithError) { this.tableauApiObj.abortWithError(msg); } else { throw msg; } this._hasAlreadyThrownErrorSoDontThrowAgain = true; return true; } /** * @returns {Object} */ _makeConnector () { let defaultImpls = { init: function (cb) { cb(); }, shutdown: function (cb) { cb(); } }; return defaultImpls; } /** * * @param {Object} wdc * @returns {Undefined} */ _registerConnector (wdc) { // do some error checking on the wdc const FUNCTION_NAMES = ['init', 'shutdown', 'getSchema', 'getData']; for (let ii = FUNCTION_NAMES.length - 1; ii >= 0; ii--) { if (typeof (wdc[FUNCTION_NAMES[ii]]) !== 'function') { throw new Error(`The connector did not define the required function: ${FUNCTION_NAMES[ii]}`); } } console.log('Connector registered'); this.globalObj._wdc = wdc; this._wdc = wdc; } /** * @returns {Undefined} */ _initTriggerFunctions () { this.privateApiObj.triggerInitialization = this._triggerInitialization.bind(this); this.privateApiObj.triggerSchemaGathering = this._triggerSchemaGathering.bind(this); this.privateApiObj.triggerDataGathering = this._triggerDataGathering.bind(this); this.privateApiObj.triggerShutdown = this._triggerShutdown.bind(this); } /** * Starts the WDC * @returns {Undefined} */ _triggerInitialization () { this._wdc.init(this.privateApiObj._initCallback); } /** * Starts the schema gathering process * @returns {Undefined} */ _triggerSchemaGathering () { this._wdc.getSchema(this.privateApiObj._schemaCallback); } /** * Starts the data gathering process * @param {Array} tablesAndIncrementValues * @returns {undefined} */ _triggerDataGathering (tablesAndIncrementValues) { if (tablesAndIncrementValues.length !== 1) { throw new Error(`Unexpected number of tables specified. Expected 1, actual ${tablesAndIncrementValues.length}`); } let tableAndIncrementValue = tablesAndIncrementValues[0]; let isJoinFiltered = !!tableAndIncrementValue.filterColumnId; let table = new Table( tableAndIncrementValue.tableInfo, tableAndIncrementValue.incrementValue, isJoinFiltered, tableAndIncrementValue.filterColumnId, tableAndIncrementValue.filterValues, this.privateApiObj._tableDataCallback ); this._wdc.getData(table, this.privateApiObj._dataDoneCallback); } /** * Tells the WDC it's time to shut down * @returns {Undefined} */ _triggerShutdown () { this._wdc.shutdown(this.privateApiObj._shutdownCallback); } /** * Initializes a series of global callbacks which have been deprecated in version 2.0.0 * @returns {Undefined} */ _initDeprecatedFunctions () { this.tableauApiObj.initCallback = this._initCallback.bind(this); this.tableauApiObj.headersCallback = this._headersCallback.bind(this); this.tableauApiObj.dataCallback = this._dataCallback.bind(this); this.tableauApiObj.shutdownCallback = this._shutdownCallback.bind(this); } /** * @deprecated Since v2.0.0 * * @returns {Undefined} */ _initCallback () { this.tableauApiObj.abortWithError('tableau.initCallback has been deprecated in version 2.0.0. Please use the callback function passed to init'); } /** * @deprecated Since v2.0.0 * * @param {Array} fieldNames * @param {Array} types * @returns {Undefined} */ _headersCallback (fieldNames, types) { // eslint-disable-line no-unused-vars this.tableauApiObj.abortWithError('tableau.headersCallback has been deprecated in version 2.0.0'); } /** * @deprecated Since v2.0.0 * * @param {*} data * @param {*} lastRecordToken * @param {*} moreData * @returns {Undefined} */ _dataCallback (data, lastRecordToken, moreData = null) { // eslint-disable-line no-unused-vars this.tableauApiObj.abortWithError('tableau.dataCallback has been deprecated in version 2.0.0'); } /** * @deprecated Since v2.0.0 * * @returns {Undefined} */ _shutdownCallback () { this.tableauApiObj.abortWithError('tableau.shutdownCallback has been deprecated in version 2.0.0. Please use the callback function passed to shutdown'); } } export default Shared;