Current collected state Current
Observed since 21 Oct, 09:19 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
@0xobelisk/grpc-client
Toolkit for interacting with dubhe gRPC indexer
TypeScript gRPC client for interacting with the Dubhe Indexer using protobuf-ts.
npm install @0xobelisk/grpc-client
import { createDubheGrpcClient } from '@0xobelisk/grpc-client';
const client = createDubheGrpcClient({
endpoint: '127.0.0.1:8080', // gRPC server endpoint (without http://)
timeout: 10000,
enableRetry: true,
retryAttempts: 3
});
await client.connect();
console.log('Connected successfully!');
// Basic query - get all data with pagination
const response = await client.query('users', {
pageSize: 10,
includeTotalCount: true
});
// Query with field selection
const response = await client.query('users', {
select: ['id', 'name', 'email'],
pageSize: 20
});
// Query with filtering
const response = await client.query('users', {
where: {
status: 'active',
role: ['admin', 'user'], // IN operator
age: { min: 18, max: 65 } // BETWEEN operator
},
orderBy: [
{ field: 'created_at', direction: 'desc' },
{ field: 'name', direction: 'asc' }
],
page: 1,
pageSize: 20,
includeTotalCount: true
});
import { FilterOperator, SortDirection } from '@0xobelisk/grpc-client';
const response = await client.queryTable({
tableName: 'users',
selectFields: ['id', 'name', 'created_at'],
filters: [
{
fieldName: 'name',
operator: FilterOperator.LIKE,
value: { stringValue: '%john%' }
},
{
fieldName: 'age',
operator: FilterOperator.GREATER_THAN,
value: { intValue: 18 }
},
{
fieldName: 'status',
operator: FilterOperator.IN,
value: { stringList: { values: ['active', 'pending'] } }
}
],
sorts: [
{
fieldName: 'created_at',
direction: SortDirection.DESCENDING,
priority: 0
}
],
pagination: {
page: 1,
pageSize: 10
},
includeTotalCount: true
});
const response = await client
.createQueryBuilder()
.tableName('users')
.select('id', 'name', 'email')
.where({
status: 'active',
role: ['admin', 'user']
})
.orderBy('created_at', 'desc')
.page(1, 15)
.includeTotalCount(true)
.execute();
const subscriptionId = client.subscribeTable(
['users', 'posts'], // table names to subscribe to
{
onUpdate: (change) => {
console.log(`Table updated: ${change.table_id}`);
console.log('New data:', change.data);
},
onError: (error) => {
console.error('Subscription error:', error);
},
onConnect: () => {
console.log('Subscription connected');
},
onDisconnect: () => {
console.log('Subscription disconnected');
}
}
);
console.log(`Subscription ID: ${subscriptionId}`);
// Later, unsubscribe
client.unsubscribe(subscriptionId);
interface DubheGrpcClientConfig {
endpoint: string; // gRPC server endpoint
enableRetry?: boolean; // Enable automatic retry (default: true)
retryAttempts?: number; // Number of retry attempts (default: 3)
timeout?: number; // Request timeout in ms (default: 30000)
}
The client supports various filter operators:
import { FilterOperator } from '@0xobelisk/grpc-client';
// Available operators:
FilterOperator.EQUALS;
FilterOperator.NOT_EQUALS;
FilterOperator.GREATER_THAN;
FilterOperator.GREATER_THAN_EQUAL;
FilterOperator.LESS_THAN;
FilterOperator.LESS_THAN_EQUAL;
FilterOperator.LIKE;
FilterOperator.NOT_LIKE;
FilterOperator.IN;
FilterOperator.NOT_IN;
FilterOperator.IS_NULL;
FilterOperator.IS_NOT_NULL;
FilterOperator.BETWEEN;
FilterOperator.NOT_BETWEEN;
import { GrpcUtils } from '@0xobelisk/grpc-client';
// Extract field from data
const value = GrpcUtils.extractField(data, 'fieldName');
// Convert protobuf struct to object
const obj = GrpcUtils.structToObject(struct);
// Check if error is gRPC error
if (GrpcUtils.isGrpcError(error, 404)) {
console.log('Not found error');
}
// Format error for display
const message = GrpcUtils.formatGrpcError(error);
import { DataUtils, QueryUtils, ValidationUtils } from '@0xobelisk/grpc-client';
// Build filters easily
const filters = [
QueryUtils.equals('status', 'active'),
QueryUtils.in('role', ['admin', 'user']),
QueryUtils.like('name', '%john%'),
QueryUtils.between('age', 18, 65),
QueryUtils.isNotNull('email')
];
// Data manipulation
const flattened = DataUtils.flatten(nestedObject);
const merged = DataUtils.deepMerge(obj1, obj2);
const picked = DataUtils.pick(object, ['field1', 'field2']);
// Validation
const isValid = ValidationUtils.isValidTableName('users');
const isValidField = ValidationUtils.isValidFieldName('user.name');
import { ErrorUtils } from '@0xobelisk/grpc-client';
try {
const response = await client.query('users');
} catch (error) {
if (ErrorUtils.isTimeoutError(error)) {
console.log('Request timed out');
} else if (ErrorUtils.isConnectionError(error)) {
console.log('Connection failed');
} else {
console.log('Other error:', ErrorUtils.formatError(error));
}
}
// Check connection status
console.log('Status:', client.getStatus()); // 'connected', 'connecting', 'disconnected', 'error'
// Check if connected
if (client.isConnected()) {
console.log('Client is ready');
}
// Get active subscriptions
console.log('Active subscriptions:', client.getActiveSubscriptionCount());
console.log('Subscription IDs:', client.getActiveSubscriptionIds());
// Disconnect
client.disconnect();
import {
createDubheGrpcClient,
FilterOperator,
SortDirection,
GrpcUtils
} from '@0xobelisk/grpc-client';
async function example() {
// Create and connect client
const client = createDubheGrpcClient({
endpoint: '127.0.0.1:8080',
timeout: 10000
});
await client.connect();
try {
// Query data
const users = await client.query('users', {
where: { status: 'active' },
orderBy: [{ field: 'created_at', direction: 'desc' }],
pageSize: 10,
includeTotalCount: true
});
console.log(`Found ${users.totalCount} users`);
console.log('Users:', users.data);
// Subscribe to updates
const subscriptionId = client.subscribeTable(['users'], {
onUpdate: (change) => {
console.log('User updated:', change.data);
},
onError: (error) => {
console.error('Subscription error:', GrpcUtils.formatGrpcError(error));
}
});
// Cleanup on exit
process.on('SIGINT', () => {
client.unsubscribe(subscriptionId);
client.disconnect();
process.exit(0);
});
} catch (error) {
console.error('Query failed:', GrpcUtils.formatGrpcError(error));
}
}
example();
For advanced usage, you can access the raw protobuf types:
import {
ProtoDubheGrpcClient,
ProtoQueryRequest,
ProtoQueryResponse
} from '@0xobelisk/grpc-client';
// Direct access to protobuf client if needed
const protoClient = new ProtoDubheGrpcClient(transport);
npm run generate
This command will:
.proto filesnpm run build
npm run lint
npm run lint:fix
The v2.x version introduces several breaking changes:
@protobuf-ts/grpcweb-transport instead of @grpc/grpc-jsclient.on('connect', () => console.log('Connected'));
client.on('error', (error) => console.error(error));
// Connection status is handled through method calls
await client.connect();
if (client.isConnected()) {
console.log('Connected');
}
// Error handling through try-catch
try {
await client.query('table');
} catch (error) {
console.error(error);
}
Apache-2.0
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
@protobuf-ts/runtimeEnvironment{
"local_name": "@protobuf-ts/runtime",
"alias": false,
"peer_metadata": null
} | ^2.11.1 | runtime |
@protobuf-ts/runtime-rpcEnvironment{
"local_name": "@protobuf-ts/runtime-rpc",
"alias": false,
"peer_metadata": null
} | ^2.11.1 | runtime |
@protobuf-ts/grpcweb-transportEnvironment{
"local_name": "@protobuf-ts/grpcweb-transport",
"alias": false,
"peer_metadata": null
} | ^2.11.1 | runtime |
tsupEnvironment{
"local_name": "tsup",
"alias": false,
"peer_metadata": null
} | ^7.1.0 | development |
dotenvEnvironment{
"local_name": "dotenv",
"alias": false,
"peer_metadata": null
} | ^16.3.1 | development |
eslintEnvironment{
"local_name": "eslint",
"alias": false,
"peer_metadata": null
} | ^9.0.0 | development |
ts-nodeEnvironment{
"local_name": "ts-node",
"alias": false,
"peer_metadata": null
} | ^10.9.2 | development |
prettierEnvironment{
"local_name": "prettier",
"alias": false,
"peer_metadata": null
} | 3.3.3 | development |
typescriptEnvironment{
"local_name": "typescript",
"alias": false,
"peer_metadata": null
} | ^5.2.2 | development |
@types/nodeEnvironment{
"local_name": "@types/node",
"alias": false,
"peer_metadata": null
} | ^24.2.0 | development |
tsconfig-pathsEnvironment{
"local_name": "tsconfig-paths",
"alias": false,
"peer_metadata": null
} | ^4.2.0 | development |
@protobuf-ts/pluginEnvironment{
"local_name": "@protobuf-ts/plugin",
"alias": false,
"peer_metadata": null
} | ^2.11.1 | development |
eslint-config-prettierEnvironment{
"local_name": "eslint-config-prettier",
"alias": false,
"peer_metadata": null
} | ^9.1.0 | development |
Source distribution
{
"shasum": "43c5099a9d1e0b5d90e329e810f3f6dae6b41f92",
"tarball": "https://registry.npmjs.org/@0xobelisk/grpc-client/-/grpc-client-1.2.0-pre.87.tgz",
"fileCount": 23,
"integrity": "sha512-dkF/JI1iKfYdKmRsLVApgmi0q4SIKUh2yGAESjzPP6DgN7unt841gMwtamxxidG3eRcBxNmBM2Hlm9t80aX6yA==",
"signatures": [
{
"sig": "MEUCIGvikZG3ZbA8l+bnxWSiyVr193TCDm0dsgWGqYmurW1uAiEA1yte312DtMGyyERq79erxAY2YIbU1pKlu6BmROKqYew=",
"keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
}
],
"unpackedSize": 256063
}Observed since 21 Oct, 09:19 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:3dd87fcff528a42ecdaed47f0081ceaa65efe4ae244700ef8ca7d0bb783ee2c2