@debros/orama 0.122.4-nightly

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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +665 -0
  3. package/dist/index.d.ts +1334 -0
  4. package/dist/index.js +2553 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +82 -0
  7. package/src/auth/client.ts +276 -0
  8. package/src/auth/index.ts +3 -0
  9. package/src/auth/types.ts +62 -0
  10. package/src/cache/client.ts +203 -0
  11. package/src/cache/index.ts +14 -0
  12. package/src/core/http.ts +541 -0
  13. package/src/core/index.ts +10 -0
  14. package/src/core/interfaces/IAuthStrategy.ts +28 -0
  15. package/src/core/interfaces/IHttpTransport.ts +73 -0
  16. package/src/core/interfaces/IRetryPolicy.ts +20 -0
  17. package/src/core/interfaces/IWebSocketClient.ts +60 -0
  18. package/src/core/interfaces/index.ts +4 -0
  19. package/src/core/transport/AuthHeaderStrategy.ts +108 -0
  20. package/src/core/transport/RequestLogger.ts +116 -0
  21. package/src/core/transport/RequestRetryPolicy.ts +53 -0
  22. package/src/core/transport/TLSConfiguration.ts +53 -0
  23. package/src/core/transport/index.ts +4 -0
  24. package/src/core/ws.ts +246 -0
  25. package/src/db/client.ts +126 -0
  26. package/src/db/index.ts +13 -0
  27. package/src/db/qb.ts +111 -0
  28. package/src/db/repository.ts +128 -0
  29. package/src/db/types.ts +67 -0
  30. package/src/errors.ts +38 -0
  31. package/src/functions/client.ts +62 -0
  32. package/src/functions/index.ts +2 -0
  33. package/src/functions/types.ts +21 -0
  34. package/src/index.ts +201 -0
  35. package/src/network/client.ts +119 -0
  36. package/src/network/index.ts +7 -0
  37. package/src/pubsub/client.ts +361 -0
  38. package/src/pubsub/index.ts +12 -0
  39. package/src/pubsub/types.ts +46 -0
  40. package/src/storage/client.ts +272 -0
  41. package/src/storage/index.ts +7 -0
  42. package/src/utils/codec.ts +68 -0
  43. package/src/utils/index.ts +3 -0
  44. package/src/utils/platform.ts +44 -0
  45. package/src/utils/retry.ts +58 -0
  46. package/src/vault/auth.ts +98 -0
  47. package/src/vault/client.ts +197 -0
  48. package/src/vault/crypto/aes.ts +271 -0
  49. package/src/vault/crypto/hkdf.ts +42 -0
  50. package/src/vault/crypto/index.ts +27 -0
  51. package/src/vault/crypto/shamir.ts +173 -0
  52. package/src/vault/index.ts +65 -0
  53. package/src/vault/quorum.ts +16 -0
  54. package/src/vault/transport/fanout.ts +94 -0
  55. package/src/vault/transport/guardian.ts +285 -0
  56. package/src/vault/transport/index.ts +19 -0
  57. package/src/vault/transport/types.ts +101 -0
  58. package/src/vault/types.ts +62 -0
@@ -0,0 +1,126 @@
1
+ import { HttpClient } from "../core/http";
2
+ import { QueryBuilder } from "./qb";
3
+ import { Repository } from "./repository";
4
+ import {
5
+ QueryResponse,
6
+ TransactionOp,
7
+ TransactionRequest,
8
+ Entity,
9
+ FindOptions,
10
+ } from "./types";
11
+
12
+ export class DBClient {
13
+ private httpClient: HttpClient;
14
+
15
+ constructor(httpClient: HttpClient) {
16
+ this.httpClient = httpClient;
17
+ }
18
+
19
+ /**
20
+ * Execute a write/DDL SQL statement.
21
+ */
22
+ async exec(
23
+ sql: string,
24
+ args: any[] = []
25
+ ): Promise<{ rows_affected: number; last_insert_id?: number }> {
26
+ return this.httpClient.post("/v1/rqlite/exec", { sql, args });
27
+ }
28
+
29
+ /**
30
+ * Execute a SELECT query.
31
+ */
32
+ async query<T = any>(sql: string, args: any[] = []): Promise<T[]> {
33
+ const response = await this.httpClient.post<QueryResponse>(
34
+ "/v1/rqlite/query",
35
+ { sql, args }
36
+ );
37
+ return response.items || [];
38
+ }
39
+
40
+ /**
41
+ * Find rows with map-based criteria.
42
+ */
43
+ async find<T = any>(
44
+ table: string,
45
+ criteria: Record<string, any> = {},
46
+ options: FindOptions = {}
47
+ ): Promise<T[]> {
48
+ const response = await this.httpClient.post<QueryResponse>(
49
+ "/v1/rqlite/find",
50
+ {
51
+ table,
52
+ criteria,
53
+ options,
54
+ }
55
+ );
56
+ return response.items || [];
57
+ }
58
+
59
+ /**
60
+ * Find a single row with map-based criteria.
61
+ */
62
+ async findOne<T = any>(
63
+ table: string,
64
+ criteria: Record<string, any>
65
+ ): Promise<T | null> {
66
+ return this.httpClient.post<T | null>("/v1/rqlite/find-one", {
67
+ table,
68
+ criteria,
69
+ });
70
+ }
71
+
72
+ /**
73
+ * Create a fluent QueryBuilder for complex SELECT queries.
74
+ */
75
+ createQueryBuilder(table: string): QueryBuilder {
76
+ return new QueryBuilder(this.httpClient, table);
77
+ }
78
+
79
+ /**
80
+ * Create a Repository for entity-based operations.
81
+ */
82
+ repository<T extends Record<string, any>>(
83
+ tableName: string,
84
+ primaryKey = "id"
85
+ ): Repository<T> {
86
+ return new Repository(this.httpClient, tableName, primaryKey);
87
+ }
88
+
89
+ /**
90
+ * Execute multiple operations atomically.
91
+ */
92
+ async transaction(
93
+ ops: TransactionOp[],
94
+ returnResults = true
95
+ ): Promise<any[]> {
96
+ const response = await this.httpClient.post<{ results?: any[] }>(
97
+ "/v1/rqlite/transaction",
98
+ {
99
+ ops,
100
+ return_results: returnResults,
101
+ }
102
+ );
103
+ return response.results || [];
104
+ }
105
+
106
+ /**
107
+ * Create a table from DDL SQL.
108
+ */
109
+ async createTable(schema: string): Promise<void> {
110
+ await this.httpClient.post("/v1/rqlite/create-table", { schema });
111
+ }
112
+
113
+ /**
114
+ * Drop a table.
115
+ */
116
+ async dropTable(table: string): Promise<void> {
117
+ await this.httpClient.post("/v1/rqlite/drop-table", { table });
118
+ }
119
+
120
+ /**
121
+ * Get current database schema.
122
+ */
123
+ async getSchema(): Promise<any> {
124
+ return this.httpClient.get("/v1/rqlite/schema");
125
+ }
126
+ }
@@ -0,0 +1,13 @@
1
+ export { DBClient } from "./client";
2
+ export { QueryBuilder } from "./qb";
3
+ export { Repository } from "./repository";
4
+ export type {
5
+ Entity,
6
+ QueryResponse,
7
+ TransactionOp,
8
+ TransactionRequest,
9
+ SelectOptions,
10
+ FindOptions,
11
+ ColumnDefinition,
12
+ } from "./types";
13
+ export { extractTableName, extractPrimaryKey } from "./types";
package/src/db/qb.ts ADDED
@@ -0,0 +1,111 @@
1
+ import { HttpClient } from "../core/http";
2
+ import { SelectOptions, QueryResponse } from "./types";
3
+
4
+ export class QueryBuilder {
5
+ private httpClient: HttpClient;
6
+ private table: string;
7
+ private options: SelectOptions = {};
8
+
9
+ constructor(httpClient: HttpClient, table: string) {
10
+ this.httpClient = httpClient;
11
+ this.table = table;
12
+ }
13
+
14
+ select(...columns: string[]): this {
15
+ this.options.select = columns;
16
+ return this;
17
+ }
18
+
19
+ innerJoin(table: string, on: string): this {
20
+ if (!this.options.joins) this.options.joins = [];
21
+ this.options.joins.push({ kind: "INNER", table, on });
22
+ return this;
23
+ }
24
+
25
+ leftJoin(table: string, on: string): this {
26
+ if (!this.options.joins) this.options.joins = [];
27
+ this.options.joins.push({ kind: "LEFT", table, on });
28
+ return this;
29
+ }
30
+
31
+ rightJoin(table: string, on: string): this {
32
+ if (!this.options.joins) this.options.joins = [];
33
+ this.options.joins.push({ kind: "RIGHT", table, on });
34
+ return this;
35
+ }
36
+
37
+ where(expr: string, args?: any[]): this {
38
+ if (!this.options.where) this.options.where = [];
39
+ this.options.where.push({ conj: "AND", expr, args });
40
+ return this;
41
+ }
42
+
43
+ andWhere(expr: string, args?: any[]): this {
44
+ return this.where(expr, args);
45
+ }
46
+
47
+ orWhere(expr: string, args?: any[]): this {
48
+ if (!this.options.where) this.options.where = [];
49
+ this.options.where.push({ conj: "OR", expr, args });
50
+ return this;
51
+ }
52
+
53
+ groupBy(...columns: string[]): this {
54
+ this.options.group_by = columns;
55
+ return this;
56
+ }
57
+
58
+ orderBy(...columns: string[]): this {
59
+ this.options.order_by = columns;
60
+ return this;
61
+ }
62
+
63
+ limit(n: number): this {
64
+ this.options.limit = n;
65
+ return this;
66
+ }
67
+
68
+ offset(n: number): this {
69
+ this.options.offset = n;
70
+ return this;
71
+ }
72
+
73
+ async getMany<T = any>(ctx?: any): Promise<T[]> {
74
+ const response = await this.httpClient.post<QueryResponse>(
75
+ "/v1/rqlite/select",
76
+ {
77
+ table: this.table,
78
+ ...this.options,
79
+ }
80
+ );
81
+ return response.items || [];
82
+ }
83
+
84
+ async getOne<T = any>(ctx?: any): Promise<T | null> {
85
+ const response = await this.httpClient.post<QueryResponse>(
86
+ "/v1/rqlite/select",
87
+ {
88
+ table: this.table,
89
+ ...this.options,
90
+ one: true,
91
+ limit: 1,
92
+ }
93
+ );
94
+ const items = response.items || [];
95
+ return items.length > 0 ? items[0] : null;
96
+ }
97
+
98
+ async count(): Promise<number> {
99
+ const response = await this.httpClient.post<QueryResponse>(
100
+ "/v1/rqlite/select",
101
+ {
102
+ table: this.table,
103
+ select: ["COUNT(*) AS count"],
104
+ where: this.options.where,
105
+ one: true,
106
+ }
107
+ );
108
+ const items = response.items || [];
109
+ return items.length > 0 ? items[0].count : 0;
110
+ }
111
+ }
@@ -0,0 +1,128 @@
1
+ import { HttpClient } from "../core/http";
2
+ import { QueryBuilder } from "./qb";
3
+ import { QueryResponse, FindOptions } from "./types";
4
+ import { SDKError } from "../errors";
5
+
6
+ export class Repository<T extends Record<string, any>> {
7
+ private httpClient: HttpClient;
8
+ private tableName: string;
9
+ private primaryKey: string;
10
+
11
+ constructor(httpClient: HttpClient, tableName: string, primaryKey = "id") {
12
+ this.httpClient = httpClient;
13
+ this.tableName = tableName;
14
+ this.primaryKey = primaryKey;
15
+ }
16
+
17
+ createQueryBuilder(): QueryBuilder {
18
+ return new QueryBuilder(this.httpClient, this.tableName);
19
+ }
20
+
21
+ async find(
22
+ criteria: Record<string, any> = {},
23
+ options: FindOptions = {}
24
+ ): Promise<T[]> {
25
+ const response = await this.httpClient.post<QueryResponse>(
26
+ "/v1/rqlite/find",
27
+ {
28
+ table: this.tableName,
29
+ criteria,
30
+ options,
31
+ }
32
+ );
33
+ return response.items || [];
34
+ }
35
+
36
+ async findOne(criteria: Record<string, any>): Promise<T | null> {
37
+ try {
38
+ const response = await this.httpClient.post<T | null>(
39
+ "/v1/rqlite/find-one",
40
+ {
41
+ table: this.tableName,
42
+ criteria,
43
+ }
44
+ );
45
+ return response;
46
+ } catch (error) {
47
+ // Return null if not found instead of throwing
48
+ if (error instanceof SDKError && error.httpStatus === 404) {
49
+ return null;
50
+ }
51
+ throw error;
52
+ }
53
+ }
54
+
55
+ async save(entity: T): Promise<T> {
56
+ const pkValue = entity[this.primaryKey];
57
+
58
+ if (!pkValue) {
59
+ // INSERT
60
+ const response = await this.httpClient.post<{
61
+ rows_affected: number;
62
+ last_insert_id: number;
63
+ }>("/v1/rqlite/exec", {
64
+ sql: this.buildInsertSql(entity),
65
+ args: this.buildInsertArgs(entity),
66
+ });
67
+
68
+ if (response.last_insert_id) {
69
+ (entity as any)[this.primaryKey] = response.last_insert_id;
70
+ }
71
+ return entity;
72
+ } else {
73
+ // UPDATE
74
+ await this.httpClient.post("/v1/rqlite/exec", {
75
+ sql: this.buildUpdateSql(entity),
76
+ args: this.buildUpdateArgs(entity),
77
+ });
78
+ return entity;
79
+ }
80
+ }
81
+
82
+ async remove(entity: T | Record<string, any>): Promise<void> {
83
+ const pkValue = entity[this.primaryKey];
84
+ if (!pkValue) {
85
+ throw new SDKError(
86
+ `Primary key "${this.primaryKey}" is required for remove`,
87
+ 400,
88
+ "MISSING_PK"
89
+ );
90
+ }
91
+
92
+ await this.httpClient.post("/v1/rqlite/exec", {
93
+ sql: `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = ?`,
94
+ args: [pkValue],
95
+ });
96
+ }
97
+
98
+ private buildInsertSql(entity: T): string {
99
+ const columns = Object.keys(entity).filter((k) => entity[k] !== undefined);
100
+ const placeholders = columns.map(() => "?").join(", ");
101
+ return `INSERT INTO ${this.tableName} (${columns.join(
102
+ ", "
103
+ )}) VALUES (${placeholders})`;
104
+ }
105
+
106
+ private buildInsertArgs(entity: T): any[] {
107
+ return Object.entries(entity)
108
+ .filter(([, v]) => v !== undefined)
109
+ .map(([, v]) => v);
110
+ }
111
+
112
+ private buildUpdateSql(entity: T): string {
113
+ const columns = Object.keys(entity)
114
+ .filter((k) => entity[k] !== undefined && k !== this.primaryKey)
115
+ .map((k) => `${k} = ?`);
116
+ return `UPDATE ${this.tableName} SET ${columns.join(", ")} WHERE ${
117
+ this.primaryKey
118
+ } = ?`;
119
+ }
120
+
121
+ private buildUpdateArgs(entity: T): any[] {
122
+ const args = Object.entries(entity)
123
+ .filter(([k, v]) => v !== undefined && k !== this.primaryKey)
124
+ .map(([, v]) => v);
125
+ args.push(entity[this.primaryKey]);
126
+ return args;
127
+ }
128
+ }
@@ -0,0 +1,67 @@
1
+ export interface Entity {
2
+ TableName(): string;
3
+ }
4
+
5
+ export interface QueryResponse {
6
+ columns?: string[];
7
+ rows?: any[][];
8
+ count?: number;
9
+ items?: any[];
10
+ }
11
+
12
+ export interface TransactionOp {
13
+ kind: "exec" | "query";
14
+ sql: string;
15
+ args?: any[];
16
+ }
17
+
18
+ export interface TransactionRequest {
19
+ statements?: string[];
20
+ ops?: TransactionOp[];
21
+ return_results?: boolean;
22
+ }
23
+
24
+ export interface SelectOptions {
25
+ select?: string[];
26
+ joins?: Array<{
27
+ kind: "INNER" | "LEFT" | "RIGHT" | "FULL";
28
+ table: string;
29
+ on: string;
30
+ }>;
31
+ where?: Array<{
32
+ conj?: "AND" | "OR";
33
+ expr: string;
34
+ args?: any[];
35
+ }>;
36
+ group_by?: string[];
37
+ order_by?: string[];
38
+ limit?: number;
39
+ offset?: number;
40
+ one?: boolean;
41
+ }
42
+
43
+ export type FindOptions = Omit<SelectOptions, "select" | "joins" | "one">;
44
+
45
+ export interface ColumnDefinition {
46
+ name: string;
47
+ isPrimaryKey?: boolean;
48
+ isAutoIncrement?: boolean;
49
+ }
50
+
51
+ export function extractTableName(entity: Entity | string): string {
52
+ if (typeof entity === "string") return entity;
53
+ return entity.TableName();
54
+ }
55
+
56
+ export function extractPrimaryKey(entity: any): string | undefined {
57
+ if (typeof entity === "string") return undefined;
58
+
59
+ // Check for explicit pk tag
60
+ const metadata = (entity as any)._dbMetadata;
61
+ if (metadata?.primaryKey) return metadata.primaryKey;
62
+
63
+ // Check for ID field
64
+ if (entity.id !== undefined) return "id";
65
+
66
+ return undefined;
67
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,38 @@
1
+ export class SDKError extends Error {
2
+ public readonly httpStatus: number;
3
+ public readonly code: string;
4
+ public readonly details: Record<string, any>;
5
+
6
+ constructor(
7
+ message: string,
8
+ httpStatus: number = 500,
9
+ code: string = "SDK_ERROR",
10
+ details: Record<string, any> = {}
11
+ ) {
12
+ super(message);
13
+ this.name = "SDKError";
14
+ this.httpStatus = httpStatus;
15
+ this.code = code;
16
+ this.details = details;
17
+ }
18
+
19
+ static fromResponse(
20
+ status: number,
21
+ body: any,
22
+ message?: string
23
+ ): SDKError {
24
+ const errorMsg = message || body?.error || `HTTP ${status}`;
25
+ const code = body?.code || `HTTP_${status}`;
26
+ return new SDKError(errorMsg, status, code, body);
27
+ }
28
+
29
+ toJSON() {
30
+ return {
31
+ name: this.name,
32
+ message: this.message,
33
+ httpStatus: this.httpStatus,
34
+ code: this.code,
35
+ details: this.details,
36
+ };
37
+ }
38
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Functions Client
3
+ * Client for calling serverless functions on the Orama Network
4
+ */
5
+
6
+ import { HttpClient } from "../core/http";
7
+ import { SDKError } from "../errors";
8
+
9
+ export interface FunctionsClientConfig {
10
+ /**
11
+ * Base URL for the functions gateway
12
+ * Defaults to using the same baseURL as the HTTP client
13
+ */
14
+ gatewayURL?: string;
15
+
16
+ /**
17
+ * Namespace for the functions
18
+ */
19
+ namespace: string;
20
+ }
21
+
22
+ export class FunctionsClient {
23
+ private httpClient: HttpClient;
24
+ private gatewayURL?: string;
25
+ private namespace: string;
26
+
27
+ constructor(httpClient: HttpClient, config?: FunctionsClientConfig) {
28
+ this.httpClient = httpClient;
29
+ this.gatewayURL = config?.gatewayURL;
30
+ this.namespace = config?.namespace ?? "default";
31
+ }
32
+
33
+ /**
34
+ * Invoke a serverless function by name
35
+ *
36
+ * @param functionName - Name of the function to invoke
37
+ * @param input - Input payload for the function
38
+ * @returns The function response
39
+ */
40
+ async invoke<TInput = any, TOutput = any>(
41
+ functionName: string,
42
+ input: TInput
43
+ ): Promise<TOutput> {
44
+ const url = this.gatewayURL
45
+ ? `${this.gatewayURL}/v1/invoke/${this.namespace}/${functionName}`
46
+ : `/v1/invoke/${this.namespace}/${functionName}`;
47
+
48
+ try {
49
+ const response = await this.httpClient.post<TOutput>(url, input);
50
+ return response;
51
+ } catch (error) {
52
+ if (error instanceof SDKError) {
53
+ throw error;
54
+ }
55
+ throw new SDKError(
56
+ `Function ${functionName} failed`,
57
+ 500,
58
+ error instanceof Error ? error.message : String(error)
59
+ );
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,2 @@
1
+ export { FunctionsClient, type FunctionsClientConfig } from "./client";
2
+ export type { FunctionResponse, SuccessResponse } from "./types";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Serverless Functions Types
3
+ * Type definitions for calling serverless functions on the Orama Network
4
+ */
5
+
6
+ /**
7
+ * Generic response from a serverless function
8
+ */
9
+ export interface FunctionResponse<T = unknown> {
10
+ success: boolean;
11
+ error?: string;
12
+ data?: T;
13
+ }
14
+
15
+ /**
16
+ * Standard success/error response used by many functions
17
+ */
18
+ export interface SuccessResponse {
19
+ success: boolean;
20
+ error?: string;
21
+ }