/** * SpintaClient - HTTP client for the Lithuanian Open Data API (data.gov.lt) * * @example * ```typescript * import { SpintaClient, QueryBuilder } from 'lt-open-data-sdk'; * * const client = new SpintaClient(); * * // Get all items (single page - uses limit from query or API default) * const cities = await client.getAll('datasets/gov/example/City'); * * // Stream all items with automatic pagination * for await (const city of client.stream('datasets/gov/example/City')) { * console.log(city.name); * } * * // With query builder * const query = new QueryBuilder() * .select('name', 'population') * .filter(f => f.field('population').gt(100000)) * .limit(100); * * const largeCities = await client.getAll('datasets/gov/example/City', query); * ``` */ import type { ClientConfig, SpintaObject, SpintaResponse, ChangeEntry, SummaryBin } from './types.js'; import { QueryBuilder } from '../builder/QueryBuilder.js'; export declare class SpintaClient { private readonly baseUrl; private readonly tokenCache; constructor(config?: ClientConfig); /** * Build headers for API requests * Refreshes token if needed before each request */ private getHeaders; /** * Make an HTTP request to the API */ private request; /** * Get a single object by its UUID * * @param model - Full model path (e.g., 'datasets/gov/example/City') * @param id - Object UUID * @returns The object with metadata * * @example * const city = await client.getOne('datasets/gov/example/City', 'abc123-...'); */ getOne(model: string, id: string): Promise; /** * Get objects from a model (single page only) * * **Note**: This fetches ONE page of results based on the limit in your query * (or the API's default limit). It does NOT download all records. * For large datasets, use `stream()` which handles pagination automatically. * * @param model - Full model path (e.g., 'datasets/gov/example/City') * @param query - Optional query builder for filtering, sorting, limiting * @returns Array of objects with metadata (unwrapped from _data) * * @example * // Get first 100 cities * const query = new QueryBuilder().limit(100); * const cities = await client.getAll('datasets/gov/example/City', query); */ getAll(model: string, query?: QueryBuilder): Promise<(T & SpintaObject)[]>; /** * Get raw response with metadata (includes _type, _page info) * * Use this when you need pagination info or the response type. * * @param model - Full model path * @param query - Optional query builder * @returns Full Spinta response with _data array and _page info */ getAllRaw(model: string, query?: QueryBuilder): Promise>; /** * Get a single page with optional page token (used for streaming with retry) */ getPageRaw(model: string, query?: QueryBuilder, pageToken?: string): Promise>; /** * Stream all objects with automatic pagination * * Implements an async iterator that automatically fetches subsequent pages * using the `_page.next` token. Validates token before each page fetch to * avoid mid-stream auth failures on large datasets. * * **Warning**: Do NOT use `.select()` with `stream()`. The data.gov.lt API * does not return pagination tokens when field projection is used, causing * the stream to stop after the first page. * * @param model - Full model path * @param query - Optional query builder (should include limit for page size) * @yields Objects one at a time with metadata * * @example * // Stream all cities with a filter * const query = new QueryBuilder() * .filter(f => f.field('population').gt(10000)) * .limit(1000); // Page size * * for await (const city of client.stream('datasets/gov/example/City', query)) { * console.log(city.name); * } */ stream(model: string, query?: QueryBuilder): AsyncGenerator; /** * Stream with retry/backoff support (exposed for CLI/advanced use). * Retries HTTP 429 with exponential backoff up to maxAttempts. */ streamWithRetry(model: string, query?: QueryBuilder, options?: { pageSize?: number; initialBackoffMs?: number; maxBackoffMs?: number; maxAttempts?: number; noRetry?: boolean; }): AsyncGenerator; /** * Count objects matching a query * * @param model - Full model path * @param query - Optional query builder for filtering (sort/select are ignored) * @returns Number of matching objects * * @example * const query = new QueryBuilder().filter(f => f.field('population').gt(100000)); * const count = await client.count('datasets/gov/example/City', query); */ count(model: string, query?: QueryBuilder): Promise; /** * List contents of a namespace * * @param namespace - Namespace path (e.g., 'datasets/gov/ivpk') * @returns Array of namespace items (sub-namespaces and models) * * @example * const items = await client.listNamespace('datasets/gov/ivpk'); * for (const item of items) { * if (item._type === 'ns') { * console.log('Namespace:', item._id); * } else { * console.log('Model:', item._id); * } * } */ listNamespace(namespace: string): Promise; /** * Discover all models within a namespace (recursively) * * Traverses the namespace hierarchy and returns all model paths found. * Uses parallel fetching for sibling namespaces to improve performance. * * @param namespace - Starting namespace path (e.g., 'datasets/gov/rc') * @param concurrency - Max concurrent requests (default 5) * @returns Array of discovered models with path and title * * @example * ```typescript * // Find all models in the Registry Centre * const models = await client.discoverModels('datasets/gov/rc'); * console.log(`Found ${models.length} models`); * for (const model of models) { * console.log(`- ${model.title ?? model.path}`); * } * ``` */ discoverModels(namespace: string, concurrency?: number): Promise; /** * Get the latest change ID for a model * * Useful for initializing sync - get the current position before starting. * * @param model - Full model path (e.g., 'datasets/gov/example/City') * @returns The most recent change entry, or null if no changes exist * * @example * const latest = await client.getLatestChange('datasets/gov/example/City'); * if (latest) { * console.log('Last change ID:', latest._cid); * } */ getLatestChange(model: string): Promise<(ChangeEntry) | null>; /** * Get the timestamp of the last update to a model * * Convenience method that returns when the dataset was last modified. * Useful for cache invalidation, freshness indicators, or conditional fetching. * * @param model - Full model path (e.g., 'datasets/gov/example/City') * @returns Date of last update, or null if no changes exist * * @example * const lastUpdate = await client.getLastUpdatedAt('datasets/gov/example/City'); * if (lastUpdate) { * console.log('Last updated:', lastUpdate.toISOString()); * } */ getLastUpdatedAt(model: string): Promise; /** * Get changes since a specific change ID * * Returns a log of all data modifications (insert, update, delete) since * the given change ID. Use for incremental data synchronization. * * @param model - Full model path * @param sinceId - Change ID to start from (exclusive). Pass 0 or omit to get all changes. * @param limit - Maximum number of changes to return (default: 100) * @returns Array of change entries with operation type and data * * @example * // Initial sync: get current position * const latest = await client.getLatestChange('datasets/gov/example/City'); * let lastId = latest?._cid ?? 0; * * // Incremental sync: get changes since last sync * const changes = await client.getChanges('datasets/gov/example/City', lastId); * for (const change of changes) { * if (change._op === 'insert') { * // Handle new record * } else if (change._op === 'update' || change._op === 'patch') { * // Handle modification * } else if (change._op === 'delete') { * // Handle deletion * } * lastId = change._cid; * } */ getChanges(model: string, sinceId?: number, limit?: number): Promise[]>; /** * Stream all changes since a specific ID with automatic pagination * * @param model - Full model path * @param sinceId - Change ID to start from (exclusive) * @param pageSize - Number of changes per page (default: 100) * @yields Change entries one at a time * * @example * for await (const change of client.streamChanges('datasets/gov/example/City', 0)) { * console.log(change._op, change._id); * } */ streamChanges(model: string, sinceId?: number, pageSize?: number): AsyncGenerator, void, undefined>; /** * Get histogram/distribution summary for a numeric field * * Returns binned counts showing the distribution of values for a field. * Useful for data exploration, profiling, and visualization. * * @param model - Full model path (e.g., 'datasets/gov/example/City') * @param field - Numeric field to summarize (e.g., 'population') * @returns Array of bins with value ranges and counts * * @example * const histogram = await client.getSummary( * 'datasets/gov/rc/ar/savivaldybe/Savivaldybe', * 'sav_kodas' * ); * for (const bin of histogram) { * console.log(`Value ~${bin.bin}: ${bin.count} records`); * } */ getSummary(model: string, field: string): Promise; } /** Discovered model from namespace traversal */ export interface DiscoveredModel { /** Full model path (e.g., 'datasets/gov/rc/ar/savivaldybe/Savivaldybe') */ path: string; /** Human-readable title from API metadata */ title?: string; /** Parent namespace path */ namespace: string; } /** Namespace item type (transformed) */ interface NamespaceItem { _id: string; _type: 'ns' | 'model'; title?: string; description?: string; } export {}; //# sourceMappingURL=SpintaClient.d.ts.map