{"version":3,"file":"optimisticProxy.mjs","names":["startNode: StoreLayer | null","currentStoreLayer: StoreLayer | null","node: NetworkResponseStoreLayer","node: StartUpdateStoreLayer","node: OptimisticNetworkResponseStoreLayer","networkResponseStoreLayer: NetworkResponseStoreLayer","encounteredIds: EncounteredIds"],"sources":["../../src/core/optimisticProxy.ts"],"sourcesContent":["import { insertEmptySetIfMissing, type EncounteredIds } from './cache';\nimport { callSubscriptions } from './subscribe';\nimport type {\n  BaseStoreLayerData,\n  IsographEnvironment,\n  StoreLayerData,\n  StoreLink,\n  StoreRecord,\n} from './IsographEnvironment';\n\nexport function getOrInsertRecord(\n  dataLayer: StoreLayerData,\n  link: StoreLink,\n): StoreRecord {\n  const recordsById = (dataLayer[link.__typename] ??= {});\n  return (recordsById[link.__link] ??= {});\n}\n\n/**\n * Given the child-most store layer (i.e. environment.store) and a link (identifying a\n * store record), create a proxy object that attempts to read through each successive\n * store layer until a value (i.e. field name) is found. If found, return that value.\n */\nexport function getStoreRecordProxy(\n  storeLayer: StoreLayer,\n  link: StoreLink,\n): Readonly<StoreRecord> | null | undefined {\n  let startNode: StoreLayer | null = storeLayer;\n  while (startNode != null) {\n    const storeRecord = startNode.data[link.__typename]?.[link.__link];\n    if (storeRecord === undefined) {\n      startNode = startNode.parentStoreLayer;\n      continue;\n    }\n\n    if (storeRecord == null) {\n      return null;\n    }\n\n    return getMutableStoreRecordProxy(startNode, link);\n  }\n\n  return undefined;\n}\n\nexport function getMutableStoreRecordProxy(\n  childMostStoreLayer: StoreLayer,\n  link: StoreLink,\n): StoreRecord {\n  return new Proxy<StoreRecord>(\n    {},\n    {\n      get(_, propertyName) {\n        let currentStoreLayer: StoreLayer | null = childMostStoreLayer;\n        while (currentStoreLayer != null) {\n          const storeRecord =\n            currentStoreLayer.data[link.__typename]?.[link.__link];\n          if (storeRecord !== undefined) {\n            if (storeRecord == null) {\n              return undefined;\n            }\n            const value = Reflect.get(storeRecord, propertyName);\n            if (value !== undefined) {\n              return value;\n            }\n          }\n          currentStoreLayer = currentStoreLayer.parentStoreLayer;\n        }\n      },\n      has(_, propertyName) {\n        let currentStoreLayer: StoreLayer | null = childMostStoreLayer;\n        while (currentStoreLayer != null) {\n          const storeRecord =\n            currentStoreLayer.data[link.__typename]?.[link.__link];\n          if (storeRecord !== undefined) {\n            if (storeRecord == null) {\n              return false;\n            }\n\n            const value = Reflect.has(storeRecord, propertyName);\n            if (value) {\n              return true;\n            }\n          }\n          currentStoreLayer = currentStoreLayer.parentStoreLayer;\n        }\n        return false;\n      },\n      set(_, p, newValue) {\n        return Reflect.set(\n          getOrInsertRecord(childMostStoreLayer.data, link),\n          p,\n          newValue,\n        );\n      },\n    },\n  );\n}\n\nexport type BaseStoreLayer = {\n  readonly kind: 'BaseStoreLayer';\n  childStoreLayer: OptimisticStoreLayer | null;\n  readonly parentStoreLayer: null;\n  readonly data: BaseStoreLayerData;\n};\n\nexport type NetworkResponseStoreLayer = {\n  readonly kind: 'NetworkResponseStoreLayer';\n  childStoreLayer: OptimisticStoreLayer | StartUpdateStoreLayer | null;\n  parentStoreLayer: OptimisticStoreLayer | StartUpdateStoreLayer;\n  readonly data: StoreLayerData;\n};\n\nexport type DataUpdate<TStoreLayer extends StoreLayer> = (\n  storeLayer: TStoreLayer,\n) => void;\n\nexport type StartUpdateStoreLayer = {\n  readonly kind: 'StartUpdateStoreLayer';\n  childStoreLayer: OptimisticStoreLayer | NetworkResponseStoreLayer | null;\n  parentStoreLayer: OptimisticStoreLayer | NetworkResponseStoreLayer;\n  data: StoreLayerData;\n  startUpdate: DataUpdate<StartUpdateStoreLayer | BaseStoreLayer>;\n};\n\nexport type OptimisticStoreLayer =\n  | OptimisticUpdaterStoreLayer\n  | OptimisticNetworkResponseStoreLayer;\n\nexport type OptimisticUpdaterStoreLayer = {\n  readonly kind: 'OptimisticUpdaterStoreLayer';\n  childStoreLayer:\n    | OptimisticStoreLayer\n    | StartUpdateStoreLayer\n    | NetworkResponseStoreLayer\n    | null;\n  parentStoreLayer:\n    | OptimisticStoreLayer\n    | StartUpdateStoreLayer\n    | NetworkResponseStoreLayer\n    | BaseStoreLayer;\n  data: StoreLayerData;\n  readonly startUpdate: DataUpdate<OptimisticUpdaterStoreLayer>;\n};\n\nexport type OptimisticNetworkResponseStoreLayer = {\n  readonly kind: 'OptimisticNetworkResponseStoreLayer';\n  childStoreLayer:\n    | OptimisticStoreLayer\n    | StartUpdateStoreLayer\n    | NetworkResponseStoreLayer\n    | null;\n  parentStoreLayer:\n    | OptimisticStoreLayer\n    | StartUpdateStoreLayer\n    | NetworkResponseStoreLayer\n    | BaseStoreLayer;\n  data: StoreLayerData;\n};\n\nexport function addNetworkResponseStoreLayer(\n  parent: StoreLayer,\n): StoreLayerWithData {\n  switch (parent.kind) {\n    case 'NetworkResponseStoreLayer':\n    case 'BaseStoreLayer': {\n      return parent;\n    }\n    case 'StartUpdateStoreLayer':\n    case 'OptimisticNetworkResponseStoreLayer':\n    case 'OptimisticUpdaterStoreLayer': {\n      const node: NetworkResponseStoreLayer = {\n        kind: 'NetworkResponseStoreLayer',\n        parentStoreLayer: parent,\n        childStoreLayer: null,\n        data: {},\n      };\n      parent.childStoreLayer = node;\n\n      return node;\n    }\n  }\n}\n\nfunction mergeDataLayer(target: StoreLayerData, source: StoreLayerData): void {\n  for (const [typeName, sourceById] of Object.entries(source)) {\n    if (sourceById == null) {\n      target[typeName] = sourceById;\n      continue;\n    }\n    const targetRecordById = (target[typeName] ??= {});\n    for (const [id, sourceRecord] of Object.entries(sourceById)) {\n      if (sourceRecord == null) {\n        targetRecordById[id] = null;\n        continue;\n      }\n      const targetRecord = (targetRecordById[id] ??= {});\n      Object.assign(targetRecord, sourceRecord);\n    }\n  }\n}\n\nexport function addStartUpdateStoreLayer(\n  parent: StoreLayer,\n  startUpdate: StartUpdateStoreLayer['startUpdate'],\n): StoreLayer {\n  switch (parent.kind) {\n    case 'BaseStoreLayer': {\n      startUpdate(parent);\n      return parent;\n    }\n    case 'StartUpdateStoreLayer': {\n      const node = parent;\n\n      const prevStartUpdate = node.startUpdate;\n      node.startUpdate = () => {\n        prevStartUpdate(node);\n        startUpdate(node);\n      };\n\n      startUpdate(node);\n      return node;\n    }\n    case 'NetworkResponseStoreLayer':\n    case 'OptimisticNetworkResponseStoreLayer':\n    case 'OptimisticUpdaterStoreLayer': {\n      const node: StartUpdateStoreLayer = {\n        kind: 'StartUpdateStoreLayer',\n        parentStoreLayer: parent,\n        childStoreLayer: null,\n        data: {},\n        startUpdate: startUpdate,\n      };\n      parent.childStoreLayer = node;\n\n      startUpdate(node);\n      return node;\n    }\n  }\n}\n\nexport function addOptimisticUpdaterStoreLayer(\n  parent: StoreLayer,\n  startUpdate: OptimisticUpdaterStoreLayer['startUpdate'],\n): OptimisticUpdaterStoreLayer {\n  switch (parent.kind) {\n    case 'BaseStoreLayer':\n    case 'StartUpdateStoreLayer':\n    case 'NetworkResponseStoreLayer':\n    case 'OptimisticNetworkResponseStoreLayer':\n    case 'OptimisticUpdaterStoreLayer': {\n      const node: OptimisticUpdaterStoreLayer = {\n        kind: 'OptimisticUpdaterStoreLayer',\n        parentStoreLayer: parent,\n        childStoreLayer: null,\n        data: {},\n        startUpdate: startUpdate,\n      };\n\n      startUpdate(node);\n      parent.childStoreLayer = node;\n\n      return node;\n    }\n  }\n}\n\nexport function addOptimisticNetworkResponseStoreLayer(\n  parent: StoreLayer,\n): OptimisticNetworkResponseStoreLayer {\n  switch (parent.kind) {\n    case 'BaseStoreLayer':\n    case 'StartUpdateStoreLayer':\n    case 'NetworkResponseStoreLayer':\n    case 'OptimisticNetworkResponseStoreLayer':\n    case 'OptimisticUpdaterStoreLayer': {\n      const node: OptimisticNetworkResponseStoreLayer = {\n        kind: 'OptimisticNetworkResponseStoreLayer',\n        parentStoreLayer: parent,\n        childStoreLayer: null,\n        data: {},\n      };\n\n      parent.childStoreLayer = node;\n\n      return node;\n    }\n  }\n}\n\n/**\n * Merge storeLayerToMerge, and its children, into baseStoreLayer.\n * We can merge until we reach a revertible layer (i.e. an optimistic layer).\n * All other layers cannot be reverted, so for housekeeping + perf, we merge\n * them into a single layer.\n *\n * Note that BaseStoreLayer.childStoreLayer has type OptimisticStoreLayer | null.\n * So, the state of the stack is never e.g. base <- network response. Instead,\n * we have a base + a child that we would like to attach to the base. So, we merge\n * (flatten) until we reach an optimistic layer or null, at which point, we can\n * set baseStoreLayer.childStoreLayer = storeLayerToMerge (via setChildOfNode).\n */\nfunction mergeLayersWithDataIntoBaseLayer(\n  environment: IsographEnvironment,\n  storeLayerToMerge: StoreLayer | null,\n  baseStoreLayer: BaseStoreLayer,\n) {\n  while (\n    storeLayerToMerge != null &&\n    storeLayerToMerge.kind !== 'OptimisticUpdaterStoreLayer'\n  ) {\n    mergeDataLayer(baseStoreLayer.data, storeLayerToMerge.data);\n    storeLayerToMerge = storeLayerToMerge.childStoreLayer;\n  }\n  setChildOfNode(environment, baseStoreLayer, storeLayerToMerge);\n}\n\n/**\n * Now that we have replaced the optimistic layer with a network response layer, we need\n * to\n * - re-execute startUpdate and optimistic nodes, in light of the replaced data, and\n * - create two objects containing the old merged data (from the optimistic update layer\n *   onward) and the new merged data (from the network response layer onward).\n * - we will compare the new and old merged data in order to determine the changed records\n *   and trigger subscriptions.\n *\n * Here, \"merged data\" means all of the records + fields that were modified, starting at\n * storeLayer, e.g. in BaseLayer <- OptimisticLayer <- StartUpdateLayer, if we\n * are replacing Optimistic, then oldData will contain the records + fields modified by\n * OptimisticLayer + StartUpdateLayer.\n */\nfunction reexecuteUpdatesAndMergeData(\n  storeLayer:\n    | OptimisticStoreLayer\n    | NetworkResponseStoreLayer\n    | StartUpdateStoreLayer\n    | null,\n  // reflects the (now reverted) optimistic layer\n  oldMergedData: StoreLayerData,\n  // reflects whatever replaced the optimistic layer\n  newMergedData: StoreLayerData,\n): void {\n  while (storeLayer != null) {\n    mergeDataLayer(oldMergedData, storeLayer.data);\n    switch (storeLayer.kind) {\n      case 'OptimisticNetworkResponseStoreLayer':\n      case 'NetworkResponseStoreLayer':\n        break;\n      case 'StartUpdateStoreLayer': {\n        storeLayer.data = {};\n        storeLayer.startUpdate(storeLayer);\n        break;\n      }\n      case 'OptimisticUpdaterStoreLayer': {\n        storeLayer.data = {};\n        storeLayer.startUpdate(storeLayer);\n        break;\n      }\n    }\n    mergeDataLayer(newMergedData, storeLayer.data);\n\n    storeLayer = storeLayer.childStoreLayer;\n  }\n}\n\n/**\n * Set storeLayerToModify's child to a given layer. This may be null!\n * If it is null, set the environment.store to storeLayerToModify.\n * If it is not null, then the existing environment.store value remains\n * valid.\n */\nfunction setChildOfNode<TStoreLayer extends StoreLayer>(\n  environment: IsographEnvironment,\n  storeLayerToModify: TStoreLayer,\n  newChildStoreLayer: TStoreLayer['childStoreLayer'],\n) {\n  storeLayerToModify.childStoreLayer = newChildStoreLayer;\n  if (newChildStoreLayer != null) {\n    newChildStoreLayer.parentStoreLayer = storeLayerToModify;\n  } else {\n    environment.store = storeLayerToModify;\n  }\n}\n\n/**\n * Remove an optimistic store layer from the stack, potentially replacing it\n * with a network response.\n *\n * After we do this, we must re-execute all child startUpdate and optimistic\n * layers (since their data may have changed.) We also keep track of changed\n * records, in order to call affected subscriptions.\n */\nexport function revertOptimisticStoreLayerAndMaybeReplace(\n  environment: IsographEnvironment,\n  optimisticNode: OptimisticStoreLayer,\n  normalizeData: null | ((storeLayer: StoreLayerWithData) => void),\n): void {\n  // We cannot just replace the optimistic node with the network response node,\n  // because (e.g.) the types allow Base <- Opt, but not Base <- NetworkResponse.\n  // We also may be removing the optimistic layer without replacing it with\n  // anything, which would also be disallowed if the original stack was\n  // Base <- Opt <- NetworkResponse.\n  //\n  // Thus, instead, we will (1) replace the optimistic node's data with an empty object\n  // and attach the network response as a child.\n  const oldMergedData = optimisticNode.data;\n  optimisticNode.data = {};\n\n  let newMergedData = {};\n  let childNode = optimisticNode.childStoreLayer;\n  if (normalizeData != null) {\n    const networkResponseStoreLayer: NetworkResponseStoreLayer = {\n      kind: 'NetworkResponseStoreLayer',\n      data: {},\n      parentStoreLayer: optimisticNode,\n      childStoreLayer: null,\n    };\n    normalizeData(networkResponseStoreLayer);\n\n    if (childNode?.kind === 'NetworkResponseStoreLayer') {\n      // (2) if the optimistic layer's child was a network response, and we are\n      // replacing it with a network response, we must merge the replacement\n      // and the child.\n      mergeDataLayer(networkResponseStoreLayer.data, childNode.data);\n      mergeDataLayer(oldMergedData, childNode.data);\n      childNode = childNode.childStoreLayer;\n    }\n    newMergedData = structuredClone(networkResponseStoreLayer.data);\n    setChildOfNode(environment, networkResponseStoreLayer, childNode);\n    optimisticNode.childStoreLayer = networkResponseStoreLayer;\n  }\n\n  // (3) Re-execute all updates, accumulating all changed values into newMergedData.\n  // Since we have already written the network response into newMergedData, we\n  // can proceed from the child of the (potentially merged) network response layer.\n  //\n  // Note that it is important that reexecuteUpdatesAndMergeData is called here!\n  // That is because we created newMergedData from the network response layer's data,\n  // and later, we may merge that network response into the parent layer (if it is\n  // a base layer). That merged layer will contain many extraneous records (unless the\n  // base layer is empty).\n  //\n  // This would cause us to re-execute subscriptions unnecessarily, as these records\n  // do not represent changes between the optimistic and network response layers.\n  reexecuteUpdatesAndMergeData(childNode, oldMergedData, newMergedData);\n\n  // (4) Now, we can finally remove the optimistic layer, i.e. do\n  // optimistic.parent.child = optimistic.child.\n  // But the types don't line up, so we handle the cases differently, based on the\n  // parent layer type.\n  if (optimisticNode.parentStoreLayer.kind === 'BaseStoreLayer') {\n    // (4a) If the optimistic parent is the base layer, then we have a problem: base.child\n    // must be an optimistic layer or null. So, we merge the optimistic children into the\n    // base layer until we reach an optimistic layer.\n    mergeLayersWithDataIntoBaseLayer(\n      environment,\n      optimisticNode.childStoreLayer,\n      optimisticNode.parentStoreLayer,\n    );\n  } else if (\n    optimisticNode.parentStoreLayer.kind === 'NetworkResponseStoreLayer' &&\n    optimisticNode.childStoreLayer?.kind === 'NetworkResponseStoreLayer'\n  ) {\n    // (4b) if the parent is a network response layer, simply merge those. (We do not\n    // attempt to merge other layers, e.g. startUpdate layers, because there is some\n    // optimistic layer between this layer and the base, and the startUpdate will need\n    // to be recalculated if the optimistic layer is reverted.)\n    mergeDataLayer(\n      optimisticNode.parentStoreLayer.data,\n      optimisticNode.childStoreLayer.data,\n    );\n\n    setChildOfNode(\n      environment,\n      optimisticNode.parentStoreLayer,\n      optimisticNode.childStoreLayer.childStoreLayer,\n    );\n  } else {\n    // (4c) Otherwise, the parent is an optimistic or start update layer, and we can\n    // set optimistic.parent.child = optimistic.child.\n    setChildOfNode(\n      environment,\n      optimisticNode.parentStoreLayer,\n      optimisticNode.childStoreLayer,\n    );\n  }\n\n  // (5) finally, compare the oldMergedData and newMergedData objects, in order to extract\n  // the modified IDs, and re-execute subscriptions.\n  let encounteredIds: EncounteredIds = new Map();\n  compareData(oldMergedData, newMergedData, encounteredIds);\n  callSubscriptions(environment, encounteredIds);\n}\n\nexport type StoreLayer =\n  | OptimisticStoreLayer\n  | NetworkResponseStoreLayer\n  | StartUpdateStoreLayer\n  | BaseStoreLayer;\n\nexport type StoreLayerWithData =\n  | BaseStoreLayer\n  | NetworkResponseStoreLayer\n  | OptimisticNetworkResponseStoreLayer;\n\nfunction compareData(\n  oldData: StoreLayerData,\n  newData: StoreLayerData,\n  encounteredIds: EncounteredIds,\n): void {\n  const oldDataTypeNames = new Set(Object.keys(oldData));\n  const newDataTypeNames = new Set(Object.keys(newData));\n\n  for (const oldTypeName of oldDataTypeNames.difference(newDataTypeNames)) {\n    const set = insertEmptySetIfMissing(encounteredIds, oldTypeName);\n    for (const id in oldData[oldTypeName]) {\n      set.add(id);\n    }\n  }\n\n  for (const [typeName, newRecords] of Object.entries(newData)) {\n    if (newRecords == null) {\n      continue;\n    }\n    const oldRecords = oldData[typeName];\n    outer: for (const [id, newRecord] of Object.entries(newRecords)) {\n      if (newRecord == null) {\n        continue;\n      }\n      const oldRecord = oldRecords?.[id];\n\n      for (const [recordKey, newRecordValue] of Object.entries(newRecord)) {\n        // TODO: compare links, compare arrays\n        if (newRecordValue !== oldRecord?.[recordKey]) {\n          const set = insertEmptySetIfMissing(encounteredIds, typeName);\n          set.add(id);\n          continue outer;\n        }\n      }\n\n      encounteredIds.get(typeName)?.delete(id);\n    }\n  }\n}\n"],"mappings":"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"}