@lark-sh/client 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,52 @@
1
+ # @lark-sh/client
2
+
3
+ JavaScript/TypeScript client for [Lark](https://lark.sh) - a real-time database with a Firebase-like API.
4
+
5
+ > **Early Alpha**: This library is under active development. APIs may change.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @lark-sh/client
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { LarkDatabase } from '@lark-sh/client';
17
+
18
+ const db = new LarkDatabase();
19
+
20
+ // Connect to a database
21
+ await db.connect('my-project/my-database', {
22
+ token: 'your-auth-token', // or use anonymous: true
23
+ });
24
+
25
+ // Get a reference and read data
26
+ const snapshot = await db.ref('users/alice').once();
27
+ console.log(snapshot.val());
28
+
29
+ // Write data
30
+ await db.ref('users/alice').set({ name: 'Alice', score: 100 });
31
+
32
+ // Subscribe to real-time updates
33
+ const unsubscribe = db.ref('users').on('value', (snapshot) => {
34
+ console.log('Users changed:', snapshot.val());
35
+ });
36
+
37
+ // Later: unsubscribe and disconnect
38
+ unsubscribe();
39
+ await db.disconnect();
40
+ ```
41
+
42
+ ## Features
43
+
44
+ - Firebase v8-style API (`ref()`, `set()`, `on()`, `once()`, etc.)
45
+ - Real-time subscriptions with `on()` / `off()`
46
+ - Works in browsers and Node.js
47
+ - TypeScript support
48
+ - `onDisconnect()` handlers for presence
49
+
50
+ ## License
51
+
52
+ MIT
@@ -0,0 +1,415 @@
1
+ /**
2
+ * OnDisconnect - registers operations to perform on the server when this client disconnects.
3
+ */
4
+
5
+ declare class OnDisconnect {
6
+ private readonly _db;
7
+ private readonly _path;
8
+ constructor(db: LarkDatabase, path: string);
9
+ /**
10
+ * Set a value when disconnected.
11
+ */
12
+ set(value: unknown): Promise<void>;
13
+ /**
14
+ * Update values when disconnected.
15
+ */
16
+ update(values: Record<string, unknown>): Promise<void>;
17
+ /**
18
+ * Remove data when disconnected.
19
+ */
20
+ remove(): Promise<void>;
21
+ /**
22
+ * Cancel any pending onDisconnect handlers at this location.
23
+ */
24
+ cancel(): Promise<void>;
25
+ /**
26
+ * Set a value with priority when disconnected.
27
+ */
28
+ setWithPriority(value: unknown, priority: number | string): Promise<void>;
29
+ }
30
+
31
+ type EventType = 'value' | 'child_added' | 'child_changed' | 'child_removed';
32
+
33
+ /**
34
+ * DatabaseReference - a reference to a specific path in the database.
35
+ * Immutable - navigation returns new references.
36
+ */
37
+
38
+ type SnapshotCallback$1 = (snapshot: DataSnapshot, previousChildKey?: string | null) => void;
39
+ interface QueryState {
40
+ orderBy?: 'key' | 'priority' | 'child' | 'value';
41
+ orderByChildPath?: string;
42
+ limitToFirst?: number;
43
+ limitToLast?: number;
44
+ startAt?: {
45
+ value: unknown;
46
+ key?: string;
47
+ };
48
+ endAt?: {
49
+ value: unknown;
50
+ key?: string;
51
+ };
52
+ equalTo?: {
53
+ value: unknown;
54
+ key?: string;
55
+ };
56
+ }
57
+ declare class DatabaseReference {
58
+ private readonly _db;
59
+ private readonly _path;
60
+ private readonly _query;
61
+ constructor(db: LarkDatabase, path: string, query?: QueryState);
62
+ /**
63
+ * The path of this reference.
64
+ */
65
+ get path(): string;
66
+ /**
67
+ * The last segment of the path (the "key"), or null for root.
68
+ */
69
+ get key(): string | null;
70
+ /**
71
+ * Get a reference to the parent node, or null if this is root.
72
+ */
73
+ get parent(): DatabaseReference | null;
74
+ /**
75
+ * Get a reference to the root of the database.
76
+ */
77
+ get root(): DatabaseReference;
78
+ /**
79
+ * Get a reference to a child path.
80
+ */
81
+ child(path: string): DatabaseReference;
82
+ /**
83
+ * Set the data at this location, overwriting any existing data.
84
+ */
85
+ set(value: unknown): Promise<void>;
86
+ /**
87
+ * Update specific children at this location without overwriting other children.
88
+ */
89
+ update(values: Record<string, unknown>): Promise<void>;
90
+ /**
91
+ * Remove the data at this location.
92
+ */
93
+ remove(): Promise<void>;
94
+ /**
95
+ * Generate a new child location with a unique key and optionally set its value.
96
+ *
97
+ * If value is provided, sets the value and returns a Promise that resolves
98
+ * to the new reference.
99
+ *
100
+ * If no value is provided, returns a reference immediately with a client-generated
101
+ * push key (you can then call set() on it).
102
+ */
103
+ push(value?: unknown): DatabaseReference | Promise<DatabaseReference>;
104
+ /**
105
+ * Set the data with a priority value for ordering.
106
+ */
107
+ setWithPriority(value: unknown, priority: number | string): Promise<void>;
108
+ /**
109
+ * Set the priority of the data at this location.
110
+ */
111
+ setPriority(priority: number | string): Promise<void>;
112
+ /**
113
+ * Read the data at this location once.
114
+ */
115
+ once(eventType?: 'value'): Promise<DataSnapshot>;
116
+ /**
117
+ * Subscribe to events at this location.
118
+ * Returns an unsubscribe function.
119
+ */
120
+ on(eventType: EventType, callback: SnapshotCallback$1): () => void;
121
+ /**
122
+ * Unsubscribe from events.
123
+ * If eventType is specified, removes all listeners of that type.
124
+ * If no eventType, removes ALL listeners at this path.
125
+ */
126
+ off(eventType?: EventType): void;
127
+ /**
128
+ * Get an OnDisconnect handler for this location.
129
+ */
130
+ onDisconnect(): OnDisconnect;
131
+ /**
132
+ * Order results by key.
133
+ */
134
+ orderByKey(): DatabaseReference;
135
+ /**
136
+ * Order results by priority.
137
+ */
138
+ orderByPriority(): DatabaseReference;
139
+ /**
140
+ * Order results by a child key.
141
+ * NOTE: Phase 2 - not yet implemented on server.
142
+ */
143
+ orderByChild(path: string): DatabaseReference;
144
+ /**
145
+ * Order results by value.
146
+ * NOTE: Phase 2 - not yet implemented on server.
147
+ */
148
+ orderByValue(): DatabaseReference;
149
+ /**
150
+ * Limit to the first N results.
151
+ */
152
+ limitToFirst(limit: number): DatabaseReference;
153
+ /**
154
+ * Limit to the last N results.
155
+ */
156
+ limitToLast(limit: number): DatabaseReference;
157
+ /**
158
+ * Start at a specific value/key.
159
+ * NOTE: Phase 2 - not yet implemented on server.
160
+ */
161
+ startAt(value: unknown, key?: string): DatabaseReference;
162
+ /**
163
+ * End at a specific value/key.
164
+ * NOTE: Phase 2 - not yet implemented on server.
165
+ */
166
+ endAt(value: unknown, key?: string): DatabaseReference;
167
+ /**
168
+ * Filter to items equal to a specific value.
169
+ * NOTE: Phase 2 - not yet implemented on server.
170
+ */
171
+ equalTo(value: unknown, key?: string): DatabaseReference;
172
+ /**
173
+ * Build query parameters for wire protocol.
174
+ */
175
+ private _buildQueryParams;
176
+ /**
177
+ * Returns the absolute URL for this database location.
178
+ * Format: https://db.lark.sh/project/database/path/to/data
179
+ */
180
+ toString(): string;
181
+ }
182
+
183
+ /**
184
+ * DataSnapshot - an immutable snapshot of data at a location.
185
+ * Received in event callbacks and from once() operations.
186
+ */
187
+
188
+ declare class DataSnapshot {
189
+ private readonly _data;
190
+ private readonly _path;
191
+ private readonly _db;
192
+ private readonly _volatile;
193
+ private readonly _priority;
194
+ constructor(data: unknown, path: string, db: LarkDatabase, options?: {
195
+ volatile?: boolean;
196
+ priority?: number | string | null;
197
+ });
198
+ /**
199
+ * Get a DatabaseReference for the location of this snapshot.
200
+ */
201
+ get ref(): DatabaseReference;
202
+ /**
203
+ * Get the last segment of the path (the "key"), or null for root.
204
+ */
205
+ get key(): string | null;
206
+ /**
207
+ * Get the raw data value.
208
+ */
209
+ val(): unknown;
210
+ /**
211
+ * Check if data exists at this location (is not null/undefined).
212
+ */
213
+ exists(): boolean;
214
+ /**
215
+ * Get a child snapshot at the specified path.
216
+ */
217
+ child(path: string): DataSnapshot;
218
+ /**
219
+ * Check if this snapshot has any children.
220
+ */
221
+ hasChildren(): boolean;
222
+ /**
223
+ * Check if this snapshot has a specific child.
224
+ */
225
+ hasChild(path: string): boolean;
226
+ /**
227
+ * Get the number of children.
228
+ */
229
+ numChildren(): number;
230
+ /**
231
+ * Iterate over children. Return true from callback to stop iteration.
232
+ */
233
+ forEach(callback: (child: DataSnapshot) => boolean | void): void;
234
+ /**
235
+ * Get the priority of the data at this location.
236
+ */
237
+ getPriority(): number | string | null;
238
+ /**
239
+ * Check if this snapshot was from a volatile (high-frequency) update.
240
+ * This is a Lark extension not present in Firebase.
241
+ */
242
+ isVolatile(): boolean;
243
+ /**
244
+ * Export the snapshot data as JSON (alias for val()).
245
+ */
246
+ toJSON(): unknown;
247
+ }
248
+
249
+ interface QueryParams {
250
+ ob?: 'k' | 'p';
251
+ lf?: number;
252
+ ll?: number;
253
+ }
254
+
255
+ /**
256
+ * SubscriptionManager - tracks active subscriptions and routes events to callbacks.
257
+ */
258
+
259
+ type SnapshotCallback = (snapshot: DataSnapshot, previousChildKey?: string | null) => void;
260
+
261
+ /**
262
+ * LarkDatabase - the main entry point for connecting to a Lark database.
263
+ */
264
+
265
+ interface ConnectOptions {
266
+ /** User's auth token (from your auth system) */
267
+ token?: string;
268
+ /** Connect anonymously (server assigns a UID) */
269
+ anonymous?: boolean;
270
+ /** Coordinator URL (default: https://db.lark.dev) */
271
+ coordinator?: string;
272
+ }
273
+ interface AuthInfo {
274
+ uid: string;
275
+ provider: string;
276
+ token: Record<string, unknown>;
277
+ }
278
+ declare class LarkDatabase {
279
+ private _state;
280
+ private _auth;
281
+ private _databaseId;
282
+ private _coordinatorUrl;
283
+ private ws;
284
+ private messageQueue;
285
+ private subscriptionManager;
286
+ private connectCallbacks;
287
+ private disconnectCallbacks;
288
+ private errorCallbacks;
289
+ constructor();
290
+ /**
291
+ * Whether the database is currently connected.
292
+ */
293
+ get connected(): boolean;
294
+ /**
295
+ * Current auth info, or null if not connected.
296
+ */
297
+ get auth(): AuthInfo | null;
298
+ /**
299
+ * @internal Get the base URL for reference toString().
300
+ */
301
+ _getBaseUrl(): string;
302
+ /**
303
+ * Connect to a database.
304
+ *
305
+ * @param databaseId - Database ID in format "project/database"
306
+ * @param options - Connection options (token, anonymous, coordinator URL)
307
+ */
308
+ connect(databaseId: string, options?: ConnectOptions): Promise<void>;
309
+ /**
310
+ * Disconnect from the database.
311
+ * This triggers onDisconnect hooks on the server.
312
+ */
313
+ disconnect(): Promise<void>;
314
+ /**
315
+ * Clean up connection state.
316
+ */
317
+ private cleanup;
318
+ /**
319
+ * Get a reference to a path in the database.
320
+ */
321
+ ref(path?: string): DatabaseReference;
322
+ /**
323
+ * Register a callback for when connection is established.
324
+ * Returns an unsubscribe function.
325
+ */
326
+ onConnect(callback: () => void): () => void;
327
+ /**
328
+ * Register a callback for when connection is lost.
329
+ * Returns an unsubscribe function.
330
+ */
331
+ onDisconnect(callback: () => void): () => void;
332
+ /**
333
+ * Register a callback for connection errors.
334
+ * Returns an unsubscribe function.
335
+ */
336
+ onError(callback: (error: Error) => void): () => void;
337
+ private handleMessage;
338
+ private handleClose;
339
+ private handleError;
340
+ private send;
341
+ /**
342
+ * @internal Send a set operation.
343
+ */
344
+ _sendSet(path: string, value: unknown, priority?: number | string): Promise<void>;
345
+ /**
346
+ * @internal Send an update operation.
347
+ */
348
+ _sendUpdate(path: string, values: Record<string, unknown>): Promise<void>;
349
+ /**
350
+ * @internal Send a delete operation.
351
+ */
352
+ _sendDelete(path: string): Promise<void>;
353
+ /**
354
+ * @internal Send a push operation. Returns the generated key.
355
+ */
356
+ _sendPush(path: string, value: unknown): Promise<string>;
357
+ /**
358
+ * @internal Send a once (read) operation.
359
+ */
360
+ _sendOnce(path: string, query?: QueryParams): Promise<DataSnapshot>;
361
+ /**
362
+ * @internal Send an onDisconnect operation.
363
+ */
364
+ _sendOnDisconnect(path: string, action: string, value?: unknown, priority?: number | string): Promise<void>;
365
+ /**
366
+ * @internal Send a subscribe message to server.
367
+ */
368
+ private sendSubscribeMessage;
369
+ /**
370
+ * @internal Send an unsubscribe message to server.
371
+ */
372
+ private sendUnsubscribeMessage;
373
+ /**
374
+ * @internal Create a DataSnapshot from event data.
375
+ */
376
+ private createSnapshot;
377
+ /**
378
+ * @internal Subscribe to events at a path.
379
+ */
380
+ _subscribe(path: string, eventType: EventType, callback: SnapshotCallback): () => void;
381
+ /**
382
+ * @internal Unsubscribe from a specific event type at a path.
383
+ */
384
+ _unsubscribeEventType(path: string, eventType: EventType): void;
385
+ /**
386
+ * @internal Unsubscribe from all events at a path.
387
+ */
388
+ _unsubscribeAll(path: string): void;
389
+ }
390
+
391
+ /**
392
+ * LarkError - custom error class for Lark operations.
393
+ */
394
+ declare class LarkError extends Error {
395
+ readonly code: string;
396
+ constructor(code: string, message?: string);
397
+ }
398
+
399
+ /**
400
+ * Push ID generation - Firebase-compatible chronologically-sortable IDs.
401
+ *
402
+ * Format: 20 characters
403
+ * - First 8 chars: timestamp (milliseconds since epoch, base64-encoded)
404
+ * - Last 12 chars: random suffix (incremented on same-millisecond calls)
405
+ *
406
+ * This ensures:
407
+ * - IDs created later sort after IDs created earlier
408
+ * - IDs created in the same millisecond are unique and still sort correctly
409
+ */
410
+ /**
411
+ * Generate a Firebase-compatible push ID.
412
+ */
413
+ declare function generatePushId(): string;
414
+
415
+ export { type AuthInfo, type ConnectOptions, DataSnapshot, DatabaseReference, type EventType, LarkDatabase, LarkError, OnDisconnect, type QueryState, type SnapshotCallback$1 as SnapshotCallback, generatePushId };