UNPKG

@teachfloor/extension-kit

Version:
228 lines (219 loc) 7.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCollection = void 0; var _index = require("./index"); var _keyEnvelope = require("./keyEnvelope"); /** * Collection Manager for handling collection data (user or app collections) * * Provides a fluent API for working with collections including: * - Adding items * - Updating items * - Removing items * - Listing with pagination * - Auto-pagination for getting all items * * @example * const messages = createCollection('chat-messages', { limit: 15 }) * await messages.add({ role: 'user', text: 'Hello' }) * const page = await messages.list() * await messages.update(page.items[0].id, { role: 'user', text: 'Updated' }) * await messages.remove(page.items[0].id) * const all = await messages.getAll() */ class CollectionManager { /** * @param {string} baseKey - The base key for this collection * @param {Object} options - Configuration options * @param {number} options.limit - Default page size (default: 15) * @param {string} options.source - Collection source: 'usercollection' or 'appcollection' (default: 'usercollection') */ constructor(baseKey) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.baseKey = baseKey; this.defaultLimit = options.limit || 15; this.source = options.source || 'usercollection'; } /** * Add an item to the collection * * Creates a new record in the collection. Returns the stored value. * * @param {*} value - The value to store (object, array, string, number, etc.) * @returns {Promise<*>} The stored value * * @example * await collection.add({ role: 'user', text: 'Hello' }) */ async add(value) { const packedKey = (0, _keyEnvelope.packKey)(this.baseKey, {}); return (0, _index.store)(packedKey, value, this.source); } /** * List items from the collection with pagination * * Returns a page of items with metadata for pagination. * * @param {Object} options - List options * @param {number} options.limit - Number of items to retrieve * @param {string} options.cursor - Cursor for pagination (from previous result) * @returns {Promise<{items: Array, hasMore: boolean, nextCursor: string|null}>} * * Each item in the array has the structure: * - id: Database record ID * - key: The collection key * - value: The stored data (your actual data) * - created_at: ISO timestamp * - updated_at: ISO timestamp * * @example * const page1 = await collection.list() * console.log(page1.items) // Array of collection records * console.log(page1.items[0].value) // Your actual data * * if (page1.hasMore) { * const page2 = await collection.list({ cursor: page1.nextCursor }) * } */ async list() { let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; const params = { limit: options.limit || this.defaultLimit }; if (options.cursor) { params.next = options.cursor; } const packedKey = (0, _keyEnvelope.packKey)(this.baseKey, params); const result = await (0, _index.retrieve)(packedKey, this.source); return { items: result.data || [], hasMore: !!result.pagination?.next, nextCursor: result.pagination?.next || null }; } /** * Update an existing collection item * * Updates the value of an existing record by its ID. * * @param {string|number} id - The item ID to update * @param {*} value - The new value to store * @returns {Promise<*>} The updated value * * @example * const page = await collection.list() * const itemId = page.items[0].id * await collection.update(itemId, { role: 'user', text: 'Updated message' }) */ async update(id, value) { const packedKey = (0, _keyEnvelope.packKey)(this.baseKey, { id, action: 'update' }); return (0, _index.store)(packedKey, value, this.source); } /** * Remove a collection item * * Deletes a record from the collection by its ID. * * @param {string|number} id - The item ID to remove * @returns {Promise<null>} * * @example * const page = await collection.list() * const itemId = page.items[0].id * await collection.remove(itemId) */ async remove(id) { const packedKey = (0, _keyEnvelope.packKey)(this.baseKey, { id, action: 'delete' }); return (0, _index.store)(packedKey, null, this.source); } /** * Get all items from the collection (auto-pagination) * * WARNING: This will fetch all pages. Use with caution on large collections. * * @param {Object} options - Options * @param {number} options.limit - Page size for each request * @returns {Promise<Array>} All items in the collection * * @example * const allMessages = await collection.getAll() * allMessages.forEach(item => { * console.log(item.value) // Your actual data * console.log(item.id) // Database ID * console.log(item.created_at) // Timestamp * }) */ async getAll() { let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; const allItems = []; let cursor = null; do { const page = await this.list({ limit: options.limit || this.defaultLimit, cursor }); allItems.push(...page.items); cursor = page.hasMore ? page.nextCursor : null; } while (cursor); return allItems; } /** * Get the base key for this collection * * @returns {string} The base key */ getKey() { return this.baseKey; } /** * Get the source type for this collection * * @returns {string} The source ('usercollection' or 'appcollection') */ getSource() { return this.source; } } /** * Create a new collection manager instance * * @param {string} key - The base key for the collection * @param {Object} options - Configuration options * @param {number} options.limit - Default page size (default: 15) * @param {string} options.source - Collection source: 'usercollection' or 'appcollection' (default: 'usercollection') * @returns {CollectionManager} A collection manager instance * * @example * import { createCollection } from '@teachfloor/extension-kit' * * // User collection (default) * const messages = createCollection('chat-messages') * * // Add item * await messages.add({ role: 'user', text: 'Hello' }) * * // List items * const page = await messages.list() * * // Update item * await messages.update(page.items[0].id, { role: 'user', text: 'Updated' }) * * // Remove item * await messages.remove(page.items[0].id) * * // App collection (future - when supported by backend) * const globalData = createCollection('global-stats', { source: 'appcollection' }) */ const createCollection = function (key) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return new CollectionManager(key, options); }; exports.createCollection = createCollection;