@sterblue/sterblue-sdk
Version:
Sterblue Graph SDK for graphile.sterblue.com
136 lines (110 loc) • 5.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.streamQueryNoCount = void 0;
var _fp = require("lodash/fp");
var _getPaginationPath = require("./get-pagination-path");
var _util = require("util");
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function* generateBatchVariables({
first,
offset = 0,
batchSize = 20
} = {
offset: 0,
batchSize: 20
}) {
if ((0, _fp.isNumber)(first)) {
const end = offset + first;
for (let batchOffset = offset; batchOffset < end; batchOffset = batchOffset + batchSize) {
const batchFirst = Math.min(batchSize, end - batchOffset);
if (batchOffset + batchSize >= end) {
yield {
first: batchFirst,
offset: batchOffset
};
} else {
yield {
first: batchFirst,
offset: batchOffset
};
}
}
return;
} else {
for (let batchOffset = offset; true; batchOffset = batchOffset + batchSize) {
const batchFirst = batchSize;
yield {
first: batchFirst,
offset: batchOffset
};
}
}
}
/**
* Stream a list query as an async iterable using batches.
* Allow to perform huge queries, replace queryHugeData
*/
const streamQueryNoCount = (queryFunction, dataPath = []) => {
return async function (_ref) {
let {
query,
variables: {
first,
offset = 0,
batchSize = 20
} = {
offset: 0,
batchSize: 20
}
} = _ref,
variables = _objectWithoutProperties(_ref.variables, ["first", "offset", "batchSize"]),
options = _objectWithoutProperties(_ref, ["query", "variables"]);
const paginationPath = (0, _getPaginationPath.getPaginationPath)(query);
if (!(0, _util.isArray)(paginationPath)) {
throw new Error("Error: The query must contain an element with the exact arguments (first: $first offset: $offset ...others)");
}
const extractArray = (0, _fp.get)([...dataPath, ...paginationPath]);
const iteratee = async batchVariables => {
const queryResult = await queryFunction(_objectSpread(_objectSpread({}, options), {}, {
query,
variables: _objectSpread(_objectSpread({}, variables), batchVariables)
}));
const extractedArray = extractArray(queryResult);
if ((0, _fp.isNil)(extractedArray)) {
throw new Error(`Could not find data as expected in query result at path ${[...dataPath, ...paginationPath]}`);
} else {
return extractArray(queryResult);
}
};
const batchVariablesIterator = generateBatchVariables({
first,
offset,
batchSize
});
async function* _result() {
for (const batchVariables of batchVariablesIterator) {
const lastBatch = await iteratee(batchVariables);
if ((0, _fp.isNil)(lastBatch) || (0, _fp.isEmpty)(lastBatch)) {
return;
} else {
for (const result of lastBatch) {
yield result;
}
}
}
return;
}
return _result(); // // This would be cool, but has no way to stop when the query returns an empty result
// return flatMap(
// iteratee,
// generateBatchVariables({ first, offset, batchSize })
// );
};
};
exports.streamQueryNoCount = streamQueryNoCount;