Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@google/dscc

Package Overview
Dependencies
Maintainers
11
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@google/dscc - npm Package Compare versions

Comparing version 0.0.9 to 0.1.0

docs/assets/css/main.css

252

__tests__/impl.test.ts

@@ -16,88 +16,180 @@ /*!

*/
import {iframeLoaded, subscribeToData} from '../src/impl';
import * as DS from '../src/data-studio-types';
import * as sut from '../src/index';
import * as DS from '../src/types';
const DEPLOYMENT_ID = 'my deployment id';
const testDimensionFields = (numRequested: number): DS.Field[] => {
const fields = [
{
id: 'dimensionField1Id',
name: 'dimensionField1Name',
description: 'dimensionField1Description',
type: DS.FieldType.TEXT,
},
{
id: 'dimensionField2Id',
name: 'dimensionField2Name',
description: 'dimensionField2Description',
type: DS.FieldType.BOOLEAN,
},
];
if (numRequested > fields.length) {
throw new Error(`Can't support ${numRequested} fields yet.`);
}
return fields.splice(0, numRequested);
};
const testMessageRows = {
primaryRows: [['(not set)', 196.5149696290909], ['feb', 0]],
comparisonRows: [['(not set)', 198.2720811099253], ['feb', null]],
const testMetricFields = (numRequested: number): DS.Field[] => {
const fields = [
{
id: 'metricField1Id',
name: 'metricField1Name',
description: 'metricField1Description',
type: DS.FieldType.NUMBER,
},
{
id: 'metricField2Id',
name: 'metricField2Name',
description: 'metricField2Description',
type: DS.FieldType.PERCENT,
},
];
if (numRequested > fields.length) {
throw new Error(`Can't support ${numRequested} fields yet.`);
}
return fields.splice(0, numRequested);
};
const testPropertyConfig: DS.ConfigData[] = [
{
id: 'hi',
heading: 'his',
elements: [
const testMessage = (numDimensions: number, numMetrics: number): DS.Message => {
const dimensionFields = testDimensionFields(numDimensions);
const metricFields = testMetricFields(numMetrics);
const fields = dimensionFields.concat(metricFields);
return {
type: DS.MessageType.RENDER,
config: {
data: {
id: 'configId',
label: 'configLabel',
elements: [
{
type: DS.ConfigDataElementType.DIMENSION,
id: 'dimensions',
label: 'configDimension1Label',
options: {
min: 1,
max: numDimensions,
supportedTypes: [],
},
values: dimensionFields.map((a) => a.id),
},
{
type: DS.ConfigDataElementType.METRIC,
id: 'metrics',
label: 'configMetric1Label',
options: {
min: 1,
max: numMetrics,
supportedTypes: [],
},
values: metricFields.map((a) => a.id),
},
],
},
style: {
id: 'styleId',
label: 'styleLabel',
elements: [],
},
},
fields,
dataResponse: {
tables: [
{
type: DS.TableType.DEFAULT,
fields: fields.map((a) => a.id),
rows: [1, 2].map((num) => {
return fields.map((a) => {
switch (a.type) {
case DS.FieldType.TEXT:
return '' + num;
case DS.FieldType.NUMBER:
return num;
case DS.FieldType.BOOLEAN:
return num % 2 === 0;
case DS.FieldType.PERCENT:
return num / 100.0;
default:
throw new Error(`${a.type} is not supported yet.`);
}
});
}),
},
],
},
};
};
test('rowsByConfigId test', () => {
const message: DS.Message = testMessage(2, 2);
const expected = {
[DS.TableType.COMPARISON]: [],
[DS.TableType.SUMMARY]: [],
[DS.TableType.DEFAULT]: [
{
id: 'firstId',
label: 'label for first one',
type: DS.ConfigElementType.DIMENSION,
options: {
max: 1,
min: 1,
supportedTypes: [],
options: [],
},
dimensions: ['1', false],
metrics: [1, 0.01],
},
{
id: 'thirdId',
label: 'label for first one',
type: DS.ConfigElementType.METRIC,
options: {
max: 1,
min: 1,
supportedTypes: [],
options: [],
},
dimensions: ['2', true],
metrics: [2, 0.02],
},
],
},
];
};
const actual = sut.rowsByConfigId(message);
expect(actual).toEqual(expected);
});
const testMessageSchema: DS.Schema = [
{
name: 'c_id',
label: 'Campaign',
concept: 'DIMENSION',
dataType: 'STRING',
semantic: 'TEXT',
},
{
name: 'a_id',
label: 'Avg. Order Value',
concept: 'METRIC',
dataType: 'NUMBER',
semantic: 'CURRENCY',
semanticOption: 'USD',
},
];
test('fieldsById works correctly', () => {
const message: DS.Message = testMessage(1, 1);
const actual = sut.fieldsById(message);
expect(actual).toMatchObject({[message.fields[0].id]: message.fields[0]});
expect(actual).toMatchObject({[message.fields[1].id]: message.fields[1]});
});
const testMessageStyle = {
useSingleColor: true,
reverseColor: false,
showText: true,
fontSize: 10,
fontColor: {
color: '#fff',
},
font: 'auto',
};
test('parseImage all three fields present', () => {
const input = 'originalurl.com\u00a0\u00a0proxiedurl.com\u00a0\u00a0alt text';
const expected: DS.ParsedImage = {
originalUrl: 'originalurl.com',
proxiedUrl: 'proxiedurl.com',
altText: 'alt text',
};
const actual = sut.parseImage(input);
expect(actual).toEqual(expected);
});
const testMessageData: DS.Message = {
type: 'RENDER',
rows: testMessageRows,
schema: testMessageSchema,
style: testMessageStyle,
data: testPropertyConfig,
};
test('parseImage two fields present', () => {
const input = 'originalurl.com\u00a0\u00a0proxiedurl.com';
const expected: DS.ParsedImage = {
originalUrl: 'originalurl.com',
proxiedUrl: 'proxiedurl.com',
altText: undefined,
};
const actual = sut.parseImage(input);
expect(actual).toEqual(expected);
});
const testMessage = {
data: testMessageData,
};
test('parseImage one fields present', () => {
const input = 'originalurl.com';
const expected: DS.ParsedImage = {
originalUrl: 'originalurl.com',
proxiedUrl: undefined,
altText: undefined,
};
const actual = sut.parseImage(input);
expect(actual).toEqual(expected);
});
beforeEach(() => {
test('subscribeToData works', () => {
const addEventListenerMock = jest.fn((event, cb) => {
if (event === 'message') {
cb(testMessage);
cb({data: testMessage(1, 1)});
} else {

@@ -114,22 +206,8 @@ throw new Error('unsupported event type for testing');

window.removeEventListener = removeEventListenerMock;
});
test('subscribeToData default transform works', async () => {
const unSub = await subscribeToData((actual) => {
expect(actual).not.toHaveProperty('data.rows.comparisonRows');
expect(actual).toHaveProperty('rows');
const unSub = sut.subscribeToData((actual) => {
expect(actual).toBeTruthy();
});
unSub();
expect(window.removeEventListener.mock.calls.length).toBeGreaterThan(0);
expect(removeEventListenerMock.mock.calls.length).toBeGreaterThan(0);
});
test('subscribeToData no transform works', async () => {
const unSub = await subscribeToData(
(actual) => {
expect(actual).toHaveProperty('rows.comparisonRows');
},
{transform: (a) => a}
);
unSub();
expect(window.removeEventListener.mock.calls.length).toBeGreaterThan(0);
});

@@ -1,5 +0,83 @@

import * as impl from './impl';
import * as LibraryTypes from './library-types';
export declare const subscribeToData: (callback: (componentData: LibraryTypes.TransformedMessage) => void, subscriptionOptions?: impl.SubsciptionOptions) => Promise<() => void>;
import { FieldsById, Message, ParsedImage, TablesByType } from './types';
export * from './types';
/**
* Returns the width of the containing iframe of the vis.
*
* Usage:
* ```
* var myWidth = dscc.getWidth();
* console.log('My width is: ', myWidth);
* ```
*/
export declare const getWidth: () => number;
/**
* Returns the height of the containing iframe of the vis.
*
* Usage:
* ```
* var myHeight = dscc.getHeight();
* console.log('My height is: ', myHeight);
* ```
*/
export declare const getHeight: () => number;
/**
* Parses a `'\u00a0\u00a0'` delimited string into component parts. If any parts
* are missing, they will be returned as undefined.
*
* Usage:
* ```
* const myImage = parseImage('originalurl.com\u00a0\u00a0proxiedurl.com\u00a0\u00a0alt text');
*
* expect(myImage).toEqual({
* originalUrl: 'originalurl.com',
* proxiedUrl: 'proxiedurl.com',
* altText: 'alt text',
* });
* ```
*/
export declare const parseImage: (value: string) => ParsedImage;
/**
* Returns the fields indexed by their Data Studio id. This is useful if you
* have to lookups many fields so you don't have to do a full search every time.
*
* Usage:
* ```
* dscc.subscribeToData(function(message) {
* var fieldsByDSId = dscc.fieldsByDSId(message);
* var field1 = fieldsByDSId['field1Id'];
* var field2 = fieldsByDSId['field2Id'];
* });
* ```
*/
export declare const fieldsById: (message: Message) => FieldsById;
/**
* Returns all tables, with row values indexed by their configId.
*
* Usage:
* ```
* dscc.subscribeToData(function(message) {
* var rowsById = dscc.rowsByConfigId(message);
* consale.log('rowsById', rowsById);
* })
* ```
*/
export declare const rowsByConfigId: (message: Message) => TablesByType;
/**
* Subscribes to messages from Data Studio. Calls `cb` for every new
* [[MessageType.RENDER]] message. Returns a function that will unsubscribe
* `callback` from further invocations.
*
* Usage:
* ```
* var unsubscribe = dscc.subscribeToData(function(message) {
* console.log(message.fields)
* console.log(message.config)
* console.log(message.dataResponse)
* });
*
* setTimeout(function() {
* unsubscribe();
* }, 3000)
* ```
*/
export declare const subscribeToData: (cb: (componentData: Message) => void) => () => void;
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });

@@ -18,6 +21,180 @@ /*!

*/
var impl = require("./impl");
exports.subscribeToData = impl.subscribeToData;
exports.getWidth = impl.getWidth;
exports.getHeight = impl.getHeight;
var parse = require("url-parse");
var types_1 = require("./types");
// Make all exported types available to external users.
__export(require("./types"));
/**
* Returns the width of the containing iframe of the vis.
*
* Usage:
* ```
* var myWidth = dscc.getWidth();
* console.log('My width is: ', myWidth);
* ```
*/
exports.getWidth = function () { return document.body.clientWidth; };
/**
* Returns the height of the containing iframe of the vis.
*
* Usage:
* ```
* var myHeight = dscc.getHeight();
* console.log('My height is: ', myHeight);
* ```
*/
exports.getHeight = function () { return document.documentElement.clientHeight; };
/**
* Returns the componentId of the vis. Component ids uniquely identify a vis to
* Data Studio, and are sent with `postMessage`s to let Data Studio know which
* vis sent data.
*
* Usage:
* ```
* var myComponentId = dscc.getComponentId();
* console.log('My componentId is: ', myComponentId);
* ```
*/
var getComponentId = function () {
var parsed = parse(window.parent.location.href, true);
return parsed.query.componentId;
};
/**
* Parses a `'\u00a0\u00a0'` delimited string into component parts. If any parts
* are missing, they will be returned as undefined.
*
* Usage:
* ```
* const myImage = parseImage('originalurl.com\u00a0\u00a0proxiedurl.com\u00a0\u00a0alt text');
*
* expect(myImage).toEqual({
* originalUrl: 'originalurl.com',
* proxiedUrl: 'proxiedurl.com',
* altText: 'alt text',
* });
* ```
*/
exports.parseImage = function (value) {
var _a = value.split('\u00a0\u00a0'), originalUrl = _a[0], proxiedUrl = _a[1], altText = _a[2];
return {
altText: altText,
originalUrl: originalUrl,
proxiedUrl: proxiedUrl,
};
};
/**
* Returns the fields indexed by their Data Studio id. This is useful if you
* have to lookups many fields so you don't have to do a full search every time.
*
* Usage:
* ```
* dscc.subscribeToData(function(message) {
* var fieldsByDSId = dscc.fieldsByDSId(message);
* var field1 = fieldsByDSId['field1Id'];
* var field2 = fieldsByDSId['field2Id'];
* });
* ```
*/
exports.fieldsById = function (message) {
return message.fields.reduce(function (acc, field) {
acc[field.id] = field;
return acc;
}, {});
};
var zip2 = function (t, u) {
if (t.length < u.length) {
return t.map(function (tEntry, idx) { return [tEntry, u[idx]]; });
}
else {
return u.map(function (uEntry, idx) { return [t[idx], uEntry]; });
}
};
var toRowById = function (indexFields, row, fields) {
var matched = zip2(fields, row);
return matched.reduce(function (acc, _a) {
var fieldId = _a[0], rowValue = _a[1];
var field = indexFields[fieldId];
var xformedValue = field.type === types_1.FieldType.IMAGE
? exports.parseImage(rowValue)
: rowValue;
acc[fieldId] = xformedValue;
return acc;
}, {});
};
var toRowByConfigId = function (message, indexedFields, fieldIds, row) {
var fieldRow = toRowById(indexedFields, row, fieldIds);
var concepts = message.config.data.elements.filter(dimensionOrMetric);
return concepts.reduce(function (rowObjects, element) {
var rowData = element.values.map(function (fieldId) { return fieldRow[fieldId]; });
rowObjects[element.id] = rowData;
return rowObjects;
}, {});
};
var dimensionOrMetric = function (element) {
return element.type === types_1.ConfigDataElementType.DIMENSION ||
element.type === types_1.ConfigDataElementType.METRIC;
};
/**
* Returns all tables, with row values indexed by their configId.
*
* Usage:
* ```
* dscc.subscribeToData(function(message) {
* var rowsById = dscc.rowsByConfigId(message);
* consale.log('rowsById', rowsById);
* })
* ```
*/
exports.rowsByConfigId = function (message) {
var _a, _b;
var indexFields = exports.fieldsById(message);
var thing = (_a = {},
_a[types_1.TableType.COMPARISON] = [],
_a[types_1.TableType.DEFAULT] = [],
_a[types_1.TableType.SUMMARY] = [],
_a);
return message.dataResponse.tables.reduce(function (acc, table) {
var tableData = table.rows.map(function (row) {
return toRowByConfigId(message, indexFields, table.fields, row);
});
acc[table.type] = tableData;
return acc;
}, (_b = {},
_b[types_1.TableType.COMPARISON] = [],
_b[types_1.TableType.DEFAULT] = [],
_b[types_1.TableType.SUMMARY] = [],
_b));
};
/**
* Subscribes to messages from Data Studio. Calls `cb` for every new
* [[MessageType.RENDER]] message. Returns a function that will unsubscribe
* `callback` from further invocations.
*
* Usage:
* ```
* var unsubscribe = dscc.subscribeToData(function(message) {
* console.log(message.fields)
* console.log(message.config)
* console.log(message.dataResponse)
* });
*
* setTimeout(function() {
* unsubscribe();
* }, 3000)
* ```
*/
exports.subscribeToData = function (cb) {
var onMessage = function (message) {
if (message.data.type === types_1.MessageType.RENDER) {
cb(message.data);
}
else {
console.error("MessageType: " + message.data.type + " is not supported by this version of the library.");
}
};
window.addEventListener('message', onMessage);
var componentId = getComponentId();
// Tell DataStudio that the viz is ready to get events.
window.parent.postMessage({ componentId: componentId, type: 'vizReady' }, '*');
return function () { return window.removeEventListener('message', onMessage); };
};
//# sourceMappingURL=index.js.map

@@ -8,12 +8,16 @@ # Deploying New NPM Version

+ Make sure the code has been built & versioned
```bash
yarn install && \
yarn build && \
yarn version
```
1. Make sure the code has been built & versioned
+ Publish the code to npm
```bash
npm publish --access public
```
```bash
yarn install
yarn build
yarn version
```
1. Commit new changes.
1. Publish the code to npm
```bash
npm publish --access public
```
{
"name": "@google/dscc",
"libraryName": "dscc",
"version": "0.0.9",
"version": "0.1.0",
"main": "lib/index.js",

@@ -14,7 +14,8 @@ "license": "Apache-2.0",

"build-watch": "onchange \"{src,__tests__}/**/*.ts\" -- yarn build",
"lint": "eslint src/**",
"lint": "tslint -c tslint.json src/**/*.ts",
"test": "jest",
"prettier": "prettier --write \"{src,__tests__}/**/*.ts\"",
"prettier-watch": "onchange \"{src,__tests__}/**/*.ts\" -- yarn prettier",
"dev": "webpack --progress --colors --watch --env dev"
"prettier": "prettier --write \"{src,__tests__,examples}/**/*.ts\"",
"prettier-watch": "onchange \"{src,__tests__,examples}/**/*.ts\" -- yarn prettier",
"dev": "webpack --progress --colors --watch --env dev",
"doc": "typedoc --out docs/ src/"
},

@@ -24,19 +25,10 @@ "devDependencies": {

"@types/url-parse": "^1.1.0",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.3",
"babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"eslint": "^4.13.1",
"eslint-config-google": "^0.9.1",
"eslint-loader": "^1.9.0",
"jest": "^22.4.2",
"onchange": "^3.3.0",
"prettier": "^1.12.1",
"ts-jest": "^22.4.4",
"ts-jest": "^23.10.1",
"ts-loader": "^4.2.0",
"typescript": "^2.8.1",
"tslint": "^5.11.0",
"typedoc": "^0.12.0",
"typescript": "^3.0.3",
"webpack": "^4.6.0",

@@ -43,0 +35,0 @@ "webpack-cli": "^2.0.14",

@@ -8,58 +8,11 @@ # dscc - Google Data Studio Community Component Helper Library

## Public Interface
## Documentation
### `subscribeToData(callback, subscriptionOptions)`
See [the doc directory][docs] for full documentation.
Calls `callback` every time Data Studio pushes a new `Message` object to your
component. `subscribeToData` returns a method to unsubscribe your callback.
## Basic Usage
`callback` should be a function that takes the type that `subscriptionOptions.transform` returns. For full
details on the `Message` object, see [library-types.ts]
`dscc` can be used through npm, or by copying the contents into the beginning of
your javascript file.
`subscriptionOptions` is an object with a `transform` property. This should be a
function that takes a Data Studio `Message` type and performs an appropriate
data transform.
#### Usage
```javascript
var callback = function(message) {
// Logs out a `Message` object.
console.log(message)
}
var unsubscribe = dscc.subscribeToData(callback);
setTimeout(function() {
// Unsubscribe callback from being called after 3 seconds.
unsubscribe();
}, 3000);
```
### `getWidth()`
Returns the width (in pixels of the containing iframe).
#### Usage
```javascript
var width = dscc.getWidth();
// This will log out the width of the iframe.
console.log(width);
```
### `getHeight()`
Returns the height (in pixels of the containing iframe).
#### Usage
```javascript
var height = dscc.getHeight();
// This will log out the height of the iframe.
console.log(height);
```
## Using `dscc` from your component
The dscc library can be used through npm, or by copying the contents into the
beginning of your javascript file.
### Through Npm

@@ -87,3 +40,3 @@

console.log(message)
// Create component as needed using componentData, height, and width...
// Create component as needed using message, height, and width...
})

@@ -108,3 +61,3 @@ }

console.log(message)
// Create component as needed using componentData, height, and width...
// Create component as needed using message, height, and width...
});

@@ -132,2 +85,2 @@ ```

[dscv-devsite]: https://developers.google.com/datastudio/visualization/
[library-types.ts]: https://github.com/googledatastudio/ds-component/blob/master/src/library-types.ts#L13-L19
[docs]: https://googledatastudio.github.io/ds-component/

@@ -16,8 +16,234 @@ /*!

*/
import * as impl from './impl';
import * as LibraryTypes from './library-types';
import * as DataStudioTypes from './data-studio-types';
import * as parse from 'url-parse';
import {
ConfigDataElement,
ConfigDataElementType,
Field,
FieldId,
FieldsById,
FieldType,
Message,
MessageType,
ParsedImage,
ParsedRowValue,
PostMessage,
Row,
RowByConfigId,
RowValue,
Table,
TablesByType,
TableType,
} from './types';
export const subscribeToData = impl.subscribeToData;
export const getWidth = impl.getWidth;
export const getHeight = impl.getHeight;
// Make all exported types available to external users.
export * from './types';
/**
* Returns the width of the containing iframe of the vis.
*
* Usage:
* ```
* var myWidth = dscc.getWidth();
* console.log('My width is: ', myWidth);
* ```
*/
export const getWidth = (): number => document.body.clientWidth;
/**
* Returns the height of the containing iframe of the vis.
*
* Usage:
* ```
* var myHeight = dscc.getHeight();
* console.log('My height is: ', myHeight);
* ```
*/
export const getHeight = (): number => document.documentElement.clientHeight;
/**
* Returns the componentId of the vis. Component ids uniquely identify a vis to
* Data Studio, and are sent with `postMessage`s to let Data Studio know which
* vis sent data.
*
* Usage:
* ```
* var myComponentId = dscc.getComponentId();
* console.log('My componentId is: ', myComponentId);
* ```
*/
const getComponentId = (): string => {
const parsed = parse(window.parent.location.href, true);
return parsed.query.componentId;
};
/**
* Parses a `'\u00a0\u00a0'` delimited string into component parts. If any parts
* are missing, they will be returned as undefined.
*
* Usage:
* ```
* const myImage = parseImage('originalurl.com\u00a0\u00a0proxiedurl.com\u00a0\u00a0alt text');
*
* expect(myImage).toEqual({
* originalUrl: 'originalurl.com',
* proxiedUrl: 'proxiedurl.com',
* altText: 'alt text',
* });
* ```
*/
export const parseImage = (value: string): ParsedImage => {
const [originalUrl, proxiedUrl, altText] = value.split('\u00a0\u00a0');
return {
altText,
originalUrl,
proxiedUrl,
};
};
/**
* Returns the fields indexed by their Data Studio id. This is useful if you
* have to lookups many fields so you don't have to do a full search every time.
*
* Usage:
* ```
* dscc.subscribeToData(function(message) {
* var fieldsByDSId = dscc.fieldsByDSId(message);
* var field1 = fieldsByDSId['field1Id'];
* var field2 = fieldsByDSId['field2Id'];
* });
* ```
*/
export const fieldsById = (message: Message): FieldsById =>
message.fields.reduce((acc: FieldsById, field: Field) => {
acc[field.id] = field;
return acc;
}, {});
const zip2 = <T, U>(t: T[], u: U[]): Array<[T, U]> => {
if (t.length < u.length) {
return t.map((tEntry: T, idx: number): [T, U] => [tEntry, u[idx]]);
} else {
return u.map((uEntry: U, idx: number): [T, U] => [t[idx], uEntry]);
}
};
interface RowById {
[fieldId: string]: ParsedRowValue;
}
const toRowById = (
indexFields: FieldsById,
row: Row,
fields: FieldId[]
): RowById => {
const matched = zip2(fields, row);
return matched.reduce(
(acc: RowById, [fieldId, rowValue]: [FieldId, RowValue]) => {
const field: Field = indexFields[fieldId];
const xformedValue =
field.type === FieldType.IMAGE
? parseImage(rowValue as string)
: rowValue;
acc[fieldId] = xformedValue;
return acc;
},
{}
);
};
const toRowByConfigId = (
message: Message,
indexedFields: FieldsById,
fieldIds: FieldId[],
row: Row
): RowByConfigId => {
const fieldRow: RowById = toRowById(indexedFields, row, fieldIds);
const concepts = message.config.data.elements.filter(dimensionOrMetric);
return concepts.reduce(
(rowObjects: RowByConfigId, element: ConfigDataElement) => {
const rowData = element.values.map(
(fieldId: FieldId) => fieldRow[fieldId]
);
rowObjects[element.id] = rowData;
return rowObjects;
},
{}
);
};
const dimensionOrMetric = (element: ConfigDataElement): boolean =>
element.type === ConfigDataElementType.DIMENSION ||
element.type === ConfigDataElementType.METRIC;
/**
* Returns all tables, with row values indexed by their configId.
*
* Usage:
* ```
* dscc.subscribeToData(function(message) {
* var rowsById = dscc.rowsByConfigId(message);
* consale.log('rowsById', rowsById);
* })
* ```
*/
export const rowsByConfigId = (message: Message): TablesByType => {
const indexFields = fieldsById(message);
const thing: TablesByType = {
[TableType.COMPARISON]: [],
[TableType.DEFAULT]: [],
[TableType.SUMMARY]: [],
};
return message.dataResponse.tables.reduce(
(acc: TablesByType, table: Table) => {
const tableData: RowByConfigId[] = table.rows.map((row) =>
toRowByConfigId(message, indexFields, table.fields, row)
);
acc[table.type] = tableData;
return acc;
},
{
[TableType.COMPARISON]: [],
[TableType.DEFAULT]: [],
[TableType.SUMMARY]: [],
}
);
};
/**
* Subscribes to messages from Data Studio. Calls `cb` for every new
* [[MessageType.RENDER]] message. Returns a function that will unsubscribe
* `callback` from further invocations.
*
* Usage:
* ```
* var unsubscribe = dscc.subscribeToData(function(message) {
* console.log(message.fields)
* console.log(message.config)
* console.log(message.dataResponse)
* });
*
* setTimeout(function() {
* unsubscribe();
* }, 3000)
* ```
*/
export const subscribeToData = (
cb: (componentData: Message) => void
): (() => void) => {
const onMessage = (message: PostMessage) => {
if (message.data.type === MessageType.RENDER) {
cb(message.data);
} else {
console.error(
`MessageType: ${
message.data.type
} is not supported by this version of the library.`
);
}
};
window.addEventListener('message', onMessage);
const componentId = getComponentId();
// Tell DataStudio that the viz is ready to get events.
window.parent.postMessage({componentId, type: 'vizReady'}, '*');
return () => window.removeEventListener('message', onMessage);
};

@@ -27,3 +27,10 @@ /*!

outputFile = libraryName + '.min.js';
plugins.push(new UglifyJsPlugin({sourceMap: false}));
plugins.push(new UglifyJsPlugin({
sourceMap: false,
uglifyOptions: {
output: {
comments: false
}
}
}));
} else {

@@ -30,0 +37,0 @@ outputFile = libraryName + '.js';

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc