Title: 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-cache database) 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, and language to 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 // 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 | Entry count broken down by collection name. | Fallback Behavior The service handles IndexedDB unavailability transparently: If indexedDB is not defined in the current environment, the service resolves with null for 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 isPersistent getter 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.