@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
throughoption - 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
- addRelationValue
- changedFields
- cleanCopy
- delete
- generatePropertySetterAction
- generateRelationAction
- get
- getData
- getPropertyMetadata
- getRelationOptions
- innerUpdate
- isDirty
- removeRelationValue
- resolveRelationId
- save
- setProperty
- setRelationValues
- takeSnapshot
- assignValuesToInstance
- count
- countQueryToProlog
- countQueryToSurrealQL
- create
- delete
- findAll
- findAllAndCount
- findOne
- fromJSONSchema
- generateSDNA
- generateSHACL
- getClassName
- getModelMetadata
- instancesFromPrologResult
- paginate
- query
- queryToProlog
- queryToSurrealQL
- register
- remove
- transaction
- update
Constructors
constructor
• new Ad4mModel(perspective, baseExpression?)
Constructs a new model instance.
Parameters
| Name | Type | Description |
|---|---|---|
perspective | PerspectiveProxy | The perspective where this model will be stored |
baseExpression? | string | Optional 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
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
| Name | Type |
|---|---|
key | string |
value | any |
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
| Name | Type | Description |
|---|---|---|
batchId? | string | Optional 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
| Name | Type |
|---|---|
key | string |
metadata | PropertyMetadataEntry |
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
| Name | Type |
|---|---|
key | string |
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
| Name | Type | Description |
|---|---|---|
optsOrInclude? | IncludeMap | GetOptions | Optional 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
| Name | Type |
|---|---|
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
| Name | Type |
|---|---|
key | string |
Returns
Defined in
model/Ad4mModel.ts:378 (opens in a new tab)
getRelationOptions
▸ Private getRelationOptions(key): RelationMetadataEntry
Get relation options from decorator
Parameters
| Name | Type |
|---|---|
key | string |
Returns
Defined in
model/Ad4mModel.ts:388 (opens in a new tab)
innerUpdate
▸ Private innerUpdate(setProperties?, batchId?): Promise<void>
Parameters
| Name | Type | Default value |
|---|---|---|
setProperties | boolean | true |
batchId? | string | undefined |
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(); // trueDefined in
model/Ad4mModel.ts:541 (opens in a new tab)
removeRelationValue
▸ Private removeRelationValue(key, value, batchId?): Promise<void>
Parameters
| Name | Type |
|---|---|
key | string |
value | any |
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
| Name | Type |
|---|---|
value | any |
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
| Name | Type | Description |
|---|---|---|
batchId? | string | Optional 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
| Name | Type |
|---|---|
key | string |
value | any |
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
| Name | Type |
|---|---|
key | string |
value | any |
batchId? | string |
Returns
Promise<void>
Defined in
model/Ad4mModel.ts:1272 (opens in a new tab)
takeSnapshot
▸ Private takeSnapshot(includedRelations?): void
Parameters
| Name | Type | Description |
|---|---|---|
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
| Name | Type |
|---|---|
perspective | PerspectiveProxy |
instance | Ad4mModel |
values | ValueTuple[] |
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
| Name | Type | Default value | Description |
|---|---|---|---|
perspective | PerspectiveProxy | undefined | The perspective to search in |
query | Query | {} | Optional query parameters to filter results |
useSurrealDB | boolean | true | Whether 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
| Name | Type |
|---|---|
perspective | PerspectiveProxy |
query | Query |
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
| Name | Type | Description |
|---|---|---|
perspective | PerspectiveProxy | The perspective context |
query | Query | Query 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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Description |
|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | - |
perspective | PerspectiveProxy | The perspective to create the instance in |
data | Record<string, any> | Property values to assign before saving |
options? | Object | Optional 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
| Name | Type | Description |
|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => Ad4mModel | - |
perspective | PerspectiveProxy | The perspective containing the instance |
id | string | The 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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | undefined | - |
perspective | PerspectiveProxy | undefined | The perspective to search in |
query | Query | {} | Optional query parameters to filter results |
useSurrealDB | boolean | true | Whether 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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | undefined | - |
perspective | PerspectiveProxy | undefined | The perspective to search in |
query | Query | {} | Optional query parameters to filter results |
useSurrealDB | boolean | true | Whether 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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | undefined | - |
perspective | PerspectiveProxy | undefined | The perspective to search in |
query | Query | {} | Optional query parameters to filter results |
useSurrealDB | boolean | true | Whether 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
| Name | Type | Description |
|---|---|---|
schema | JSONSchema | JSON Schema definition |
options | JSONSchemaToModelOptions | Configuration 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:
- Explicit configuration in options parameter (highest precedence)
- x-ad4m metadata in the JSON Schema
- Inference from schema title and property names
- 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
| Name | Type |
|---|---|
name | string |
sdna | string |
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
| Name | Type |
|---|---|
name | string |
shape | any |
Defined in
model/Ad4mModel.ts:148 (opens in a new tab)
getClassName
▸ Static getClassName(perspective): Promise<string>
Parameters
| Name | Type |
|---|---|
perspective | PerspectiveProxy |
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
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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type |
|---|---|
this | typeof Ad4mModel & (...args: any[]) => T |
perspective | PerspectiveProxy |
query | Query |
result | AllInstancesResult |
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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | undefined | - |
perspective | PerspectiveProxy | undefined | The perspective to search in |
pageSize | number | undefined | Number of items per page |
pageNumber | number | undefined | Which page to retrieve (1-based) |
query? | Query | undefined | Optional additional query parameters |
useSurrealDB | boolean | true | Whether 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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Description |
|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | - |
perspective | PerspectiveProxy | The perspective to query |
query? | Query | Optional initial query parameters |
Returns
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
| Name | Type |
|---|---|
perspective | PerspectiveProxy |
query | Query |
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
| Name | Type | Description |
|---|---|---|
perspective | PerspectiveProxy | The perspective to query (used for metadata extraction) |
query | Query | Query 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:
- First, identify candidate base expressions by filtering links based on where conditions
- Then, for each candidate base, resolve properties and relations via subqueries
- 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 10Defined 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
| Name | Type | Description |
|---|---|---|
this | typeof Ad4mModel | - |
perspective | PerspectiveProxy | The perspective to register the model on |
Returns
Promise<void>
Example
await Recipe.register(perspective);
// Now you can create / query Recipe instances on this perspectiveDefined 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
| Name | Type | Description |
|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => Ad4mModel | - |
perspective | PerspectiveProxy | The perspective containing the instance |
id | string | The 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.
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
| Name | Type |
|---|---|
R | void |
Parameters
| Name | Type | Description |
|---|---|---|
perspective | PerspectiveProxy | The 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 hereDefined 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
| Name | Type |
|---|---|
T | extends Ad4mModel<T> |
Parameters
| Name | Type | Description |
|---|---|---|
this | typeof Ad4mModel & (...args: any[]) => T | - |
perspective | PerspectiveProxy | The perspective containing the instance |
id | string | The expression URI of the instance to update |
data | Record<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,
});