@luxdb/sdk 1.4.1 → 1.4.3
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 +205 -0
- package/dist/cjs/index.js +1 -4
- package/dist/cjs/project.js +292 -1
- package/dist/cjs/table.js +52 -61
- package/dist/esm/index.js +1 -4
- package/dist/esm/project.js +290 -0
- package/dist/esm/table.js +52 -61
- package/dist/types/auth.d.ts +84 -0
- package/dist/types/index.d.ts +5 -5
- package/dist/types/project.d.ts +102 -11
- package/dist/types/table.d.ts +17 -19
- package/dist/types/types.d.ts +9 -1
- package/package.json +3 -3
package/dist/esm/table.js
CHANGED
|
@@ -56,9 +56,10 @@ export class TableSubscription {
|
|
|
56
56
|
try {
|
|
57
57
|
const initial = await this.fetchMatches();
|
|
58
58
|
for (const row of initial) {
|
|
59
|
-
|
|
59
|
+
const id = row.id;
|
|
60
|
+
if (id == null)
|
|
60
61
|
continue;
|
|
61
|
-
this.knownRows.set(String(
|
|
62
|
+
this.knownRows.set(String(id), row);
|
|
62
63
|
}
|
|
63
64
|
const pattern = `_t:${this.table}:row:*`;
|
|
64
65
|
this.unsubscribeFn = await this.client._subscribePattern(pattern, (raw) => {
|
|
@@ -108,7 +109,9 @@ export class TableSubscription {
|
|
|
108
109
|
if (!previous || !next)
|
|
109
110
|
return;
|
|
110
111
|
this.knownRows.set(pk, next);
|
|
111
|
-
const
|
|
112
|
+
const previousRow = previous;
|
|
113
|
+
const nextRow = next;
|
|
114
|
+
const changed = Object.keys(nextRow).filter((key) => previousRow[key] !== nextRow[key]);
|
|
112
115
|
this.emitChange({
|
|
113
116
|
type: 'update',
|
|
114
117
|
table: this.table,
|
|
@@ -128,6 +131,8 @@ export class TableSubscription {
|
|
|
128
131
|
export class TableQueryBuilder {
|
|
129
132
|
constructor(client, name, options) {
|
|
130
133
|
this.conditions = [];
|
|
134
|
+
this.groupFields = [];
|
|
135
|
+
this.havingConditions = [];
|
|
131
136
|
this.selectClause = '*';
|
|
132
137
|
this.expectSingle = false;
|
|
133
138
|
this.client = client;
|
|
@@ -153,7 +158,7 @@ export class TableQueryBuilder {
|
|
|
153
158
|
const args = [this.selectClause, 'FROM', this.name];
|
|
154
159
|
const allConditions = extra ? [...this.conditions, ...extra] : this.conditions;
|
|
155
160
|
if (this.joinClause) {
|
|
156
|
-
args.push('JOIN', this.joinClause.table, this.joinClause.alias, 'ON', this.joinClause.onLeft, '=', this.joinClause.onRight);
|
|
161
|
+
args.push(...(this.joinClause.type === 'LEFT' ? ['LEFT', 'JOIN'] : ['JOIN']), this.joinClause.table, this.joinClause.alias, 'ON', this.joinClause.onLeft, '=', this.joinClause.onRight);
|
|
157
162
|
}
|
|
158
163
|
if (allConditions.length) {
|
|
159
164
|
args.push('WHERE');
|
|
@@ -165,6 +170,25 @@ export class TableQueryBuilder {
|
|
|
165
170
|
}
|
|
166
171
|
}
|
|
167
172
|
}
|
|
173
|
+
if (this.groupFields.length) {
|
|
174
|
+
args.push('GROUP', 'BY', ...this.groupFields);
|
|
175
|
+
}
|
|
176
|
+
if (this.havingConditions.length) {
|
|
177
|
+
args.push('HAVING');
|
|
178
|
+
for (let i = 0; i < this.havingConditions.length; i++) {
|
|
179
|
+
const cond = this.havingConditions[i];
|
|
180
|
+
args.push(cond.field, cond.op, String(cond.value));
|
|
181
|
+
if (i < this.havingConditions.length - 1) {
|
|
182
|
+
args.push('AND');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (this.similarityClause) {
|
|
187
|
+
args.push('NEAR', this.similarityClause.field, `[${this.similarityClause.vector.join(',')}]`, 'K', String(this.similarityClause.k));
|
|
188
|
+
if (this.similarityClause.threshold != null) {
|
|
189
|
+
args.push('THRESHOLD', String(this.similarityClause.threshold));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
168
192
|
if (this.orderField) {
|
|
169
193
|
args.push('ORDER', 'BY', this.orderField, this.orderDir || 'ASC');
|
|
170
194
|
}
|
|
@@ -226,68 +250,41 @@ export class TableQueryBuilder {
|
|
|
226
250
|
return this;
|
|
227
251
|
}
|
|
228
252
|
join(table, alias, onLeft, onRight) {
|
|
229
|
-
this.joinClause = { table, alias, onLeft, onRight };
|
|
253
|
+
this.joinClause = { type: 'INNER', table, alias, onLeft, onRight };
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
leftJoin(table, alias, onLeft, onRight) {
|
|
257
|
+
this.joinClause = { type: 'LEFT', table, alias, onLeft, onRight };
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
group(fields) {
|
|
261
|
+
this.groupFields = Array.isArray(fields)
|
|
262
|
+
? fields
|
|
263
|
+
: fields.split(',').map((field) => field.trim()).filter(Boolean);
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
groupBy(fields) {
|
|
267
|
+
return this.group(fields);
|
|
268
|
+
}
|
|
269
|
+
having(field, op, value) {
|
|
270
|
+
this.havingConditions.push({ field, op, value });
|
|
230
271
|
return this;
|
|
231
272
|
}
|
|
232
|
-
|
|
273
|
+
near(field, vector, options = {}) {
|
|
233
274
|
this.similarityClause = {
|
|
234
275
|
field,
|
|
235
276
|
vector,
|
|
236
|
-
k: options.k,
|
|
237
|
-
|
|
277
|
+
k: options.k ?? 10,
|
|
278
|
+
threshold: options.threshold,
|
|
238
279
|
};
|
|
239
280
|
return this;
|
|
240
281
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (metadata && typeof metadata === 'object') {
|
|
244
|
-
for (const key of ['id', 'pk', 'row_id']) {
|
|
245
|
-
const value = metadata[key];
|
|
246
|
-
if (value != null)
|
|
247
|
-
return String(value);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
const expectedPrefix = `${this.name}:${field}:`;
|
|
251
|
-
if (result.key.startsWith(expectedPrefix)) {
|
|
252
|
-
return result.key.slice(expectedPrefix.length);
|
|
253
|
-
}
|
|
254
|
-
const segments = result.key.split(':');
|
|
255
|
-
if (segments.length > 0) {
|
|
256
|
-
return segments[segments.length - 1] || null;
|
|
257
|
-
}
|
|
258
|
-
return null;
|
|
282
|
+
similar(field, vector, options = {}) {
|
|
283
|
+
return this.near(field, vector, options);
|
|
259
284
|
}
|
|
260
285
|
async run() {
|
|
261
286
|
try {
|
|
262
|
-
|
|
263
|
-
if (this.similarityClause) {
|
|
264
|
-
if (this.joinClause) {
|
|
265
|
-
return err('SIMILAR_JOIN_UNSUPPORTED', 'similar(...) cannot be combined with join(...) yet');
|
|
266
|
-
}
|
|
267
|
-
const similarResults = await this.client.vsearch(this.similarityClause.vector, {
|
|
268
|
-
k: this.similarityClause.k,
|
|
269
|
-
filter: this.similarityClause.filter,
|
|
270
|
-
meta: true,
|
|
271
|
-
});
|
|
272
|
-
for (const match of similarResults) {
|
|
273
|
-
const pk = this.parseSimilarityPk(match, this.similarityClause.field);
|
|
274
|
-
if (!pk)
|
|
275
|
-
continue;
|
|
276
|
-
const args = this.buildSelectArgs([{ field: 'id', op: '=', value: pk }]);
|
|
277
|
-
const one = await this.client._tselect(args);
|
|
278
|
-
if (one.length === 0)
|
|
279
|
-
continue;
|
|
280
|
-
rows.push({ ...one[0], _similarity: match.similarity });
|
|
281
|
-
}
|
|
282
|
-
if (this.offsetCount != null || this.limitCount != null) {
|
|
283
|
-
const start = this.offsetCount ?? 0;
|
|
284
|
-
const end = this.limitCount != null ? start + this.limitCount : undefined;
|
|
285
|
-
rows = rows.slice(start, end);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
else {
|
|
289
|
-
rows = await this.client._tselect(this.buildSelectArgs());
|
|
290
|
-
}
|
|
287
|
+
const rows = await this.client._tselect(this.buildSelectArgs());
|
|
291
288
|
const validated = rows.map((row) => this.validateRow(row));
|
|
292
289
|
if (this.expectSingle) {
|
|
293
290
|
if (validated.length === 0) {
|
|
@@ -380,12 +377,6 @@ export class TableQueryBuilder {
|
|
|
380
377
|
}
|
|
381
378
|
}
|
|
382
379
|
subscribe() {
|
|
383
|
-
if (this.similarityClause) {
|
|
384
|
-
return new TableSubscription(this.client, this.name, (extra) => this.buildSelectArgs(extra), {
|
|
385
|
-
code: 'SIMILAR_SUBSCRIBE_UNSUPPORTED',
|
|
386
|
-
message: 'subscribe() is not supported on similar(...) queries yet',
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
380
|
return new TableSubscription(this.client, this.name, (extra) => this.buildSelectArgs(extra));
|
|
390
381
|
}
|
|
391
382
|
}
|
package/dist/types/auth.d.ts
CHANGED
|
@@ -11,6 +11,90 @@ export interface LuxAuthUser {
|
|
|
11
11
|
user_metadata?: Record<string, unknown>;
|
|
12
12
|
app_metadata?: Record<string, unknown>;
|
|
13
13
|
}
|
|
14
|
+
export type LuxUser = LuxAuthUser;
|
|
15
|
+
export interface LuxAuthUserRow {
|
|
16
|
+
id: string;
|
|
17
|
+
email?: string;
|
|
18
|
+
phone?: string;
|
|
19
|
+
encrypted_password?: string;
|
|
20
|
+
email_confirmed_at?: number | null;
|
|
21
|
+
phone_confirmed_at?: number | null;
|
|
22
|
+
raw_user_meta_data?: string;
|
|
23
|
+
raw_app_meta_data?: string;
|
|
24
|
+
created_at?: number | null;
|
|
25
|
+
updated_at?: number | null;
|
|
26
|
+
last_sign_in_at?: number | null;
|
|
27
|
+
banned_until?: number | null;
|
|
28
|
+
deleted_at?: number | null;
|
|
29
|
+
}
|
|
30
|
+
export interface LuxAuthIdentityRow {
|
|
31
|
+
id: string;
|
|
32
|
+
user_id: string;
|
|
33
|
+
provider: string;
|
|
34
|
+
provider_id: string;
|
|
35
|
+
identity_data?: string;
|
|
36
|
+
created_at?: number | null;
|
|
37
|
+
updated_at?: number | null;
|
|
38
|
+
}
|
|
39
|
+
export interface LuxAuthSessionRow {
|
|
40
|
+
id: string;
|
|
41
|
+
user_id: string;
|
|
42
|
+
refresh_token_hash: string;
|
|
43
|
+
refresh_token_family?: string;
|
|
44
|
+
user_agent?: string;
|
|
45
|
+
ip?: string;
|
|
46
|
+
expires_at?: number | null;
|
|
47
|
+
revoked_at?: number | null;
|
|
48
|
+
created_at?: number | null;
|
|
49
|
+
updated_at?: number | null;
|
|
50
|
+
}
|
|
51
|
+
export interface LuxAuthKeyRow {
|
|
52
|
+
id: string;
|
|
53
|
+
name?: string;
|
|
54
|
+
kind: 'publishable' | 'secret' | string;
|
|
55
|
+
prefix: string;
|
|
56
|
+
key_hash: string;
|
|
57
|
+
scopes?: string;
|
|
58
|
+
created_at?: number | null;
|
|
59
|
+
revoked_at?: number | null;
|
|
60
|
+
last_used_at?: number | null;
|
|
61
|
+
}
|
|
62
|
+
export interface LuxAuthSigningKeyRow {
|
|
63
|
+
id: string;
|
|
64
|
+
kid: string;
|
|
65
|
+
algorithm: string;
|
|
66
|
+
public_jwk?: string;
|
|
67
|
+
private_key_encrypted?: string;
|
|
68
|
+
active: boolean;
|
|
69
|
+
created_at?: number | null;
|
|
70
|
+
rotated_at?: number | null;
|
|
71
|
+
}
|
|
72
|
+
export interface LuxAuthGrantRow {
|
|
73
|
+
id: string;
|
|
74
|
+
user_id: string;
|
|
75
|
+
capability: string;
|
|
76
|
+
created_at?: number | null;
|
|
77
|
+
revoked_at?: number | null;
|
|
78
|
+
}
|
|
79
|
+
export interface LuxAuthProviderRow {
|
|
80
|
+
provider: LuxOAuthProvider | string;
|
|
81
|
+
enabled: boolean;
|
|
82
|
+
client_id?: string;
|
|
83
|
+
client_secret?: string;
|
|
84
|
+
redirect_uri?: string;
|
|
85
|
+
scopes?: string;
|
|
86
|
+
created_at?: number | null;
|
|
87
|
+
updated_at?: number | null;
|
|
88
|
+
}
|
|
89
|
+
export interface LuxAuthTables {
|
|
90
|
+
'auth.users': LuxAuthUserRow;
|
|
91
|
+
'auth.identities': LuxAuthIdentityRow;
|
|
92
|
+
'auth.sessions': LuxAuthSessionRow;
|
|
93
|
+
'auth.keys': LuxAuthKeyRow;
|
|
94
|
+
'auth.signing_keys': LuxAuthSigningKeyRow;
|
|
95
|
+
'auth.grants': LuxAuthGrantRow;
|
|
96
|
+
'auth.providers': LuxAuthProviderRow;
|
|
97
|
+
}
|
|
14
98
|
export interface LuxAuthSession {
|
|
15
99
|
access_token: string;
|
|
16
100
|
token_type: 'bearer';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,15 +3,15 @@ import { LuxAuthClient, type LuxAuthOptions } from './auth';
|
|
|
3
3
|
import { createProjectClient, LuxProjectClient, type LuxProjectOptions } from './project';
|
|
4
4
|
import { TimeSeriesNamespace, VectorNamespace } from './namespaces';
|
|
5
5
|
import { TableQueryBuilder, type TableQueryBuilderOptions } from './table';
|
|
6
|
-
import type { KSubEvent, TableRow, TSAddOptions, TSMRangeResult, TSRangeOptions, TSSample, VSearchResult } from './types';
|
|
7
|
-
export type { LuxAuthKey, LuxAuthChangeEvent, LuxAuthOptions, LuxAuthSession, LuxAuthStateChangeCallback, LuxAuthStorage, LuxAuthSubscription, LuxAuthUser, LuxOAuthProvider, LuxOAuthUrl, LuxSignInWithOAuthOptions, LuxCreateApiKeyOptions, LuxSignInOptions, LuxSignUpOptions, } from './auth';
|
|
6
|
+
import type { KSubEvent, LuxTypedRow, TableRow, TSAddOptions, TSMRangeResult, TSRangeOptions, TSSample, VSearchResult } from './types';
|
|
7
|
+
export type { LuxAuthKey, LuxAuthGrantRow, LuxAuthIdentityRow, LuxAuthChangeEvent, LuxAuthOptions, LuxAuthKeyRow, LuxAuthProviderRow, LuxAuthSession, LuxAuthSessionRow, LuxAuthSigningKeyRow, LuxAuthStateChangeCallback, LuxAuthStorage, LuxAuthSubscription, LuxAuthTables, LuxAuthUserRow, LuxAuthUser, LuxUser, LuxOAuthProvider, LuxOAuthUrl, LuxSignInWithOAuthOptions, LuxCreateApiKeyOptions, LuxSignInOptions, LuxSignUpOptions, } from './auth';
|
|
8
8
|
export { createProjectClient, LuxProjectClient, };
|
|
9
9
|
export { createBrowserClient } from './browser';
|
|
10
10
|
export type { LuxBrowserClientOptions } from './browser';
|
|
11
11
|
export { createServerClient } from './ssr';
|
|
12
12
|
export type { LuxCookieMethods, LuxCookieOptions, LuxServerClientOptions } from './ssr';
|
|
13
|
-
export type { LuxProjectOptions, LuxTableColumn, LuxVectorSearchOptions, } from './project';
|
|
14
|
-
export type { KSubEvent, LuxError, LuxResult, TableChangeEvent, TableChangeType, TableErrorEvent, TableRow, TableSchema, TSAddOptions, TSMRangeResult, TSRangeOptions, TSSample, VSearchResult, } from './types';
|
|
13
|
+
export type { LuxProjectLiveEvent, LuxProjectLiveEventType, LuxProjectOptions, LuxTableColumn, LuxVectorSearchOptions, } from './project';
|
|
14
|
+
export type { KSubEvent, LuxAggregateRow, LuxAggregateValue, LuxError, LuxInferRow, LuxNearRow, LuxResult, LuxSimilarity, LuxTypedRow, TableChangeEvent, TableChangeType, TableErrorEvent, TableRow, TableSchema, TSAddOptions, TSMRangeResult, TSRangeOptions, TSSample, VSearchResult, } from './types';
|
|
15
15
|
export { TableQueryBuilder, TableSubscription } from './table';
|
|
16
16
|
export type { TableQueryBuilderOptions } from './table';
|
|
17
17
|
export type LuxClientOptions = RedisOptions & LuxAuthOptions;
|
|
@@ -23,7 +23,7 @@ export declare class Lux extends Redis {
|
|
|
23
23
|
authApi: LuxAuthClient;
|
|
24
24
|
private realtimeManager?;
|
|
25
25
|
constructor(options?: LuxClientOptions | RedisOptions | string);
|
|
26
|
-
table<T extends
|
|
26
|
+
table<T extends object | readonly object[] = TableRow>(name: string, options?: TableQueryBuilderOptions<LuxTypedRow<T>>): TableQueryBuilder<LuxTypedRow<T>>;
|
|
27
27
|
_subscribePattern(pattern: string, handler: (event: KSubEvent) => void): Promise<() => void>;
|
|
28
28
|
_tselect(args: string[]): Promise<TableRow[]>;
|
|
29
29
|
vset(key: string, vector: number[], options?: {
|
package/dist/types/project.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { LuxAuthClient, type LuxAuthOptions } from './auth';
|
|
2
|
-
import type { LuxResult } from './types';
|
|
2
|
+
import type { LuxResult, LuxTypedRow } from './types';
|
|
3
3
|
export interface LuxProjectOptions {
|
|
4
4
|
url: string;
|
|
5
5
|
key: string;
|
|
6
6
|
fetch?: typeof fetch;
|
|
7
|
+
websocket?: typeof WebSocket;
|
|
7
8
|
auth?: Omit<LuxAuthOptions, 'httpUrl' | 'apiKey' | 'fetch'>;
|
|
8
9
|
}
|
|
9
10
|
export interface LuxTableColumn {
|
|
10
11
|
name: string;
|
|
11
|
-
type: 'STR' | 'INT' | 'FLOAT' | 'BOOL' | 'TIMESTAMP' | 'UUID'
|
|
12
|
+
type: 'STR' | 'INT' | 'FLOAT' | 'BOOL' | 'TIMESTAMP' | 'UUID' | `VECTOR(${number})`;
|
|
12
13
|
primaryKey?: boolean;
|
|
13
14
|
unique?: boolean;
|
|
14
15
|
notNull?: boolean;
|
|
@@ -21,8 +22,10 @@ export interface LuxVectorSearchOptions {
|
|
|
21
22
|
filter?: string;
|
|
22
23
|
filter_value?: string;
|
|
23
24
|
}
|
|
24
|
-
type QueryValue = string | number | boolean | null;
|
|
25
|
+
type QueryValue = string | number | boolean | number[] | null;
|
|
25
26
|
type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'is';
|
|
27
|
+
type ProjectRowInput<T extends object> = Partial<T> & Record<string, QueryValue>;
|
|
28
|
+
type ProjectSelectSingle<TResult> = TResult extends readonly (infer Row)[] ? Row : TResult;
|
|
26
29
|
interface QueryFilter {
|
|
27
30
|
column: string;
|
|
28
31
|
operator: FilterOperator;
|
|
@@ -32,13 +35,51 @@ interface QueryOrder {
|
|
|
32
35
|
column: string;
|
|
33
36
|
ascending: boolean;
|
|
34
37
|
}
|
|
38
|
+
interface QueryJoin {
|
|
39
|
+
type: 'inner' | 'left';
|
|
40
|
+
table: string;
|
|
41
|
+
alias: string;
|
|
42
|
+
onLeft: string;
|
|
43
|
+
onRight: string;
|
|
44
|
+
}
|
|
45
|
+
interface QueryHaving {
|
|
46
|
+
column: string;
|
|
47
|
+
operator: FilterOperator;
|
|
48
|
+
value: QueryValue;
|
|
49
|
+
}
|
|
50
|
+
interface QueryNear {
|
|
51
|
+
field: string;
|
|
52
|
+
vector: number[];
|
|
53
|
+
k: number;
|
|
54
|
+
threshold?: number;
|
|
55
|
+
}
|
|
56
|
+
export type LuxProjectLiveEventType = 'snapshot' | 'insert' | 'update' | 'delete' | 'error';
|
|
57
|
+
export interface LuxProjectLiveEvent<T extends object = Record<string, unknown>> {
|
|
58
|
+
type: LuxProjectLiveEventType;
|
|
59
|
+
table: string;
|
|
60
|
+
pk?: string;
|
|
61
|
+
new: T | null;
|
|
62
|
+
old: T | null;
|
|
63
|
+
rows?: T[];
|
|
64
|
+
changed?: string[];
|
|
65
|
+
raw?: unknown;
|
|
66
|
+
error?: {
|
|
67
|
+
code?: string;
|
|
68
|
+
message?: string;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
type LiveEventHandler<T extends object> = (event: LuxProjectLiveEvent<T>) => void;
|
|
35
72
|
export declare class LuxProjectClient {
|
|
36
73
|
readonly url: string;
|
|
37
74
|
readonly key: string;
|
|
38
75
|
readonly auth: LuxAuthClient;
|
|
39
76
|
private fetchImpl;
|
|
77
|
+
private WebSocketImpl?;
|
|
78
|
+
private liveSocket;
|
|
79
|
+
private liveSubscriptions;
|
|
80
|
+
private livePending;
|
|
40
81
|
constructor(options: LuxProjectOptions);
|
|
41
|
-
table<T extends
|
|
82
|
+
table<T extends object | readonly object[] = Record<string, unknown>>(name: string): LuxProjectTable<LuxTypedRow<T>>;
|
|
42
83
|
ping(): Promise<LuxResult<unknown>>;
|
|
43
84
|
createTable(name: string, columns: Array<string | LuxTableColumn>): Promise<LuxResult<unknown>>;
|
|
44
85
|
exec(command: string | string[]): Promise<LuxResult<unknown>>;
|
|
@@ -55,15 +96,33 @@ export declare class LuxProjectClient {
|
|
|
55
96
|
count?: number;
|
|
56
97
|
}): Promise<LuxResult<unknown>>;
|
|
57
98
|
request<T = unknown>(method: string, path: string, body?: unknown): Promise<LuxResult<T>>;
|
|
99
|
+
_subscribeLive(spec: Record<string, unknown>, handler: (event: unknown) => void, error: (error: {
|
|
100
|
+
code?: string;
|
|
101
|
+
message?: string;
|
|
102
|
+
}) => void): Promise<() => void>;
|
|
103
|
+
private ensureLiveSocket;
|
|
104
|
+
private sendLive;
|
|
58
105
|
}
|
|
59
|
-
export declare class LuxProjectTable<T extends
|
|
106
|
+
export declare class LuxProjectTable<T extends object> {
|
|
60
107
|
private client;
|
|
61
108
|
private name;
|
|
62
109
|
constructor(client: LuxProjectClient, name: string);
|
|
63
|
-
select(columns?: string): LuxProjectSelectBuilder<T,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
110
|
+
select<TResult extends object = T>(columns?: string): LuxProjectSelectBuilder<T, TResult[]>;
|
|
111
|
+
eq(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
112
|
+
neq(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
113
|
+
gt(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
114
|
+
gte(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
115
|
+
lt(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
116
|
+
lte(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
117
|
+
near(column: string, vector: number[], options?: {
|
|
118
|
+
k?: number;
|
|
119
|
+
threshold?: number;
|
|
120
|
+
}): LuxProjectSelectBuilder<T, T[]>;
|
|
121
|
+
is(column: string, value: QueryValue): LuxProjectSelectBuilder<T, T[]>;
|
|
122
|
+
live(): LuxProjectLiveSubscription<T>;
|
|
123
|
+
insert(row: ProjectRowInput<T>): LuxProjectInsertBuilder<unknown>;
|
|
124
|
+
insert(rows: Array<ProjectRowInput<T>>): LuxProjectInsertBuilder<unknown[]>;
|
|
125
|
+
update(patch: ProjectRowInput<T>): LuxProjectMutationBuilder<unknown>;
|
|
67
126
|
delete(): LuxProjectMutationBuilder<unknown>;
|
|
68
127
|
count(): Promise<LuxResult<number>>;
|
|
69
128
|
}
|
|
@@ -78,6 +137,10 @@ declare abstract class LuxProjectFilterBuilder<TResult, TSelf> extends LuxProjec
|
|
|
78
137
|
protected tableName: string;
|
|
79
138
|
protected filters: QueryFilter[];
|
|
80
139
|
protected orderBy?: QueryOrder;
|
|
140
|
+
protected joins: QueryJoin[];
|
|
141
|
+
protected groupColumns: string[];
|
|
142
|
+
protected havingFilters: QueryHaving[];
|
|
143
|
+
protected nearQuery?: QueryNear;
|
|
81
144
|
protected limitCount?: number;
|
|
82
145
|
protected offsetCount?: number;
|
|
83
146
|
protected constructor(client: LuxProjectClient, tableName: string);
|
|
@@ -88,20 +151,48 @@ declare abstract class LuxProjectFilterBuilder<TResult, TSelf> extends LuxProjec
|
|
|
88
151
|
lt(column: string, value: QueryValue): TSelf;
|
|
89
152
|
lte(column: string, value: QueryValue): TSelf;
|
|
90
153
|
is(column: string, value: QueryValue): TSelf;
|
|
154
|
+
join(table: string, alias: string, onLeft: string, onRight: string): TSelf;
|
|
155
|
+
leftJoin(table: string, alias: string, onLeft: string, onRight: string): TSelf;
|
|
156
|
+
group(columns: string | string[]): TSelf;
|
|
157
|
+
having(column: string, operator: FilterOperator, value: QueryValue): TSelf;
|
|
91
158
|
protected addFilter(column: string, operator: FilterOperator, value: QueryValue): TSelf;
|
|
92
159
|
protected filteredQueryParams(): URLSearchParams;
|
|
93
160
|
}
|
|
94
|
-
export declare class LuxProjectSelectBuilder<T extends
|
|
161
|
+
export declare class LuxProjectSelectBuilder<T extends object, TResult> extends LuxProjectFilterBuilder<TResult, LuxProjectSelectBuilder<T, TResult>> {
|
|
95
162
|
private columns;
|
|
96
163
|
private expectSingle;
|
|
97
164
|
constructor(client: LuxProjectClient, tableName: string, columns: string);
|
|
98
165
|
order(column: string, options?: {
|
|
99
166
|
ascending?: boolean;
|
|
100
167
|
}): this;
|
|
168
|
+
near(column: string, vector: number[], options?: {
|
|
169
|
+
k?: number;
|
|
170
|
+
threshold?: number;
|
|
171
|
+
}): this;
|
|
101
172
|
limit(count: number): this;
|
|
102
173
|
range(from: number, to: number): this;
|
|
103
|
-
single(): LuxProjectSelectBuilder<T,
|
|
174
|
+
single(): LuxProjectSelectBuilder<T, ProjectSelectSingle<TResult>>;
|
|
104
175
|
execute(): Promise<LuxResult<TResult>>;
|
|
176
|
+
live(): LuxProjectLiveSubscription<LuxTypedRow<TResult>>;
|
|
177
|
+
}
|
|
178
|
+
export declare class LuxProjectLiveSubscription<T extends object> {
|
|
179
|
+
private client;
|
|
180
|
+
private table;
|
|
181
|
+
private columns;
|
|
182
|
+
private filters;
|
|
183
|
+
private nearQuery?;
|
|
184
|
+
private orderBy?;
|
|
185
|
+
private limitCount?;
|
|
186
|
+
private offsetCount?;
|
|
187
|
+
private handlers;
|
|
188
|
+
private unsubscribeFn;
|
|
189
|
+
constructor(client: LuxProjectClient, table: string, columns: string, filters: QueryFilter[], nearQuery?: QueryNear | undefined, orderBy?: QueryOrder | undefined, limitCount?: number | undefined, offsetCount?: number | undefined);
|
|
190
|
+
on(type: LuxProjectLiveEventType | 'change', handler: LiveEventHandler<T>): this;
|
|
191
|
+
unsubscribe(): Promise<void>;
|
|
192
|
+
private start;
|
|
193
|
+
private spec;
|
|
194
|
+
private handleEvent;
|
|
195
|
+
private emit;
|
|
105
196
|
}
|
|
106
197
|
export declare class LuxProjectInsertBuilder<TResult> extends LuxProjectThenable<TResult> {
|
|
107
198
|
private client;
|
package/dist/types/table.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { KSubEvent, LuxError, LuxResult, TableChangeEvent, TableErrorEvent, TableRow, TableSchema
|
|
1
|
+
import type { KSubEvent, LuxError, LuxResult, TableChangeEvent, TableErrorEvent, TableRow, TableSchema } from './types';
|
|
2
2
|
type TableWhereOp = '=' | '!=' | '>' | '<' | '>=' | '<=';
|
|
3
3
|
type TableWhereValue = string | number | boolean;
|
|
4
4
|
interface TableWhereCondition {
|
|
@@ -10,19 +10,11 @@ interface TableClient {
|
|
|
10
10
|
call(command: string, ...args: Array<string | number>): Promise<unknown>;
|
|
11
11
|
_tselect(args: string[]): Promise<TableRow[]>;
|
|
12
12
|
_subscribePattern(pattern: string, handler: (event: KSubEvent) => void): Promise<() => void>;
|
|
13
|
-
vsearch(query: number[], options: {
|
|
14
|
-
k: number;
|
|
15
|
-
filter?: {
|
|
16
|
-
key: string;
|
|
17
|
-
value: string;
|
|
18
|
-
};
|
|
19
|
-
meta?: boolean;
|
|
20
|
-
}): Promise<VSearchResult[]>;
|
|
21
13
|
}
|
|
22
|
-
export interface TableQueryBuilderOptions<T extends
|
|
14
|
+
export interface TableQueryBuilderOptions<T extends object> {
|
|
23
15
|
schema?: TableSchema<T>;
|
|
24
16
|
}
|
|
25
|
-
export declare class TableSubscription<T extends
|
|
17
|
+
export declare class TableSubscription<T extends object> {
|
|
26
18
|
private client;
|
|
27
19
|
private table;
|
|
28
20
|
private selectArgsBuilder;
|
|
@@ -41,7 +33,7 @@ export declare class TableSubscription<T extends TableRow> {
|
|
|
41
33
|
private start;
|
|
42
34
|
private handleRawChange;
|
|
43
35
|
}
|
|
44
|
-
export declare class TableQueryBuilder<T extends
|
|
36
|
+
export declare class TableQueryBuilder<T extends object = TableRow> {
|
|
45
37
|
private client;
|
|
46
38
|
private name;
|
|
47
39
|
private conditions;
|
|
@@ -51,6 +43,8 @@ export declare class TableQueryBuilder<T extends TableRow = TableRow> {
|
|
|
51
43
|
private offsetCount?;
|
|
52
44
|
private joinClause?;
|
|
53
45
|
private similarityClause?;
|
|
46
|
+
private groupFields;
|
|
47
|
+
private havingConditions;
|
|
54
48
|
private selectClause;
|
|
55
49
|
private expectSingle;
|
|
56
50
|
private schema?;
|
|
@@ -73,14 +67,18 @@ export declare class TableQueryBuilder<T extends TableRow = TableRow> {
|
|
|
73
67
|
limit(n: number): this;
|
|
74
68
|
offset(n: number): this;
|
|
75
69
|
join(table: string, alias: string, onLeft: string, onRight: string): this;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
leftJoin(table: string, alias: string, onLeft: string, onRight: string): this;
|
|
71
|
+
group(fields: string | string[]): this;
|
|
72
|
+
groupBy(fields: string | string[]): this;
|
|
73
|
+
having(field: string, op: TableWhereOp, value: TableWhereValue): this;
|
|
74
|
+
near(field: string, vector: number[], options?: {
|
|
75
|
+
k?: number;
|
|
76
|
+
threshold?: number;
|
|
77
|
+
}): this;
|
|
78
|
+
similar(field: string, vector: number[], options?: {
|
|
79
|
+
k?: number;
|
|
80
|
+
threshold?: number;
|
|
82
81
|
}): this;
|
|
83
|
-
private parseSimilarityPk;
|
|
84
82
|
run(): Promise<LuxResult<T[] | T>>;
|
|
85
83
|
then<TFulfilled = LuxResult<T[] | T>, TRejected = never>(onfulfilled?: ((value: LuxResult<T[] | T>) => TFulfilled | PromiseLike<TFulfilled>) | null, onrejected?: ((reason: unknown) => TRejected | PromiseLike<TRejected>) | null): Promise<TFulfilled | TRejected>;
|
|
86
84
|
insert(data: Record<string, unknown>): Promise<LuxResult<number>>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -31,6 +31,14 @@ export interface TableRow {
|
|
|
31
31
|
id?: number | string;
|
|
32
32
|
[field: string]: unknown;
|
|
33
33
|
}
|
|
34
|
+
export type LuxInferRow<T> = T extends readonly (infer Row)[] ? Row : T;
|
|
35
|
+
export type LuxTypedRow<T> = LuxInferRow<T> extends object ? LuxInferRow<T> : TableRow;
|
|
36
|
+
export type LuxAggregateValue = number | string;
|
|
37
|
+
export type LuxAggregateRow<Aliases extends string = string> = Record<Aliases, LuxAggregateValue>;
|
|
38
|
+
export interface LuxSimilarity {
|
|
39
|
+
_similarity: number | string;
|
|
40
|
+
}
|
|
41
|
+
export type LuxNearRow<T extends object = Record<string, unknown>> = T & LuxSimilarity;
|
|
34
42
|
export interface LuxError {
|
|
35
43
|
code: string;
|
|
36
44
|
message: string;
|
|
@@ -52,7 +60,7 @@ export interface TableSchema<T> {
|
|
|
52
60
|
safeParse?: (input: unknown) => SchemaSafeParse<T>;
|
|
53
61
|
}
|
|
54
62
|
export type TableChangeType = 'insert' | 'update' | 'delete' | 'change' | 'error';
|
|
55
|
-
export interface TableChangeEvent<T extends TableRow> {
|
|
63
|
+
export interface TableChangeEvent<T extends object = TableRow> {
|
|
56
64
|
type: Exclude<TableChangeType, 'error'>;
|
|
57
65
|
table: string;
|
|
58
66
|
pk: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luxdb/sdk",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "Lux SDK
|
|
3
|
+
"version": "1.4.3",
|
|
4
|
+
"description": "Official Lux TypeScript SDK for app data, auth, tables, vectors, realtime, and Redis-compatible direct access",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
7
7
|
"types": "./dist/types/index.d.ts",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"url": "https://github.com/lux-db/lux",
|
|
60
60
|
"directory": "sdk"
|
|
61
61
|
},
|
|
62
|
-
"keywords": ["lux", "
|
|
62
|
+
"keywords": ["lux", "database", "application-database", "auth", "tables", "vectors", "realtime", "redis", "cache", "queues", "timeseries"]
|
|
63
63
|
}
|