@prodo/core
Version:
Core package for [Prodo](https://prodo.dev). See [documentation](https://docs.prodo.dev) for more info.
176 lines (162 loc) • 4.25 kB
text/typescript
import * as React from "react";
import { Comp, Event, PluginDispatch } from "./types";
export interface PluginActionCtx<ActionCtx, Universe> {
dispatch: PluginDispatch<ActionCtx>;
universe: Universe;
rootDispatch: PluginDispatch<ActionCtx>;
}
export interface PluginViewCtx<ActionCtx, Universe> {
dispatch: PluginDispatch<ActionCtx>;
universe: Universe;
subscribe: (path: string[], unsubscribe?: (comp: Comp) => void) => void;
}
export type PluginInitFn<InitOptions, Universe> = (
config: InitOptions,
universe: Universe,
store: { dispatch: PluginDispatch<any>; exposedUniverseVars: string[] },
) => void;
export type PluginActionCtxFn<
InitOptions,
Universe,
ActionCtx,
CustomEvent = {}
> = (
env: {
ctx: PluginActionCtx<ActionCtx, Universe> & ActionCtx;
universe: Universe;
event: Event & CustomEvent;
},
config: InitOptions,
) => void;
export type PluginViewCtxFn<InitOptions, Universe, ActionCtx, ViewCtx> = (
env: {
ctx: PluginViewCtx<ActionCtx, Universe> & ViewCtx;
universe: Universe;
comp: Comp;
},
config: InitOptions,
) => void;
export type PluginOnCompleteEventFn<InitOptions, CustomEvent, ActionCtx> = (
env: {
event: Event & CustomEvent;
rootDispatch: PluginDispatch<ActionCtx>;
},
config: InitOptions,
) => void;
export interface ProdoInternals<
InitOptions,
Universe,
ActionCtx,
ViewCtx,
CustomEvent = {}
> {
name: string;
init?: PluginInitFn<InitOptions, Universe>;
actionCtx?: PluginActionCtxFn<InitOptions, Universe, ActionCtx, CustomEvent>;
viewCtx?: PluginViewCtxFn<InitOptions, Universe, ActionCtx, ViewCtx>;
onCompleteEvent?: PluginOnCompleteEventFn<
InitOptions,
CustomEvent,
ActionCtx
>;
Provider?: React.ComponentType<{ children: React.ReactNode }>;
exposedUniverseVars?: string[];
}
export type PluginAction<ActionCtx, A extends any[]> = (
ctx: ActionCtx,
) => (...args: A) => void;
export type PluginActionCreator<ActionCtx> = <A extends any[]>(
func: (ctx: ActionCtx) => (...args: A) => void,
actionName: string,
) => (ctx: ActionCtx) => (...args: A) => void;
export interface ProdoPlugin<
InitOptions,
Universe,
ActionCtx,
ViewCtx,
CustomEvent = {}
> {
name: string;
init: (initFn: PluginInitFn<InitOptions, Universe>) => void;
prepareActionCtx: (
actionCtxFn: PluginActionCtxFn<
InitOptions,
Universe,
ActionCtx,
CustomEvent
>,
) => void;
prepareViewCtx: (
viewCtxFn: PluginViewCtxFn<InitOptions, Universe, ActionCtx, ViewCtx>,
) => void;
onCompleteEvent: (
completeEventFn: PluginOnCompleteEventFn<
InitOptions,
CustomEvent,
ActionCtx
>,
) => void;
action: PluginActionCreator<ActionCtx>;
setProvider: (
provider: React.ComponentType<{ children: React.ReactNode }>,
) => void;
_internals: ProdoInternals<
InitOptions,
Universe,
ActionCtx,
ViewCtx,
CustomEvent
>;
exposeUniverseVars: (vars: string[]) => void;
}
export const mkUserAction = <ActionCtx, A extends any[]>(
action: PluginAction<ActionCtx, A>,
): ((...args: A) => void) => {
return action as any;
};
export const createPlugin = <
InitOptions,
Universe,
ActionCtx,
ViewCtx,
CustomEvent = {}
>(
name: string,
): ProdoPlugin<InitOptions, Universe, ActionCtx, ViewCtx, CustomEvent> => {
const prodoInternals: ProdoInternals<
InitOptions,
Universe,
ActionCtx,
ViewCtx,
CustomEvent
> = {
name,
};
return {
name,
init: initFn => {
prodoInternals.init = initFn;
},
prepareActionCtx: actionCtxFn => {
prodoInternals.actionCtx = actionCtxFn;
},
prepareViewCtx: viewCtxFn => {
prodoInternals.viewCtx = viewCtxFn;
},
onCompleteEvent: onCompleteEventFn => {
prodoInternals.onCompleteEvent = onCompleteEventFn;
},
action: (func, actionName) => {
(func as any).__name = actionName;
(func as any).__pluginName = name;
return func as any;
},
setProvider: provider => {
prodoInternals.Provider = provider;
},
exposeUniverseVars: exposeUniverseVars => {
prodoInternals.exposedUniverseVars = exposeUniverseVars;
},
_internals: prodoInternals,
};
};