{
  "version": 3,
  "sources": ["../../../src/lib/core/Computed.ts"],
  "sourcesContent": ["/* eslint-disable prefer-rest-params */\nimport { ArraySet } from './ArraySet'\nimport { HistoryBuffer } from './HistoryBuffer'\nimport { maybeCaptureParent, startCapturingParents, stopCapturingParents } from './capture'\nimport { GLOBAL_START_EPOCH } from './constants'\nimport { EMPTY_ARRAY, equals, haveParentsChanged, singleton } from './helpers'\nimport { getGlobalEpoch } from './transactions'\nimport { Child, ComputeDiff, RESET_VALUE, Signal } from './types'\nimport { logComputedGetterWarning } from './warnings'\n\n/**\n * @public\n */\nexport const UNINITIALIZED = Symbol.for('com.tldraw.state/UNINITIALIZED')\n/**\n * The type of the first value passed to a computed signal function as the 'prevValue' parameter.\n *\n * @see [[isUninitialized]].\n * @public\n */\nexport type UNINITIALIZED = typeof UNINITIALIZED\n\n/**\n * Call this inside a computed signal function to determine whether it is the first time the function is being called.\n *\n * Mainly useful for incremental signal computation.\n *\n * @example\n * ```ts\n * const count = atom('count', 0)\n * const double = computed('double', (prevValue) => {\n *   if (isUninitialized(prevValue)) {\n *     print('First time!')\n *   }\n *   return count.get() * 2\n * })\n * ```\n *\n * @param value - The value to check.\n * @public\n */\nexport const isUninitialized = (value: any): value is UNINITIALIZED => {\n\treturn value === UNINITIALIZED\n}\n\nexport const WithDiff = singleton(\n\t'WithDiff',\n\t() =>\n\t\tclass WithDiff<Value, Diff> {\n\t\t\tconstructor(public value: Value, public diff: Diff) {}\n\t\t}\n)\nexport type WithDiff<Value, Diff> = { value: Value; diff: Diff }\n\n/**\n * When writing incrementally-computed signals it is convenient (and usually more performant) to incrementally compute the diff too.\n *\n * You can use this function to wrap the return value of a computed signal function to indicate that the diff should be used instead of calculating a new one with [[AtomOptions.computeDiff]].\n *\n * @example\n * ```ts\n * const count = atom('count', 0)\n * const double = computed('double', (prevValue) => {\n *   const nextValue = count.get() * 2\n *   if (isUninitialized(prevValue)) {\n *     return nextValue\n *   }\n *   return withDiff(nextValue, nextValue - prevValue)\n * }, { historyLength: 10 })\n * ```\n *\n *\n * @param value - The value.\n * @param diff - The diff.\n * @public\n */\nexport function withDiff<Value, Diff>(value: Value, diff: Diff): WithDiff<Value, Diff> {\n\treturn new WithDiff(value, diff)\n}\n\n/**\n * Options for creating computed signals. Used when calling [[computed]].\n * @public\n */\nexport interface ComputedOptions<Value, Diff> {\n\t/**\n\t * The maximum number of diffs to keep in the history buffer.\n\t *\n\t * If you don't need to compute diffs, or if you will supply diffs manually via [[Atom.set]], you can leave this as `undefined` and no history buffer will be created.\n\t *\n\t * If you expect the value to be part of an active effect subscription all the time, and to not change multiple times inside of a single transaction, you can set this to a relatively low number (e.g. 10).\n\t *\n\t * Otherwise, set this to a higher number based on your usage pattern and memory constraints.\n\t *\n\t */\n\thistoryLength?: number\n\t/**\n\t * A method used to compute a diff between the atom's old and new values. If provided, it will not be used unless you also specify [[AtomOptions.historyLength]].\n\t */\n\tcomputeDiff?: ComputeDiff<Value, Diff>\n\t/**\n\t * If provided, this will be used to compare the old and new values of the atom to determine if the value has changed.\n\t * By default, values are compared using first using strict equality (`===`), then `Object.is`, and finally any `.equals` method present in the object's prototype chain.\n\t * @param a - The old value\n\t * @param b - The new value\n\t * @returns\n\t */\n\tisEqual?: (a: any, b: any) => boolean\n}\n\n/**\n * A computed signal created via [[computed]].\n *\n * @public\n */\nexport interface Computed<Value, Diff = unknown> extends Signal<Value, Diff> {\n\t/**\n\t * Whether this computed child is involved in an actively-running effect graph.\n\t * @public\n\t */\n\treadonly isActivelyListening: boolean\n\n\t/** @internal */\n\treadonly parents: Signal<any, any>[]\n\t/** @internal */\n\treadonly parentEpochs: number[]\n}\n\n/**\n * @internal\n */\nclass __UNSAFE__Computed<Value, Diff = unknown> implements Computed<Value, Diff> {\n\tlastChangedEpoch = GLOBAL_START_EPOCH\n\tlastTraversedEpoch = GLOBAL_START_EPOCH\n\n\t/**\n\t * The epoch when the reactor was last checked.\n\t */\n\tprivate lastCheckedEpoch = GLOBAL_START_EPOCH\n\n\tparents: Signal<any, any>[] = []\n\tparentEpochs: number[] = []\n\n\tchildren = new ArraySet<Child>()\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget isActivelyListening(): boolean {\n\t\treturn !this.children.isEmpty\n\t}\n\n\thistoryBuffer?: HistoryBuffer<Diff>\n\n\t// The last-computed value of this signal.\n\tprivate state: Value = UNINITIALIZED as unknown as Value\n\n\tprivate computeDiff?: ComputeDiff<Value, Diff>\n\n\tprivate readonly isEqual: (a: any, b: any) => boolean\n\n\tconstructor(\n\t\t/**\n\t\t * The name of the signal. This is used for debugging and performance profiling purposes. It does not need to be globally unique.\n\t\t */\n\t\tpublic readonly name: string,\n\t\t/**\n\t\t * The function that computes the value of the signal.\n\t\t */\n\t\tprivate readonly derive: (\n\t\t\tpreviousValue: Value | UNINITIALIZED,\n\t\t\tlastComputedEpoch: number\n\t\t) => Value | WithDiff<Value, Diff>,\n\t\toptions?: ComputedOptions<Value, Diff>\n\t) {\n\t\tif (options?.historyLength) {\n\t\t\tthis.historyBuffer = new HistoryBuffer(options.historyLength)\n\t\t}\n\t\tthis.computeDiff = options?.computeDiff\n\t\tthis.isEqual = options?.isEqual ?? equals\n\t}\n\n\t__unsafe__getWithoutCapture(): Value {\n\t\tconst isNew = this.lastChangedEpoch === GLOBAL_START_EPOCH\n\n\t\tif (!isNew && (this.lastCheckedEpoch === getGlobalEpoch() || !haveParentsChanged(this))) {\n\t\t\tthis.lastCheckedEpoch = getGlobalEpoch()\n\t\t\treturn this.state\n\t\t}\n\n\t\ttry {\n\t\t\tstartCapturingParents(this)\n\t\t\tconst result = this.derive(this.state, this.lastCheckedEpoch)\n\t\t\tconst newState = result instanceof WithDiff ? result.value : result\n\t\t\tif (this.state === UNINITIALIZED || !this.isEqual(newState, this.state)) {\n\t\t\t\tif (this.historyBuffer && !isNew) {\n\t\t\t\t\tconst diff = result instanceof WithDiff ? result.diff : undefined\n\t\t\t\t\tthis.historyBuffer.pushEntry(\n\t\t\t\t\t\tthis.lastChangedEpoch,\n\t\t\t\t\t\tgetGlobalEpoch(),\n\t\t\t\t\t\tdiff ??\n\t\t\t\t\t\t\tthis.computeDiff?.(this.state, newState, this.lastCheckedEpoch, getGlobalEpoch()) ??\n\t\t\t\t\t\t\tRESET_VALUE\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tthis.lastChangedEpoch = getGlobalEpoch()\n\t\t\t\tthis.state = newState\n\t\t\t}\n\t\t\tthis.lastCheckedEpoch = getGlobalEpoch()\n\n\t\t\treturn this.state\n\t\t} finally {\n\t\t\tstopCapturingParents()\n\t\t}\n\t}\n\n\tget(): Value {\n\t\tconst value = this.__unsafe__getWithoutCapture()\n\t\tmaybeCaptureParent(this)\n\t\treturn value\n\t}\n\n\tgetDiffSince(epoch: number): RESET_VALUE | Diff[] {\n\t\t// need to call .get() to ensure both that this derivation is up to date\n\t\t// and that tracking happens correctly\n\t\tthis.get()\n\n\t\tif (epoch >= this.lastChangedEpoch) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\n\t\treturn this.historyBuffer?.getChangesSince(epoch) ?? RESET_VALUE\n\t}\n}\n\nexport const _Computed = singleton('Computed', () => __UNSAFE__Computed)\nexport type _Computed = InstanceType<typeof __UNSAFE__Computed>\n\nfunction computedMethodAnnotation(\n\toptions: ComputedOptions<any, any> = {},\n\t_target: any,\n\tkey: string,\n\tdescriptor: PropertyDescriptor\n) {\n\tconst originalMethod = descriptor.value\n\tconst derivationKey = Symbol.for('__@bigbluebutton/state__computed__' + key)\n\n\tdescriptor.value = function (this: any) {\n\t\tlet d = this[derivationKey] as Computed<any> | undefined\n\n\t\tif (!d) {\n\t\t\td = new _Computed(key, originalMethod!.bind(this) as any, options)\n\t\t\tObject.defineProperty(this, derivationKey, {\n\t\t\t\tenumerable: false,\n\t\t\t\tconfigurable: false,\n\t\t\t\twritable: false,\n\t\t\t\tvalue: d,\n\t\t\t})\n\t\t}\n\t\treturn d.get()\n\t}\n\tdescriptor.value[isComputedMethodKey] = true\n\n\treturn descriptor\n}\n\nfunction computedAnnotation(\n\toptions: ComputedOptions<any, any> = {},\n\t_target: any,\n\tkey: string,\n\tdescriptor: PropertyDescriptor\n) {\n\tif (descriptor.get) {\n\t\tlogComputedGetterWarning()\n\t\treturn computedGetterAnnotation(options, _target, key, descriptor)\n\t} else {\n\t\treturn computedMethodAnnotation(options, _target, key, descriptor)\n\t}\n}\n\nfunction computedGetterAnnotation(\n\toptions: ComputedOptions<any, any> = {},\n\t_target: any,\n\tkey: string,\n\tdescriptor: PropertyDescriptor\n) {\n\tconst originalMethod = descriptor.get\n\tconst derivationKey = Symbol.for('__@bigbluebutton/state__computed__' + key)\n\n\tdescriptor.get = function (this: any) {\n\t\tlet d = this[derivationKey] as Computed<any> | undefined\n\n\t\tif (!d) {\n\t\t\td = new _Computed(key, originalMethod!.bind(this) as any, options)\n\t\t\tObject.defineProperty(this, derivationKey, {\n\t\t\t\tenumerable: false,\n\t\t\t\tconfigurable: false,\n\t\t\t\twritable: false,\n\t\t\t\tvalue: d,\n\t\t\t})\n\t\t}\n\t\treturn d.get()\n\t}\n\n\treturn descriptor\n}\n\nconst isComputedMethodKey = '@@__isComputedMethod__@@'\n\n/**\n * Retrieves the underlying computed instance for a given property created with the [[computed]]\n * decorator.\n *\n * @example\n * ```ts\n * class Counter {\n *   max = 100\n *   count = atom(0)\n *\n *   @computed getRemaining() {\n *     return this.max - this.count.get()\n *   }\n * }\n *\n * const c = new Counter()\n * const remaining = getComputedInstance(c, 'getRemaining')\n * remaining.get() === 100 // true\n * c.count.set(13)\n * remaining.get() === 87 // true\n * ```\n *\n * @param obj - The object\n * @param propertyName - The property name\n * @public\n */\nexport function getComputedInstance<Obj extends object, Prop extends keyof Obj>(\n\tobj: Obj,\n\tpropertyName: Prop\n): Computed<Obj[Prop]> {\n\tconst key = Symbol.for('__@bigbluebutton/state__computed__' + propertyName.toString())\n\tlet inst = obj[key as keyof typeof obj] as Computed<Obj[Prop]> | undefined\n\tif (!inst) {\n\t\t// deref to make sure it exists first\n\t\tconst val = obj[propertyName]\n\t\tif (typeof val === 'function' && (val as any)[isComputedMethodKey]) {\n\t\t\tval.call(obj)\n\t\t}\n\n\t\tinst = obj[key as keyof typeof obj] as Computed<Obj[Prop]> | undefined\n\t}\n\treturn inst as any\n}\n\n/**\n * Creates a computed signal.\n *\n * @example\n * ```ts\n * const name = atom('name', 'John')\n * const greeting = computed('greeting', () => `Hello ${name.get()}!`)\n * console.log(greeting.get()) // 'Hello John!'\n * ```\n *\n * `computed` may also be used as a decorator for creating computed getter methods.\n *\n * @example\n * ```ts\n * class Counter {\n *   max = 100\n *   count = atom<number>(0)\n *\n *   @computed getRemaining() {\n *     return this.max - this.count.get()\n *   }\n * }\n * ```\n *\n * You may optionally pass in a [[ComputedOptions]] when used as a decorator:\n *\n * @example\n * ```ts\n * class Counter {\n *   max = 100\n *   count = atom<number>(0)\n *\n *   @computed({isEqual: (a, b) => a === b})\n *   getRemaining() {\n *     return this.max - this.count.get()\n *   }\n * }\n * ```\n *\n * @param name - The name of the signal.\n * @param compute - The function that computes the value of the signal.\n * @param options - Options for the signal.\n *\n * @public\n */\nexport function computed<Value, Diff = unknown>(\n\tname: string,\n\tcompute: (\n\t\tpreviousValue: Value | typeof UNINITIALIZED,\n\t\tlastComputedEpoch: number\n\t) => Value | WithDiff<Value, Diff>,\n\toptions?: ComputedOptions<Value, Diff>\n): Computed<Value, Diff>\n\n/** @public */\nexport function computed(\n\ttarget: any,\n\tkey: string,\n\tdescriptor: PropertyDescriptor\n): PropertyDescriptor\n/** @public */\nexport function computed<Value, Diff = unknown>(\n\toptions?: ComputedOptions<Value, Diff>\n): (target: any, key: string, descriptor: PropertyDescriptor) => PropertyDescriptor\n/** @public */\nexport function computed() {\n\tif (arguments.length === 1) {\n\t\tconst options = arguments[0]\n\t\treturn (target: any, key: string, descriptor: PropertyDescriptor) =>\n\t\t\tcomputedAnnotation(options, target, key, descriptor)\n\t} else if (typeof arguments[0] === 'string') {\n\t\treturn new _Computed(arguments[0], arguments[1], arguments[2])\n\t} else {\n\t\treturn computedAnnotation(undefined, arguments[0], arguments[1], arguments[2])\n\t}\n}\n\n/**\n * Returns true if the given value is a computed signal.\n *\n * @param value\n * @returns {value is Computed<any>}\n * @public\n */\nexport function isComputed(value: any): value is Computed<any> {\n\treturn value && value instanceof _Computed\n}\n"],
  "mappings": "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",
  "names": []
}
