API Reference
classes
Modelquerybuilder

@coasys/ad4m / Exports / ModelQueryBuilder

Class: ModelQueryBuilder<T>

Query builder for Ad4mModel queries. Allows building queries with a fluent interface and either running them once or subscribing to updates.

Example

const builder = Recipe.query(perspective)
  .where({ category: "Dessert" })
  .order({ rating: "DESC" })
  .limit(10);
 
// Run once
const recipes = await builder.run();
 
// Or subscribe to updates
await builder.subscribe(recipes => {
  console.log("Updated recipes:", recipes);
});

Type parameters

NameType
Textends Ad4mModel

Table of contents

Constructors

Properties

Methods

Constructors

constructor

• new ModelQueryBuilder<T>(perspective, ctor, query?)

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameType
perspectivePerspectiveProxy
ctortypeof Ad4mModel
query?Query

Defined in

core/src/model/ModelQueryBuilder.ts:45 (opens in a new tab)

Properties

ctor

• Private ctor: typeof Ad4mModel

Defined in

core/src/model/ModelQueryBuilder.ts:40 (opens in a new tab)


currentSubscription

• Private Optional currentSubscription: Object

Type declaration

NameType
dispose() => Promise<void>

Defined in

core/src/model/ModelQueryBuilder.ts:41 (opens in a new tab)


modelClassName

• Private modelClassName: string = null

Defined in

core/src/model/ModelQueryBuilder.ts:39 (opens in a new tab)


perspective

• Private perspective: PerspectiveProxy

Defined in

core/src/model/ModelQueryBuilder.ts:37 (opens in a new tab)


queryParams

• Private queryParams: Query = {}

Defined in

core/src/model/ModelQueryBuilder.ts:38 (opens in a new tab)


subscriptionChain

• Private subscriptionChain: Promise<void>

Tail of the subscribe/dispose chain; see serialize().

Defined in

core/src/model/ModelQueryBuilder.ts:43 (opens in a new tab)

Methods

count

▸ count(): Promise<number>

Gets the total count of matching entities.

Returns

Promise<number>

Total count

Example

const totalDesserts = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .count();

Defined in

core/src/model/ModelQueryBuilder.ts:580 (opens in a new tab)


countSparql

▸ countSparql(): Promise<number>

Gets the total count of matching entities using SPARQL. Delegates to count().

Returns

Promise<number>

Defined in

core/src/model/ModelQueryBuilder.ts:589 (opens in a new tab)


countSubscribe

▸ countSubscribe(callback): Promise<number>

Subscribes to count updates for matching entities.

This method:

  1. Creates and initializes a SPARQL live query subscription for the count (default)
  2. Sets up the callback to process future count updates
  3. Returns the initial count immediately

Remember to call dispose() when you're done with the subscription to clean up resources.

Parameters

NameTypeDescription
callback(count: number) => voidFunction to call with updated count

Returns

Promise<number>

Initial count

Example

const builder = Recipe.query(perspective)
  .where({ status: "active" });
 
const initialCount = await builder.countSubscribe(count => {
  console.log("Active items:", count);
});
 
// When done with subscription:
builder.dispose();

Defined in

core/src/model/ModelQueryBuilder.ts:621 (opens in a new tab)


countSubscribeNow

▸ Private countSubscribeNow(callback): Promise<number>

Parameters

NameType
callback(count: number) => void

Returns

Promise<number>

Defined in

core/src/model/ModelQueryBuilder.ts:625 (opens in a new tab)


countSubscribeSparql

▸ countSubscribeSparql(callback): Promise<number>

Subscribes to count updates using SPARQL.

Parameters

NameType
callback(count: number) => void

Returns

Promise<number>

Deprecated

Use countSubscribe() instead — now routes through Rust model subscription.

Defined in

core/src/model/ModelQueryBuilder.ts:708 (opens in a new tab)


deepQuery

▸ deepQuery(enabled?): ModelQueryBuilder<T>

Controls whether SPARQL property getters are evaluated during hydration.

By default, collection queries evaluate property getters (deepQuery=true). Call .deepQuery(false) to skip getter evaluation for performance.

Parameters

NameTypeDefault valueDescription
enabledbooleantrueWhether to evaluate property getters (default: true)

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

const messages = await Message.query(perspective)
  .parent(channel)
  .deepQuery(false)  // skip property getters for performance
  .limit(30)
  .get();

Defined in

core/src/model/ModelQueryBuilder.ts:285 (opens in a new tab)


dispose

▸ dispose(): Promise<void>

Disposes of the current subscription if one exists.

This method:

  1. Stops the keepalive signals to the subscription
  2. Unsubscribes from subscription updates
  3. Notifies the backend to clean up subscription resources
  4. Clears the subscription reference

Steps 1, 2 and 4 happen synchronously, so builder.dispose() without await is still a complete local cleanup. The returned promise resolves once the executor has released this subscriber's hold on the subscription (it never rejects). The executor shares one subscription between all subscribers of the same query and only drops it when the last one disposes, so disposing here does not interrupt another builder's updates.

You should call this method when you're done with a subscription to prevent memory leaks and ensure proper cleanup.

Returns

Promise<void>

Defined in

core/src/model/ModelQueryBuilder.ts:70 (opens in a new tab)


executeSparqlQuery

▸ Private executeSparqlQuery(): Promise<T[]>

Shared query execution logic — routes through the executor-side modelQuery endpoint.

Returns

Promise<T[]>

Defined in

core/src/model/ModelQueryBuilder.ts:390 (opens in a new tab)


first

▸ first(): Promise<T>

Returns the first matching instance, or null if none match.

Internally sets limit: 1 and delegates to get().

Returns

Promise<T>

The first matching instance, or null

Example

const recipe = await Recipe.query(perspective)
  .where({ name: "Pasta" })
  .first();

Defined in

core/src/model/ModelQueryBuilder.ts:409 (opens in a new tab)


get

▸ get(): Promise<T[]>

Executes the query once and returns the results.

Returns

Promise<T[]>

Array of matching entities

Example

const recipes = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .get();

Defined in

core/src/model/ModelQueryBuilder.ts:376 (opens in a new tab)


getSparql

▸ getSparql(): Promise<T[]>

Executes the query once using SPARQL and returns the results.

Returns

Promise<T[]>

Defined in

core/src/model/ModelQueryBuilder.ts:383 (opens in a new tab)


include

▸ include(map): ModelQueryBuilder<T>

Specifies which relations to eager-load (hydrate into model instances).

Without include, relation fields contain raw expression URIs (strings). With include, the URIs are resolved into fully-hydrated model instances using the target class declared in the relation decorator.

Supports nested includes for multi-level eager loading.

Parameters

NameTypeDescription
mapTypedIncludeMap<T>An IncludeMap describing which relations to hydrate

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

// Hydrate comments one level deep
const recipes = await Recipe.query(perspective)
  .include({ comments: true })
  .run();
// recipe.comments is now Comment[] (model instances), not string[]
 
// Nested: hydrate comments AND each comment's author
const recipes = await Recipe.query(perspective)
  .include({ comments: { author: true } })
  .run();

Defined in

core/src/model/ModelQueryBuilder.ts:354 (opens in a new tab)


includeUnverified

▸ includeUnverified(enabled?): ModelQueryBuilder<T>

Also hydrate from links whose signature did not verify.

Off by default: the executor withholds unverified links. Turn it on only to display an unverified claim, never for data you act on. See includeUnverified.

Parameters

NameTypeDefault valueDescription
enabledbooleantrueWhether to include unverified links (default: true)

Returns

ModelQueryBuilder<T>

The query builder for chaining

Defined in

core/src/model/ModelQueryBuilder.ts:323 (opens in a new tab)


limit

▸ limit(limit): ModelQueryBuilder<T>

Sets the maximum number of results to return.

Parameters

NameTypeDescription
limitnumberMaximum number of results

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.limit(10)

Defined in

core/src/model/ModelQueryBuilder.ts:138 (opens in a new tab)


linkStatus

▸ linkStatus(status): ModelQueryBuilder<T>

Reads instances as they exist in links of one status only.

'shared' leaves out every Local link, both from the values returned and from what decides which instances are returned. Use it when the data is shown to another user. 'local' is the converse: it returns only instances flagged in a Local link, so a Local note on a card flagged only in a Shared link is read without linkStatus, not under 'local'. See linkStatus.

Parameters

NameTypeDescription
statusLinkStatus'shared' or 'local'

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

const cards = await Card.query(perspective).linkStatus('shared').get();

Defined in

core/src/model/ModelQueryBuilder.ts:308 (opens in a new tab)


links

▸ links(keys): ModelQueryBuilder<T>

Asks for the individual links behind each instance — author, timestamp and proof per link — under instance.__links. See Query.links.

Parameters

NameTypeDescription
keysstring[]Property / relation names, or absolute predicate IRIs

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

const [post] = await Post.query(perspective).links(["comments"]).get();
post.__links!.comments.map((l) => l.timestamp); // when each comment was attached

Defined in

core/src/model/ModelQueryBuilder.ts:262 (opens in a new tab)


offset

▸ offset(offset): ModelQueryBuilder<T>

Sets the number of results to skip.

Parameters

NameTypeDescription
offsetnumberNumber of results to skip

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.offset(20) // Skip first 20 results

Defined in

core/src/model/ModelQueryBuilder.ts:154 (opens in a new tab)


order

▸ order(orderBy): ModelQueryBuilder<T>

Sets the order for the query results.

Parameters

NameTypeDescription
orderByTypedOrder<T>The ordering criteria

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.order({ createdAt: "DESC" })

Defined in

core/src/model/ModelQueryBuilder.ts:122 (opens in a new tab)


overrideModelClassName

▸ overrideModelClassName(className): ModelQueryBuilder<T>

Parameters

NameType
classNamestring

Returns

ModelQueryBuilder<T>

Defined in

core/src/model/ModelQueryBuilder.ts:359 (opens in a new tab)


paginate

▸ paginate(pageSize, pageNumber): Promise<PaginationResult<T>>

Gets a page of results with pagination metadata.

Parameters

NameTypeDescription
pageSizenumberNumber of items per page
pageNumbernumberWhich page to retrieve (1-based)

Returns

Promise<PaginationResult<T>>

Paginated results with metadata

Example

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

Defined in

core/src/model/ModelQueryBuilder.ts:727 (opens in a new tab)


paginateSparql

▸ paginateSparql(pageSize, pageNumber): Promise<PaginationResult<T>>

Gets a page of results using SPARQL. Delegates to paginate().

Parameters

NameType
pageSizenumber
pageNumbernumber

Returns

Promise<PaginationResult<T>>

Defined in

core/src/model/ModelQueryBuilder.ts:737 (opens in a new tab)


paginateSubscribe

▸ paginateSubscribe(pageSize, pageNumber, callback): Promise<PaginationResult<T>>

Subscribes to paginated results updates.

This method:

  1. Creates and initializes a SPARQL live query subscription for the paginated results (default)
  2. Sets up the callback to process future page updates
  3. Returns the initial page immediately

Remember to call dispose() when you're done with the subscription to clean up resources.

Parameters

NameTypeDescription
pageSizenumberNumber of items per page
pageNumbernumberWhich page to retrieve (1-based)
callback(results: PaginationResult<T>) => voidFunction to call with updated pagination results

Returns

Promise<PaginationResult<T>>

Initial pagination results

Example

const builder = Recipe.query(perspective)
  .where({ category: "Main" });
 
const initialPage = await builder.paginateSubscribe(10, 1, page => {
  console.log("Updated page:", page.results);
});
 
// When done with subscription:
builder.dispose();

Defined in

core/src/model/ModelQueryBuilder.ts:771 (opens in a new tab)


paginateSubscribeNow

▸ Private paginateSubscribeNow(pageSize, pageNumber, callback): Promise<PaginationResult<T>>

Parameters

NameType
pageSizenumber
pageNumbernumber
callback(results: PaginationResult<T>) => void

Returns

Promise<PaginationResult<T>>

Defined in

core/src/model/ModelQueryBuilder.ts:779 (opens in a new tab)


paginateSubscribeSparql

▸ paginateSubscribeSparql(pageSize, pageNumber, callback): Promise<PaginationResult<T>>

Subscribes to paginated results updates using SPARQL. Delegates to paginateSubscribe().

Parameters

NameType
pageSizenumber
pageNumbernumber
callback(results: PaginationResult<T>) => void

Returns

Promise<PaginationResult<T>>

Defined in

core/src/model/ModelQueryBuilder.ts:916 (opens in a new tab)


parent

▸ parent(idOrInstance, modelOrPredicate?, options?): ModelQueryBuilder<T>

Scopes the query to instances linked from a parent.

The predicate is resolved in order of precedence:

  1. Instance only — the parent's constructor is used as the model class; its relation metadata is scanned for a relation whose target() matches the queried model class.
  2. Instance + options with field — direct field-name lookup on the parent model's relation metadata (disambiguates when a parent has multiple relations targeting the same child class).
  3. String id + model class — same metadata scan (or field lookup if options include field).
  4. String id + string predicate — raw escape hatch, no metadata lookup.

Passing a plain string id with no second argument throws because the predicate cannot be resolved without a model class.

Parameters

NameTypeDescription
idOrInstancestring | Ad4mModelThe parent's expression URI or an Ad4mModel instance
modelOrPredicate?string | typeof Ad4mModel | { field: string }A model class (predicate auto-resolved) or a raw predicate string
options?ObjectOptional settings: field for direct relation-name lookup
options.field?string-

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

// Instance — predicate auto-resolved from Cookbook's @HasMany(() => Recipe)
Recipe.query(perspective).parent(cookbook).get();
 
// Instance + field — disambiguate when parent has multiple relations to same child
Recipe.query(perspective).parent(cookbook, { field: "recipes" }).get();
 
// String id + model class
Recipe.query(perspective).parent(cookbookId, Cookbook).get();
 
// String id + model class + field
Recipe.query(perspective).parent(cookbookId, Cookbook, { field: "recipes" }).get();
 
// String id + raw predicate (escape hatch)
Recipe.query(perspective).parent(cookbookId, "cookbook://recipe").get();

Defined in

core/src/model/ModelQueryBuilder.ts:199 (opens in a new tab)


properties

▸ properties(properties): ModelQueryBuilder<T>

Specifies which properties to include in the results.

Parameters

NameTypeDescription
propertiesstring[] | PropertyKeysOf<T>[]Array of property names to include

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.properties(["name", "description", "rating"])

Defined in

core/src/model/ModelQueryBuilder.ts:244 (opens in a new tab)


serialize

▸ Private serialize<R>(run): Promise<R>

Runs one subscribe variant after every earlier one on this builder has finished. Each variant disposes the previous subscription (awaiting the executor) and then registers its own; two overlapping calls would both find no current subscription, both register, and the builder could only ever dispose the last one. Serializing keeps exactly one subscription per builder.

Type parameters

Name
R

Parameters

NameType
run() => Promise<R>

Returns

Promise<R>

Defined in

core/src/model/ModelQueryBuilder.ts:84 (opens in a new tab)


subscribe

▸ subscribe(callback): Promise<T[]>

Subscribes to the query and receives updates when results change.

This method:

  1. Creates and initializes a SPARQL live query subscription (default)
  2. Sets up the callback to process future updates
  3. Returns the initial results immediately

Remember to call dispose() when you're done with the subscription to clean up resources.

Parameters

NameTypeDescription
callback(results: T[]) => voidFunction to call with updated results

Returns

Promise<T[]>

Initial results array

Example

const builder = Recipe.query(perspective)
  .where({ status: "cooking" });
 
const initialRecipes = await builder.subscribe(recipes => {
  console.log("Updated recipes:", recipes);
});
 
// When done with subscription:
builder.dispose();

Defined in

core/src/model/ModelQueryBuilder.ts:445 (opens in a new tab)


subscribeNow

▸ Private subscribeNow(callback): Promise<T[]>

Parameters

NameType
callback(results: T[]) => void

Returns

Promise<T[]>

Defined in

core/src/model/ModelQueryBuilder.ts:449 (opens in a new tab)


subscribeSparql

▸ subscribeSparql(callback): Promise<T[]>

Subscribes to the query and receives updates using SPARQL.

Parameters

NameType
callback(results: T[]) => void

Returns

Promise<T[]>

Deprecated

Use subscribe() instead — now routes through Rust model subscription.

Defined in

core/src/model/ModelQueryBuilder.ts:564 (opens in a new tab)


where

▸ where(conditions): ModelQueryBuilder<T>

Adds where conditions to the query.

Parameters

NameTypeDescription
conditionsTypedQueryWhere<T>The conditions to filter by

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.where({
  category: "Dessert",
  rating: { gt: 4 },
  tags: ["vegan", "quick"],
  published: true
})

Defined in

core/src/model/ModelQueryBuilder.ts:106 (opens in a new tab)