Optional values
Values flow between Tasks and Wires. Every value a Task reads is required by default. optional marks one as not required — when the source is missing, the Task still runs and the field is undefined.
Inside a context
Section titled “Inside a context”optional works in both run.context and enabled.context.
import { compose, createTask, optional } from "@grlt-hub/app-compose"
const user = createTask({ name: "user", run: { fn: () => ({ name: "John" }), },})
const location = createTask({ name: "location", run: { fn: () => "Antarctica" },})
const greeting = createTask({ name: "greeting", run: { context: { user: optional(user.result) }, // 👈 fn: ({ user }) => { console.log(`Hello, ${user?.name ?? "<unknown-user>"}`) }, },})
const recommendations = createTask({ name: "recommendations", run: { fn: () => console.log("recommendations loaded"), }, enabled: { context: [ optional(user.result), // 👈 optional(location.result), // 👈 ], fn: (ctx) => ctx.some((x) => x !== undefined), },})
// Try commenting a step:// .step(user) → "<unknown-user>", recommendations run// .step(location) → "Hello, John", recommendations run// both → "<unknown-user>", recommendations skipcompose() .step(user) .step(greeting) .step(location) .step(recommendations) .run()Inside a Wire
Section titled “Inside a Wire”optional works in createWire.from. The destination tag carries T | undefined.
import { compose, createTask, createWire, optional, tag } from "@grlt-hub/app-compose"
const userName = tag<string | undefined>("userName")
const user = createTask({ name: "user", run: { fn: () => ({ name: "John" }), },})
const greeting = createTask({ name: "greeting", run: { context: { name: userName.value, }, fn: ({ name }) => { console.log(`Welcome back, ${name ?? "<unknown-user>"}`) }, },})
const userNameWire = createWire({ from: optional(user.result.name), // 👈 to: userName,})
compose() // 👇 comment — greeting → "<unknown-user>" .step(user) .step(userNameWire) .step(greeting) .run()Inside a shape
Section titled “Inside a shape”optional works in shape. The callback receives T | undefined.
import { compose, createTask, createWire, optional, shape, tag } from "@grlt-hub/app-compose"
const userName = tag<string>("userName")
const user = createTask({ name: "user", run: { fn: () => ({ name: "John" }) },})
const greeting = createTask({ name: "greeting", run: { context: { name: userName.value, }, fn: ({ name }) => console.log(`Welcome back, ${name}`), },})
const userNameShape = shape( optional(user.result.name), // 👈 (name) => name ?? "<unknown-user>")
const userNameWire = createWire({ from: userNameShape, to: userName,})
compose() // 👇 comment — greeting → "<unknown-user>" .step(user) .step(userNameWire) .step(greeting) .run()