///|
struct ExampleState {
labels : Array[String]
} derive(Debug, Eq, FromJson, ToJson)
///|
struct ExampleRuntimeResource {
visits : Ref[Int]
} derive(Debug)
///|
extenum @any.Payload += {
ExampleRuntimeResource(ExampleRuntimeResource)
}
///|
impl @any.Anyable for ExampleRuntimeResource with fn iso() {
{
id: @any.TypeId::TypeId(
"totto2727/workgraph-core/examples/basic",
"ExampleRuntimeResource",
[],
),
box: resource => ExampleRuntimeResource(resource),
unbox: payload => {
guard! payload is ExampleRuntimeResource(resource)
resource
},
}
}
///|
fn example_runtime_resource_ref() -> @any_collection.AnyRef[
@core.ResourceKey,
ExampleRuntimeResource,
] {
@any_collection.AnyRef::AnyRef(
@core.ResourceKey::ResourceKey("example-runtime-resource") catch {
_ => abort("static example resource key must be valid")
},
)
}
///|
fn example_reducer() -> @core.Reducer[ExampleState, String] {
@core.Reducer::Reducer(fn(state, patch) {
{ labels: [..state.labels, patch] }
})
}
///|
fn example_id(value : String) -> @core.NodeId {
@core.NodeId::NodeId(value) catch {
_ => abort("static example node ID must be valid")
}
}
///|
fn example_metadata(name : String) -> @core.NodeMetadata {
@core.NodeMetadata::NodeMetadata(
name~,
description=None,
kind=@core.Function,
tags=[],
)
}
///|
fn example_node(
id : @core.NodeId,
label : String,
) -> @core.Node[ExampleState, String] {
@core.Node::Node(id, example_metadata(label), async fn(context, _state) {
@async.pause()
let reference = example_runtime_resource_ref()
let resource = match context.resources.get(reference) {
Some(resource) => resource
None => {
let resource = ExampleRuntimeResource::{ visits: Ref(0) }
context.resources.set(reference, resource)
resource
}
}
resource.visits.val = resource.visits.val + 1
@core.NodeOutput::NodeOutput(Some("\{label}:\{resource.visits.val}"), None)
})
}
///|
async fn main {
let plan = example_id("plan")
let verify = example_id("test")
let definition = @core.GraphDefinition::GraphDefinition(example_reducer())
definition.add_node(example_node(plan, "plan"))
definition.add_node(example_node(verify, "test"))
definition.set_router(
plan,
@core.router([@core.DeclaredRoute::DeclaredRoute(verify)], fn(
_state,
_completion,
) {
@core.To(verify)
}),
)
definition.set_router(
verify,
@core.router([], fn(_state, _completion) { @core.End }),
)
definition.set_entry(plan)
let runtime = @core.GraphRuntime::GraphRuntime(definition.compile())
let result = runtime.invoke({ labels: [] })
let snapshot = ToJson::to_json(result.final_state)
let restored : ExampleState = @json.from_json(snapshot)
println("labels=\{restored.labels.join(",")}")
println("snapshot=\{snapshot.stringify()}")
println("steps=\{result.steps}")
}