@applicaster/quick-brick-core
Version:
Core package for Applicaster's Quick Brick App
142 lines (107 loc) • 3.79 kB
text/typescript
/* eslint-disable react-hooks/rules-of-hooks */
import * as R from "ramda";
import { allSettled } from "promise";
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
import * as React from "react";
import { coreAppLogger } from "../logger";
const logger = coreAppLogger.addSubsystem("AppLifeCycleManager");
const debugActions = (actions) =>
logger.debug({
message: `useSubscribeToActionProviders - available actions count: ${
Object.keys(actions).length
}`,
data: { actions },
});
const warnUndefinedContext = (context) =>
logger.warning({
message: "One of your action plugins has an undefined context value",
data: { context },
});
type Subscription = {
[x: string]: () => any;
};
const getModuleContext = R.path(["module", "context"]);
const getContexts = R.compose(
R.map((action) => {
const item = getModuleContext(action);
item["pluginId"] = action.name;
return item;
}),
R.values
);
const useSubscribeToActionProviders = () => {
// @ts-ignore
const actionContext = useActions();
React.useEffect(() => {
if (!actionContext || !actionContext.actions) return;
debugActions(actionContext.actions);
}, [actionContext]);
const subscriptions = getContexts(actionContext.actions).map((context) => {
const subscription = React.useContext<{}>(context);
if (subscription) {
subscription["pluginId"] = context.pluginId;
return subscription;
} else {
warnUndefinedContext(context);
}
});
return subscriptions || [];
};
export const useRiverInitialState = () => {
const key = "getRiverInitialState";
const actionProvidersSubscriptions = useSubscribeToActionProviders();
const subscriptions = React.useMemo(() => {
if (!actionProvidersSubscriptions.length) return undefined;
return actionProvidersSubscriptions.reduce((acc, item) => {
const riverInitialStatePromise = item[key]?.();
if (riverInitialStatePromise) {
acc.push(riverInitialStatePromise);
}
return acc;
}, [] as Subscription[]);
}, [actionProvidersSubscriptions]);
if (!actionProvidersSubscriptions.length) return undefined;
return subscriptions;
};
const getActionInitialStateSetters = (key) => {
return R.compose(
R.map((subscription: { [x: string]: any; pluginId: any }) => {
return async () => {
const now = performance.now();
logger.info({
message: `Invocation Started - action plugin ${key}, pluginId: ${subscription.pluginId}`,
});
const promiseFunc = subscription[key];
const result = await promiseFunc();
logger.info({
message: `Invocation Completed - action plugin ${key}, pluginId: ${
subscription.pluginId
}: ${performance.now() - now} ms`,
});
return result;
};
}),
R.filter((subscription: { [x: string]: any }) => {
return subscription[key];
})
);
};
export const useActionSetters = (key: string = "getInitialState") => {
const actionProvidersSubscriptions = useSubscribeToActionProviders();
if (!actionProvidersSubscriptions.length) return undefined;
const subscriptions = React.useMemo(() => {
if (!actionProvidersSubscriptions.length) return undefined;
return getActionInitialStateSetters(key)(actionProvidersSubscriptions);
}, [key, actionProvidersSubscriptions]);
if (!actionProvidersSubscriptions.length) return undefined;
return subscriptions;
};
export async function initializeActionSetters(actionSetters: any) {
if (!actionSetters) return Promise.resolve();
const loaders: Promise<{}>[] = actionSetters.map(
(setter: () => Promise<{}>) => {
return setter();
}
);
return allSettled(loaders);
}