@applicaster/zapp-react-native-ui-components
Version:
Applicaster Zapp React Native ui components for the Quick Brick App
101 lines (83 loc) • 2.29 kB
text/typescript
/// <reference types="@applicaster/applicaster-types" />
import * as R from "ramda";
import uuid from "uuid/v4";
import { createZappPipesContext } from "./ZappPipesContextFactory";
const initialContext = {
context: null,
setContext: () => {},
};
type EntryWithParent = ZappEntry & { parent?: EntryWithParent };
type SingleEntry = {
data: EntryWithParent;
route: string;
id: string;
parentId?: string;
};
type EntryContextType = { [K in string]: SingleEntry };
const getParentRoute = R.compose(
R.concat("/"),
R.join("/"),
R.flatten,
R.init,
R.splitEvery(2),
R.tail,
R.split("/")
);
export function findParent(context, route, getChildren = false) {
const parentRoute = getParentRoute(route);
const parent = R.propOr(null, parentRoute, context);
const children = getChildren
? R.compose(
R.defaultTo(null),
R.find(R.propEq("parentId", parent?.id)),
R.values
)(context)
: null;
return children || parent;
}
export function selector(
context: EntryContextType,
route: string,
getChildren: boolean
): EntryWithParent {
const parent = findParent(context, route, getChildren);
return parent?.data;
}
function prepareContext(
newContext: ZappEntry,
currentContext: EntryContextType,
route: string,
getChildren: boolean
): EntryContextType {
const parent = findParent(currentContext, route, getChildren);
const newEntry = {
route,
id: uuid(),
data: newContext,
} as SingleEntry;
const entryClone = R.clone(newEntry);
if (
parent?.data?.entry?.includes(newEntry?.data) ||
R.equals(parent?.data, newEntry?.data)
) {
// to avoid circular dependencies when a parent feed contains
// the current entry, we remove entries from the parent
const parentClone = R.clone(parent);
delete parentClone.data.entry;
entryClone.data.parent = parentClone.data;
entryClone.parentId = parentClone.id as string;
} else {
if (parent) {
entryClone.data.parent = parent.data;
entryClone.parentId = parent.id as string;
}
}
return R.assoc(route, entryClone, currentContext);
}
export const ZappPipesEntryContext = createZappPipesContext<
EntryWithParent,
EntryContextType
>(initialContext, {
selector,
prepareContext,
});