Comparing version 2.2.2 to 2.3.0-beta.1
# Change Log | ||
All notable changes to this project will be documented in this file. | ||
## 2.3.0 (unreleased/beta) - 2021-02-07 | ||
- Adds `<BindProps logic={keyedLogic} props={{ id: 12 }}>`, which passes a specific build of | ||
`keyedLogic` via React Context down to nested components. This build will be used when calling | ||
a hook like `useValues(keyedLogic)` without props. [Read more here](https://kea.js.org/blog/kea-2.3). | ||
## 2.2.2 - 2020-10-27 | ||
@@ -5,0 +10,0 @@ - Create store automatically if calling `resetContext`, except for the default initial context. |
@@ -1385,3 +1385,4 @@ 'use strict'; | ||
run: { | ||
heap: [] | ||
heap: [], | ||
reactContexts: new WeakMap() | ||
}, | ||
@@ -1537,16 +1538,8 @@ reducers: { | ||
} | ||
function clearBuildCache(pathString) { | ||
function unmountLogic(logic) { | ||
var _getContext2 = getContext(), | ||
cache = _getContext2.build.cache; | ||
_getContext2$mount = _getContext2.mount, | ||
counter = _getContext2$mount.counter, | ||
mounted = _getContext2$mount.mounted; | ||
delete cache[pathString]; | ||
} | ||
function unmountLogic(logic) { | ||
var _getContext3 = getContext(), | ||
_getContext3$mount = _getContext3.mount, | ||
counter = _getContext3$mount.counter, | ||
mounted = _getContext3$mount.mounted; | ||
var pathStrings = Object.keys(logic.connections).filter(function (k) { | ||
@@ -1584,3 +1577,3 @@ return k !== logic.pathString; | ||
connectedLogic.events.afterUnmount && connectedLogic.events.afterUnmount(); | ||
clearBuildCache(pathString); | ||
delete getContext().build.cache[pathString]; | ||
} | ||
@@ -1802,3 +1795,7 @@ } | ||
if (input.key && typeof key === 'undefined') { | ||
throw new Error('[KEA] Must have key to build logic'); | ||
var _path = typeof input.path === 'function' ? input.path(key) : input.path; | ||
var _pathString = Array.isArray(_path) ? " " + _path.join('.') : ''; | ||
throw new Error("[KEA] Must have key to build logic" + _pathString + ", got props: " + JSON.stringify(props)); | ||
} | ||
@@ -2043,3 +2040,3 @@ | ||
function useValues(logic) { | ||
useMountedLogic(logic); | ||
var builtLogic = useMountedLogic(logic); | ||
return React.useMemo(function () { | ||
@@ -2052,3 +2049,3 @@ var response = {}; | ||
get: function get() { | ||
return reactRedux.useSelector(logic.selectors[key]); | ||
return reactRedux.useSelector(builtLogic.selectors[key]); | ||
} | ||
@@ -2058,3 +2055,3 @@ }); | ||
for (var _i = 0, _Object$keys = Object.keys(logic.selectors); _i < _Object$keys.length; _i++) { | ||
for (var _i = 0, _Object$keys = Object.keys(builtLogic.selectors); _i < _Object$keys.length; _i++) { | ||
_loop(); | ||
@@ -2064,11 +2061,11 @@ } | ||
return response; | ||
}, [logic.pathString]); | ||
}, [builtLogic.pathString]); | ||
} | ||
function useAllValues(logic) { | ||
useMountedLogic(logic); | ||
var builtLogic = useMountedLogic(logic); | ||
var response = {}; | ||
for (var _i2 = 0, _Object$keys2 = Object.keys(logic['selectors']); _i2 < _Object$keys2.length; _i2++) { | ||
for (var _i2 = 0, _Object$keys2 = Object.keys(builtLogic['selectors']); _i2 < _Object$keys2.length; _i2++) { | ||
var key = _Object$keys2[_i2]; | ||
response[key] = reactRedux.useSelector(logic['selectors'][key]); | ||
response[key] = reactRedux.useSelector(builtLogic['selectors'][key]); | ||
} | ||
@@ -2079,6 +2076,5 @@ | ||
function useActions(logic) { | ||
useMountedLogic(logic); | ||
return logic['actions']; | ||
var builtLogic = useMountedLogic(logic); | ||
return builtLogic['actions']; | ||
} | ||
function isWrapper(toBeDetermined) { | ||
@@ -2091,17 +2087,19 @@ if (toBeDetermined._isKea) { | ||
} | ||
var blankContext = React.createContext(undefined); | ||
function useMountedLogic(logic) { | ||
logic = isWrapper(logic) ? logic.build() : logic; | ||
var builtLogicContext = isWrapper(logic) ? getContext().run.reactContexts.get(logic) : null; | ||
var defaultBuiltLogic = React.useContext(builtLogicContext || blankContext); | ||
var builtLogic = isWrapper(logic) ? defaultBuiltLogic || logic.build() : logic; | ||
var unmount = React.useRef(undefined); | ||
if (!unmount.current) { | ||
unmount.current = logic.mount(); | ||
unmount.current = builtLogic.mount(); | ||
} | ||
var pathString = React.useRef(logic.pathString); | ||
var pathString = React.useRef(builtLogic.pathString); | ||
if (pathString.current !== logic.pathString) { | ||
if (pathString.current !== builtLogic.pathString) { | ||
unmount.current(); | ||
unmount.current = logic.mount(); | ||
pathString.current = logic.pathString; | ||
unmount.current = builtLogic.mount(); | ||
pathString.current = builtLogic.pathString; | ||
} | ||
@@ -2111,7 +2109,30 @@ | ||
return function () { | ||
return unmount.current && unmount.current(); | ||
unmount.current && unmount.current(); | ||
}; | ||
}, []); | ||
return builtLogic; | ||
} | ||
function getOrCreateContextForLogicWrapper(logic) { | ||
var context = getContext().run.reactContexts.get(logic); | ||
if (!context) { | ||
context = React.createContext(undefined); | ||
getContext().run.reactContexts.set(logic, context); | ||
} | ||
return context; | ||
} | ||
function BindProps(_ref) { | ||
var logic = _ref.logic, | ||
props = _ref.props, | ||
children = _ref.children; | ||
var LogicContext = getOrCreateContextForLogicWrapper(logic); | ||
var builtLogic = logic(props); | ||
useMountedLogic(builtLogic); | ||
return React.createElement(LogicContext.Provider, { | ||
value: builtLogic | ||
}, children); | ||
} | ||
var ATTACH_REDUCER$1 = ATTACH_REDUCER; | ||
@@ -2122,2 +2143,3 @@ var DETACH_REDUCER$1 = DETACH_REDUCER; | ||
exports.ATTACH_REDUCER = ATTACH_REDUCER$1; | ||
exports.BindProps = BindProps; | ||
exports.DETACH_REDUCER = DETACH_REDUCER$1; | ||
@@ -2124,0 +2146,0 @@ exports.activatePlugin = activatePlugin; |
import { AnyAction, Reducer, Middleware, compose, StoreEnhancer, Store, Action } from 'redux'; | ||
import { ComponentType, FunctionComponent } from 'react'; | ||
import { ComponentType, FunctionComponent, Context as Context$1, ReactNode } from 'react'; | ||
@@ -40,6 +40,7 @@ declare type AnyComponent = ComponentType | FunctionComponent; | ||
} | ||
interface BuiltLogicAdditions { | ||
interface BuiltLogicAdditions<LogicType extends Logic> { | ||
_isKeaBuild: boolean; | ||
mount(callback?: any): () => void; | ||
mount(callback?: (logic: LogicType) => any): () => void; | ||
extend: (extendedInput: LogicInput) => LogicWrapper; | ||
wrapper: LogicWrapper; | ||
} | ||
@@ -50,10 +51,10 @@ interface LogicWrapperAdditions<LogicType extends Logic> { | ||
inputs: LogicInput[]; | ||
<T extends LogicType['props'] | AnyComponent>(props: T): T extends LogicType['props'] ? LogicType & BuiltLogicAdditions : FunctionComponent; | ||
(): LogicType & BuiltLogicAdditions; | ||
<T extends LogicType['props'] | AnyComponent>(props: T): T extends LogicType['props'] ? LogicType & BuiltLogicAdditions<LogicType> : FunctionComponent; | ||
(): LogicType & BuiltLogicAdditions<LogicType>; | ||
wrap: (Component: AnyComponent) => KeaComponent; | ||
build: (props?: LogicType['props'], autoConnectInListener?: boolean) => LogicType & BuiltLogicAdditions; | ||
build: (props?: LogicType['props'], autoConnectInListener?: boolean) => LogicType & BuiltLogicAdditions<LogicType>; | ||
mount: (callback?: any) => () => void; | ||
extend: (extendedInput: LogicInput) => LogicWrapper; | ||
} | ||
declare type BuiltLogic = Logic & BuiltLogicAdditions; | ||
declare type BuiltLogic = Logic & BuiltLogicAdditions<Logic>; | ||
declare type LogicWrapper = Logic & LogicWrapperAdditions<Logic>; | ||
@@ -180,17 +181,17 @@ declare type ActionDefinitions<LogicType extends Logic> = Record<string, any | (() => any)> | LogicType['actionCreators']; | ||
beforeKea?: (input: LogicInput) => void; | ||
beforeBuild?: (logic: Logic & BuiltLogicAdditions, inputs: LogicInput[]) => void; | ||
beforeLogic?: (logic: Logic & BuiltLogicAdditions, input: LogicInput) => void; | ||
afterLogic?: (logic: Logic & BuiltLogicAdditions, input: LogicInput) => void; | ||
afterBuild?: (logic: Logic & BuiltLogicAdditions, inputs: LogicInput[]) => void; | ||
beforeMount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterMount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeAttach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterAttach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeUnmount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterUnmount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeDetach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterDetach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeBuild?: (logic: BuiltLogic, inputs: LogicInput[]) => void; | ||
beforeLogic?: (logic: BuiltLogic, input: LogicInput) => void; | ||
afterLogic?: (logic: BuiltLogic, input: LogicInput) => void; | ||
afterBuild?: (logic: BuiltLogic, inputs: LogicInput[]) => void; | ||
beforeMount?: (logic: BuiltLogic) => void; | ||
afterMount?: (logic: BuiltLogic) => void; | ||
beforeAttach?: (logic: BuiltLogic) => void; | ||
afterAttach?: (logic: BuiltLogic) => void; | ||
beforeUnmount?: (logic: BuiltLogic) => void; | ||
afterUnmount?: (logic: BuiltLogic) => void; | ||
beforeDetach?: (logic: BuiltLogic) => void; | ||
afterDetach?: (logic: BuiltLogic) => void; | ||
beforeWrapper?: (input: LogicInput, Klass: AnyComponent) => void; | ||
afterWrapper?: (input: LogicInput, Klass: AnyComponent, Kea: KeaComponent) => void; | ||
beforeRender?: (logic: Logic & BuiltLogicAdditions, props: Props) => void; | ||
beforeRender?: (logic: BuiltLogic, props: Props) => void; | ||
beforeCloseContext?: (context: Context) => void; | ||
@@ -239,2 +240,3 @@ } | ||
}[]; | ||
reactContexts: WeakMap<LogicWrapper, Context$1<BuiltLogic | undefined>>; | ||
}; | ||
@@ -260,4 +262,11 @@ reducers: { | ||
declare function useActions<L extends BuiltLogic | LogicWrapper>(logic: L): L['actions']; | ||
declare function useMountedLogic(logic: BuiltLogic | LogicWrapper): void; | ||
declare function useMountedLogic(logic: BuiltLogic | LogicWrapper): BuiltLogic; | ||
declare type BindPropsProps = { | ||
logic: LogicWrapper; | ||
props: LogicWrapper['props']; | ||
children: ReactNode; | ||
}; | ||
declare function BindProps({ logic, props, children }: BindPropsProps): JSX.Element; | ||
declare function getContext(): Context; | ||
@@ -294,2 +303,2 @@ declare function openContext(options?: ContextOptions, initial?: boolean): Context; | ||
export { ATTACH_REDUCER, AnyComponent, BreakPointFunction, BuiltLogic, BuiltLogicAdditions, Context, ContextOptions, CreateStoreOptions, DETACH_REDUCER, InternalContextOptions, KeaComponent, KeaPlugin, ListenerFunction, ListenerFunctionWrapper, Logic, LogicEventType, LogicInput, LogicWrapper, LogicWrapperAdditions, MakeLogicType, PartialRecord, PathCreator, PathType, PluginEventArrays, PluginEvents, Props, ReducerFunction, RequiredPathCreator, Selector, activatePlugin, addConnection, closeContext, connect, createAction, getContext, getPluginContext, getStore, isBreakpoint, kea, keaReducer, openContext, resetContext, setPluginContext, useActions, useAllValues, useKea, useMountedLogic, useValues }; | ||
export { ATTACH_REDUCER, AnyComponent, BindProps, BreakPointFunction, BuiltLogic, BuiltLogicAdditions, Context, ContextOptions, CreateStoreOptions, DETACH_REDUCER, InternalContextOptions, KeaComponent, KeaPlugin, ListenerFunction, ListenerFunctionWrapper, Logic, LogicEventType, LogicInput, LogicWrapper, LogicWrapperAdditions, MakeLogicType, PartialRecord, PathCreator, PathType, PluginEventArrays, PluginEvents, Props, ReducerFunction, RequiredPathCreator, Selector, activatePlugin, addConnection, closeContext, connect, createAction, getContext, getPluginContext, getStore, isBreakpoint, kea, keaReducer, openContext, resetContext, setPluginContext, useActions, useAllValues, useKea, useMountedLogic, useValues }; |
import { createSelector } from 'reselect'; | ||
import { applyMiddleware, compose, createStore } from 'redux'; | ||
import { useRef, useEffect, createElement, useMemo } from 'react'; | ||
import { useRef, useEffect, createElement, useMemo, createContext, useContext } from 'react'; | ||
import { connect as connect$1, useSelector } from 'react-redux'; | ||
@@ -1381,3 +1381,4 @@ | ||
run: { | ||
heap: [] | ||
heap: [], | ||
reactContexts: new WeakMap() | ||
}, | ||
@@ -1533,16 +1534,8 @@ reducers: { | ||
} | ||
function clearBuildCache(pathString) { | ||
function unmountLogic(logic) { | ||
var _getContext2 = getContext(), | ||
cache = _getContext2.build.cache; | ||
_getContext2$mount = _getContext2.mount, | ||
counter = _getContext2$mount.counter, | ||
mounted = _getContext2$mount.mounted; | ||
delete cache[pathString]; | ||
} | ||
function unmountLogic(logic) { | ||
var _getContext3 = getContext(), | ||
_getContext3$mount = _getContext3.mount, | ||
counter = _getContext3$mount.counter, | ||
mounted = _getContext3$mount.mounted; | ||
var pathStrings = Object.keys(logic.connections).filter(function (k) { | ||
@@ -1580,3 +1573,3 @@ return k !== logic.pathString; | ||
connectedLogic.events.afterUnmount && connectedLogic.events.afterUnmount(); | ||
clearBuildCache(pathString); | ||
delete getContext().build.cache[pathString]; | ||
} | ||
@@ -1798,3 +1791,7 @@ } | ||
if (input.key && typeof key === 'undefined') { | ||
throw new Error('[KEA] Must have key to build logic'); | ||
var _path = typeof input.path === 'function' ? input.path(key) : input.path; | ||
var _pathString = Array.isArray(_path) ? " " + _path.join('.') : ''; | ||
throw new Error("[KEA] Must have key to build logic" + _pathString + ", got props: " + JSON.stringify(props)); | ||
} | ||
@@ -2039,3 +2036,3 @@ | ||
function useValues(logic) { | ||
useMountedLogic(logic); | ||
var builtLogic = useMountedLogic(logic); | ||
return useMemo(function () { | ||
@@ -2048,3 +2045,3 @@ var response = {}; | ||
get: function get() { | ||
return useSelector(logic.selectors[key]); | ||
return useSelector(builtLogic.selectors[key]); | ||
} | ||
@@ -2054,3 +2051,3 @@ }); | ||
for (var _i = 0, _Object$keys = Object.keys(logic.selectors); _i < _Object$keys.length; _i++) { | ||
for (var _i = 0, _Object$keys = Object.keys(builtLogic.selectors); _i < _Object$keys.length; _i++) { | ||
_loop(); | ||
@@ -2060,11 +2057,11 @@ } | ||
return response; | ||
}, [logic.pathString]); | ||
}, [builtLogic.pathString]); | ||
} | ||
function useAllValues(logic) { | ||
useMountedLogic(logic); | ||
var builtLogic = useMountedLogic(logic); | ||
var response = {}; | ||
for (var _i2 = 0, _Object$keys2 = Object.keys(logic['selectors']); _i2 < _Object$keys2.length; _i2++) { | ||
for (var _i2 = 0, _Object$keys2 = Object.keys(builtLogic['selectors']); _i2 < _Object$keys2.length; _i2++) { | ||
var key = _Object$keys2[_i2]; | ||
response[key] = useSelector(logic['selectors'][key]); | ||
response[key] = useSelector(builtLogic['selectors'][key]); | ||
} | ||
@@ -2075,6 +2072,5 @@ | ||
function useActions(logic) { | ||
useMountedLogic(logic); | ||
return logic['actions']; | ||
var builtLogic = useMountedLogic(logic); | ||
return builtLogic['actions']; | ||
} | ||
function isWrapper(toBeDetermined) { | ||
@@ -2087,17 +2083,19 @@ if (toBeDetermined._isKea) { | ||
} | ||
var blankContext = createContext(undefined); | ||
function useMountedLogic(logic) { | ||
logic = isWrapper(logic) ? logic.build() : logic; | ||
var builtLogicContext = isWrapper(logic) ? getContext().run.reactContexts.get(logic) : null; | ||
var defaultBuiltLogic = useContext(builtLogicContext || blankContext); | ||
var builtLogic = isWrapper(logic) ? defaultBuiltLogic || logic.build() : logic; | ||
var unmount = useRef(undefined); | ||
if (!unmount.current) { | ||
unmount.current = logic.mount(); | ||
unmount.current = builtLogic.mount(); | ||
} | ||
var pathString = useRef(logic.pathString); | ||
var pathString = useRef(builtLogic.pathString); | ||
if (pathString.current !== logic.pathString) { | ||
if (pathString.current !== builtLogic.pathString) { | ||
unmount.current(); | ||
unmount.current = logic.mount(); | ||
pathString.current = logic.pathString; | ||
unmount.current = builtLogic.mount(); | ||
pathString.current = builtLogic.pathString; | ||
} | ||
@@ -2107,7 +2105,30 @@ | ||
return function () { | ||
return unmount.current && unmount.current(); | ||
unmount.current && unmount.current(); | ||
}; | ||
}, []); | ||
return builtLogic; | ||
} | ||
function getOrCreateContextForLogicWrapper(logic) { | ||
var context = getContext().run.reactContexts.get(logic); | ||
if (!context) { | ||
context = createContext(undefined); | ||
getContext().run.reactContexts.set(logic, context); | ||
} | ||
return context; | ||
} | ||
function BindProps(_ref) { | ||
var logic = _ref.logic, | ||
props = _ref.props, | ||
children = _ref.children; | ||
var LogicContext = getOrCreateContextForLogicWrapper(logic); | ||
var builtLogic = logic(props); | ||
useMountedLogic(builtLogic); | ||
return createElement(LogicContext.Provider, { | ||
value: builtLogic | ||
}, children); | ||
} | ||
var ATTACH_REDUCER$1 = ATTACH_REDUCER; | ||
@@ -2117,2 +2138,2 @@ var DETACH_REDUCER$1 = DETACH_REDUCER; | ||
export { ATTACH_REDUCER$1 as ATTACH_REDUCER, DETACH_REDUCER$1 as DETACH_REDUCER, activatePlugin, addConnection, closeContext, connect, createAction, getContext, getPluginContext, getStore, isBreakpoint, kea, keaReducer, openContext, resetContext, setPluginContext, useActions, useAllValues, useKea, useMountedLogic, useValues }; | ||
export { ATTACH_REDUCER$1 as ATTACH_REDUCER, BindProps, DETACH_REDUCER$1 as DETACH_REDUCER, activatePlugin, addConnection, closeContext, connect, createAction, getContext, getPluginContext, getStore, isBreakpoint, kea, keaReducer, openContext, resetContext, setPluginContext, useActions, useAllValues, useKea, useMountedLogic, useValues }; |
@@ -0,0 +0,0 @@ import { complexLogicType } from './complexLogicType'; |
@@ -0,0 +0,0 @@ import { Logic } from '../src/types'; |
@@ -0,0 +0,0 @@ import { githubLogicType } from './githubLogicType'; |
@@ -0,0 +0,0 @@ import { Logic } from '../src/types'; |
@@ -0,0 +0,0 @@ import { logicType } from './logicType'; |
@@ -0,0 +0,0 @@ import { Logic } from '../src/types'; |
export {}; |
@@ -0,0 +0,0 @@ import { Context, ContextOptions } from '../types'; |
import { KeaPlugin } from '../types'; | ||
export declare const corePlugin: KeaPlugin; |
@@ -0,0 +0,0 @@ interface KeaReduxAction { |
import { Logic } from '../../types'; | ||
export declare function addConnection(logic: Logic, otherLogic: Logic): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createActionCreators(logic: Logic, input: LogicInput): void; | ||
export declare function createActionType(key: string, pathString: string): string; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createActions(logic: Logic, input: LogicInput): void; |
@@ -0,0 +0,0 @@ import { BuiltLogic, Logic, LogicInput, LogicWrapper, Selector } from '../../types'; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createConstants(logic: Logic, input: LogicInput): void; | ||
export default function convertConstants(constants: string[]): Record<string, string>; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createDefaults(logic: Logic, input: LogicInput): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createEvents(logic: Logic, input: LogicInput): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createReducerSelectors(logic: Logic, input: LogicInput): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createReducer(logic: Logic, input: LogicInput): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createReducers(logic: Logic, input: LogicInput): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createSelectors(logic: Logic, input: LogicInput): void; |
import { Logic, LogicInput } from '../../types'; | ||
export declare function createValues(logic: Logic, input: LogicInput): void; |
export * from './types'; | ||
export { kea, connect } from './kea'; | ||
export { useValues, useAllValues, useActions, useMountedLogic, useKea } from './react/hooks'; | ||
export { BindProps } from './react/bind-props'; | ||
export { resetContext, openContext, closeContext, getContext, getPluginContext, setPluginContext } from './context'; | ||
@@ -5,0 +6,0 @@ export { getStore } from './store/store'; |
import { LogicWrapper, Props, LogicInput, BuiltLogic } from '../types'; | ||
export declare function getBuiltLogic(inputs: LogicInput[], props: Props, wrapper: LogicWrapper, autoConnectInListener?: boolean): BuiltLogic; |
export { kea, connect } from './kea'; |
@@ -0,0 +0,0 @@ import { Logic, LogicInput, LogicWrapper, LogicWrapperAdditions } from '../types'; |
@@ -1,3 +0,3 @@ | ||
import { Logic } from '../types'; | ||
import { BuiltLogic, Logic } from '../types'; | ||
export declare function mountLogic(logic: Logic, count?: number): void; | ||
export declare function unmountLogic(logic: Logic): void; | ||
export declare function unmountLogic(logic: BuiltLogic): void; |
import { LogicInput, PathType, Props } from '../types'; | ||
export declare function getPathForInput(input: LogicInput, props: Props): PathType; | ||
export declare function getPathStringForInput(input: LogicInput, props: Props): string; |
@@ -0,0 +0,0 @@ import { KeaPlugin } from '../types'; |
@@ -0,0 +0,0 @@ import { KeaPlugin, PluginEvents } from '../types'; |
@@ -6,2 +6,3 @@ import { LogicInput, LogicWrapper, BuiltLogic } from '../types'; | ||
export declare function useActions<L extends BuiltLogic | LogicWrapper>(logic: L): L['actions']; | ||
export declare function useMountedLogic(logic: BuiltLogic | LogicWrapper): void; | ||
export declare function isWrapper(toBeDetermined: BuiltLogic | LogicWrapper): toBeDetermined is LogicWrapper; | ||
export declare function useMountedLogic(logic: BuiltLogic | LogicWrapper): BuiltLogic; |
import { AnyComponent, KeaComponent, LogicWrapper } from '../types'; | ||
export declare function wrapComponent(Component: AnyComponent, wrapper: LogicWrapper): KeaComponent; |
@@ -1,2 +0,2 @@ | ||
import { BuiltLogicAdditions, Logic, ReducerFunction } from '../types'; | ||
import { BuiltLogic, ReducerFunction } from '../types'; | ||
import { Reducer } from 'redux'; | ||
@@ -7,4 +7,4 @@ export declare const ATTACH_REDUCER = "@KEA/ATTACH_REDUCER"; | ||
export declare function keaReducer(pathStart?: string): ReducerFunction; | ||
export declare function attachReducer(logic: Logic & BuiltLogicAdditions): void; | ||
export declare function detachReducer(logic: Logic & BuiltLogicAdditions): void; | ||
export declare function attachReducer(logic: BuiltLogic): void; | ||
export declare function detachReducer(logic: BuiltLogic): void; | ||
export declare function regenerateRootReducer(pathStart: string): void; | ||
@@ -11,0 +11,0 @@ export declare function recursiveCreateReducer(treeNode: ReducerFunction | Record<string, any>): ReducerFunction; |
import { Store } from 'redux'; | ||
export declare function getStore(opts?: {}): Store | void; |
import { Reducer, Store, Action as ReduxAction, Middleware, StoreEnhancer, compose, AnyAction } from 'redux'; | ||
import { ComponentType, FunctionComponent } from 'react'; | ||
import { Context as ReactContext, ComponentType, FunctionComponent } from 'react'; | ||
export declare type AnyComponent = ComponentType | FunctionComponent; | ||
@@ -39,6 +39,7 @@ export declare type Selector = (state?: any, props?: any) => any; | ||
} | ||
export interface BuiltLogicAdditions { | ||
export interface BuiltLogicAdditions<LogicType extends Logic> { | ||
_isKeaBuild: boolean; | ||
mount(callback?: any): () => void; | ||
mount(callback?: (logic: LogicType) => any): () => void; | ||
extend: (extendedInput: LogicInput) => LogicWrapper; | ||
wrapper: LogicWrapper; | ||
} | ||
@@ -49,10 +50,10 @@ export interface LogicWrapperAdditions<LogicType extends Logic> { | ||
inputs: LogicInput[]; | ||
<T extends LogicType['props'] | AnyComponent>(props: T): T extends LogicType['props'] ? LogicType & BuiltLogicAdditions : FunctionComponent; | ||
(): LogicType & BuiltLogicAdditions; | ||
<T extends LogicType['props'] | AnyComponent>(props: T): T extends LogicType['props'] ? LogicType & BuiltLogicAdditions<LogicType> : FunctionComponent; | ||
(): LogicType & BuiltLogicAdditions<LogicType>; | ||
wrap: (Component: AnyComponent) => KeaComponent; | ||
build: (props?: LogicType['props'], autoConnectInListener?: boolean) => LogicType & BuiltLogicAdditions; | ||
build: (props?: LogicType['props'], autoConnectInListener?: boolean) => LogicType & BuiltLogicAdditions<LogicType>; | ||
mount: (callback?: any) => () => void; | ||
extend: (extendedInput: LogicInput) => LogicWrapper; | ||
} | ||
export declare type BuiltLogic = Logic & BuiltLogicAdditions; | ||
export declare type BuiltLogic = Logic & BuiltLogicAdditions<Logic>; | ||
export declare type LogicWrapper = Logic & LogicWrapperAdditions<Logic>; | ||
@@ -179,17 +180,17 @@ declare type ActionDefinitions<LogicType extends Logic> = Record<string, any | (() => any)> | LogicType['actionCreators']; | ||
beforeKea?: (input: LogicInput) => void; | ||
beforeBuild?: (logic: Logic & BuiltLogicAdditions, inputs: LogicInput[]) => void; | ||
beforeLogic?: (logic: Logic & BuiltLogicAdditions, input: LogicInput) => void; | ||
afterLogic?: (logic: Logic & BuiltLogicAdditions, input: LogicInput) => void; | ||
afterBuild?: (logic: Logic & BuiltLogicAdditions, inputs: LogicInput[]) => void; | ||
beforeMount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterMount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeAttach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterAttach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeUnmount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterUnmount?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeDetach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
afterDetach?: (logic: Logic & BuiltLogicAdditions) => void; | ||
beforeBuild?: (logic: BuiltLogic, inputs: LogicInput[]) => void; | ||
beforeLogic?: (logic: BuiltLogic, input: LogicInput) => void; | ||
afterLogic?: (logic: BuiltLogic, input: LogicInput) => void; | ||
afterBuild?: (logic: BuiltLogic, inputs: LogicInput[]) => void; | ||
beforeMount?: (logic: BuiltLogic) => void; | ||
afterMount?: (logic: BuiltLogic) => void; | ||
beforeAttach?: (logic: BuiltLogic) => void; | ||
afterAttach?: (logic: BuiltLogic) => void; | ||
beforeUnmount?: (logic: BuiltLogic) => void; | ||
afterUnmount?: (logic: BuiltLogic) => void; | ||
beforeDetach?: (logic: BuiltLogic) => void; | ||
afterDetach?: (logic: BuiltLogic) => void; | ||
beforeWrapper?: (input: LogicInput, Klass: AnyComponent) => void; | ||
afterWrapper?: (input: LogicInput, Klass: AnyComponent, Kea: KeaComponent) => void; | ||
beforeRender?: (logic: Logic & BuiltLogicAdditions, props: Props) => void; | ||
beforeRender?: (logic: BuiltLogic, props: Props) => void; | ||
beforeCloseContext?: (context: Context) => void; | ||
@@ -238,2 +239,3 @@ } | ||
}[]; | ||
reactContexts: WeakMap<LogicWrapper, ReactContext<BuiltLogic | undefined>>; | ||
}; | ||
@@ -240,0 +242,0 @@ reducers: { |
export {}; |
{ | ||
"name": "kea", | ||
"version": "2.2.2", | ||
"version": "2.3.0-beta.1", | ||
"description": "Smart front-end architecture", | ||
@@ -5,0 +5,0 @@ "author": "Marius Andra", |
@@ -57,2 +57,6 @@ import { corePlugin } from '../core' | ||
react: { | ||
contexts: new WeakMap(), | ||
}, | ||
reducers: { | ||
@@ -59,0 +63,0 @@ tree: {}, |
@@ -7,2 +7,3 @@ export * from './types' | ||
export { useValues, useAllValues, useActions, useMountedLogic, useKea } from './react/hooks' | ||
export { BindProps } from './react/bind-props' | ||
@@ -9,0 +10,0 @@ export { resetContext, openContext, closeContext, getContext, getPluginContext, setPluginContext } from './context' |
@@ -11,3 +11,3 @@ import { runPlugins } from '../plugins' | ||
// Converts `input` into `logic` by running all build steps in succession | ||
function applyInputToLogic(logic: Logic & BuiltLogicAdditions, input: LogicInput) { | ||
function applyInputToLogic(logic: BuiltLogic, input: LogicInput) { | ||
runPlugins('beforeLogic', logic, input) | ||
@@ -66,3 +66,3 @@ | ||
}, | ||
} as any) as Logic & BuiltLogicAdditions | ||
} as any) as BuiltLogic | ||
@@ -140,3 +140,5 @@ return logic | ||
if (input.key && typeof key === 'undefined') { | ||
throw new Error('[KEA] Must have key to build logic') | ||
const path = typeof input.path === 'function' ? input.path(key) : input.path | ||
const pathString = Array.isArray(path) ? ` ${path.join('.')}` : '' | ||
throw new Error(`[KEA] Must have key to build logic${pathString}, got props: ${JSON.stringify(props)}`) | ||
} | ||
@@ -143,0 +145,0 @@ |
@@ -134,5 +134,5 @@ import { getContext } from '../context' | ||
args: undefined | AnyComponent, | ||
): (LogicType & BuiltLogicAdditions) | KeaComponent { | ||
): (LogicType & BuiltLogicAdditions<LogicType>) | KeaComponent { | ||
if (typeof args === 'object' || typeof args === 'undefined') { | ||
return wrapper.build(args) as LogicType & BuiltLogicAdditions | ||
return wrapper.build(args) as LogicType & BuiltLogicAdditions<LogicType> | ||
} | ||
@@ -149,3 +149,3 @@ return wrapper.wrap(args) | ||
wrapper.build = (props = {}, autoConnectInListener = true) => | ||
getBuiltLogic(wrapper.inputs, props, wrapper, autoConnectInListener) as LogicType & BuiltLogicAdditions | ||
getBuiltLogic(wrapper.inputs, props, wrapper, autoConnectInListener) as LogicType & BuiltLogicAdditions<LogicType> | ||
wrapper.mount = (callback) => wrapper.build().mount(callback) | ||
@@ -152,0 +152,0 @@ wrapper.extend = (extendedInput) => { |
@@ -5,3 +5,3 @@ import { attachReducer, detachReducer } from '../store/reducer' | ||
import { getContext } from '../context/index' | ||
import { Logic } from '../types' | ||
import { BuiltLogic, Logic } from '../types' | ||
@@ -38,11 +38,4 @@ export function mountLogic(logic: Logic, count = 1): void { | ||
function clearBuildCache(pathString: string): void { | ||
export function unmountLogic(logic: BuiltLogic): void { | ||
const { | ||
build: { cache }, | ||
} = getContext() | ||
delete cache[pathString] | ||
} | ||
export function unmountLogic(logic: Logic): void { | ||
const { | ||
mount: { counter, mounted }, | ||
@@ -75,5 +68,6 @@ } = getContext() | ||
clearBuildCache(pathString) | ||
// clear build cache | ||
delete getContext().build.cache[pathString] | ||
} | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { useMemo, useEffect, useRef } from 'react' | ||
import { useMemo, useEffect, useRef, useContext, createContext } from 'react' | ||
import { useSelector } from 'react-redux' | ||
@@ -6,2 +6,3 @@ | ||
import { LogicInput, LogicWrapper, BuiltLogic } from '../types' | ||
import { getContext } from '../context' | ||
@@ -13,3 +14,3 @@ export function useKea(input: LogicInput, deps = []): LogicWrapper { | ||
export function useValues<L extends BuiltLogic | LogicWrapper>(logic: L): L['values'] { | ||
useMountedLogic(logic) | ||
const builtLogic = useMountedLogic(logic) | ||
@@ -19,5 +20,5 @@ return useMemo(() => { | ||
for (const key of Object.keys(logic.selectors)) { | ||
for (const key of Object.keys(builtLogic.selectors)) { | ||
Object.defineProperty(response, key, { | ||
get: () => useSelector(logic.selectors[key]), | ||
get: () => useSelector(builtLogic.selectors[key]), | ||
}) | ||
@@ -27,11 +28,11 @@ } | ||
return response | ||
}, [logic.pathString]) | ||
}, [builtLogic.pathString]) | ||
} | ||
export function useAllValues<L extends BuiltLogic | LogicWrapper>(logic: L): L['values'] { | ||
useMountedLogic(logic) | ||
const builtLogic = useMountedLogic(logic) | ||
const response: Record<string, any> = {} | ||
for (const key of Object.keys(logic['selectors'])) { | ||
response[key] = useSelector(logic['selectors'][key]) | ||
for (const key of Object.keys(builtLogic['selectors'])) { | ||
response[key] = useSelector(builtLogic['selectors'][key]) | ||
} | ||
@@ -43,7 +44,7 @@ | ||
export function useActions<L extends BuiltLogic | LogicWrapper>(logic: L): L['actions'] { | ||
useMountedLogic(logic) | ||
return logic['actions'] | ||
const builtLogic = useMountedLogic(logic) | ||
return builtLogic['actions'] | ||
} | ||
function isWrapper(toBeDetermined: BuiltLogic | LogicWrapper): toBeDetermined is LogicWrapper { | ||
export function isWrapper(toBeDetermined: BuiltLogic | LogicWrapper): toBeDetermined is LogicWrapper { | ||
if ((toBeDetermined as LogicWrapper)._isKea) { | ||
@@ -55,20 +56,31 @@ return true | ||
export function useMountedLogic(logic: BuiltLogic | LogicWrapper): void { | ||
logic = isWrapper(logic) ? logic.build() : logic | ||
const blankContext = createContext(undefined as BuiltLogic | undefined) | ||
export function useMountedLogic(logic: BuiltLogic | LogicWrapper): BuiltLogic { | ||
const builtLogicContext = isWrapper(logic) ? getContext().react.contexts.get(logic as LogicWrapper) : null | ||
const defaultBuiltLogic = useContext(builtLogicContext || blankContext) | ||
const builtLogic = isWrapper(logic) ? defaultBuiltLogic || logic.build() : logic | ||
const unmount = useRef(undefined as undefined | (() => void)) | ||
if (!unmount.current) { | ||
unmount.current = logic.mount() | ||
unmount.current = builtLogic.mount() | ||
} | ||
const pathString = useRef(logic.pathString) | ||
const pathString = useRef(builtLogic.pathString) | ||
if (pathString.current !== logic.pathString) { | ||
if (pathString.current !== builtLogic.pathString) { | ||
unmount.current() | ||
unmount.current = logic.mount() | ||
pathString.current = logic.pathString | ||
unmount.current = builtLogic.mount() | ||
pathString.current = builtLogic.pathString | ||
} | ||
useEffect(() => () => unmount.current && unmount.current(), []) | ||
useEffect( | ||
() => () => { | ||
unmount.current && unmount.current() | ||
}, | ||
[], | ||
) | ||
return builtLogic | ||
} |
import { getContext } from '../context' | ||
import { runPlugins } from '../plugins' | ||
import {BuiltLogicAdditions, Logic, ReducerFunction} from '../types' | ||
import { BuiltLogic, ReducerFunction } from '../types' | ||
import { Reducer } from 'redux' | ||
@@ -35,3 +35,3 @@ | ||
export function attachReducer(logic: Logic & BuiltLogicAdditions): void { | ||
export function attachReducer(logic: BuiltLogic): void { | ||
const { path, reducer } = logic | ||
@@ -95,3 +95,3 @@ const { | ||
export function detachReducer(logic: Logic & BuiltLogicAdditions): void { | ||
export function detachReducer(logic: BuiltLogic): void { | ||
const { path } = logic | ||
@@ -98,0 +98,0 @@ |
import { Reducer, Store, Action as ReduxAction, Middleware, StoreEnhancer, compose, AnyAction } from 'redux' | ||
import { ComponentType, FunctionComponent } from 'react' | ||
import { Context as ReactContext, ComponentType, FunctionComponent } from 'react' | ||
@@ -43,6 +43,7 @@ // universal helpers | ||
export interface BuiltLogicAdditions { | ||
export interface BuiltLogicAdditions<LogicType extends Logic> { | ||
_isKeaBuild: boolean | ||
mount(callback?: any): () => void | ||
mount(callback?: (logic: LogicType) => any): () => void | ||
extend: (extendedInput: LogicInput) => LogicWrapper | ||
wrapper: LogicWrapper | ||
} | ||
@@ -55,7 +56,7 @@ | ||
<T extends LogicType['props'] | AnyComponent>(props: T): T extends LogicType['props'] | ||
? LogicType & BuiltLogicAdditions | ||
? LogicType & BuiltLogicAdditions<LogicType> | ||
: FunctionComponent | ||
(): LogicType & BuiltLogicAdditions | ||
(): LogicType & BuiltLogicAdditions<LogicType> | ||
wrap: (Component: AnyComponent) => KeaComponent | ||
build: (props?: LogicType['props'], autoConnectInListener?: boolean) => LogicType & BuiltLogicAdditions | ||
build: (props?: LogicType['props'], autoConnectInListener?: boolean) => LogicType & BuiltLogicAdditions<LogicType> | ||
mount: (callback?: any) => () => void | ||
@@ -65,3 +66,3 @@ extend: (extendedInput: LogicInput) => LogicWrapper | ||
export type BuiltLogic = Logic & BuiltLogicAdditions | ||
export type BuiltLogic = Logic & BuiltLogicAdditions<Logic> | ||
export type LogicWrapper = Logic & LogicWrapperAdditions<Logic> | ||
@@ -290,17 +291,17 @@ | ||
beforeKea?: (input: LogicInput) => void | ||
beforeBuild?: (logic: Logic & BuiltLogicAdditions, inputs: LogicInput[]) => void | ||
beforeLogic?: (logic: Logic & BuiltLogicAdditions, input: LogicInput) => void | ||
afterLogic?: (logic: Logic & BuiltLogicAdditions, input: LogicInput) => void | ||
afterBuild?: (logic: Logic & BuiltLogicAdditions, inputs: LogicInput[]) => void | ||
beforeMount?: (logic: Logic & BuiltLogicAdditions) => void | ||
afterMount?: (logic: Logic & BuiltLogicAdditions) => void | ||
beforeAttach?: (logic: Logic & BuiltLogicAdditions) => void | ||
afterAttach?: (logic: Logic & BuiltLogicAdditions) => void | ||
beforeUnmount?: (logic: Logic & BuiltLogicAdditions) => void | ||
afterUnmount?: (logic: Logic & BuiltLogicAdditions) => void | ||
beforeDetach?: (logic: Logic & BuiltLogicAdditions) => void | ||
afterDetach?: (logic: Logic & BuiltLogicAdditions) => void | ||
beforeBuild?: (logic: BuiltLogic, inputs: LogicInput[]) => void | ||
beforeLogic?: (logic: BuiltLogic, input: LogicInput) => void | ||
afterLogic?: (logic: BuiltLogic, input: LogicInput) => void | ||
afterBuild?: (logic: BuiltLogic, inputs: LogicInput[]) => void | ||
beforeMount?: (logic: BuiltLogic) => void | ||
afterMount?: (logic: BuiltLogic) => void | ||
beforeAttach?: (logic: BuiltLogic) => void | ||
afterAttach?: (logic: BuiltLogic) => void | ||
beforeUnmount?: (logic: BuiltLogic) => void | ||
afterUnmount?: (logic: BuiltLogic) => void | ||
beforeDetach?: (logic: BuiltLogic) => void | ||
afterDetach?: (logic: BuiltLogic) => void | ||
beforeWrapper?: (input: LogicInput, Klass: AnyComponent) => void | ||
afterWrapper?: (input: LogicInput, Klass: AnyComponent, Kea: KeaComponent) => void | ||
beforeRender?: (logic: Logic & BuiltLogicAdditions, props: Props) => void | ||
beforeRender?: (logic: BuiltLogic, props: Props) => void | ||
beforeCloseContext?: (context: Context) => void | ||
@@ -351,2 +352,6 @@ } | ||
react: { | ||
contexts: WeakMap<LogicWrapper, ReactContext<BuiltLogic | undefined>> | ||
} | ||
reducers: { | ||
@@ -353,0 +358,0 @@ tree: any |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
541233
149
8961
1
22