@drakkar.software/starfish-client 3.0.0-alpha.38 → 3.0.0-alpha.39

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/client.d.ts CHANGED
@@ -95,6 +95,25 @@ export interface BatchPullOptions {
95
95
  * omit the collection from `params` entirely (an unlisted collection reads one
96
96
  * auto-filled doc). Results come back under the same name in request order. */
97
97
  params?: Record<string, Record<string, string>[]>;
98
+ /**
99
+ * Per-collection append options, index-aligned to `params`. Makes the batch
100
+ * request **append/checkpoint-aware**: each entry returns the bounded tail of
101
+ * that collection's append-only log rather than the full document.
102
+ *
103
+ * Serialized as URL-encoded JSON alongside `params`. Server ignores it for
104
+ * collections that are not append-only (returns `{ error: "append_params_not_supported" }`
105
+ * for those entries). `full` is disallowed in batch (`full_not_allowed` per entry).
106
+ *
107
+ * Example — read the last 5 events for two rooms and the newest item for a third:
108
+ * ```ts
109
+ * await client.batchPull(["events"], {
110
+ * params: { events: [{ room: "a" }, { room: "b" }, { room: "c" }] },
111
+ * appendParams: { events: [{ last: 5 }, { last: 5 }, { last: 1 }] },
112
+ * })
113
+ * ```
114
+ * Each `data[appendField]` in the result is the filtered array for that entry.
115
+ */
116
+ appendParams?: Record<string, AppendPullOptions[]>;
98
117
  }
99
118
  /**
100
119
  * Low-level HTTP client for the Starfish sync protocol.
@@ -239,8 +258,7 @@ export declare class StarfishClient {
239
258
  *
240
259
  * For the common "many docs of one collection" case prefer {@link batchPullMany}.
241
260
  *
242
- * Note: not append/checkpoint-aware for incremental append-only reads use
243
- * `pull(path, { since })` (or `AppendLogCursor`) per collection.
261
+ * Pass `appendParams` per entry for append-only bounded-tail reads (see {@link batchPullManyAppend}).
244
262
  */
245
263
  batchPull(collections: string[], opts?: BatchPullOptions): Promise<BatchPullResult>;
246
264
  /**
@@ -251,6 +269,33 @@ export declare class StarfishClient {
251
269
  * issues no request and returns `[]`.
252
270
  */
253
271
  batchPullMany(collection: string, paramsList: Record<string, string>[]): Promise<BatchPullEntry[]>;
272
+ /**
273
+ * Convenience over {@link batchPull} for reading append-only bounded tails from
274
+ * MANY entries of ONE collection in a single round-trip.
275
+ *
276
+ * Each request in `requests` carries optional `params` (path params) and
277
+ * `options` (append bounds: `since`/`last`/`limit`/`appendField`). An empty
278
+ * `requests` issues no request and returns `[]`.
279
+ *
280
+ * Returns an array aligned to `requests` by index. Each element is either:
281
+ * - the filtered array `T[]` extracted from `entry.data[appendField]`, or
282
+ * - `{ error: string }` if the server returned a per-entry error.
283
+ *
284
+ * The `appendField` used for extraction defaults to `"items"` and can be
285
+ * overridden per request via `options.appendField`.
286
+ *
287
+ * The `appendField` option is client-side only (used for result extraction, not sent to the server).
288
+ * It must match the collection's server-configured append field and defaults to `"items"`.
289
+ *
290
+ * Note: `full: true` is not supported in batch and is rejected client-side
291
+ * before the request is sent.
292
+ */
293
+ batchPullManyAppend<T = unknown>(collection: string, requests: {
294
+ params?: Record<string, string>;
295
+ options: AppendPullOptions;
296
+ }[]): Promise<(T[] | {
297
+ error: string;
298
+ })[]>;
254
299
  /**
255
300
  * Push synced data to the server.
256
301
  * @param path - The push endpoint path (e.g. "/push/users/abc/settings")
package/dist/index.js CHANGED
@@ -446,8 +446,7 @@ var StarfishClient = class {
446
446
  *
447
447
  * For the common "many docs of one collection" case prefer {@link batchPullMany}.
448
448
  *
449
- * Note: not append/checkpoint-aware for incremental append-only reads use
450
- * `pull(path, { since })` (or `AppendLogCursor`) per collection.
449
+ * Pass `appendParams` per entry for append-only bounded-tail reads (see {@link batchPullManyAppend}).
451
450
  */
452
451
  async batchPull(collections, opts = {}) {
453
452
  const search = new URLSearchParams();
@@ -455,6 +454,27 @@ var StarfishClient = class {
455
454
  if (opts.params && Object.keys(opts.params).length > 0) {
456
455
  search.set("params", JSON.stringify(opts.params));
457
456
  }
457
+ if (opts.appendParams && Object.keys(opts.appendParams).length > 0) {
458
+ for (const [col, optsArr] of Object.entries(opts.appendParams)) {
459
+ for (const ap of optsArr) {
460
+ if (ap.full) {
461
+ throw new Error(
462
+ `batchPull: appendParams["${col}"] contains full:true \u2014 full is not supported in batch pull`
463
+ );
464
+ }
465
+ if (ap.since != null && (!Number.isInteger(ap.since) || ap.since < 0)) {
466
+ throw new Error(`batchPull: appendParams["${col}"].since must be a non-negative integer`);
467
+ }
468
+ if (ap.last != null && (!Number.isInteger(ap.last) || ap.last < 0)) {
469
+ throw new Error(`batchPull: appendParams["${col}"].last must be a non-negative integer`);
470
+ }
471
+ if (ap.limit != null && (!Number.isInteger(ap.limit) || ap.limit < 0)) {
472
+ throw new Error(`batchPull: appendParams["${col}"].limit must be a non-negative integer`);
473
+ }
474
+ }
475
+ }
476
+ search.set("appendParams", JSON.stringify(opts.appendParams));
477
+ }
458
478
  const pathAndQuery = `${this.applyNamespace("/batch/pull")}?${search.toString()}`;
459
479
  const url = `${this.baseUrl}${pathAndQuery}`;
460
480
  const authHeaders = await this.buildAuthHeaders("GET", pathAndQuery, void 0);
@@ -479,6 +499,44 @@ var StarfishClient = class {
479
499
  const res = await this.batchPull([collection], { params: { [collection]: paramsList } });
480
500
  return res.collections[collection] ?? [];
481
501
  }
502
+ /**
503
+ * Convenience over {@link batchPull} for reading append-only bounded tails from
504
+ * MANY entries of ONE collection in a single round-trip.
505
+ *
506
+ * Each request in `requests` carries optional `params` (path params) and
507
+ * `options` (append bounds: `since`/`last`/`limit`/`appendField`). An empty
508
+ * `requests` issues no request and returns `[]`.
509
+ *
510
+ * Returns an array aligned to `requests` by index. Each element is either:
511
+ * - the filtered array `T[]` extracted from `entry.data[appendField]`, or
512
+ * - `{ error: string }` if the server returned a per-entry error.
513
+ *
514
+ * The `appendField` used for extraction defaults to `"items"` and can be
515
+ * overridden per request via `options.appendField`.
516
+ *
517
+ * The `appendField` option is client-side only (used for result extraction, not sent to the server).
518
+ * It must match the collection's server-configured append field and defaults to `"items"`.
519
+ *
520
+ * Note: `full: true` is not supported in batch and is rejected client-side
521
+ * before the request is sent.
522
+ */
523
+ async batchPullManyAppend(collection, requests) {
524
+ if (requests.length === 0) return [];
525
+ const paramsList = requests.map((r) => r.params ?? {});
526
+ const appendParamsList = requests.map(({ options: { appendField: _af, ...wireOpts } }) => wireOpts);
527
+ const res = await this.batchPull([collection], {
528
+ params: { [collection]: paramsList },
529
+ appendParams: { [collection]: appendParamsList }
530
+ });
531
+ const entries = res.collections[collection] ?? [];
532
+ return entries.map((entry, i) => {
533
+ if (entry.error) return { error: entry.error };
534
+ const appendField = requests[i]?.options.appendField ?? APPEND_DEFAULT_FIELD;
535
+ const data = entry.data;
536
+ const items = data?.[appendField];
537
+ return Array.isArray(items) ? items : [];
538
+ });
539
+ }
482
540
  /**
483
541
  * Push synced data to the server.
484
542
  * @param path - The push endpoint path (e.g. "/push/users/abc/settings")