From 9f1717fa212b43946c8e9e0593dc15835a04d25e Mon Sep 17 00:00:00 2001 From: Trezy Date: Fri, 6 Mar 2026 14:30:49 -0600 Subject: [PATCH] docs: add Meilisearch example --- docs/guides/index-hooks.md | 33 ++++++++++++ docs/reference/scripts/meilisearch-sync.md | 58 ++++++++++++++++++++++ sidebars.ts | 5 ++ 3 files changed, 96 insertions(+) create mode 100644 docs/reference/scripts/meilisearch-sync.md diff --git a/docs/guides/index-hooks.md b/docs/guides/index-hooks.md index 4d8aa8b..d674faa 100644 --- a/docs/guides/index-hooks.md +++ b/docs/guides/index-hooks.md @@ -126,6 +126,39 @@ end See the full [Algolia sync reference](../reference/scripts/algolia-sync.md) for more detail. +### Sync to Meilisearch + +Push records to a self-hosted Meilisearch index on create/update, and remove them on delete: + +```lua +function handle() + local headers = { + ["Authorization"] = "Bearer " .. env.MEILISEARCH_API_KEY, + ["Content-Type"] = "application/json" + } + + if action == "delete" then + http.delete(env.MEILISEARCH_URL .. "/indexes/records/documents/" .. uri, { + headers = headers + }) + else + http.post(env.MEILISEARCH_URL .. "/indexes/records/documents", { + headers = headers, + body = json.encode(toarray({ + { + id = uri, + collection = collection, + did = did, + record = record + } + })) + }) + end +end +``` + +See the full [Meilisearch sync reference](../reference/scripts/meilisearch-sync.md) for more detail. + ## Next steps - [Lua Scripting](scripting.md): Full reference for the sandbox, APIs, and debugging diff --git a/docs/reference/scripts/meilisearch-sync.md b/docs/reference/scripts/meilisearch-sync.md new file mode 100644 index 0000000..7ec9b97 --- /dev/null +++ b/docs/reference/scripts/meilisearch-sync.md @@ -0,0 +1,58 @@ +# Index Hook: Meilisearch Sync + +Push records to a Meilisearch search index whenever they are created, updated, or deleted on the network. + +**Lexicon type:** record (index hook) + +```lua +function handle() + local headers = { + ["Authorization"] = "Bearer " .. env.MEILISEARCH_API_KEY, + ["Content-Type"] = "application/json" + } + + if action == "delete" then + http.delete(env.MEILISEARCH_URL .. "/indexes/records/documents/" .. uri, { + headers = headers + }) + else + http.post(env.MEILISEARCH_URL .. "/indexes/records/documents", { + headers = headers, + body = json.encode(toarray({ + { + id = uri, + collection = collection, + did = did, + record = record + } + })) + }) + end +end +``` + +## How it works + +1. On **create** or **update**: sends a `POST` request to Meilisearch's document API with the record data wrapped in an array. Meilisearch upserts by `id` — if a document with the same AT URI already exists, it's replaced. +2. On **delete**: sends a `DELETE` request to remove the document from the index by its AT URI. + +The `toarray()` function ensures the table is encoded as a JSON array (Meilisearch expects an array of documents). See [JSON API](../../guides/index-hooks.md#json-api). + +## Configuration + +This script uses [script variables](../../guides/scripting.md) instead of hardcoded values. Set these via the [admin API](../../reference/admin-api.md) or dashboard: + +| Variable | Value | +| --------------------- | ------------------------------------------------------------------------------ | +| `MEILISEARCH_URL` | Your Meilisearch instance URL (e.g. `http://meilisearch.railway.internal:7700`) | +| `MEILISEARCH_API_KEY` | A Meilisearch API key with write permissions | + +Script variables are stored in the `script_variables` table and accessible as `env.*` in Lua. + +## Use case + +This hook keeps an external search index in sync with your indexed records in real time. Users searching through Meilisearch get results that reflect the latest state of the network without polling or scheduled jobs. + +Meilisearch is a good fit for self-hosted deployments — colocate it alongside HappyView (e.g. on the same Railway project) for sub-millisecond network latency. + +Combine this with a [query script](../../guides/scripting.md) that searches Meilisearch instead of the local database for a full-text search experience that goes beyond what `db.search` offers. diff --git a/sidebars.ts b/sidebars.ts index bb35bb2..cad4372 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -174,6 +174,11 @@ const sidebars: SidebarsConfig = { id: "reference/scripts/algolia-sync", label: "Algolia Sync", }, + { + type: "doc", + id: "reference/scripts/meilisearch-sync", + label: "Meilisearch Sync", + }, ], }, { -- 2.51.2