UNPKG

@azure/cosmos

Version:
155 lines (154 loc) 5.54 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var RidSkipCountFilter_exports = {}; __export(RidSkipCountFilter_exports, { RidSkipCountFilter: () => RidSkipCountFilter }); module.exports = __toCommonJS(RidSkipCountFilter_exports); var import_orderByComparator = require("../orderByComparator.js"); class RidSkipCountFilter { /** * @param filterContext - The context containing values from the continuation token. */ constructor(filterContext) { this.filterContext = filterContext; this.remainingSkipCount = this.filterContext.skipCount; } remainingSkipCount; /** * Applies the comprehensive OrderBy + RID + SkipCount filtering logic. * @param documents - The documents fetched from the target partition. * @returns A new array containing only the documents that should be processed. */ applyFilter(documents) { const filteredDocs = []; let skippedCount = 0; for (const doc of documents) { if (!this.shouldIncludeDocument(doc)) { skippedCount++; continue; } filteredDocs.push(doc); } return filteredDocs; } /** * Determines if a document should be included based on OrderBy values, RID, and skip count. * Implements the .NET SDK's FilterNextAsync logic with robust OrderBy comparison. */ shouldIncludeDocument(doc) { const sortOrderCompare = this.compareOrderByItems(doc); if (sortOrderCompare < 0) { return true; } if (sortOrderCompare > 0) { return false; } const docRid = doc._rid; let ridOrderCompare; if (this.filterContext.rid === docRid) { ridOrderCompare = 0; } else { const continuationBigInt = this.ridToBigInt(this.filterContext.rid); const docBigInt = this.ridToBigInt(docRid); if (continuationBigInt < docBigInt) { ridOrderCompare = -1; } else if (continuationBigInt > docBigInt) { ridOrderCompare = 1; } else { ridOrderCompare = 0; } } const sortOrders = this.filterContext.sortOrders || []; const queryExecutionInfo = this.filterContext.queryExecutionInfo; const hasDescendingSort = sortOrders.some((order) => order === "Descending"); if (!queryExecutionInfo || queryExecutionInfo.reverseRidEnabled) { if (hasDescendingSort) { ridOrderCompare = -ridOrderCompare; } } else { if (queryExecutionInfo.reverseIndexScan) { ridOrderCompare = -ridOrderCompare; } } if (ridOrderCompare > 0) { return false; } if (ridOrderCompare < 0) { return true; } if (this.remainingSkipCount > 0) { this.remainingSkipCount--; return false; } return true; } /** * Convert RID to BigInt for accurate comparison. * Decodes base64 RID and extracts the Document ID portion (8 bytes at offset 8) as BigInt. * * RID Structure (from Java SDK ResourceId.java): * - Bytes 0-3: Database ID (4 bytes) * - Bytes 4-7: Collection ID (4 bytes) * - Bytes 8-15: Document ID (8 bytes, stored in Big Endian but compared in Little Endian) * - Bytes 16-19: Attachment ID (4 bytes, optional) */ ridToBigInt(rid) { if (rid === null || rid === void 0) { throw new Error(`RID is null or undefined`); } if (typeof rid !== "string") { throw new Error(`RID must be a string, got ${typeof rid}`); } if (rid.trim().length === 0) { throw new Error(`RID is empty string`); } try { const normalizedRid = rid.replace(/-/g, "/"); const bytes = Buffer.from(normalizedRid, "base64"); if (bytes.length < 16) { throw new Error(`RID too short: expected at least 16 bytes, got ${bytes.length}`); } let result = 0n; for (let i = 15; i >= 8; i--) { result = result << 8n | BigInt(bytes[i] & 255); } return result; } catch (error) { throw new Error( `Failed to convert RID '${rid}' to BigInt: ${error instanceof Error ? error.message : String(error)}` ); } } /** * Compares the OrderBy items of a document with the continuation token's OrderBy items. * Uses the exported compareOrderByItems utility function from orderByItemComparator. * @param doc - The document to compare * @returns negative if doc comes before continuation, 0 if same, positive if doc comes after */ compareOrderByItems(doc) { const docOrderByItems = doc.orderByItems || []; const continuationOrderByItems = this.filterContext.orderByItems || []; const sortOrders = this.filterContext.sortOrders || []; return (0, import_orderByComparator.compareOrderByItems)(docOrderByItems, continuationOrderByItems, sortOrders); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RidSkipCountFilter });