{"version":3,"file":"shared-B6kzJYNx.mjs","sources":["../src/core/bindDom.js","../src/core/effect.js"],"sourcesContent":["// src/core/bindDom.js\n/**\n * Lume-JS DOM Binding\n *\n * Binds reactive state to DOM elements using data-* attributes.\n *\n * Built-in attributes (always available):\n *   data-bind=\"key\"           → Two-way binding for inputs, textContent for others\n *   data-hidden=\"key\"         → Toggles hidden (truthy = hidden)\n *   data-disabled=\"key\"       → Toggles disabled (truthy = disabled)\n *   data-checked=\"key\"        → Toggles checked (for checkboxes/radios)\n *   data-required=\"key\"       → Toggles required (truthy = required)\n *   data-aria-expanded=\"key\"  → Sets aria-expanded to \"true\"/\"false\"\n *   data-aria-hidden=\"key\"    → Sets aria-hidden to \"true\"/\"false\"\n *\n * Extensible via handlers option:\n *   import { show, classToggle } from 'lume-js/handlers';\n *   bindDom(root, store, { handlers: [show, classToggle('active')] });\n *\n * Custom handlers:\n *   const tooltip = { attr: 'data-tooltip', apply(el, val) { el.title = val ?? ''; } };\n *   bindDom(root, store, { handlers: [tooltip] });\n *\n * Usage:\n *   import { bindDom } from \"lume-js\";\n *   const cleanup = bindDom(document.body, store);\n *\n * @security `data-bind` attribute values are resolved once at bind time and\n * trusted as state path expressions. If an attacker can inject `data-bind`\n * attributes into the DOM, they can subscribe to any reachable reactive state.\n * Ensure your HTML is trusted or sanitize it before calling bindDom().\n */\n\nimport { logWarn } from '../utils/log.js';\n\n// --- Default Handlers (always active, backwards compatible) ---\n\nconst boolHandler = (name) => ({\n  attr: `data-${name}`,\n  apply(el, val) { el[name] = Boolean(val); }\n});\n\nconst ariaHandler = (name) => ({\n  attr: `data-${name}`,\n  apply(el, val) { el.setAttribute(name, val ? 'true' : 'false'); }\n});\n\nconst DEFAULT_HANDLERS = [\n  boolHandler('hidden'),\n  boolHandler('disabled'),\n  boolHandler('checked'),\n  boolHandler('required'),\n  ariaHandler('aria-expanded'),\n  ariaHandler('aria-hidden'),\n];\n\n/**\n * Merge default and user handlers.\n * User handlers override defaults with same attr (Map deduplicates).\n * User handler arrays are flattened one level (supports classToggle()).\n */\nfunction mergeHandlers(defaults, userHandlers) {\n  if (!userHandlers.length) return defaults;\n  const merged = new Map();\n  for (const h of defaults) merged.set(h.attr, h);\n  for (const h of userHandlers.flat()) merged.set(h.attr, h);\n  return [...merged.values()];\n}\n\n/**\n * DOM binding for reactive state\n */\nexport function bindDom(root, store, options = {}) {\n  if (!(root instanceof HTMLElement)) {\n    throw new Error('bindDom() requires a valid HTMLElement as root');\n  }\n  if (!store || typeof store !== 'object') {\n    throw new Error('bindDom() requires a reactive state object');\n  }\n\n  const { immediate = false, handlers: userHandlers = [] } = options;\n  const handlers = mergeHandlers(DEFAULT_HANDLERS, userHandlers);\n\n  const performBinding = () => {\n    const cleanups = [];\n    const bindingMap = new WeakMap();\n\n    // Build compiled selector: data-bind (always) + all handler attrs\n    const selector = ['[data-bind]', ...handlers.map(h => `[${h.attr}]`)].join(',');\n    const elements = root.querySelectorAll(selector);\n\n    for (const el of elements) {\n      // data-bind (two-way) — always in core, special handling\n      if (el.hasAttribute('data-bind')) {\n        const c = handleDataBind(el, store, el.getAttribute('data-bind'), bindingMap);\n        if (c) cleanups.push(c);\n      }\n\n      // All registered handlers (default + user)\n      for (const handler of handlers) {\n        if (el.hasAttribute(handler.attr)) {\n          const c = applyHandler(el, store, el.getAttribute(handler.attr), handler);\n          if (c) cleanups.push(c);\n        }\n      }\n    }\n\n    // Event delegation for two-way bindings\n    const inputHandler = e => {\n      const binding = bindingMap.get(e.target);\n      if (binding) binding.target[binding.key] = getInputValue(e.target);\n    };\n    root.addEventListener(\"input\", inputHandler);\n    cleanups.push(() => root.removeEventListener(\"input\", inputHandler));\n\n    return () => cleanups.forEach(c => c());\n  };\n\n  // Auto-wait for DOM if needed\n  if (!immediate && document.readyState === 'loading') {\n    let cleanup = null;\n    const onReady = () => { cleanup = performBinding(); };\n    document.addEventListener('DOMContentLoaded', onReady, { once: true });\n    return () => cleanup ? cleanup() : document.removeEventListener('DOMContentLoaded', onReady);\n  }\n\n  return performBinding();\n}\n\n/**\n * Apply a handler to an element via subscription.\n * Resolves the state path and subscribes to changes.\n */\nfunction applyHandler(el, store, path, handler) {\n  const result = resolveProp(store, path);\n  if (!result) return null;\n  const { target, key } = result;\n  return target.$subscribe(key, val => handler.apply(el, val));\n}\n\n/**\n * Handle data-bind (two-way for inputs, textContent for others)\n */\nfunction handleDataBind(el, store, path, bindingMap) {\n  const result = resolveProp(store, path);\n  if (!result) return null;\n\n  const { target, key } = result;\n  const unsub = target.$subscribe(key, val => applyBindValue(el, val));\n\n  if (isFormInput(el)) {\n    bindingMap.set(el, { target, key });\n  }\n\n  return unsub;\n}\n\n/**\n * Resolve a nested path in an object.\n * Example: resolvePath(obj, ['user', 'address']) returns obj.user.address\n */\nfunction resolvePath(obj, pathArr) {\n  if (!pathArr || pathArr.length === 0) {\n    return obj;\n  }\n  let current = obj;\n  for (let i = 0; i < pathArr.length; i++) {\n    const key = pathArr[i];\n    if (current === null || current === undefined) {\n      return null;\n    }\n    if (!(key in current)) {\n      return null;\n    }\n    current = current[key];\n  }\n  return current;\n}\n\n/**\n * Resolve path to target and key.\n *\n * ⚠️ Path bindings are resolved once at bind time. If an intermediate\n * object in the path is null/undefined at bindDom call time, the binding\n * is permanently dead and will not self-heal when the path later becomes valid.\n */\nfunction resolveProp(store, path) {\n  if (!path) return null;\n\n  const pathArr = path.split(\".\");\n  const key = pathArr.pop();\n  const target = resolvePath(store, pathArr);\n\n  if (target === null || target === undefined) {\n    logWarn(`[Lume.js] Invalid path \"${path}\"`);\n    return null;\n  }\n\n  if (!target?.$subscribe) {\n    logWarn(`[Lume.js] Target for \"${path}\" is not reactive`);\n    return null;\n  }\n\n  return { target, key };\n}\n\n/**\n * Update element with value (for data-bind).\n *\n * Exported for internal reuse (e.g. the repeat addon's template bindings)\n * so addon and core data-bind semantics never drift. Not part of the\n * public package API.\n */\nexport function applyBindValue(el, val) {\n  if (el.tagName === \"INPUT\") {\n    if (el.type === \"checkbox\") el.checked = Boolean(val);\n    else if (el.type === \"radio\") el.checked = el.value === String(val);\n    else el.value = val ?? '';\n  } else if (el.tagName === \"TEXTAREA\" || el.tagName === \"SELECT\") {\n    el.value = val ?? '';\n  } else {\n    el.textContent = val ?? '';\n  }\n}\n\n/**\n * Get value from input\n */\nfunction getInputValue(el) {\n  if (el.type === \"checkbox\") return el.checked;\n  if (el.type === \"number\" || el.type === \"range\") return el.valueAsNumber;\n  return el.value;\n}\n\n/**\n * Check if element is form input\n */\nfunction isFormInput(el) {\n  return el.tagName === \"INPUT\" || el.tagName === \"TEXTAREA\" || el.tagName === \"SELECT\";\n}","import { withReadObserver } from './state.js';\nimport { logError } from '../utils/log.js';\n\n/**\n * Lume-JS Effect\n *\n * Reactive effects with two modes:\n * 1. Auto-tracking (default): Tracks dependencies automatically via withReadObserver\n * 2. Explicit deps: You specify exactly what triggers re-runs\n *\n * Auto-tracking uses scope-based read observation — state.js has zero permanent\n * dependency on this module. Read tracking is only active during the synchronous\n * execution of an effect's body.\n *\n * Usage:\n *   import { effect } from \"lume-js\";\n *\n *   // Auto-tracking mode (existing behavior)\n *   effect(() => {\n *     console.log('Count is:', store.count);\n *     // Automatically re-runs when store.count changes\n *   });\n *\n *   // Explicit deps mode (new - no magic)\n *   effect(() => {\n *     console.log('Count is:', store.count);\n *   }, [[store, 'count']]);  // Only re-runs when store.count changes\n *\n * Features:\n * - Automatic dependency collection via withReadObserver scope (default)\n * - Subscriptions persist across runs: a re-run with the same reads makes\n *   zero subscribe/unsubscribe calls and zero allocations; dependencies the\n *   effect stopped reading are swept by run generation\n * - Explicit dependencies for side-effects\n * - Explicit-deps notifications are coalesced: one run per microtask,\n *   no matter how many tracked keys (or stores) changed in the same tick\n * - Returns cleanup function\n * - Compatible with per-state batching\n */\n\n// Module-scoped effect context (prevents third-party spoofing via globalThis)\nlet currentEffect = null;\n\n// withReadObserver is used below to scope read tracking to synchronous effect execution.\n\n/**\n * Auto-tracking effect runner with persistent subscriptions.\n *\n * Dependencies live in a per-effect registry (proxy -> key -> record) that\n * survives across runs: a re-run whose reads match the previous run makes\n * zero subscriptions, zero unsubscriptions, and zero allocations — it only\n * stamps each record with the current run generation. Records not stamped\n * by the latest completed run (a dependency the effect stopped reading)\n * are swept afterwards. Runs that read nothing, and runs that throw, keep\n * every subscription so the effect stays reactive.\n *\n * @param {function} fn - The effect body\n * @returns {function} Disposer that unsubscribes everything\n */\nfunction autoTrackedEffect(fn) {\n  const deps = new Map(); // proxy -> Map<key, { unsub, gen }>\n  let totalDeps = 0;\n  let runGen = 0;\n  let gen = 0;\n  let seen = 0; // existing records re-read this run\n  let added = 0; // new subscriptions made this run\n  let isRunning = false;\n  const context = {}; // identity: attributes reads to this effect, not a nested one\n\n  const onRead = (proxy, key, registerEffect) => {\n    // Only the currently active effect (not a nested one) tracks the read\n    if (currentEffect !== context) return;\n    let byKey = deps.get(proxy);\n    if (!byKey) {\n      byKey = new Map();\n      deps.set(proxy, byKey);\n    }\n    const rec = byKey.get(key);\n    if (rec) {\n      if (rec.gen !== gen) {\n        rec.gen = gen;\n        seen++;\n      }\n      return;\n    }\n    byKey.set(key, { unsub: registerEffect(key, run), gen });\n    added++;\n    totalDeps++;\n  };\n\n  function sweep() {\n    for (const [proxy, byKey] of deps) {\n      for (const [key, rec] of byKey) {\n        if (rec.gen !== gen) {\n          rec.unsub();\n          byKey.delete(key);\n          totalDeps--;\n        }\n      }\n      if (byKey.size === 0) deps.delete(proxy);\n    }\n  }\n\n  function run() {\n    /* v8 ignore next -- defensive guard: synchronous re-entry is unreachable through the public API */\n    if (isRunning) return;\n    gen = ++runGen;\n    seen = 0;\n    added = 0;\n    // Save previous context to support nested effects/computed\n    const previousEffect = currentEffect;\n    currentEffect = context;\n    isRunning = true;\n    try {\n      withReadObserver(onRead, fn);\n    } catch (error) {\n      // Keep every subscription (pre-existing and just-created) so the\n      // effect stays reactive after a throwing run.\n      logError('[Lume.js effect] Error in effect:', error);\n      throw error;\n    } finally {\n      currentEffect = previousEffect;\n      isRunning = false;\n    }\n    // Sweep dropped dependencies — unless nothing was read (early return:\n    // keep the old subscriptions) or every pre-existing record was re-read\n    // (the stable case: nothing to drop, skip the walk entirely).\n    if (seen + added > 0 && seen < totalDeps - added) sweep();\n  }\n\n  run();\n\n  return () => {\n    for (const byKey of deps.values()) {\n      for (const rec of byKey.values()) rec.unsub();\n    }\n    deps.clear();\n    totalDeps = 0;\n  };\n}\n\n/**\n * Creates an effect that runs reactively\n *\n * @param {function} fn - Function to run reactively\n * @param {Array<[object, string]>} [deps] - Optional explicit dependencies as [store, key] tuples\n * @returns {function} Cleanup function to stop the effect\n *\n * @example\n * // Auto-tracking (default)\n * const store = state({ count: 0 });\n * effect(() => {\n *   document.title = `Count: ${store.count}`;\n * });\n * \n * @example\n * // Explicit deps (no magic)\n * effect(() => {\n *   analytics.log(store.count);  // Won't track store.count automatically\n * }, [[store, 'count']]);        // Explicit: only re-run on store.count\n */\nexport function effect(fn, deps) {\n  if (typeof fn !== 'function') {\n    throw new Error('effect() requires a function');\n  }\n\n  // AUTO-TRACKING MODE (default): persistent subscriptions, generation sweep\n  if (!Array.isArray(deps)) {\n    return autoTrackedEffect(fn);\n  }\n\n  const cleanups = [];\n  let isRunning = false;\n\n  /**\n   * Execute the effect function\n   */\n  const execute = () => {\n    /* v8 ignore next -- re-entry guard: unreachable because $subscribe fires via microtask after isRunning resets in finally */\n    if (isRunning) return;\n    isRunning = true;\n\n    try {\n      fn();\n    } catch (error) {\n      logError('[Lume.js effect] Error in effect:', error);\n      throw error;\n    } finally {\n      isRunning = false;\n    }\n  };\n\n  // EXPLICIT DEPS MODE: subscribe to the given [store, key1, key2, ...] tuples.\n  // Coalesce notifications: when several tracked keys change in the same\n  // flush (or several stores flush in the same tick), run the effect once\n  // per microtask instead of once per changed key. This matches the\n  // dedupe guarantee auto-tracking mode gets from the per-state effect queue.\n  let scheduled = false;\n  let disposed = false;\n  cleanups.push(() => { disposed = true; });\n\n  const scheduleExecute = () => {\n    if (scheduled) return;\n    scheduled = true;\n    queueMicrotask(() => {\n      scheduled = false;\n      if (disposed) return;\n      // execute() logs and re-throws; swallow here so a throwing effect\n      // doesn't become an uncaught error inside the microtask (same\n      // containment the state flush loop provides for subscribers).\n      try { execute(); } catch { /* already logged by execute() */ }\n    });\n  };\n\n  // Subscribe to each [store, key1, key2, ...] tuple explicitly\n  for (const dep of deps) {\n    if (Array.isArray(dep) && dep.length >= 2) {\n      const [store, ...keys] = dep;\n      if (store && typeof store.$subscribe === 'function') {\n        // Subscribe to each key in this tuple\n        for (const key of keys) {\n          // $subscribe calls immediately, then on changes\n          // We want: call execute immediately once, then on changes\n          let isFirst = true;\n          const unsub = store.$subscribe(key, () => {\n            if (isFirst) {\n              isFirst = false;\n              return; // Skip first call, we'll run execute() below\n            }\n            scheduleExecute();\n          });\n          cleanups.push(unsub);\n        }\n      }\n    }\n  }\n  // Run immediately\n  execute();\n\n  // Return cleanup function\n  return () => {\n    // while/pop is faster than forEach\n    while (cleanups.length) cleanups.pop()();\n  };\n}"],"names":[],"mappings":"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"}