Args and deps
Args are a node’s typed input. They feed three things: the key function that derives identity, the dependencies resolver, and the driver context. Dependencies are the other nodes this node reads, declared as graph edges.
Args
Declare the args type in the spec shape. The same type is what callers pass when they request the node.
type ProfileSpec = Frond.NodeSpec<{
args: { userId: string };
key: Frond.Key.Structure<{ userId: string }>;
result: ProfileResult;
}>;
runtime.client.node(ProfileNode, { userId: "u_42" });
A node that takes no input uses Frond.Args.None in the shape and Frond.Args.none ({}) at the call site.
type ConfigSpec = Frond.NodeSpec<{
args: Frond.Args.None;
key: Frond.Key.Singleton;
result: ConfigResult;
}>;
Inside the driver, args are on ctx.args. Inside the class, they are on this.args.
The key function
key(args) returns the value that becomes the node’s identity key. It must be pure and deterministic — no clock, random, environment, or async. Pick out the args that distinguish one instance from another.
key: (args) => Frond.Key.structure({ userId: args.userId }),
A structured-args node returns Frond.Key.structure(...); a no-args node returns Frond.Key.singleton(). See Identity and keys for canonicalization and the failure modes.
Declaring dependencies
Frond.dependencies takes a resolver from args to a record of Frond.dep(spec, args) entries. The record keys are how you read each dependency.
dependencies: Frond.dependencies((args) => ({
session: Frond.dep(SessionNode, Frond.Args.none),
profile: Frond.dep(ProfileNode, { userId: args.userId }),
})),
A dependency’s args can derive from this node’s args, as profile does above. The dependency resolves to a node id the same way any read does, so two nodes depending on ProfileNode with the same userId share one instance. See Dependencies for edges, readiness, and eviction.
The dependency set is part of the node’s wiring. updateArgs() must resolve to the same dependency set; args that would change which nodes are depended on fail the update.
Reading dependencies
In the driver, ctx.deps.<name> is the resolved dependency — the ready node instance, not a raw value. Read its result through .result.
acquire: Frond.Driver.Acquire((ctx) =>
buildAccount(ctx.deps.session.result, ctx.deps.profile.result)
),
In the class, the same instances are on this.deps.
get accountId(): string {
return this.deps.profile.result.accountId;
}
To re-acquire a single dependency from a refresh or action, use ctx.refreshDep("profile").
Next: Actions — methods the runtime mediates against a ready node.