@seaverse/data-service-sdk 0.10.2 → 0.11.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/README.md CHANGED
@@ -16,6 +16,7 @@ SeaVerse Data Service SDK for accessing Firestore with secure token management a
16
16
  |---------------------|---------------|--------------|
17
17
  | **Write Public Data** | `helper.addToPublicData()` | `await helper.addToPublicData('posts', {title: 'Hello'})` |
18
18
  | **Read Public Data** | `helper.getPublicData()` | `const posts = await helper.getPublicData('posts')` |
19
+ | **Read with Pagination** | `helper.getPublicData()` | `const posts = await helper.getPublicData('posts', false, {limit: 10})` |
19
20
  | **Write Private Data** | `helper.addToUserData()` | `await helper.addToUserData('notes', {text: 'Secret'})` |
20
21
  | **Read Private Data** | `helper.getUserData()` | `const notes = await helper.getUserData('notes')` |
21
22
 
@@ -378,6 +379,16 @@ posts.forEach(doc => {
378
379
  console.log(doc.id, doc.data());
379
380
  });
380
381
 
382
+ // ✅ Pagination support: Get first 10 posts
383
+ const firstPage = await helper.getPublicData('posts', false, { limit: 10 });
384
+
385
+ // Get next 10 posts (start after last document)
386
+ const lastDoc = firstPage.docs[firstPage.docs.length - 1];
387
+ const nextPage = await helper.getPublicData('posts', false, {
388
+ limit: 10,
389
+ startAfter: lastDoc
390
+ });
391
+
381
392
  // ✅ LLM-FRIENDLY: Write to userData (private) - auto-isolated!
382
393
  await helper.addToUserData('notes', {
383
394
  title: 'Private Note',
@@ -762,6 +773,42 @@ const userPosts = query(
762
773
  const snapshot = await getDocs(userPosts);
763
774
  ```
764
775
 
776
+ ### Use Case 5: Pagination (New!)
777
+
778
+ ```typescript
779
+ // ✅ Simple pagination with FirestoreHelper
780
+
781
+ // Get first page (10 posts)
782
+ const firstPage = await helper.getPublicData('posts', false, { limit: 10 });
783
+
784
+ console.log(`Fetched ${firstPage.docs.length} posts`);
785
+ firstPage.forEach(doc => {
786
+ console.log('Post:', doc.id, doc.data());
787
+ });
788
+
789
+ // Check if there are more pages
790
+ if (firstPage.docs.length === 10) {
791
+ // Get next page (start after last document)
792
+ const lastDoc = firstPage.docs[firstPage.docs.length - 1];
793
+ const nextPage = await helper.getPublicData('posts', false, {
794
+ limit: 10,
795
+ startAfter: lastDoc
796
+ });
797
+
798
+ console.log(`Next page: ${nextPage.docs.length} posts`);
799
+ }
800
+
801
+ // Also works with getUserData and getPublicRead
802
+ const userNotes = await helper.getUserData('notes', false, { limit: 20 });
803
+ const configs = await helper.getPublicRead('config', { limit: 5 });
804
+ ```
805
+
806
+ **Pagination Best Practices:**
807
+ - Use a consistent `limit` value across pages for predictable UX
808
+ - Store the last document from the current page to fetch the next page
809
+ - Check if `docs.length` equals your limit to determine if there might be more pages
810
+ - For infinite scroll, keep appending results; for traditional pagination, replace the view
811
+
765
812
  ## Permission Examples
766
813
 
767
814
  ### What Users CAN Do
@@ -1316,4 +1363,4 @@ Here's a complete example for using the SDK directly in the browser without any
1316
1363
  ## Related SDKs
1317
1364
 
1318
1365
  - [@seaverse/auth-sdk](../auth-sdk) - User authentication and account management
1319
- - [@seaverse/payment-sdk](../payment-sdk) - Payment processing integration
1366
+ - [@seaverse/assets-sdk](../assets-sdk) - Assets and payment processing integration
package/dist/browser.js CHANGED
@@ -4782,6 +4782,7 @@ class FirestoreHelper {
4782
4782
  *
4783
4783
  * @param collectionName - Collection name
4784
4784
  * @param includeDeleted - Include soft-deleted documents (default: false)
4785
+ * @param options - Pagination options (limit and startAfter)
4785
4786
  * @returns QuerySnapshot with documents
4786
4787
  *
4787
4788
  * @example
@@ -4794,11 +4795,21 @@ class FirestoreHelper {
4794
4795
  *
4795
4796
  * // Include deleted posts (admin use case)
4796
4797
  * const allPosts = await helper.getPublicData('posts', true);
4798
+ *
4799
+ * // Pagination: Get first 10 posts
4800
+ * const firstPage = await helper.getPublicData('posts', false, { limit: 10 });
4801
+ *
4802
+ * // Get next 10 posts (start after last document)
4803
+ * const lastDoc = firstPage.docs[firstPage.docs.length - 1];
4804
+ * const nextPage = await helper.getPublicData('posts', false, {
4805
+ * limit: 10,
4806
+ * startAfter: lastDoc
4807
+ * });
4797
4808
  * ```
4798
4809
  */
4799
- async getPublicData(collectionName, includeDeleted = false) {
4810
+ async getPublicData(collectionName, includeDeleted = false, options) {
4800
4811
  const path = getPublicDataPath(this.appId, collectionName);
4801
- return this.getDocs(path, includeDeleted);
4812
+ return this.getDocs(path, includeDeleted, options);
4802
4813
  }
4803
4814
  /**
4804
4815
  * Get all documents from userData collection (user's private data)
@@ -4807,6 +4818,7 @@ class FirestoreHelper {
4807
4818
  *
4808
4819
  * @param collectionName - Collection name
4809
4820
  * @param includeDeleted - Include soft-deleted documents (default: false)
4821
+ * @param options - Pagination options (limit and startAfter)
4810
4822
  * @returns QuerySnapshot with documents
4811
4823
  *
4812
4824
  * @example
@@ -4815,26 +4827,45 @@ class FirestoreHelper {
4815
4827
  * snapshot.forEach(doc => {
4816
4828
  * console.log('My note:', doc.data());
4817
4829
  * });
4830
+ *
4831
+ * // Pagination: Get first 20 notes
4832
+ * const firstPage = await helper.getUserData('notes', false, { limit: 20 });
4833
+ *
4834
+ * // Get next page
4835
+ * const lastDoc = firstPage.docs[firstPage.docs.length - 1];
4836
+ * const nextPage = await helper.getUserData('notes', false, {
4837
+ * limit: 20,
4838
+ * startAfter: lastDoc
4839
+ * });
4818
4840
  * ```
4819
4841
  */
4820
- async getUserData(collectionName, includeDeleted = false) {
4842
+ async getUserData(collectionName, includeDeleted = false, options) {
4821
4843
  const path = getUserDataPath(this.appId, this.userId, collectionName);
4822
- return this.getDocs(path, includeDeleted);
4844
+ return this.getDocs(path, includeDeleted, options);
4823
4845
  }
4824
4846
  /**
4825
4847
  * Get all documents from publicRead collection (read-only for users)
4826
4848
  *
4827
4849
  * @param collectionName - Collection name
4850
+ * @param options - Pagination options (limit and startAfter)
4828
4851
  * @returns QuerySnapshot with documents
4829
4852
  *
4830
4853
  * @example
4831
4854
  * ```typescript
4832
4855
  * const configs = await helper.getPublicRead('config');
4856
+ *
4857
+ * // Pagination
4858
+ * const firstPage = await helper.getPublicRead('config', { limit: 10 });
4859
+ * const lastDoc = firstPage.docs[firstPage.docs.length - 1];
4860
+ * const nextPage = await helper.getPublicRead('config', {
4861
+ * limit: 10,
4862
+ * startAfter: lastDoc
4863
+ * });
4833
4864
  * ```
4834
4865
  */
4835
- async getPublicRead(collectionName) {
4866
+ async getPublicRead(collectionName, options) {
4836
4867
  const path = getPublicReadPath(this.appId, collectionName);
4837
- return this.getDocs(path);
4868
+ return this.getDocs(path, false, options);
4838
4869
  }
4839
4870
  /**
4840
4871
  * Get collection reference for publicData
@@ -5003,22 +5034,36 @@ class FirestoreHelper {
5003
5034
  }
5004
5035
  /**
5005
5036
  * Internal: Get all documents from collection
5006
- * Optionally filter out soft-deleted documents
5037
+ * Optionally filter out soft-deleted documents and support pagination
5007
5038
  */
5008
- async getDocs(collectionPath, includeDeleted = false) {
5009
- const { getDocs, collection, query, where } = await this.loadFirestore();
5039
+ async getDocs(collectionPath, includeDeleted = false, options) {
5040
+ const { getDocs, collection, query, where, limit, startAfter } = await this.loadFirestore();
5010
5041
  const colRef = collection(this.db, collectionPath);
5011
- if (includeDeleted) {
5012
- // Return all documents (including soft-deleted)
5013
- return getDocs(colRef);
5014
- }
5015
- else {
5042
+ // Build query constraints
5043
+ const constraints = [];
5044
+ // Add soft-delete filter if needed
5045
+ if (!includeDeleted) {
5016
5046
  // Filter out soft-deleted documents
5017
5047
  // Use '!=' to include documents without _deleted field (new documents)
5018
5048
  // This will return documents where _deleted is missing, null, undefined, or false
5019
- const q = query(colRef, where('_deleted', '!=', true));
5049
+ constraints.push(where('_deleted', '!=', true));
5050
+ }
5051
+ // Add pagination constraints if provided
5052
+ if (options?.limit) {
5053
+ constraints.push(limit(options.limit));
5054
+ }
5055
+ if (options?.startAfter) {
5056
+ constraints.push(startAfter(options.startAfter));
5057
+ }
5058
+ // Execute query
5059
+ if (constraints.length > 0) {
5060
+ const q = query(colRef, ...constraints);
5020
5061
  return getDocs(q);
5021
5062
  }
5063
+ else {
5064
+ // No constraints, return all documents
5065
+ return getDocs(colRef);
5066
+ }
5022
5067
  }
5023
5068
  /**
5024
5069
  * Internal: Get collection reference
@@ -5047,7 +5092,8 @@ class FirestoreHelper {
5047
5092
  query: firestore.query,
5048
5093
  where: firestore.where,
5049
5094
  orderBy: firestore.orderBy,
5050
- limit: firestore.limit
5095
+ limit: firestore.limit,
5096
+ startAfter: firestore.startAfter
5051
5097
  };
5052
5098
  }
5053
5099
  }