@bluecopa/core
The core package provides essential API utilities and functions for data management, workbook handling, dataset operations, and definition execution in the Bluecopa platform.
Table of Contents
Version
Current version: 0.1.4
Installation
npm install @bluecopa/core
Requirements
- Node.js >= 18.0.0
- Dependencies:
- axios (1.12.0) - For HTTP requests
- lodash (4.17.21) - For utility functions
- centrifuge (5.0.0) - For WebSocket connections
Configuration
The package uses a singleton-based configuration system to manage API settings. Configure it before making API calls.
Import and set the config:
import { copaSetConfig, copaApi } from "@bluecopa/core";
copaSetConfig({
apiBaseUrl: "https://develop.bluecopa.com",
accessToken: "your-access-token",
workspaceId: "your-workspace-id",
userId: "your-user-id",
});
Getting User Details and Setting User ID
To automatically set the userId from the logged-in user:
import { copaSetConfig, copaApi } from "@bluecopa/core";
copaSetConfig({
apiBaseUrl: "https://develop.bluecopa.com",
accessToken: "your-access-token",
workspaceId: "your-workspace-id",
});
try {
const userDetails = await copaApi.user.getLoggedInUserDetails();
copaSetConfig({ userId: userDetails.id });
console.log("User ID set:", userDetails.id);
} catch (error) {
console.error("Failed to get user details:", error);
}
copaSetConfig(partialConfig: Partial<Config>): Updates the configuration.
copaGetConfig(): Retrieves the current configuration.
resetConfig(): Resets to default empty values.
The Config interface:
export interface Config {
apiBaseUrl: string;
accessToken: string;
workspaceId: string;
userId: string;
solutionId?: string;
websocketProvider?: IWebsocketProvider;
}
API Reference
All API functions are asynchronous and use the shared apiClient for HTTP requests. They handle errors by throwing objects with message and status. Access via copaApi.moduleName.functionName().
Dataset Module
copaApi.dataset.getData(): Retrieves specific dataset data by ID or parameters
copaApi.dataset.getDatasets(): Fetches a list of datasets
copaApi.dataset.getSampleData(): Gets sample data for datasets
See: dataset/getData.ts, dataset/getSampleData.ts, dataset/getDatasets.ts
Definition Module
copaApi.definition.runDefinition(): Executes a custom definition
copaApi.definition.runPublishedDefinition(): Runs a published definition
copaApi.definition.runSampleDefinition(): Executes a sample definition for testing
See: definition/runPublishedDefinition.ts, definition/runSampleDefinition.ts, definition/runDefinition.ts
File Module
copaApi.files.getFileUrlByFileId(fileId: string): Generates a URL for a file by its ID
See: file/getFileUrlByFileId.ts
InputTable Module
copaApi.inputTable.getData(): Retrieves data from an input table
copaApi.inputTable.getInputTables(): Fetches all input tables
copaApi.inputTable.getTableById(id: string): Gets a specific input table by ID
See: inputTable/getData.ts, inputTable/getInputTables.ts, inputTable/getTableById.ts
Metric Module
copaApi.metric.getData(): Fetches metric data
See: metric/getData.ts
User Module
copaApi.user.getLoggedInUserDetails(): Retrieves details of the currently logged-in user
See: user/getLoggedInUserDetails.ts
Workbook Module
copaApi.workbook.getPublishedWorkbookById(id: string): Fetches a published workbook by ID
copaApi.workbook.getWorkbooksByType(type: string): Retrieves workbooks filtered by type
See: workbook/getPublishedWorkbookById.ts, workbook/getWorkbooksByType.ts
Workflow Module
copaApi.workflow.getWorkflowInstanceStatusById(id: string): Checks the status of a workflow instance
copaApi.workflow.triggerHttpWorkflowById(id: string): Triggers an HTTP-based workflow
copaApi.workflow.triggerWorkflowById(id: string): Triggers a workflow by ID
See: workflow/triggerHttpWorkflowById.ts, workflow/triggerWorkflowById.ts, workflow/getWorkflowInstanceStatusById.ts
Worksheet Module
copaApi.worksheet.getWorksheets(): Fetches all worksheets
copaApi.worksheet.getWorksheetsByType(type: string): Retrieves worksheets by type
See: worksheet/getWorksheets.ts, worksheet/getWorksheetsByType.ts
InputTableDB — Reactive Database Client
A Firebase-like client for querying and subscribing to Bluecopa Input Table V2 data. No init required — just import and use.
Full SDK Guide — comprehensive documentation with architecture details, error handling, framework integration (Svelte/React), and all available features.
Quick Start
import { copaSetConfig, copaInputTableDb } from "@bluecopa/core";
copaSetConfig({
apiBaseUrl: "https://develop.bluecopa.com",
accessToken: "your-token",
workspaceId: "ws-123",
solutionId: "sol-abc",
websocketProvider: ws,
});
const unsub = copaInputTableDb.collection("invoices")
.where("status", "==", "pending")
.orderBy("updated_at", "desc")
.limit(50)
.subscribe((rows) => console.log(rows));
unsub();
CRUD
const rows = await copaInputTableDb.collection("invoices").get();
const inv = await copaInputTableDb.collection("invoices").doc(id).get();
const newId = await copaInputTableDb.collection("invoices").add({ vendor: "Acme", amount: 100 });
await copaInputTableDb.collection("invoices").doc(id).update({ status: "approved" });
await copaInputTableDb.collection("invoices").doc(id).delete();
const unsub = copaInputTableDb.collection("invoices").doc(id).onSnapshot((doc) => {
console.log(doc);
});
const unsub = copaInputTableDb.collection("invoices").count((n) => console.log(n));
Query Operators
== | equals |
!= | not equals |
< | less than |
<= | less than or eq |
> | greater than |
>= | gte |
in | in array |
not-in | not in array |
Aggregate Queries
Compute server-side aggregates (sum, avg, count, min, max) without fetching all rows. Combines with where(), limit(), and skip() filters.
const result = await copaInputTableDb
.collection("invoices")
.where("status", "==", "active")
.aggregate({ amount: ["sum", "avg"], price: ["min", "max"] });
const result = await copaInputTableDb
.collection("invoices")
.aggregate({ _count: true });
const result = await copaInputTableDb
.collection("invoices")
.aggregate({ name: ["count"], _count: true });
.aggregate() is a terminal method — it bypasses local RxDB and hits PostgREST directly. Errors throw InputTableError. An empty spec {} returns {} without calling the API.
Grouped Aggregates
Add a { groupBy: [...columns] } second argument to get per-group breakdowns. Returns an array instead of a single object.
const rows = await copaInputTableDb
.collection("invoices")
.aggregate({ amount: ["sum"] }, { groupBy: ["status"] });
const rows = await copaInputTableDb
.collection("invoices")
.where("year", "==", 2024)
.orderBy("order_date", "asc")
.aggregate({ amount: ["sum", "avg"] }, { groupBy: ["order_date", "status"] });
const rows = await copaInputTableDb
.collection("invoices")
.aggregate({ _count: true }, { groupBy: ["status"] });
const rows = await copaInputTableDb
.collection("invoices")
.aggregate({}, { groupBy: ["status"] });
Notes:
orderBy() is forwarded to PostgREST when groupBy is present (ignored otherwise)
limit()/skip() apply to the number of groups, not input rows
- A column cannot appear in both the aggregate spec and
groupBy — throws InputTableError
- Empty
groupBy: [] behaves like no groupBy — returns a single object
Framework Integration
Svelte 5
<script>
import { copaInputTableDb } from "@bluecopa/core";
let rows = $state([]);
$effect(() =>
copaInputTableDb.collection("invoices")
.where("status", "==", "pending")
.subscribe((r) => { rows = r; })
);
</script>
React
useEffect(() => {
return copaInputTableDb.collection("invoices")
.where("status", "==", "pending")
.subscribe(setRows);
}, []);
Vanilla JS
const unsub = copaInputTableDb.collection("invoices").subscribe(setRows);
unsub();
WebSocket Provider (optional)
Enables realtime sync via push instead of polling:
import { copaSetConfig, copaInputTableDb, copaUtils } from "@bluecopa/core";
const ws = copaUtils.websocketUtils.WebsocketContextFactory.create("centrifugo", {
connectionUrl: "wss://...",
token: "jwt",
userId: "user-123",
});
copaSetConfig({ websocketProvider: ws });
copaInputTableDb.setWebsocketProvider(ws);
If no provider is set, the SDK still works via HTTP pull replication and logs a console warning.
Cleanup
await copaInputTableDb.destroy();
WebSocket Connection
The core package provides WebSocket utilities for real-time communication using Centrifugo.
WebSocket Factory
Access WebSocket functionality through the utilities:
import { copaUtils } from "@bluecopa/core";
const websocket = copaUtils.websocketUtils.WebsocketContextFactory.create(
"centrifugo",
{
connectionUrl: "wss://your-centrifugo-url",
},
);
WebSocket Provider Interface
The IWebsocketProvider interface provides the following methods:
connect(): Establishes the WebSocket connection
bind(channel: string, event: string, callback: (data: any) => void): Subscribe to private user-specific channels
bindGlobal(event: string, callback: (data: any) => void): Subscribe to global channels
unbindAll(channel: string): Unsubscribe from all events on a channel
disconnect(): Close the WebSocket connection
WebSocket Usage Example
import { copaSetConfig, copaApi, copaUtils } from "@bluecopa/core";
copaSetConfig({
apiBaseUrl: "https://develop.bluecopa.com",
accessToken: "your-access-token",
workspaceId: "your-workspace-id",
userId: "your-user-id",
});
const websocket = copaUtils.websocketUtils.WebsocketContextFactory.create(
"centrifugo",
{
connectionUrl: "wss://centrifugo.your-domain.com/connection/websocket",
},
);
websocket.bind("notifications", "new_message", (data) => {
console.log("New notification:", data);
});
websocket.bindGlobal("system_updates", (data) => {
console.log("System update:", data);
});
websocket.disconnect();
WebSocket Requirements
- userId: Required for private channel subscriptions (
bind method)
- accessToken: Required for authentication with Centrifugo
- connectionUrl: WebSocket endpoint URL
The WebSocket connection automatically uses the configured accessToken and userId from the config for authentication and channel binding.
Examples
1. Complete Setup with User Details and WebSocket
Complete example showing configuration, user details retrieval, and WebSocket setup.
import { copaSetConfig, copaApi, copaUtils } from "@bluecopa/core";
copaSetConfig({
apiBaseUrl: "https://develop.bluecopa.com",
accessToken: "your-access-token",
workspaceId: "your-workspace-id",
});
try {
const userDetails = await copaApi.user.getLoggedInUserDetails();
copaSetConfig({ userId: userDetails.id });
console.log("User configured:", userDetails.name, userDetails.id);
} catch (error: any) {
console.error("Failed to get user details:", error.message, error.status);
}
const websocket = copaUtils.websocketUtils.WebsocketContextFactory.create(
"centrifugo",
{
connectionUrl: "wss://centrifugo.develop.bluecopa.com/connection/websocket",
},
);
websocket.bind("notifications", "new_message", (data) => {
console.log("New notification received:", data);
});
2. Get Input Tables
Fetches all input tables from the API.
import { copaApi } from "@bluecopa/core";
copaSetConfig({
apiBaseUrl: "https://api.example.com",
accessToken: "token",
workspaceId: "ws1",
userId: "user123",
});
const { getInputTables } = copaApi.inputTable;
const { getWorkbooksByType } = copaApi.workbook;
3. Get Workbooks by Type
Retrieves workbooks filtered by a specific type.
import { copaApi } from "@bluecopa/core";
import type { Worksheet } from "$models/gen/Api";
try {
const workbooks = await copaApi.workbook.getWorkbooksByType(
"dashboard" as Worksheet["type"],
);
console.log(workbooks);
} catch (error: any) {
console.error(error.message, error.status);
}
Development
- Run the build:
npm run build (in the root or package-specific script)
- TypeScript configuration: See tsconfig.json
- Vite configuration: See vite.config.ts
Related Packages