API Reference
classes
Ad4mmodel

@coasys/ad4m / Exports / Ad4mModel

Class: Ad4mModel

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 {
  // Required property with literal value
  @Property({
    through: "recipe://name",
    resolveLanguage: "literal"
  })
  name: 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);

Table of contents

Constructors

Properties

Accessors

Methods

Constructors

constructor

new Ad4mModel(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 Literal URL is generated.

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, "literal://...");

Defined in

model/Ad4mModel.ts:347 (opens in a new tab)

Properties

_baseExpression

Private _baseExpression: string

Defined in

model/Ad4mModel.ts:124 (opens in a new tab)


_perspective

Private _perspective: PerspectiveProxy

Defined in

model/Ad4mModel.ts:125 (opens in a new tab)


_snapshot

Private _snapshot: Record<string, any> = null

Defined in

model/Ad4mModel.ts:126 (opens in a new tab)


author

author: string

Defined in

model/Ad4mModel.ts:127 (opens in a new tab)


createdAt

createdAt: any

Defined in

model/Ad4mModel.ts:128 (opens in a new tab)


updatedAt

updatedAt: any

Defined in

model/Ad4mModel.ts:129 (opens in a new tab)


classNamesByClass

Static Private classNamesByClass: WeakMap<typeof Ad4mModel, { [perspectiveId: string]: string; }>

Defined in

model/Ad4mModel.ts:131 (opens in a new tab)

Accessors

baseExpression

get baseExpression(): string

Returns

string

Deprecated

Use .id instead. Will be removed in a future version.

Defined in

model/Ad4mModel.ts:362 (opens in a new tab)


id

get id(): string

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

Returns

string

Defined in

model/Ad4mModel.ts:355 (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

Defined in

model/Ad4mModel.ts:370 (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.

Defined in

model/Ad4mModel.ts:181 (opens in a new tab)

Methods

addRelationValue

Private addRelationValue(key, value, batchId?): Promise<void>

Parameters

NameType
keystring
valueany
batchId?string

Returns

Promise<void>

Defined in

model/Ad4mModel.ts:1296 (opens in a new tab)


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"]

Defined in

model/Ad4mModel.ts:558 (opens in a new tab)


cleanCopy

Private cleanCopy(): Record<string, any>

Returns

Record<string, any>

Defined in

model/Ad4mModel.ts:1467 (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);

Defined in

model/Ad4mModel.ts:1622 (opens in a new tab)


generatePropertySetterAction

Private generatePropertySetterAction(key, metadata): any[]

Generate property setter action from metadata.

Parameters

NameType
keystring
metadataPropertyMetadataEntry

Returns

any[]

Defined in

model/Ad4mModel.ts:398 (opens in a new tab)


generateRelationAction

Private generateRelationAction(key, actionType): any[]

Generate relation action from metadata.

Parameters

NameType
keystring
actionType"setter" | "adder" | "remover"

Returns

any[]

Defined in

model/Ad4mModel.ts:437 (opens in a new tab)


get

get(optsOrInclude?): Promise<Ad4mModel>

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<Ad4mModel>

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

Defined in

model/Ad4mModel.ts:1590 (opens in a new tab)


getData

Private getData(opts?): Promise<Ad4mModel>

Parameters

NameType
opts?GetOptions

Returns

Promise<Ad4mModel>

Defined in

model/Ad4mModel.ts:602 (opens in a new tab)


getPropertyMetadata

Private getPropertyMetadata(key): PropertyMetadataEntry

Get property metadata from decorator.

Parameters

NameType
keystring

Returns

PropertyMetadataEntry

Defined in

model/Ad4mModel.ts:378 (opens in a new tab)


getRelationOptions

Private getRelationOptions(key): RelationMetadataEntry

Get relation options from decorator

Parameters

NameType
keystring

Returns

RelationMetadataEntry

Defined in

model/Ad4mModel.ts:388 (opens in a new tab)


innerUpdate

Private innerUpdate(setProperties?, batchId?): Promise<void>

Parameters

NameTypeDefault value
setPropertiesbooleantrue
batchId?stringundefined

Returns

Promise<void>

Defined in

model/Ad4mModel.ts:1489 (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

Defined in

model/Ad4mModel.ts:541 (opens in a new tab)


removeRelationValue

Private removeRelationValue(key, value, batchId?): Promise<void>

Parameters

NameType
keystring
valueany
batchId?string

Returns

Promise<void>

Defined in

model/Ad4mModel.ts:1319 (opens in a new tab)


resolveRelationId

Private resolveRelationId(value): string

Resolve a relation argument to a plain string ID. Accepts either a raw string ID or an Ad4mModel instance (in which case .id is used).

Parameters

NameType
valueany

Returns

string

Defined in

model/Ad4mModel.ts:1266 (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();

Defined in

model/Ad4mModel.ts:1368 (opens in a new tab)


setProperty

Private setProperty(key, value, batchId?): Promise<void>

Parameters

NameType
keystring
valueany
batchId?string

Returns

Promise<void>

Defined in

model/Ad4mModel.ts:1239 (opens in a new tab)


setRelationValues

Private setRelationValues(key, value, batchId?): Promise<void>

Parameters

NameType
keystring
valueany
batchId?string

Returns

Promise<void>

Defined in

model/Ad4mModel.ts:1272 (opens in a new tab)


takeSnapshot

Private takeSnapshot(includedRelations?): void

Parameters

NameTypeDescription
includedRelations?Record<string, any>Controls which relation fields are recorded in the snapshot for dirty-tracking: • undefined (default) — snapshot ALL relations (used by .get(), .create(), .save() etc. where full hydration has occurred). • IncludeMap object (e.g. { views: true }) — only snapshot the relations named in the map. Fields not listed are omitted from the snapshot so that changedFields() ignores them. • null / empty object — skip ALL relations (used by bare subscriptions that don't eagerly load relations).

Returns

void

Defined in

model/Ad4mModel.ts:485 (opens in a new tab)


assignValuesToInstance

Static assignValuesToInstance(perspective, instance, values): Promise<void>

Assigns decoded Prolog property values to an instance. Delegates to the standalone function in hydration.ts.

Parameters

NameType
perspectivePerspectiveProxy
instanceAd4mModel
valuesValueTuple[]

Returns

Promise<void>

Defined in

model/Ad4mModel.ts:466 (opens in a new tab)


count

Static count(perspective, query?, useSurrealDB?): any

Gets a count of all matching instances.

Parameters

NameTypeDefault valueDescription
perspectivePerspectiveProxyundefinedThe perspective to search in
queryQuery{}Optional query parameters to filter results
useSurrealDBbooleantrueWhether to use SurrealDB (default: true, 10-100x faster) or Prolog (legacy)

Returns

any

Total count of matching entities

Example

const totalRecipes = await Recipe.count(perspective);
const activeRecipes = await Recipe.count(perspective, {
  where: { status: "active" }
});
 
// Use Prolog explicitly (legacy)
const countProlog = await Recipe.count(perspective, {}, false);

Defined in

model/Ad4mModel.ts:1224 (opens in a new tab)


countQueryToProlog

Static countQueryToProlog(perspective, query?, modelClassName?): Promise<string>

Parameters

NameType
perspectivePerspectiveProxy
queryQuery
modelClassName?string

Returns

Promise<string>

Defined in

model/Ad4mModel.ts:1166 (opens in a new tab)


countQueryToSurrealQL

Static Private countQueryToSurrealQL(perspective, query): Promise<string>

Generates a SurrealQL COUNT query for the model.

Parameters

NameTypeDescription
perspectivePerspectiveProxyThe perspective context
queryQueryQuery parameters to filter the count

Returns

Promise<string>

SurrealQL COUNT query string

Defined in

model/Ad4mModel.ts:1196 (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 ParentScope (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?ParentScope-

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

Defined in

model/Ad4mModel.ts:1712 (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);

Defined in

model/Ad4mModel.ts:1825 (opens in a new tab)


findAll

Static findAll<T>(this, perspective, query?, useSurrealDB?): Promise<T[]>

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

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDefault valueDescription
thistypeof Ad4mModel & (...args: any[]) => Tundefined-
perspectivePerspectiveProxyundefinedThe perspective to search in
queryQuery{}Optional query parameters to filter results
useSurrealDBbooleantrueWhether to use SurrealDB (default: true, 10-100x faster) or Prolog (legacy)

Returns

Promise<T[]>

Array of matching models

Example

// Get all recipes (uses SurrealDB by default)
const allRecipes = await Recipe.findAll(perspective);
 
// Get recipes with specific criteria (uses SurrealDB)
const recipes = await Recipe.findAll(perspective, {
  where: { 
    name: "Pasta",
    rating: { gt: 4 }
  },
  order: { createdAt: "DESC" },
  limit: 10
});
 
// Explicitly use Prolog (legacy, for backward compatibility)
const recipesProlog = await Recipe.findAll(perspective, {}, false);

Defined in

model/Ad4mModel.ts:1033 (opens in a new tab)


findAllAndCount

Static findAllAndCount<T>(this, perspective, query?, useSurrealDB?): Promise<ResultsWithTotalCount<T>>

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

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDefault valueDescription
thistypeof Ad4mModel & (...args: any[]) => Tundefined-
perspectivePerspectiveProxyundefinedThe perspective to search in
queryQuery{}Optional query parameters to filter results
useSurrealDBbooleantrueWhether to use SurrealDB (default: true, 10-100x faster) or Prolog (legacy)

Returns

Promise<ResultsWithTotalCount<T>>

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`);
 
// Use Prolog explicitly (legacy)
const { results, totalCount } = await Recipe.findAllAndCount(perspective, {}, false);

Defined in

model/Ad4mModel.ts:1106 (opens in a new tab)


findOne

Static findOne<T>(this, perspective, query?, useSurrealDB?): Promise<T>

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>

Parameters

NameTypeDefault valueDescription
thistypeof Ad4mModel & (...args: any[]) => Tundefined-
perspectivePerspectiveProxyundefinedThe perspective to search in
queryQuery{}Optional query parameters to filter results
useSurrealDBbooleantrueWhether to use SurrealDB (default: true) or Prolog (legacy)

Returns

Promise<T>

The first matching instance, or null

Example

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

Defined in

model/Ad4mModel.ts:1075 (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://",
  resolveLanguage: "literal"
});
 
// 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

Defined in

model/Ad4mModel.ts:1975 (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

Defined in

model/Ad4mModel.ts:138 (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

Defined in

model/Ad4mModel.ts:148 (opens in a new tab)


getClassName

Static getClassName(perspective): Promise<string>

Parameters

NameType
perspectivePerspectiveProxy

Returns

Promise<string>

Defined in

model/Ad4mModel.ts:152 (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", resolveLanguage: "literal" })
  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"

Defined in

model/Ad4mModel.ts:223 (opens in a new tab)


instancesFromPrologResult

Static instancesFromPrologResult<T>(this, perspective, query, result): Promise<ResultsWithTotalCount<T>>

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameType
thistypeof Ad4mModel & (...args: any[]) => T
perspectivePerspectiveProxy
queryQuery
resultAllInstancesResult

Returns

Promise<ResultsWithTotalCount<T>>

Defined in

model/Ad4mModel.ts:734 (opens in a new tab)


paginate

Static paginate<T>(this, perspective, pageSize, pageNumber, query?, useSurrealDB?): Promise<PaginationResult<T>>

Helper function for pagination with explicit page size and number.

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameTypeDefault valueDescription
thistypeof Ad4mModel & (...args: any[]) => Tundefined-
perspectivePerspectiveProxyundefinedThe perspective to search in
pageSizenumberundefinedNumber of items per page
pageNumbernumberundefinedWhich page to retrieve (1-based)
query?QueryundefinedOptional additional query parameters
useSurrealDBbooleantrueWhether to use SurrealDB (default: true, 10-100x faster) or Prolog (legacy)

Returns

Promise<PaginationResult<T>>

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`);
 
// Use Prolog explicitly (legacy)
const pageProlog = await Recipe.paginate(perspective, 10, 1, {}, false);

Defined in

model/Ad4mModel.ts:1144 (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?QueryOptional 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);
  });

Defined in

model/Ad4mModel.ts:1916 (opens in a new tab)


queryToProlog

Static queryToProlog(perspective, query, modelClassName?): Promise<string>

Parameters

NameType
perspectivePerspectiveProxy
queryQuery
modelClassName?string

Returns

Promise<string>

Defined in

model/Ad4mModel.ts:662 (opens in a new tab)


queryToSurrealQL

Static queryToSurrealQL(perspective, query): Promise<string>

Generates a SurrealQL 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 SurrealQL query string ready for execution

Description

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

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:

  • SurrealDB 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.queryToSurrealQL(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

Defined in

model/Ad4mModel.ts:728 (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

Defined in

model/Ad4mModel.ts:1849 (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 deleteremove is preserved as an alias.

Defined in

model/Ad4mModel.ts:1804 (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

Defined in

model/Ad4mModel.ts:1883 (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,
});

Defined in

model/Ad4mModel.ts:1776 (opens in a new tab)