@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.
@@ -671,8 +671,7 @@ var StarfishClient = class {
671
671
  *
672
672
  * For the common "many docs of one collection" case prefer {@link batchPullMany}.
673
673
  *
674
- * Note: not append/checkpoint-aware for incremental append-only reads use
675
- * `pull(path, { since })` (or `AppendLogCursor`) per collection.
674
+ * Pass `appendParams` per entry for append-only bounded-tail reads (see {@link batchPullManyAppend}).
676
675
  */
677
676
  async batchPull(collections, opts = {}) {
678
677
  const search = new URLSearchParams();
@@ -680,6 +679,27 @@ var StarfishClient = class {
680
679
  if (opts.params && Object.keys(opts.params).length > 0) {
681
680
  search.set("params", JSON.stringify(opts.params));
682
681
  }
682
+ if (opts.appendParams && Object.keys(opts.appendParams).length > 0) {
683
+ for (const [col, optsArr] of Object.entries(opts.appendParams)) {
684
+ for (const ap of optsArr) {
685
+ if (ap.full) {
686
+ throw new Error(
687
+ `batchPull: appendParams["${col}"] contains full:true \u2014 full is not supported in batch pull`
688
+ );
689
+ }
690
+ if (ap.since != null && (!Number.isInteger(ap.since) || ap.since < 0)) {
691
+ throw new Error(`batchPull: appendParams["${col}"].since must be a non-negative integer`);
692
+ }
693
+ if (ap.last != null && (!Number.isInteger(ap.last) || ap.last < 0)) {
694
+ throw new Error(`batchPull: appendParams["${col}"].last must be a non-negative integer`);
695
+ }
696
+ if (ap.limit != null && (!Number.isInteger(ap.limit) || ap.limit < 0)) {
697
+ throw new Error(`batchPull: appendParams["${col}"].limit must be a non-negative integer`);
698
+ }
699
+ }
700
+ }
701
+ search.set("appendParams", JSON.stringify(opts.appendParams));
702
+ }
683
703
  const pathAndQuery = `${this.applyNamespace("/batch/pull")}?${search.toString()}`;
684
704
  const url = `${this.baseUrl}${pathAndQuery}`;
685
705
  const authHeaders = await this.buildAuthHeaders("GET", pathAndQuery, void 0);
@@ -704,6 +724,44 @@ var StarfishClient = class {
704
724
  const res = await this.batchPull([collection], { params: { [collection]: paramsList } });
705
725
  return res.collections[collection] ?? [];
706
726
  }
727
+ /**
728
+ * Convenience over {@link batchPull} for reading append-only bounded tails from
729
+ * MANY entries of ONE collection in a single round-trip.
730
+ *
731
+ * Each request in `requests` carries optional `params` (path params) and
732
+ * `options` (append bounds: `since`/`last`/`limit`/`appendField`). An empty
733
+ * `requests` issues no request and returns `[]`.
734
+ *
735
+ * Returns an array aligned to `requests` by index. Each element is either:
736
+ * - the filtered array `T[]` extracted from `entry.data[appendField]`, or
737
+ * - `{ error: string }` if the server returned a per-entry error.
738
+ *
739
+ * The `appendField` used for extraction defaults to `"items"` and can be
740
+ * overridden per request via `options.appendField`.
741
+ *
742
+ * The `appendField` option is client-side only (used for result extraction, not sent to the server).
743
+ * It must match the collection's server-configured append field and defaults to `"items"`.
744
+ *
745
+ * Note: `full: true` is not supported in batch and is rejected client-side
746
+ * before the request is sent.
747
+ */
748
+ async batchPullManyAppend(collection, requests) {
749
+ if (requests.length === 0) return [];
750
+ const paramsList = requests.map((r) => r.params ?? {});
751
+ const appendParamsList = requests.map(({ options: { appendField: _af, ...wireOpts } }) => wireOpts);
752
+ const res = await this.batchPull([collection], {
753
+ params: { [collection]: paramsList },
754
+ appendParams: { [collection]: appendParamsList }
755
+ });
756
+ const entries = res.collections[collection] ?? [];
757
+ return entries.map((entry, i) => {
758
+ if (entry.error) return { error: entry.error };
759
+ const appendField = requests[i]?.options.appendField ?? APPEND_DEFAULT_FIELD;
760
+ const data = entry.data;
761
+ const items = data?.[appendField];
762
+ return Array.isArray(items) ? items : [];
763
+ });
764
+ }
707
765
  /**
708
766
  * Push synced data to the server.
709
767
  * @param path - The push endpoint path (e.g. "/push/users/abc/settings")