@topgunbuild/client 0.8.1 → 0.10.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/dist/index.mjs CHANGED
@@ -1336,10 +1336,11 @@ var _SyncEngine = class _SyncEngine {
1336
1336
  break;
1337
1337
  }
1338
1338
  case "QUERY_RESP": {
1339
- const { queryId, results } = message.payload;
1339
+ const { queryId, results, nextCursor, hasMore, cursorStatus } = message.payload;
1340
1340
  const query = this.queries.get(queryId);
1341
1341
  if (query) {
1342
1342
  query.onResult(results, "server");
1343
+ query.updatePaginationInfo({ nextCursor, hasMore, cursorStatus });
1343
1344
  }
1344
1345
  break;
1345
1346
  }
@@ -2493,7 +2494,8 @@ var _SyncEngine = class _SyncEngine {
2493
2494
  where: filter.where,
2494
2495
  sort: filter.sort,
2495
2496
  limit: filter.limit,
2496
- offset: filter.offset
2497
+ cursor: filter.cursor
2498
+ // Phase 14.1: replaces offset
2497
2499
  }
2498
2500
  });
2499
2501
  }
@@ -2566,9 +2568,6 @@ var _SyncEngine = class _SyncEngine {
2566
2568
  });
2567
2569
  }
2568
2570
  let sliced = results;
2569
- if (filter.offset) {
2570
- sliced = sliced.slice(filter.offset);
2571
- }
2572
2571
  if (filter.limit) {
2573
2572
  sliced = sliced.slice(0, filter.limit);
2574
2573
  }
@@ -2581,6 +2580,11 @@ var _SyncEngine = class _SyncEngine {
2581
2580
  const query = this.hybridQueries.get(payload.subscriptionId);
2582
2581
  if (query) {
2583
2582
  query.onResult(payload.results, "server");
2583
+ query.updatePaginationInfo({
2584
+ nextCursor: payload.nextCursor,
2585
+ hasMore: payload.hasMore,
2586
+ cursorStatus: payload.cursorStatus
2587
+ });
2584
2588
  }
2585
2589
  }
2586
2590
  /**
@@ -2703,6 +2707,9 @@ var QueryHandle = class {
2703
2707
  this.changeTracker = new ChangeTracker();
2704
2708
  this.pendingChanges = [];
2705
2709
  this.changeListeners = /* @__PURE__ */ new Set();
2710
+ // Pagination info (Phase 14.1)
2711
+ this._paginationInfo = { hasMore: false, cursorStatus: "none" };
2712
+ this.paginationListeners = /* @__PURE__ */ new Set();
2706
2713
  // Track if we've received authoritative server response
2707
2714
  this.hasReceivedServerData = false;
2708
2715
  this.id = crypto.randomUUID();
@@ -2896,6 +2903,49 @@ var QueryHandle = class {
2896
2903
  getMapName() {
2897
2904
  return this.mapName;
2898
2905
  }
2906
+ // ============== Pagination Methods (Phase 14.1) ==============
2907
+ /**
2908
+ * Get current pagination info.
2909
+ * Returns nextCursor, hasMore, and cursorStatus.
2910
+ */
2911
+ getPaginationInfo() {
2912
+ return { ...this._paginationInfo };
2913
+ }
2914
+ /**
2915
+ * Subscribe to pagination info changes.
2916
+ * Called when server sends QUERY_RESP with new cursor info.
2917
+ *
2918
+ * @returns Unsubscribe function
2919
+ */
2920
+ onPaginationChange(listener) {
2921
+ this.paginationListeners.add(listener);
2922
+ listener(this.getPaginationInfo());
2923
+ return () => this.paginationListeners.delete(listener);
2924
+ }
2925
+ /**
2926
+ * Update pagination info from server response.
2927
+ * Called by SyncEngine when processing QUERY_RESP.
2928
+ *
2929
+ * @internal
2930
+ */
2931
+ updatePaginationInfo(info) {
2932
+ this._paginationInfo = {
2933
+ nextCursor: info.nextCursor,
2934
+ hasMore: info.hasMore ?? false,
2935
+ cursorStatus: info.cursorStatus ?? "none"
2936
+ };
2937
+ this.notifyPaginationListeners();
2938
+ }
2939
+ notifyPaginationListeners() {
2940
+ const info = this.getPaginationInfo();
2941
+ for (const listener of this.paginationListeners) {
2942
+ try {
2943
+ listener(info);
2944
+ } catch (e) {
2945
+ logger.error({ err: e }, "QueryHandle pagination listener error");
2946
+ }
2947
+ }
2948
+ }
2899
2949
  };
2900
2950
 
2901
2951
  // src/DistributedLock.ts
@@ -3487,6 +3537,9 @@ var HybridQueryHandle = class {
3487
3537
  this.changeListeners = /* @__PURE__ */ new Set();
3488
3538
  // Track server data reception
3489
3539
  this.hasReceivedServerData = false;
3540
+ // Pagination info (Phase 14.1)
3541
+ this._paginationInfo = { hasMore: false, cursorStatus: "none" };
3542
+ this.paginationListeners = /* @__PURE__ */ new Set();
3490
3543
  this.id = crypto.randomUUID();
3491
3544
  this.syncEngine = syncEngine;
3492
3545
  this.mapName = mapName;
@@ -3669,9 +3722,6 @@ var HybridQueryHandle = class {
3669
3722
  });
3670
3723
  }
3671
3724
  let sliced = results;
3672
- if (this.filter.offset) {
3673
- sliced = sliced.slice(this.filter.offset);
3674
- }
3675
3725
  if (this.filter.limit) {
3676
3726
  sliced = sliced.slice(0, this.filter.limit);
3677
3727
  }
@@ -3704,6 +3754,49 @@ var HybridQueryHandle = class {
3704
3754
  }
3705
3755
  return false;
3706
3756
  }
3757
+ // ============== Pagination Methods (Phase 14.1) ==============
3758
+ /**
3759
+ * Get current pagination info.
3760
+ * Returns nextCursor, hasMore, and cursorStatus.
3761
+ */
3762
+ getPaginationInfo() {
3763
+ return { ...this._paginationInfo };
3764
+ }
3765
+ /**
3766
+ * Subscribe to pagination info changes.
3767
+ * Called when server sends HYBRID_QUERY_RESP with new cursor info.
3768
+ *
3769
+ * @returns Unsubscribe function
3770
+ */
3771
+ onPaginationChange(listener) {
3772
+ this.paginationListeners.add(listener);
3773
+ listener(this.getPaginationInfo());
3774
+ return () => this.paginationListeners.delete(listener);
3775
+ }
3776
+ /**
3777
+ * Update pagination info from server response.
3778
+ * Called by SyncEngine when processing HYBRID_QUERY_RESP.
3779
+ *
3780
+ * @internal
3781
+ */
3782
+ updatePaginationInfo(info) {
3783
+ this._paginationInfo = {
3784
+ nextCursor: info.nextCursor,
3785
+ hasMore: info.hasMore ?? false,
3786
+ cursorStatus: info.cursorStatus ?? "none"
3787
+ };
3788
+ this.notifyPaginationListeners();
3789
+ }
3790
+ notifyPaginationListeners() {
3791
+ const info = this.getPaginationInfo();
3792
+ for (const listener of this.paginationListeners) {
3793
+ try {
3794
+ listener(info);
3795
+ } catch (e) {
3796
+ logger.error({ err: e }, "HybridQueryHandle pagination listener error");
3797
+ }
3798
+ }
3799
+ }
3707
3800
  };
3708
3801
 
3709
3802
  // src/cluster/ClusterClient.ts
@@ -5610,7 +5703,7 @@ var TopGunClient = class {
5610
5703
  * Results include relevance scores for FTS ranking.
5611
5704
  *
5612
5705
  * @param mapName Name of the map to query
5613
- * @param filter Hybrid query filter with predicate, where, sort, limit, offset
5706
+ * @param filter Hybrid query filter with predicate, where, sort, limit, cursor
5614
5707
  * @returns HybridQueryHandle for managing the subscription
5615
5708
  *
5616
5709
  * @example