Codync
免费开源的 1:1 Grok Bot 与 Muse 替代方案。可在 iPhone、Mac 或 Linux 桌面上将 Claude 代码、Codex、Cursor 以及 40 多个编码代理作为持久机器人使用。支持群组聊天、线程、应用。
AI 翻译
Ecto-native Meilisearch indexing and search orchestration for Elixir/Phoenix apps
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Scrypath, the Ecto-native search indexing library, helps Phoenix and Ecto teams add search to existing schemas without hiding the operational work that keeps search in sync.
Public website: sztheory.github.io/scrypath
Add Scrypath to your dependencies:
def deps do
[
{:scrypath, "~> 0.3"}
]
end
Start here: follow the Golden path from installation through your first inline Scrypath.search/3.
mix verify.adopter locally or mix verify.adopter --live with its services; main may contain unreleased changes. Outside-adopter intake routes real-app evidence. Scope reopens only for a concrete production bug, reviewed outside-adopter evidence, or a deliberate strategic product decision, as described in the scope and reopen policy.Scrypath.search_within_facet/4; multi-index search covers Scrypath.search_many/2, :all expansion, and federation_weight:; per-query tuning distinguishes request-time parameters from index-time settings.mix verify.ops_ui checks it. See CONTRIBUTING for the CI and mix verify.* map.Integration smoke (optional): the Phoenix + Meilisearch example documents its Docker services and env vars. From the repository root, run cd examples/phoenix_meilisearch && ./scripts/smoke.sh; that script lives inside the example.
Scrypath is Meilisearch-first in v1. Its backend seam is internal, not a promised public abstraction, and v1 does not promise public multi-backend parity. Scrypath owns its internal transport dependency; configure backend and sync behavior in your app instead of pinning Req in the base install path. Add Oban only when you choose sync_mode: :oban.
Start with one searchable schema and one Phoenix context that owns both repo persistence and Scrypath orchestration. Declare search metadata with use Scrypath on the Ecto schema, own Scrypath.sync_record/3 after successful repo writes and Scrypath.search/3 from context functions, and keep controllers or LiveView as thin callers into that boundary. For the full copy-paste path - including context module, controller, and IEx check - follow guides/golden-path.md.
defmodule MyApp.Blog.Post do
use Ecto.Schema
use Scrypath,
fields: [:title, :body],
filterable: [:status],
sortable: [:inserted_at]
schema "posts" do
field :title, :string
field :body, :string
field :status, :string
timestamps()
end
end
Scrypath is a good fit when you want:
Scrypath.search/3 pathScrypath is not trying to be:
If you want hidden model hooks, implicit repo access, or a library that pretends accepted work means immediate search visibility, this is the wrong tool.
Scrypath keeps one common runtime surface and one explicit backend-specific escape hatch:
Scrypath for runtime reflection, sync verbs, operator visibility, backfill, managed reindex, and the common search pathScrypath.Schema for the declaration contractScrypath.Projection for document projection rulesScrypath.Meilisearch for backend-native operations that do not belong on the common pathBackfill and managed reindex now use the same internal operations seam as sync, but that seam stays private. The public backend-native namespace remains Scrypath.Meilisearch.*.
The operator surface also stays on Scrypath.*:
Scrypath.sync_status/2Scrypath.failed_sync_work/2Scrypath.retry_sync_work/2Scrypath.reconcile_sync/2For terminal-first operations, the thin mix scrypath.status, mix scrypath.failed,
mix scrypath.retry, and mix scrypath.reconcile tasks wrap those same root APIs.
They do not create a second operator product surface.
use Scrypath is metadata-only. It validates the declaration and exposes stable __scrypath__/1 reflection keys without generating schema-specific runtime verbs.
Call Scrypath.sync_record/3 after successful repo persistence. Choose :inline for the first-hour path and workflows that can wait on backend work, :oban when durable enqueue and worker throughput matter, or :manual for imports and operator-controlled follow-up. A successful return means work was accepted, or—when inline task waiting applies—completed; neither makes the database and search writes atomic, and accepted work may not yet be visible in search. See sync modes and visibility for the exact return contract, lifecycle, and recovery guidance.
Scrypath follows semantic versioning for the public API: minor releases can add backwards-compatible capability; major releases signal breaking changes worth a deliberate upgrade read. Patch releases stay focused on fixes and safe doc corrections - see CHANGELOG.md at the repository root for the human-facing release narrative.
The version in root mix.exs (@version) is the source of truth for this checkout; the latest published package is listed on hex.pm/packages/scrypath.
Quality for the packaged artifact is guarded by mix verify.phase11, the always-on gate referenced from docs/releasing.md. That document - not this README - owns the full verify matrix, Release Please flow, and publish checks for maintainers.
The common search path stays small and explicit:
{:ok, result} =
Scrypath.search(MyApp.Blog.Post, "ecto",
backend: Scrypath.Meilisearch,
repo: Repo,
filter: [status: "published"],
sort: [desc: :inserted_at],
page: [number: 2, size: 20],
preload: [:author]
)
result.records
result.hits
result.missing_ids
result.page
Hydration is explicit and repo-backed. Scrypath does not infer repos globally or hide stale rows when search hits no longer match the database.
Scrypath treats repair and rebuild work as first-class operator workflows:
Scrypath.backfill/2Scrypath.reindex/2Use backfill when the live index contract is still correct and you need to repair missing or stale documents.
Use managed reindex when the contract changed, settings changed, or you no longer trust the live index contents.
{:ok, result} =
Scrypath.reindex(MyApp.Blog.Post,
backend: Scrypath.Meilisearch,
repo: Repo,
batch_size: 500,
cutover?: false
)
result.live_index
result.target_index
result.settings_applied
result.batches
result.documents
result.cutover
cutover?: false leaves the live index untouched while you inspect the rebuilt target.
Detect drift before deciding whether a live-index backfill is enough or whether you need a full rebuild. Common signals are:
Accepted work is not the same thing as search visibility, and durable enqueue is not the same thing as rebuild completion.
Use Scrypath.sync_status/2 and Scrypath.failed_sync_work/2 when you need to inspect pending, retrying, failed, or last-successful work without reading raw Meilisearch or Oban payloads.
Use Scrypath.reconcile_sync/2 when you need a report-first operator view that combines sync visibility, failed work, and rebuild visibility before you decide on recovery.
Scrypath.reconcile_sync/2 does not heal anything by default. It returns drift signals plus explicit recovery actions so the caller can choose retry, backfill, or reindex deliberately.
CI runs live Meilisearch-backed tests in a dedicated workflow job. Locally you can use Docker Compose (from the repo root):
docker compose up -d
SCRYPATH_MEILISEARCH_URL=http://127.0.0.1:7700 mix verify.meilisearch_smoke
docker compose down
mix verify.meilisearch_smoke --skip-integration exits without contacting Meilisearch (useful for quick task wiring checks only; it does not run the live suites).
For a minimal consumer-shaped setup (Docker Compose with Postgres and Meilisearch on an explicit network, path dependency on this repo, and a scripted smoke test), see examples/phoenix_meilisearch/README.md.
For a richer click-around showcase with a multi-tenant storefront and mounted operator UI, see examples/scrypath_ecommerce/README.md.
See ARCHITECTURE.md for the full runtime boundary, sync guarantees, drift model, and managed reindex workflow order.
For operational guides, see Sync Modes and Visibility, Meilisearch Concepts, Meilisearch Operations, Operator Mix Tasks, Operator Support, and Search backend operations - SRE view.