@volter/twin-algolia 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts ADDED
@@ -0,0 +1,103 @@
1
+ // @volter/twin-algolia — the Algolia (algolia.com) hosted-search API twin, built on the shared
2
+ // @volter/world-core kernel. Single-plane REST transport: every route lives under
3
+ // `/1/indexes/{indexName}/...` (index list/delete/clear, record CRUD, REAL search — tokenize +
4
+ // Damerau-Levenshtein typo tolerance + a faithful-subset ranking + REAL filter/facetFilters
5
+ // evaluation + exact facet-count aggregation + customRanking tie-breaks + basic bidirectional
6
+ // synonym expansion, settings get/set). Host-TOLERANT (not host-SPLIT, unlike pinecone): every
7
+ // real Algolia host shape ({appId}.algolia.net / {appId}-dsn.algolia.net /
8
+ // {appId}-N.algolianet.com) routes to the SAME single plane, since Algolia's REST paths already
9
+ // carry the index name — no host-based dispatch is needed (see algolia-twin.ts's header). State
10
+ // lives entirely in the kernel action log (no side-store). API-first vendor: no mirror, no UI
11
+ // capabilities (ui-scope.json).
12
+ //
13
+ // THE SEARCH ENGINE (README ## Coverage has the full reasoning): this twin's search is a
14
+ // faithful, deterministic SUBSET of the documented tie-break criteria, not a lesser stub;
15
+ // widening it is `algolia.search.ranking_criteria_coverage` (todo). Writes apply synchronously
16
+ // to one kernel root. Tokenization is deterministic ASCII/Unicode word-splitting today, with
17
+ // stemming/plurals/CJK segmentation filed as `algolia.search.language_processing`. (Conformance/capability tooling lives in
18
+ // @volter/world-tooling, a dev dependency — NOT shipped.)
19
+ export {
20
+ handleAlgoliaTwinRequest,
21
+ routeAlgoliaSurface,
22
+ mintHost,
23
+ recoverAppIdFromHost,
24
+ algoliaTwinSnapshot,
25
+ ALGOLIA_RESOURCE_TYPES,
26
+ } from './algolia-twin.ts';
27
+ export type {
28
+ AlgoliaRequest,
29
+ AlgoliaResponse,
30
+ AlgoliaSurface,
31
+ AlgoliaResourceType,
32
+ AlgoliaTwinSnapshot,
33
+ } from './algolia-twin.ts';
34
+ export { createAlgoliaTwinFetch, createAlgoliaTwinServer, type AlgoliaTwinFetchOptions } from './algolia-server.ts';
35
+ export {
36
+ mapIndex,
37
+ mapRecord,
38
+ pullAlgoliaIndexes,
39
+ pullAlgoliaRecords,
40
+ syncAlgoliaFromReal,
41
+ } from './algolia-connector.ts';
42
+ export type { AlgoliaLikeClient, AlgoliaRealIndex, AlgoliaRealRecord, AlgoliaBudgetedOptions } from './algolia-connector.ts';
43
+ // The client-side rate budget — the fail-closed backstop every live Algolia call goes through. The
44
+ // MECHANISM is the kernel's shared, vendor-agnostic `RateBudget`; what lives here is Algolia's
45
+ // DECLARATION (window/ceiling/per-method weights) plus `guardAlgoliaClient`, the choke point the
46
+ // connector entrypoints apply unconditionally. Exported so an operator can inspect spend
47
+ // (`snapshot`) and a caller can catch `AlgoliaBudgetError` by type; there is deliberately no export
48
+ // that disables the guard.
49
+ export {
50
+ ALGOLIA_BUDGETED_METHODS,
51
+ ALGOLIA_BUDGET_CEILING,
52
+ ALGOLIA_BUDGET_MAX_RETRY_AFTER_S,
53
+ ALGOLIA_BUDGET_WINDOW_MS,
54
+ ALGOLIA_CALL_WEIGHTS,
55
+ ALGOLIA_RATE_BUDGET,
56
+ AlgoliaBudget,
57
+ AlgoliaBudgetError,
58
+ algoliaBudgetPath,
59
+ algoliaCallWeight,
60
+ algoliaClientBudget,
61
+ guardAlgoliaClient,
62
+ } from './algolia-budget.ts';
63
+ export type { AlgoliaBudgetErrorKind, AlgoliaBudgetOptions, AlgoliaBudgetReservation, AlgoliaBudgetSnapshot } from './algolia-budget.ts';
64
+ export { matchesAlgoliaFilters, matchesFacetFilters, computeFacetCounts } from './algolia-filter.ts';
65
+ export type { FacetFilters, FacetFilterClause } from './algolia-filter.ts';
66
+ export { tokenize, damerauLevenshtein, rankRecords, buildSynonymGroups } from './algolia-search.ts';
67
+ export type { SearchRecord, RankedHit, CustomRankingRule } from './algolia-search.ts';
68
+
69
+ // Registry descriptor: the pack self-describes so tooling can discover it.
70
+ import type { TwinPack } from '@volter/world-core';
71
+ import { ALGOLIA_RATE_BUDGET as RATE_BUDGET } from './algolia-budget.ts';
72
+ export const pack: TwinPack = {
73
+ vendor: 'algolia',
74
+ // The SAME object algolia-budget.ts declares at module load — one source of truth, so registering
75
+ // the pack and importing the connector can never arm two different ceilings.
76
+ rateBudget: RATE_BUDGET,
77
+ transport: 'rest',
78
+ archetype: 'crud',
79
+ bin: 'world-algolia',
80
+ resources: ['index', 'record', 'synonym', 'settings'],
81
+ specSource: 'algolia-conformance.ts (endpoint/resource inventory grounded LIVE against the installed algoliasearch SDK, driven end-to-end with a throwaway local server before this handler was written — see spec-sources.json)',
82
+ description: 'Algolia hosted-search twin — index list/delete/clear, record CRUD (add/replace/partial/delete/batch), REAL tokenize+typo+ranking search engine with REAL filter/facetFilters/facet-count evaluation, customRanking, basic synonym expansion, settings get/set, host-tolerant router. Kernel-backed. No mirror (API-first vendor).',
83
+ // Adoption, all in the pack's one home (descriptor-first back-migration, adding-a-twin.md §3, 2026-08-31; the bare
84
+ // `algolia` stem and the `algoliasearch` SDK name moved off the central maps unchanged). Stems:
85
+ // the bare ALGOLIA_* shape and the ALGOLIA_WRITE_* write-key half real apps split out.
86
+ adoption: {
87
+ // Algolia's own Python client - same distribution name as the npm one, different registry.
88
+ pypi: ['algoliasearch'],
89
+ sdks: ['algoliasearch'], envStems: ['ALGOLIA', 'ALGOLIAWRITE'],
90
+ },
91
+ // No `browserRouting`: unlike every other pack (which has ONE fixed absolute API host to strip
92
+ // for the zero-edit dev proxy — even supabase's per-PROJECT data API omits it in favor of its
93
+ // static management-API host), Algolia has NO fixed host at all — every real host is
94
+ // `{appId}.algolia.net`-shaped, with the caller's OWN appId baked directly into the domain. A
95
+ // literal `{appId}` placeholder is not a stripeable absolute host, so `browserRouting` is
96
+ // correctly omitted here rather than populated with a non-matching placeholder.
97
+ // INTERCEPTION RULING — hostsNone, the pack's own home for it: per-app-ID host scheme
98
+ // ({appId}.algolia.net / {appId}-dsn.algolia.net / {appId}-N.algolianet.com, see the pack
99
+ // README §Host tolerance) — no fixed host list to match; the host-tolerant twin is wired by
100
+ // explicit client host config.
101
+ hostsNone:
102
+ "per-app-ID host scheme ({appId}.algolia.net / {appId}-dsn.algolia.net / {appId}-N.algolianet.com, see the pack README §Host tolerance) — no fixed host list to match; the host-tolerant twin is wired by explicit client host config",
103
+ };