{"version":3,"file":"index.mjs","sources":["../src/-private/utils.ts","../src/-private/deep-tracked.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n  createStorage,\n  getValue,\n  setValue,\n} from \"ember-tracked-storage-polyfill\";\n\nimport type { TrackedStorage } from \"ember-tracked-storage-polyfill\";\n\nconst COLLECTION = Symbol(\"__ COLLECTION __\");\n\ntype Key = number | string | symbol;\n\nconst STORAGES_CACHE = new WeakMap<\n  object | Array<unknown>,\n  // The tracked storage for an object or array.\n  // ie: TrackedArray, TrackedObject, but all in one\n  Map<Key, TrackedStorage<unknown>>\n>();\n\nfunction ensureStorages(context: any) {\n  let existing = STORAGES_CACHE.get(context);\n\n  if (!existing) {\n    existing = new Map();\n    STORAGES_CACHE.set(context, existing);\n  }\n\n  return existing;\n}\n\nfunction storageFor(context: any, key: Key) {\n  let storages = ensureStorages(context);\n\n  return storages.get(key);\n}\n\nexport function initStorage(context: any, key: Key, initialValue: any = null) {\n  let storages = ensureStorages(context);\n\n  let initialStorage = createStorage(initialValue, () => false);\n\n  storages.set(key, initialStorage);\n\n  return getValue(initialStorage);\n}\n\nexport function hasStorage(context: any, key: Key) {\n  return Boolean(storageFor(context, key));\n}\n\nexport function readStorage(context: any, key: Key) {\n  let storage = storageFor(context, key);\n\n  if (storage === undefined) {\n    return initStorage(context, key, null);\n  }\n\n  return getValue(storage);\n}\n\nexport function updateStorage(context: any, key: Key, value: any = null) {\n  let storage = storageFor(context, key);\n\n  if (!storage) {\n    initStorage(context, key, value);\n\n    return;\n  }\n\n  setValue(storage, value);\n}\n\nexport function readCollection(context: any) {\n  if (!hasStorage(context, COLLECTION)) {\n    initStorage(context, COLLECTION, context);\n  }\n\n  return readStorage(context, COLLECTION);\n}\n\nexport function dirtyCollection(context: any) {\n  if (!hasStorage(context, COLLECTION)) {\n    initStorage(context, COLLECTION, context);\n  }\n\n  return updateStorage(context, COLLECTION, context);\n}\n\nconst BOUND_FUNS = new WeakMap<object, Map<Key, unknown>>();\n\nexport function fnCacheFor<T extends object = object>(context: T) {\n  let fnCache = BOUND_FUNS.get(context);\n\n  if (!fnCache) {\n    fnCache = new Map();\n    BOUND_FUNS.set(context, fnCache);\n  }\n\n  return fnCache; // as Map<keyof T, T[keyof T]>;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * TODO: decorators and TS are... fun\n *       this file needs a lot of work\n *\n */\nimport {\n  dirtyCollection,\n  fnCacheFor,\n  hasStorage,\n  initStorage,\n  readCollection,\n  readStorage,\n  updateStorage,\n} from \"./utils\";\n\ntype DeepTrackedArgs<T> =\n  | [T[]]\n  | [Record<string, unknown>]\n  | [object, string | symbol, PropertyDescriptor];\n\ntype PropertyList = Array<string | number | symbol>;\ntype TrackedProxy<T> = T;\n\n/**\n * Deeply track an Array, and all nested objects/arrays within.\n *\n * If an element / value is ever a non-object or non-array, deep-tracking will exit\n *\n */\nexport function tracked<T>(arr: T[]): TrackedProxy<T[]>;\n/**\n * Deeply track an Object, and all nested objects/arrays within.\n *\n * If an element / value is ever a non-object or non-array, deep-tracking will exit\n *\n */\nexport function tracked<T extends Record<string, unknown>>(\n  obj: T,\n): TrackedProxy<T>;\n/**\n * Deeply track an Object or Array, and all nested objects/arrays within.\n *\n * If an element / value is ever a non-object or non-array, deep-tracking will exit\n *\n */\nexport function tracked(...args: any): any;\n\nexport function tracked<T>(...[obj, key, desc]: DeepTrackedArgs<T>): unknown {\n  if (key !== undefined && desc !== undefined) {\n    return deepTrackedForDescriptor(obj, key, desc);\n  }\n\n  return deepTracked(obj);\n}\n\nfunction deepTrackedForDescriptor(\n  _obj: object,\n  key: string | symbol,\n  desc: any,\n): any {\n  let initializer = desc.initializer;\n\n  delete desc.initializer;\n  delete desc.value;\n  delete desc.writable;\n  delete desc.configurable;\n\n  desc.get = function get() {\n    if (hasStorage(this, key)) {\n      return readStorage(this, key);\n    }\n\n    return initStorage(this, key, deepTracked(initializer?.call(this)));\n  };\n\n  desc.set = function set(v: any) {\n    updateStorage(this, key, deepTracked(v));\n  };\n}\n\nconst TARGET = Symbol(\"TARGET\");\nconst IS_PROXIED = Symbol(\"IS_PROXIED\");\n\nconst SECRET_PROPERTIES: PropertyList = [TARGET, IS_PROXIED];\n\nconst ARRAY_COLLECTION_PROPERTIES = [\"length\"];\nconst ARRAY_CONSUME_METHODS = [\n  Symbol.iterator,\n  \"at\",\n  \"concat\",\n  \"entries\",\n  \"every\",\n  \"filter\",\n  \"find\",\n  \"findIndex\",\n  \"findLast\",\n  \"findLastIndex\",\n  \"flat\",\n  \"flatMap\",\n  \"forEach\",\n  \"group\",\n  \"groupToMap\",\n  \"includes\",\n  \"indexOf\",\n  \"join\",\n  \"keys\",\n  \"lastIndexOf\",\n  \"map\",\n  \"reduce\",\n  \"reduceRight\",\n  \"slice\",\n  \"some\",\n  \"toString\",\n  \"values\",\n  \"length\",\n];\n\nconst ARRAY_DIRTY_METHODS = [\n  \"sort\",\n  \"fill\",\n  \"pop\",\n  \"push\",\n  \"shift\",\n  \"splice\",\n  \"unshift\",\n  \"reverse\",\n];\n\nconst ARRAY_QUERY_METHODS: PropertyList = [\n  \"indexOf\",\n  \"contains\",\n  \"lastIndexOf\",\n  \"includes\",\n];\n\nfunction deepTracked<T extends object>(\n  obj?: T | undefined,\n): T | undefined | null {\n  if (obj === null || obj === undefined) {\n    return obj;\n  }\n\n  if (obj[IS_PROXIED as keyof T]) {\n    return obj;\n  }\n\n  if (Array.isArray(obj)) {\n    return deepProxy(obj, arrayProxyHandler) as unknown as T;\n  }\n\n  if (typeof obj === \"object\") {\n    return deepProxy(obj, objProxyHandler) as unknown as T;\n  }\n\n  return obj;\n}\n\nconst arrayProxyHandler: ProxyHandler<Array<unknown>> = {\n  get<T extends unknown[]>(target: T, property: keyof T, receiver: T) {\n    let value = Reflect.get(target, property, receiver);\n\n    if (property === TARGET) {\n      return value;\n    }\n\n    if (property === IS_PROXIED) {\n      return true;\n    }\n\n    if (typeof property === \"string\") {\n      let parsed = parseInt(property, 10);\n\n      if (!isNaN(parsed)) {\n        // Why consume the collection?\n        // because indices can change if the collection changes\n        readCollection(target);\n        readStorage(target, parsed);\n\n        // SAFETY: when a non-deep-trackable is passed to deepTracked, it no-ops\n        //         and immediately returns\n        return deepTracked(value as object);\n      }\n\n      if (ARRAY_COLLECTION_PROPERTIES.includes(property)) {\n        readCollection(target);\n\n        return value;\n      }\n    }\n\n    if (typeof value === \"function\") {\n      let fnCache = fnCacheFor(target);\n      let existing = fnCache.get(property);\n\n      if (!existing) {\n        let fn = (...args: unknown[]) => {\n          if (typeof property === \"string\") {\n            if (ARRAY_QUERY_METHODS.includes(property)) {\n              readCollection(target);\n\n              let fn = target[property];\n\n              if (typeof fn === \"function\") {\n                return fn.call(target, ...args.map(unwrap));\n              }\n            } else if (ARRAY_CONSUME_METHODS.includes(property)) {\n              readCollection(target);\n            } else if (ARRAY_DIRTY_METHODS.includes(property)) {\n              dirtyCollection(target);\n            }\n          }\n\n          return Reflect.apply(value, receiver, args);\n        };\n\n        fnCache.set(property, fn);\n\n        return fn;\n      }\n\n      return existing;\n    }\n\n    return value;\n  },\n  set(target, property, value, receiver) {\n    if (typeof property === \"string\") {\n      let parsed = parseInt(property, 10);\n\n      if (!isNaN(parsed)) {\n        updateStorage(target, property, value);\n        // when setting, the collection must be dirtied.. :(\n        // this is to support updating {{#each}},\n        // which uses object identity by default\n        dirtyCollection(target);\n\n        return Reflect.set(target, property, value, receiver);\n      } else if (property === \"length\") {\n        dirtyCollection(target);\n\n        return Reflect.set(target, property, value, receiver);\n      }\n    }\n\n    dirtyCollection(target);\n\n    return Reflect.set(target, property, value, receiver);\n  },\n  has(target, property) {\n    if (SECRET_PROPERTIES.includes(property)) {\n      return true;\n    }\n\n    readStorage(target, property);\n\n    return property in target;\n  },\n  getPrototypeOf() {\n    return Array.prototype;\n  },\n};\n\nconst objProxyHandler = {\n  get<T extends object>(target: T, prop: keyof T, receiver: T) {\n    if (prop === TARGET) {\n      return target;\n    }\n\n    if (prop === IS_PROXIED) {\n      return true;\n    }\n\n    readStorage(target, prop);\n\n    // SAFETY: when a non-deep-trackable is passed to deepTracked, it no-ops\n    //         and immediately returns\n    return deepTracked(Reflect.get(target, prop, receiver) as object);\n  },\n  has<T extends object>(target: T, prop: keyof T) {\n    if (SECRET_PROPERTIES.includes(prop)) {\n      return true;\n    }\n\n    readStorage(target, prop);\n\n    return prop in target;\n  },\n\n  ownKeys<T extends object>(target: T) {\n    readCollection(target);\n\n    return Reflect.ownKeys(target);\n  },\n\n  set<T extends object>(\n    target: T,\n    prop: keyof T,\n    value: T[keyof T],\n    receiver: T,\n  ) {\n    updateStorage(target, prop);\n    dirtyCollection(target);\n\n    return Reflect.set(target, prop, value, receiver);\n  },\n\n  getPrototypeOf() {\n    return Object.prototype;\n  },\n};\n\nconst PROXY_CACHE = new WeakMap<any, object>();\n\nfunction unwrap<T>(obj: T) {\n  if (typeof obj !== \"object\") {\n    return obj;\n  }\n\n  if (obj === null) {\n    return obj;\n  }\n\n  if (TARGET in obj) {\n    return obj[TARGET as keyof T];\n  }\n\n  return obj;\n}\n\nfunction deepProxy<T extends object>(\n  obj: T,\n  handler: ProxyHandler<T>,\n): TrackedProxy<T> {\n  let existing = PROXY_CACHE.get(obj);\n\n  if (existing) {\n    return existing as T;\n  }\n\n  let proxied = new Proxy(obj, handler);\n\n  PROXY_CACHE.set(obj, proxied);\n\n  return proxied as T;\n}\n"],"names":["fn"],"mappings":"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"}