@hybridb/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,220 @@
1
+ # @hybridb/sdk
2
+
3
+ **Official TypeScript SDK for the [Stellrai](https://stellrai.com) governed execution runtime.**
4
+
5
+ > Stellrai doesn't care how you built your app. It governs how it executes.
6
+
7
+ Build with any framework, any database, any stack. Route governed actions through `@hybridb/sdk` — and every critical operation becomes decided, audited, and reversible by default.
8
+
9
+ ---
10
+
11
+ ## What this SDK does
12
+
13
+ When your app needs to perform a **governed action** — an AI decision, a payment, identity resolution, an external provider call, or any audit-required state change — you route it through this SDK. Everything else in your app stays exactly as it was.
14
+
15
+ | Governed (use SDK) | Not governed (use any tool) |
16
+ |---|---|
17
+ | AI decisions and inferences | UI rendering |
18
+ | Payments and financial operations | Local database reads/writes |
19
+ | Identity resolution and auth | In-memory computation |
20
+ | External provider calls (Stripe, KYC, etc.) | Draft content and UI state |
21
+ | Audit-required state changes | Application configuration |
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install @hybridb/sdk
29
+ # or
30
+ pnpm add @hybridb/sdk
31
+ # or
32
+ yarn add @hybridb/sdk
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Quick start
38
+
39
+ ### 1. Get an API key
40
+
41
+ Sign up at [stellrai.com](https://stellrai.com) — free tier, no credit card required. Your API key is shown once at registration.
42
+
43
+ ### 2. Initialise the client
44
+
45
+ ```typescript
46
+ import { HybriDBClient } from '@hybridb/sdk';
47
+
48
+ const hdb = new HybriDBClient({
49
+ baseUrl: 'https://hybridb.stellrai.com',
50
+ apiKey: process.env.HYBRIDB_API_KEY!,
51
+ });
52
+ ```
53
+
54
+ ### 3. Trigger a governed pipeline
55
+
56
+ ```typescript
57
+ const execution = await hdb.triggerPipeline({
58
+ pipelineId: 'process-payment',
59
+ input: { userId: 'u_123', amount: 15000, currency: 'USD' },
60
+ idempotencyKey: crypto.randomUUID(),
61
+ });
62
+
63
+ console.log(execution.id); // exec_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
64
+ console.log(execution.status); // 'completed'
65
+ ```
66
+
67
+ ### 4. Rollback a failed execution
68
+
69
+ ```typescript
70
+ if (execution.status === 'failed') {
71
+ const result = await hdb.reversibility.rollback(execution.id, {
72
+ rollbackType: 'full',
73
+ reason: 'Payment processor returned 422',
74
+ });
75
+
76
+ console.log(result.outcome); // 'success'
77
+ console.log(result.stepsRolledBack); // ['charge', 'reserve', 'notify']
78
+ console.log(result.durationMs); // 2840
79
+ }
80
+ ```
81
+
82
+ ### 5. Replay from a checkpoint
83
+
84
+ ```typescript
85
+ const checkpoints = await hdb.reversibility.getCheckpoints(execution.id);
86
+
87
+ const replay = await hdb.reversibility.replay(execution.id, {
88
+ fromCheckpoint: checkpoints[1].id, // resume after step 2 — not from step zero
89
+ reason: 'Retry notification step after rate limit',
90
+ });
91
+
92
+ console.log(replay.newExecutionId); // new child execution
93
+ console.log(replay.parentExecutionId); // original execution
94
+ ```
95
+
96
+ ---
97
+
98
+ ## API reference
99
+
100
+ ### `HybriDBClient`
101
+
102
+ ```typescript
103
+ const hdb = new HybriDBClient({
104
+ baseUrl: string, // required — e.g. 'https://hybridb.stellrai.com'
105
+ apiKey: string, // required — your Stellrai API key
106
+ timeout?: number, // ms, default 10000
107
+ retries?: number, // default 3
108
+ retryDelay?: number, // ms, default 500
109
+ });
110
+ ```
111
+
112
+ ### Pipelines
113
+
114
+ ```typescript
115
+ hdb.triggerPipeline(input) // trigger a governed pipeline
116
+ hdb.getPipelineExecution(executionId) // get execution status
117
+ ```
118
+
119
+ ### Reversibility
120
+
121
+ ```typescript
122
+ hdb.reversibility.rollback(executionId, input) // rollback full / selective / to checkpoint
123
+ hdb.reversibility.replay(executionId, input) // replay from a specific checkpoint
124
+ hdb.reversibility.getCheckpoints(executionId) // list all checkpoints
125
+ hdb.reversibility.getCheckpoint(executionId, id) // get checkpoint (checksum-verified)
126
+ hdb.reversibility.getRollbackLog(executionId) // audit log of rollback operations
127
+ hdb.reversibility.getCircuitBreaker(pipelineId) // get circuit breaker status
128
+ hdb.reversibility.setCircuitBreaker(pipelineId, input) // open / close circuit breaker
129
+ ```
130
+
131
+ ### Decisions
132
+
133
+ ```typescript
134
+ hdb.requestDecision(request) // policy-governed decision
135
+ hdb.getDecision(decisionId) // retrieve a past decision
136
+ ```
137
+
138
+ ### Identity & Auth
139
+
140
+ ```typescript
141
+ hdb.authenticate(input) // email + password → token pair
142
+ hdb.refreshToken(refreshToken) // refresh an access token
143
+ hdb.revokeSession() // invalidate current session
144
+ hdb.verifyToken(token) // local JWT verification via JWKS (requires jose)
145
+ hdb.actors.createApiKey(actorId, input)
146
+ hdb.actors.revokeApiKey(actorId, keyId)
147
+ hdb.actors.createMapping(actorId, input)
148
+ hdb.orgs.addMember(orgId, input)
149
+ hdb.orgs.updateMemberRole(orgId, actorId, role)
150
+ hdb.orgs.revokeMember(orgId, actorId)
151
+ hdb.orgs.listMembers(orgId)
152
+ ```
153
+
154
+ ### Events & Audit
155
+
156
+ ```typescript
157
+ hdb.publishEvent(input) // publish a business event
158
+ hdb.queryAuditLog(params) // query the immutable audit log
159
+ hdb.health() // check API status
160
+ ```
161
+
162
+ ### React context (optional)
163
+
164
+ ```typescript
165
+ import { HybriDBProvider, useHybriDBClient } from '@hybridb/sdk/react';
166
+
167
+ // Wrap at app root
168
+ <HybriDBProvider client={hdb}>
169
+ {children}
170
+ </HybriDBProvider>
171
+
172
+ // Use in any component
173
+ const { client } = useHybriDBClient();
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Error handling
179
+
180
+ All SDK methods throw `HybriDBError` on failure. Never swallow these — they represent governance failures, not application errors.
181
+
182
+ ```typescript
183
+ import { HybriDBClient, HybriDBError } from '@hybridb/sdk';
184
+
185
+ try {
186
+ const execution = await hdb.triggerPipeline({ ... });
187
+ } catch (err) {
188
+ if (err instanceof HybriDBError) {
189
+ console.error(err.code); // e.g. 'POLICY_BLOCKED', 'RATE_LIMITED'
190
+ console.error(err.message); // human-readable description
191
+ console.error(err.details); // structured detail object (when present)
192
+ }
193
+ throw err; // let errors propagate — don't hide governance failures
194
+ }
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Requirements
200
+
201
+ - Node.js 18+
202
+ - TypeScript 5+ (optional but recommended)
203
+ - `jose` ^5.0 (only required if you use `hdb.verifyToken()` — auto-installed as dependency)
204
+ - React 18+ (only required for `@hybridb/sdk/react` — optional peer dependency)
205
+
206
+ ---
207
+
208
+ ## Links
209
+
210
+ - **Dashboard:** [stellrai.com/dashboard](https://stellrai.com/dashboard)
211
+ - **API Reference:** [hybridb.stellrai.com/docs](https://hybridb.stellrai.com/docs)
212
+ - **OpenAPI spec:** [hybridb.stellrai.com/openapi.json](https://hybridb.stellrai.com/openapi.json)
213
+ - **Status:** [hybridb.stellrai.com/health](https://hybridb.stellrai.com/health)
214
+ - **Issues:** [github.com/3pplea-Holdings/stellrai/issues](https://github.com/3pplea-Holdings/stellrai/issues)
215
+
216
+ ---
217
+
218
+ ## License
219
+
220
+ MIT © [3PPLEA Holdings LLC](https://stellrai.com)
@@ -0,0 +1,157 @@
1
+ import { TokenPair, ActorContext, UUID, IdentityMapping, OrgMembership, InitiateRollbackInput, RollbackResult, InitiateReplayInput, ReplayResult, CheckpointSummary, Checkpoint, RollbackLog, CircuitBreakerStatus, SetCircuitBreakerInput, DecisionInput, DecisionResponse, TriggerPipelineInput, PipelineExecution, PublishEventInput, HybriDBEvent, PaginatedResponse, AuditEntry } from './common/index.js';
2
+
3
+ interface HybriDBClientConfig {
4
+ baseUrl: string;
5
+ apiKey: string;
6
+ timeout?: number;
7
+ retries?: number;
8
+ retryDelay?: number;
9
+ }
10
+ interface AuthenticateInput {
11
+ email: string;
12
+ password: string;
13
+ orgId?: string;
14
+ }
15
+ interface CreateMappingInput {
16
+ providerId: string;
17
+ externalId: string;
18
+ userId: string;
19
+ actorId: string;
20
+ }
21
+ interface OrgMemberInput {
22
+ actorId: string;
23
+ role: string;
24
+ }
25
+ interface ApiKeyInput {
26
+ name?: string;
27
+ scopes: string[];
28
+ expiresAt?: string;
29
+ }
30
+ interface AuditQueryParams {
31
+ actorId?: string;
32
+ action?: string;
33
+ outcome?: string;
34
+ decisionId?: string;
35
+ sessionId?: string;
36
+ from?: string;
37
+ to?: string;
38
+ page?: number;
39
+ limit?: number;
40
+ }
41
+ declare class HybriDBClient {
42
+ private readonly baseUrl;
43
+ private readonly apiKey;
44
+ private readonly timeout;
45
+ private readonly retries;
46
+ private readonly retryDelay;
47
+ constructor(config: HybriDBClientConfig);
48
+ /** Exchange email + password for an access + refresh token pair. */
49
+ authenticate(input: AuthenticateInput): Promise<TokenPair>;
50
+ /** Refresh an access token using a refresh token. */
51
+ refreshToken(refreshToken: string): Promise<TokenPair>;
52
+ /** Revoke the current session (requires authenticated API key/JWT). */
53
+ revokeSession(): Promise<void>;
54
+ /**
55
+ * Verify a JWT token locally using JWKS from the hybriDB server.
56
+ * Returns the decoded actor context without making a decision API call.
57
+ * JWKS is cached for 1 hour (spec: Cache-Control: max-age=3600).
58
+ */
59
+ verifyToken(token: string): Promise<ActorContext>;
60
+ /** Fetch JWKS from the hybriDB server (cached for 1 hour). */
61
+ getJwks(): Promise<{
62
+ keys: Record<string, unknown>[];
63
+ }>;
64
+ /** Namespace for actor management operations. */
65
+ readonly actors: {
66
+ /** Issue an API key for an actor. Requires actor:admin scope. */
67
+ readonly createApiKey: (actorId: UUID, input: ApiKeyInput) => Promise<{
68
+ id: string;
69
+ key: string;
70
+ }>;
71
+ /** Revoke an API key. Requires actor:admin scope. */
72
+ readonly revokeApiKey: (actorId: UUID, keyId: UUID) => Promise<void>;
73
+ /** Create an identity mapping (external provider → actor). Requires actor:write scope. */
74
+ readonly createMapping: (actorId: UUID, input: CreateMappingInput) => Promise<IdentityMapping>;
75
+ };
76
+ /** Namespace for organisation membership operations. */
77
+ readonly orgs: {
78
+ /** Add a member to an organisation. Requires org:admin scope. */
79
+ readonly addMember: (orgId: UUID, input: OrgMemberInput) => Promise<OrgMembership>;
80
+ /** Update a member's role. Requires org:admin scope. */
81
+ readonly updateMemberRole: (orgId: UUID, actorId: UUID, role: string) => Promise<OrgMembership>;
82
+ /** Revoke an actor's membership. Requires org:admin scope. */
83
+ readonly revokeMember: (orgId: UUID, actorId: UUID) => Promise<void>;
84
+ /** List organisation members. Requires org:read scope. */
85
+ readonly listMembers: (orgId: UUID) => Promise<OrgMembership[]>;
86
+ };
87
+ /** Namespace for Reversible Autonomy operations (v2.4). */
88
+ readonly reversibility: {
89
+ /**
90
+ * Initiate a rollback for an execution.
91
+ * Types: 'full' (all steps), 'selective' (targetSteps list), 'to_checkpoint'.
92
+ * Requires pipeline:rollback scope.
93
+ */
94
+ readonly rollback: (executionId: UUID, input: Omit<InitiateRollbackInput, "executionId">) => Promise<RollbackResult>;
95
+ /**
96
+ * Initiate a replay from a checkpoint.
97
+ * Creates a new child execution starting from the checkpoint's step.
98
+ * Requires pipeline:replay scope.
99
+ */
100
+ readonly replay: (executionId: UUID, input: Omit<InitiateReplayInput, "executionId">) => Promise<ReplayResult>;
101
+ /**
102
+ * List all checkpoints for an execution (ordered by step_index asc).
103
+ * Requires pipeline:read scope.
104
+ */
105
+ readonly getCheckpoints: (executionId: UUID) => Promise<CheckpointSummary[]>;
106
+ /**
107
+ * Get a specific checkpoint (with checksum verification).
108
+ * Throws REPLAY_CONTEXT_INVALID if checksum mismatches.
109
+ * Requires pipeline:read scope.
110
+ */
111
+ readonly getCheckpoint: (executionId: UUID, checkpointId: UUID) => Promise<Checkpoint>;
112
+ /**
113
+ * List all rollback log entries for an execution.
114
+ * Requires pipeline:read scope.
115
+ */
116
+ readonly getRollbackLog: (executionId: UUID) => Promise<RollbackLog[]>;
117
+ /**
118
+ * Get circuit breaker status for a pipeline.
119
+ * Requires pipeline:read scope.
120
+ */
121
+ readonly getCircuitBreaker: (pipelineId: UUID) => Promise<CircuitBreakerStatus>;
122
+ /**
123
+ * Open or close the circuit breaker for a pipeline.
124
+ * Opening halts all future executions immediately.
125
+ * Requires pipeline:circuit_breaker scope.
126
+ */
127
+ readonly setCircuitBreaker: (pipelineId: UUID, input: Omit<SetCircuitBreakerInput, "pipelineId">) => Promise<CircuitBreakerStatus>;
128
+ };
129
+ requestDecision(request: DecisionInput): Promise<DecisionResponse>;
130
+ getDecision(decisionId: UUID): Promise<DecisionResponse>;
131
+ triggerPipeline(input: TriggerPipelineInput): Promise<PipelineExecution>;
132
+ getPipelineExecution(executionId: UUID): Promise<PipelineExecution>;
133
+ /** Publish a business event. Note: use actorId (v1.2), not identityId. */
134
+ publishEvent(input: PublishEventInput): Promise<HybriDBEvent>;
135
+ queryAuditLog(params: AuditQueryParams): Promise<PaginatedResponse<AuditEntry>>;
136
+ health(): Promise<{
137
+ status: string;
138
+ version: string;
139
+ }>;
140
+ private get;
141
+ private getPublic;
142
+ private post;
143
+ private postPublic;
144
+ private patch;
145
+ private delete;
146
+ private request;
147
+ private unwrap;
148
+ private isRetryable;
149
+ private sleep;
150
+ }
151
+ declare class HybriDBError extends Error {
152
+ readonly code: string;
153
+ readonly details?: Record<string, unknown> | undefined;
154
+ constructor(code: string, message: string, details?: Record<string, unknown> | undefined);
155
+ }
156
+
157
+ export { type ApiKeyInput as A, type CreateMappingInput as C, HybriDBClient as H, type OrgMemberInput as O, type AuditQueryParams as a, type AuthenticateInput as b, type HybriDBClientConfig as c, HybriDBError as d };
@@ -0,0 +1,157 @@
1
+ import { TokenPair, ActorContext, UUID, IdentityMapping, OrgMembership, InitiateRollbackInput, RollbackResult, InitiateReplayInput, ReplayResult, CheckpointSummary, Checkpoint, RollbackLog, CircuitBreakerStatus, SetCircuitBreakerInput, DecisionInput, DecisionResponse, TriggerPipelineInput, PipelineExecution, PublishEventInput, HybriDBEvent, PaginatedResponse, AuditEntry } from './common/index.js';
2
+
3
+ interface HybriDBClientConfig {
4
+ baseUrl: string;
5
+ apiKey: string;
6
+ timeout?: number;
7
+ retries?: number;
8
+ retryDelay?: number;
9
+ }
10
+ interface AuthenticateInput {
11
+ email: string;
12
+ password: string;
13
+ orgId?: string;
14
+ }
15
+ interface CreateMappingInput {
16
+ providerId: string;
17
+ externalId: string;
18
+ userId: string;
19
+ actorId: string;
20
+ }
21
+ interface OrgMemberInput {
22
+ actorId: string;
23
+ role: string;
24
+ }
25
+ interface ApiKeyInput {
26
+ name?: string;
27
+ scopes: string[];
28
+ expiresAt?: string;
29
+ }
30
+ interface AuditQueryParams {
31
+ actorId?: string;
32
+ action?: string;
33
+ outcome?: string;
34
+ decisionId?: string;
35
+ sessionId?: string;
36
+ from?: string;
37
+ to?: string;
38
+ page?: number;
39
+ limit?: number;
40
+ }
41
+ declare class HybriDBClient {
42
+ private readonly baseUrl;
43
+ private readonly apiKey;
44
+ private readonly timeout;
45
+ private readonly retries;
46
+ private readonly retryDelay;
47
+ constructor(config: HybriDBClientConfig);
48
+ /** Exchange email + password for an access + refresh token pair. */
49
+ authenticate(input: AuthenticateInput): Promise<TokenPair>;
50
+ /** Refresh an access token using a refresh token. */
51
+ refreshToken(refreshToken: string): Promise<TokenPair>;
52
+ /** Revoke the current session (requires authenticated API key/JWT). */
53
+ revokeSession(): Promise<void>;
54
+ /**
55
+ * Verify a JWT token locally using JWKS from the hybriDB server.
56
+ * Returns the decoded actor context without making a decision API call.
57
+ * JWKS is cached for 1 hour (spec: Cache-Control: max-age=3600).
58
+ */
59
+ verifyToken(token: string): Promise<ActorContext>;
60
+ /** Fetch JWKS from the hybriDB server (cached for 1 hour). */
61
+ getJwks(): Promise<{
62
+ keys: Record<string, unknown>[];
63
+ }>;
64
+ /** Namespace for actor management operations. */
65
+ readonly actors: {
66
+ /** Issue an API key for an actor. Requires actor:admin scope. */
67
+ readonly createApiKey: (actorId: UUID, input: ApiKeyInput) => Promise<{
68
+ id: string;
69
+ key: string;
70
+ }>;
71
+ /** Revoke an API key. Requires actor:admin scope. */
72
+ readonly revokeApiKey: (actorId: UUID, keyId: UUID) => Promise<void>;
73
+ /** Create an identity mapping (external provider → actor). Requires actor:write scope. */
74
+ readonly createMapping: (actorId: UUID, input: CreateMappingInput) => Promise<IdentityMapping>;
75
+ };
76
+ /** Namespace for organisation membership operations. */
77
+ readonly orgs: {
78
+ /** Add a member to an organisation. Requires org:admin scope. */
79
+ readonly addMember: (orgId: UUID, input: OrgMemberInput) => Promise<OrgMembership>;
80
+ /** Update a member's role. Requires org:admin scope. */
81
+ readonly updateMemberRole: (orgId: UUID, actorId: UUID, role: string) => Promise<OrgMembership>;
82
+ /** Revoke an actor's membership. Requires org:admin scope. */
83
+ readonly revokeMember: (orgId: UUID, actorId: UUID) => Promise<void>;
84
+ /** List organisation members. Requires org:read scope. */
85
+ readonly listMembers: (orgId: UUID) => Promise<OrgMembership[]>;
86
+ };
87
+ /** Namespace for Reversible Autonomy operations (v2.4). */
88
+ readonly reversibility: {
89
+ /**
90
+ * Initiate a rollback for an execution.
91
+ * Types: 'full' (all steps), 'selective' (targetSteps list), 'to_checkpoint'.
92
+ * Requires pipeline:rollback scope.
93
+ */
94
+ readonly rollback: (executionId: UUID, input: Omit<InitiateRollbackInput, "executionId">) => Promise<RollbackResult>;
95
+ /**
96
+ * Initiate a replay from a checkpoint.
97
+ * Creates a new child execution starting from the checkpoint's step.
98
+ * Requires pipeline:replay scope.
99
+ */
100
+ readonly replay: (executionId: UUID, input: Omit<InitiateReplayInput, "executionId">) => Promise<ReplayResult>;
101
+ /**
102
+ * List all checkpoints for an execution (ordered by step_index asc).
103
+ * Requires pipeline:read scope.
104
+ */
105
+ readonly getCheckpoints: (executionId: UUID) => Promise<CheckpointSummary[]>;
106
+ /**
107
+ * Get a specific checkpoint (with checksum verification).
108
+ * Throws REPLAY_CONTEXT_INVALID if checksum mismatches.
109
+ * Requires pipeline:read scope.
110
+ */
111
+ readonly getCheckpoint: (executionId: UUID, checkpointId: UUID) => Promise<Checkpoint>;
112
+ /**
113
+ * List all rollback log entries for an execution.
114
+ * Requires pipeline:read scope.
115
+ */
116
+ readonly getRollbackLog: (executionId: UUID) => Promise<RollbackLog[]>;
117
+ /**
118
+ * Get circuit breaker status for a pipeline.
119
+ * Requires pipeline:read scope.
120
+ */
121
+ readonly getCircuitBreaker: (pipelineId: UUID) => Promise<CircuitBreakerStatus>;
122
+ /**
123
+ * Open or close the circuit breaker for a pipeline.
124
+ * Opening halts all future executions immediately.
125
+ * Requires pipeline:circuit_breaker scope.
126
+ */
127
+ readonly setCircuitBreaker: (pipelineId: UUID, input: Omit<SetCircuitBreakerInput, "pipelineId">) => Promise<CircuitBreakerStatus>;
128
+ };
129
+ requestDecision(request: DecisionInput): Promise<DecisionResponse>;
130
+ getDecision(decisionId: UUID): Promise<DecisionResponse>;
131
+ triggerPipeline(input: TriggerPipelineInput): Promise<PipelineExecution>;
132
+ getPipelineExecution(executionId: UUID): Promise<PipelineExecution>;
133
+ /** Publish a business event. Note: use actorId (v1.2), not identityId. */
134
+ publishEvent(input: PublishEventInput): Promise<HybriDBEvent>;
135
+ queryAuditLog(params: AuditQueryParams): Promise<PaginatedResponse<AuditEntry>>;
136
+ health(): Promise<{
137
+ status: string;
138
+ version: string;
139
+ }>;
140
+ private get;
141
+ private getPublic;
142
+ private post;
143
+ private postPublic;
144
+ private patch;
145
+ private delete;
146
+ private request;
147
+ private unwrap;
148
+ private isRetryable;
149
+ private sleep;
150
+ }
151
+ declare class HybriDBError extends Error {
152
+ readonly code: string;
153
+ readonly details?: Record<string, unknown> | undefined;
154
+ constructor(code: string, message: string, details?: Record<string, unknown> | undefined);
155
+ }
156
+
157
+ export { type ApiKeyInput as A, type CreateMappingInput as C, HybriDBClient as H, type OrgMemberInput as O, type AuditQueryParams as a, type AuthenticateInput as b, type HybriDBClientConfig as c, HybriDBError as d };