Skip to content
中文

FamilyStore ​

KIT · interface · Type contract

CAS must cover every writer and the active pointer in one real storage commit.

Import ​

ts
import type { FamilyStore } from '@jangts/agent-core/kits/family';
js
/** @typedef {import('@jangts/agent-core/kits/family').FamilyStore} FamilyStore */

Other public entry points:@jangts/agent-core/types, @jangts/agent-core/structs, @jangts/agent-core/kits, @jangts/agent-core/kits/family.

Definition ​

ts
interface FamilyStore<State>

Type parameters ​

Type parameterConstraintDefault type
State——

Field structure ​

FieldTypeRequiredDescription
load(id: string) => Promise<FamilyRecord<State> | undefined>RequiredReturns the record, or undefined when it does not exist.
compareAndSwap(id: string, expectedRevision: number | undefined, next: FamilyRecord<State>) => Promise<boolean>RequiredCommits next only when the stored revision equals expectedRevision; returns success.

Member index ​

MemberPurpose
loadReturns the record, or undefined when it does not exist.
compareAndSwapCommits next only when the stored revision equals expectedRevision; returns success.

Member details ​

load ​

Returns the record, or undefined when it does not exist.

ts
FamilyStore.load(id: string): Promise<FamilyRecord<State> | undefined>

Returns the record, or undefined when it does not exist.

ParameterTypePassingDescription
idstringRequired—

Returns: Promise<FamilyRecord<State> \| undefined>.

Awaited value: FamilyRecord<State> \| undefined.

Optional shapes of Return value: choose one shape; required fields for each branch are listed separately.

Branch 1

undefined

Branch 2
FieldTypeRequiredDescription
idstringRequiredRead-only. Family id; also the store key.
revisionnumberRequiredRead-only. Optimistic concurrency token; every accepted mutation increments it by one.
activeIdstringRequiredRead-only. Id of the active version; promotion moves this pointer.
expiresAtMsnumberRequiredRead-only. Instant after which the record is no longer retained, in epoch milliseconds.
versionsreadonly FamilyVersion<State>[]RequiredRead-only. Versions in creation order; bounded by maxVersions when configured.

compareAndSwap ​

Commits next only when the stored revision equals expectedRevision; returns success.

ts
FamilyStore.compareAndSwap(id: string, expectedRevision: number | undefined, next: FamilyRecord<State>): Promise<boolean>

Commits next only when the stored revision equals expectedRevision; returns success.

ParameterTypePassingDescription
idstringRequired—
expectedRevisionnumber | undefinedRequired—
nextFamilyRecord<State>Required—
Fields of next
FieldTypeRequiredDescription
idstringRequiredRead-only. Family id; also the store key.
revisionnumberRequiredRead-only. Optimistic concurrency token; every accepted mutation increments it by one.
activeIdstringRequiredRead-only. Id of the active version; promotion moves this pointer.
expiresAtMsnumberRequiredRead-only. Instant after which the record is no longer retained, in epoch milliseconds.
versionsreadonly FamilyVersion<State>[]RequiredRead-only. Versions in creation order; bounded by maxVersions when configured.

Returns: Promise<boolean>.

Awaited value: boolean.

Examples ​

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);
}

API reference, usage examples and developer guides.