UNPKG

grafast

Version:

Cutting edge GraphQL planning and execution engine

173 lines 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LoadManyStep = void 0; exports.loadManyCallback = loadManyCallback; exports.loadManyLoader = loadManyLoader; exports.loadMany = loadMany; const multistep_js_1 = require("../multistep.js"); const step_js_1 = require("../step.js"); const utils_js_1 = require("../utils.js"); const _loadCommon_js_1 = require("./_loadCommon.js"); const access_js_1 = require("./access.js"); const constant_js_1 = require("./constant.js"); const loadedRecord_js_1 = require("./loadedRecord.js"); /** * A TypeScript Identity Function to help you strongly type your * LoadManyCallback. */ function loadManyCallback(load) { return load; } /** * A TypeScript Identity Function to help you strongly type your * LoadManyLoader. */ function loadManyLoader(load) { return load; } const idByLoad = new WeakMap(); let loadCounter = 0; class LoadManyStep extends step_js_1.Step { static { this.$$export = { moduleName: "grafast", exportName: "LoadManyStep" }; } constructor(lookup, loader) { super(); this.isSyncAndSafe = false; this.loadInfo = null; this.loadInfoKey = ""; this.attributes = new Set(); this.paramDepIdByKey = Object.create(null); this.sharedDepId = null; this._accessMap = null; // TODO: prompt users to disable this if they don't need it. this.cloneStreams = true; const { load, shared, ioEquivalence, paginationSupport } = loader; this.name = loader.name || load.displayName || load.name; this.load = load; if (typeof this.load !== "function") { throw new Error(`Invalid options passed to LoadManyStep - there must be a 'load' function!`); } this.ioEquivalence = ioEquivalence ?? null; const $lookup = (0, multistep_js_1.multistep)(lookup, "load"); this.addDependency($lookup); if (shared != null) { const $shared = (0, multistep_js_1.multistep)(shared, "loadUnary"); this.sharedDepId = this.addUnaryDependency($shared); } if (!paginationSupport) { delete this.applyPagination; } else { this.paginationSupport = paginationSupport; } } toStringMeta() { return this.name ?? null; } getAccessMap() { return (this._accessMap ??= (0, _loadCommon_js_1.makeAccessMap)(this.getDep(0), this.ioEquivalence)); } listItem($item) { return new loadedRecord_js_1.LoadedRecordStep(this, $item, false, this.toStringMeta(), this.getAccessMap()); } setParam(paramKey, value) { this.paramDepIdByKey[paramKey] = this.addUnaryDependency(value instanceof step_js_1.Step ? value : (0, constant_js_1.constant)(value)); } addAttributes(attributes) { for (const attribute of attributes) { this.attributes.add(attribute); } } deduplicate(peers) { return peers.filter((p) => p.load === this.load && (0, _loadCommon_js_1.ioEquivalenceMatches)(p.ioEquivalence, this.ioEquivalence) && (0, utils_js_1.recordsMatch)(p.paramDepIdByKey, this.paramDepIdByKey)); } deduplicatedWith(replacement) { for (const attr of this.attributes) { replacement.attributes.add(attr); } } getParamSignature() { return (this._paramSig ??= (0, _loadCommon_js_1.paramSig)(this.paramDepIdByKey, (depId) => this.getDepOptions(depId).step.id)); } finalize() { // Find all steps of this type that use the same callback and have // equivalent params and then match their list of attributes together. const paramSig = this.getParamSignature(); const kin = this.operationPlan .getStepsByStepClass(LoadManyStep) .filter((step) => { if (step.id === this.id) return false; if (step.load !== this.load) return false; if (step.getParamSignature() !== paramSig) return false; return true; }); for (const otherStep of kin) { for (const attr of otherStep.attributes) { this.attributes.add(attr); } } // Build the loadOptions const attributes = [...this.attributes].sort(); this.loadInfo = { attributes }; // If the canonicalJSONStringify is the same, then we deem that the options are the same this.loadInfoKey = (0, utils_js_1.canonicalJSONStringify)(this.loadInfo); let loadId = idByLoad.get(this.load); if (!loadId) { loadId = String(++loadCounter); idByLoad.set(this.load, loadId); } this.metaKey = `LoadManyStep|${loadId}|${this.loadInfoKey}`; super.finalize(); } execute(details) { return (0, _loadCommon_js_1.executeLoad)(details, this.sharedDepId, this.paramDepIdByKey, this.loadInfo, this.load); } applyPagination($params) { this.setParam("reverse", (0, access_js_1.access)($params, "reverse")); this.setParam("after", (0, access_js_1.access)($params, "after")); this.setParam("offset", (0, access_js_1.access)($params, "offset")); this.setParam("limit", (0, access_js_1.access)($params, "limit")); } connectionClone() { const lookup = this.getDep(0); const { load, ioEquivalence } = this; const shared = this.sharedDepId != null ? this.getDep(this.sharedDepId) : null; const $clone = new LoadManyStep(lookup, { load, shared, ioEquivalence, }); // Copy attributes? for (const attr of this.attributes) { $clone.attributes.add(attr); } // Clone over all params except for pagination params for (const [key, depId] of Object.entries(this.paramDepIdByKey)) { if (key === "reverse" || key === "after" || key === "offset" || key === "limit") { // Skip pagination param continue; } $clone.setParam(key, this.getDep(depId)); } return $clone; } } exports.LoadManyStep = LoadManyStep; function loadMany(lookup, loader) { if (arguments.length > 2) { throw new Error("The signature of loadMany has changed, additional arguments should now be passed via a 'loader' object: `loadMany(lookup, loader)` where `loader` is either a `load` function or object containing it `{ load, shared?, ioEquivalence?, paginationSupport? }`"); } return new LoadManyStep(lookup, typeof loader === "function" ? { load: loader } : loader); } //# sourceMappingURL=loadMany.js.map