{"version":3,"file":"YogaManagerWorker-BAOqyqBg.cjs","names":[],"sources":["../src/types/NodeOperations.ts","../src/util/toSerializableValue.ts","../src/YogaManagerWorker.ts"],"sourcesContent":["export enum NodeOperations {\n  AddNode = 1,\n  RemoveNode = 2,\n  AddChildNode = 3,\n  AddChildNodeAtIndex = 4,\n  DetachChildNode = 5,\n  AddIndependentRoot = 6,\n  RemoveIndependentRoot = 7,\n}\n","function isPrimitiveValue(\n  valueType:\n    | 'string'\n    | 'number'\n    | 'bigint'\n    | 'boolean'\n    | 'symbol'\n    | 'undefined'\n    | 'object'\n    | 'function',\n): boolean {\n  return (\n    valueType === 'string' ||\n    valueType === 'number' ||\n    valueType === 'boolean' ||\n    valueType === 'bigint'\n  );\n}\n\n// oxlint-disable-next-line typescript/no-explicit-any -- Any value can be passed in\nexport function toSerializableValue<T>(key: string, value: any): T | null {\n  const valueType = typeof value;\n\n  if (isPrimitiveValue(valueType)) {\n    return value as T;\n  } else if (valueType === 'object') {\n    // Only transforms can be objects\n    if (key === 'transform') {\n      return value as T;\n    } else if (value != null && 'current' in value && isPrimitiveValue(typeof value.current)) {\n      // ...unless it's a reanimated animation. Unfortunately, there's no real\n      // good way to serialize animations. There's also no real good way to\n      // keep this logic in the reanimated plugin, so we'll just have to do it\n      // here.\n      return value.current as T;\n    }\n\n    return null;\n  }\n\n  return null;\n}\n","import { EventEmitter } from 'tseep';\n\nimport type { LightningElementStyle } from '@plextv/react-lightning';\n\nimport { NodeOperations } from './types/NodeOperations';\nimport { isFlexStyleProp } from './util/isFlexStyleProp';\nimport { SimpleDataView } from './util/SimpleDataView';\nimport { toSerializableValue } from './util/toSerializableValue';\nimport Worker from './worker?worker&inline';\nimport type { YogaManager, YogaManagerEvents } from './YogaManager';\n\n// oxlint-disable-next-line typescript/no-explicit-any -- Basic type for function signatures\ntype AnyFunc = (...args: any[]) => any;\n\nexport type Workerized<T> = {\n  [K in keyof T]: T[K] extends AnyFunc\n    ? ReturnType<T[K]> extends PromiseLike<unknown>\n      ? T[K]\n      : (...args: Parameters<T[K]>) => Promise<ReturnType<T[K]>>\n    : never;\n};\n\n/**\n * Coalesces calls within a sync task — runs `fn` once at the end of the\n * current sync code with the latest args. Uses a microtask, not setTimeout,\n * because the timer's 1ms+ minimum breaks coalescing during a React commit.\n */\nfunction debounceMicrotask<T extends (...args: unknown[]) => void | Promise<void>>(fn: T): T {\n  let scheduled = false;\n  let latestArgs: unknown[];\n\n  const debouncedFn = function (this: unknown, ...args: unknown[]) {\n    latestArgs = args;\n\n    if (scheduled) {\n      return;\n    }\n\n    scheduled = true;\n    queueMicrotask(() => {\n      scheduled = false;\n      fn.apply(this, latestArgs);\n    });\n  };\n\n  return debouncedFn as T;\n}\n\nfunction wrapWorker<T>(worker: Worker): Workerized<T> {\n  const _callees: Record<string, [AnyFunc, AnyFunc]> = {};\n  const _eventEmitter = new EventEmitter<YogaManagerEvents>();\n  let _stylesToSend: Record<number, Partial<LightningElementStyle>> = {};\n  let _numStylesToSend = 0;\n  let _needsRender = false;\n  const _childOperations = new SimpleDataView(undefined, undefined, _onChildOpsOverflow);\n\n  /**\n   * Overflow flush is nodeOps-only — combining pending styles with a\n   * partial nodeOps batch would land styles before the remaining nodeOps,\n   * targeting nodes that don't exist yet (\"node not found\" warnings).\n   */\n  function _onChildOpsOverflow(filledBuffer: ArrayBuffer) {\n    worker.postMessage(\n      {\n        method: 'nodeOperations',\n        args: [filledBuffer],\n      },\n      [filledBuffer],\n    );\n  }\n\n  function flushSendStyles() {\n    // Cheap counter check instead of `Object.keys(_stylesToSend).length` —\n    // the latter walks every key in the record on each call.\n    if (_numStylesToSend === 0) {\n      return;\n    }\n\n    // Combine with pending nodeOps — collapses two postMessages into one.\n    if (_childOperations.offset > 0) {\n      _flushBothInternal();\n\n      return;\n    }\n\n    worker.postMessage({\n      method: 'applyStyles',\n      args: [_stylesToSend, !_needsRender],\n    });\n\n    _needsRender = false;\n    _stylesToSend = {};\n    _numStylesToSend = 0;\n  }\n\n  const queueSendStyles = debounceMicrotask(flushSendStyles);\n\n  function applyStyle(\n    elementId: number,\n    style: Partial<LightningElementStyle> | null,\n    skipRender = false,\n  ) {\n    if (style) {\n      let styleToSend = _stylesToSend[elementId];\n\n      if (!styleToSend) {\n        _numStylesToSend++;\n        styleToSend = {};\n        _stylesToSend[elementId] = styleToSend;\n      }\n\n      // `for...in` skips Object.entries' tuple allocation — hot path on\n      // every applyStyle. Filter non-flex keys here so we don't serialize\n      // them, ship them across postMessage, and let the worker re-filter.\n      for (const key in style) {\n        if (!isFlexStyleProp(key)) {\n          continue;\n        }\n\n        // oxlint-disable-next-line typescript/no-explicit-any -- intentional: style values can be many shapes; toSerializableValue guards\n        const serializedValue = toSerializableValue(key, (style as any)[key]);\n\n        if (serializedValue != null) {\n          // @ts-expect-error\n          styleToSend[key] = serializedValue;\n        }\n      }\n    } else {\n      // Existence check is required — `applyStyle(id, null)` fires from\n      // childRemoved regardless of whether anything was buffered, and a\n      // counter underflow breaks the > 50 / === 0 thresholds below.\n      if (!_stylesToSend[elementId]) {\n        return;\n      }\n\n      delete _stylesToSend[elementId];\n      _numStylesToSend--;\n    }\n\n    _needsRender ||= !skipRender;\n\n    if (_numStylesToSend > 50) {\n      flushSendStyles();\n    } else {\n      queueSendStyles();\n    }\n  }\n\n  function flushChildOperations() {\n    const buffer = _childOperations.buffer;\n\n    if (buffer.byteLength === 0) {\n      return;\n    }\n\n    // Combine with pending styles if any. See `_flushBothInternal`.\n    if (_numStylesToSend > 0) {\n      _flushBothInternal();\n\n      return;\n    }\n\n    worker.postMessage(\n      {\n        method: 'nodeOperations',\n        args: [buffer],\n      },\n      [buffer],\n    );\n\n    _childOperations.reset();\n  }\n\n  /**\n   * Single 'flushBoth' postMessage — worker applies nodeOps then styles,\n   * preserving the causal ordering. Caller must have verified BOTH queues\n   * have data; this function blindly transfers and clears.\n   */\n  function _flushBothInternal() {\n    const buffer = _childOperations.buffer;\n\n    worker.postMessage(\n      {\n        method: 'flushBoth',\n        args: [buffer, _stylesToSend, !_needsRender],\n      },\n      [buffer],\n    );\n\n    _childOperations.reset();\n    _stylesToSend = {};\n    _numStylesToSend = 0;\n    _needsRender = false;\n  }\n\n  const queueSendNodeOperations = debounceMicrotask(flushChildOperations);\n\n  // Coalesce N synchronous queueRender calls into one postMessage —\n  // unmount cascades otherwise produce ~2 messages per destroyed node.\n  let _wantsRender = false;\n  let _renderElementId = 0;\n  let _renderForce = false;\n\n  function flushRender() {\n    if (!_wantsRender) {\n      return;\n    }\n\n    // Capture before flushSendStyles resets _needsRender. When applyStyles\n    // ships with skipRender=false the worker auto-renders, so the explicit\n    // queueRender below would be redundant.\n    const willAutoRender = _numStylesToSend > 0 && _needsRender;\n\n    flushChildOperations();\n    flushSendStyles();\n\n    if (!willAutoRender) {\n      worker.postMessage({\n        method: 'queueRender',\n        args: [_renderElementId, _renderForce],\n      });\n    }\n\n    _wantsRender = false;\n    _renderElementId = 0;\n    _renderForce = false;\n  }\n\n  const queueRenderDrain = debounceMicrotask(flushRender);\n\n  function nodeOperation(\n    method:\n      | 'addNode'\n      | 'removeNode'\n      | 'addChildNode'\n      | 'detachChildNode'\n      | 'addIndependentRoot'\n      | 'removeIndependentRoot',\n    elementOrParentId: number,\n    childId?: number,\n    index?: number,\n  ) {\n    switch (method) {\n      case 'addNode':\n        _childOperations.writeUint8(NodeOperations.AddNode);\n        _childOperations.writeUint32(elementOrParentId);\n        break;\n      case 'removeNode':\n        _childOperations.writeUint8(NodeOperations.RemoveNode);\n        _childOperations.writeUint32(elementOrParentId);\n        break;\n      case 'addIndependentRoot':\n        _childOperations.writeUint8(NodeOperations.AddIndependentRoot);\n        _childOperations.writeUint32(elementOrParentId);\n        break;\n      case 'removeIndependentRoot':\n        _childOperations.writeUint8(NodeOperations.RemoveIndependentRoot);\n        _childOperations.writeUint32(elementOrParentId);\n        break;\n      case 'addChildNode':\n        if (childId === undefined) {\n          throw new Error('Child ID must be provided for addChildNode operation');\n        }\n\n        _childOperations.writeUint8(\n          index === undefined ? NodeOperations.AddChildNode : NodeOperations.AddChildNodeAtIndex,\n        );\n        _childOperations.writeUint32(elementOrParentId);\n        _childOperations.writeUint32(childId);\n\n        if (index !== undefined) {\n          _childOperations.writeUint32(index);\n        }\n        break;\n      case 'detachChildNode':\n        if (childId === undefined) {\n          throw new Error('Child ID must be provided for detachChildNode operation');\n        }\n\n        _childOperations.writeUint8(NodeOperations.DetachChildNode);\n        _childOperations.writeUint32(elementOrParentId);\n        _childOperations.writeUint32(childId);\n        break;\n      default:\n        throw new Error(`Unknown node operation: ${method}`);\n    }\n\n    queueSendNodeOperations();\n  }\n\n  worker.onmessage = (event: MessageEvent<{ id: string; result?: unknown; error?: string }>) => {\n    const { id, result, error } = event.data;\n\n    if (id === 'render') {\n      // Special case for render updates\n      _eventEmitter.emit('render', result as ArrayBuffer);\n\n      return;\n    }\n\n    const callee = _callees[id];\n\n    if (!callee) {\n      console.error(`No handler found for worker message id: ${id}`);\n\n      return;\n    }\n\n    const [resolve, reject] = callee;\n\n    delete _callees[id];\n\n    if (error) {\n      reject(new Error(error));\n    } else {\n      resolve(result);\n    }\n  };\n\n  // Used by `init` only — every other call is fire-and-forget on the\n  // buffered pipeline. Flushes pending ops/styles for causal ordering.\n  function _awaitable(method: string, args: unknown[]): Promise<unknown> {\n    return new Promise((resolve, reject) => {\n      const id = getId();\n\n      _callees[id] = [resolve, reject];\n\n      flushChildOperations();\n      flushSendStyles();\n\n      worker.postMessage({ id, method, args });\n    });\n  }\n\n  // Pre-bound methods instead of a Proxy — Proxy.get + closure allocation\n  // per node-op call was measurable self-time in VL recycle bursts.\n  const proxy = {\n    on: _eventEmitter.on.bind(_eventEmitter),\n    off: _eventEmitter.off.bind(_eventEmitter),\n    applyStyle,\n    addNode: (elementId: number) => nodeOperation('addNode', elementId),\n    removeNode: (elementId: number) => nodeOperation('removeNode', elementId),\n    addChildNode: (parentId: number, childId: number, index?: number) =>\n      nodeOperation('addChildNode', parentId, childId, index),\n    detachChildNode: (parentId: number, childId: number) =>\n      nodeOperation('detachChildNode', parentId, childId),\n    queueRender: (elementId: number, force?: boolean) => {\n      _wantsRender = true;\n      _renderElementId = elementId;\n      _renderForce = !!force;\n      queueRenderDrain();\n    },\n    addIndependentRoot: (elementId: number) => nodeOperation('addIndependentRoot', elementId),\n    removeIndependentRoot: (elementId: number) => nodeOperation('removeIndependentRoot', elementId),\n    init: (yogaOptions?: unknown) => _awaitable('init', [yogaOptions]),\n  };\n\n  return proxy as unknown as Workerized<T>;\n}\n\nlet count = 0;\nfunction getId(): number {\n  return ++count;\n}\n\nexport default (): Workerized<YogaManager> => wrapWorker<YogaManager>(new Worker());\n"],"mappings":"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"}