Family
KIT · constant · Runtime value
Import
ts
import { Family } from '@jangts/agent-core/kits/family';js
import { Family } from '@jangts/agent-core/kits/family';Other public entry points:@jangts/agent-core/types, @jangts/agent-core/kits, @jangts/agent-core/kits/family.
Definition
Member index
| Member | Purpose |
|---|---|
defineAgentFamily | See the overload below for full inputs and outputs. |
Member details
defineAgentFamily
ts
Family.defineAgentFamily<State, App>(definition: FamilyDefinition<State, App>): AgentFamily<State, App>Compile a versioned family backed by an App-owned compare-and-swap store.
Every mutation reads the record, verifies the caller's expected revision, then commits with a compare-and-swap, so concurrent writers fail with a revision conflict rather than overwriting each other. Reads are also treated as policy checks because the App binds its read rules into the store it supplies.
| Type parameter | Constraint | Default type |
|---|---|---|
State | — | — |
App | — | — |
| Parameter | Type | Passing | Description |
|---|---|---|---|
definition | FamilyDefinition<State, App> | Required | — |
Fields of definition
| Field | Type | Required | Description |
|---|---|---|---|
store | FamilyStore<State> | Required | Read-only. See the type definition and usage context. |
maxVersions | number | undefined | Optional | Read-only. Maximum retained versions; older versions are dropped once the bound is exceeded. |
retentionMs | number | undefined | Optional | Read-only. Retention window in milliseconds, measured from a write. |
now | (() => number) | undefined | Optional | Read-only. Clock override for timestamps and expiry; defaults to Date.now. |
isState | (value: unknown) => value is State | Required | Validates a state loaded from the store before it is used. |
authorize | (operation: FamilyOperation, record: FamilyRecord<State> | undefined, context: OperationContext<App>) => MaybePromise<void> | Required | Guards one mutation; called before any write, including with an absent record. |
validate | (candidate: FamilyVersion<State>, context: OperationContext<App>) => MaybePromise<void> | Required | Validates a candidate version before it is appended. |
merge | ((input: { base: State; target: State; source: State; }, context: OperationContext<App>) => MaybePromise<{ value?: State | undefined; conflicts: readonly string[]; }>) | undefined | Optional | Resolves a three-way merge. Returns the merged state and any conflicts. A non-empty conflict list aborts the merge without writing a version, so value is ignored in that case. |
Returns: AgentFamily<State, App>.
Return value structure
| Field | Type | Required | Description |
|---|---|---|---|
read | (id: string, context: OperationContext<App>) => Promise<FamilyRecord<State>> | Required | Reads the record; throws when the family does not exist or has expired. |
create | (request: { id: string; branch: AgentBranch; state: State; }, context: OperationContext<App>) => Promise<FamilyRecord<State>> | Required | Creates the first version and makes it active. |
fork | (request: { id: string; revision: number; parentId: string; branch: AgentBranch; state: State; }, context: OperationContext<App>) => Promise<FamilyRecord<State>> | Required | Appends a version forked from parentId; the active pointer does not change. |
merge | (request: { id: string; revision: number; baseId: string; targetId: string; sourceId: string; }, context: OperationContext<App>) => Promise<{ saved: boolean; record: FamilyRecord<State>; conflicts: readonly string[]; }> | Required | Merges source into target; saved is false when the merge reported conflicts. |
promote | (request: { id: string; revision: number; candidateId: string; expectedActiveId: string; }, context: OperationContext<App>) => Promise<FamilyRecord<State>> | Required | Makes candidateId active; fails when the active version changed since expectedActiveId. |
Examples
- Agent family: versions, merge, and explicit promotion: Manage data branches on real CAS storage; candidate versions are explicitly promoted after checks and authorization.
Configure state checks, source verification, and three-way merge
Configuration · Node.js
ts
import { defineAgentFamily } from '@jangts/agent-core/kits/family';
import type { FamilyStore } from '@jangts/agent-core/kits/family';
import type { OperationContext } from '@jangts/agent-core';
type State = { goal: string; sourceRevision: string };
export function family<App>(store: FamilyStore<State>,
authorize: (context: OperationContext<App>) => Promise<void>,
verify: (state: State) => Promise<void>) {
return defineAgentFamily<State, App>({
store, maxVersions: 16, retentionMs: 7 * 86400000,
isState: (value): value is State => !!value && typeof (value as State).goal === 'string'
&& typeof (value as State).sourceRevision === 'string',
authorize: (_operation, _record, context) => authorize(context),
validate: candidate => verify(candidate.state),
async merge({ base, target, source }) {
if (target.goal !== base.goal && source.goal !== base.goal && target.goal !== source.goal)
return { conflicts: ['goal'] };
return { value: target.goal === base.goal ? source : target, conflicts: [] };
},
});
}js
import { defineAgentFamily } from '@jangts/agent-core/kits/family';
export function family(store, authorize, verify) {
return defineAgentFamily({
store, maxVersions: 16, retentionMs: 7 * 86400000,
isState: (value) => !!value && typeof value.goal === 'string'
&& typeof value.sourceRevision === 'string',
authorize: (_operation, _record, context) => authorize(context),
validate: candidate => verify(candidate.state),
async merge({ base, target, source }) {
if (target.goal !== base.goal && source.goal !== base.goal && target.goal !== source.goal)
return { conflicts: ['goal'] };
return { value: target.goal === base.goal ? source : target, conflicts: [] };
},
});
}Explicitly promote an approved candidate version
Extension · Node.js
The App calls this after real approval; promote still re-runs source, authorization, revision, and CAS checks.
ts
import type { AgentFamily } from '@jangts/agent-core/kits/family';
import type { OperationContext } from '@jangts/agent-core';
export async function activate<State, App>(family: AgentFamily<State, App>, id: string,
candidateId: string, context: OperationContext<App>) {
const record = await family.read(id, context);
return family.promote({ id, revision: record.revision, candidateId,
expectedActiveId: record.activeId }, context);
}js
export async function activate(family, id, candidateId, context) {
const record = await family.read(id, context);
return family.promote({ id, revision: record.revision, candidateId,
expectedActiveId: record.activeId }, context);
}