import hooks = require("./hooks"); import { IElementParams, IGlobalObject, IContext, IElementContext } from "./types"; import HooksTypes = require("./types/hooks"); import { Processor } from "./Processor"; import { CallbacksManager } from "./CallbacksManager"; import { EventsManager } from "./EventsManager"; import { IPartialObserver, ISubscribable } from "./types/subscriptions"; import { subscribeHook } from "./hooks"; import { Subscription } from "./Subscription"; import { callHook } from "./hooks/callHook"; import { Context } from "./Context"; import { Iterator } from "./Iterator"; import { completeHook } from "./hooks/completeHook"; import { useRefHook } from "./hooks/useRefHook"; // tslint:disable-next-line: variable-name export const ___global: IGlobalObject = { current: undefined, }; export const getCurrentGlobal = () => { if (!___global.current) { throw new Error("Unexpected call, can't call hook outside component"); } return ___global.current; }; export const useState: HooksTypes.useState = (defaultValue) => { const { elementId, elementState, locator } = getCurrentGlobal(); return hooks.useStateHook(locator.eventsManager, locator.callbacksManager, elementId, elementState, defaultValue); }; export const useEffect: HooksTypes.useEffect = (fn, deps) => { const { elementState } = getCurrentGlobal(); return hooks.useEffectHook(elementState, fn, deps); }; export const useContext: HooksTypes.useContext = (context: IContext) => { const { elementState } = getCurrentGlobal(); return hooks.useContextHook(elementState, context); }; export const withContext: HooksTypes.withContext = (context: IContext, value: any) => { const { elementState } = getCurrentGlobal(); return hooks.withContextHook(elementState, context, value); }; export const subscribe: HooksTypes.subscribe = (params: IElementParams, observer?: IPartialObserver) => { const { elementState, elementId, locator } = getCurrentGlobal(); return subscribeHook( locator.processor, locator.eventsManager, locator.callbacksManager, elementId, elementState, params, observer ? observer : {}, ); }; export const call: HooksTypes.call = (params, observer) => { const { locator, elementId, elementState } = getCurrentGlobal(); return callHook( locator.processor, locator.eventsManager, locator.callbacksManager, elementId, elementState, params, observer ? observer : {}, ); }; export const useRef: HooksTypes.useRef = () => { const { elementState } = getCurrentGlobal(); return useRefHook(elementState); }; export const complete: HooksTypes.complete = () => { const { elementState } = getCurrentGlobal(); return completeHook(elementState); }; export const createFunc = ( func: (...args: A) => R | Promise, ): (( ...args: A ) => IElementParams & { call: (observer?: IPartialObserver) => void; subscribe: (observer?: IPartialObserver) => void; }) => { return (...args: A) => ({ name: func.name, args, func, call: (observer?: IPartialObserver) => { call( { name: func.name, args, func, }, observer, ); }, subscribe: (observer?: IPartialObserver) => { subscribe( { name: func.name, args, func, }, observer, ); }, }); }; export const createProcessor = (params: IElementParams) => { const callbacksManager = new CallbacksManager(); const eventsManager = new EventsManager(callbacksManager); const processor = new Processor({ root: params, callbacksManager, eventsManager, }); return processor; }; export const createSubscription = ( params: IElementParams, observer?: IPartialObserver, contexts?: IElementContext[], ) => { return new Subscription({ contexts, params, observer, globalObject: ___global }); }; export const createContext = (defaultValue?: T): IContext => { const context = new Context(); context.defaultValue = defaultValue; return context; }; export const toPromise = (params: IElementParams, contexts?: IElementContext[]) => { return new Promise((resolve, reject) => { const subscription = createSubscription( params, { next: (value) => { resolve(value); subscription.unsubscribe(); }, error: reject, }, contexts, ); }); }; export const createIterator = (params: IElementParams, contexts?: IElementContext[]) => { const subscribable: ISubscribable = { subscribe: (observer: IPartialObserver) => { return createSubscription(params, observer, contexts); }, }; const channel = new Iterator({ subscribable, }); return channel; };