/* @jsxImportSource solid-js */ import type { Component } from 'solid-js'; import { createContext, useContext } from 'solid-js'; import { Dynamic } from 'solid-js/web'; import { removeNonUnit } from './utils/removeNonUnit'; import { removeStorePrefix } from './utils/removeStorePrefix'; /** * Creates model `factory` * @param creator Function that returns new `model` instance * @returns Factory with `createModel` method, `useModel` hook and model `Provider` */ export const modelFactory = any>(creator: T) => { const ModelContext = createContext | null>(null); const useModel = () => { const model = useContext(ModelContext); if (!model) { throw new Error('No model found'); } return model; }; const unitShape = () => { const model = useModel(); const modelUnits = removeNonUnit(model); return removeStorePrefix(modelUnits); }; return { /** Function that returns new `model` instance */ createModel: creator, /** Hook that returns current `model` instance */ useModel, /** `Provider` to pass current `model` instance into */ Provider: ModelContext.Provider, '@@unitShape': unitShape, }; }; export type Model> = ReturnType< Factory['createModel'] >; /** * HOC that wraps your `View` into model `Provider`. Also adds `model` prop that will be passed into `Provider` * @param factory Factory that will be passed through Context * @param View Root component that will be wrapped into Context * @returns Wrapped component */ export const modelView = < U extends {}, T extends ReturnType >( factory: T, View: Component }> ) => { const Render = (props: Parameters[0]) => { return ( ); }; // `as` is used for a better "Go To Definition" return Render as typeof View; };