refactor: expose nucleus and supernova via stardust package (#415)

BREAKING CHANGE: nucleus and supernova are no longer public packages and are both replaced by stardust
This commit is contained in:
Miralem Drek
2020-04-28 13:02:41 +02:00
committed by GitHub
parent 7a669316cd
commit 6a28ec3dd4
52 changed files with 315 additions and 1746 deletions

View File

@@ -1,6 +1,6 @@
{ {
"buildCommand": "build:codesandbox", "buildCommand": "build:codesandbox",
"packages": ["apis/nucleus"], "packages": ["apis/stardust"],
"sandboxes": ["/.codesandbox/mekko"], "sandboxes": ["/.codesandbox/mekko"],
"silent": true "silent": true
} }

View File

@@ -8,8 +8,7 @@
"build": "parcel build index.html" "build": "parcel build index.html"
}, },
"dependencies": { "dependencies": {
"@nebula.js/nucleus": "next", "@nebula.js/stardust": "next",
"@nebula.js/supernova": "next",
"@nebula.js/sn-mekko-chart": "1.0.0", "@nebula.js/sn-mekko-chart": "1.0.0",
"enigma.js": "2.6.3" "enigma.js": "2.6.3"
}, },

View File

@@ -1,17 +1,17 @@
import enigma from 'enigma.js'; import enigma from 'enigma.js';
import qixSchema from 'enigma.js/schemas/12.34.11.json'; import qixSchema from 'enigma.js/schemas/12.34.11.json';
import nucleus from '@nebula.js/nucleus'; import { embed } from '@nebula.js/stardust';
import mekko from '@nebula.js/sn-mekko-chart'; import mekko from '@nebula.js/sn-mekko-chart';
const openApp = id => const openApp = (id) =>
enigma enigma
.create({ .create({
schema: qixSchema, schema: qixSchema,
url: `wss://apps.core.qlik.com/app/${id}`, url: `wss://apps.core.qlik.com/app/${id}`,
}) })
.open() .open()
.then(global => global.getActiveDoc()); .then((global) => global.getActiveDoc());
const appCache = (window.appCache = window.appCache || {}); const appCache = (window.appCache = window.appCache || {});
@@ -20,11 +20,11 @@ export default function init({ appId, fields, objectId }) {
appCache[appId] = openApp(appId); appCache[appId] = openApp(appId);
} }
appCache[appId].then(app => { appCache[appId].then((app) => {
const nebbie = nucleus(app, { const nebbie = embed(app, {
load: () => Promise.resolve(mekko), load: () => Promise.resolve(mekko),
}); });
nebbie.selections().then(s => s.mount(document.getElementById('selections'))); nebbie.selections().then((s) => s.mount(document.getElementById('selections')));
nebbie.types.clearFromCache('dummy'); nebbie.types.clearFromCache('dummy');
nebbie.render( nebbie.render(

View File

@@ -4,7 +4,7 @@ import { withKnobs } from '@storybook/addon-knobs';
import { create } from '@storybook/theming'; import { create } from '@storybook/theming';
import { createTheme, ThemeProvider } from '@nebula.js/ui/theme'; import { createTheme, ThemeProvider } from '@nebula.js/ui/theme';
import InstanceContext from '../apis/nucleus/src/contexts/InstanceContext'; import InstanceContext from '../apis/stardust/src/embed/contexts/InstanceContext';
const translator = { const translator = {
get(s) { get(s) {
@@ -14,11 +14,11 @@ const translator = {
const t = createTheme('light'); const t = createTheme('light');
addDecorator(storyFn => { addDecorator((storyFn) => {
return <ThemeProvider theme={t}>{storyFn()}</ThemeProvider>; return <ThemeProvider theme={t}>{storyFn()}</ThemeProvider>;
}); });
addDecorator(storyFn => { addDecorator((storyFn) => {
return <InstanceContext.Provider value={{ translator }}>{storyFn()}</InstanceContext.Provider>; return <InstanceContext.Provider value={{ translator }}>{storyFn()}</InstanceContext.Provider>;
}); });

View File

@@ -1,5 +0,0 @@
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/nucleus.js');
} else {
module.exports = require('./dist/nucleus.dev.js');
}

View File

@@ -1,45 +1,14 @@
{ {
"name": "@nebula.js/nucleus", "name": "@nebula.js/nucleus",
"private": true,
"version": "0.5.0", "version": "0.5.0",
"description": "", "main": "src/index.js",
"license": "MIT",
"author": "QlikTech International AB",
"keywords": [],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/qlik-oss/nebula.js.git",
"directory": "apis/nucleus"
},
"main": "index.js",
"module": "dist/nucleus.esm",
"jsdelivr": "dist/nucleus.js",
"unpkg": "dist/nucleus.js",
"files": [
"dist"
],
"scripts": {
"build": "cross-env NODE_ENV=production rollup --config ../../rollup.config.js",
"build:watch": "rollup --config ../../rollup.config.js -w",
"lint": "eslint --ext .js,.jsx src",
"prepublishOnly": "rm -rf dist && yarn run build",
"spec": "scriptappy-from-jsdoc -c ./spec/spec.conf.js"
},
"peerDependencies": {
"@material-ui/core": "^4.9.0",
"@material-ui/icons": "^4.5.1",
"@material-ui/styles": "^4.9.0",
"@nebula.js/supernova": "^0.x",
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
"devDependencies": { "devDependencies": {
"@material-ui/core": "4.9.9", "@material-ui/core": "4.9.9",
"@material-ui/icons": "4.9.1", "@material-ui/icons": "4.9.1",
"@material-ui/styles": "4.9.6", "@material-ui/styles": "4.9.6",
"@nebula.js/locale": "0.5.0", "@nebula.js/locale": "0.5.0",
"@nebula.js/supernova": "0.5.0",
"@nebula.js/theme": "0.5.0", "@nebula.js/theme": "0.5.0",
"@nebula.js/ui": "0.5.0", "@nebula.js/ui": "0.5.0",
"node-event-emitter": "0.0.1", "node-event-emitter": "0.0.1",

View File

@@ -1,389 +0,0 @@
{
"scriptappy": "1.0.0",
"info": {
"name": "@nebula.js/nucleus",
"version": "0.2.0-alpha.1",
"license": "MIT",
"stability": "experimental",
"x-qlik-visibility": "public"
},
"entries": {
"nucleus": {
"description": "Initiates a new `Nucleus` instance using the specified `app`.",
"kind": "interface",
"params": [
{
"name": "app",
"type": "enigma.Doc"
},
{
"name": "instanceConfig",
"optional": true,
"type": "#/definitions/Configuration"
}
],
"returns": {
"type": "#/definitions/Nucleus"
},
"entries": {
"createConfiguration": {
"description": "Creates a new `nucleus` scope bound to the specified `configuration`.\n\nThe configuration is merged with all previous scopes.",
"kind": "function",
"params": [
{
"name": "configuration",
"description": "The configuration object",
"type": "#/definitions/Configuration"
}
],
"returns": {
"type": "#/entries/nucleus"
},
"examples": [
"import nucleus from '@nebula.js/nucleus';\n// create a 'master' config which registers all types\nconst m = nucleus.createConfiguration({\n types: [{\n name: 'mekko',\n version: '1.0.0',\n load: () => Promise.resolve(mekko)\n }],\n});\n\n// create an alternate config with dark theme\n// and inherit the config from the previous\nconst d = m.createConfiguration({\n theme: 'dark'\n});\n\nm(app).render({ type: 'mekko' }); // will render the object with default theme\nd(app).render({ type: 'mekko' }); // will render the object with 'dark' theme\nnucleus(app).render({ type: 'mekko' }); // will throw error since 'mekko' is not a register type on the default instance"
]
}
},
"examples": ["import nucleus from '@nebula.js/nucleus'\nconst n = nucleus(app);\nn.render({ id: 'abc' });"]
}
},
"definitions": {
"Context": {
"kind": "interface",
"entries": {
"constraints": {
"optional": true,
"kind": "object",
"entries": {
"active": {
"optional": true,
"type": "boolean"
},
"passive": {
"optional": true,
"type": "boolean"
},
"select": {
"optional": true,
"type": "boolean"
}
}
},
"theme": {
"optional": true,
"defaultValue": "light",
"type": "string"
},
"language": {
"optional": true,
"defaultValue": "en-US",
"type": "string"
}
}
},
"Configuration": {
"kind": "interface",
"entries": {
"context": {
"optional": true,
"type": "#/definitions/Context"
},
"types": {
"optional": true,
"kind": "array",
"items": {
"type": "#/definitions/TypeInfo"
}
},
"themes": {
"optional": true,
"kind": "array",
"items": {
"type": "#/definitions/ThemeInfo"
}
},
"env": {
"optional": true,
"type": "object"
}
}
},
"Nucleus": {
"kind": "class",
"entries": {
"render": {
"description": "Renders a supernova into an HTMLElement.",
"kind": "function",
"params": [
{
"name": "cfg",
"description": "The render configuration.",
"kind": "union",
"items": [
{
"type": "#/definitions/CreateConfig"
},
{
"type": "#/definitions/GetConfig"
}
]
}
],
"returns": {
"description": "A controller to the rendered supernova",
"type": "Promise",
"generics": [
{
"type": "#/definitions/SupernovaController"
}
]
},
"examples": [
"// render from existing object\nn.render({\n element: el,\n id: 'abcdef'\n});",
"// render on the fly\nn.render({\n type: 'barchart',\n fields: ['Product', { qLibraryId: 'u378hn', type: 'measure' }]\n});"
]
},
"context": {
"description": "Updates the current context of this nucleus instance.\nUse this when you want to change some part of the current context, like theme.",
"kind": "function",
"params": [
{
"name": "ctx",
"description": "The context to update.",
"type": "#/definitions/Context"
}
],
"returns": {
"type": "Promise",
"generics": [
{
"type": "undefined"
}
]
},
"examples": [
"// change theme\nn.context({ theme: 'dark'});",
"// limit constraints\nn.context({ constraints: { active: true } });"
]
},
"selections": {
"description": "Gets the app selections of this instance.",
"kind": "function",
"params": [],
"returns": {
"type": "Promise",
"generics": [
{
"type": "#/definitions/AppSelections"
}
]
},
"examples": ["const selections = await n.selections();\nselections.mount(element);"]
}
}
},
"ThemeInfo": {
"kind": "interface",
"entries": {
"id": {
"description": "Theme identifier",
"type": "string"
},
"load": {
"description": "A function that should return a Promise that resolve to a raw JSON theme",
"kind": "function",
"params": [],
"returns": {
"type": "Promise",
"generics": [
{
"type": "ThemeJSON"
}
]
}
}
}
},
"SupernovaController": {
"description": "A controller to further modify a supernova after it has been rendered.",
"kind": "class",
"entries": {
"destroy": {
"description": "Destroys the supernova and removes if from the the DOM.",
"kind": "function",
"params": [],
"examples": ["const ctl =\nctl.destroy();"]
}
},
"examples": ["const ctl = await nucleus(app).render({\n element,\n type: 'barchart'\n});\nctl.destroy();"]
},
"AppSelections": {
"kind": "class",
"entries": {
"mount": {
"description": "Mounts the app selection UI into the provided HTMLElement",
"kind": "function",
"params": [
{
"name": "element",
"type": "HTMLElement"
}
],
"examples": ["selections.mount(element);"]
},
"unmount": {
"description": "Unmounts the app selection UI from the DOM",
"kind": "function",
"params": [],
"examples": ["selections.unmount();"]
}
}
},
"CreateConfig": {
"extends": [
{
"type": "#/definitions/BaseConfig"
}
],
"kind": "interface",
"entries": {
"type": {
"type": "string"
},
"version": {
"type": "string"
},
"fields": {
"optional": true,
"kind": "union",
"items": [
{
"kind": "array",
"items": {
"type": "#/definitions/Field"
}
}
]
},
"properties": {
"optional": true,
"type": "qae.GenericObjectProperties"
}
}
},
"BaseConfig": {
"kind": "interface",
"entries": {
"element": {
"type": "HTMLElement"
},
"options": {
"optional": true,
"type": "object"
}
}
},
"GetConfig": {
"extends": [
{
"type": "#/definitions/BaseConfig"
}
],
"kind": "interface",
"entries": {
"id": {
"type": "string"
}
}
},
"Field": {
"kind": "alias",
"items": {
"kind": "union",
"items": [
{
"type": "string"
},
{
"type": "qae.NxDimension"
},
{
"type": "qae.NxMeasure"
},
{
"type": "#/definitions/LibraryField"
}
]
}
},
"LibraryField": {
"kind": "interface",
"entries": {
"qLibraryId": {
"type": "string"
},
"type": {
"kind": "union",
"items": [
{
"kind": "literal",
"value": "dimension"
},
{
"kind": "literal",
"value": "measure"
}
]
}
}
},
"LoadType": {
"kind": "interface",
"params": [
{
"name": "type",
"kind": "object",
"entries": {
"name": {
"type": "string"
},
"version": {
"type": "string"
}
}
},
{
"name": "env",
"type": "object"
}
],
"returns": {
"type": "Promise",
"generics": [
{
"type": "Supernova"
}
]
},
"entries": {}
},
"TypeInfo": {
"kind": "interface",
"entries": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"load": {
"type": "#/definitions/LoadType"
},
"meta": {
"optional": true,
"type": "object"
}
}
}
}
}

View File

@@ -108,20 +108,20 @@ function nuked(configuration = {}) {
const locale = appLocaleFn(configuration.context.language); const locale = appLocaleFn(configuration.context.language);
/** /**
* Initiates a new `Nucleus` instance using the specified `app`. * Initiates a new embed instance using the specified `app`.
* @entry * @entry
* @interface nucleus * @function embed
* @param {enigma.Doc} app * @param {enigma.Doc} app
* @param {Configuration=} instanceConfig * @param {Configuration=} instanceConfig
* @returns {Nucleus} * @returns {Embed}
* @example * @example
* import nucleus from '@nebula.js/nucleus' * import { embed } from '@nebula.js/stardust'
* const n = nucleus(app); * const n = embed(app);
* n.render({ id: 'abc' }); * n.render({ id: 'abc' });
*/ */
function nucleus(app, instanceConfig) { function embed(app, instanceConfig) {
if (instanceConfig) { if (instanceConfig) {
return nucleus.createConfiguration(instanceConfig)(app); return embed.createConfiguration(instanceConfig)(app);
} }
let currentContext = { let currentContext = {
@@ -185,22 +185,14 @@ function nuked(configuration = {}) {
/** /**
* @class * @class
* @alias Nucleus * @alias Embed
* @hideconstructor * @hideconstructor
*/ */
const api = /** @lends Nucleus# */ { const api = /** @lends Embed# */ {
get: async () => {
// eslint-disable-next-line
console.warn(new Error('nucleus.get() has been deprecated, use nucleus.render() instead').stack);
},
create: async () => {
// eslint-disable-next-line
console.warn(new Error('nucleus.create() has been deprecated, use nucleus.render() instead').stack);
},
/** /**
* Renders a supernova into an HTMLElement. * Renders a visualization into an HTMLElement.
* @param {CreateConfig | GetConfig} cfg - The render configuration. * @param {CreateConfig | GetConfig} cfg - The render configuration.
* @returns {Promise<SupernovaController>} A controller to the rendered supernova * @returns {Promise<SupernovaController>} A controller to the rendered visualization
* @example * @example
* // render from existing object * // render from existing object
* n.render({ * n.render({
@@ -222,7 +214,7 @@ function nuked(configuration = {}) {
return create(cfg, corona); return create(cfg, corona);
}, },
/** /**
* Updates the current context of this nucleus instance. * Updates the current context of this embed instance.
* Use this when you want to change some part of the current context, like theme. * Use this when you want to change some part of the current context, like theme.
* @param {Context} ctx - The context to update. * @param {Context} ctx - The context to update.
* @returns {Promise<undefined>} * @returns {Promise<undefined>}
@@ -320,16 +312,16 @@ function nuked(configuration = {}) {
} }
/** /**
* Creates a new `nucleus` scope bound to the specified `configuration`. * Creates a new `embed` scope bound to the specified `configuration`.
* *
* The configuration is merged with all previous scopes. * The configuration is merged with all previous scopes.
* @memberof nucleus * @memberof embed
* @param {Configuration} configuration - The configuration object * @param {Configuration} configuration - The configuration object
* @returns {nucleus} * @returns {Embed}
* @example * @example
* import nucleus from '@nebula.js/nucleus'; * import { embed } from '@nebula.js/stardust';
* // create a 'master' config which registers all types * // create a 'master' config which registers all types
* const m = nucleus.createConfiguration({ * const m = embed.createConfiguration({
* types: [{ * types: [{
* name: 'mekko', * name: 'mekko',
* version: '1.0.0', * version: '1.0.0',
@@ -345,12 +337,12 @@ function nuked(configuration = {}) {
* *
* m(app).render({ type: 'mekko' }); // will render the object with default theme * m(app).render({ type: 'mekko' }); // will render the object with default theme
* d(app).render({ type: 'mekko' }); // will render the object with 'dark' theme * d(app).render({ type: 'mekko' }); // will render the object with 'dark' theme
* nucleus(app).render({ type: 'mekko' }); // will throw error since 'mekko' is not a register type on the default instance * embed(app).render({ type: 'mekko' }); // will throw error since 'mekko' is not a register type on the default instance
*/ */
nucleus.createConfiguration = (c) => nuked(mergeConfigs(configuration, c)); embed.createConfiguration = (c) => nuked(mergeConfigs(configuration, c));
nucleus.config = configuration; embed.config = configuration;
return nucleus; return embed;
} }
/** /**

View File

@@ -7,7 +7,7 @@
"keywords": [ "keywords": [
"qlik", "qlik",
"nebula", "nebula",
"supernova", "stardust",
"snapshot" "snapshot"
], ],
"publishConfig": { "publishConfig": {

View File

@@ -2,15 +2,15 @@ import renderer from '../renderer';
describe('snapshooter', () => { describe('snapshooter', () => {
let sandbox; let sandbox;
let nucleus; let embed;
let nebbie; let nebbie;
before(() => { before(() => {
sandbox = sinon.createSandbox(); sandbox = sinon.createSandbox();
}); });
beforeEach(() => { beforeEach(() => {
nucleus = sandbox.stub(); embed = sandbox.stub();
nucleus.config = { embed.config = {
snapshot: { snapshot: {
get: sandbox.stub(), get: sandbox.stub(),
}, },
@@ -19,9 +19,9 @@ describe('snapshooter', () => {
nebbie = { nebbie = {
render: sandbox.stub().returns(Promise.resolve()), render: sandbox.stub().returns(Promise.resolve()),
}; };
nucleus.returns(nebbie); embed.returns(nebbie);
nucleus.config.snapshot.get.returns( embed.config.snapshot.get.returns(
Promise.resolve({ Promise.resolve({
meta: { theme: 'dark', language: 'sv' }, meta: { theme: 'dark', language: 'sv' },
layout: { layout: {
@@ -39,17 +39,17 @@ describe('snapshooter', () => {
}); });
it('should get snapshot with id "abc"', async () => { it('should get snapshot with id "abc"', async () => {
await renderer({ nucleus, snapshot: 'abc' }); await renderer({ embed, snapshot: 'abc' });
expect(nucleus.config.snapshot.get).to.have.been.calledWithExactly('abc'); expect(embed.config.snapshot.get).to.have.been.calledWithExactly('abc');
}); });
it('should catch snapshot get errors and render the error', async () => { it('should catch snapshot get errors and render the error', async () => {
nucleus.config.snapshot.get.throws(new Error('meh')); embed.config.snapshot.get.throws(new Error('meh'));
const element = { const element = {
setAttribute: sandbox.stub(), setAttribute: sandbox.stub(),
}; };
try { try {
await renderer({ nucleus, element, snapshot: '' }); await renderer({ embed, element, snapshot: '' });
expect(1).to.equal('a'); // just to make sure this test fails if error is not trown expect(1).to.equal('a'); // just to make sure this test fails if error is not trown
} catch (e) { } catch (e) {
/* */ /* */
@@ -58,9 +58,9 @@ describe('snapshooter', () => {
expect(element.innerHTML).to.eql('<p>meh</p>'); expect(element.innerHTML).to.eql('<p>meh</p>');
}); });
it('should call nucleus with context theme and language', async () => { it('should call embed with context theme and language', async () => {
await renderer({ nucleus, snapshot: '' }); await renderer({ embed, snapshot: '' });
expect(nucleus.firstCall.args[1]).to.eql({ expect(embed.firstCall.args[1]).to.eql({
context: { context: {
theme: 'dark', theme: 'dark',
language: 'sv', language: 'sv',
@@ -69,8 +69,8 @@ describe('snapshooter', () => {
}); });
it('should mock an app that returns a mocked model', async () => { it('should mock an app that returns a mocked model', async () => {
await renderer({ nucleus, snapshot: '' }); await renderer({ embed, snapshot: '' });
const app = nucleus.firstCall.args[0]; const app = embed.firstCall.args[0];
const model = await app.getObject('xyz'); const model = await app.getObject('xyz');
expect(model.getLayout).to.be.a('function'); expect(model.getLayout).to.be.a('function');
expect(model.on).to.be.a('function'); expect(model.on).to.be.a('function');
@@ -78,8 +78,8 @@ describe('snapshooter', () => {
}); });
it('the mocked model should return the snapshot as layout', async () => { it('the mocked model should return the snapshot as layout', async () => {
await renderer({ nucleus, snapshot: '' }); await renderer({ embed, snapshot: '' });
const app = nucleus.firstCall.args[0]; const app = embed.firstCall.args[0];
const model = await app.getObject('xyz'); const model = await app.getObject('xyz');
const ly = await model.getLayout(); const ly = await model.getLayout();
expect(ly).to.eql({ expect(ly).to.eql({
@@ -91,8 +91,8 @@ describe('snapshooter', () => {
}); });
it('should reject mocked getObject when id is not matching qId', async () => { it('should reject mocked getObject when id is not matching qId', async () => {
await renderer({ nucleus, snapshot: '' }); await renderer({ embed, snapshot: '' });
const app = nucleus.firstCall.args[0]; const app = embed.firstCall.args[0];
try { try {
await app.getObject('unknown'); await app.getObject('unknown');
expect(1).to.equal(0); // should never reach this point expect(1).to.equal(0); // should never reach this point
@@ -103,7 +103,7 @@ describe('snapshooter', () => {
it('should call nebbie.render() with id when qInfo.qId is truthy', async () => { it('should call nebbie.render() with id when qInfo.qId is truthy', async () => {
const el = 'el'; const el = 'el';
await renderer({ nucleus, element: el, snapshot: '' }); await renderer({ embed, element: el, snapshot: '' });
expect(nebbie.render).to.have.been.calledWithExactly({ expect(nebbie.render).to.have.been.calledWithExactly({
id: 'xyz', id: 'xyz',
element: el, element: el,
@@ -113,7 +113,7 @@ describe('snapshooter', () => {
it('should call nebbie.render() with type when qInfo is falsy', async () => { it('should call nebbie.render() with type when qInfo is falsy', async () => {
const el = 'el'; const el = 'el';
await renderer({ await renderer({
nucleus, embed,
element: el, element: el,
snapshot: { meta: {}, layout: { myProp: 'yes', visualization: 'legendary' } }, snapshot: { meta: {}, layout: { myProp: 'yes', visualization: 'legendary' } },
}); });
@@ -130,7 +130,7 @@ describe('snapshooter', () => {
}; };
nebbie.render.throws(new Error('aaaaaaah!')); nebbie.render.throws(new Error('aaaaaaah!'));
try { try {
await renderer({ nucleus, element: el, snapshot: '' }); await renderer({ embed, element: el, snapshot: '' });
} catch (e) { } catch (e) {
expect(e.message).to.eql('aaaaaaah!'); expect(e.message).to.eql('aaaaaaah!');
} }

View File

@@ -1,12 +1,12 @@
/* eslint no-param-reassign: 0 */ /* eslint no-param-reassign: 0 */
async function renderSnapshot({ nucleus, element, snapshot: key }) { async function renderSnapshot({ embed, element, snapshot: key }) {
let snapshot = {}; let snapshot = {};
const renderError = (e) => { const renderError = (e) => {
element.innerHTML = `<p>${e.message}</p>`; element.innerHTML = `<p>${e.message}</p>`;
element.setAttribute('data-njs-error', e.message); element.setAttribute('data-njs-error', e.message);
}; };
try { try {
snapshot = typeof key === 'string' ? await nucleus.config.snapshot.get(key) : key; snapshot = typeof key === 'string' ? await embed.config.snapshot.get(key) : key;
} catch (e) { } catch (e) {
renderError(e); renderError(e);
throw e; throw e;
@@ -38,13 +38,13 @@ async function renderSnapshot({ nucleus, element, snapshot: key }) {
getAppLayout: async () => appLayout || {}, getAppLayout: async () => appLayout || {},
}; };
const nebbie = await nucleus(app, { const nebbie = await embed(app, {
context: { context: {
theme, theme,
language, language,
// do NOT override constraints to allow the passed in nuked config to control it instead, // do NOT override constraints to allow the passed in embedding config to control it instead,
// however, since it's a snapshot the 'select' constraint will always be set to true from // however, since it's a snapshot the 'select' constraint will always be set to true from
// the nucleus internals // the embed internals
// constraints: {} // constraints: {}
}, },
}); });
@@ -63,7 +63,7 @@ async function renderSnapshot({ nucleus, element, snapshot: key }) {
} }
); );
} catch (e) { } catch (e) {
renderError(e || { message: 'Failed to render supernova' }); renderError(e || { message: 'Failed to render visualization.' });
throw e; throw e;
} }
} }

21
apis/stardust/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2020-present QlikTech International AB
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

29
apis/stardust/README.md Normal file
View File

@@ -0,0 +1,29 @@
# stardust
Stardust is a JavaScript library for building and embedding visualizations on top of Qlik's Associative Engine.
## Installation
```sh
npm install @nebula.js/stardust
```
## Example usage
```js
import { embed } from '@nebula.js/stardust';
import mekko from '@nebula.js/sn-mekko-chart';
const orion = embed.createConfiguration({
types: [{
name: 'mekko',
load: () => Promise.resolve(mekko);
}]
})(app);
orion.render({
element,
type: 'mekko',
fields: ['Product', 'Region', 'Sales']
});
```

5
apis/stardust/index.js Normal file
View File

@@ -0,0 +1,5 @@
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/stardust.js');
} else {
module.exports = require('./dist/stardust.dev.js');
}

View File

@@ -0,0 +1,63 @@
{
"name": "@nebula.js/stardust",
"version": "0.5.0",
"description": "Product and framework agnostic integration API for Qlik's Associative Engine",
"license": "MIT",
"author": "QlikTech International AB",
"keywords": [
"qlik",
"qix",
"sense",
"nebula",
"stardust"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/qlik-oss/nebula.js.git",
"directory": "apis/stardust"
},
"main": "index.js",
"module": "dist/stardust.esm",
"jsdelivr": "dist/stardust.js",
"unpkg": "dist/stardust.js",
"files": [
"LICENSE",
"dist"
],
"scripts": {
"build": "cross-env NODE_ENV=production rollup --config ../../rollup.config.js",
"build:dev": "rollup --config ../../rollup.config.js",
"build:watch": "rollup --config ../../rollup.config.js -w",
"prepublishOnly": "rm -rf dist && yarn run build",
"spec": "scriptappy-from-jsdoc -c ./spec/spec.conf.js"
},
"devDependencies": {
"@material-ui/core": "4.9.9",
"@material-ui/icons": "4.9.1",
"@material-ui/styles": "4.9.6",
"@nebula.js/locale": "0.5.0",
"@nebula.js/nucleus": "0.5.0",
"@nebula.js/supernova": "0.5.0",
"@nebula.js/theme": "0.5.0",
"@nebula.js/ui": "0.5.0",
"extend": "3.0.2",
"node-event-emitter": "0.0.1",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-test-renderer": "16.13.1",
"react-window": "1.8.5",
"react-window-infinite-loader": "1.0.5",
"regenerator-runtime": "0.13.5",
"semver": "6.3.0"
},
"peerDependencies": {
"@material-ui/core": "^4.9.0",
"@material-ui/icons": "^4.5.1",
"@material-ui/styles": "^4.9.0",
"react": "^16.12.0",
"react-dom": "^16.12.0"
}
}

View File

@@ -0,0 +1,35 @@
/* eslint no-underscore-dangle: 0 */
import 'regenerator-runtime/runtime'; // Polyfill for using async/await
import embed from '@nebula.js/nucleus';
import { generator, hook } from '@nebula.js/supernova';
// mashup api
export { embed };
// component api
export {
useState,
useEffect,
useMemo,
useImperativeHandle,
usePromise,
useAction,
useRect,
useModel,
useApp,
useGlobal,
useElement,
useSelections,
useTheme,
useLayout,
useStaleLayout,
useAppLayout,
useTranslator,
useConstraints,
useOptions,
onTakeSnapshot,
} from '@nebula.js/supernova';
// component internals
const __DO_NOT_USE__ = { generator, hook };
export { __DO_NOT_USE__ };

View File

@@ -1,5 +0,0 @@
if (process.env.NODE_ENV === 'production') {
module.exports = require('./dist/supernova.js');
} else {
module.exports = require('./dist/supernova.dev.js');
}

View File

@@ -1,35 +1,10 @@
{ {
"name": "@nebula.js/supernova", "name": "@nebula.js/supernova",
"private": true,
"version": "0.5.0", "version": "0.5.0",
"description": "", "main": "src/index.js",
"license": "MIT",
"author": "QlikTech International AB",
"keywords": [],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/qlik-oss/nebula.js.git",
"directory": "apis/supernova"
},
"main": "index.js",
"module": "dist/supernova.esm",
"jsdelivr": "dist/supernova.js",
"unpkg": "dist/supernova.js",
"files": [
"dist"
],
"scripts": {
"build": "cross-env NODE_ENV=production rollup --config ../../rollup.config.js",
"build:dev": "rollup --config ../../rollup.config.js",
"build:watch": "rollup --config ../../rollup.config.js -w",
"prepublishOnly": "rm -rf dist && yarn run build",
"spec": "scriptappy-from-jsdoc -c ./spec/spec.conf.js"
},
"devDependencies": { "devDependencies": {
"extend": "3.0.2", "extend": "3.0.2",
"node-event-emitter": "0.0.1", "node-event-emitter": "0.0.1"
"regenerator-runtime": "0.13.5"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ import qae from './qae';
* @param {Galaxy} galaxy * @param {Galaxy} galaxy
* @returns {SupernovaDefinition} * @returns {SupernovaDefinition}
* @example * @example
* import { useElement, useLayout } from '@nebula.js/supernova'; * import { useElement, useLayout } from '@nebula.js/stardust';
* *
* export default function() { * export default function() {
* return { * return {

View File

@@ -254,7 +254,7 @@ export function hook(cb) {
* @param {S|function():S} initialState - The initial state. * @param {S|function():S} initialState - The initial state.
* @returns {Array<S,SetStateFn<S>>} The value and a function to update it. * @returns {Array<S,SetStateFn<S>>} The value and a function to update it.
* @example * @example
* import { useState } from '@nebula.js/supernova'; * import { useState } from '@nebula.js/stardust';
* // ... * // ...
* // initiate with simple primitive value * // initiate with simple primitive value
* const [zoomed, setZoomed] = useState(false); * const [zoomed, setZoomed] = useState(false);
@@ -301,7 +301,7 @@ export function useState(initial) {
* @param {EffectCallback} effect - The callback. * @param {EffectCallback} effect - The callback.
* @param {Array<any>=} deps - The dependencies which should trigger the callback. * @param {Array<any>=} deps - The dependencies which should trigger the callback.
* @example * @example
* import { useEffect } from '@nebula.js/supernova'; * import { useEffect } from '@nebula.js/stardust';
* // ... * // ...
* useEffect(() => { * useEffect(() => {
* console.log('mounted'); * console.log('mounted');
@@ -347,7 +347,7 @@ function useLayoutEffect(cb, deps) {
* @param {Array<any>} deps - The dependencies. * @param {Array<any>} deps - The dependencies.
* @returns {T} The value returned from the factory function. * @returns {T} The value returned from the factory function.
* @example * @example
* import { useMemo } from '@nebula.js/supernova'; * import { useMemo } from '@nebula.js/stardust';
* // ... * // ...
* const v = useMemo(() => { * const v = useMemo(() => {
* return doSomeHeavyCalculation(); * return doSomeHeavyCalculation();
@@ -374,8 +374,8 @@ export function useMemo(fn, deps) {
* @param {Array<any>=} deps - The dependencies. * @param {Array<any>=} deps - The dependencies.
* @returns {Array<P,Error>} The resolved value. * @returns {Array<P,Error>} The resolved value.
* @example * @example
* import { usePromise } from '@nebula.js/supernova'; * import { usePromise } from '@nebula.js/stardust';
* import { useModel } from '@nebula.js/supernova'; * import { useModel } from '@nebula.js/stardust';
* // ... * // ...
* const model = useModel(); * const model = useModel();
* const [resolved, rejected] = usePromise(() => model.getLayout(), []); * const [resolved, rejected] = usePromise(() => model.getLayout(), []);
@@ -448,7 +448,7 @@ export function usePromise(p, deps) {
* @entry * @entry
* @returns {HTMLElement} * @returns {HTMLElement}
* @example * @example
* import { useElement } from '@nebula.js/supernova'; * import { useElement } from '@nebula.js/stardust';
* // ... * // ...
* const el = useElement(); * const el = useElement();
* el.innerHTML = 'Hello!'; * el.innerHTML = 'Hello!';
@@ -470,7 +470,7 @@ export function useElement() {
* @entry * @entry
* @returns {Rect} The size of the element. * @returns {Rect} The size of the element.
* @example * @example
* import { useRect } from '@nebula.js/supernova'; * import { useRect } from '@nebula.js/stardust';
* // ... * // ...
* const rect = useRect(); * const rect = useRect();
* useEffect(() => { * useEffect(() => {
@@ -549,7 +549,7 @@ export function useRect() {
* @entry * @entry
* @returns {qae.GenericObjectLayout} * @returns {qae.GenericObjectLayout}
* @example * @example
* import { useLayout } from '@nebula.js/supernova'; * import { useLayout } from '@nebula.js/stardust';
* // ... * // ...
* const layout = useLayout(); * const layout = useLayout();
* console.log(layout); * console.log(layout);
@@ -569,7 +569,7 @@ export function useLayout() {
* @entry * @entry
* @returns {qae.GenericObjectLayout} * @returns {qae.GenericObjectLayout}
* @example * @example
* import { useStaleLayout } from '@nebula.js/supernova'; * import { useStaleLayout } from '@nebula.js/stardust';
* // ... * // ...
* const staleLayout = useStaleLayout(); * const staleLayout = useStaleLayout();
* console.log(staleLayout); * console.log(staleLayout);
@@ -588,7 +588,7 @@ export function useStaleLayout() {
* @entry * @entry
* @returns {qae.NxAppLayout} The app layout * @returns {qae.NxAppLayout} The app layout
* @example * @example
* import { useAppLayout } from '@nebula.js/supernova'; * import { useAppLayout } from '@nebula.js/stardust';
* // ... * // ...
* const appLayout = useAppLayout(); * const appLayout = useAppLayout();
* console.log(appLayout.qLocaleInfo); * console.log(appLayout.qLocaleInfo);
@@ -602,7 +602,7 @@ export function useAppLayout() {
* @entry * @entry
* @returns {enigma.GenericObject|undefined} * @returns {enigma.GenericObject|undefined}
* @example * @example
* import { useModel } from '@nebula.js/supernova'; * import { useModel } from '@nebula.js/stardust';
* // ... * // ...
* const model = useModel(); * const model = useModel();
* useEffect(() => { * useEffect(() => {
@@ -621,7 +621,7 @@ export function useModel() {
* @entry * @entry
* @returns {enigma.Doc|undefined} The doc API. * @returns {enigma.Doc|undefined} The doc API.
* @example * @example
* import { useApp } from '@nebula.js/supernova'; * import { useApp } from '@nebula.js/stardust';
* // ... * // ...
* const app = useApp(); * const app = useApp();
* useEffect(() => { * useEffect(() => {
@@ -640,7 +640,7 @@ export function useApp() {
* @entry * @entry
* @returns {enigma.Global|undefined} The global API. * @returns {enigma.Global|undefined} The global API.
* @example * @example
* import { useGlobal } from '@nebula.js/supernova'; * import { useGlobal } from '@nebula.js/stardust';
* *
* // ... * // ...
* const g = useGlobal(); * const g = useGlobal();
@@ -660,9 +660,9 @@ export function useGlobal() {
* @entry * @entry
* @returns {ObjectSelections} The object selections. * @returns {ObjectSelections} The object selections.
* @example * @example
* import { useSelections } from '@nebula.js/supernova'; * import { useSelections } from '@nebula.js/stardust';
* import { useElement } from '@nebula.js/supernova'; * import { useElement } from '@nebula.js/stardust';
* import { useEffect } from '@nebula.js/supernova'; * import { useEffect } from '@nebula.js/stardust';
* // ... * // ...
* const selections = useSelections(); * const selections = useSelections();
* const element = useElement(); * const element = useElement();
@@ -685,7 +685,7 @@ export function useSelections() {
* @entry * @entry
* @returns {Theme} The theme. * @returns {Theme} The theme.
* @example * @example
* import { useTheme } from '@nebula.js/supernova'; * import { useTheme } from '@nebula.js/stardust';
* *
* const theme = useTheme(); * const theme = useTheme();
* console.log(theme.getContrastinColorTo('#ff0000')); * console.log(theme.getContrastinColorTo('#ff0000'));
@@ -699,7 +699,7 @@ export function useTheme() {
* @entry * @entry
* @returns {Translator} The translator. * @returns {Translator} The translator.
* @example * @example
* import { useTranslator } from '@nebula.js/supernova'; * import { useTranslator } from '@nebula.js/stardust';
* // ... * // ...
* const translator = useTranslator(); * const translator = useTranslator();
* console.log(translator.get('SomeString')); * console.log(translator.get('SomeString'));
@@ -730,7 +730,7 @@ export function useTranslator() {
* @returns {A} * @returns {A}
* *
* @example * @example
* import { useAction } from '@nebula.js/supernova'; * import { useAction } from '@nebula.js/stardust';
* // ... * // ...
* const [zoomed, setZoomed] = useState(false); * const [zoomed, setZoomed] = useState(false);
* const act = useAction(() => ({ * const act = useAction(() => ({
@@ -785,15 +785,15 @@ export function useAction(fn, deps) {
* @entry * @entry
* @returns {Constraints} * @returns {Constraints}
* @example * @example
* // configure nucleus to disallow active interactions when rendering * // configure embed to disallow active interactions when rendering
* nucleus(app, { * embed(app, {
* constraints: { * constraints: {
* active: true, // do not allow interactions * active: true, // do not allow interactions
* } * }
* }).render({ element, id: 'sdfsdf' }); * }).render({ element, id: 'sdfsdf' });
* *
* @example * @example
* import { useConstraints } from '@nebula.js/supernova'; * import { useConstraints } from '@nebula.js/stardust';
* // ... * // ...
* const constraints = useConstraints(); * const constraints = useConstraints();
* useEffect(() => { * useEffect(() => {
@@ -825,8 +825,8 @@ export function useConstraints() {
* @returns {object} * @returns {object}
* *
* @example * @example
* // when rendering the supernova with nucleus, anything can be set in options * // when embedding the supernova, anything can be set in options
* nucleus(app).render({ * embed(app).render({
* element, * element,
* type: 'my-chart', * type: 'my-chart',
* options: { * options: {
@@ -836,8 +836,8 @@ export function useConstraints() {
* *
* @example * @example
* // it is up to you use and implement the provided options * // it is up to you use and implement the provided options
* import { useOptions } from '@nebula.js/supernova'; * import { useOptions } from '@nebula.js/stardust';
* import { useEffect } from '@nebula.js/supernova'; * import { useEffect } from '@nebula.js/stardust';
* // ... * // ...
* const options = useOptions(); * const options = useOptions();
* useEffect(() => { * useEffect(() => {
@@ -867,7 +867,7 @@ export function useOptions() {
* @param {function():T} factory * @param {function():T} factory
* @param {Array<any>=} deps * @param {Array<any>=} deps
* @example * @example
* import { useImperativeHandle } form '@nebula.js/supernova'; * import { useImperativeHandle } form '@nebula.js/stardust';
* // ... * // ...
* useImperativeHandle(() => ({ * useImperativeHandle(() => ({
* resetZoom() { * resetZoom() {
@@ -876,9 +876,9 @@ export function useOptions() {
* })); * }));
* *
* @example * @example
* // when rendering the supernova with nucleus, you can get a handle to this API * // when embedding the supernova, you can get a handle to this API
* // and use it to control the supernova * // and use it to control the supernova
* const ctl = await nucleus(app).render({ * const ctl = await embed(app).render({
* element, * element,
* type: 'my-chart', * type: 'my-chart',
* }); * });
@@ -907,9 +907,9 @@ export function useImperativeHandle(fn, deps) {
* @entry * @entry
* @param {function(qae.GenericObjectLayout): Promise<qae.GenericObjectLayout>} snapshotCallback * @param {function(qae.GenericObjectLayout): Promise<qae.GenericObjectLayout>} snapshotCallback
* @example * @example
* import { onTakeSnapshot } from '@nebula.js/supernova'; * import { onTakeSnapshot } from '@nebula.js/stardust';
* import { useState } from '@nebula.js/supernova'; * import { useState } from '@nebula.js/stardust';
* import { useLayout } from '@nebula.js/supernova'; * import { useLayout } from '@nebula.js/stardust';
* *
* const layout = useLayout(); * const layout = useLayout();
* const [zoomed] = useState(layout.isZoomed || false); * const [zoomed] = useState(layout.isZoomed || false);

View File

@@ -1,4 +1,3 @@
import 'regenerator-runtime/runtime'; // Polyfill for using async/await
import generator from './generator'; import generator from './generator';
export { generator }; export { generator };

View File

@@ -24,9 +24,6 @@
"prepublishOnly": "rm -rf dist && yarn run build" "prepublishOnly": "rm -rf dist && yarn run build"
}, },
"peerDependencies": { "peerDependencies": {
"@nebula.js/supernova": "^0.x" "@nebula.js/stardust": "^0.x"
},
"devDependencies": {
"regenerator-runtime": "0.13.5"
} }
} }

View File

@@ -19,7 +19,7 @@ describe('test-utils', () => {
updateRectOnNextRun: sandbox.stub(), updateRectOnNextRun: sandbox.stub(),
}; };
hook = sandbox.stub().returns(hooked); hook = sandbox.stub().returns(hooked);
[{ create }] = aw.mock([['@nebula.js/supernova', () => ({ hook })]], ['../index']); [{ create }] = aw.mock([['@nebula.js/stardust', () => ({ __DO_NOT_USE__: { hook } })]], ['../index']);
}); });
afterEach(() => { afterEach(() => {

View File

@@ -1,7 +1,8 @@
/* eslint import/prefer-default-export:0 */ /* eslint import/prefer-default-export:0 */
import 'regenerator-runtime/runtime'; // temporary polyfill for transpiled async/await in supernova import { __DO_NOT_USE__ } from '@nebula.js/stardust';
import { hook } from '@nebula.js/supernova';
const { hook } = __DO_NOT_USE__;
if (!global.requestAnimationFrame) { if (!global.requestAnimationFrame) {
global.requestAnimationFrame = (cb) => setTimeout(cb, 10); global.requestAnimationFrame = (cb) => setTimeout(cb, 10);

View File

@@ -7,9 +7,10 @@ module.exports = {
exclude: [ exclude: [
'**/commands/**', '**/commands/**',
'**/__stories__/**', '**/__stories__/**',
'**/apis/supernova/index.js',
'**/apis/nucleus/index.js', '**/apis/nucleus/index.js',
'**/apis/locale/index.js', '**/apis/locale/index.js',
'**/apis/stardust/index.js',
'**/apis/supernova/index.js',
'**/apis/theme/index.js', '**/apis/theme/index.js',
'**/apis/test-utils/index.js', '**/apis/test-utils/index.js',
'**/packages/ui/icons/**/*.js', // Exclude the defined icons but test the `<SvgIcon />` '**/packages/ui/icons/**/*.js', // Exclude the defined icons but test the `<SvgIcon />`

View File

@@ -40,11 +40,11 @@ const config = ({ mode = 'production', format = 'umd', cwd = process.cwd(), argv
const peers = pkg.peerDependencies || {}; const peers = pkg.peerDependencies || {};
const external = format === 'esm' ? Object.keys(peers) : []; const external = format === 'esm' ? Object.keys(peers) : [];
// supernova should always be external // stardust should always be external
if (!peers['@nebula.js/supernova']) { if (!peers['@nebula.js/stardust']) {
console.warn('@nebula.js/supernova should be specified as a peer dependency'); console.warn('@nebula.js/stardust should be specified as a peer dependency');
} else if (external.indexOf('@nebula.js/supernova') === -1) { } else if (external.indexOf('@nebula.js/stardust') === -1) {
external.push('@nebula.js/supernova'); external.push('@nebula.js/stardust');
} }
return { return {
@@ -90,7 +90,7 @@ const config = ({ mode = 'production', format = 'umd', cwd = process.cwd(), argv
name: moduleName, name: moduleName,
sourcemap, sourcemap,
globals: { globals: {
'@nebula.js/supernova': 'supernova', '@nebula.js/stardust': 'stardust',
}, },
}, },
}; };

View File

@@ -10,9 +10,8 @@
"start": "parcel src/index.html" "start": "parcel src/index.html"
}, },
"dependencies": { "dependencies": {
"@nebula.js/nucleus": "<%= nebulaVersion %>", "@nebula.js/stardust": "<%= nebulaVersion %>",
"@nebula.js/sn-bar-chart": "^0.2.2", "@nebula.js/sn-bar-chart": "^0.2.2",
"@nebula.js/supernova": "<%= nebulaVersion %>",
"enigma.js": "^2.6.3", "enigma.js": "^2.6.3",
"parcel-bundler": "^1.12.4" "parcel-bundler": "^1.12.4"
} }

View File

@@ -1,8 +1,8 @@
import nucleus from '@nebula.js/nucleus/dist/nucleus'; import { embed } from '@nebula.js/stardust/dist/stardust';
import barchart from '@nebula.js/sn-bar-chart'; import barchart from '@nebula.js/sn-bar-chart';
const n = nucleus.createConfiguration({ const n = embed.createConfiguration({
context: { context: {
theme: 'light', theme: 'light',
language: 'en-US', language: 'en-US',

View File

@@ -1,5 +1,5 @@
/* eslint-disable */ /* eslint-disable */
import nucleus from './configure'; import embed from './configure';
import connect from './connect'; import connect from './connect';
async function run() { async function run() {
@@ -9,7 +9,7 @@ async function run() {
appId: '<App id>', appId: '<App id>',
}); });
const n = nucleus(app); const n = embed(app);
(await n.selections()).mount(document.querySelector('.toolbar')); (await n.selections()).mount(document.querySelector('.toolbar'));

View File

@@ -31,6 +31,6 @@
"eslint-plugin-mocha": "5.2.1" "eslint-plugin-mocha": "5.2.1"
}, },
"peerDependencies": { "peerDependencies": {
"@nebula.js/supernova": "^0.x" "@nebula.js/stardust": "^0.x"
} }
} }

View File

@@ -1,4 +1,4 @@
import { useElement } from '@nebula.js/supernova'; import { useElement } from '@nebula.js/stardust';
import properties from './object-properties'; import properties from './object-properties';
import data from './data'; import data from './data';

View File

@@ -33,6 +33,6 @@
"picasso-plugin-q": "0.25.2" "picasso-plugin-q": "0.25.2"
}, },
"peerDependencies": { "peerDependencies": {
"@nebula.js/supernova": "^0.1.0-alpha.28" "@nebula.js/stardust": "^0.x"
} }
} }

View File

@@ -6,7 +6,7 @@ import {
useRect, useRect,
useEffect, useEffect,
useConstraints, useConstraints,
} from '@nebula.js/supernova'; } from '@nebula.js/stardust';
import picassojs from 'picasso.js'; import picassojs from 'picasso.js';
import picassoQ from 'picasso-plugin-q'; import picassoQ from 'picasso-plugin-q';

View File

@@ -30,9 +30,8 @@ const cfg = ({ srcDir, distDir, dev = false, serveConfig = {} }) => {
}, },
resolve: { resolve: {
alias: { alias: {
'@nebula.js/nucleus': path.resolve(__dirname, '../../../apis/nucleus'), '@nebula.js/stardust': path.resolve(__dirname, '../../../apis/stardust/src'),
'@nebula.js/snapshooter/client': path.resolve(__dirname, '../../../apis/snapshooter/src/renderer'), '@nebula.js/snapshooter/client': path.resolve(__dirname, '../../../apis/snapshooter/src/renderer'),
'@nebula.js/supernova': path.resolve(__dirname, '../../../apis/supernova/src'),
'@nebula.js/theme': path.resolve(__dirname, '../../../apis/theme/src'), '@nebula.js/theme': path.resolve(__dirname, '../../../apis/theme/src'),
'@nebula.js/locale': path.resolve(__dirname, '../../../apis/locale/src'), '@nebula.js/locale': path.resolve(__dirname, '../../../apis/locale/src'),
fixtures: path.resolve(__dirname, '../../../test/component'), fixtures: path.resolve(__dirname, '../../../test/component'),

View File

@@ -51,12 +51,14 @@
"@babel/preset-react": "7.9.4", "@babel/preset-react": "7.9.4",
"@material-ui/core": "4.9.9", "@material-ui/core": "4.9.9",
"@nebula.js/nucleus": "0.5.0", "@nebula.js/nucleus": "0.5.0",
"@nebula.js/supernova": "0.5.0", "@nebula.js/stardust": "0.5.0",
"@nebula.js/ui": "0.5.0", "@nebula.js/ui": "0.5.0",
"autosuggest-highlight": "3.1.1", "autosuggest-highlight": "3.1.1",
"babel-loader": "8.1.0", "babel-loader": "8.1.0",
"d3-require": "1.2.4", "d3-require": "1.2.4",
"enigma.js": "2.6.3", "enigma.js": "2.6.3",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-webpack": "^0.12.1",
"monaco-editor": "0.20.0", "monaco-editor": "0.20.0",
"monaco-editor-webpack-plugin": "1.9.0", "monaco-editor-webpack-plugin": "1.9.0",
"react": "16.13.1", "react": "16.13.1",

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useLayoutEffect, useState, useRef, useMemo } from 'react'; import React, { useEffect, useLayoutEffect, useState, useRef, useMemo } from 'react';
import nucleus from '@nebula.js/nucleus/src/index'; import { embed } from '@nebula.js/stardust';
import { createTheme, ThemeProvider } from '@nebula.js/ui/theme'; import { createTheme, ThemeProvider } from '@nebula.js/ui/theme';
import { WbSunny, Brightness3, ColorLens, Language, Home } from '@nebula.js/ui/icons'; import { WbSunny, Brightness3, ColorLens, Language, Home } from '@nebula.js/ui/icons';
@@ -79,7 +79,7 @@ export default function App({ app, info }) {
); );
useEffect(() => { useEffect(() => {
const n = nucleus(app, { const n = embed(app, {
context: { context: {
theme: currentThemeName, theme: currentThemeName,
language: currentLanguage, language: currentLanguage,

View File

@@ -1,4 +1,4 @@
import nucleus from '@nebula.js/nucleus'; import { embed } from '@nebula.js/stardust';
import snapshooter from '@nebula.js/snapshooter/client'; import snapshooter from '@nebula.js/snapshooter/client';
import { openApp, params, info as serverInfo } from './connect'; import { openApp, params, info as serverInfo } from './connect';
@@ -6,7 +6,7 @@ import runFixture from './run-fixture';
import initiateWatch from './hot'; import initiateWatch from './hot';
const nuke = async ({ app, supernova: { name }, themes, theme, language }) => { const nuke = async ({ app, supernova: { name }, themes, theme, language }) => {
const nuked = nucleus.createConfiguration({ const nuked = embed.createConfiguration({
themes: themes themes: themes
? themes.map((t) => ({ ? themes.map((t) => ({
key: t, key: t,
@@ -71,7 +71,7 @@ async function renderSnapshot() {
const element = document.querySelector('#chart-container'); const element = document.querySelector('#chart-container');
element.classList.toggle('full', true); element.classList.toggle('full', true);
const n = nucleus.createConfiguration({ const n = embed.createConfiguration({
themes: themes themes: themes
? themes.map((t) => ({ ? themes.map((t) => ({
key: t, key: t,
@@ -94,7 +94,7 @@ async function renderSnapshot() {
window.onHotChange(supernova.name, async () => { window.onHotChange(supernova.name, async () => {
snapshooter({ snapshooter({
nucleus: n, embed: n,
element, element,
snapshot: params.snapshot, snapshot: params.snapshot,
}); });
@@ -152,7 +152,7 @@ const renderFixture = async () => {
}), }),
}; };
const nebbie = nucleus(mockedApp, { const nebbie = embed(mockedApp, {
...config, ...config,
...instanceConfig, ...instanceConfig,
types: [ types: [

View File

@@ -1,4 +1,4 @@
import * as supernova from '@nebula.js/supernova'; import * as stardust from '@nebula.js/stardust';
import { requireFrom } from 'd3-require'; import { requireFrom } from 'd3-require';
@@ -8,7 +8,7 @@ const getModule = (name, url) => {
const resolve = url ? remoteResolve : localResolve; const resolve = url ? remoteResolve : localResolve;
const r = requireFrom(async (n) => resolve(n)); const r = requireFrom(async (n) => resolve(n));
const a = r.alias({ const a = r.alias({
'@nebula.js/supernova': supernova, '@nebula.js/stardust': stardust,
}); });
return a(url || name); return a(url || name);
}; };

View File

@@ -5,8 +5,7 @@
<title>Nebula mashup</title> <title>Nebula mashup</title>
<script src="https://unpkg.com/enigma.js"></script> <script src="https://unpkg.com/enigma.js"></script>
<script src="https://unpkg.com/@nebula.js/supernova"></script> <script src="https://unpkg.com/@nebula.js/stardust"></script>
<script src="https://unpkg.com/@nebula.js/nucleus"></script>
<style> <style>
body { body {

View File

@@ -1,20 +1,20 @@
/* eslint-disable */ /* eslint-disable */
const { useElement } = supernova; const { useElement } = stardust;
connect().then(app => { connect().then((app) => {
const sn = { const sn = {
component() { component() {
useElement().innerHTML = 'Hello'; useElement().innerHTML = 'Hello';
}, },
}; };
const nebbie = window.nucleus(app, { const nebbie = stardust.embed(app, {
load: (type, config) => Promise.resolve(sn), load: (type, config) => Promise.resolve(sn),
}); });
nebbie.selections().then(s => s.mount(document.querySelector('.toolbar'))); nebbie.selections().then((s) => s.mount(document.querySelector('.toolbar')));
document.querySelectorAll('.object').forEach(el => { document.querySelectorAll('.object').forEach((el) => {
const type = el.getAttribute('data-type'); const type = el.getAttribute('data-type');
nebbie.render({ nebbie.render({

View File

@@ -21,14 +21,14 @@
"start": "nebula serve --no-build" "start": "nebula serve --no-build"
}, },
"peerDependencies": { "peerDependencies": {
"@nebula.js/supernova": "^0.1.0-alpha.28" "@nebula.js/stardust": ">=0.6.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "7.4.4", "@babel/cli": "7.4.4",
"@babel/plugin-transform-react-jsx": "7.3.0", "@babel/plugin-transform-react-jsx": "7.3.0",
"@babel/preset-env": "7.4.5", "@babel/preset-env": "7.4.5",
"@babel/preset-react": "7.0.0", "@babel/preset-react": "7.0.0",
"@nebula.js/cli": "0.1.0-alpha.28", "@nebula.js/cli": "0.6.0",
"eslint": "5.12.1", "eslint": "5.12.1",
"eslint-config-airbnb": "17.1.0", "eslint-config-airbnb": "17.1.0",
"eslint-plugin-import": "2.15.0", "eslint-plugin-import": "2.15.0",

View File

@@ -16,10 +16,10 @@ module.exports = [
exports: 'default', exports: 'default',
sourcemap: true, sourcemap: true,
globals: { globals: {
'@nebula.js/supernova': 'supernova', '@nebula.js/stardust': 'stardust',
}, },
}, },
external: ['@nebula.js/supernova'], external: ['@nebula.js/stardust'],
plugins: [ plugins: [
nodeResolve({ nodeResolve({
extensions: ['.js', '.jsx'], extensions: ['.js', '.jsx'],

View File

@@ -1,4 +1,4 @@
import { useElement, useLayout, useEffect } from '@nebula.js/supernova'; import { useElement, useLayout, useEffect } from '@nebula.js/stardust';
import properties from './object-properties'; import properties from './object-properties';
import data from './data'; import data from './data';

View File

@@ -3,7 +3,7 @@
"description": "", "description": "",
"scripts": { "scripts": {
"build": "cross-env NODE_ENV=production FORCE_COLOR=1 lerna run build --stream", "build": "cross-env NODE_ENV=production FORCE_COLOR=1 lerna run build --stream",
"build:codesandbox": "cross-env NODE_ENV=production CODESANDBOX=1 FORCE_COLOR=1 lerna run build --stream --scope \"@nebula.js/{nucleus,supernova,theme,locale}\"", "build:codesandbox": "cross-env NODE_ENV=production CODESANDBOX=1 FORCE_COLOR=1 lerna run build --stream --scope \"@nebula.js/{stardust,theme,locale}\"",
"build:watch": "FORCE_COLOR=1 lerna run build:watch --stream --concurrency 99 --no-sort", "build:watch": "FORCE_COLOR=1 lerna run build:watch --stream --concurrency 99 --no-sort",
"format": "prettier --write '**/**/*'", "format": "prettier --write '**/**/*'",
"locale:verify": "node tools/verify-translations.js", "locale:verify": "node tools/verify-translations.js",

View File

@@ -30,7 +30,7 @@ if (pkg.main !== 'index.js') {
// in our webpack/rollup configs we include '.dev.js' as file extension when building // in our webpack/rollup configs we include '.dev.js' as file extension when building
// a dev distribution, the module target should therefore end with '.esm' and not with '.esm.js' // a dev distribution, the module target should therefore end with '.esm' and not with '.esm.js'
// so that the node resolve algorithm finds the correct module based on module format and dev mode // so that the node resolve algorithm finds the correct module based on module format and dev mode
// e.g. '@nebula.js/supernova' -> '@nebula.js/supernova/dist/supernova.esm.dev.js' // e.g. '@nebula.js/stardust' -> '@nebula.js/stardust/dist/stardust.esm.dev.js'
const moduleTargetName = getTargetFileName('esm').replace(/\.js$/, ''); const moduleTargetName = getTargetFileName('esm').replace(/\.js$/, '');
if (pkg.module && pkg.module !== moduleTargetName) { if (pkg.module && pkg.module !== moduleTargetName) {
throw Error(`module target must be ${moduleTargetName}`); throw Error(`module target must be ${moduleTargetName}`);
@@ -60,7 +60,7 @@ const browserList = [
const GLOBALS = { const GLOBALS = {
react: 'React', react: 'React',
'react-dom': 'ReactDOM', 'react-dom': 'ReactDOM',
'@nebula.js/supernova': 'supernova', '@nebula.js/stardust': 'stardust',
}; };
const propTypes = [ const propTypes = [
@@ -118,7 +118,7 @@ const config = (isEsm, dev = false) => {
output: { output: {
file: path.resolve(targetDir, getFileName(isEsm ? 'esm' : '', dev)), file: path.resolve(targetDir, getFileName(isEsm ? 'esm' : '', dev)),
format: isEsm ? 'esm' : 'umd', format: isEsm ? 'esm' : 'umd',
exports: ['supernova', 'test-utils'].indexOf(targetName) !== -1 ? 'named' : 'default', exports: ['test-utils', 'stardust'].indexOf(targetName) !== -1 ? 'named' : 'default',
name: umdName, name: umdName,
sourcemap: false, sourcemap: false,
banner, banner,
@@ -173,6 +173,7 @@ const config = (isEsm, dev = false) => {
'/**/apis/locale/**', '/**/apis/locale/**',
'/**/apis/nucleus/**', '/**/apis/nucleus/**',
'/**/apis/snapshooter/**', '/**/apis/snapshooter/**',
'/**/apis/stardust/**',
'/**/apis/supernova/**', '/**/apis/supernova/**',
'/**/apis/theme/**', '/**/apis/theme/**',
'/**/packages/ui/**', '/**/packages/ui/**',

View File

@@ -12,7 +12,7 @@ import {
useAction, useAction,
useConstraints, useConstraints,
useOptions, useOptions,
} from '@nebula.js/supernova'; } from '@nebula.js/stardust';
function sn({ flags }) { function sn({ flags }) {
return { return {
@@ -43,7 +43,7 @@ function sn({ flags }) {
if (count >= 1) { if (count >= 1) {
act(); act();
} else { } else {
setCount(prev => prev + 1); setCount((prev) => prev + 1);
} }
}; };
element.addEventListener('click', listener); element.addEventListener('click', listener);
@@ -55,7 +55,7 @@ function sn({ flags }) {
const [v] = usePromise( const [v] = usePromise(
() => () =>
new Promise(r => { new Promise((r) => {
setTimeout(() => { setTimeout(() => {
r('ready!'); r('ready!');
}, 100); }, 100);

View File

@@ -6,7 +6,7 @@ const pie = {
}, },
}; };
const bar = function(env) { const bar = function (env) {
env.translator.add({ env.translator.add({
id: 'hello', id: 'hello',
locale: { locale: {
@@ -23,7 +23,7 @@ const bar = function(env) {
}; };
// eslint-disable-next-line // eslint-disable-next-line
const configured = nucleus.createConfiguration({ const configured = stardust.embed.createConfiguration({
context: { context: {
theme: 'dark', theme: 'dark',
language: 'sv-SE', language: 'sv-SE',

View File

@@ -2,8 +2,7 @@
<html> <html>
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<script src="/apis/supernova/dist/supernova.js"></script> <script src="/apis/stardust/dist/stardust.js"></script>
<script src="/apis/nucleus/dist/nucleus.js"></script>
<script src="/apis/snapshooter/client.js"></script> <script src="/apis/snapshooter/client.js"></script>
<script src="configured.js"></script> <script src="configured.js"></script>
@@ -30,7 +29,7 @@
window.location.search window.location.search
.substring(1) .substring(1)
.split('&') .split('&')
.forEach(pair => { .forEach((pair) => {
const idx = pair.indexOf('='); const idx = pair.indexOf('=');
const name = pair.substr(0, idx); const name = pair.substr(0, idx);
const value = decodeURIComponent(pair.substring(idx + 1)); const value = decodeURIComponent(pair.substring(idx + 1));
@@ -40,7 +39,7 @@
return opts; return opts;
})(); })();
snapshooter({ snapshooter({
nucleus: configured, embed: configured,
element: document.querySelector('#object'), element: document.querySelector('#object'),
snapshot: params.snapshot, snapshot: params.snapshot,
}); });

View File

@@ -3,8 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>Mashup</title> <title>Mashup</title>
<script src="/apis/supernova/dist/supernova.js"></script> <script src="/apis/stardust/dist/stardust.js"></script>
<script src="/apis/nucleus/dist/nucleus.js"></script>
<script src="configured.js"></script> <script src="configured.js"></script>
<style> <style>

View File

@@ -3,14 +3,14 @@ const { declare } = require('@babel/helper-plugin-utils');
const vars = require('../apis/nucleus/src/locale/translations/all.json'); const vars = require('../apis/nucleus/src/locale/translations/all.json');
const ids = {}; const ids = {};
Object.keys(vars).forEach(key => { Object.keys(vars).forEach((key) => {
ids[vars[key].id] = key; ids[vars[key].id] = key;
}); });
const used = []; const used = [];
const warnings = {}; const warnings = {};
const warn = s => console.warn(`\x1b[43m\x1b[30m WARN \x1b[0m \x1b[1m\x1b[33m ${s}\x1b[0m`); const warn = (s) => console.warn(`\x1b[43m\x1b[30m WARN \x1b[0m \x1b[1m\x1b[33m ${s}\x1b[0m`);
const find = declare((/* api, options */) => { const find = declare((/* api, options */) => {
function useString(id) { function useString(id) {

View File

@@ -18,7 +18,7 @@ const languages = [
'ru-RU', 'ru-RU',
]; ];
Object.keys(vars).forEach(key => { Object.keys(vars).forEach((key) => {
const supportLanguagesForString = Object.keys(vars[key].locale); const supportLanguagesForString = Object.keys(vars[key].locale);
if (supportLanguagesForString.indexOf('en-US') === -1) { if (supportLanguagesForString.indexOf('en-US') === -1) {
// en-US must exist // en-US must exist