{"version":3,"file":"shared-D6eU3LnD.mjs","sources":["../src/core/batch.js","../src/core/state.js"],"sourcesContent":["/**\n * Lume-JS Cross-Store Batching\n *\n * While batchDepth > 0, states skip their microtask flush and enqueue a\n * small flush handle here instead (via enqueueIfBatching, called from\n * state.js's scheduler); batch() drains the set synchronously when the\n * outermost batch ends. Effects collected from all enqueued states run\n * from one Set per wave, so an effect depending on several mutated stores\n * runs exactly once per batch instead of once per store.\n *\n * This module never imports state.js — state.js imports from here — so\n * there is no cycle, no global scheduler object, and no import side effect.\n */\n\nimport { logError, logWarn } from '../utils/log.js';\n\n// Cap for cascading flush waves (effects mutating state that re-triggers\n// effects). Shared with the per-state microtask flush in state.js.\nexport const MAX_FLUSH_ITERATIONS = 100;\n\nlet batchDepth = 0;\nconst batchedStates = new Set();\n\n/**\n * Called by state.js when a write is scheduled. Returns true if a batch is\n * active and the state's flush handle was captured (the caller must then\n * skip its own microtask scheduling).\n *\n * Internal API between core modules — not exported from the package root.\n *\n * @param {{runBeforeFlushHooks: function, notifySubscribers: function, takeEffects: function}} handle\n * @returns {boolean}\n */\nexport function enqueueIfBatching(handle) {\n  if (batchDepth === 0) return false;\n  batchedStates.add(handle);\n  return true;\n}\n\nfunction flushBatchedStates() {\n  let iterations = 0;\n  while (batchedStates.size > 0 && iterations < MAX_FLUSH_ITERATIONS) {\n    iterations++;\n    const wave = Array.from(batchedStates);\n    batchedStates.clear();\n\n    // Notify each state's subscribers, collecting effects into one\n    // deduplicated set (the same effect queued by N stores runs once).\n    const effects = new Set();\n    for (const s of wave) {\n      s.runBeforeFlushHooks();\n      s.notifySubscribers();\n      for (const fx of s.takeEffects()) effects.add(fx);\n    }\n\n    // Effects run after all subscribers of the wave. Writes they make\n    // re-enter batchedStates (depth is still held) → next iteration.\n    for (const fx of effects) {\n      try { fx(); }\n      catch (err) { logError('[Lume.js state] Error in effect:', err); }\n    }\n  }\n  if (iterations >= MAX_FLUSH_ITERATIONS) {\n    // Drop the runaway wave so a future, unrelated batch doesn't inherit\n    // it. Nothing is lost permanently: the states keep their queued work\n    // and flush it on their next write via the normal microtask path.\n    batchedStates.clear();\n    logError(\n      '[Lume.js state] Maximum batch flush iterations reached (100). ' +\n      'This usually indicates an infinite loop caused by an effect or computed mutating state it depends on.'\n    );\n  }\n}\n\n/**\n * Group multiple state writes and flush them together, synchronously,\n * when the outermost batch() returns.\n *\n * Guarantees:\n * - Subscribers see only the final value of each key (intermediate writes\n *   within the batch are coalesced, as with microtask batching).\n * - An effect that depends on several stores mutated in the batch runs\n *   exactly ONCE — unlike microtask batching, which is per-state and runs\n *   such effects once per store.\n * - Nested batch() calls are absorbed: everything flushes when the\n *   outermost batch ends.\n * - If fn throws, writes made before the throw still flush, then the\n *   error propagates. State scheduling is left clean either way.\n *\n * `fn` must be synchronous — writes after an `await` happen outside the\n * batch and fall back to normal per-state microtask flushing (a console\n * warning is logged if fn returns a Promise).\n *\n * @param {function} fn - Function performing state writes\n * @returns {*} The return value of fn\n *\n * @example\n * import { state, effect, batch } from 'lume-js';\n *\n * const a = state({ value: 1 });\n * const b = state({ value: 2 });\n * effect(() => render(a.value + b.value));\n *\n * batch(() => {\n *   a.value = 10;\n *   b.value = 20;\n * }); // render() ran exactly once, seeing 30\n */\nexport function batch(fn) {\n  if (typeof fn !== 'function') {\n    throw new Error('batch() requires a function');\n  }\n\n  // Nested batch: let the outermost batch flush everything\n  if (batchDepth > 0) return fn();\n\n  batchDepth++;\n  let result;\n  try {\n    result = fn();\n    if (result && typeof result.then === 'function') {\n      logWarn(\n        '[Lume.js batch] batch() received an async function. Only writes before the first await are batched; ' +\n        'later writes flush via normal microtasks.'\n      );\n    }\n    return result;\n  } finally {\n    // Flush while depth is still held so cascading writes from\n    // subscribers/effects keep collecting into batchedStates (deduped),\n    // then release. Runs on success AND when fn throws (writes made\n    // before the throw are committed, then the error propagates).\n    try {\n      flushBatchedStates();\n    } finally {\n      batchDepth--;\n    }\n  }\n}\n","/**\n * Lume-JS Reactive State Core\n *\n * Provides minimal reactive state with standard JavaScript.\n * Features automatic microtask batching for performance.\n * Read tracking is opt-in via withReadObserver — state.js has zero permanent\n * dependency on effect.js or any other module.\n *\n * Features:\n * - Lightweight and Go-style\n * - Explicit nested states\n * - $subscribe for listening to key changes\n * - Cleanup with unsubscribe\n * - Per-state microtask batching for writes\n * - batch() for grouping writes across states with cross-store effect dedupe\n * - Scope-based read tracking via withReadObserver (multi-observer safe)\n *\n * Usage:\n *   import { state } from \"lume-js\";\n *\n *   const store = state({ count: 0 });\n *   const unsub = store.$subscribe(\"count\", val => console.log(val));\n *   unsub(); // cleanup\n */\n\nimport { logError, logWarn } from '../utils/log.js';\nimport { enqueueIfBatching, MAX_FLUSH_ITERATIONS } from './batch.js';\n\n// Per-state batching – each state object maintains its own microtask flush.\n// This keeps effects simple and aligned with Lume's minimal philosophy.\n\n/**\n * Creates a reactive state object.\n *\n * @param {Object} obj - Initial state object (must be plain object)\n * @returns {Proxy} Reactive proxy with $subscribe method\n *\n * @example\n * const store = state({ count: 0 });\n */\n\n// Active read observers — only populated during withReadObserver scopes.\n// This keeps state.js pure: tracking only happens when someone explicitly\n// asks to observe reads within a synchronous function call.\n//\n// Note: This Set is module-level, so all reactive state instances and effects\n// within the SAME module instance share it. This is standard behavior for\n// auto-tracking reactive libraries (Vue, MobX, Solid, etc.). Multiple copies\n// of the lume-js module (e.g. from different bundled chunks) each get their\n// own independent Set via ES module / CommonJS isolation.\nconst readers = new Set();\n\n/**\n * Brand symbol stamped on every object passed to state().\n *\n * Uses the global symbol registry (Symbol.for) so independent copies of\n * lume-js on the same page (e.g. a CDN build next to a bundled chunk)\n * agree on the same brand. This is a type tag for reliable detection\n * (see isReactive in addons), not a security boundary — any code can\n * stamp it.\n *\n * Internal API — exported for addons; not re-exported from the package root.\n */\nexport const REACTIVE_BRAND = Symbol.for('lume.reactive');\n\n// batch() lives in ./batch.js (which never imports this module — no cycle).\n// state.js participates through enqueueIfBatching in scheduleFlush below.\n\n/**\n * Run a function with a read observer active.\n * The observer receives (proxy, key, registerEffect) for every property read.\n * Multiple observers can be active simultaneously (nested effects, devtools, etc.)\n *\n * Internal API — used by effect.js for auto-tracking. May be stabilized\n * for third-party addons in a future release.\n *\n * @security The observer sees reads from ALL state instances within the same\n * module instance, including nested scopes. Only pass trusted observer functions.\n * A future scoped variant (e.g., scopedReadObserver(store, fn)) may limit\n * observation to a single state instance.\n *\n * @param {function} onRead - Called on each property access inside fn\n * @param {function} fn - The function to run under observation\n */\nexport function withReadObserver(onRead, fn) {\n  readers.add(onRead);\n  try {\n    return fn();\n  } finally {\n    readers.delete(onRead);\n  }\n}\n\nexport function state(obj) {\n  // Validate input\n  if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {\n    throw new Error('state() requires a plain object');\n  }\n  if (Object.isFrozen(obj) || Object.isSealed(obj)) {\n    throw new Error('state() requires a mutable plain object');\n  }\n\n  // Object.create(null) - no prototype chain lookups\n  const listeners = Object.create(null);\n  const pendingNotifications = new Map(); // Per-state pending changes\n  const pendingEffects = new Set(); // Dedupe effects per state\n  const beforeFlushHooks = [];\n  let flushScheduled = false;\n  // Live count of listeners across all keys ($subscribe callbacks and effect\n  // subscriptions both register through addListener, which keeps this in\n  // sync). Lets the set trap skip the whole notify/flush pipeline for a\n  // store nothing observes — see the no-subscriber fast path in the trap.\n  let listenerCount = 0;\n\n  // ── Flush steps ──────────────────────────────────────────────────────\n  // Named pieces shared by the per-state microtask flush and batch().\n\n  function runBeforeFlushHooks() {\n    for (let i = 0; i < beforeFlushHooks.length; i++) {\n      try {\n        beforeFlushHooks[i]();\n      } catch (err) {\n        logError('[Lume.js state] Error in beforeFlush hook:', err);\n      }\n    }\n  }\n\n  function notifySubscribers() {\n    // Drain BEFORE delivering. Iterating the live Map is wrong twice over:\n    // a subscriber writing back to an already-delivered key would update\n    // the in-flight entry (never revisited) and the trailing clear() would\n    // destroy it — a silently lost update; and a subscriber opening a\n    // batch() would re-deliver every in-flight entry through the wave's\n    // re-entrant call. Draining first means write-backs land in the now-\n    // empty live Map and are delivered by the next flush iteration/wave.\n    // No listeners on any key: drop the coalesced pending writes without the\n    // Array.from allocation or the delivery loop. Only reachable when a flush\n    // was scheduled by something other than a plain observed write (e.g. a\n    // store with beforeFlush hooks but no subscribers) — the set trap\n    // short-circuits the common no-observer write before scheduling at all.\n    if (listenerCount === 0) {\n      pendingNotifications.clear();\n      return;\n    }\n    const entries = Array.from(pendingNotifications);\n    pendingNotifications.clear();\n    for (const [key, value] of entries) {\n      if (listeners[key]) {\n        const subs = listeners[key];\n        let i = 0;\n        while (i < subs.length) {\n          const fn = subs[i];\n          try {\n            fn(value);\n          } catch (err) {\n            logError(`[Lume.js state] Error notifying subscriber for key \"${String(key)}\":`, err);\n          }\n          // Only advance if fn wasn't removed (something shifted into its place)\n          if (subs[i] === fn) i++;\n        }\n      }\n    }\n  }\n\n  /** Drain queued effects (Set deduplicates) into an array. */\n  function takeEffects() {\n    const effects = Array.from(pendingEffects);\n    pendingEffects.clear();\n    return effects;\n  }\n\n  // Handle this state gives batch() — flush steps only, no live queues.\n  const batchHandle = { runBeforeFlushHooks, notifySubscribers, takeEffects };\n\n  /**\n   * Schedule a single microtask flush for this state object.\n   *\n   * Flush order per state:\n   * 1) Notify subscribers for changed keys (key → subscribers)\n   * 2) Run each queued effect exactly once (Set-based dedupe)\n   * 3) Repeat up to 100 iterations to handle cascading updates,\n   *    then log an error to prevent infinite loops.\n   *\n   * Notes:\n   * - Batching is per state; effects that depend on multiple states\n   *   may run once per state that changed (by design). Use batch() to\n   *   group writes across states and run such effects once.\n   * - Inside batch(), the microtask is skipped: the state enqueues\n   *   itself for the synchronous flush at the end of the batch.\n   */\n  function scheduleFlush() {\n    // Inside batch(): the batch captures this state's flush handle and\n    // flushes synchronously at the end — skip the microtask.\n    if (enqueueIfBatching(batchHandle)) return;\n\n    if (flushScheduled) return;\n\n    flushScheduled = true;\n    queueMicrotask(() => {\n      let iterations = 0;\n\n      try {\n        while ((pendingNotifications.size > 0 || pendingEffects.size > 0) && iterations < MAX_FLUSH_ITERATIONS) {\n          iterations++;\n          runBeforeFlushHooks();\n          notifySubscribers();\n          const effects = takeEffects();\n          for (let i = 0; i < effects.length; i++) {\n            try {\n              effects[i]();\n            } catch (err) {\n              logError('[Lume.js state] Error in effect:', err);\n            }\n          }\n        }\n      } finally {\n        flushScheduled = false;\n      }\n\n      if (iterations >= MAX_FLUSH_ITERATIONS) {\n        logError(\n          '[Lume.js state] Maximum flush iterations reached (100). ' +\n          'This usually indicates an infinite loop caused by an effect or computed mutating state it depends on.'\n        );\n      }\n    });\n  }\n\n  // Stamp the shared brand (non-enumerable: spreads/Object.assign copies\n  // of a store do not inherit the brand and won't masquerade as reactive).\n  Object.defineProperty(obj, REACTIVE_BRAND, { value: true });\n\n  const MAX_SUBSCRIBERS = 1000;\n  const noopUnsubscribe = () => {};\n\n  /**\n   * Shared listener registration with a per-key cap (subscriber DoS\n   * protection). Applied identically to $subscribe callbacks and effect\n   * subscriptions so both paths degrade the same way: a loud console\n   * error and a no-op unsubscribe.\n   */\n  function addListener(key, fn, kind) {\n    if (!listeners[key]) listeners[key] = [];\n    if (listeners[key].length >= MAX_SUBSCRIBERS) {\n      logError(\n        `[Lume.js state] Subscriber limit (${MAX_SUBSCRIBERS}) reached for key \"${String(key)}\". ` +\n        `${kind} ignored — it will NOT receive updates. ` +\n        'This usually means subscriptions are created in a loop without cleanup.'\n      );\n      return noopUnsubscribe;\n    }\n    listeners[key].push(fn);\n    listenerCount++;\n    return () => {\n      if (listeners[key]) {\n        const idx = listeners[key].indexOf(fn);\n        if (idx !== -1) {\n          listeners[key].splice(idx, 1);\n          listenerCount--; // inside the idx guard: a double-unsubscribe is a no-op\n          if (listeners[key].length === 0) delete listeners[key];\n        }\n      }\n    };\n  }\n\n  // Defined once per state instance — not per property read — to avoid per-read closure allocation.\n  const registerEffect = (key, executeFn) => {\n    const callback = () => {\n      pendingEffects.add(executeFn);\n    };\n    return addListener(key, callback, 'Effect subscription');\n  };\n\n  const BLOCKED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\n  const proxy = new Proxy(obj, {\n    get(target, key) {\n      // Skip effect tracking for internal meta methods (e.g. $subscribe)\n      if (typeof key === 'string' && key.startsWith('$')) {\n        return target[key];\n      }\n\n      const value = target[key];\n\n      // Notify active read observers (effects, devtools, etc.)\n      if (readers.size > 0) {\n        for (const reader of readers) {\n          reader(proxy, key, registerEffect);\n        }\n      }\n\n      return value;\n    },\n\n    set(target, key, value) {\n      if (typeof key === 'string' && BLOCKED_KEYS.has(key)) {\n        logWarn(`[Lume.js state] Blocked write to reserved key \"${key}\"`);\n        return true;\n      }\n\n      const oldValue = target[key];\n\n      // Skip update if value unchanged - Object.is() handles NaN and -0 correctly\n      if (Object.is(oldValue, value)) return true;\n\n      target[key] = value;\n\n      // No-subscriber fast path: with zero listeners and no beforeFlush\n      // hooks, nothing observes this write — populating the pending map,\n      // enqueuing into a batch, and flushing would notify nobody. Storing\n      // the value is the whole job, so skip the scheduling cost (it is O(N)\n      // per frame for a store written N times a frame, e.g. a high-churn\n      // data layer read back by a rAF poll instead of subscribers). A later\n      // $subscribe still delivers the current value immediately, and effects\n      // subscribe before they can depend on a key, so no update is missed.\n      if (listenerCount === 0 && beforeFlushHooks.length === 0) return true;\n\n      // Batch notifications at the state level (per-state, not global)\n      pendingNotifications.set(key, value);\n      scheduleFlush();\n\n      return true;\n    }\n  });\n\n  /**\n   * Subscribe to changes for a specific key.\n   * Calls the callback immediately with the current value.\n   * Returns an unsubscribe function for cleanup.\n   *\n   * @param {string} key - Property key to watch\n   * @param {function} fn - Callback function\n   * @returns {function} Unsubscribe function\n   */\n  // Set on obj (not proxy) to avoid triggering the set trap.\n  // The get trap already returns target[key] directly for $-prefixed keys.\n  /**\n   * Register a callback to run before each flush.\n   * Returns an unsubscribe function.\n   */\n  obj.$beforeFlush = (fn) => {\n    if (typeof fn !== 'function') {\n      throw new Error('$beforeFlush requires a function');\n    }\n    if (beforeFlushHooks.indexOf(fn) === -1) {\n      beforeFlushHooks.push(fn);\n    }\n    return () => {\n      const idx = beforeFlushHooks.indexOf(fn);\n      if (idx !== -1) {\n        beforeFlushHooks.splice(idx, 1);\n      }\n    };\n  };\n\n  obj.$subscribe = (key, fn) => {\n    if (typeof fn !== 'function') {\n      throw new Error('Subscriber must be a function');\n    }\n\n    const unsubscribe = addListener(key, fn, 'New subscriber');\n\n    // Over the cap: listener was not added, skip the immediate call too\n    if (unsubscribe === noopUnsubscribe) return unsubscribe;\n\n    // Call immediately with current value (NOT batched)\n    fn(proxy[key]);\n\n    return unsubscribe;\n  };\n\n  return proxy;\n}\n"],"names":[],"mappings":"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"}