Index
Services Overview
This section documents the client-side services available in the Business Platform client package. Services encapsulate reusable logic for data access, caching, and communication with platform APIs.
Available Services
| Service | Description |
|---|---|
| DisplayValueCacheService | Persistent cache for display value entries, backed by IndexedDB with automatic in-memory fallback. |
DisplayValueCacheService
Module: @smallstack/client/services/dataview
The DisplayValueCacheService provides a persistent, IndexedDB-backed cache for DisplayValueEntry objects. It is designed to reduce redundant network requests when resolving human-readable display values for entities across collections.
When IndexedDB is unavailable (for example, in Safari private browsing mode or when storage quota is exceeded), the service automatically falls back to an in-memory cache for the duration of the session.
Key Features
- Persistent storage via IndexedDB (
smallstack-display-cachedatabase) - Automatic fallback to in-memory caching when IndexedDB is unavailable
- Batch read and write operations for efficient multi-entry access
- Composite cache keys combining
collectionName,entityId,schemaHash, andlanguageto ensure correctness across schema versions and locales - Indexed columns for efficient querying by collection, entity, schema hash, or language
Cache Key Structure
Each cache entry is identified by a composite key with the following structure:
{collectionName}:{entityId}:{schemaHash}:{language}
This ensures that cached display values are invalidated automatically when the underlying schema changes (schemaHash) or when a different locale is requested (language).
Basic Usage
import { DisplayValueCacheService } from "@smallstack/client/services/dataview";
const cache = new DisplayValueCacheService();
// Initialize the cache (safe to call multiple times)
await cache.init();
// Check whether IndexedDB is available
console.log(cache.isPersistent); // true if IndexedDB is active
// Read a single entry
const entry = await cache.getCacheEntry({
collectionName: "products",
entityId: "abc123",
schemaHash: "d4f9e1",
language: "en"
});
// Write a single entry
await cache.setCacheEntry(
{ collectionName: "products", entityId: "abc123", schemaHash: "d4f9e1", language: "en" },
{ displayValue: "Widget Pro", ... }
);
Batch Operations
Use batch methods when resolving display values for multiple entities at once to minimize transaction overhead:
// Batch read — returns only the entries that exist in the cache
const entries = await cache.getCacheEntriesMany([
{ collectionName: "products", entityId: "abc123", schemaHash: "d4f9e1", language: "en" },
{ collectionName: "products", entityId: "xyz789", schemaHash: "d4f9e1", language: "en" }
]);
// entries: Map<entityId, DisplayValueEntry>
// Batch write — executes in a single IndexedDB transaction
await cache.setCacheEntriesMany([
{ key: { collectionName: "products", entityId: "abc123", schemaHash: "d4f9e1", language: "en" }, entry: { ... } },
{ key: { collectionName: "products", entityId: "xyz789", schemaHash: "d4f9e1", language: "en" }, entry: { ... } }
]);
Resetting the Cache
To fully delete the underlying IndexedDB database (for example, in tests or after a major schema migration):
import { deleteDisplayCacheDB } from "@smallstack/client/services/dataview";
await deleteDisplayCacheDB();
Type Reference
DisplayCacheKey
| Field | Type | Description |
|---|---|---|
collectionName |
string |
The name of the entity collection. |
entityId |
string |
The unique identifier of the entity. |
schemaHash |
string |
A hash of the schema version used to generate the display value. |
language |
string |
The locale/language code for the display value. |
CachedDisplayValueEntry
Extends DisplayValueEntry with the following additional fields:
| Field | Type | Description |
|---|---|---|
cacheKey |
string |
Composite primary key stored in IndexedDB. |
collectionName |
string |
The collection this entry belongs to. |
schemaHash |
string |
Schema version hash at the time of caching. |
language |
string |
Language code for this entry. |
DisplayCacheMetadata
| Field | Type | Description |
|---|---|---|
totalEntries |
number |
Total number of entries currently in the cache. |
entriesByCollection |
Record<string, number> |
Entry count broken down by collection name. |
Fallback Behavior
The service handles IndexedDB unavailability transparently:
- If
indexedDBis not defined in the current environment, the service resolves withnullfor the database handle and operates purely in memory. - If
indexedDB.open()fails (e.g. quota exceeded, permissions denied), a warning is logged to the console and the service continues in in-memory mode. - The
isPersistentgetter can be checked at runtime to determine which mode is active.
Note: In-memory cache entries are lost when the page is reloaded. For session-scoped caching without persistence requirements this is acceptable, but long-lived applications should ensure IndexedDB is available for best performance.