firewalk
Version:
A collection traversal library for Firestore
121 lines • 6.14 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _AbstractTraverser_instances, _a, _AbstractTraverser_configRules, _AbstractTraverser_validateConfig;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractTraverser = void 0;
const errors_1 = require("../../../errors");
const utils_1 = require("../../utils");
class AbstractTraverser {
constructor(traversalConfig, exitEarlyPredicates) {
_AbstractTraverser_instances.add(this);
this.traversalConfig = traversalConfig;
this.exitEarlyPredicates = exitEarlyPredicates;
__classPrivateFieldGet(this, _AbstractTraverser_instances, "m", _AbstractTraverser_validateConfig).call(this);
}
traverseEach(callback_1) {
return __awaiter(this, arguments, void 0, function* (callback, config = {}) {
const { sleepTimeBetweenDocs } = Object.assign(Object.assign({}, _a.baseTraverseEachConfig), config);
const { batchCount, docCount } = yield this.traverse((batchDocs, batchIndex) => __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i < batchDocs.length; i++) {
yield callback(batchDocs[i], i, batchIndex);
if (sleepTimeBetweenDocs > 0) {
yield (0, utils_1.sleep)(sleepTimeBetweenDocs);
}
}
}));
return { batchCount, docCount };
});
}
runTraversal(processBatch) {
return __awaiter(this, void 0, void 0, function* () {
const { batchSize, sleepTimeBetweenBatches, maxDocCount } = this.traversalConfig;
let curBatchIndex = 0;
let docCount = 0;
let query = this.traversable.limit(Math.min(batchSize, maxDocCount));
while (true) {
const { docs: batchDocs } = yield query.get();
const batchDocCount = batchDocs.length;
if (batchDocCount === 0) {
break;
}
const lastDocInBatch = batchDocs[batchDocCount - 1];
docCount += batchDocCount;
const onAfterBatchProcess = yield processBatch(batchDocs, curBatchIndex);
if (this.shouldExitEarly(batchDocs, curBatchIndex) || docCount === maxDocCount) {
break;
}
yield (onAfterBatchProcess === null || onAfterBatchProcess === void 0 ? void 0 : onAfterBatchProcess());
if (sleepTimeBetweenBatches > 0) {
yield (0, utils_1.sleep)(sleepTimeBetweenBatches);
}
query = query.startAfter(lastDocInBatch).limit(Math.min(batchSize, maxDocCount - docCount));
curBatchIndex++;
}
return { batchCount: curBatchIndex, docCount };
});
}
shouldExitEarly(batchDocs, batchIndex) {
return this.exitEarlyPredicates.some((predicate) => predicate(batchDocs, batchIndex));
}
}
exports.AbstractTraverser = AbstractTraverser;
_a = AbstractTraverser, _AbstractTraverser_instances = new WeakSet(), _AbstractTraverser_validateConfig = function _AbstractTraverser_validateConfig() {
(0, utils_1.extractKeys)(__classPrivateFieldGet(_a, _a, "f", _AbstractTraverser_configRules)).forEach((key) => {
const val = this.traversalConfig[key];
const { isValid, valDescription } = __classPrivateFieldGet(_a, _a, "f", _AbstractTraverser_configRules)[key];
if (!isValid(val)) {
throw new errors_1.InvalidConfigError(`The '${key}' field in traversal config must be ${valDescription}.`);
}
});
};
AbstractTraverser.baseConfig = {
batchSize: 250,
sleepTimeBetweenBatches: 0,
maxDocCount: Infinity,
maxConcurrentBatchCount: 1,
maxBatchRetryCount: 0,
sleepTimeBetweenTrials: 1000,
};
_AbstractTraverser_configRules = { value: {
batchSize: {
isValid: utils_1.isPositiveInteger,
valDescription: 'a positive integer',
},
sleepTimeBetweenBatches: {
isValid: utils_1.isNonNegativeInteger,
valDescription: 'a non-negative integer',
},
maxDocCount: {
isValid: utils_1.isUnboundedPositiveInteger,
valDescription: 'a positive integer or infinity',
},
maxConcurrentBatchCount: {
isValid: utils_1.isPositiveInteger,
valDescription: 'a positive integer',
},
maxBatchRetryCount: {
isValid: utils_1.isNonNegativeInteger,
valDescription: 'a non-negative integer',
},
sleepTimeBetweenTrials: {
isValid: (val) => typeof val === 'function' || (0, utils_1.isNonNegativeInteger)(val),
valDescription: 'a non-negative integer or a function that returns a non-negative integer',
},
} };
AbstractTraverser.baseTraverseEachConfig = {
sleepTimeBetweenDocs: 0,
};
//# sourceMappingURL=AbstractTraverser.js.map