BoxLang 🚀 A New JVM Dynamic Language Learn More...
A resilient, endpoint-oriented Typesense client for ColdBox applications. cbTypesense uses Hyper 8, supports named least-privilege connections, and keeps application-specific search projection and authorization outside the module.
typesense/typesense:29.0@sha256:316b7e71c21f7e5e5caa8daa150e1b3f2be8c876081ee1f77bc2d92cd7f137d0
The exact upstream source, license checksum, and container provenance
are recorded in compatibility/typesense-29.0.md
.
The module is MIT licensed. Typesense 29.0 is a separate GPL-3.0 program and is not bundled in this package.
box install cbtypesense
Configure one or more named connections in
config/ColdBox.cfc. Keep search, indexing, and
administrative credentials separate in production.
moduleSettings = {
cbtypesense : {
defaultConnection : "search",
unhealthyNodeTtlMs : 30000,
maxRetries : 3,
connections : {
search : {
nodes : [
{ protocol : "http", host : "127.0.0.1", port : 8108 }
],
apiKey : getSystemSetting( "TYPESENSE_SEARCH_API_KEY", "" ),
connectTimeoutMs : 500,
readTimeoutMs : 1500,
retries : 1,
retryBackoffMs : 25
},
indexer : {
nodes : [
{ protocol : "http", host : "127.0.0.1", port : 8108 }
],
apiKey : getSystemSetting( "TYPESENSE_INDEX_API_KEY", "" )
}
}
}
};
Configuration is validated without making a network request. The
normalized configuration returned by Config@cbtypesense
is copied so callers cannot mutate shared state.
Inject the default façade or request an isolated named client from the factory:
property name="typesense" inject="Client@cbtypesense";
property name="typesenseClients" inject="ClientFactory@cbtypesense";
typesense.collections().create( schema );
typesense.documents( "inventory_items" ).upsert( document );
result = typesense.documents( "inventory_items" ).importDocuments(
documents,
action = "upsert"
);
typesense.documents( "inventory_items" ).deleteByFilter(
filterBy = "organizationId:=organization-123",
batchSize = 100
);
searchResponse = typesense.search( "inventory_items", {
q : "blue dress",
query_by : "name,brand,model",
filter_by : "organization_id:=42"
} );
typesense.aliases().upsert( "inventory_items_current", "inventory_items_v1" );
indexer = typesenseClients.get( "indexer" );
Public endpoint clients cover collections and schemas, aliases, document CRUD/import/export/search, multi-search, API keys, local scoped-search-key generation, and health/debug/stats/metrics/snapshot operations.
importDocuments() accepts an array of structs, a
generator closure, an object implementing hasNext() and
next(), a line reader implementing
readLine(), or prepared NDJSON. It returns
TypesenseImportResult; always inspect its succeeded and
failed counts. Set throwOnFailure=true when any failed
line must abort the caller.
Use request() only as a forward-compatible escape hatch.
It accepts relative paths only and still applies configured
authentication, normalized errors, and retry safety.
Calls return TypesenseResponse, which exposes status,
parsed data, headers, request ID, and raw body. Search responses
additionally expose hits(), facetCounts(),
found(), page(), and searchTimeMs().
Failures use cbTypesense.AuthenticationException,
PermissionException, NotFoundException,
ValidationException, RateLimitException,
ConnectionException, or ServerException.
Reads retry eligible connection, 408, 429, and server failures across
configured nodes. Unsafe writes are never retried automatically.
Explicitly idempotent upsert/import calls can opt in with retry=true.
Generate scoped keys locally from a search-only parent key. A
filter_by restriction is required;
expires_at is validated when present.
scopedKey = getInstance( "ScopedKey@cbtypesense" ).generate(
parentKey = variables.parentSearchKey,
parameters = {
filter_by : "organization_id:=42 && visibility:=[organization]",
expires_at : dateAdd( "n", 15, now() ).getTime() / 1000
}
);
The module does not decide tenant or ACL filters. That belongs to the consuming application.
box install
cd test-harness && box install && cd ..
docker compose -f test-harness/compose.typesense.yml up -d
box server start [email protected]
box testbox run
box run-script format:check
box run-script build:module
The live suite uses unique collections and cleans up its documents, aliases, and keys. Docker is used only for the external test service; no Typesense binary or image is included in the module artifact.
CI builds the distributable ZIP before every engine job, installs it
into a clean ColdBox test application's modules/
directory, asserts that Client@cbtypesense resolves from
that installed artifact, and runs the complete live lifecycle. Stable
ColdBox 8 is certified on BoxLang, BoxLang CFML compatibility mode,
Lucee 5/6, and Adobe ColdFusion 2023/2025; the current ColdBox
bleeding-edge matrix is additional compatibility evidence.
cbTypesense is released under the MIT License.
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
$
box install cbtypesense