Comparing version 0.14.0 to 1.0.0-alpha.96e58a3f
@@ -6,13 +6,4 @@ 'use strict'; | ||
}); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* eslint-disable no-console, no-underscore-dangle */ | ||
/* globals window */ | ||
exports.default = createApp; | ||
var _rxjs = require('rxjs'); | ||
var _lodash = require('lodash'); | ||
@@ -22,16 +13,10 @@ | ||
var _createStore2 = require('./createStore'); | ||
var _App = require('./App'); | ||
var _createStore3 = _interopRequireDefault(_createStore2); | ||
var _App2 = _interopRequireDefault(_App); | ||
var _Provider = require('./components/Provider'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _Provider2 = _interopRequireDefault(_Provider); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var _h = require('./h'); | ||
var _h2 = _interopRequireDefault(_h); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
@@ -41,336 +26,5 @@ | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var BaseApp = function () { | ||
function BaseApp() { | ||
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
_classCallCheck(this, BaseApp); | ||
this.options = _extends({ | ||
// primary info | ||
name: null, | ||
devSessionId: null, | ||
rootApp: null, | ||
version: 1, | ||
// the root component to render | ||
component: null, | ||
// list of Model instances | ||
models: {}, | ||
// store | ||
store: null, | ||
reducer: function reducer() { | ||
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
return state; | ||
}, | ||
initialState: {}, | ||
enableLogger: true, | ||
services: {}, | ||
factories: {}, | ||
// lifecycle callbacks | ||
beforeMount: function beforeMount() {}, | ||
afterMount: function afterMount() {}, | ||
beforeUnmount: function beforeUnmount() {} | ||
}, opts); | ||
// errors | ||
if (!this.options.name) { | ||
throw new Error('Must provide `name` in options'); | ||
} | ||
if (!this.options.component) { | ||
throw new Error('Must provide `component` in options'); | ||
} | ||
// widgets | ||
this.widgetsByRegion = {}; | ||
if (typeof window !== 'undefined' && typeof window.app !== 'undefined') { | ||
this.options.rootApp = window.app; | ||
} | ||
this.widgetsSubject$ = new _rxjs.Subject(); | ||
// store | ||
this._createStore(this.options.reducer, this.options.initialState); | ||
this.readableApps = []; | ||
} | ||
_createClass(BaseApp, [{ | ||
key: 'getRootApp', | ||
value: function getRootApp() { | ||
return this.options.rootApp; | ||
} | ||
}, { | ||
key: 'getModel', | ||
value: function getModel(modelName) {// eslint-disable-line | ||
// will be implemented below when extended | ||
} | ||
}, { | ||
key: 'getService', | ||
value: function getService(serviceName) {// eslint-disable-line | ||
// will be implemented below when extended | ||
} | ||
}, { | ||
key: 'getFactory', | ||
value: function getFactory(factoryName) { | ||
// TODO: optimize code to be more DRY | ||
var factories = this.getOption('factories'); | ||
var FactoryClass = factories[factoryName]; | ||
if (FactoryClass) { | ||
return new FactoryClass({ | ||
app: this | ||
}); | ||
} | ||
var rootApp = this.getRootApp(); | ||
if (!rootApp) { | ||
return null; | ||
} | ||
var rootFactories = rootApp.getOption('factories'); | ||
var RootFactoryClass = rootFactories[factoryName]; | ||
if (RootFactoryClass) { | ||
return new RootFactoryClass({ | ||
app: this | ||
}); | ||
} | ||
return null; | ||
} | ||
}, { | ||
key: 'createStore', | ||
value: function createStore(rootReducer) { | ||
var initialState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
console.warn('[DEPRECATED] `createStore` has been deprecated.'); | ||
return this._createStore(rootReducer, initialState); | ||
} | ||
}, { | ||
key: '_createStore', | ||
value: function _createStore(rootReducer) { | ||
var initialState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var Store = (0, _createStore3.default)({ | ||
reducer: rootReducer, | ||
initialState: initialState, | ||
enableLogger: this.options.enableLogger, | ||
thunkArgument: { app: this }, | ||
appendAction: { | ||
appName: this.options.name | ||
} | ||
}); | ||
this.options.store = new Store(); | ||
return this.options.store; | ||
} | ||
}, { | ||
key: 'getStore', | ||
value: function getStore() { | ||
var appName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
console.warn('[DEPRECATED] `getStore` has been deprecated, use `getState$` instead.'); | ||
return this._getStore(appName); | ||
} | ||
}, { | ||
key: '_getAppByName', | ||
value: function _getAppByName() { | ||
var appName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
if (!appName) { | ||
return this; | ||
} | ||
var rootApp = this.getRootApp(); | ||
var widgetsByRegion = rootApp ? rootApp.widgetsByRegion : this.widgetsByRegion; | ||
var appsByName = _lodash2.default.reduce(widgetsByRegion, function (result, value) { | ||
value.forEach(function (app) { | ||
var name = app.getOption('name'); | ||
result[name] = app; | ||
}); | ||
return result; | ||
}, {}); | ||
// @TODO: check for permissions | ||
if (typeof appsByName[appName] !== 'undefined') { | ||
return appsByName[appName]; | ||
} | ||
return null; | ||
} | ||
}, { | ||
key: '_getStore', | ||
value: function _getStore() { | ||
var appName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
var app = this._getAppByName(appName); | ||
if (!app) { | ||
return null; | ||
} | ||
return app.getOption('store'); | ||
} | ||
}, { | ||
key: 'getState$', | ||
value: function getState$() { | ||
var appName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
var app = this._getAppByName(appName); | ||
if (!app) { | ||
return null; | ||
} | ||
return app.options.store.getState$(); | ||
} | ||
}, { | ||
key: 'dispatch', | ||
value: function dispatch(action) { | ||
return this._getStore().dispatch(action); | ||
} | ||
}, { | ||
key: 'getOption', | ||
value: function getOption(key) { | ||
return this.options[key]; | ||
} | ||
}, { | ||
key: 'registerWidget', | ||
value: function registerWidget(widgetApp, regionName) { | ||
if (!Array.isArray(this.widgetsByRegion[regionName])) { | ||
this.widgetsByRegion[regionName] = []; | ||
} | ||
this.widgetsByRegion[regionName].push(widgetApp); | ||
return this.widgetsSubject$.next(this.widgetsByRegion); | ||
} | ||
}, { | ||
key: 'beforeMount', | ||
value: function beforeMount() { | ||
return this.options.beforeMount.bind(this)(); | ||
} | ||
/** | ||
* | ||
* @param {Object} [componentProps=null] | ||
* @return {Function<Object>} | ||
*/ | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var componentProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
var Component = this.getOption('component'); | ||
var self = this; | ||
return function () { | ||
return (0, _h2.default)( | ||
_Provider2.default, | ||
{ app: self }, | ||
(0, _h2.default)(Component, componentProps) | ||
); | ||
}; | ||
} | ||
}, { | ||
key: 'afterMount', | ||
value: function afterMount() { | ||
return this.options.afterMount.bind(this)(); | ||
} | ||
}, { | ||
key: 'beforeUnmount', | ||
value: function beforeUnmount() { | ||
var output = this.options.beforeUnmount.bind(this)(); | ||
this.options.store.destroy(); | ||
return output; | ||
} | ||
/** | ||
* Alternative to Core.registerWidget(), | ||
* by doing Widget.setRegion() | ||
*/ | ||
}, { | ||
key: 'setRegion', | ||
value: function setRegion(regionName) { | ||
return this.setRegions([regionName]); | ||
} | ||
}, { | ||
key: 'setRegions', | ||
value: function setRegions(regionNames) { | ||
var _this = this; | ||
var rootApp = this.getRootApp(); | ||
if (!rootApp) { | ||
throw new Error('No root app instance available, so cannot set region.'); | ||
} | ||
return regionNames.forEach(function (regionName) { | ||
return rootApp.registerWidget(_this, regionName); | ||
}); | ||
} | ||
}, { | ||
key: 'getWidgets', | ||
value: function getWidgets() { | ||
var regionName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
if (!regionName) { | ||
return this.widgetsByRegion; | ||
} | ||
var list = this.widgetsByRegion[regionName]; | ||
if (!list) { | ||
return []; | ||
} | ||
return list; | ||
} | ||
}, { | ||
key: 'observeWidgets', | ||
value: function observeWidgets() { | ||
console.warn('[DEPRECATED] `observeWidgets` is deprecated, use `observeWidgets$` instead.'); | ||
return this.observeWidgets$(); | ||
} | ||
}, { | ||
key: 'observeWidgets$', | ||
value: function observeWidgets$() { | ||
return this.widgetsSubject$.startWith(this.getWidgets()); | ||
} | ||
}, { | ||
key: 'readStateFrom', | ||
value: function readStateFrom() { | ||
var appNames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | ||
this.readableApps = appNames; | ||
} | ||
}]); | ||
return BaseApp; | ||
}(); | ||
function createApp() { | ||
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
var modelRegistry = {}; | ||
var serviceInstances = {}; | ||
var App = function (_BaseApp) { | ||
@@ -384,67 +38,17 @@ _inherits(App, _BaseApp); | ||
// models | ||
var _this2 = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, _lodash2.default.merge(options, opts))); | ||
_lodash2.default.each(_this2.options.models, function (ModelClass, modelName) { | ||
if (typeof ModelClass !== 'function') { | ||
throw new Error('Expected model class \'' + modelName + '\' to be a valid Model class'); | ||
} | ||
modelRegistry[modelName] = _lodash2.default.memoize(function () { | ||
var attrs = _this2.options.modelAttributes[modelName] || {}; | ||
return new ModelClass(attrs); | ||
}, function () { | ||
return modelName; | ||
}); | ||
}); | ||
// services | ||
_lodash2.default.each(_this2.options.services, function (ServiceClass, serviceName) { | ||
serviceInstances[serviceName] = new ServiceClass({ | ||
app: _this2 | ||
}); | ||
}); | ||
return _this2; | ||
return _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, _lodash2.default.merge(options, opts))); | ||
} | ||
_createClass(App, [{ | ||
key: 'getModel', | ||
value: function getModel(modelName) { | ||
if (modelName in modelRegistry) { | ||
return modelRegistry[modelName](); | ||
} | ||
var rootApp = this.getRootApp(); | ||
if (rootApp) { | ||
return rootApp.getModel(modelName); | ||
} | ||
return null; | ||
} | ||
}, { | ||
key: 'getService', | ||
value: function getService(serviceName) { | ||
if (serviceInstances[serviceName]) { | ||
return serviceInstances[serviceName]; | ||
} | ||
return App; | ||
}(_App2.default); | ||
var rootApp = this.getRootApp(); | ||
if (typeof options.name !== 'undefined') { | ||
Object.defineProperty(App, 'frintAppName', { | ||
value: options.name, | ||
configurable: true | ||
}); | ||
} | ||
if (!rootApp) { | ||
return null; | ||
} | ||
var serviceFromRoot = rootApp.getService(serviceName); | ||
if (serviceFromRoot) { | ||
return serviceFromRoot; | ||
} | ||
return null; | ||
} | ||
}]); | ||
return App; | ||
}(BaseApp); | ||
return App; | ||
} | ||
module.exports = exports['default']; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _combineReducers = require('./combineReducers'); | ||
var _App = require('./App'); | ||
var _combineReducers2 = _interopRequireDefault(_combineReducers); | ||
var _App2 = _interopRequireDefault(_App); | ||
@@ -16,68 +16,32 @@ var _createApp = require('./createApp'); | ||
var _createComponent = require('./createComponent'); | ||
var _createCore = require('./createCore'); | ||
var _createComponent2 = _interopRequireDefault(_createComponent); | ||
var _createCore2 = _interopRequireDefault(_createCore); | ||
var _createFactory = require('./createFactory'); | ||
var _createWidget = require('./createWidget'); | ||
var _createFactory2 = _interopRequireDefault(_createFactory); | ||
var _createWidget2 = _interopRequireDefault(_createWidget); | ||
var _createModel = require('./createModel'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _createModel2 = _interopRequireDefault(_createModel); | ||
var Frint = { | ||
App: _App2.default, | ||
createApp: _createApp2.default, | ||
createCore: _createCore2.default, | ||
createWidget: _createWidget2.default | ||
}; | ||
var _createService = require('./createService'); | ||
Frint.use = function use(Plugin) { | ||
if (typeof Plugin.install !== 'function') { | ||
throw new Error('Plugin does not have any `install` option.'); | ||
} | ||
var _createService2 = _interopRequireDefault(_createService); | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
} | ||
var _mapToProps = require('./components/mapToProps'); | ||
return Plugin.install.apply(Plugin, [Frint].concat(args)); | ||
}; | ||
var _mapToProps2 = _interopRequireDefault(_mapToProps); | ||
var _Model = require('./Model'); | ||
var _Model2 = _interopRequireDefault(_Model); | ||
var _PropTypes = require('./PropTypes'); | ||
var _PropTypes2 = _interopRequireDefault(_PropTypes); | ||
var _Region = require('./components/Region'); | ||
var _Region2 = _interopRequireDefault(_Region); | ||
var _render = require('./render'); | ||
var _render2 = _interopRequireDefault(_render); | ||
var _createStore = require('./createStore'); | ||
var _createStore2 = _interopRequireDefault(_createStore); | ||
var _isObservable = require('./utils/isObservable'); | ||
var _isObservable2 = _interopRequireDefault(_isObservable); | ||
var _h = require('./h'); | ||
var _h2 = _interopRequireDefault(_h); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = { | ||
combineReducers: _combineReducers2.default, | ||
createApp: _createApp2.default, | ||
createComponent: _createComponent2.default, | ||
createFactory: _createFactory2.default, | ||
createModel: _createModel2.default, | ||
createService: _createService2.default, | ||
createStore: _createStore2.default, | ||
mapToProps: _mapToProps2.default, | ||
Model: _Model2.default, | ||
PropTypes: _PropTypes2.default, | ||
Region: _Region2.default, | ||
render: _render2.default, | ||
isObservable: _isObservable2.default, | ||
h: _h2.default | ||
}; | ||
exports.default = Frint; | ||
module.exports = exports['default']; |
102
package.json
{ | ||
"name": "frint", | ||
"version": "0.14.0", | ||
"description": "Framework for building front-end apps", | ||
"main": "./lib/index.js", | ||
"version": "1.0.0-alpha.96e58a3f", | ||
"description": "Core plugin for Frint", | ||
"main": "lib/index.js", | ||
"homepage": "https://github.com/Travix-International/frint/tree/master/packages/frint-core", | ||
"scripts": { | ||
"build": "webpack", | ||
"transpile": "babel src --out-dir lib", | ||
"lint": "eslint --color '{src,test}/**/*.js'", | ||
"cover": "nyc --reporter=lcov --require babel-register mocha && npm run cover:report", | ||
"cover:report": "nyc report", | ||
"test": "npm run cover", | ||
"coverage:coveralls": "cat ./coverage/lcov.info | coveralls", | ||
"alex:docs": "alex", | ||
"alex:code": "alex 'src/**/*.js'", | ||
"alex": "npm run alex:docs && npm run alex:code", | ||
"dist:lib": "webpack --config ./dist/webpack.config.js", | ||
"dist:min": "uglifyjs dist/frint.js --output dist/frint.min.js", | ||
"lint": "../../node_modules/.bin/eslint --color '{src,test}/**/*.js'", | ||
"transpile": "../../node_modules/.bin/babel src --out-dir lib", | ||
"test": "../../node_modules/.bin/mocha --colors --compilers js:babel-register --recursive './src/**/*.spec.js'", | ||
"cover:run": "../../node_modules/.bin/nyc --reporter=lcov --require babel-register ../../node_modules/.bin/mocha --colors --compilers js:babel-register --recursive './src/**/*.spec.js'", | ||
"cover:report": "../../node_modules/.bin/nyc report", | ||
"cover": "npm run cover:run && npm run cover:report", | ||
"dist:lib": "echo \"Nothing to build\"", | ||
"dist:min": "echo \"Nothing to minify\"", | ||
"dist": "npm run dist:lib && npm run dist:min", | ||
"docs:prepare": "gitbook install", | ||
"docs:clean": "rimraf _book", | ||
"docs:build": "npm run docs:prepare && gitbook build -g Travix-International/frint", | ||
"docs:watch": "npm run docs:prepare && gitbook serve", | ||
"docs:publish": "npm run docs:clean && npm run docs:build && cp CNAME ./_book/CNAME && cd _book && git init && git commit --allow-empty -m 'update book' && git checkout -b gh-pages && touch .nojekyll && git add . && git commit -am 'update book' && git push git@github.com:Travix-International/frint gh-pages --force" | ||
"prepublish": "npm run transpile" | ||
}, | ||
@@ -31,67 +24,18 @@ "repository": { | ||
"author": { | ||
"name": "Travix International", | ||
"url": "http://travix.com" | ||
"name": "Travix International B.V.", | ||
"url": "https://travix.com" | ||
}, | ||
"contributors": [ | ||
{ | ||
"name": "Fahad Ibnay Heylaal", | ||
"url": "https://github.com/fahad19" | ||
}, | ||
{ | ||
"name": "Ricardo Machado", | ||
"url": "https://github.com/mAiNiNfEcTiOn" | ||
}, | ||
{ | ||
"name": "Mark Vincze", | ||
"url": "https://github.com/markvincze" | ||
}, | ||
{ | ||
"name": "Alex Miranda", | ||
"url": "https://github.com/alexmiranda" | ||
} | ||
"keywords": [ | ||
"frint", | ||
"frint-plugin" | ||
], | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/Travix-International/frint/issues" | ||
}, | ||
"homepage": "https://github.com/Travix-International/frint#readme", | ||
"dependencies": { | ||
"diyai": "^0.6.3", | ||
"lodash": "^4.13.1", | ||
"react": "^0.14.8", | ||
"react-dom": "^0.14.8", | ||
"rxjs": "^5.0.1" | ||
"rxjs": "^5.2.0" | ||
}, | ||
"devDependencies": { | ||
"alex": "^4.0.1", | ||
"babel-cli": "^6.10.1", | ||
"babel-core": "^6.13.2", | ||
"babel-eslint": "^7.1.0", | ||
"babel-loader": "^6.2.9", | ||
"babel-preset-travix": "^1.1.0", | ||
"babel-register": "^6.9.0", | ||
"chai": "^3.5.0", | ||
"coveralls": "^2.11.12", | ||
"eslint": "^3.3.1", | ||
"eslint-config-travix": "^2.2.0", | ||
"eslint-plugin-babel": "^4.0.0", | ||
"eslint-plugin-import": "^2.0.1", | ||
"eslint-plugin-react": "^6.6.0", | ||
"gitbook-cli": "^2.3.0", | ||
"http-server": "^0.9.0", | ||
"istanbul": "^1.1.0-alpha.1", | ||
"jsdom": "^9.4.1", | ||
"mocha": "^3.1.2", | ||
"nyc": "^8.4.0", | ||
"rimraf": "^2.5.2", | ||
"sinon": "^1.17.4", | ||
"sinon-chai": "^2.8.0", | ||
"uglify-js": "^2.7.5", | ||
"webpack": "^1.14.0" | ||
"bugs": { | ||
"url": "https://github.com/Travix-International/frint/issues" | ||
}, | ||
"greenkeeper": { | ||
"ignore": [ | ||
"react", | ||
"react-dom" | ||
] | ||
} | ||
"license": "MIT" | ||
} |
493
README.md
@@ -1,19 +0,494 @@ | ||
# frint | ||
# core | ||
[![npm](https://img.shields.io/npm/v/frint.svg)](https://www.npmjs.com/package/frint) [![Build Status](https://img.shields.io/travis/Travix-International/frint/master.svg)](http://travis-ci.org/Travix-International/frint) [![Coverage](https://img.shields.io/coveralls/Travix-International/frint.svg)](https://coveralls.io/github/Travix-International/frint) [![NSP Status](https://nodesecurity.io/orgs/travix-international-bv/projects/2c3431f8-ed10-4ef2-8edb-4873c656497c/badge)](https://nodesecurity.io/orgs/travix-international-bv/projects/2c3431f8-ed10-4ef2-8edb-4873c656497c) | ||
> The base of Frint | ||
> An opinionated library for building front-end applications. | ||
<!-- MarkdownTOC autolink=true bracket=round --> | ||
For documentation, visit [https://frint.js.org](https://frint.js.org). | ||
- [Guide](#guide) | ||
- [Terminologies](#terminologies) | ||
- [Usage](#usage) | ||
- [Creating and registering widgets](#creating-and-registering-widgets) | ||
- [Understanding Providers](#understanding-providers) | ||
- [Plugins](#plugins) | ||
- [API](#api) | ||
- [use](#use) | ||
- [App](#app) | ||
- [createCore](#createcore) | ||
- [createWidget](#createwidget) | ||
- [createClass](#createclass) | ||
- [app](#app-1) | ||
## Installation | ||
<!-- /MarkdownTOC --> | ||
With **npm**: | ||
--- | ||
# Guide | ||
## Terminologies | ||
* `App`: The base for Core and Widgets. | ||
* `Core`: The root app, that renders to DOM directly. | ||
* `Widget`: Apps that register themselves to Core. | ||
* `Provider`: Dependency for your apps (Core and Widgets). | ||
* `Plugin`: Modules that extend the core framework. | ||
## Usage | ||
Let's import the necessary functions from the library first: | ||
```js | ||
const Frint = require('frint'); | ||
const { createCore } = Frint; | ||
``` | ||
$ npm install --save frint | ||
Now we can create our App: | ||
```js | ||
const CoreApp = createCore({ name: 'MyAppName' }); | ||
``` | ||
## License | ||
Instantiate the Core app: | ||
MIT © [Travix International](http://travix.com) | ||
```js | ||
const app = new CoreApp(); // now you have the Core app's instance | ||
// usually we set the core app to `window.app`, | ||
// so Widgets coming in from separate bundles can register themselves | ||
window.app = app; | ||
``` | ||
## Creating and registering widgets | ||
```js | ||
const { createWidget } = Frint; | ||
const MyWidget = createWidget({ name: 'MyWidgetName' }); | ||
``` | ||
To register the Widget in your Core App: | ||
```js | ||
window.app.registerWidget(MyWidget); | ||
``` | ||
## Understanding Providers | ||
Providers are dependencies for your Frint application (not to be confused with `npm` packages). | ||
They can be set at Core app level, at Widget level, or even only at Core app level but cascade them to the Widgets. | ||
### Direct values | ||
For values that are already known: | ||
```js | ||
const CoreApp = createCore({ | ||
name: 'MyAppName', | ||
providers: [ | ||
{ | ||
name: 'foo', | ||
useValue: 'foo value here' | ||
} | ||
] | ||
}); | ||
const app = new CoreApp(); | ||
app.get('foo') === 'foo value here'; | ||
``` | ||
### Generated values from factories | ||
If you want to get the value from a function (will be called only once during App construction): | ||
```js | ||
const CoreApp = createCore({ | ||
name: 'MyAppName', | ||
providers: [ | ||
{ | ||
name: 'bar', | ||
useFactory: function () { | ||
return 'bar value'; | ||
} | ||
}, | ||
] | ||
}); | ||
const app = new CoreApp(); | ||
app.get('bar') === 'bar value'; | ||
``` | ||
### Classes | ||
You can also have classes defined as providers. They will be instantiated when the App is constructed, and then made available to you: | ||
```js | ||
class Baz { | ||
getValue() { | ||
return 'baz value'; | ||
} | ||
} | ||
const CoreApp = createCore({ | ||
name: 'MyAppName', | ||
providers: [ | ||
{ | ||
name: 'baz', | ||
useClass: Baz | ||
} | ||
] | ||
}); | ||
const app = new CoreApp(); | ||
app.get('baz').getValue() === 'baz value'; | ||
``` | ||
### Cascading | ||
If you wish to cascade a provider from Core App to your Widgets, you can: | ||
```js | ||
const CoreApp = createCore({ | ||
name: 'MyCoreApp', | ||
providers: [ | ||
{ | ||
name: 'window', | ||
useValue: window, // the global `window` object | ||
cascade: true, | ||
} | ||
] | ||
}); | ||
const MyWidget = createWidget({ | ||
name: 'MyWidget' | ||
}); | ||
const app = new CoreApp(); | ||
app.registerWidget(MyWidget); | ||
app.get('window') === window; | ||
app.getWidgetInstance('MyWidget').get('window') === window; | ||
``` | ||
### Reserved provider names | ||
* `app`: The current App in scope (Core or Widget) | ||
* `rootApp`: Always refers to the top-most App (which is Core) | ||
### Dependencies | ||
Providers can also list their dependencies (by their names). | ||
```js | ||
class Baz { | ||
constructor({ foo, bar, app }) { | ||
// I have access to both `foo` and `bar` here. | ||
// And I can access the scoped `app` instance too. | ||
} | ||
} | ||
const CoreApp = createCore({ | ||
name: 'MyCoreApp', | ||
providers: [ | ||
{ | ||
name: 'foo', | ||
useValue: 'foo value' | ||
}, | ||
{ | ||
name: 'bar', | ||
useFactory: function ({ foo }) { | ||
return `In bar, I have foo's value: ${foo}` | ||
}, | ||
deps: ['foo'] // value's of provider names listed here will be fed as arguments | ||
}, | ||
{ | ||
name: 'baz', | ||
useClass: Baz, | ||
deps: ['foo', 'bar', 'app'] | ||
} | ||
], | ||
}) | ||
``` | ||
### Scoped | ||
When cascading providers from Core to Widgets, it is likely you may want to scope those values by the Widget they are targeting. It is applicable in only `useFactory` and `useClass` usage, since they generate values. | ||
```js | ||
const CoreApp = createCore({ | ||
name: 'MyCoreApp', | ||
providers: [ | ||
{ | ||
name: 'theNameOfTheApp', | ||
useFactory: function ({ app }) { | ||
return app.getOption('name'); | ||
}, | ||
deps: ['app'], | ||
cascade: true, | ||
scoped: true, | ||
} | ||
] | ||
}); | ||
const MyWidget = createWidget({ | ||
name: 'MyWidget' | ||
}); | ||
const app = new CoreApp(); | ||
app.registerWidget(MyWidget); | ||
app.get('theNameOfTheApp') === 'MyCoreApp'; | ||
app.getWidgetInstance('MyWidget').get('theNameOfTheApp') === 'MyWidget'; | ||
``` | ||
## Plugins | ||
Plugins help extend the core of the framework. | ||
### Installation | ||
Plugins can be installed as follows: | ||
```js | ||
const Frint = require('frint'); | ||
const FooPlugin = require('frint-plugin-foo'); | ||
Frint.use(FooPlugin); | ||
``` | ||
### Development | ||
A plugin in its simplest form, is an object exposing a `install` function. The function accepts `Frint`, which can be extended further from there. | ||
```js | ||
// frint-plugin-foo/index.js | ||
module.exports = { | ||
install: function (Frint, options = {}) { | ||
// extend `Frint` here | ||
} | ||
}; | ||
``` | ||
--- | ||
# API | ||
## use | ||
> use(Plugin, options = {}) | ||
### Arguments | ||
1. `Plugin` (`Object` [required]) | ||
2. `options` (`Object` [optional]) | ||
### Returns | ||
`void` | ||
## App | ||
> App | ||
The base App class. | ||
Core and Widget extend this class. | ||
## createCore | ||
> createCore(options) | ||
### Arguments | ||
1. `options` (`Object`) | ||
* `options.name`: (`String` [required]): Name of your App | ||
* `options.initialize`: (`Function` [optional]): Called when App is constructed | ||
* `options.providers`: (`Array` [optional]): Array of provider objects | ||
### Returns | ||
`App`: The generated App class based on `options`. | ||
## createWidget | ||
> createWidget(options) | ||
Same as `createCore`, but intended for creating Widgets, that get registered to Core apps. | ||
## createClass | ||
> createClass(methods) | ||
Creates and returns a ES6 compatible class. | ||
Useful in non-ES6 compatible environments. | ||
### Arguments | ||
1. `options` (`Object`) | ||
* `initialize` (`Function`): To be used as a regular class constructor. | ||
### Returns | ||
`Function`: ES6 compatible class. | ||
## app | ||
> const app = new App(); | ||
The `App` instance (either Core or Widget): | ||
### app.getOption | ||
> app.getOption(key) | ||
#### Arguments | ||
1. `key` (`String`) | ||
#### Returns | ||
`Any`. | ||
#### Example | ||
`app.getOption('name')` would give you `MyAppName` string. | ||
### app.getRootApp | ||
> app.getRootApp() | ||
#### Returns | ||
Gives you the Core App instance. | ||
### app.getProviders | ||
> app.getProviders() | ||
Gives you an array of provider definitions as passed while creating the App class. | ||
#### Returns | ||
`Array`. | ||
### app.getProvider | ||
> app.getProvider(name) | ||
Gives you the provider's original definition. | ||
#### Arguments | ||
1. `name` (`String`): The name of the provider that you want | ||
#### Returns | ||
`Object`: The provider definition | ||
Not to be confused with the computed value of the provider. | ||
### app.get | ||
> app.get(name) | ||
Gives you the computed value of the provider. | ||
#### Arguments | ||
1. `name` (`String`): The name of the provider | ||
#### Returns | ||
`Any`: The computed value of the provider. | ||
### app.getWidgets$ | ||
> app.getWidgets$(regionName = null) | ||
#### Arguments | ||
1. `regionName` (`String` [optional]): Filter the list of widgets by region names if needed | ||
#### Returns | ||
`Observable`: That emits an array of most recent available Widgets. | ||
### app.registerWidget | ||
> app.registerWidget(Widget, options = {}) | ||
Register Widget class to Core app. | ||
#### Arguments | ||
1. `Widget` (`App`): The widget class created via `createWidget`. | ||
1. `options` (`Object` [optional]) | ||
* `name` (`String` [optional]): If the Widget's name needs to be overridden. | ||
* `multi` (`Boolean` [optional]): If the Widget is a multi-instance widget (defaults to `false`) | ||
#### Returns | ||
`void` | ||
### app.hasWidgetInstance | ||
> app.hasWidgetInstance(name, region = null, regionKey = null) | ||
Check if Widget instance is available or not. | ||
#### Arguments | ||
1. `name` (`String`): The name of the Widget that you are looking for | ||
1. `region` (`String` [optional]): If you want the Widget of a specific region | ||
1. `regionKey` (`String` [optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys. | ||
#### Returns | ||
`Boolean`. | ||
### app.getWidgetInstance | ||
> app.getWidgetInstance(name, region = null, regionKey = null) | ||
Gets the Widget instance if available. | ||
#### Arguments | ||
1. `name` (`String`): The name of the Widget that you are looking for | ||
1. `region` (`String` [optional]): If you want the Widget of a specific region | ||
1. `regionKey` (`String` [optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys. | ||
#### Returns | ||
`App|Boolean`: The widget instance, or false if not availble. | ||
### app.getWidgetOnceAvailable$ | ||
> app.getWidgetOnceAvailable$(name, region = null, regionKey = null) | ||
Returns an Observable, which emits with the Widget's instance once it is available. | ||
#### Arguments | ||
1. `name` (`String`): The name of the Widget that you are looking for | ||
1. `region` (`String` [optional]): If you want the Widget of a specific region | ||
1. `regionKey` (`String` [optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys. | ||
#### Returns | ||
`Observable`: Emits the Widget instance once found, only once. | ||
### app.instantiateWidget | ||
> app.instantiateWidget(name, region = null, regionKey = null) | ||
Instantiates the registered Widget class, (for the targetted region/regionKey if it is a multi-instance Widget). | ||
#### Arguments | ||
1. `name` (`String`): The name of the Widget that you are looking for | ||
1. `region` (`String` [optional]): If you want the Widget of a specific region | ||
1. `regionKey` (`String` [optional]): If it is a multi-instance Widget, then the lookup can be scoped by region's keys. | ||
### Returns | ||
`Array`: The updated collection of widgets. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
3
0
495
0
40114
12
717
2
1
+ Addeddiyai@^0.6.3
+ Addeddiyai@0.6.3(transitive)
- Removedreact@^0.14.8
- Removedreact-dom@^0.14.8
- Removedacorn@5.7.4(transitive)
- Removedamdefine@1.0.1(transitive)
- Removedasap@2.0.6(transitive)
- Removedast-types@0.9.6(transitive)
- Removedbalanced-match@1.0.2(transitive)
- Removedbase62@1.2.8(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedcommander@2.20.3(transitive)
- Removedcommoner@0.10.8(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedcore-js@1.2.7(transitive)
- Removeddefined@1.0.1(transitive)
- Removeddetective@4.7.1(transitive)
- Removedenvify@3.4.1(transitive)
- Removedesprima@3.1.3(transitive)
- Removedesprima-fb@15001.1.0-dev-harmony-fb(transitive)
- Removedfbjs@0.6.1(transitive)
- Removedglob@5.0.15(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedinflight@1.0.6(transitive)
- Removedinherits@2.0.4(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedjstransform@11.0.3(transitive)
- Removedloose-envify@1.4.0(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.5.6(transitive)
- Removedobject-assign@2.1.1(transitive)
- Removedonce@1.4.0(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedprivate@0.1.8(transitive)
- Removedpromise@7.3.1(transitive)
- Removedq@1.5.1(transitive)
- Removedreact@0.14.10(transitive)
- Removedreact-dom@0.14.10(transitive)
- Removedrecast@0.11.23(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsource-map@0.4.40.5.7(transitive)
- Removedthrough@2.3.8(transitive)
- Removedua-parser-js@0.7.39(transitive)
- Removedwhatwg-fetch@0.9.0(transitive)
- Removedwrappy@1.0.2(transitive)
Updatedrxjs@^5.2.0