54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
import Value from 'Components/Value'
|
|
import React, { createContext, useContext, useMemo } from 'react'
|
|
import rules, { DottedName } from 'Rules'
|
|
import Engine from '.'
|
|
export const EngineContext = createContext<{
|
|
engine: Engine<DottedName> | null
|
|
error: string | null
|
|
}>({ engine: new Engine({ rules }), error: null })
|
|
|
|
type InputProps = {
|
|
rules?: any
|
|
situation?: any
|
|
children: React.ReactNode
|
|
}
|
|
|
|
export function Provider({ rules, situation, children }: InputProps) {
|
|
const [engine, error] = useMemo(() => {
|
|
try {
|
|
return [new Engine({ rules }), null]
|
|
} catch (err) {
|
|
return [null, (err?.message ?? err.toString()) as string]
|
|
}
|
|
}, [rules])
|
|
if (engine !== null && !Object.is(situation, engine.situation)) {
|
|
engine.setSituation(situation)
|
|
}
|
|
return (
|
|
<EngineContext.Provider value={{ engine, error }}>
|
|
{children}
|
|
</EngineContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useEvaluation(expression: string) {
|
|
const { engine } = useContext(EngineContext)
|
|
return engine === null ? null : engine.evaluate(expression)
|
|
}
|
|
|
|
export function useError() {
|
|
return useContext(EngineContext).error
|
|
}
|
|
|
|
export function Evaluation({ expression }) {
|
|
const value = useEvaluation(expression)
|
|
return value === null ? null : <Value {...value} />
|
|
}
|
|
|
|
export default {
|
|
Provider,
|
|
useEvaluation,
|
|
useError,
|
|
Evaluation
|
|
}
|