forked from apache/superset
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request apache#19 from apache-superset/kristw--new-core
Add new core modules from incubator-superset
- Loading branch information
Showing
18 changed files
with
720 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
## @superset-ui/core | ||
|
||
[![Version](https://img.shields.io/npm/v/@superset-ui/core.svg?style=flat)](https://img.shields.io/npm/v/@superset-ui/core.svg?style=flat) | ||
[![David (path)](https://img.shields.io/david/apache-superset/superset-ui.svg?path=packages%2Fsuperset-ui-core&style=flat-square)](https://david-dm.org/apache-superset/superset-ui?path=packages/superset-ui-core) | ||
|
||
Description | ||
|
||
#### Example usage | ||
|
||
```js | ||
import { xxx } from '@superset-ui/core'; | ||
``` | ||
|
||
#### API | ||
|
||
`fn(args)` | ||
|
||
- TBD | ||
|
||
### Development | ||
|
||
`@data-ui/build-config` is used to manage the build configuration for this package including babel | ||
builds, jest testing, eslint, and prettier. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "@superset-ui/core", | ||
"version": "0.2.0", | ||
"description": "Superset UI core", | ||
"sideEffects": false, | ||
"main": "lib/index.js", | ||
"module": "esm/index.js", | ||
"files": [ | ||
"esm", | ||
"lib" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/apache-superset/superset-ui.git" | ||
}, | ||
"keywords": [ | ||
"superset" | ||
], | ||
"author": "Superset", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/apache-superset/superset-ui/issues" | ||
}, | ||
"homepage": "https://github.com/apache-superset/superset-ui#readme", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"lodash": "^4.17.11" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export { default as Plugin } from './models/Plugin'; | ||
export { default as Preset } from './models/Preset'; | ||
export { default as Registry } from './models/Registry'; | ||
|
||
export { default as convertKeysToCamelCase } from './utils/convertKeysToCamelCase'; | ||
export { default as isDefined } from './utils/isDefined'; | ||
export { default as isRequired } from './utils/isRequired'; | ||
export { default as makeSingleton } from './utils/makeSingleton'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
export default class Plugin { | ||
constructor() { | ||
this.resetConfig(); | ||
} | ||
|
||
resetConfig() { | ||
// The child class can set default config | ||
// by overriding this function. | ||
this.config = {}; | ||
|
||
return this; | ||
} | ||
|
||
configure(config, replace = false) { | ||
if (replace) { | ||
this.config = config; | ||
} else { | ||
this.config = { ...this.config, ...config }; | ||
} | ||
|
||
return this; | ||
} | ||
|
||
register() { | ||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export default class Preset { | ||
constructor({ name = '', description = '', presets = [], plugins = [] } = {}) { | ||
this.name = name; | ||
this.description = description; | ||
this.presets = presets; | ||
this.plugins = plugins; | ||
} | ||
|
||
register() { | ||
this.presets.forEach(preset => { | ||
preset.register(); | ||
}); | ||
this.plugins.forEach(plugin => { | ||
plugin.register(); | ||
}); | ||
|
||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
export default class Registry { | ||
constructor(name = '') { | ||
this.name = name; | ||
this.items = {}; | ||
this.promises = {}; | ||
} | ||
|
||
clear() { | ||
this.items = {}; | ||
this.promises = {}; | ||
|
||
return this; | ||
} | ||
|
||
has(key) { | ||
const item = this.items[key]; | ||
|
||
return item !== null && item !== undefined; | ||
} | ||
|
||
registerValue(key, value) { | ||
const item = this.items[key]; | ||
if (!item || item.value !== value) { | ||
this.items[key] = { value }; | ||
delete this.promises[key]; | ||
} | ||
|
||
return this; | ||
} | ||
|
||
registerLoader(key, loader) { | ||
const item = this.items[key]; | ||
if (!item || item.loader !== loader) { | ||
this.items[key] = { loader }; | ||
delete this.promises[key]; | ||
} | ||
|
||
return this; | ||
} | ||
|
||
get(key) { | ||
const item = this.items[key]; | ||
if (item) { | ||
return item.loader ? item.loader() : item.value; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
getAsPromise(key) { | ||
const promise = this.promises[key]; | ||
if (promise) { | ||
return promise; | ||
} | ||
const item = this.get(key); | ||
if (item) { | ||
const newPromise = Promise.resolve(item); | ||
this.promises[key] = newPromise; | ||
|
||
return newPromise; | ||
} | ||
|
||
return Promise.reject(new Error(`Item with key "${key}" is not registered.`)); | ||
} | ||
|
||
getMap() { | ||
return this.keys().reduce((prev, key) => { | ||
const map = prev; | ||
map[key] = this.get(key); | ||
|
||
return map; | ||
}, {}); | ||
} | ||
|
||
getMapAsPromise() { | ||
const keys = this.keys(); | ||
|
||
return Promise.all(keys.map(key => this.getAsPromise(key))).then(values => | ||
values.reduce((prev, value, i) => { | ||
const map = prev; | ||
map[keys[i]] = value; | ||
|
||
return map; | ||
}, {}), | ||
); | ||
} | ||
|
||
keys() { | ||
return Object.keys(this.items); | ||
} | ||
|
||
values() { | ||
return this.keys().map(key => this.get(key)); | ||
} | ||
|
||
valuesAsPromise() { | ||
return Promise.all(this.keys().map(key => this.getAsPromise(key))); | ||
} | ||
|
||
entries() { | ||
return this.keys().map(key => ({ | ||
key, | ||
value: this.get(key), | ||
})); | ||
} | ||
|
||
entriesAsPromise() { | ||
const keys = this.keys(); | ||
|
||
return Promise.all(keys.map(key => this.getAsPromise(key))).then(values => | ||
values.map((value, i) => ({ | ||
key: keys[i], | ||
value, | ||
})), | ||
); | ||
} | ||
|
||
remove(key) { | ||
delete this.items[key]; | ||
delete this.promises[key]; | ||
|
||
return this; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
packages/superset-ui-core/src/utils/convertKeysToCamelCase.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import camelCase from 'lodash/fp/camelCase'; | ||
import isPlainObject from 'lodash/fp/isPlainObject'; | ||
import mapKeys from 'lodash/fp/mapKeys'; | ||
|
||
export default function convertKeysToCamelCase(object) { | ||
if (object === null || object === undefined) { | ||
return object; | ||
} | ||
if (isPlainObject(object)) { | ||
return mapKeys(k => camelCase(k), object); | ||
} | ||
throw new Error(`Cannot convert input that is not a plain object: ${object}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function isDefined(x) { | ||
return x !== null && x !== undefined; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function isRequired(field) { | ||
throw new Error(`${field} is required.`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export default function makeSingleton(BaseClass, ...args) { | ||
let singleton; | ||
|
||
return function getInstance() { | ||
if (!singleton) { | ||
singleton = new BaseClass(...args); | ||
} | ||
|
||
return singleton; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
describe('My Test', () => { | ||
it('tests something', () => { | ||
expect(1).toEqual(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import Plugin from '../../src/models/Plugin'; | ||
|
||
describe('Plugin', () => { | ||
it('exists', () => { | ||
expect(Plugin).toBeDefined(); | ||
}); | ||
|
||
describe('new Plugin()', () => { | ||
it('creates a new plugin', () => { | ||
const plugin = new Plugin(); | ||
expect(plugin).toBeInstanceOf(Plugin); | ||
}); | ||
}); | ||
|
||
describe('.configure(config, replace)', () => { | ||
it('extends the default config with given config when replace is not set or false', () => { | ||
const plugin = new Plugin(); | ||
plugin.configure({ key: 'abc', foo: 'bar' }); | ||
plugin.configure({ key: 'def' }); | ||
expect(plugin.config).toEqual({ key: 'def', foo: 'bar' }); | ||
}); | ||
it('replaces the default config with given config when replace is true', () => { | ||
const plugin = new Plugin(); | ||
plugin.configure({ key: 'abc', foo: 'bar' }); | ||
plugin.configure({ key: 'def' }, true); | ||
expect(plugin.config).toEqual({ key: 'def' }); | ||
}); | ||
it('returns the plugin itself', () => { | ||
const plugin = new Plugin(); | ||
expect(plugin.configure({ key: 'abc' })).toBe(plugin); | ||
}); | ||
}); | ||
|
||
describe('.resetConfig()', () => { | ||
it('resets config back to default', () => { | ||
const plugin = new Plugin(); | ||
plugin.configure({ key: 'abc', foo: 'bar' }); | ||
plugin.resetConfig(); | ||
expect(plugin.config).toEqual({}); | ||
}); | ||
it('returns the plugin itself', () => { | ||
const plugin = new Plugin(); | ||
expect(plugin.resetConfig()).toBe(plugin); | ||
}); | ||
}); | ||
|
||
describe('.register()', () => { | ||
it('returns the plugin itself', () => { | ||
const plugin = new Plugin(); | ||
expect(plugin.register()).toBe(plugin); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import Preset from '../../src/models/Preset'; | ||
import Plugin from '../../src/models/Plugin'; | ||
|
||
describe('Preset', () => { | ||
it('exists', () => { | ||
expect(Preset).toBeDefined(); | ||
}); | ||
|
||
describe('new Preset()', () => { | ||
it('creates new preset', () => { | ||
const preset = new Preset(); | ||
expect(preset).toBeInstanceOf(Preset); | ||
}); | ||
}); | ||
|
||
describe('.register()', () => { | ||
it('register all listed presets then plugins', () => { | ||
const values = []; | ||
class Plugin1 extends Plugin { | ||
register() { | ||
values.push(1); | ||
} | ||
} | ||
class Plugin2 extends Plugin { | ||
register() { | ||
values.push(2); | ||
} | ||
} | ||
class Plugin3 extends Plugin { | ||
register() { | ||
values.push(3); | ||
} | ||
} | ||
class Plugin4 extends Plugin { | ||
register() { | ||
const { key } = this.config; | ||
values.push(key); | ||
} | ||
} | ||
|
||
const preset1 = new Preset({ | ||
plugins: [new Plugin1()], | ||
}); | ||
const preset2 = new Preset({ | ||
plugins: [new Plugin2()], | ||
}); | ||
const preset3 = new Preset({ | ||
presets: [preset1, preset2], | ||
plugins: [new Plugin3(), new Plugin4().configure({ key: 'abc' })], | ||
}); | ||
preset3.register(); | ||
expect(values).toEqual([1, 2, 3, 'abc']); | ||
}); | ||
|
||
it('returns itself', () => { | ||
const preset = new Preset(); | ||
expect(preset.register()).toBe(preset); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.