import 'atomico/ssr/load'; import {html} from "atomico"; import type {VNode, VNodeAny} from "atomico/types/vnode"; import {type ActionArgs, emit, type EventObject,type MachineContext, type ParameterizedObject} from "xstate"; import {EventMessage} from "@/iterator"; export type StreamOptions ={ href:string connect: (options?:{event?:string, swap?:string}) => Record }; export type RenderStream = StreamOptions & { service:(id?: string) => RenderStream; event:(type:string)=>StreamOptions }; export function workflowStream(workflow: string ):RenderStream { return { href: workflow, event: (type: string) => streamElements(workflow, type), service: (id?: string) => workflowStream(`${workflow}/${id}` ), connect: streamElements(workflow).connect } } export function streamElements(workflow: string, type?: string | undefined):StreamOptions { const href = `${workflow}${type ? `/events/${type}` : ''}`; return { href, connect(options) { const {event, swap}= options ||{ } return { 'hx-swap': swap || 'beforeend' , 'sse-swap':event || type, 'sse-connect': `${workflow}/events`, 'ext':'sse' } } } } //render action export type Html={( strings: TemplateStringsArray, ...values: any[] ): R;} export type NodeExpression=(args:ActionArgs & {stream:RenderStream , html:Html},params:TParams) => VNodeAny; export function render( nodeOrExpr:NodeExpression | VNodeAny, ) { return renderTo('render', nodeOrExpr) } export function renderTo(type:string, nodeOrExpr:NodeExpression | VNodeAny, ) { const expr = typeof nodeOrExpr === 'function' ? nodeOrExpr : () => nodeOrExpr; return emit(({context, self, ...args}: ActionArgs, params: TParams) => { const selfId = self.id; const node = expr({ stream: context?.stream || workflowStream(selfId), self, html, ...args, context: context }, params); return renderEvent(type,node); }) function renderEvent(type:string, node:VNode) { if(!node?.render) { console.log('No render method',type, node); debugger; return { type: type, event: type, data: node.toString(), }; } const rendered = node.render() as unknown as { type: string, name: string, nodeName: string, attributes: any, innerHTML: string, outerHTML: string, }; return { type: type, event: type, data: rendered?.toString(), } satisfies EventMessage & { type: typeof type, event: string } } }