Search: all 7 kinds and the empty filter
Eight concrete browser functions, quest versus journal categories, authorized recents and validation.
Use the api supplied to a mounted module block. These are complete JavaScript functions; import one into main.js and call it inside mount({ api, signal }). See the minimal package for installation and lifecycle.
As GM, create synthetic documents with the names below in a disposable campaign. Grant a player read access when testing visibility. Command search must be enabled on the host. Every query has at least two characters. An empty filter searches all categories; omitting kind has the same effect.
kind describes the result category. Quests and boards remain journal documents: their result type is journal, while kind is quest or quest_board. The journal filter returns other journals, excluding quests and quest boards.
kind: "": All document kinds
Prerequisite: create at least two Beacon documents in different categories.
export async function findAll(api, signal) {
return api.table.search("Beacon", {
kind: "",
signal,
});
}Expected result: Up to 20 readable documents of any category matching Beacon, sorted by title.
Validate: run findAll(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "actor": Actors
Prerequisite: create Beacon Scout in the actor category.
export async function findActors(api, signal) {
return api.table.search("Beacon Scout", {
kind: "actor",
signal,
});
}Expected result: Readable documents with kind: "actor" matching Beacon Scout.
Validate: run findActors(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "item": Items
Prerequisite: create Beacon Rope in the item category.
export async function findItems(api, signal) {
return api.table.search("Beacon Rope", {
kind: "item",
signal,
});
}Expected result: Readable documents with kind: "item" matching Beacon Rope.
Validate: run findItems(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "journal": Journals
Prerequisite: create Beacon Notes in the journal category.
export async function findJournals(api, signal) {
return api.table.search("Beacon Notes", {
kind: "journal",
signal,
});
}Expected result: Readable documents with kind: "journal" matching Beacon Notes.
Validate: run findJournals(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "quest": Quests
Prerequisite: create Beacon Rescue in the quest category.
export async function findQuests(api, signal) {
return api.table.search("Beacon Rescue", {
kind: "quest",
signal,
});
}Expected result: Readable documents with kind: "quest" matching Beacon Rescue.
Validate: run findQuests(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "quest_board": Quest boards
Prerequisite: create Beacon Jobs in the quest_board category.
export async function findQuestBoards(api, signal) {
return api.table.search("Beacon Jobs", {
kind: "quest_board",
signal,
});
}Expected result: Readable documents with kind: "quest_board" matching Beacon Jobs.
Validate: run findQuestBoards(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "scene": Scenes
Prerequisite: create Beacon Harbor in the scene category.
export async function findScenes(api, signal) {
return api.table.search("Beacon Harbor", {
kind: "scene",
signal,
});
}Expected result: Readable documents with kind: "scene" matching Beacon Harbor.
Validate: run findScenes(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
kind: "compendium": Compendiums
Prerequisite: create Beacon Collection in the compendium category.
export async function findCompendiums(api, signal) {
return api.table.search("Beacon Collection", {
kind: "compendium",
signal,
});
}Expected result: Readable documents with kind: "compendium" matching Beacon Collection.
Validate: run findCompendiums(api, signal) as GM and player; revoke access to one document and repeat. No matches returns an empty array, not an error.
Recent results and errors
For recents, use an empty query and up to 12 references previously returned by search. Use type: "journal" for a quest/board; quest is not a valid recent.type. Every call revalidates campaign and read access.
export async function recentDocuments(api, previousResults, signal) {
const recent = previousResults.slice(0, 12).map(({ id, type }) => ({ id, type }));
return api.table.search("", { recent, signal });
}A query shorter than two characters without recent returns []. More than 200 characters, unknown filters and invalid references are rejected. Disabled search or revoked membership prevents the call; the adapter exposes codes such as permission_denied and invalid_data. cancelled/stale_context indicate cancellation or a disposed block. Do not cache permissions from search results.
How to use AI to build a typed search
On the target release, inspect table/services.py and domain-api.js. Adapt the quest_board example into a readable-board picker. Render titles with textContent, use the block signal and handle empty results, revoked permissions and cancellation. Do not invent api.quests or expose private notes. Include a GM/player check using Beacon fixtures.