UNPKG

grafast

Version:

Cutting edge GraphQL planning and execution engine

150 lines 5.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LoadOneStep = void 0; exports.loadOneCallback = loadOneCallback; exports.loadOneLoader = loadOneLoader; exports.loadOne = loadOne; 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"); /** * A TypeScript Identity Function to help you strongly type your * LoadOneCallback. */ function loadOneCallback(load) { return load; } /** * A TypeScript Identity Function to help you strongly type your * LoadOneLoader. */ function loadOneLoader(load) { return load; } const idByLoad = new WeakMap(); let loadCounter = 0; class LoadOneStep extends step_js_1.Step { static { this.$$export = { moduleName: "grafast", exportName: "LoadOneStep" }; } 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; const { load, shared, ioEquivalence } = loader; this.name = loader.name || load.displayName || load.name; this.load = load; if (typeof this.load !== "function") { throw new Error(`Invalid options passed to LoadOneStep - there must be a 'load' function!`); } this.ioEquivalence = ioEquivalence ?? null; const $spec = (0, multistep_js_1.multistep)(lookup, "load"); this.addDependency($spec); if (shared != null) { const $shared = (0, multistep_js_1.multistep)(shared, "loadUnary"); this.sharedDepId = this.addUnaryDependency($shared); } } toStringMeta() { return this.name ?? null; } getAccessMap() { return (this._accessMap ??= (0, _loadCommon_js_1.makeAccessMap)(this.getDep(0), this.ioEquivalence)); } 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(LoadOneStep) .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 loadInfo 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 = `LoadOneStep|${loadId}|${this.loadInfoKey}`; super.finalize(); } execute(details) { return (0, _loadCommon_js_1.executeLoad)(details, this.sharedDepId, this.paramDepIdByKey, this.loadInfo, this.load); } // Things that were originally in LoadedRecordStep get(attr) { return this.cacheStep("get", attr, () => this._getInner(attr)); } _getInner(attr) { if (this.operationPlan.phase === "plan") { // Allow auto-collapsing of the waterfall by knowing keys are equivalent const accessMap = this.getAccessMap(); const $step = accessMap[attr]; if ($step) { return $step; } } this.attributes.add(attr); return (0, access_js_1.access)(this, attr); } } exports.LoadOneStep = LoadOneStep; /** * Loads an individual record identified by the `lookup` using the `loader`. * * @param lookup - A step/multistep representing the value to look up - could be an * identifier or combination of identifiers. * @param loader - The function to load this, or a LoadManyLoader object containing such a function */ function loadOne(lookup, loader) { if (arguments.length > 2) { throw new Error("The signature of loadOne has changed, additional arguments should now be passed via a 'loader' object: `loadOne(lookup, loader)` where `loader` is either a `load` function or object containing it `{ load, shared?, ioEquivalence?, paginationSupport? }`"); } return new LoadOneStep(lookup, typeof loader === "function" ? { load: loader } : loader); } //# sourceMappingURL=loadOne.js.map