API Reference
classes
Interpretationrun

@coasys/ad4m / Exports / InterpretationRun

Class: InterpretationRun

Base class for defining data models in AD4M.

Description

Ad4mModel provides the foundation for creating data models that are stored in AD4M perspectives. Each model instance is represented as a subgraph in the perspective, with properties and relations mapped to links in that graph. The class uses Prolog-based queries to efficiently search and filter instances based on their properties and relationships.

Key concepts:

  • Each model instance has a unique base expression that serves as its identifier
  • Properties are stored as links with predicates defined by the through option
  • Relations represent one-to-many relationships as sets of links
  • Queries are translated to Prolog for efficient graph pattern matching
  • Changes are tracked through the perspective's subscription system

Example

// Define a recipe model
@Model({ name: "Recipe" })
class Recipe extends Ad4mModel {
  // Plain property — no `resolveLanguage` → deterministic typed literal
  // storage (fast POS-index path). This is the perf default.
  @Property({ through: "recipe://name" })
  name: string = "";
 
  // Property that needs per-value provenance (e.g. a signed message body):
  // `resolveLanguage: "literal"` routes values through expression_create on
  // the built-in literal language, producing a signed envelope URI
  // (author/timestamp/proof) instead of a bare typed literal.
  @Property({
    through: "recipe://signed_note",
    resolveLanguage: "literal"
  })
  signedNote: string = "";
 
  // Property resolved through a custom language: values are routed through
  // expression_create on that language (signed expression URIs).
  @Optional({
    through: "recipe://photo",
    resolveLanguage: "QmFileStorageLanguageAddress..."
  })
  photo: string = "";
 
  // Optional property with custom initial value
  @Optional({
    through: "recipe://status",
    initial: "recipe://draft"
  })
  status: string = "";
 
  // Read-only computed property
  @ReadOnly({
    through: "recipe://rating",
    getter: `
      findall(Rating, triple(Base, "recipe://user_rating", Rating), Ratings),
      sum_list(Ratings, Sum),
      length(Ratings, Count),
      Value is Sum / Count
    `
  })
  averageRating: number = 0;
 
  // Relation of ingredients
  *   @HasMany({ through: "recipe://ingredient" })
  *   ingredients: string[] = [];
 
  // Relation of comments linked to another model
  @HasMany(() => Comment, { through: "recipe://comment" })
  comments: Comment[] = [];
}
 
// Create and save a new recipe
const recipe = new Recipe(perspective);
recipe.name = "Chocolate Cake";
recipe.ingredients = ["flour", "sugar", "cocoa"];
await recipe.save();
 
// Query recipes in different ways
// Get all recipes
const allRecipes = await Recipe.findAll(perspective);
 
// Find recipes with specific criteria
const desserts = await Recipe.findAll(perspective, {
  where: { 
    status: "recipe://published",
    averageRating: { gt: 4 }
  },
  order: { name: "ASC" },
  limit: 10
});
 
// Use the fluent query builder
const popularRecipes = await Recipe.query(perspective)
  .where({ averageRating: { gt: 4.5 } })
  .order({ averageRating: "DESC" })
  .limit(5)
  .get();
 
// Subscribe to real-time updates
await Recipe.query(perspective)
  .where({ status: "recipe://cooking" })
  .subscribe(recipes => {
    console.log("Currently being cooked:", recipes);
  });
 
// Paginate results
const { results, totalCount, pageNumber } = await Recipe.query(perspective)
  .where({ status: "recipe://published" })
  .paginate(10, 1);

Hierarchy

Table of contents

Constructors

Properties

Accessors

Methods

Constructors

constructor

• new InterpretationRun(perspective, baseExpression?)

Constructs a new model instance.

Parameters

NameTypeDescription
perspectivePerspectiveProxyThe perspective where this model will be stored
baseExpression?stringOptional expression URI for this instance. If omitted, a random ad4m://obj/<id> IRI is generated, independent of any property content — this is what keeps two instances with identical property values distinct.

Example

// Create a new recipe with auto-generated base expression
const recipe = new Recipe(perspective);
 
// Create with specific base expression
const recipe = new Recipe(perspective, "ad4m://obj/existing-id");

Inherited from

Ad4mModel.constructor

Defined in

core/src/model/Ad4mModel.ts:721 (opens in a new tab)

Properties

__links

• Optional __links: LinksMap

Per-link rows for the entries asked for with Query.links, keyed as they were asked. Absent when the query did not ask for any.

Inherited from

Ad4mModel.__links

Defined in

core/src/model/Ad4mModel.ts:499 (opens in a new tab)


author

• author: string

Inherited from

Ad4mModel.author

Defined in

core/src/model/Ad4mModel.ts:492 (opens in a new tab)


createdAt

• createdAt: any

Inherited from

Ad4mModel.createdAt

Defined in

core/src/model/Ad4mModel.ts:493 (opens in a new tab)


debugPrompt

• Optional debugPrompt: string

Raw LLM prompt this pass fed the model. Present only when the pass's AutoProcessor had emitDebugEvents: true. Absent by default.

Defined in

core/src/perspectives/InterpretationModels.ts:182 (opens in a new tab)


debugResponse

• Optional debugResponse: string

Raw LLM response this pass received. Same rules as debugPrompt.

Defined in

core/src/perspectives/InterpretationModels.ts:186 (opens in a new tab)


model

• Optional model: string

LLM model id used for this run.

Defined in

core/src/perspectives/InterpretationModels.ts:155 (opens in a new tab)


processor

• Optional processor: string

URI of the AutoProcessorConfig node that triggered this run.

Defined in

core/src/perspectives/InterpretationModels.ts:167 (opens in a new tab)


promptVersion

• Optional promptVersion: string

SHA-256 hex of the system prompt + few-shots at the time of the run.

Defined in

core/src/perspectives/InterpretationModels.ts:159 (opens in a new tab)


ranAt

• Optional ranAt: string

RFC3339 timestamp when the run completed.

Defined in

core/src/perspectives/InterpretationModels.ts:163 (opens in a new tab)


runId

• runId: string = ""

UUID for this run — the dedup key across run nodes.

Defined in

core/src/perspectives/InterpretationModels.ts:151 (opens in a new tab)


sources

• sources: string[] = []

Source item IDs consumed by this pass. Stored as multiple links with the same predicate; the processed-turn cursor uses these to avoid re-interpreting a turn. Values are plain strings (turn hex), so the property opts into sh:datatype-gated literal decoding on hydration.

Defined in

core/src/perspectives/InterpretationModels.ts:177 (opens in a new tab)


updatedAt

• updatedAt: any

Inherited from

Ad4mModel.updatedAt

Defined in

core/src/model/Ad4mModel.ts:494 (opens in a new tab)

Accessors

id

• get id(): string

The unique identifier (expression URI) of this model instance.

Returns

string

Inherited from

Ad4mModel.id

Defined in

core/src/model/Ad4mModel.ts:738 (opens in a new tab)


perspective

• Protected get perspective(): PerspectiveProxy

Protected getter for the perspective. Allows subclasses to access the perspective while keeping it private from external code.

Returns

PerspectiveProxy

Inherited from

Ad4mModel.perspective

Defined in

core/src/model/Ad4mModel.ts:746 (opens in a new tab)


timestamp

• get timestamp(): any

Backwards compatibility alias for createdAt.

Returns

any

Deprecated

Use createdAt instead. This will be removed in a future version.

Inherited from

Ad4mModel.timestamp

Defined in

core/src/model/Ad4mModel.ts:505 (opens in a new tab)

Methods

changedFields

▸ changedFields(): string[]

Returns the names of properties/relations that differ from the snapshot taken at the last hydration.

Returns all field names if no snapshot exists.

Returns

string[]

Example

recipe.name = "New Name";
recipe.changedFields(); // ["name"]

Inherited from

Ad4mModel.changedFields

Defined in

core/src/model/Ad4mModel.ts:927 (opens in a new tab)


delete

▸ delete(batchId?): Promise<void>

Deletes the model instance from the perspective.

Parameters

NameTypeDescription
batchId?stringOptional batch ID for batch operations

Returns

Promise<void>

Throws

Will throw if removal fails

Example

const recipe = await Recipe.findAll(perspective)[0];
await recipe.delete();
 
// Or with batch operations:
const batchId = await perspective.createBatch();
await recipe.delete(batchId);
await perspective.commitBatch(batchId);

Inherited from

Ad4mModel.delete

Defined in

core/src/model/Ad4mModel.ts:1870 (opens in a new tab)


get

▸ get(optsOrInclude?): Promise<InterpretationRun>

Gets the model instance with all properties and relations populated.

Parameters

NameTypeDescription
optsOrInclude?IncludeMap | GetOptionsOptional hydration options. Accepts two forms: - GetOptions wrapper: { include: { comments: true }, properties: ['title'] } - IncludeMap shorthand: { comments: true } (equivalent to { include: { comments: true } })

Returns

Promise<InterpretationRun>

The populated model instance

Throws

Will throw if data retrieval fails

Example

const recipe = new Recipe(perspective, existingId);
await recipe.get();
console.log(recipe.name, recipe.ingredients);
 
// Shorthand — pass IncludeMap directly:
await recipe.get({ ingredients: true });
 
// Full options — includes sparse fieldset:
await recipe.get({ include: { ingredients: true }, properties: ['name'] });

Inherited from

Ad4mModel.get

Defined in

core/src/model/Ad4mModel.ts:1838 (opens in a new tab)


isDirty

▸ isDirty(): boolean

Returns true if any tracked property or relation has changed since the last hydration (or since takeSnapshot() was last called).

Always returns true if no snapshot exists (e.g. a freshly constructed instance that hasn't been fetched yet).

Returns

boolean

Example

const recipe = await Recipe.create(perspective, { name: "Pasta" });
recipe.isDirty();        // false — just hydrated
recipe.name = "Risotto";
recipe.isDirty();        // true

Inherited from

Ad4mModel.isDirty

Defined in

core/src/model/Ad4mModel.ts:910 (opens in a new tab)


save

▸ save(batchId?): Promise<void>

Saves the model instance to the perspective.

New instances (no snapshot yet): creates the subject via createSubject with initial scalar values, then sets relations via innerUpdate.

Existing instances (snapshot present, i.e. fetched via get() or a query): updates only dirty fields via innerUpdate, then refreshes from the perspective.

Parameters

NameTypeDescription
batchId?stringOptional batch ID for batch operations

Returns

Promise<void>

Throws

Will throw if instance creation, linking, or updating fails

Example

// Create
const recipe = new Recipe(perspective);
recipe.name = "Spaghetti";
await recipe.save();
 
// Update
recipe.rating = 10;
await recipe.save();

Inherited from

Ad4mModel.save

Defined in

core/src/model/Ad4mModel.ts:1528 (opens in a new tab)


count

▸ Static count<T>(this, perspective, query?, options?): Promise<number>

Gets a count of all matching instances.

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to search in
query?TypedQuery<T>Optional query parameters to filter results
options?CallOptions-

Returns

Promise<number>

Total count of matching entities

Example

const totalRecipes = await Recipe.count(perspective);
const activeRecipes = await Recipe.count(perspective, {
  where: { status: "active" }
});

Inherited from

Ad4mModel.count

Defined in

core/src/model/Ad4mModel.ts:1384 (opens in a new tab)


create

▸ Static create<T>(this, perspective, data?, options?): Promise<T>

Creates and saves a new model instance in one step.

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to create the instance in
dataRecord<string, any>Property values to assign before saving
options?ObjectOptional settings: - parent — a Scope (model form or raw form) whose id will be used to create an incoming link from the parent to the new instance. - batchId — an existing batch id; when provided the link write and save() are added to the batch instead of committed immediately.
options.batchId?string-
options.parent?Scope-

Returns

Promise<T>

The saved model instance

Example

// Simple create
const recipe = await Recipe.create(perspective, {
  name: "Spaghetti",
  rating: 5,
});
 
// Create under a parent (link auto-created)
const comment = await Comment.create(perspective, { text: "Great!" }, {
  parent: { model: Post, id: postId },
});
 
// Create inside a transaction
await Ad4mModel.transaction(perspective, async (tx) => {
  await Recipe.create(perspective, { name: "Pasta" }, { batchId: tx.batchId });
});

Inherited from

Ad4mModel.create

Defined in

core/src/model/Ad4mModel.ts:1960 (opens in a new tab)


delete

▸ Static delete(this, perspective, id): Promise<void>

Deletes an existing model instance identified by id.

Also cleans up any incoming links that point to this instance.

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => Ad4mModel-
perspectivePerspectiveProxyThe perspective containing the instance
idstringThe expression URI of the instance to delete

Returns

Promise<void>

Example

await Recipe.delete(perspective, recipeId);

Inherited from

Ad4mModel.delete

Defined in

core/src/model/Ad4mModel.ts:2075 (opens in a new tab)


evaluateGetters

▸ Static evaluateGetters<T>(instances, perspective, propertyNames?): Promise<void>

Evaluate SPARQL getters for a batch of instances on demand.

Since deepQuery defaults to true, property getters are evaluated automatically during collection queries. Use this method when deepQuery was explicitly set to false and you want to lazily resolve getter-backed properties for a subset of instances.

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDescription
instancesT[]Array of model instances to evaluate getters on
perspectivePerspectiveProxyThe perspective to query against
propertyNames?string[]Optional list of getter-backed property names to evaluate. If omitted, all getters are evaluated.

Returns

Promise<void>

Example

const messages = await Message.query(perspective).deepQuery(false).limit(30).get();
// messages[i].replyingTo is undefined (getter skipped)
 
// Evaluate getters for the visible subset
await Message.evaluateGetters(messages.slice(0, 10), perspective, ['replyingTo']);
// messages[0..9].replyingTo is now populated

Inherited from

Ad4mModel.evaluateGetters

Defined in

core/src/model/Ad4mModel.ts:1760 (opens in a new tab)


findAll

▸ Static findAll<T, Q>(this, perspective, query?, options?): Promise<T & IncludeExtras<T, IncludeOf<Q>>[]>

Gets all instances of the model in the perspective that match the query params.

Type parameters

NameType
Textends Ad4mModel<T>
Qextends Query | StrictTypedQuery<T> = {}

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to search in
query?QOptional query parameters to filter results
options?CallOptions-

Returns

Promise<T & IncludeExtras<T, IncludeOf<Q>>[]>

Array of matching models

Example

const allRecipes = await Recipe.findAll(perspective);
 
const recipes = await Recipe.findAll(perspective, {
  where: {
    name: "Pasta",
    rating: { gt: 4 }
  },
  order: { createdAt: "DESC" },
  limit: 10
});

Inherited from

Ad4mModel.findAll

Defined in

core/src/model/Ad4mModel.ts:1255 (opens in a new tab)


findAllAndCount

▸ Static findAllAndCount<T, Q>(this, perspective, query?, options?): Promise<ResultsWithTotalCount<T & IncludeExtras<T, IncludeOf<Q>>>>

Gets all instances with count of total matches without offset & limit applied.

Type parameters

NameType
Textends Ad4mModel<T>
Qextends Query | StrictTypedQuery<T> = {}

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to search in
query?QOptional query parameters to filter results
options?CallOptions-

Returns

Promise<ResultsWithTotalCount<T & IncludeExtras<T, IncludeOf<Q>>>>

Object containing results array and total count

Example

const { results, totalCount } = await Recipe.findAllAndCount(perspective, {
  where: { category: "Dessert" },
  limit: 10
});
console.log(`Showing 10 of ${totalCount} dessert recipes`);

Inherited from

Ad4mModel.findAllAndCount

Defined in

core/src/model/Ad4mModel.ts:1318 (opens in a new tab)


findOne

▸ Static findOne<T, Q>(this, perspective, query?, options?): Promise<T & IncludeExtras<T, IncludeOf<Q>>>

Finds the first instance matching the query, or null if none exists.

Equivalent to findAll with limit: 1 — only one instance is hydrated.

Type parameters

NameType
Textends Ad4mModel<T>
Qextends Query | StrictTypedQuery<T> = {}

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to search in
query?QOptional query parameters to filter results
options?CallOptions-

Returns

Promise<T & IncludeExtras<T, IncludeOf<Q>>>

The first matching instance, or null

Example

const recipe = await Recipe.findOne(perspective, {
  where: { name: "Pasta" }
});
if (recipe) {
  console.log(recipe.name);
}

Inherited from

Ad4mModel.findOne

Defined in

core/src/model/Ad4mModel.ts:1290 (opens in a new tab)


fromJSONSchema

▸ Static fromJSONSchema(schema, options): typeof Ad4mModel

Creates an Ad4mModel class from a JSON Schema definition.

Parameters

NameTypeDescription
schemaJSONSchemaJSON Schema definition
optionsJSONSchemaToModelOptionsConfiguration options

Returns

typeof Ad4mModel

Generated Ad4mModel subclass

Description

This method dynamically generates an Ad4mModel subclass from a JSON Schema, enabling integration with systems that use JSON Schema for type definitions.

The method follows a cascading approach for determining predicates:

  1. Explicit configuration in options parameter (highest precedence)
  2. x-ad4m metadata in the JSON Schema
  3. Inference from schema title and property names
  4. Error if no namespace can be determined

Example

// With explicit configuration
const PersonClass = Ad4mModel.fromJSONSchema(schema, {
  name: "Person",
  namespace: "person://"
});
 
// With property mapping
const ContactClass = Ad4mModel.fromJSONSchema(schema, {
  name: "Contact",
  namespace: "contact://",
  propertyMapping: {
    "name": "foaf://name",
    "email": "foaf://mbox"
  }
});
 
// With x-ad4m metadata in schema
const schema = {
  "title": "Product",
  "x-ad4m": { "namespace": "product://" },
  "properties": {
    "name": { 
      "type": "string",
      "x-ad4m": { "through": "product://title" }
    }
  }
};
const ProductClass = Ad4mModel.fromJSONSchema(schema, { name: "Product" });

Throws

Error when namespace cannot be inferred

Inherited from

Ad4mModel.fromJSONSchema

Defined in

core/src/model/Ad4mModel.ts:2244 (opens in a new tab)


fromSHACL

▸ Static fromSHACL(shape, name, classResolver?): typeof Ad4mModel

Synthesise an Ad4mModel subclass from a SHACL shape.

Parameters

NameTypeDescription
shapeSHACLShapeThe SHACL shape to synthesise from.
namestringThe model name (e.g. "Channel").
classResolver?(localName: string) => typeof Ad4mModelOptional thunk factory. When provided, any collection property that carries a sh:class URI will have its target wired up lazily: target: () => classResolver(localName). Because target is only called at query time (inside enrichShapeForIncludes / jsonToModelInstance), the resolver just needs to return the correct class by the time a query runs — making it safe to pass a closure over a registry object that is still being populated (e.g. the result record inside getModelClasses).

Returns

typeof Ad4mModel

Inherited from

Ad4mModel.fromSHACL

Defined in

core/src/model/Ad4mModel.ts:2288 (opens in a new tab)


generateSDNA

▸ Static generateSDNA(): Object

Generates the SDNA (Subject DNA) Prolog rules for this model class. Injected at class-definition time by the @Model decorator. Returns a default value on un-decorated base classes.

Returns

Object

NameType
namestring
sdnastring

Inherited from

Ad4mModel.generateSDNA

Defined in

core/src/model/Ad4mModel.ts:516 (opens in a new tab)


generateSHACL

▸ Static generateSHACL(): Object

Generates the SHACL shape graph for this model class. Injected at class-definition time by the @Model decorator. Returns { shape: null, name: '' } on un-decorated base classes — the decorator's parentSHACL?.shape?.nodeShapeUri check handles this.

Returns

Object

NameType
namestring
shapeany

Inherited from

Ad4mModel.generateSHACL

Defined in

core/src/model/Ad4mModel.ts:526 (opens in a new tab)


getClassName

▸ Static getClassName(perspective): Promise<string>

Parameters

NameType
perspectivePerspectiveProxy

Returns

Promise<string>

Inherited from

Ad4mModel.getClassName

Defined in

core/src/model/Ad4mModel.ts:530 (opens in a new tab)


getModelMetadata

▸ Static getModelMetadata(): ModelMetadata

Extracts metadata from decorators for query building.

Returns

ModelMetadata

Structured metadata object containing className, properties, and relations

Description

This method reads the metadata stored by decorators (@Property, @HasMany, etc.) and returns it in a structured format that's easier to work with for query builders and other systems that need to introspect model structure.

The metadata includes:

  • Class name from

Model

  • Property metadata (predicates, types, constraints, etc.)
  • Relation metadata (predicates, filters, etc.)

For models created via fromJSONSchema(), this method will derive metadata from the WeakMap registries that were populated during the dynamic class creation. If these structures are empty but a JSON schema was attached to the class, it can fall back to deriving metadata from that schema.

Throws

Error if the class doesn't have

Model

decorator

Example

@Model({ name: "Recipe" })
class Recipe extends Ad4mModel {
  @Property({ through: "recipe://name" })
  name: string = "";
 
  @HasMany({ through: "recipe://ingredient" })
  ingredients: string[] = [];
}
 
const metadata = Recipe.getModelMetadata();
console.log(metadata.className); // "Recipe"
console.log(metadata.properties.name.predicate); // "recipe://name"
console.log(metadata.relations.ingredients.predicate); // "recipe://ingredient"

Inherited from

Ad4mModel.getModelMetadata

Defined in

core/src/model/Ad4mModel.ts:593 (opens in a new tab)


paginate

▸ Static paginate<T, Q>(this, perspective, pageSize, pageNumber, query?, options?): Promise<PaginationResult<T & IncludeExtras<T, IncludeOf<Q>>>>

Helper function for pagination with explicit page size and number.

Type parameters

NameType
Textends Ad4mModel<T>
Qextends Query | StrictTypedQuery<T> = {}

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to search in
pageSizenumberNumber of items per page
pageNumbernumberWhich page to retrieve (1-based)
query?QOptional additional query parameters
options?CallOptions-

Returns

Promise<PaginationResult<T & IncludeExtras<T, IncludeOf<Q>>>>

Paginated results with metadata

Example

const page = await Recipe.paginate(perspective, 10, 1, {
  where: { category: "Main Course" }
});
console.log(`Page ${page.pageNumber} of recipes, ${page.results.length} items`);

Inherited from

Ad4mModel.paginate

Defined in

core/src/model/Ad4mModel.ts:1345 (opens in a new tab)


query

▸ Static query<T>(this, perspective, query?): ModelQueryBuilder<T>

Creates a query builder for fluent query construction.

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective to query
query?TypedQuery<T>Optional initial query parameters

Returns

ModelQueryBuilder<T>

A new query builder instance

Example

const recipes = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .order({ rating: "DESC" })
  .limit(5)
  .run();
 
// With real-time updates
await Recipe.query(perspective)
  .where({ status: "cooking" })
  .subscribe(recipes => {
    console.log("Currently cooking:", recipes);
  });

Inherited from

Ad4mModel.query

Defined in

core/src/model/Ad4mModel.ts:2186 (opens in a new tab)


queryToSPARQL

▸ Static queryToSPARQL(perspective, query): Promise<string>

Generates a SPARQL query from a Query object.

Parameters

NameTypeDescription
perspectivePerspectiveProxyThe perspective to query (used for metadata extraction)
queryQueryQuery parameters (where, order, limit, offset, properties, relations)

Returns

Promise<string>

Complete SPARQL query string ready for execution

Description

This method translates high-level query parameters into a SPARQL query string that can be executed against the SPARQL backend. Unlike Prolog queries which operate on SDNA-aware predicates, SPARQL queries operate directly on raw links stored in SPARQL.

The generated query uses a CTE (Common Table Expression) pattern:

  1. First, identify candidate base expressions by filtering links based on where conditions
  2. Then, for each candidate base, resolve properties and relations via subqueries
  3. Finally, apply ordering, pagination (LIMIT/START) at the SQL level

Key architectural notes:

  • SPARQL stores only raw links (source, predicate, target, author, timestamp)
  • No SDNA knowledge at the database level
  • Properties are resolved via subqueries that look for links with specific predicates
  • Relations are similar but return multiple values instead of one
  • Special fields (base, author, timestamp) are accessed directly, not via subqueries

Example

const query = Recipe.queryToSPARQL(perspective, {
  where: { name: "Pasta", rating: { gt: 4 } },
  order: { timestamp: "DESC" },
  limit: 10
});
// Returns: SELECT source AS base, array::first(target[WHERE predicate = ...]) AS name, ...
//          FROM link WHERE ... GROUP BY source ORDER BY timestamp DESC LIMIT 10

Inherited from

Ad4mModel.queryToSPARQL

Defined in

core/src/model/Ad4mModel.ts:1065 (opens in a new tab)


register

▸ Static register(this, perspective): Promise<void>

Registers this model's SHACL schema on the given perspective.

This ensures the perspective knows about the model's shape (properties, relations, constraints) so instances can be created, queried, and validated.

Parameters

NameTypeDescription
thistypeof Ad4mModel-
perspectivePerspectiveProxyThe perspective to register the model on

Returns

Promise<void>

Example

await Recipe.register(perspective);
// Now you can create / query Recipe instances on this perspective

Inherited from

Ad4mModel.register

Defined in

core/src/model/Ad4mModel.ts:2099 (opens in a new tab)


registerAll

▸ Static registerAll(perspective, models): Promise<void>

Batch-registers multiple model classes on a perspective in a single RPC call. This is significantly faster than calling register() on each model individually because it eliminates N-1 round-trips and mutex acquisitions.

Parameters

NameTypeDescription
perspectivePerspectiveProxyThe perspective to register the models on
modelstypeof Ad4mModel[]Array of Ad4mModel subclasses to register

Returns

Promise<void>

Example

await Ad4mModel.registerAll(perspective, [Community, Channel, Message, Task]);

Inherited from

Ad4mModel.registerAll

Defined in

core/src/model/Ad4mModel.ts:2119 (opens in a new tab)


remove

▸ Static remove(this, perspective, id): Promise<void>

Deletes an existing model instance identified by id.

Also cleans up any incoming links that point to this instance.

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => Ad4mModel-
perspectivePerspectiveProxyThe perspective containing the instance
idstringThe expression URI of the instance to delete

Returns

Promise<void>

Example

await Recipe.delete(perspective, recipeId);

Deprecated

Use the name delete — remove is preserved as an alias.

Inherited from

Ad4mModel.remove

Defined in

core/src/model/Ad4mModel.ts:2054 (opens in a new tab)


transaction

▸ Static transaction<R>(perspective, fn): Promise<R>

Executes a set of model operations inside a single batch (transaction).

All save, update, and delete calls made via the provided batchId are buffered and flushed atomically when the callback completes. If the callback throws, the batch is not committed, preventing partial writes.

Type parameters

NameType
Rvoid

Parameters

NameTypeDescription
perspectivePerspectiveProxyThe perspective to operate on
fn(tx: { batchId: string }) => Promise<R>Async callback that receives a TransactionContext object. Pass tx.batchId to save(tx.batchId), update(tx.batchId), delete(tx.batchId), etc.

Returns

Promise<R>

The value returned by fn

Example

await Ad4mModel.transaction(perspective, async (tx) => {
  const recipe = new Recipe(perspective);
  recipe.name = "Spaghetti";
  await recipe.save(tx.batchId);
 
  const old = await Recipe.query(perspective).where({ name: "Stale" }).run();
  for (const r of old) await r.delete(tx.batchId);
});
// All changes committed atomically here

Inherited from

Ad4mModel.transaction

Defined in

core/src/model/Ad4mModel.ts:2153 (opens in a new tab)


update

▸ Static update<T>(this, perspective, id, data): Promise<T>

Updates an existing model instance identified by id.

Fetches the instance, applies the provided changes, calls save(), and returns the refreshed instance.

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDescription
thistypeof Ad4mModel & (...args: any[]) => T-
perspectivePerspectiveProxyThe perspective containing the instance
idstringThe expression URI of the instance to update
dataRecord<string, any>Property values to merge before saving

Returns

Promise<T>

The updated model instance

Example

const recipe = await Recipe.update(perspective, recipeId, {
  rating: 10,
});

Inherited from

Ad4mModel.update

Defined in

core/src/model/Ad4mModel.ts:2026 (opens in a new tab)