text: import { __assign } from "tslib";
  import { wrap } from 'optimism';
  import { invariant, InvariantError } from 'ts-invariant';
  import { isField, resultKeyNameFromField, isReference, makeReference, createFragmentMap, shouldInclude, addTypenameToDocument, getDefaultValues, getFragmentDefinitions, getMainDefinition, getQueryDefinition, maybeDeepFreeze, mergeDeepArray, getFragmentFromSelection, } from "../../utilities/index.js";
  import { supportsResultCaching } from "./entityStore.js";
  import { getTypenameFromStoreObject } from "./helpers.js";
  import { MissingFieldError } from "../core/types/common.js";
  ;
  function missingFromInvariant(err, context) {
      return new MissingFieldError(err.message, context.path.slice(), context.query, context.clientOnly, context.variables);
  }
  var StoreReader = (function () {
      function StoreReader(config) {
          var _this = this;
          this.config = config;
          this.executeSelectionSet = wrap(function (options) { return _this.execSelectionSetImpl(options); }, {
              keyArgs: function (options) {
                  return [
                      options.selectionSet,
                      options.objectOrReference,
                      options.context,
                  ];
              },
              makeCacheKey: function (selectionSet, parent, context) {
                  if (supportsResultCaching(context.store)) {
                      return context.store.makeCacheKey(selectionSet, isReference(parent) ? parent.__ref : parent, context.varString);
                  }
              }
          });
          this.knownResults = new WeakMap();
          this.executeSubSelectedArray = wrap(function (options) {
              return _this.execSubSelectedArrayImpl(options);
          }, {
              makeCacheKey: function (_a) {
                  var field = _a.field, array = _a.array, context = _a.context;
                  if (supportsResultCaching(context.store)) {
                      return context.store.makeCacheKey(field, array, context.varString);
                  }
              }
          });
          this.config = __assign({ addTypename: true }, config);
      }
      StoreReader.prototype.diffQueryAgainstStore = function (_a) {
          var store = _a.store, query = _a.query, _b = _a.rootId, rootId = _b === void 0 ? 'ROOT_QUERY' : _b, variables = _a.variables, _c = _a.returnPartialData, returnPartialData = _c === void 0 ? true : _c;
          var policies = this.config.cache.policies;
          variables = __assign(__assign({}, getDefaultValues(getQueryDefinition(query))), variables);
          var execResult = this.executeSelectionSet({
              selectionSet: getMainDefinition(query).selectionSet,
              objectOrReference: makeReference(rootId),
              context: {
                  store: store,
                  query: query,
                  policies: policies,
                  variables: variables,
                  varString: JSON.stringify(variables),
                  fragmentMap: createFragmentMap(getFragmentDefinitions(query)),
                  path: [],
                  clientOnly: false,
              },
          });
          var hasMissingFields = execResult.missing && execResult.missing.length > 0;
          if (hasMissingFields && !returnPartialData) {
              throw execResult.missing[0];
          }
          return {
              result: execResult.result,
              missing: execResult.missing,
              complete: !hasMissingFields,
          };
      };
      StoreReader.prototype.isFresh = function (result, parent, selectionSet, context) {
          if (supportsResultCaching(context.store) &&
              this.knownResults.get(result) === selectionSet) {
              var latest = this.executeSelectionSet.peek(selectionSet, parent, context);
              if (latest && result === latest.result) {
                  return true;
              }
          }
          return false;
      };
      StoreReader.prototype.execSelectionSetImpl = function (_a) {
          var _this = this;
          var selectionSet = _a.selectionSet, objectOrReference = _a.objectOrReference, context = _a.context;
          if (isReference(objectOrReference) &&
              !context.policies.rootTypenamesById[objectOrReference.__ref] &&
              !context.store.has(objectOrReference.__ref)) {
              return {
                  result: {},
                  missing: [missingFromInvariant(process.env.NODE_ENV === "production" ? new InvariantError(4) : new InvariantError("Dangling reference to missing " + objectOrReference.__ref + " object"), context)],
              };
          }
          var variables = context.variables, policies = context.policies, store = context.store;
          var objectsToMerge = [];
          var finalResult = { result: null };
          var typename = store.getFieldValue(objectOrReference, "__typename");
          if (this.config.addTypename &&
              typeof typename === "string" &&
              !policies.rootIdsByTypename[typename]) {
              objectsToMerge.push({ __typename: typename });
          }
          function getMissing() {
              return finalResult.missing || (finalResult.missing = []);
          }
          function handleMissing(result) {
              var _a;
              if (result.missing)
                  (_a = getMissing()).push.apply(_a, result.missing);
              return result.result;
          }
          var workSet = new Set(selectionSet.selections);
          workSet.forEach(function (selection) {
              var _a;
              if (!shouldInclude(selection, variables))
                  return;
              if (isField(selection)) {
                  var fieldValue = policies.readField({
                      fieldName: selection.name.value,
                      field: selection,
                      variables: context.variables,
                      from: objectOrReference,
                  }, context);
                  var resultName = resultKeyNameFromField(selection);
                  context.path.push(resultName);
                  var wasClientOnly = context.clientOnly;
                  context.clientOnly = wasClientOnly || !!(selection.directives &&
                      selection.directives.some(function (d) { return d.name.value === "client"; }));
                  if (fieldValue === void 0) {
                      if (!addTypenameToDocument.added(selection)) {
                          getMissing().push(missingFromInvariant(process.env.NODE_ENV === "production" ? new InvariantError(5) : new InvariantError("Can't find field '" + selection.name.value + "' on " + (isReference(objectOrReference)
                              ? objectOrReference.__ref + " object"
                              : "object " + JSON.stringify(objectOrReference, null, 2))), context));
                      }
                  }
                  else if (Array.isArray(fieldValue)) {
                      fieldValue = handleMissing(_this.executeSubSelectedArray({
                          field: selection,
                          array: fieldValue,
                          context: context,
                      }));
                  }
                  else if (!selection.selectionSet) {
                      if (process.env.NODE_ENV !== 'production') {
                          assertSelectionSetForIdValue(context.store, selection, fieldValue);
                          maybeDeepFreeze(fieldValue);
                      }
                  }
                  else if (fieldValue != null) {
                      fieldValue = handleMissing(_this.executeSelectionSet({
                          selectionSet: selection.selectionSet,
                          objectOrReference: fieldValue,
                          context: context,
                      }));
                  }
                  if (fieldValue !== void 0) {
                      objectsToMerge.push((_a = {}, _a[resultName] = fieldValue, _a));
                  }
                  context.clientOnly = wasClientOnly;
                  invariant(context.path.pop() === resultName);
              }
              else {
                  var fragment = getFragmentFromSelection(selection, context.fragmentMap);
                  if (fragment && policies.fragmentMatches(fragment, typename)) {
                      fragment.selectionSet.selections.forEach(workSet.add, workSet);
                  }
              }
          });
          finalResult.result = mergeDeepArray(objectsToMerge);
          if (process.env.NODE_ENV !== 'production') {
              Object.freeze(finalResult.result);
          }
          this.knownResults.set(finalResult.result, selectionSet);
          return finalResult;
      };
      StoreReader.prototype.execSubSelectedArrayImpl = function (_a) {
          var _this = this;
          var field = _a.field, array = _a.array, context = _a.context;
          var missing;
          function handleMissing(childResult, i) {
              if (childResult.missing) {
                  missing = missing || [];
                  missing.push.apply(missing, childResult.missing);
              }
              invariant(context.path.pop() === i);
              return childResult.result;
          }
          if (field.selectionSet) {
              array = array.filter(context.store.canRead);
          }
          array = array.map(function (item, i) {
              if (item === null) {
                  return null;
              }
              context.path.push(i);
              if (Array.isArray(item)) {
                  return handleMissing(_this.executeSubSelectedArray({
                      field: field,
                      array: item,
                      context: context,
                  }), i);
              }
              if (field.selectionSet) {
                  return handleMissing(_this.executeSelectionSet({
                      selectionSet: field.selectionSet,
                      objectOrReference: item,
                      context: context,
                  }), i);
              }
              if (process.env.NODE_ENV !== 'production') {
                  assertSelectionSetForIdValue(context.store, field, item);
              }
              invariant(context.path.pop() === i);
              return item;
          });
          if (process.env.NODE_ENV !== 'production') {
              Object.freeze(array);
          }
          return { result: array, missing: missing };
      };
      return StoreReader;
  }());
  export { StoreReader };
  function assertSelectionSetForIdValue(store, field, fieldValue) {
      if (!field.selectionSet) {
          var workSet_1 = new Set([fieldValue]);
          workSet_1.forEach(function (value) {
              if (value && typeof value === "object") {
                  process.env.NODE_ENV === "production" ? invariant(!isReference(value), 6) : invariant(!isReference(value), "Missing selection set for object of type " + getTypenameFromStoreObject(store, value) + " returned for query field " + field.name.value);
                  Object.values(value).forEach(workSet_1.add, workSet_1);
              }
          });
      }
  }
  //# sourceMappingURL=readFromStore.js.map