frint-component-handlers
Advanced tools
Comparing version
@@ -77,6 +77,284 @@ this["FrintComponentHandlers"] = | ||
}); | ||
exports.default = {}; | ||
module.exports = exports["default"]; | ||
var _ObserveHandler = __webpack_require__(1); | ||
var _ObserveHandler2 = _interopRequireDefault(_ObserveHandler); | ||
var _RegionHandler = __webpack_require__(2); | ||
var _RegionHandler2 = _interopRequireDefault(_RegionHandler); | ||
var _RegionService = __webpack_require__(4); | ||
var _RegionService2 = _interopRequireDefault(_RegionService); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = { | ||
ObserveHandler: _ObserveHandler2.default, | ||
RegionHandler: _RegionHandler2.default, | ||
RegionService: _RegionService2.default | ||
}; | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 1 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = { | ||
getProps$: null, | ||
getInitialData: function getInitialData() { | ||
return { | ||
computedProps: {} | ||
}; | ||
}, | ||
beforeMount: function beforeMount() { | ||
var _this = this; | ||
if (typeof this.getProps$ !== 'function') { | ||
return; | ||
} | ||
this._subscription = this.getProps$(this.app).subscribe(function (props) { | ||
_this.setData('computedProps', props); | ||
}); | ||
}, | ||
beforeDestroy: function beforeDestroy() { | ||
if (this._subscription) { | ||
this._subscription.unsubscribe(); | ||
} | ||
} | ||
}; | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 2 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _lodash = __webpack_require__(3); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = { | ||
getInitialData: function getInitialData() { | ||
return { | ||
list: [], // array of apps ==> { name, instance } | ||
listForRendering: [] // array of {name, Component} objects | ||
}; | ||
}, | ||
sendProps: function sendProps(appInstance, props) { | ||
var regionService = appInstance.get(appInstance.options.providerNames.region); | ||
if (!regionService) { | ||
return; | ||
} | ||
regionService.emit(props); | ||
}, | ||
beforeMount: function beforeMount() { | ||
var _this = this; | ||
var rootApp = !this.app ? window.app // @TODO: can we avoid globals? | ||
: this.app.getRootApp(); | ||
if (!rootApp) { | ||
return; | ||
} | ||
this.rootApp = rootApp; | ||
var apps$ = rootApp.getApps$(this.getProp('name'), this.getProp('uniqueKey')); | ||
this._subscription = apps$.subscribe({ | ||
next: function next(list) { | ||
_this.setDataWithCallback('list', list, function () { | ||
_this.getData('list').forEach(function (item) { | ||
var appName = item.name, | ||
appWeight = item.weight, | ||
multi = item.multi; | ||
var isPresent = _this.getData('listForRendering').some(function (w) { | ||
return w.name === appName; | ||
}); | ||
// @TODO: take care of removal in streamed list too? | ||
if (isPresent) { | ||
return; | ||
} | ||
var regionArgs = _this.getProp('uniqueKey') ? [_this.getProp('name'), _this.getProp('uniqueKey')] : [_this.getProp('name')]; | ||
if (_this.getProp('uniqueKey') && !rootApp.hasAppInstance.apply(rootApp, [appName].concat(regionArgs))) { | ||
rootApp.instantiateApp.apply(rootApp, [appName].concat(regionArgs)); | ||
} | ||
var appInstance = rootApp.getAppInstance.apply(rootApp, [appName].concat(regionArgs)); | ||
if (appInstance) { | ||
_this.sendProps(appInstance, { | ||
name: _this.getProp('name'), | ||
uniqueKey: _this.getProp('uniqueKey'), | ||
data: _this.getProp('data') | ||
}); | ||
} | ||
_this.setData('listForRendering', _this.getData('listForRendering').concat({ | ||
name: appName, | ||
weight: appWeight, | ||
instance: appInstance, | ||
multi: multi, | ||
Component: _this.getMountableComponent(appInstance) | ||
}).sort(function (a, b) { | ||
return a.weight - b.weight; | ||
})); | ||
}); | ||
}); | ||
}, | ||
error: function error(err) { | ||
console.warn('Subscription error for <Region name="' + _this.name + '" />:', err); | ||
} | ||
}); | ||
}, | ||
shouldUpdate: function shouldUpdate(nextProps, nextData) { | ||
var shouldUpdate = !_lodash2.default.isEqual(this.getProps(), nextProps); | ||
if (!shouldUpdate) { | ||
var listForRendering = nextData.listForRendering; | ||
shouldUpdate = shouldUpdate || this.getData('listForRendering').length !== listForRendering.length; | ||
shouldUpdate = shouldUpdate || _lodash2.default.zipWith(this.getData('listForRendering'), listForRendering, function (a, b) { | ||
return a.name === b.name; | ||
}).some(function (value) { | ||
return !value; | ||
}); | ||
} | ||
return shouldUpdate; | ||
}, | ||
afterUpdate: function afterUpdate() { | ||
var _this2 = this; | ||
var newProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | ||
var _ref = newProps || {}, | ||
_ref$name = _ref.name, | ||
name = _ref$name === undefined ? this.getProp('name') : _ref$name, | ||
_ref$uniqueKey = _ref.uniqueKey, | ||
uniqueKey = _ref$uniqueKey === undefined ? this.getProp('uniqueKey') : _ref$uniqueKey, | ||
_ref$data = _ref.data, | ||
data = _ref$data === undefined ? this.getProp('data') : _ref$data; | ||
this.getData('listForRendering').filter(function (item) { | ||
return item.instance; | ||
}).forEach(function (item) { | ||
return _this2.sendProps(item.instance, { | ||
name: name, | ||
uniqueKey: uniqueKey, | ||
data: data | ||
}); | ||
}); | ||
}, | ||
beforeDestroy: function beforeDestroy() { | ||
var _this3 = this; | ||
if (this._subscription) { | ||
this._subscription.unsubscribe(); | ||
} | ||
if (this.rootApp) { | ||
this.getData('listForRendering').filter(function (item) { | ||
return item.multi; | ||
}).forEach(function (item) { | ||
_this3.rootApp.destroyApp(item.name, _this3.getProp('name'), _this3.getProp('uniqueKey')); | ||
}); | ||
} | ||
} | ||
}; /* global window */ | ||
/* eslint-disable no-console */ | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 3 */ | ||
/***/ (function(module, exports) { | ||
(function() { module.exports = this["_"]; }()); | ||
/***/ }), | ||
/* 4 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
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; }; }(); | ||
var _rxjs = __webpack_require__(5); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var RegionService = function () { | ||
function RegionService() { | ||
_classCallCheck(this, RegionService); | ||
this.props$ = new _rxjs.BehaviorSubject({}); | ||
} | ||
_createClass(RegionService, [{ | ||
key: 'emit', | ||
value: function emit() { | ||
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
this.props$.next(props); | ||
} | ||
// @TODO: support synchronous versions | ||
// getName() {} | ||
// getKey() {} | ||
}, { | ||
key: 'getProps$', | ||
value: function getProps$() { | ||
return this.props$; | ||
} | ||
}, { | ||
key: 'getData$', | ||
value: function getData$() { | ||
return this.props$.map(function (props) { | ||
return props.data; | ||
}); | ||
} | ||
}]); | ||
return RegionService; | ||
}(); | ||
exports.default = RegionService; | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 5 */ | ||
/***/ (function(module, exports) { | ||
(function() { module.exports = this["Rx"]; }()); | ||
/***/ }) | ||
/******/ ]); |
@@ -1,1 +0,1 @@ | ||
this.FrintComponentHandlers=function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var r={};return t.m=e,t.c=r,t.d=function(e,r,n){t.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(r,"a",r),r},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={},e.exports=t.default}]); | ||
this.FrintComponentHandlers=function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(e,"__esModule",{value:!0});var i=n(1),o=r(i),u=n(2),a=r(u),s=n(4),p=r(s);e.default={ObserveHandler:o.default,RegionHandler:a.default,RegionService:p.default},t.exports=e.default},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default={getProps$:null,getInitialData:function(){return{computedProps:{}}},beforeMount:function(){var t=this;"function"==typeof this.getProps$&&(this._subscription=this.getProps$(this.app).subscribe(function(e){t.setData("computedProps",e)}))},beforeDestroy:function(){this._subscription&&this._subscription.unsubscribe()}},t.exports=e.default},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=function(t){return t&&t.__esModule?t:{default:t}}(r);e.default={getInitialData:function(){return{list:[],listForRendering:[]}},sendProps:function(t,e){var n=t.get(t.options.providerNames.region);n&&n.emit(e)},beforeMount:function(){var t=this,e=this.app?this.app.getRootApp():window.app;if(e){this.rootApp=e;var n=e.getApps$(this.getProp("name"),this.getProp("uniqueKey"));this._subscription=n.subscribe({next:function(n){t.setDataWithCallback("list",n,function(){t.getData("list").forEach(function(n){var r=n.name,i=n.weight,o=n.multi;if(!t.getData("listForRendering").some(function(t){return t.name===r})){var u=t.getProp("uniqueKey")?[t.getProp("name"),t.getProp("uniqueKey")]:[t.getProp("name")];t.getProp("uniqueKey")&&!e.hasAppInstance.apply(e,[r].concat(u))&&e.instantiateApp.apply(e,[r].concat(u));var a=e.getAppInstance.apply(e,[r].concat(u));a&&t.sendProps(a,{name:t.getProp("name"),uniqueKey:t.getProp("uniqueKey"),data:t.getProp("data")}),t.setData("listForRendering",t.getData("listForRendering").concat({name:r,weight:i,instance:a,multi:o,Component:t.getMountableComponent(a)}).sort(function(t,e){return t.weight-e.weight}))}})})},error:function(e){console.warn('Subscription error for <Region name="'+t.name+'" />:',e)}})}},shouldUpdate:function(t,e){var n=!i.default.isEqual(this.getProps(),t);if(!n){var r=e.listForRendering;n=n||this.getData("listForRendering").length!==r.length,n=n||i.default.zipWith(this.getData("listForRendering"),r,function(t,e){return t.name===e.name}).some(function(t){return!t})}return n},afterUpdate:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=e||{},r=n.name,i=void 0===r?this.getProp("name"):r,o=n.uniqueKey,u=void 0===o?this.getProp("uniqueKey"):o,a=n.data,s=void 0===a?this.getProp("data"):a;this.getData("listForRendering").filter(function(t){return t.instance}).forEach(function(e){return t.sendProps(e.instance,{name:i,uniqueKey:u,data:s})})},beforeDestroy:function(){var t=this;this._subscription&&this._subscription.unsubscribe(),this.rootApp&&this.getData("listForRendering").filter(function(t){return t.multi}).forEach(function(e){t.rootApp.destroyApp(e.name,t.getProp("name"),t.getProp("uniqueKey"))})}},t.exports=e.default},function(t,e){!function(){t.exports=this._}()},function(t,e,n){"use strict";function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),o=n(5),u=function(){function t(){r(this,t),this.props$=new o.BehaviorSubject({})}return i(t,[{key:"emit",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.props$.next(t)}},{key:"getProps$",value:function(){return this.props$}},{key:"getData$",value:function(){return this.props$.map(function(t){return t.data})}}]),t}();e.default=u,t.exports=e.default},function(t,e){!function(){t.exports=this.Rx}()}]); |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -6,3 +6,22 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = {}; | ||
module.exports = exports["default"]; | ||
var _ObserveHandler = require('./ObserveHandler'); | ||
var _ObserveHandler2 = _interopRequireDefault(_ObserveHandler); | ||
var _RegionHandler = require('./RegionHandler'); | ||
var _RegionHandler2 = _interopRequireDefault(_RegionHandler); | ||
var _RegionService = require('./RegionService'); | ||
var _RegionService2 = _interopRequireDefault(_RegionService); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = { | ||
ObserveHandler: _ObserveHandler2.default, | ||
RegionHandler: _RegionHandler2.default, | ||
RegionService: _RegionService2.default | ||
}; | ||
module.exports = exports['default']; |
@@ -16,2 +16,6 @@ 'use strict'; | ||
if (typeof this.getProps$ !== 'function') { | ||
return; | ||
} | ||
this._subscription = this.getProps$(this.app).subscribe(function (props) { | ||
@@ -22,6 +26,7 @@ _this.setData('computedProps', props); | ||
beforeDestroy: function beforeDestroy() { | ||
console.log('ObserveHandler: beforeDestroy'); | ||
this._subscription.unsubsribe(); | ||
if (this._subscription) { | ||
this._subscription.unsubscribe(); | ||
} | ||
} | ||
}; | ||
module.exports = exports['default']; |
@@ -44,42 +44,43 @@ 'use strict'; | ||
next: function next(list) { | ||
_this.setData('list', list); | ||
_this.getData('list').forEach(function (item) { | ||
var appName = item.name, | ||
appWeight = item.weight, | ||
multi = item.multi; | ||
_this.setDataWithCallback('list', list, function () { | ||
_this.getData('list').forEach(function (item) { | ||
var appName = item.name, | ||
appWeight = item.weight, | ||
multi = item.multi; | ||
var existsInState = _this.getData('listForRendering').some(function (w) { | ||
return w.name === appName; | ||
}); | ||
var isPresent = _this.getData('listForRendering').some(function (w) { | ||
return w.name === appName; | ||
}); | ||
// @TODO: take care of removal in streamed list too? | ||
// @TODO: take care of removal in streamed list too? | ||
if (existsInState) { | ||
return; | ||
} | ||
if (isPresent) { | ||
return; | ||
} | ||
var regionArgs = _this.getProp('uniqueKey') ? [_this.getProp('name'), _this.getProp('uniqueKey')] : [_this.getProp('name')]; | ||
var regionArgs = _this.getProp('uniqueKey') ? [_this.getProp('name'), _this.getProp('uniqueKey')] : [_this.getProp('name')]; | ||
if (_this.getProp('uniqueKey') && !rootApp.hasAppInstance.apply(rootApp, [appName].concat(regionArgs))) { | ||
rootApp.instantiateApp.apply(rootApp, [appName].concat(regionArgs)); | ||
} | ||
if (_this.getProp('uniqueKey') && !rootApp.hasAppInstance.apply(rootApp, [appName].concat(regionArgs))) { | ||
rootApp.instantiateApp.apply(rootApp, [appName].concat(regionArgs)); | ||
} | ||
var appInstance = rootApp.getAppInstance.apply(rootApp, [appName].concat(regionArgs)); | ||
if (appInstance) { | ||
_this.sendProps(appInstance, { | ||
name: _this.getProp('name'), | ||
uniqueKey: _this.getProp('uniqueKey'), | ||
data: _this.getProp('data') | ||
}); | ||
} | ||
var appInstance = rootApp.getAppInstance.apply(rootApp, [appName].concat(regionArgs)); | ||
if (appInstance) { | ||
_this.sendProps(appInstance, { | ||
name: _this.getProp('name'), | ||
uniqueKey: _this.getProp('uniqueKey'), | ||
data: _this.getProp('data') | ||
}); | ||
} | ||
_this.setData('listForRendering', _this.getData('listForRendering').concat({ | ||
name: appName, | ||
weight: appWeight, | ||
instance: appInstance, | ||
multi: multi, | ||
Component: _this.getMountableComponent(appInstance) | ||
}).sort(function (a, b) { | ||
return a.weight - b.weight; | ||
})); | ||
_this.setData('listForRendering', _this.getData('listForRendering').concat({ | ||
name: appName, | ||
weight: appWeight, | ||
instance: appInstance, | ||
multi: multi, | ||
Component: _this.getMountableComponent(appInstance) | ||
}).sort(function (a, b) { | ||
return a.weight - b.weight; | ||
})); | ||
}); | ||
}); | ||
@@ -99,4 +100,4 @@ }, | ||
shouldUpdate = shouldUpdate || this.getData('listForRendering').length !== listForRendering.length; | ||
shouldUpdate = shouldUpdate || _lodash2.default.zipWith(this.getData('listForRendering'), listForRendering, function (prev, next) { | ||
return prev.name === next.name; | ||
shouldUpdate = shouldUpdate || _lodash2.default.zipWith(this.getData('listForRendering'), listForRendering, function (a, b) { | ||
return a.name === b.name; | ||
}).some(function (value) { | ||
@@ -114,16 +115,10 @@ return !value; | ||
var name = void 0; | ||
var uniqueKey = void 0; | ||
var data = void 0; | ||
var _ref = newProps || {}, | ||
_ref$name = _ref.name, | ||
name = _ref$name === undefined ? this.getProp('name') : _ref$name, | ||
_ref$uniqueKey = _ref.uniqueKey, | ||
uniqueKey = _ref$uniqueKey === undefined ? this.getProp('uniqueKey') : _ref$uniqueKey, | ||
_ref$data = _ref.data, | ||
data = _ref$data === undefined ? this.getProp('data') : _ref$data; | ||
if (newProps) { | ||
name = newProps.name; | ||
uniqueKey = newProps.uniqueKey; | ||
data = newProps.data; | ||
} else { | ||
name = this.getProp('name'); | ||
uniqueKey = this.getProp('uniqueKey'); | ||
data = this.getProp('data'); | ||
} | ||
this.getData('listForRendering').filter(function (item) { | ||
@@ -142,3 +137,5 @@ return item.instance; | ||
this._subscription.unsubsribe(); | ||
if (this._subscription) { | ||
this._subscription.unsubscribe(); | ||
} | ||
@@ -145,0 +142,0 @@ if (this.rootApp) { |
@@ -5,5 +5,5 @@ 'use strict'; | ||
var _Region = require('../services/Region'); | ||
var _RegionService = require('./RegionService'); | ||
var _Region2 = _interopRequireDefault(_Region); | ||
var _RegionService2 = _interopRequireDefault(_RegionService); | ||
@@ -14,9 +14,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/* global describe, it */ | ||
describe('frint-react › services › Region', function () { | ||
describe('frint-component-handlers › RegionService', function () { | ||
it('is a function', function () { | ||
(0, _chai.expect)(_Region2.default).to.be.a('function'); | ||
(0, _chai.expect)(_RegionService2.default).to.be.a('function'); | ||
}); | ||
it('emits props', function (done) { | ||
var region = new _Region2.default(); | ||
var region = new _RegionService2.default(); | ||
region.emit({ | ||
@@ -36,3 +36,3 @@ key: 'value' | ||
it('can get only data as an observable', function (done) { | ||
var region = new _Region2.default(); | ||
var region = new _RegionService2.default(); | ||
region.emit({ | ||
@@ -39,0 +39,0 @@ name: 'sidebar', |
{ | ||
"name": "frint-component-handlers", | ||
"version": "2.3.0-alpha.f9a1b324", | ||
"version": "2.4.0", | ||
"description": "Component handlers package for Frint", | ||
@@ -34,2 +34,6 @@ "main": "lib/index.js", | ||
}, | ||
"devDependencies": { | ||
"frint": "^2.4.0", | ||
"frint-component-utils": "^2.4.0" | ||
}, | ||
"bugs": { | ||
@@ -36,0 +40,0 @@ "url": "https://github.com/Travix-International/frint/issues" |
@@ -5,3 +5,3 @@ # frint-component-handlers | ||
> Component package of Frint | ||
> Component handlers package of Frint | ||
@@ -12,2 +12,6 @@ <!-- MarkdownTOC autolink=true bracket=round --> | ||
- [Installation](#installation) | ||
- [API](#api) | ||
- [RegionHandler](#regionhandler) | ||
- [ObserveHandler](#observehandler) | ||
- [RegionService](#regionservice) | ||
@@ -31,1 +35,53 @@ <!-- /MarkdownTOC --> | ||
``` | ||
# API | ||
## RegionHandler | ||
> RegionHandler | ||
Handler for creating `Region` component. | ||
## ObserveHandler | ||
> ObserveHandler | ||
Handler for creating `observe` higher-order component. | ||
## RegionService | ||
> RegionService | ||
If your App wishes to receive data coming from the Region component it's rendered in, RegionService is your way to access it. | ||
Methods exposed by the instance: | ||
### emit | ||
> emit(props) | ||
The props that need to be emitted (Region component uses it internally). | ||
#### Arguments | ||
1. `props` (`Object`) | ||
#### Returns | ||
`void`. | ||
### getProps$ | ||
> getProps$() | ||
#### Returns | ||
`Observable`: of emitted props from the Region component. | ||
### getData$ | ||
> getdata$() | ||
#### Returns | ||
`Observable`: of the `data` prop from the Region component. |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
34081
127.89%14
16.67%764
114.01%0
-100%85
193.1%2
Infinity%