@bem-react/di
Advanced tools
Comparing version 2.2.8 to 3.0.0
@@ -68,17 +68,19 @@ 'use strict'; | ||
}; | ||
var useComponentRegistry = function (id) { | ||
var useRegistry = function (id) { | ||
var registries = useRegistries(); | ||
return registries[id].snapshot(); | ||
}; | ||
var registryHocMark = 'RegistryHoc'; | ||
function withBase(hoc) { | ||
var fakeComponent = function () { | ||
throw new Error("Not found base component for enhance HOC: " + hoc.toString()); | ||
/** | ||
* @deprecated consider using 'useRegistry' instead | ||
*/ | ||
var useComponentRegistry = useRegistry; | ||
var registryOverloadMark = 'RegistryOverloadHMark'; | ||
function withOverload(overload) { | ||
return { | ||
$symbol: registryOverloadMark, | ||
overload: overload, | ||
}; | ||
fakeComponent.$symbol = registryHocMark; | ||
fakeComponent.hoc = hoc; | ||
return fakeComponent; | ||
} | ||
function isHoc(component) { | ||
return component.$symbol === registryHocMark; | ||
function isOverload(entity) { | ||
return entity.$symbol === registryOverloadMark; | ||
} | ||
@@ -88,3 +90,3 @@ var Registry = /** @class */ (function () { | ||
var id = _a.id, _b = _a.overridable, overridable = _b === void 0 ? true : _b; | ||
this.components = {}; | ||
this.entities = {}; | ||
this.id = id; | ||
@@ -94,29 +96,29 @@ this.overridable = overridable; | ||
/** | ||
* Set react component in registry by id. | ||
* Set registry entry by id. | ||
* | ||
* @param id component id | ||
* @param component valid react component | ||
* @param id entry id | ||
* @param entity valid registry entity | ||
*/ | ||
Registry.prototype.set = function (id, component) { | ||
this.components[id] = component; | ||
Registry.prototype.set = function (id, entity) { | ||
this.entities[id] = entity; | ||
return this; | ||
}; | ||
/** | ||
* Set hoc for extends component in registry by id | ||
* Set extender for registry entry by id. | ||
* | ||
* @param id component id | ||
* @param hoc hoc for extends component | ||
* @param id entry id | ||
* @param overload valid registry entity extender | ||
*/ | ||
Registry.prototype.extends = function (id, hoc) { | ||
this.components[id] = withBase(hoc); | ||
Registry.prototype.extends = function (id, overload) { | ||
this.entities[id] = withOverload(overload); | ||
return this; | ||
}; | ||
/** | ||
* Set react components in registry via object literal. | ||
* Set react entities in registry via object literal. | ||
* | ||
* @param componentsSet set of valid react components | ||
* @param entitiesSet set of valid registry entities | ||
*/ | ||
Registry.prototype.fill = function (componentsSet) { | ||
for (var key in componentsSet) { | ||
this.components[key] = componentsSet[key]; | ||
Registry.prototype.fill = function (entitiesSet) { | ||
for (var key in entitiesSet) { | ||
this.entities[key] = entitiesSet[key]; | ||
} | ||
@@ -126,22 +128,22 @@ return this; | ||
/** | ||
* Get react component from registry by id. | ||
* Get entry from registry by id. | ||
* | ||
* @param id component id | ||
* @param id entry id | ||
*/ | ||
Registry.prototype.get = function (id) { | ||
{ | ||
if (!this.components[id]) { | ||
throw new Error("Component with id '" + id + "' not found."); | ||
if (!this.entities[id]) { | ||
throw new Error("Entry with id '" + id + "' not found."); | ||
} | ||
} | ||
return this.components[id]; | ||
return this.entities[id]; | ||
}; | ||
/** | ||
* Returns list of components from registry. | ||
* Returns raw entities from registry. | ||
*/ | ||
Registry.prototype.snapshot = function () { | ||
return this.components; | ||
return this.entities; | ||
}; | ||
/** | ||
* Override components by external registry. | ||
* Override entities by external registry. | ||
* @internal | ||
@@ -153,10 +155,10 @@ * | ||
var clone = new Registry({ id: this.id, overridable: this.overridable }); | ||
clone.fill(this.components); | ||
clone.fill(this.entities); | ||
if (!otherRegistry) | ||
return clone; | ||
var otherRegistryComponents = otherRegistry.snapshot(); | ||
for (var componentName in otherRegistryComponents) { | ||
if (!otherRegistryComponents.hasOwnProperty(componentName)) | ||
var otherRegistryEntities = otherRegistry.snapshot(); | ||
for (var entityName in otherRegistryEntities) { | ||
if (!otherRegistryEntities.hasOwnProperty(entityName)) | ||
continue; | ||
clone.components[componentName] = this.mergeComponents(clone.components[componentName], otherRegistryComponents[componentName]); | ||
clone.entities[entityName] = this.mergeEntities(this.id, clone.entities[entityName], otherRegistryEntities[entityName]); | ||
} | ||
@@ -166,16 +168,18 @@ return clone; | ||
/** | ||
* Returns extended or replacing for base impleme | ||
* Returns extended or replaced entity | ||
* | ||
* @param id entity entry id | ||
* @param base base implementation | ||
* @param overrides overridden implementation | ||
*/ | ||
Registry.prototype.mergeComponents = function (base, overrides) { | ||
if (isHoc(overrides)) { | ||
if (!base) | ||
return overrides; | ||
if (isHoc(base)) { | ||
// If both components are hocs, then create compose-hoc | ||
return withBase(function (Base) { return overrides.hoc(base.hoc(Base)); }); | ||
Registry.prototype.mergeEntities = function (id, base, overrides) { | ||
if (isOverload(overrides)) { | ||
if (!base && true) { | ||
throw new Error("Overload has no base in Registry '" + id + "'."); | ||
} | ||
return overrides.hoc(base); | ||
if (isOverload(base)) { | ||
// If both entities are hocs, then create compose-hoc | ||
return withOverload(function (Base) { return overrides.overload(base.overload(Base)); }); | ||
} | ||
return overrides.overload(base); | ||
} | ||
@@ -193,2 +197,3 @@ return overrides; | ||
exports.useRegistries = useRegistries; | ||
exports.useRegistry = useRegistry; | ||
exports.withRegistry = withRegistry; |
@@ -1,1 +0,1 @@ | ||
'use strict';function t(t){var e=function(){throw new Error("Not found base component for enhance HOC: "+t.toString())};return e.$symbol=c,e.hoc=t,e}function e(t){return t.$symbol===c}Object.defineProperty(exports,'__esModule',{value:!0});var n=require('react'),r=function(){return(r=Object.assign||function(t){for(var e,n=1,r=arguments.length;n<r;n++)for(var o in e=arguments[n])({}).hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t}).apply(this,arguments)},o=n.createContext({}),i=o.Provider,s=o.Consumer,u=function(){return n.useContext(o)},c='RegistryHoc',p=function(){function n(t){var e=t.id,n=t.overridable,r=void 0===n||n;this.components={},this.id=e,this.overridable=r}return n.prototype.set=function(t,e){return this.components[t]=e,this},n.prototype.extends=function(e,n){return this.components[e]=t(n),this},n.prototype.fill=function(t){for(var e in t)this.components[e]=t[e];return this},n.prototype.get=function(t){return this.components[t]},n.prototype.snapshot=function(){return this.components},n.prototype.merge=function(t){var e=new n({id:this.id,overridable:this.overridable});if(e.fill(this.components),!t)return e;var r=t.snapshot();for(var o in r)r.hasOwnProperty(o)&&(e.components[o]=this.mergeComponents(e.components[o],r[o]));return e},n.prototype.mergeComponents=function(n,r){return e(r)&&n?e(n)?t(function(t){return r.hoc(n.hoc(t))}):r.hoc(n):r},n}();exports.ComponentRegistryConsumer=function(t){return n.createElement(s,null,function(e){return t.children(e[t.id].snapshot())})},exports.Registry=p,exports.RegistryConsumer=s,exports.registryContext=o,exports.useComponentRegistry=function(t){return u()[t].snapshot()},exports.useRegistries=u,exports.withRegistry=function(){var t=[].slice.call(arguments);return function(e){return function(o){var u=n.useRef(null);return n.createElement(s,null,function(s){if(null===u.current){for(var c=r({},s),p=0;p<t.length;p++){var a=t[p],f=c[a.id];c[a.id]=a.overridable?f?a.merge(f):a:a&&f?f.merge(a):a}u.current=c}return n.createElement(i,{value:u.current},n.createElement(e,o))})}}}; | ||
'use strict';function e(e){return{$symbol:c,overload:e}}function t(e){return e.$symbol===c}Object.defineProperty(exports,'__esModule',{value:!0});var r=require('react'),n=function(){return(n=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var i in t=arguments[r])({}).hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)},i=r.createContext({}),o=i.Provider,s=i.Consumer,u=function(){return r.useContext(i)},a=function(e){return u()[e].snapshot()},l=a,c='RegistryOverloadHMark',p=function(){function r(e){var t=e.id,r=e.overridable,n=void 0===r||r;this.entities={},this.id=t,this.overridable=n}return r.prototype.set=function(e,t){return this.entities[e]=t,this},r.prototype.extends=function(t,r){return this.entities[t]=e(r),this},r.prototype.fill=function(e){for(var t in e)this.entities[t]=e[t];return this},r.prototype.get=function(e){return this.entities[e]},r.prototype.snapshot=function(){return this.entities},r.prototype.merge=function(e){var t=new r({id:this.id,overridable:this.overridable});if(t.fill(this.entities),!e)return t;var n=e.snapshot();for(var i in n)n.hasOwnProperty(i)&&(t.entities[i]=this.mergeEntities(this.id,t.entities[i],n[i]));return t},r.prototype.mergeEntities=function(r,n,i){return t(i)?t(n)?e(function(e){return i.overload(n.overload(e))}):i.overload(n):i},r}();exports.ComponentRegistryConsumer=function(e){return r.createElement(s,null,function(t){return e.children(t[e.id].snapshot())})},exports.Registry=p,exports.RegistryConsumer=s,exports.registryContext=i,exports.useComponentRegistry=l,exports.useRegistries=u,exports.useRegistry=a,exports.withRegistry=function(){var e=[].slice.call(arguments);return function(t){return function(i){var u=r.useRef(null);return r.createElement(s,null,function(s){if(null===u.current){for(var a=n({},s),l=0;l<e.length;l++){var c=e[l],p=a[c.id];a[c.id]=c.overridable?p?c.merge(p):c:c&&p?p.merge(c):c}u.current=a}return r.createElement(o,{value:u.current},r.createElement(t,i))})}}}; |
@@ -6,2 +6,12 @@ # Change Log | ||
# [3.0.0](https://github.com/bem/bem-react/compare/@bem-react/di@2.2.8...@bem-react/di@3.0.0) (2021-06-22) | ||
### Features | ||
- **di:** make di able to keep anything ([e302953](https://github.com/bem/bem-react/commit/e30295305e133ba240e5dc691eb80ab04199c12e)) | ||
### BREAKING CHANGES | ||
- **di:** `HOC` and `IRegistryComponents` aren't exported from di, and generic-param for `Registry.set` has different meaning | ||
## [2.2.8](https://github.com/bem/bem-react/compare/@bem-react/di@2.2.7...@bem-react/di@2.2.8) (2021-06-21) | ||
@@ -8,0 +18,0 @@ |
55
di.d.ts
@@ -12,2 +12,6 @@ import React, { ReactNode, FC, ComponentType } from 'react'; | ||
export declare const useRegistries: () => Record<string, Registry>; | ||
export declare const useRegistry: <T extends {}>(id: string) => T; | ||
/** | ||
* @deprecated consider using 'useRegistry' instead | ||
*/ | ||
export declare const useComponentRegistry: <T extends {}>(id: string) => T; | ||
@@ -18,47 +22,47 @@ export interface IRegistryOptions { | ||
} | ||
declare const registryHocMark = "RegistryHoc"; | ||
export declare type HOC<T> = (WrappedComponent: ComponentType) => ComponentType<T>; | ||
declare type IRegistryEntity<T = any> = ComponentType<T> | IRegistryHOC<T>; | ||
export declare type IRegistryComponents = Record<string, IRegistryEntity>; | ||
interface IRegistryHOC<T> extends React.FC<T> { | ||
$symbol: typeof registryHocMark; | ||
hoc: HOC<T>; | ||
declare const registryOverloadMark = "RegistryOverloadHMark"; | ||
declare type SimpleOverload<T> = (Base: T) => T; | ||
interface IRegistryEntityOverload<T> { | ||
$symbol: typeof registryOverloadMark; | ||
overload: SimpleOverload<T>; | ||
} | ||
declare type IRegistryEntity<T = any> = T | IRegistryEntityOverload<T>; | ||
export declare type IRegistryEntities = Record<string, IRegistryEntity>; | ||
export declare class Registry { | ||
id: string; | ||
overridable: boolean; | ||
private components; | ||
private entities; | ||
constructor({ id, overridable }: IRegistryOptions); | ||
/** | ||
* Set react component in registry by id. | ||
* Set registry entry by id. | ||
* | ||
* @param id component id | ||
* @param component valid react component | ||
* @param id entry id | ||
* @param entity valid registry entity | ||
*/ | ||
set<T>(id: string, component: ComponentType<T>): this; | ||
set<T>(id: string, entity: T): this; | ||
/** | ||
* Set hoc for extends component in registry by id | ||
* Set extender for registry entry by id. | ||
* | ||
* @param id component id | ||
* @param hoc hoc for extends component | ||
* @param id entry id | ||
* @param overload valid registry entity extender | ||
*/ | ||
extends<T>(id: string, hoc: HOC<T>): this; | ||
extends<T>(id: string, overload: SimpleOverload<T>): this; | ||
/** | ||
* Set react components in registry via object literal. | ||
* Set react entities in registry via object literal. | ||
* | ||
* @param componentsSet set of valid react components | ||
* @param entitiesSet set of valid registry entities | ||
*/ | ||
fill(componentsSet: IRegistryComponents): this; | ||
fill(entitiesSet: IRegistryEntities): this; | ||
/** | ||
* Get react component from registry by id. | ||
* Get entry from registry by id. | ||
* | ||
* @param id component id | ||
* @param id entry id | ||
*/ | ||
get<T>(id: string): IRegistryEntity<T>; | ||
/** | ||
* Returns list of components from registry. | ||
* Returns raw entities from registry. | ||
*/ | ||
snapshot<RT>(): RT; | ||
/** | ||
* Override components by external registry. | ||
* Override entities by external registry. | ||
* @internal | ||
@@ -70,9 +74,10 @@ * | ||
/** | ||
* Returns extended or replacing for base impleme | ||
* Returns extended or replaced entity | ||
* | ||
* @param id entity entry id | ||
* @param base base implementation | ||
* @param overrides overridden implementation | ||
*/ | ||
private mergeComponents; | ||
private mergeEntities; | ||
} | ||
export {}; |
{ | ||
"name": "@bem-react/di", | ||
"version": "2.2.8", | ||
"version": "3.0.0", | ||
"description": "BEM React Dependency Injection", | ||
@@ -33,3 +33,3 @@ "homepage": "https://github.com/bem/bem-react/tree/master/packages/di", | ||
}, | ||
"gitHead": "655f2d80cb58a8ea09bdee2ace75813838879a38" | ||
"gitHead": "2ad5610fd32e66840afa1f04aa6222346f7f002b" | ||
} |
@@ -9,2 +9,3 @@ # @bem-react/di · [![npm (scoped)](https://img.shields.io/npm/v/@bem-react/di.svg)](https://www.npmjs.com/package/@bem-react/di) [![npm bundle size (minified + gzip)](https://img.shields.io/bundlephobia/minzip/@bem-react/di.svg)](https://bundlephobia.com/result?p=@bem-react/di) | ||
- implement an _experimental_ version of a component alongside the common one | ||
- store components and their auxiliaries (like settings and functions) in a single place | ||
@@ -164,3 +165,3 @@ ## Install | ||
with `useComponentRegistry` (_require react version 16.8.0+_) | ||
with `useRegistry` (_require react version 16.8.0+_) | ||
@@ -170,3 +171,3 @@ ```tsx | ||
import { cn } from '@bem-react/classname' | ||
import { useComponentRegistry } from '@bem-react/di' | ||
import { useRegistry } from '@bem-react/di' | ||
@@ -178,3 +179,3 @@ // No Header or Footer imports | ||
export const App = () => { | ||
const { Header, Footer } = useComponentRegistry(cnApp()) | ||
const { Header, Footer } = useRegistry(cnApp()) | ||
@@ -235,5 +236,5 @@ return ( | ||
// extends original Header | ||
expRegistry.extends('Header', BaseHeader => props => ( | ||
expRegistry.extends('Header', (BaseHeader) => (props) => ( | ||
<div> | ||
<BaseHeader height={200} color={red}/> | ||
<BaseHeader height={200} color={red} /> | ||
</div> | ||
@@ -247,1 +248,30 @@ )) | ||
_DI_ merges nested registries composing and ordinary components for you. So you always can get a reference to previous component's implementation. | ||
## Storing other | ||
_DI_ registry may keep not only components but also their settings and any other auxiliaries (like functions). | ||
```tsx | ||
import { useRegistry } from '@bem-react/di' | ||
const cnHeader = cn('Header') | ||
export const Header = (props) => { | ||
const { theme, showNotification, prepareProps } = useRegistry(cnApp()) | ||
// one function is used to fulfill props | ||
const { title, username } = prepareProps(props) | ||
useEffect(() => { | ||
// another function is used inside hook | ||
showNotification() | ||
}) | ||
return ( | ||
<header className={cnHeader({ theme })}> | ||
<h1>{title}</h1> | ||
<h2>Greetings ${username}</h2> | ||
</header> | ||
) | ||
} | ||
``` |
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
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
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
45644
280
272
1