@lark-sh/client 0.1.3 → 0.1.5
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/dist/index.d.mts +269 -13
- package/dist/index.d.ts +269 -13
- package/dist/index.js +783 -108
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +780 -107
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -28,13 +28,20 @@ declare class OnDisconnect {
|
|
|
28
28
|
setWithPriority(value: unknown, priority: number | string): Promise<void>;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
type EventType = 'value' | 'child_added' | 'child_changed' | 'child_removed';
|
|
31
|
+
type EventType = 'value' | 'child_added' | 'child_changed' | 'child_removed' | 'child_moved';
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* DatabaseReference - a reference to a specific path in the database.
|
|
35
35
|
* Immutable - navigation returns new references.
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
|
+
/** Result of a transaction operation */
|
|
39
|
+
interface TransactionResult {
|
|
40
|
+
/** Whether the transaction was committed (always true on success) */
|
|
41
|
+
committed: boolean;
|
|
42
|
+
/** Snapshot of the data after the transaction */
|
|
43
|
+
snapshot: DataSnapshot;
|
|
44
|
+
}
|
|
38
45
|
type SnapshotCallback$1 = (snapshot: DataSnapshot, previousChildKey?: string | null) => void;
|
|
39
46
|
interface QueryState {
|
|
40
47
|
orderBy?: 'key' | 'priority' | 'child' | 'value';
|
|
@@ -85,6 +92,22 @@ declare class DatabaseReference {
|
|
|
85
92
|
set(value: unknown): Promise<void>;
|
|
86
93
|
/**
|
|
87
94
|
* Update specific children at this location without overwriting other children.
|
|
95
|
+
*
|
|
96
|
+
* Also supports Firebase-style multi-path updates when keys look like paths
|
|
97
|
+
* (start with '/'). In this mode, each path is written atomically as a transaction.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```javascript
|
|
101
|
+
* // Normal update (merge at single path)
|
|
102
|
+
* await ref.update({ score: 10, name: 'Riley' });
|
|
103
|
+
*
|
|
104
|
+
* // Multi-path update (atomic writes to multiple paths)
|
|
105
|
+
* await db.ref().update({
|
|
106
|
+
* '/users/alice/score': 100,
|
|
107
|
+
* '/users/bob/score': 200,
|
|
108
|
+
* '/leaderboard/alice': null // null = delete
|
|
109
|
+
* });
|
|
110
|
+
* ```
|
|
88
111
|
*/
|
|
89
112
|
update(values: Record<string, unknown>): Promise<void>;
|
|
90
113
|
/**
|
|
@@ -109,6 +132,29 @@ declare class DatabaseReference {
|
|
|
109
132
|
* Set the priority of the data at this location.
|
|
110
133
|
*/
|
|
111
134
|
setPriority(priority: number | string): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Atomically modify the data at this location using optimistic concurrency.
|
|
137
|
+
*
|
|
138
|
+
* The update function receives the current value and should return the new
|
|
139
|
+
* value. If the data changed on the server before the write could be
|
|
140
|
+
* committed, the function is called again with the new value, and the
|
|
141
|
+
* process repeats until successful or the maximum retries are exceeded.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```javascript
|
|
145
|
+
* // Increment a counter atomically
|
|
146
|
+
* const result = await ref.transaction(currentValue => {
|
|
147
|
+
* return (currentValue || 0) + 1;
|
|
148
|
+
* });
|
|
149
|
+
* console.log('New value:', result.snapshot.val());
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* @param updateFunction - Function that receives current value and returns new value.
|
|
153
|
+
* Return undefined to abort the transaction.
|
|
154
|
+
* @param maxRetries - Maximum number of retries (default: 25)
|
|
155
|
+
* @returns TransactionResult with committed status and final snapshot
|
|
156
|
+
*/
|
|
157
|
+
transaction(updateFunction: (currentValue: unknown) => unknown, maxRetries?: number): Promise<TransactionResult>;
|
|
112
158
|
/**
|
|
113
159
|
* Read the data at this location once.
|
|
114
160
|
*/
|
|
@@ -138,12 +184,10 @@ declare class DatabaseReference {
|
|
|
138
184
|
orderByPriority(): DatabaseReference;
|
|
139
185
|
/**
|
|
140
186
|
* Order results by a child key.
|
|
141
|
-
* NOTE: Phase 2 - not yet implemented on server.
|
|
142
187
|
*/
|
|
143
188
|
orderByChild(path: string): DatabaseReference;
|
|
144
189
|
/**
|
|
145
190
|
* Order results by value.
|
|
146
|
-
* NOTE: Phase 2 - not yet implemented on server.
|
|
147
191
|
*/
|
|
148
192
|
orderByValue(): DatabaseReference;
|
|
149
193
|
/**
|
|
@@ -156,17 +200,14 @@ declare class DatabaseReference {
|
|
|
156
200
|
limitToLast(limit: number): DatabaseReference;
|
|
157
201
|
/**
|
|
158
202
|
* Start at a specific value/key.
|
|
159
|
-
* NOTE: Phase 2 - not yet implemented on server.
|
|
160
203
|
*/
|
|
161
204
|
startAt(value: unknown, key?: string): DatabaseReference;
|
|
162
205
|
/**
|
|
163
206
|
* End at a specific value/key.
|
|
164
|
-
* NOTE: Phase 2 - not yet implemented on server.
|
|
165
207
|
*/
|
|
166
208
|
endAt(value: unknown, key?: string): DatabaseReference;
|
|
167
209
|
/**
|
|
168
210
|
* Filter to items equal to a specific value.
|
|
169
|
-
* NOTE: Phase 2 - not yet implemented on server.
|
|
170
211
|
*/
|
|
171
212
|
equalTo(value: unknown, key?: string): DatabaseReference;
|
|
172
213
|
/**
|
|
@@ -191,9 +232,11 @@ declare class DataSnapshot {
|
|
|
191
232
|
private readonly _db;
|
|
192
233
|
private readonly _volatile;
|
|
193
234
|
private readonly _priority;
|
|
235
|
+
private readonly _serverTimestamp;
|
|
194
236
|
constructor(data: unknown, path: string, db: LarkDatabase, options?: {
|
|
195
237
|
volatile?: boolean;
|
|
196
238
|
priority?: number | string | null;
|
|
239
|
+
serverTimestamp?: number | null;
|
|
197
240
|
});
|
|
198
241
|
/**
|
|
199
242
|
* Get a DatabaseReference for the location of this snapshot.
|
|
@@ -240,6 +283,13 @@ declare class DataSnapshot {
|
|
|
240
283
|
* This is a Lark extension not present in Firebase.
|
|
241
284
|
*/
|
|
242
285
|
isVolatile(): boolean;
|
|
286
|
+
/**
|
|
287
|
+
* Get the server timestamp for this snapshot (milliseconds since Unix epoch).
|
|
288
|
+
* Only present on volatile value events. Use deltas between timestamps for
|
|
289
|
+
* interpolation rather than absolute times to avoid clock sync issues.
|
|
290
|
+
* This is a Lark extension not present in Firebase.
|
|
291
|
+
*/
|
|
292
|
+
getServerTimestamp(): number | null;
|
|
243
293
|
/**
|
|
244
294
|
* Export the snapshot data as JSON (alias for val()).
|
|
245
295
|
*/
|
|
@@ -247,16 +297,50 @@ declare class DataSnapshot {
|
|
|
247
297
|
}
|
|
248
298
|
|
|
249
299
|
interface QueryParams {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
300
|
+
orderBy?: 'key' | 'priority' | 'child' | 'value';
|
|
301
|
+
orderByChild?: string;
|
|
302
|
+
limitToFirst?: number;
|
|
303
|
+
limitToLast?: number;
|
|
304
|
+
startAt?: unknown;
|
|
305
|
+
startAtKey?: string;
|
|
306
|
+
endAt?: unknown;
|
|
307
|
+
endAtKey?: string;
|
|
308
|
+
equalTo?: unknown;
|
|
309
|
+
equalToKey?: string;
|
|
310
|
+
}
|
|
311
|
+
interface TxSetOp {
|
|
312
|
+
o: 's';
|
|
313
|
+
p: string;
|
|
314
|
+
v: unknown;
|
|
315
|
+
}
|
|
316
|
+
interface TxUpdateOp {
|
|
317
|
+
o: 'u';
|
|
318
|
+
p: string;
|
|
319
|
+
v: Record<string, unknown>;
|
|
320
|
+
}
|
|
321
|
+
interface TxDeleteOp {
|
|
322
|
+
o: 'd';
|
|
323
|
+
p: string;
|
|
324
|
+
}
|
|
325
|
+
interface TxConditionOp {
|
|
326
|
+
o: 'c';
|
|
327
|
+
p: string;
|
|
328
|
+
v: unknown;
|
|
329
|
+
}
|
|
330
|
+
type TxOperation = TxSetOp | TxUpdateOp | TxDeleteOp | TxConditionOp;
|
|
331
|
+
interface MoveEntry {
|
|
332
|
+
k: string;
|
|
333
|
+
ak: string;
|
|
253
334
|
}
|
|
254
335
|
|
|
255
336
|
/**
|
|
256
337
|
* SubscriptionManager - tracks active subscriptions and routes events to callbacks.
|
|
257
338
|
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
339
|
+
* Handles the new delta-based protocol where server sends 'put' and 'patch' events.
|
|
340
|
+
* Client generates child_added, child_changed, child_removed, child_moved events locally.
|
|
341
|
+
*
|
|
342
|
+
* Supports ordered queries: tracks child order from server's `k` (orderedKeys) and `ak` (afterKey)
|
|
343
|
+
* fields, and fires child_moved when positions change via `mv` (moves) array.
|
|
260
344
|
*/
|
|
261
345
|
|
|
262
346
|
type SnapshotCallback = (snapshot: DataSnapshot, previousChildKey?: string | null) => void;
|
|
@@ -278,14 +362,43 @@ interface AuthInfo {
|
|
|
278
362
|
provider: string;
|
|
279
363
|
token: Record<string, unknown>;
|
|
280
364
|
}
|
|
365
|
+
/** A set operation in a transaction */
|
|
366
|
+
interface TransactionSetOp {
|
|
367
|
+
op: 'set';
|
|
368
|
+
path: string;
|
|
369
|
+
value: unknown;
|
|
370
|
+
}
|
|
371
|
+
/** An update (merge) operation in a transaction */
|
|
372
|
+
interface TransactionUpdateOp {
|
|
373
|
+
op: 'update';
|
|
374
|
+
path: string;
|
|
375
|
+
value: Record<string, unknown>;
|
|
376
|
+
}
|
|
377
|
+
/** A delete operation in a transaction */
|
|
378
|
+
interface TransactionDeleteOp {
|
|
379
|
+
op: 'delete';
|
|
380
|
+
path: string;
|
|
381
|
+
}
|
|
382
|
+
/** A condition check in a transaction (for compare-and-swap) */
|
|
383
|
+
interface TransactionConditionOp {
|
|
384
|
+
op: 'condition';
|
|
385
|
+
path: string;
|
|
386
|
+
value: unknown;
|
|
387
|
+
}
|
|
388
|
+
/** A single operation in a transaction (array syntax) */
|
|
389
|
+
type TransactionOp = TransactionSetOp | TransactionUpdateOp | TransactionDeleteOp | TransactionConditionOp;
|
|
390
|
+
/** Object syntax for transactions: path -> value (null = delete) */
|
|
391
|
+
type TransactionObject = Record<string, unknown>;
|
|
281
392
|
declare class LarkDatabase {
|
|
282
393
|
private _state;
|
|
283
394
|
private _auth;
|
|
284
395
|
private _databaseId;
|
|
285
396
|
private _coordinatorUrl;
|
|
397
|
+
private _volatilePaths;
|
|
286
398
|
private ws;
|
|
287
399
|
private messageQueue;
|
|
288
400
|
private subscriptionManager;
|
|
401
|
+
private pendingWrites;
|
|
289
402
|
private connectCallbacks;
|
|
290
403
|
private disconnectCallbacks;
|
|
291
404
|
private errorCallbacks;
|
|
@@ -302,6 +415,26 @@ declare class LarkDatabase {
|
|
|
302
415
|
* @internal Get the base URL for reference toString().
|
|
303
416
|
*/
|
|
304
417
|
_getBaseUrl(): string;
|
|
418
|
+
/**
|
|
419
|
+
* Get the volatile path patterns from the server.
|
|
420
|
+
* These patterns indicate which paths should use unreliable transport.
|
|
421
|
+
* WebSocket always uses reliable transport, but this is stored for future UDP support.
|
|
422
|
+
*/
|
|
423
|
+
get volatilePaths(): string[];
|
|
424
|
+
/**
|
|
425
|
+
* Check if there are any pending writes waiting for acknowledgment.
|
|
426
|
+
* Useful for showing "saving..." indicators in UI.
|
|
427
|
+
*/
|
|
428
|
+
hasPendingWrites(): boolean;
|
|
429
|
+
/**
|
|
430
|
+
* Get the number of pending writes waiting for acknowledgment.
|
|
431
|
+
*/
|
|
432
|
+
getPendingWriteCount(): number;
|
|
433
|
+
/**
|
|
434
|
+
* Clear all pending writes.
|
|
435
|
+
* Call this if you don't want to retry writes on reconnect.
|
|
436
|
+
*/
|
|
437
|
+
clearPendingWrites(): void;
|
|
305
438
|
/**
|
|
306
439
|
* Connect to a database.
|
|
307
440
|
*
|
|
@@ -322,6 +455,48 @@ declare class LarkDatabase {
|
|
|
322
455
|
* Get a reference to a path in the database.
|
|
323
456
|
*/
|
|
324
457
|
ref(path?: string): DatabaseReference;
|
|
458
|
+
/**
|
|
459
|
+
* Execute an atomic transaction with multiple operations.
|
|
460
|
+
*
|
|
461
|
+
* Supports two syntaxes:
|
|
462
|
+
*
|
|
463
|
+
* **Object syntax** (like Firebase multi-path update):
|
|
464
|
+
* ```javascript
|
|
465
|
+
* await db.transaction({
|
|
466
|
+
* '/users/alice/name': 'Alice',
|
|
467
|
+
* '/users/alice/score': 100,
|
|
468
|
+
* '/temp/data': null // null = delete
|
|
469
|
+
* });
|
|
470
|
+
* ```
|
|
471
|
+
*
|
|
472
|
+
* **Array syntax** (explicit operations):
|
|
473
|
+
* ```javascript
|
|
474
|
+
* await db.transaction([
|
|
475
|
+
* { op: 'set', path: '/users/alice/name', value: 'Alice' },
|
|
476
|
+
* { op: 'update', path: '/metadata', value: { lastUpdated: '...' } },
|
|
477
|
+
* { op: 'delete', path: '/temp/data' },
|
|
478
|
+
* { op: 'condition', path: '/counter', value: 5 } // CAS check
|
|
479
|
+
* ]);
|
|
480
|
+
* ```
|
|
481
|
+
*
|
|
482
|
+
* All operations are atomic: either all succeed or all fail.
|
|
483
|
+
* Conditions are checked first; if any fail, the transaction is rejected
|
|
484
|
+
* with error code 'condition_failed'.
|
|
485
|
+
*/
|
|
486
|
+
transaction(operations: TransactionOp[] | TransactionObject): Promise<void>;
|
|
487
|
+
/**
|
|
488
|
+
* Convert a public TransactionOp to wire format TxOperation.
|
|
489
|
+
*/
|
|
490
|
+
private convertToTxOp;
|
|
491
|
+
/**
|
|
492
|
+
* Convert object syntax to wire format TxOperations.
|
|
493
|
+
* Each path becomes a set operation, null values become deletes.
|
|
494
|
+
*/
|
|
495
|
+
private convertObjectToTxOps;
|
|
496
|
+
/**
|
|
497
|
+
* @internal Send a transaction to the server.
|
|
498
|
+
*/
|
|
499
|
+
_sendTransaction(ops: TxOperation[]): Promise<void>;
|
|
325
500
|
/**
|
|
326
501
|
* Register a callback for when connection is established.
|
|
327
502
|
* Returns an unsubscribe function.
|
|
@@ -389,7 +564,7 @@ declare class LarkDatabase {
|
|
|
389
564
|
/**
|
|
390
565
|
* @internal Subscribe to events at a path.
|
|
391
566
|
*/
|
|
392
|
-
_subscribe(path: string, eventType: EventType, callback: SnapshotCallback): () => void;
|
|
567
|
+
_subscribe(path: string, eventType: EventType, callback: SnapshotCallback, queryParams?: QueryParams): () => void;
|
|
393
568
|
/**
|
|
394
569
|
* @internal Unsubscribe from a specific event type at a path.
|
|
395
570
|
*/
|
|
@@ -408,6 +583,67 @@ declare class LarkError extends Error {
|
|
|
408
583
|
constructor(code: string, message?: string);
|
|
409
584
|
}
|
|
410
585
|
|
|
586
|
+
/**
|
|
587
|
+
* PendingWriteManager - tracks pending write operations for optimistic updates.
|
|
588
|
+
*
|
|
589
|
+
* Each write operation is assigned a unique operation ID (oid). The manager tracks
|
|
590
|
+
* pending writes until they are acknowledged by the server. On reconnect, pending
|
|
591
|
+
* writes can be retried to ensure data consistency.
|
|
592
|
+
*/
|
|
593
|
+
type WriteOperation = 'set' | 'update' | 'delete' | 'push' | 'transaction';
|
|
594
|
+
interface PendingWrite {
|
|
595
|
+
oid: string;
|
|
596
|
+
operation: WriteOperation;
|
|
597
|
+
path: string;
|
|
598
|
+
value?: unknown;
|
|
599
|
+
timestamp: number;
|
|
600
|
+
}
|
|
601
|
+
declare class PendingWriteManager {
|
|
602
|
+
private pending;
|
|
603
|
+
private counter;
|
|
604
|
+
/**
|
|
605
|
+
* Generate a unique operation ID.
|
|
606
|
+
* Format: op_{timestamp}_{counter}_{random}
|
|
607
|
+
*/
|
|
608
|
+
generateOid(): string;
|
|
609
|
+
/**
|
|
610
|
+
* Track a new pending write operation.
|
|
611
|
+
*/
|
|
612
|
+
trackWrite(oid: string, operation: WriteOperation, path: string, value?: unknown): void;
|
|
613
|
+
/**
|
|
614
|
+
* Called when a write is acknowledged by the server.
|
|
615
|
+
* Removes the write from pending tracking.
|
|
616
|
+
*/
|
|
617
|
+
onAck(oid: string): boolean;
|
|
618
|
+
/**
|
|
619
|
+
* Called when a write is rejected by the server.
|
|
620
|
+
* Removes the write from pending tracking.
|
|
621
|
+
*/
|
|
622
|
+
onNack(oid: string): boolean;
|
|
623
|
+
/**
|
|
624
|
+
* Get all pending writes for retry on reconnect.
|
|
625
|
+
* Returns writes in order of their timestamps (oldest first).
|
|
626
|
+
*/
|
|
627
|
+
getPendingWrites(): PendingWrite[];
|
|
628
|
+
/**
|
|
629
|
+
* Check if a specific operation is still pending.
|
|
630
|
+
*/
|
|
631
|
+
isPending(oid: string): boolean;
|
|
632
|
+
/**
|
|
633
|
+
* Get the number of pending writes.
|
|
634
|
+
*/
|
|
635
|
+
get pendingCount(): number;
|
|
636
|
+
/**
|
|
637
|
+
* Clear all pending writes (e.g., on disconnect when not retrying).
|
|
638
|
+
*/
|
|
639
|
+
clear(): void;
|
|
640
|
+
/**
|
|
641
|
+
* Remove writes older than a specified age (in milliseconds).
|
|
642
|
+
* Useful for cleaning up stale pending writes that may never be acked.
|
|
643
|
+
*/
|
|
644
|
+
removeStale(maxAgeMs: number): number;
|
|
645
|
+
}
|
|
646
|
+
|
|
411
647
|
/**
|
|
412
648
|
* Push ID generation - Firebase-compatible chronologically-sortable IDs.
|
|
413
649
|
*
|
|
@@ -424,4 +660,24 @@ declare class LarkError extends Error {
|
|
|
424
660
|
*/
|
|
425
661
|
declare function generatePushId(): string;
|
|
426
662
|
|
|
427
|
-
|
|
663
|
+
/**
|
|
664
|
+
* Volatile path matching utilities.
|
|
665
|
+
*
|
|
666
|
+
* Volatile paths are patterns where a wildcard matches exactly one path segment.
|
|
667
|
+
* These paths use unreliable transport for better performance (UDP when available).
|
|
668
|
+
*/
|
|
669
|
+
/**
|
|
670
|
+
* Check if a path matches any of the volatile path patterns.
|
|
671
|
+
*
|
|
672
|
+
* Pattern matching rules:
|
|
673
|
+
* - Wildcard matches exactly one path segment (not zero, not multiple)
|
|
674
|
+
* - Patterns and paths are compared segment by segment
|
|
675
|
+
* - Path must have the same number of segments as the pattern
|
|
676
|
+
*
|
|
677
|
+
* @param path - The path to check (e.g., "/players/abc/position")
|
|
678
|
+
* @param patterns - Array of volatile patterns with wildcards
|
|
679
|
+
* @returns true if the path matches any pattern
|
|
680
|
+
*/
|
|
681
|
+
declare function isVolatilePath(path: string, patterns: string[] | null | undefined): boolean;
|
|
682
|
+
|
|
683
|
+
export { type AuthInfo, type ConnectOptions, DataSnapshot, DatabaseReference, type EventType, LarkDatabase, LarkError, type MoveEntry, OnDisconnect, type PendingWrite, PendingWriteManager, type QueryParams, type QueryState, type SnapshotCallback$1 as SnapshotCallback, type TransactionConditionOp, type TransactionDeleteOp, type TransactionObject, type TransactionOp, type TransactionResult, type TransactionSetOp, type TransactionUpdateOp, type WriteOperation, generatePushId, isVolatilePath };
|