Search
Tenant-scoped full-text search (Meilisearch / in-memory adapter).
What it shows
Section titled “What it shows”searchable/searchWeighton fields- Handler reads via
ctx.searchAdapter
Source
Section titled “Source”Feature entry point: src/feature.ts.
cd samples/recipes/searchbun testSource code
Section titled “Source code”The feature entry point — embedded straight from the source file, so the code here is exactly what runs. Multi-file samples keep their remaining files next to it on GitHub (link below):
// Search Sample// Shows: searchable fields, searchWeight, search via InMemory SearchAdapter.// Each handler builds its executor inline so `ctx.searchAdapter` is read fresh// per call — tests swap the adapter between runs.
import { buildEntityTable, createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";import { createEntity, createTextField, defineFeature } from "@cosmicdrift/kumiko-framework/engine";import { z } from "zod";
export const productEntity = createEntity({ table: "read_sample_products", fields: { name: createTextField({ required: true, searchable: true }), brand: createTextField({ searchable: true }), sku: createTextField({ required: true }), category: createTextField(), }, searchWeight: 10,});
const productTable = buildEntityTable("product", productEntity);
export const productFeature = defineFeature("shop", (r) => { r.entity("product", productEntity);
r.writeHandler( "product:create", z.object({ name: z.string().min(1), brand: z.string().optional(), sku: z.string().min(1), category: z.string().optional(), }), async (event, ctx) => { const crud = createEventStoreExecutor(productTable, productEntity, { searchAdapter: ctx.searchAdapter, entityName: "product", }); return crud.create(event.payload, event.user, ctx.db); }, { access: { roles: ["Admin"] } }, );
r.queryHandler( "product:list", z.object({ search: z.string().optional(), limit: z.number().optional(), }), async (query, ctx) => { const crud = createEventStoreExecutor(productTable, productEntity, { searchAdapter: ctx.searchAdapter, entityName: "product", }); return crud.list(query.payload, query.user, ctx.db); }, { access: { openToAll: true } }, );});📄 On GitHub: samples/recipes/search/src/feature.ts