Derive method contract
The types come from packages/editor/src/core/derive.ts and core/derivation.ts and are exported from @skaile/forge-editor/core. For how to write a derive method, see Derive methods and the Derivation index.
DeriveMethod
One way to make a new block or text from a block. A Feature contributes methods in EditorFeature.deriveMethods; defineEditor merges them in feature order into preset.deriveMethods (DeriveRegistry).
| Field | Type | Meaning |
|---|---|---|
id | string | Unique across the preset. Also the id of the block action generated from the method. |
label | (ctx: FeatureContext) => string | Menu label, in the language of the surface (ctx.t). |
icon | string | Iconify name. |
ability | Ability? | Shown only on blocks that have this ability (BlockAction.ability). |
order | number? | Position among the block actions (BlockAction.order). |
placement | BlockAction['placement']? | Where the action shows. |
requires | readonly string[] | Capability ids the original must all have. Every id must be declared by a Feature (or built in) when the preset is defined. |
available | (ctx: DeriveContext) => boolean? | Backend flags and per-block conditions (ctx.ctx.backend.ai, a readable source). Absent: always available where requires holds. |
run | (ctx: DeriveContext) => void | Does the work and writes the result, and for a Derived block its Derivation. |
menu | (ctx: DeriveContext) => MenuItem[] | For a method with sub-choices (derive into one of several Block types). |
Exactly one of run and menu is set; defineEditor throws for neither or both, for a duplicate id and for a requires entry no Feature declares.
DeriveContext
| Field | Meaning |
|---|---|
editor | the editor |
node | the original block |
pos | the position right before node |
ctx | the FeatureContext of the surface (backend, public AI flags, settings, notices, translations) |
Registry and functions
| Export | Does |
|---|---|
DeriveRegistry | methods (feature order) and get(id) |
createDeriveRegistry(methods) | builds a registry |
deriveMethodsAt(editor, ctx, pos) | the methods that can run on the block at pos: the block has every capability the method requires, and available holds. Empty without a block there or without a preset. |
deriveActionsOf(preset, ctx) | one BlockAction per method, in the shape the block UI renders; requires, ability and available gate it. blockActionsOf includes them. |
Derivation
The record in meta.derivation of a Derived block. The original keeps nothing.
| Field | Type | Meaning |
|---|---|---|
from | { asset: string } | { block: string, document?: string } | The original: an uploaded asset by asset name, or a block by block ID. document is the Document the block lives in; absent = this Document. |
method | DerivationMethod | How it was made: 'transcription', 'pdf-text', 'ocr', 'description', 'bibliography', ai:<typeId> for a block derived by the model, or any string. |
model | string? | The model that made it. |
createdAt | string | ISO timestamp. |
inputHash | string | SHA-256 hex of the asset bytes or of the source block's Markdown; '' when unknown. |
outputHash | string | SHA-256 hex of the produced body's Markdown; '' when unknown. |
output | string? | Asset name of the stored raw output (text/markdown). |
inputs | Record<string, { from: DerivationSource, hash: string }>? | The named inputs of an N-to-1 Derivation (mixdown, a summary of several Blocks). from and inputHash then name the primary input, and inputHash is derivationFingerprint. |
activity | { id: string, agent?: string, at?: string }? | The run that produced the Block (an AI request, a job); agent is a model or tool id. |
DERIVATION_KEY is the meta key ('derivation'). derivationOf(node) reads a Derivation (null without one). derivedChildrenOf(parent) lists the direct children of parent that are Derived blocks, with their child index. isForeignSource(derivation, documentId) tells whether it points at a block of another Document.
Derivation index
derivationIndexOf(doc) builds the reverse index once per document version (memoised per doc node):
Member of DerivationIndex | Meaning |
|---|---|
derived | every Derived block with its position, in document order |
blockById(id) | { node, pos } of the block with block ID id (any depth), or null |
assetBlocks(name) | the AssetBlock[] ({ node, pos, holder }) that hold the stored asset name, in document order; holder is the position and size of the block around the asset block |
derivedFromBlock(id) | the Derived blocks whose Derivation points at block id, in this or any Document (isForeignSource tells them apart) |
derivedFromAsset(name) | the Derived blocks whose Derivation points at the stored asset name |
Functions on top of it:
| Function | Returns |
|---|---|
derivedOf(doc, originalPos, documentId?) | the DerivedEntry[] ({ node, pos, derivation }) made from the original at originalPos, in document order. They point at its block ID or at an asset the original holds as a direct child (its Source media). A Derived block moved out of the original still counts; Derivations from another Document are not listed. |
derivationOriginOf(doc, derivedPos, documentId?) | DerivationOrigin: { status: 'found', node, pos }, { status: 'missing' } (the original was deleted) or { status: 'foreign' } (another Document, not looked up); null when the node is no Derived block |
derivationState(doc, derivedPos, bodyHash, documentId?, foreignHash?, inputHashOf?) | DerivationState: source (the origin status), stale (an original changed since: an asset's stored hash against inputHash, a Block of another Document through foreignHash, each named input through inputHashOf(from); null for a block original in this Document, when unknown, and for inputs without inputHashOf) and edited (bodyHash() differs from outputHash; null when outputHash is unknown); null when the node is no Derived block |
derivedStateOf(state) | DerivedStateId ('fresh' | 'stale' | 'edited' | 'missing' | 'foreign'): the first that applies of missing, stale, edited, foreign (original in another Document, nothing known of it), else fresh |
derivationFingerprint({ method, inputs }) | SHA-256 hex of the method and the hash of every input by input name; independent of the order of the keys in inputs |