@lark-sh/client 0.1.16 → 0.1.18

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.
@@ -1,59 +1,3 @@
1
- // src/protocol/constants.ts
2
- var OnDisconnectAction = {
3
- SET: "s",
4
- UPDATE: "u",
5
- DELETE: "d",
6
- CANCEL: "c"
7
- };
8
- var ErrorCode = {
9
- PERMISSION_DENIED: "permission_denied",
10
- INVALID_DATA: "invalid_data",
11
- NOT_FOUND: "not_found",
12
- INVALID_PATH: "invalid_path",
13
- INVALID_OPERATION: "invalid_operation",
14
- INTERNAL_ERROR: "internal_error",
15
- CONDITION_FAILED: "condition_failed",
16
- INVALID_QUERY: "invalid_query",
17
- AUTH_REQUIRED: "auth_required"
18
- };
19
- var DEFAULT_COORDINATOR_URL = "https://db.lark.sh";
20
-
21
- // src/connection/Coordinator.ts
22
- var Coordinator = class {
23
- constructor(baseUrl = DEFAULT_COORDINATOR_URL) {
24
- this.baseUrl = baseUrl.replace(/\/$/, "");
25
- }
26
- /**
27
- * Request connection details from the coordinator.
28
- *
29
- * @param database - Database ID in format "project/database"
30
- * @returns Connection details including WebSocket URL and UDP host/port
31
- */
32
- async connect(database) {
33
- const body = { database };
34
- const response = await fetch(`${this.baseUrl}/connect`, {
35
- method: "POST",
36
- headers: {
37
- "Content-Type": "application/json"
38
- },
39
- body: JSON.stringify(body)
40
- });
41
- if (!response.ok) {
42
- let errorMessage = `Coordinator request failed: ${response.status}`;
43
- try {
44
- const errorBody = await response.json();
45
- if (errorBody.message) {
46
- errorMessage = errorBody.message;
47
- }
48
- } catch {
49
- }
50
- throw new Error(errorMessage);
51
- }
52
- const data = await response.json();
53
- return data;
54
- }
55
- };
56
-
57
1
  // src/connection/WebSocketTransport.ts
58
2
  import WebSocketNode from "ws";
59
3
  var WebSocketImpl = typeof WebSocket !== "undefined" ? WebSocket : WebSocketNode;
@@ -1420,7 +1364,6 @@ var View = class {
1420
1364
  /**
1421
1365
  * Check if this View loads all data (no limits, no range filters).
1422
1366
  * A View that loads all data can serve as a "complete" cache for child paths.
1423
- * This matches Firebase's loadsAllData() semantics.
1424
1367
  */
1425
1368
  loadsAllData() {
1426
1369
  if (!this.queryParams) return true;
@@ -1836,8 +1779,8 @@ var SubscriptionManager = class {
1836
1779
  /**
1837
1780
  * Detect and fire child_moved events for children that changed position OR sort value.
1838
1781
  *
1839
- * Firebase fires child_moved for ANY priority/sort value change, regardless of whether
1840
- * the position actually changes. This is Case 2003 behavior.
1782
+ * child_moved fires for ANY priority/sort value change, regardless of whether
1783
+ * the position actually changes.
1841
1784
  *
1842
1785
  * IMPORTANT: child_moved should only fire for children whose VALUE or PRIORITY changed.
1843
1786
  * Children that are merely "displaced" by another child moving should NOT fire child_moved.
@@ -2040,9 +1983,6 @@ var SubscriptionManager = class {
2040
1983
  * A complete View has no limits and no range filters, so it contains all data
2041
1984
  * for its subtree. Child subscriptions can use the ancestor's data instead
2042
1985
  * of creating their own server subscription.
2043
- *
2044
- * This matches Firebase's behavior where child listeners don't need their own
2045
- * server subscription if an ancestor has an unlimited listener.
2046
1986
  */
2047
1987
  hasAncestorCompleteView(path) {
2048
1988
  const normalized = normalizePath(path);
@@ -2168,8 +2108,8 @@ var SubscriptionManager = class {
2168
2108
  /**
2169
2109
  * Recursively sort object keys for consistent comparison.
2170
2110
  * This ensures {a:1, b:2} and {b:2, a:1} compare as equal.
2171
- * Uses simple alphabetical sorting (not Firebase key sorting) since we're
2172
- * just checking data equality, not display order.
2111
+ * Uses simple alphabetical sorting since we're just checking data equality,
2112
+ * not display order.
2173
2113
  */
2174
2114
  sortKeysForComparison(value) {
2175
2115
  if (value === null || typeof value !== "object") {
@@ -2763,6 +2703,26 @@ var SubscriptionManager = class {
2763
2703
  }
2764
2704
  };
2765
2705
 
2706
+ // src/protocol/constants.ts
2707
+ var OnDisconnectAction = {
2708
+ SET: "s",
2709
+ UPDATE: "u",
2710
+ DELETE: "d",
2711
+ CANCEL: "c"
2712
+ };
2713
+ var ErrorCode = {
2714
+ PERMISSION_DENIED: "permission_denied",
2715
+ INVALID_DATA: "invalid_data",
2716
+ NOT_FOUND: "not_found",
2717
+ INVALID_PATH: "invalid_path",
2718
+ INVALID_OPERATION: "invalid_operation",
2719
+ INTERNAL_ERROR: "internal_error",
2720
+ CONDITION_FAILED: "condition_failed",
2721
+ INVALID_QUERY: "invalid_query",
2722
+ AUTH_REQUIRED: "auth_required"
2723
+ };
2724
+ var DEFAULT_LARK_DOMAIN = "larkdb.net";
2725
+
2766
2726
  // src/OnDisconnect.ts
2767
2727
  var OnDisconnect = class {
2768
2728
  constructor(db, path) {
@@ -2868,6 +2828,7 @@ function generatePushId() {
2868
2828
 
2869
2829
  // src/utils/validation.ts
2870
2830
  var MAX_KEY_BYTES = 768;
2831
+ var MAX_STRING_VALUE_BYTES = 10 * 1024 * 1024;
2871
2832
  var INVALID_KEY_CHARS = /[.#$\[\]\/]/;
2872
2833
  var CONTROL_CHARS = /[\x00-\x1f\x7f]/;
2873
2834
  function hasControlChars(str) {
@@ -2938,10 +2899,11 @@ function validateValue(value, context, path = "") {
2938
2899
  return;
2939
2900
  }
2940
2901
  if (typeof value === "string") {
2941
- if (hasControlChars(value)) {
2902
+ const byteLength = getByteLength(value);
2903
+ if (byteLength > MAX_STRING_VALUE_BYTES) {
2942
2904
  throw new LarkError(
2943
2905
  ErrorCode.INVALID_DATA,
2944
- `${prefix}string value${location} contains control characters (ASCII 0-31, 127 are not allowed)`
2906
+ `${prefix}string value${location} exceeds maximum size of 10 MB (got ${Math.round(byteLength / 1024 / 1024 * 100) / 100} MB)`
2945
2907
  );
2946
2908
  }
2947
2909
  return;
@@ -3060,7 +3022,6 @@ var DatabaseReference = class _DatabaseReference {
3060
3022
  * For queries (created via orderBy*, limitTo*, startAt, etc.), this returns
3061
3023
  * a reference to the same path without query constraints.
3062
3024
  * For non-query references, this returns the reference itself.
3063
- * This matches Firebase's Query.ref behavior.
3064
3025
  */
3065
3026
  get ref() {
3066
3027
  if (Object.keys(this._query).length === 0) {
@@ -3085,7 +3046,7 @@ var DatabaseReference = class _DatabaseReference {
3085
3046
  * Returns "default" for non-query references (no constraints).
3086
3047
  * Returns a sorted JSON string of wire-format params for queries.
3087
3048
  *
3088
- * This matches Firebase's queryIdentifier format for wire compatibility.
3049
+ * Used for wire protocol and subscription deduplication.
3089
3050
  */
3090
3051
  get queryIdentifier() {
3091
3052
  const queryObj = {};
@@ -3144,7 +3105,7 @@ var DatabaseReference = class _DatabaseReference {
3144
3105
  }
3145
3106
  /**
3146
3107
  * Get the data at this location. Alias for once('value').
3147
- * This is Firebase's newer API for reading data.
3108
+ * Alternative to once('value') for reading data.
3148
3109
  */
3149
3110
  async get() {
3150
3111
  return this.once("value");
@@ -3183,7 +3144,7 @@ var DatabaseReference = class _DatabaseReference {
3183
3144
  /**
3184
3145
  * Update specific children at this location without overwriting other children.
3185
3146
  *
3186
- * Also supports Firebase-style multi-path updates when keys look like paths
3147
+ * Also supports multi-path updates when keys look like paths
3187
3148
  * (start with '/'). In this mode, each path is written atomically as a transaction.
3188
3149
  *
3189
3150
  * @example
@@ -3264,7 +3225,7 @@ var DatabaseReference = class _DatabaseReference {
3264
3225
  * For objects: injects `.priority` into the value object.
3265
3226
  * For primitives: wraps as `{ '.value': primitive, '.priority': priority }`.
3266
3227
  *
3267
- * This follows Firebase's wire format for primitives with priority.
3228
+ * Uses { '.value': value, '.priority': priority } format for the wire protocol.
3268
3229
  *
3269
3230
  * @param value - The value to write
3270
3231
  * @param priority - The priority for ordering
@@ -4024,9 +3985,9 @@ var DataSnapshot = class _DataSnapshot {
4024
3985
  * Get a child snapshot at the specified path.
4025
3986
  *
4026
3987
  * Special handling:
4027
- * - `.priority` returns the priority value (Firebase compatible)
3988
+ * - `.priority` returns the priority value
4028
3989
  * - For wrapped primitives, only `.priority` returns data; other paths return null
4029
- * - Non-existent paths return a snapshot with val() === null (Firebase compatible)
3990
+ * - Non-existent paths return a snapshot with val() === null
4030
3991
  */
4031
3992
  child(path) {
4032
3993
  const childPath = joinPath(this._path, path);
@@ -4130,7 +4091,6 @@ var DataSnapshot = class _DataSnapshot {
4130
4091
  }
4131
4092
  /**
4132
4093
  * Check if this snapshot was from a volatile (high-frequency) update.
4133
- * This is a Lark extension not present in Firebase.
4134
4094
  */
4135
4095
  isVolatile() {
4136
4096
  return this._volatile;
@@ -4139,7 +4099,6 @@ var DataSnapshot = class _DataSnapshot {
4139
4099
  * Get the server timestamp for this snapshot (milliseconds since Unix epoch).
4140
4100
  * Only present on volatile value events. Use deltas between timestamps for
4141
4101
  * interpolation rather than absolute times to avoid clock sync issues.
4142
- * This is a Lark extension not present in Firebase.
4143
4102
  */
4144
4103
  getServerTimestamp() {
4145
4104
  return this._serverTimestamp;
@@ -4262,7 +4221,7 @@ var LarkDatabase = class {
4262
4221
  this._state = "disconnected";
4263
4222
  this._auth = null;
4264
4223
  this._databaseId = null;
4265
- this._coordinatorUrl = null;
4224
+ this._domain = null;
4266
4225
  this._volatilePaths = [];
4267
4226
  this._transportType = null;
4268
4227
  // Auth state
@@ -4325,8 +4284,9 @@ var LarkDatabase = class {
4325
4284
  * @internal Get the base URL for reference toString().
4326
4285
  */
4327
4286
  _getBaseUrl() {
4328
- if (this._coordinatorUrl && this._databaseId) {
4329
- return `${this._coordinatorUrl}/${this._databaseId}`;
4287
+ if (this._domain && this._databaseId) {
4288
+ const projectId = this._databaseId.split("/")[0];
4289
+ return `https://${projectId}.${this._domain}`;
4330
4290
  }
4331
4291
  return "lark://";
4332
4292
  }
@@ -4378,7 +4338,7 @@ var LarkDatabase = class {
4378
4338
  * Connect to a database.
4379
4339
  *
4380
4340
  * @param databaseId - Database ID in format "project/database"
4381
- * @param options - Connection options (token, anonymous, coordinator URL)
4341
+ * @param options - Connection options (token, anonymous, domain)
4382
4342
  */
4383
4343
  async connect(databaseId, options = {}) {
4384
4344
  if (this._state !== "disconnected") {
@@ -4402,16 +4362,17 @@ var LarkDatabase = class {
4402
4362
  const previousState = this._state;
4403
4363
  this._state = isReconnect ? "reconnecting" : "connecting";
4404
4364
  this._databaseId = databaseId;
4405
- this._coordinatorUrl = options.coordinator || DEFAULT_COORDINATOR_URL;
4365
+ this._domain = options.domain || DEFAULT_LARK_DOMAIN;
4406
4366
  if (!isReconnect) {
4407
4367
  this._currentToken = options.token || "";
4408
4368
  this._isAnonymous = !options.token && options.anonymous !== false;
4409
4369
  }
4410
4370
  try {
4411
- const coordinatorUrl = this._coordinatorUrl;
4412
- const coordinator = new Coordinator(coordinatorUrl);
4413
- const connectResponse = await coordinator.connect(databaseId);
4414
- const wsUrl = connectResponse.ws_url;
4371
+ const projectId = databaseId.split("/")[0];
4372
+ if (!projectId) {
4373
+ throw new Error('Invalid database ID: must be in format "projectId/databaseName"');
4374
+ }
4375
+ const wsUrl = `wss://${projectId}.${this._domain}/ws`;
4415
4376
  const transportResult = await createTransport(
4416
4377
  wsUrl,
4417
4378
  {
@@ -4572,7 +4533,7 @@ var LarkDatabase = class {
4572
4533
  this._auth = null;
4573
4534
  this._databaseId = null;
4574
4535
  this._volatilePaths = [];
4575
- this._coordinatorUrl = null;
4536
+ this._domain = null;
4576
4537
  this._connectionId = null;
4577
4538
  this._connectOptions = null;
4578
4539
  this._transportType = null;
@@ -4769,7 +4730,7 @@ var LarkDatabase = class {
4769
4730
  *
4770
4731
  * Supports two syntaxes:
4771
4732
  *
4772
- * **Object syntax** (like Firebase multi-path update):
4733
+ * **Object syntax** (multi-path update):
4773
4734
  * ```javascript
4774
4735
  * await db.transaction({
4775
4736
  * '/users/alice/name': 'Alice',
@@ -5389,4 +5350,4 @@ export {
5389
5350
  ServerValue,
5390
5351
  LarkDatabase
5391
5352
  };
5392
- //# sourceMappingURL=chunk-CYCSP6TZ.mjs.map
5353
+ //# sourceMappingURL=chunk-UVJBN3NR.mjs.map