{
  "version": 3,
  "sources": ["../../src/editorbar/engine/OnPageEngineSignals.ts"],
  "sourcesContent": ["import { assert } from \"@framerjs/shared\"\nimport {\n\tcomputed as createComputed,\n\teffect as createEffect,\n\tsignal as createSignal,\n\tendBatch,\n\tstartBatch,\n} from \"alien-signals\"\nimport type { BaseEngineScheduler } from \"document/base-engine/BaseEngine.ts\"\nimport { type DependencyList, useMemo, useSyncExternalStore } from \"react\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\n\ntype Equals<Value> = (a: Value, b: Value) => boolean\n\ninterface EngineClass {\n\tscheduler: Pick<BaseEngineScheduler, \"signalChanges\">\n}\n\ntype State<Value> = ReturnType<typeof createSignal<Value>>\n\n/**\n * A decorator to create a state signal. Optionally accepts a custom equality function to avoid\n * unnecessary updates.\n */\nexport function state<This extends EngineClass, Value>(equals: Equals<Value> = Object.is) {\n\treturn (\n\t\t_target: ClassAccessorDecoratorTarget<This, Value>,\n\t\t_context: ClassAccessorDecoratorContext<This, Value>,\n\t): ClassAccessorDecoratorResult<This, Value> => {\n\t\tconst signals = new WeakMap<This, State<Value>>()\n\n\t\treturn {\n\t\t\tget(): Value {\n\t\t\t\tconst signal = signals.get(this)\n\t\t\t\tassert(signal, \"Signal must exist\")\n\t\t\t\treturn signal()\n\t\t\t},\n\n\t\t\tset(value: Value) {\n\t\t\t\tconst signal = signals.get(this)\n\t\t\t\tassert(signal, \"Signal must exist\")\n\n\t\t\t\tconst current = signal()\n\t\t\t\tif (equals(current, value)) return\n\n\t\t\t\tthis.scheduler.signalChanges(this)\n\n\t\t\t\treturn signal(value)\n\t\t\t},\n\n\t\t\tinit(value) {\n\t\t\t\tconst signal = createSignal(value)\n\t\t\t\tsignals.set(this, signal)\n\t\t\t\treturn undefined as Value\n\t\t\t},\n\t\t}\n\t}\n}\n\ntype Computed<Value> = ReturnType<typeof createComputed<Value>>\n\ntype ClassGetterDecoratorTarget<This, Value> = (this: This) => Value\ntype ClassGetterDecoratorResult<This, Value> = (this: This) => Value\n\n/**\n * A decorator to create a computed signal. Can be used to create derived state based on other\n * signals. Optionally accepts a custom equality function to avoid unnecessary updates.\n */\nexport function computed<This extends EngineClass, Value>(equals: Equals<Value> = Object.is) {\n\treturn (\n\t\ttarget: ClassGetterDecoratorTarget<This, Value>,\n\t\t_context: ClassGetterDecoratorContext<This, Value>,\n\t): ClassGetterDecoratorResult<This, Value> => {\n\t\tconst signals = new WeakMap<This, Computed<Value>>()\n\n\t\treturn function (this: This): Value {\n\t\t\tconst existing = signals.get(this)\n\t\t\tif (existing) return existing()\n\n\t\t\tconst signal = createComputed<Value>(previous => {\n\t\t\t\tconst value = target.call(this)\n\n\t\t\t\tif (isUndefined(previous)) return value\n\t\t\t\tif (equals(previous, value)) return previous\n\n\t\t\t\treturn value\n\t\t\t})\n\n\t\t\tsignals.set(this, signal)\n\t\t\treturn signal()\n\t\t}\n\t}\n}\n\n/**\n * A hook to listen to store state created with the `@state` and `@computed` decorators. Optionally\n * accepts a custom equality function to avoid unnecessary re-renders.\n *\n * @example\n * const value = useSignalState(() => engine.stores.store.value, [])\n *\n * @example\n * const value = useSignalState(() => engine.stores.store.value, [], isShallowEqual)\n *\n * @example\n * const value = useSignalState(() => engine.stores.store.value + value, [value])\n */\nexport function useSignalState<Value>(\n\tcompute: () => Value,\n\tdependencies: DependencyList,\n\tequals: Equals<NoInfer<Value>> = Object.is,\n): Value {\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: Covered by dependencies.\n\tconst store = useMemo(() => {\n\t\tconst signal = createComputed<Value>(previous => {\n\t\t\tconst value = compute()\n\n\t\t\tif (isUndefined(previous)) return value\n\t\t\tif (equals(previous, value)) return previous\n\n\t\t\treturn value\n\t\t})\n\n\t\treturn {\n\t\t\tsubscribe(callback: () => void) {\n\t\t\t\treturn createEffect(() => {\n\t\t\t\t\tsignal()\n\t\t\t\t\tcallback()\n\t\t\t\t})\n\t\t\t},\n\n\t\t\tgetSnapshot() {\n\t\t\t\treturn signal()\n\t\t\t},\n\t\t}\n\t}, [...dependencies, equals])\n\n\treturn useSyncExternalStore(store.subscribe, store.getSnapshot)\n}\n\n/**\n * Starts a batch of signal changes. Should be called once per engine frame inside `signalChanges`.\n * Without this all signals will notify their subscribers immediately causing `useSignalState` to\n * render outside of the engine frame.\n */\nexport function startSignalBatch() {\n\tstartBatch()\n}\n\n/**\n * Ends a batch of signal changes. Should be called once at the end of the engine frame to render\n * all pending `useSignalState` hooks.\n */\nexport function endSignalBatch() {\n\tendBatch()\n}\n"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;;AASA,mBAAmE;AAe5D,SAAS,MAAuC,SAAwB,OAAO,IAAI;AACzF,SAAO,CACN,SACA,aAC+C;AAC/C,UAAM,UAAU,oBAAI,QAA4B;AAEhD,WAAO;AAAA,MACN,MAAa;AACZ,cAAMA,UAAS,QAAQ,IAAI,IAAI;AAC/B,eAAOA,SAAQ,mBAAmB;AAClC,eAAOA,QAAO;AAAA,MACf;AAAA,MAEA,IAAI,OAAc;AACjB,cAAMA,UAAS,QAAQ,IAAI,IAAI;AAC/B,eAAOA,SAAQ,mBAAmB;AAElC,cAAM,UAAUA,QAAO;AACvB,YAAI,OAAO,SAAS,KAAK,EAAG;AAE5B,aAAK,UAAU,cAAc,IAAI;AAEjC,eAAOA,QAAO,KAAK;AAAA,MACpB;AAAA,MAEA,KAAK,OAAO;AACX,cAAMA,UAAS,OAAa,KAAK;AACjC,gBAAQ,IAAI,MAAMA,OAAM;AACxB,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AACD;AAWO,SAASC,UAA0C,SAAwB,OAAO,IAAI;AAC5F,SAAO,CACN,QACA,aAC6C;AAC7C,UAAM,UAAU,oBAAI,QAA+B;AAEnD,WAAO,WAA6B;AACnC,YAAM,WAAW,QAAQ,IAAI,IAAI;AACjC,UAAI,SAAU,QAAO,SAAS;AAE9B,YAAMD,UAAS,SAAsB,cAAY;AAChD,cAAM,QAAQ,OAAO,KAAK,IAAI;AAE9B,YAAI,YAAY,QAAQ,EAAG,QAAO;AAClC,YAAI,OAAO,UAAU,KAAK,EAAG,QAAO;AAEpC,eAAO;AAAA,MACR,CAAC;AAED,cAAQ,IAAI,MAAMA,OAAM;AACxB,aAAOA,QAAO;AAAA,IACf;AAAA,EACD;AACD;AAeO,SAAS,eACf,SACA,cACA,SAAiC,OAAO,IAChC;AAER,QAAM,YAAQ,sBAAQ,MAAM;AAC3B,UAAMA,UAAS,SAAsB,cAAY;AAChD,YAAM,QAAQ,QAAQ;AAEtB,UAAI,YAAY,QAAQ,EAAG,QAAO;AAClC,UAAI,OAAO,UAAU,KAAK,EAAG,QAAO;AAEpC,aAAO;AAAA,IACR,CAAC;AAED,WAAO;AAAA,MACN,UAAU,UAAsB;AAC/B,eAAO,OAAa,MAAM;AACzB,UAAAA,QAAO;AACP,mBAAS;AAAA,QACV,CAAC;AAAA,MACF;AAAA,MAEA,cAAc;AACb,eAAOA,QAAO;AAAA,MACf;AAAA,IACD;AAAA,EACD,GAAG,CAAC,GAAG,cAAc,MAAM,CAAC;AAE5B,aAAO,mCAAqB,MAAM,WAAW,MAAM,WAAW;AAC/D;AAOO,SAAS,mBAAmB;AAClC,aAAW;AACZ;AAMO,SAAS,iBAAiB;AAChC,WAAS;AACV;",
  "names": ["signal", "computed"]
}
