@jasonshimmy/custom-elements-runtime 3.4.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -7
- package/dist/css-utils-Bn-dO44e.js +203 -0
- package/dist/{css-utils-CC43BbEy.js.map → css-utils-Bn-dO44e.js.map} +1 -1
- package/dist/{css-utils-CC43BbEy.js → css-utils-CFeP8SK1.cjs} +5 -71
- package/dist/{css-utils-mgjmH8qX.cjs.map → css-utils-CFeP8SK1.cjs.map} +1 -1
- package/dist/custom-elements-runtime.cjs.js +3 -4
- package/dist/custom-elements-runtime.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.colors.cjs.js +1 -2
- package/dist/custom-elements-runtime.colors.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.colors.es.js +277 -277
- package/dist/custom-elements-runtime.colors.es.js.map +1 -1
- package/dist/custom-elements-runtime.directive-enhancements.cjs.js +1 -2
- package/dist/custom-elements-runtime.directive-enhancements.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.directive-enhancements.es.js +106 -122
- package/dist/custom-elements-runtime.directive-enhancements.es.js.map +1 -1
- package/dist/custom-elements-runtime.directives.cjs.js +1 -2
- package/dist/custom-elements-runtime.directives.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.directives.es.js +60 -65
- package/dist/custom-elements-runtime.directives.es.js.map +1 -1
- package/dist/custom-elements-runtime.dom-jit-css.cjs.js +1 -7
- package/dist/custom-elements-runtime.dom-jit-css.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.dom-jit-css.es.js +103 -115
- package/dist/custom-elements-runtime.dom-jit-css.es.js.map +1 -1
- package/dist/custom-elements-runtime.es.js +206 -253
- package/dist/custom-elements-runtime.es.js.map +1 -1
- package/dist/custom-elements-runtime.event-bus.cjs.js +1 -2
- package/dist/custom-elements-runtime.event-bus.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.event-bus.es.js +102 -108
- package/dist/custom-elements-runtime.event-bus.es.js.map +1 -1
- package/dist/custom-elements-runtime.jit-css.cjs.js +1 -2
- package/dist/custom-elements-runtime.jit-css.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.jit-css.es.js +14 -32
- package/dist/custom-elements-runtime.jit-css.es.js.map +1 -1
- package/dist/custom-elements-runtime.router.cjs.js +20 -21
- package/dist/custom-elements-runtime.router.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.router.es.js +866 -926
- package/dist/custom-elements-runtime.router.es.js.map +1 -1
- package/dist/custom-elements-runtime.ssr-middleware.cjs.js +3 -4
- package/dist/custom-elements-runtime.ssr-middleware.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.ssr-middleware.es.js +67 -73
- package/dist/custom-elements-runtime.ssr-middleware.es.js.map +1 -1
- package/dist/custom-elements-runtime.ssr.cjs.js +1 -1
- package/dist/custom-elements-runtime.ssr.es.js +3 -14
- package/dist/custom-elements-runtime.store.cjs.js +1 -2
- package/dist/custom-elements-runtime.store.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.store.es.js +32 -33
- package/dist/custom-elements-runtime.store.es.js.map +1 -1
- package/dist/custom-elements-runtime.transitions.cjs.js +1 -2
- package/dist/custom-elements-runtime.transitions.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.transitions.es.js +200 -210
- package/dist/custom-elements-runtime.transitions.es.js.map +1 -1
- package/dist/custom-elements-runtime.vite-plugin.cjs.js +4 -2
- package/dist/custom-elements-runtime.vite-plugin.cjs.js.map +1 -1
- package/dist/custom-elements-runtime.vite-plugin.es.js +155 -78
- package/dist/custom-elements-runtime.vite-plugin.es.js.map +1 -1
- package/dist/helpers-7zLtbh_q.cjs +5 -0
- package/dist/helpers-7zLtbh_q.cjs.map +1 -0
- package/dist/helpers-kOWgceUQ.js +696 -0
- package/dist/helpers-kOWgceUQ.js.map +1 -0
- package/dist/hooks-BY_35J9Y.cjs +2 -0
- package/dist/hooks-BY_35J9Y.cjs.map +1 -0
- package/dist/hooks-Dj1xwqpK.js +407 -0
- package/dist/hooks-Dj1xwqpK.js.map +1 -0
- package/dist/logger-DIJ0UH3R.js +36 -0
- package/dist/{logger-L25axmB-.js.map → logger-DIJ0UH3R.js.map} +1 -1
- package/dist/logger-Dkht1dCX.cjs +2 -0
- package/dist/{logger-BYIN7ysT.cjs.map → logger-Dkht1dCX.cjs.map} +1 -1
- package/dist/namespace-helpers-CIUkG8Mn.js +56 -0
- package/dist/{namespace-helpers-BucDdgz_.js.map → namespace-helpers-CIUkG8Mn.js.map} +1 -1
- package/dist/namespace-helpers-yYIb7INq.cjs +2 -0
- package/dist/{namespace-helpers-Bf7rm9JV.cjs.map → namespace-helpers-yYIb7INq.cjs.map} +1 -1
- package/dist/runtime/tag-utils.d.ts +11 -0
- package/dist/ssr-Bg9jYXYv.js +171 -0
- package/dist/{ssr-H9GDwbTy.js.map → ssr-Bg9jYXYv.js.map} +1 -1
- package/dist/ssr-CucZ-Iwz.cjs +4 -0
- package/dist/{ssr-DRsGduIK.cjs.map → ssr-CucZ-Iwz.cjs.map} +1 -1
- package/dist/ssr.d.ts +2 -0
- package/dist/style-A8l3aQ52.cjs +55 -0
- package/dist/{style-Bjn8zDiZ.cjs.map → style-A8l3aQ52.cjs.map} +1 -1
- package/dist/style-DSSoCbC9.js +1877 -0
- package/dist/{style-DuDoj_xK.js.map → style-DSSoCbC9.js.map} +1 -1
- package/dist/tag-utils-Dg0vRKq9.js +10 -0
- package/dist/tag-utils-Dg0vRKq9.js.map +1 -0
- package/dist/tag-utils-ZOoyzCm9.cjs +2 -0
- package/dist/tag-utils-ZOoyzCm9.cjs.map +1 -0
- package/dist/template-compiler-BJRZoRzZ.js +3044 -0
- package/dist/{template-compiler-Cs5axmn4.js.map → template-compiler-BJRZoRzZ.js.map} +1 -1
- package/dist/template-compiler-C0SkzB_f.cjs +19 -0
- package/dist/{template-compiler-BB4JJdqk.cjs.map → template-compiler-C0SkzB_f.cjs.map} +1 -1
- package/dist/vite-plugin.d.ts +96 -2
- package/package.json +8 -8
- package/dist/css-utils-mgjmH8qX.cjs +0 -577
- package/dist/hooks-_3xP4G2N.js +0 -1189
- package/dist/hooks-_3xP4G2N.js.map +0 -1
- package/dist/hooks-fYQgZk2g.cjs +0 -7
- package/dist/hooks-fYQgZk2g.cjs.map +0 -1
- package/dist/logger-BYIN7ysT.cjs +0 -3
- package/dist/logger-L25axmB-.js +0 -41
- package/dist/namespace-helpers-Bf7rm9JV.cjs +0 -3
- package/dist/namespace-helpers-BucDdgz_.js +0 -61
- package/dist/ssr-DRsGduIK.cjs +0 -5
- package/dist/ssr-H9GDwbTy.js +0 -172
- package/dist/style-Bjn8zDiZ.cjs +0 -56
- package/dist/style-DuDoj_xK.js +0 -1972
- package/dist/template-compiler-BB4JJdqk.cjs +0 -23
- package/dist/template-compiler-Cs5axmn4.js +0 -3236
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers-kOWgceUQ.js","names":[],"sources":["../src/lib/runtime/scheduler.ts","../src/lib/runtime/reactive-proxy-cache.ts","../src/lib/runtime/discovery-state.ts","../src/lib/runtime/reactive.ts","../src/lib/runtime/helpers.ts"],"sourcesContent":["/**\n * Update Scheduler for batching DOM updates\n * Prevents excessive re-renders and improves performance\n */\nimport { devWarn, devError } from './logger';\n\n/**\n * A scheduled update function to be executed in the next flush cycle.\n */\ntype ScheduledUpdate = () => void;\n\n/**\n * Scheduling priority for update tasks.\n *\n * - `'immediate'` — Run synchronously before returning (use sparingly).\n * - `'normal'` — Batch via microtask (default).\n * - `'idle'` — Defer to browser idle time via `requestIdleCallback`\n * (time-sliced, non-blocking rendering for low-priority work).\n */\nexport type UpdatePriority = 'immediate' | 'normal' | 'idle';\n\n/**\n * Environment detection utilities\n */\nexport interface TestEnvironment {\n isTest: boolean;\n isVitest: boolean;\n isCypress: boolean;\n}\n\n/**\n * Detect test environment with improved reliability\n */\nexport function detectTestEnvironment(): TestEnvironment {\n // Check Node.js environment first\n const nodeEnv = (() => {\n try {\n const process = (\n globalThis as { process?: { env?: { NODE_ENV?: string } } }\n ).process;\n return process?.env?.NODE_ENV;\n } catch {\n return undefined;\n }\n })();\n\n // Check browser test environments\n const browserTestEnv = (() => {\n try {\n if (typeof window === 'undefined')\n return { vitest: false, cypress: false };\n\n const win = window as { __vitest__?: unknown; Cypress?: unknown };\n return {\n vitest: Boolean(win.__vitest__),\n cypress: Boolean(win.Cypress),\n };\n } catch {\n return { vitest: false, cypress: false };\n }\n })();\n\n const isTest =\n nodeEnv === 'test' || browserTestEnv.vitest || browserTestEnv.cypress;\n\n return {\n isTest,\n isVitest: browserTestEnv.vitest,\n isCypress: browserTestEnv.cypress,\n };\n}\n\nclass UpdateScheduler {\n private pendingUpdates = new Map<string | (() => void), ScheduledUpdate>();\n private isFlushScheduled = false;\n private isFlushing = false;\n private readonly testEnv: TestEnvironment;\n private lastCleanup = 0;\n private readonly CLEANUP_INTERVAL = 5 * 60 * 1000; // 5 minutes\n private readonly MAX_PENDING_SIZE = 10000; // Prevent memory bloat\n\n // Idle / time-sliced priority support\n private pendingIdleUpdates = new Map<\n string | (() => void),\n ScheduledUpdate\n >();\n private idleCallbackHandle: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n // Cache environment detection result to avoid repeated checks\n this.testEnv = detectTestEnvironment();\n this.schedulePeriodicCleanup();\n }\n\n /**\n * Schedule an update to be executed in the next microtask\n * Uses component identity to deduplicate multiple render requests for the same component\n */\n schedule(update: () => void, componentId?: string): void {\n // IMPORTANT: Never use update.toString() as it breaks with minification!\n // Use the componentId if provided, otherwise use the function reference directly as the key\n // since Map supports using function references as keys (identity-based comparison)\n const key = componentId || update;\n\n // Prevent memory bloat by limiting pending updates\n if (this.pendingUpdates.size >= this.MAX_PENDING_SIZE) {\n this.performEmergencyCleanup();\n }\n\n this.pendingUpdates.set(key, update);\n\n if (!this.isFlushScheduled) {\n this.scheduleFlush();\n }\n }\n\n /**\n * Schedule the flush operation based on environment\n */\n private scheduleFlush(): void {\n this.isFlushScheduled = true;\n\n if (this.testEnv.isTest && !this.isFlushing) {\n // Safe to flush synchronously in test environment to avoid timing issues\n this.flush();\n } else {\n // Batch via microtask in production or when already flushing\n queueMicrotask(() => this.flush());\n }\n }\n\n /**\n * Execute all pending updates with priority ordering\n */\n private flush(): void {\n // Prevent reentrant flushes\n if (this.isFlushing) {\n return;\n }\n\n this.isFlushing = true;\n\n // Capture current updates and reset state\n const updates = this.pendingUpdates;\n this.pendingUpdates = new Map();\n this.isFlushScheduled = false;\n\n try {\n // Execute all updates in batch\n for (const update of updates.values()) {\n try {\n update();\n } catch (error) {\n // Continue with other updates even if one fails\n devError('Error in batched update:', error);\n }\n }\n } finally {\n this.isFlushing = false;\n }\n }\n\n /**\n * Force flush any pending DOM updates immediately. This is useful in\n * test environments or callers that require synchronous guarantees after\n * state changes. Prefer relying on the scheduler's automatic flush when\n * possible; use this only when a caller needs to synchronously observe\n * rendered DOM changes.\n */\n flushImmediately(): void {\n if (this.pendingUpdates.size === 0) {\n return;\n }\n\n // Clear any scheduled flush since we're doing it now\n this.isFlushScheduled = false;\n this.flush();\n }\n\n /**\n * Get the number of pending updates\n */\n get pendingCount(): number {\n return this.pendingUpdates.size;\n }\n\n /**\n * Check if there are pending updates\n */\n get hasPendingUpdates(): boolean {\n return this.pendingUpdates.size > 0;\n }\n\n /**\n * Check if currently flushing updates\n */\n get isFlushingUpdates(): boolean {\n return this.isFlushing;\n }\n\n /**\n * Schedule periodic cleanup to prevent memory leaks\n */\n private schedulePeriodicCleanup(): void {\n if (this.testEnv.isTest) return; // Skip in tests\n\n const cleanup = () => {\n this.performPeriodicCleanup();\n if (!this.testEnv.isTest) {\n setTimeout(cleanup, this.CLEANUP_INTERVAL);\n }\n };\n\n setTimeout(cleanup, this.CLEANUP_INTERVAL);\n }\n\n /**\n * Perform periodic cleanup of stale entries\n */\n private performPeriodicCleanup(): void {\n const now = Date.now();\n if (now - this.lastCleanup < this.CLEANUP_INTERVAL) return;\n\n // In normal operation, pending updates should be processed quickly\n // If we have many pending updates for a long time, something might be wrong\n if (this.pendingUpdates.size > 100) {\n devWarn(\n `Scheduler has ${this.pendingUpdates.size} pending updates. Consider investigating.`,\n );\n }\n\n this.lastCleanup = now;\n }\n\n /**\n * Emergency cleanup when pending updates exceed safe limits.\n * @param queue - The specific map to trim; defaults to the normal queue.\n */\n private performEmergencyCleanup(\n queue: Map<string | (() => void), ScheduledUpdate> = this.pendingUpdates,\n ): void {\n devWarn(\n 'Scheduler emergency cleanup: too many pending updates, clearing oldest entries',\n );\n\n // Clear half of the queue (oldest first by insertion order)\n const entries = Array.from(queue.entries());\n const toRemove = Math.floor(entries.length / 2);\n\n for (let i = 0; i < toRemove; i++) {\n queue.delete(entries[i][0]);\n }\n }\n\n /**\n * Schedule an update with an explicit priority level.\n *\n * - `'immediate'` — Runs synchronously before returning.\n * - `'normal'` — Default microtask batching (same as `schedule()`).\n * - `'idle'` — Deferred to browser idle time via `requestIdleCallback`\n * with time-slicing to avoid blocking the main thread.\n * Falls back to a 5 ms `setTimeout` when\n * `requestIdleCallback` is unavailable (e.g. Safari < 16).\n *\n * @example Defer a low-priority analytics flush\n * ```ts\n * scheduleWithPriority(() => flushAnalytics(), 'idle');\n * ```\n */\n scheduleWithPriority(\n update: () => void,\n priority: UpdatePriority = 'normal',\n componentId?: string,\n ): void {\n if (priority === 'immediate') {\n try {\n update();\n } catch (error) {\n devError('Error in immediate update:', error);\n }\n return;\n }\n\n if (priority === 'idle') {\n const key = componentId ?? update;\n if (this.pendingIdleUpdates.size >= this.MAX_PENDING_SIZE) {\n this.performEmergencyCleanup(this.pendingIdleUpdates);\n }\n this.pendingIdleUpdates.set(key, update);\n this.scheduleIdleFlush();\n return;\n }\n\n // 'normal' → microtask-batched path, always via queueMicrotask so that\n // multiple synchronous calls with the same componentId are deduped before\n // the flush fires (even in test environments where schedule() auto-flushes\n // synchronously to simplify timing).\n const key = componentId ?? update;\n if (this.pendingUpdates.size >= this.MAX_PENDING_SIZE) {\n this.performEmergencyCleanup();\n }\n this.pendingUpdates.set(key, update);\n if (!this.isFlushScheduled) {\n this.isFlushScheduled = true;\n queueMicrotask(() => this.flush());\n }\n }\n\n /**\n * Schedule a flush of idle-priority updates.\n * Uses `requestIdleCallback` when available; falls back to a short `setTimeout`.\n */\n private scheduleIdleFlush(): void {\n if (this.idleCallbackHandle !== null) return;\n\n if (this.testEnv.isTest) {\n // In tests, run after current call stack via microtask so updates are\n // observable synchronously in the same tick.\n this.idleCallbackHandle = setTimeout(() => {\n this.idleCallbackHandle = null;\n this.flushIdleUpdates(null);\n }, 0);\n return;\n }\n\n // Use requestIdleCallback when the browser supports it (Chrome/Firefox/Edge)\n if (typeof requestIdleCallback !== 'undefined') {\n const handle = requestIdleCallback(\n (deadline) => {\n this.idleCallbackHandle = null;\n this.flushIdleUpdates(deadline);\n },\n { timeout: 2000 },\n ) as unknown as ReturnType<typeof setTimeout>;\n this.idleCallbackHandle = handle;\n } else {\n // Polyfill: simulate a ~50 ms idle deadline via setTimeout\n this.idleCallbackHandle = setTimeout(() => {\n this.idleCallbackHandle = null;\n const start = Date.now();\n this.flushIdleUpdates({\n timeRemaining: () => Math.max(0, 50 - (Date.now() - start)),\n didTimeout: false,\n });\n }, 5);\n }\n }\n\n /**\n * Process pending idle-priority updates in a time-sliced manner.\n * Yields back to the browser when the deadline's `timeRemaining()` reaches\n * zero and reschedules any unprocessed work.\n */\n private flushIdleUpdates(\n deadline: { timeRemaining: () => number; didTimeout: boolean } | null,\n ): void {\n // Snapshot and clear current idle queue\n const updates = Array.from(this.pendingIdleUpdates.entries());\n this.pendingIdleUpdates = new Map();\n\n for (let i = 0; i < updates.length; i++) {\n // Yield if we've used our idle time (unless the callback timed out,\n // in which case we must finish to avoid indefinite deferral)\n if (deadline && !deadline.didTimeout && deadline.timeRemaining() <= 0) {\n // Re-queue remaining work for the next idle window\n for (let j = i; j < updates.length; j++) {\n this.pendingIdleUpdates.set(updates[j][0], updates[j][1]);\n }\n this.scheduleIdleFlush();\n return;\n }\n\n try {\n updates[i][1]();\n } catch (error) {\n devError('Error in idle update:', error);\n }\n }\n }\n}\n\n// Global scheduler instance\nexport const updateScheduler = new UpdateScheduler();\n\n/**\n * Schedule a DOM update to be batched with optional component identity and priority.\n */\nexport function scheduleDOMUpdate(\n update: () => void,\n componentId?: string,\n): void {\n updateScheduler.schedule(update, componentId);\n}\n\n/**\n * Schedule an update with explicit priority.\n * See `UpdateScheduler.scheduleWithPriority` for full documentation.\n *\n * @example\n * ```ts\n * // Defer low-priority work to browser idle time (time-sliced, non-blocking)\n * scheduleWithPriority(() => updateAnalyticsDashboard(), 'idle');\n *\n * // Run a critical update before any async code resumes\n * scheduleWithPriority(() => updateCriticalUI(), 'immediate');\n * ```\n */\nexport function scheduleWithPriority(\n update: () => void,\n priority: UpdatePriority = 'normal',\n componentId?: string,\n): void {\n updateScheduler.scheduleWithPriority(update, priority, componentId);\n}\n\n/**\n * Force flush any pending DOM updates immediately. This is useful in\n * test environments or callers that require synchronous guarantees after\n * state changes. Prefer relying on the scheduler's automatic flush when\n * possible; use this only when a caller needs to synchronously observe\n * rendered DOM changes.\n */\nexport function flushDOMUpdates(): void {\n updateScheduler.flushImmediately();\n}\n\n/**\n * Returns a Promise that resolves after the next DOM update cycle completes.\n * Equivalent to Vue's `nextTick()` — useful when you need to observe DOM\n * state that reflects the latest reactive changes.\n *\n * @example\n * ```ts\n * count.value++;\n * await nextTick();\n * console.log(element.shadowRoot.querySelector('span').textContent); // updated\n * ```\n */\nexport function nextTick(): Promise<void> {\n // Flush all pending updates, including any new work enqueued during a flush\n // (e.g. watcher-triggered re-renders), before resolving. Looping ensures\n // callers always observe fully-settled DOM state rather than a partial flush.\n return new Promise<void>((resolve) => {\n const MAX_FLUSH_ITERATIONS = 100;\n let iterations = 0;\n while (updateScheduler.hasPendingUpdates && iterations < MAX_FLUSH_ITERATIONS) {\n updateScheduler.flushImmediately();\n iterations++;\n }\n if (iterations >= MAX_FLUSH_ITERATIONS) {\n devWarn(\n '[nextTick] Maximum flush iterations reached — possible circular update loop. ' +\n 'Check for watchers or computed values that unconditionally mutate reactive state.',\n );\n }\n // Resolve after all synchronous flushes have completed.\n queueMicrotask(resolve);\n });\n}\n","/**\n * Reactive proxy cache to optimize proxy creation and reuse\n * Uses WeakMap for automatic garbage collection when objects are no longer referenced\n */\n\n/**\n * Cache for reactive proxies to avoid creating multiple proxies for the same object\n */\n// legacy symbol marker removed — use WeakSet and non-enumerable flag instead\n// Track actual proxy instances with a WeakSet for robust detection\nconst proxiedObjects = new WeakSet<object>();\n// No legacy flag: rely solely on WeakSet and WeakMap for proxy detection\n\nclass ReactiveProxyCache {\n private static cache = new WeakMap<object, object>();\n private static arrayHandlerCache = new WeakMap<\n object,\n ProxyHandler<object>\n >();\n private static objectHandlerCache = new WeakMap<\n object,\n ProxyHandler<object>\n >();\n\n /**\n * Get or create a reactive proxy for an object\n */\n static getOrCreateProxy<T extends object>(\n obj: T,\n reactiveState: {\n triggerUpdate: () => void;\n makeReactiveValue: (value: unknown) => unknown;\n },\n isArray: boolean = false,\n ): T {\n // Check if we already have a cached proxy\n const cached = this.cache.get(obj);\n if (cached) {\n return cached as T;\n }\n\n // Create appropriate handler\n const handler = isArray\n ? this.getOrCreateArrayHandler(reactiveState)\n : this.getOrCreateObjectHandler(reactiveState);\n\n // Create proxy\n const proxy = new Proxy(obj, handler);\n\n // Mark and track the proxy instance (do this via the optimizer helper)\n try {\n ProxyOptimizer.markAsProxy(proxy as Record<string | symbol, unknown>);\n } catch {\n void 0;\n }\n\n // Cache the proxy by the original target object\n this.cache.set(obj, proxy);\n\n return proxy as T;\n }\n\n /**\n * Get or create a cached array handler\n */\n private static getOrCreateArrayHandler(reactiveState: {\n triggerUpdate: () => void;\n makeReactiveValue: (value: unknown) => unknown;\n }): ProxyHandler<object> {\n // Create a unique handler for this reactive state\n if (!this.arrayHandlerCache.has(reactiveState)) {\n const handler: ProxyHandler<unknown[]> = {\n get: (target, prop, receiver) => {\n const value = Reflect.get(target, prop, receiver);\n\n // Intercept array mutating methods\n if (typeof value === 'function' && typeof prop === 'string') {\n const mutatingMethods = [\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'sort',\n 'reverse',\n 'fill',\n 'copyWithin',\n ];\n if (mutatingMethods.includes(prop)) {\n return function (...args: unknown[]) {\n const result = value.apply(target, args);\n // Trigger update after mutation\n reactiveState.triggerUpdate();\n return result;\n };\n }\n }\n\n if (\n value !== null &&\n typeof value === 'object' &&\n typeof prop === 'string'\n ) {\n return reactiveState.makeReactiveValue(value);\n }\n return value;\n },\n set: (target, prop, value) => {\n (target as unknown as Record<string | symbol, unknown>)[prop] =\n reactiveState.makeReactiveValue(value);\n reactiveState.triggerUpdate();\n return true;\n },\n deleteProperty: (target, prop) => {\n delete (target as unknown as Record<string | symbol, unknown>)[prop];\n reactiveState.triggerUpdate();\n return true;\n },\n };\n\n this.arrayHandlerCache.set(reactiveState, handler);\n }\n\n return this.arrayHandlerCache.get(reactiveState)!;\n }\n\n /**\n * Get or create a cached object handler\n */\n private static getOrCreateObjectHandler(reactiveState: {\n triggerUpdate: () => void;\n makeReactiveValue: (value: unknown) => unknown;\n }): ProxyHandler<object> {\n // Create a unique handler for this reactive state\n if (!this.objectHandlerCache.has(reactiveState)) {\n const handler: ProxyHandler<Record<string | symbol, unknown>> = {\n get: (target, prop, receiver) => {\n const value = Reflect.get(target, prop, receiver);\n if (\n value !== null &&\n typeof value === 'object' &&\n typeof prop === 'string'\n ) {\n return reactiveState.makeReactiveValue(value);\n }\n return value;\n },\n set: (target, prop, value) => {\n (target as Record<string | symbol, unknown>)[prop] =\n reactiveState.makeReactiveValue(value);\n reactiveState.triggerUpdate();\n return true;\n },\n deleteProperty: (target, prop) => {\n delete (target as Record<string | symbol, unknown>)[prop];\n reactiveState.triggerUpdate();\n return true;\n },\n };\n\n this.objectHandlerCache.set(reactiveState, handler);\n }\n\n return this.objectHandlerCache.get(reactiveState)!;\n }\n\n /**\n * Check if an object already has a cached proxy\n */\n static hasProxy(obj: object): boolean {\n return this.cache.has(obj);\n }\n\n /**\n * Clear all cached proxies (useful for testing)\n */\n static clear(): void {\n this.cache = new WeakMap();\n this.arrayHandlerCache = new WeakMap();\n this.objectHandlerCache = new WeakMap();\n }\n\n /**\n * Get cache statistics (for debugging)\n * Note: WeakMap doesn't provide size, so this is limited\n */\n static getStats(): { hasCachedProxies: boolean } {\n // WeakMap doesn't expose size, but we can check if we have any handlers cached\n return {\n hasCachedProxies: this.cache instanceof WeakMap,\n };\n }\n}\n\n/**\n * Optimized proxy creation utilities\n */\nclass ProxyOptimizer {\n // Cache a stable reactiveContext object keyed by onUpdate -> makeReactive\n // This allows handler caches in ReactiveProxyCache to reuse handlers\n // for identical reactive contexts instead of creating a new context object\n // on each createReactiveProxy call.\n private static contextCache = new WeakMap<\n (...args: unknown[]) => unknown,\n WeakMap<\n (...args: unknown[]) => unknown,\n {\n triggerUpdate: () => void;\n makeReactiveValue: (value: unknown) => unknown;\n }\n >\n >();\n /**\n * Create an optimized reactive proxy with minimal overhead\n */\n static createReactiveProxy<T extends object>(\n obj: T,\n onUpdate: () => void,\n makeReactive: (value: unknown) => unknown,\n ): T {\n // If the argument is already a proxy instance, return it directly.\n try {\n if (proxiedObjects.has(obj)) return obj;\n } catch {\n // ignore\n }\n\n const isArray = Array.isArray(obj);\n\n // Reuse a stable reactiveContext object per (onUpdate, makeReactive) pair.\n let inner = this.contextCache.get(onUpdate);\n if (!inner) {\n inner = new WeakMap();\n this.contextCache.set(onUpdate, inner);\n }\n let reactiveContext = inner.get(makeReactive);\n if (!reactiveContext) {\n reactiveContext = {\n triggerUpdate: onUpdate,\n makeReactiveValue: makeReactive,\n };\n inner.set(makeReactive, reactiveContext);\n }\n\n // Delegate to the cache which will return an existing proxy for the target\n // or create one if it doesn't exist yet.\n return ReactiveProxyCache.getOrCreateProxy(obj, reactiveContext, isArray);\n }\n\n /**\n * Mark an object as a proxy (for optimization)\n */\n static markAsProxy(obj: object): void {\n if (!obj) return;\n\n // Prefer adding the actual proxy instance to the WeakSet which does not trigger proxy traps\n try {\n proxiedObjects.add(obj);\n } catch {\n // ignore\n }\n }\n}\n\nexport { ReactiveProxyCache, ProxyOptimizer };\n","/**\n * discovery-state.ts\n *\n * Isolated discovery-render flag. Extracted from hooks.ts to break the\n * circular dependency between hooks.ts and reactive.ts — both modules need\n * to check `isDiscoveryRender()`, but hooks.ts also imports from reactive.ts.\n *\n * All side-effectful hooks (watchEffect, watch, useOnConnected, useStyle,\n * provide, inject, useEmit, …) must guard their setup with\n * `isDiscoveryRender()` and return early / return no-ops when it is true.\n */\n\nimport { devWarn } from './logger';\n\nlet _discoveryRender = false;\n\n/**\n * Returns `true` while a discovery render is in progress.\n * Used by `html` tagged templates and hooks to short-circuit side effects.\n * @internal\n */\nexport function isDiscoveryRender(): boolean {\n return _discoveryRender;\n}\n\n/**\n * Mark the start of a discovery render pass.\n * Call this immediately before invoking the render function for the first time\n * (before `useProps` prop-name collection).\n *\n * Emits a dev warning when called while a discovery render is already active\n * so that nested or mismatched begin/end pairs are surfaced during development.\n * @internal\n */\nexport function beginDiscoveryRender(): void {\n if (_discoveryRender) {\n devWarn(\n '[CER] beginDiscoveryRender() called while a discovery render is already active. ' +\n \"This usually means a component was registered inside another component's render function. \" +\n 'Ensure component() calls are at module top-level.',\n );\n }\n _discoveryRender = true;\n}\n\n/**\n * Mark the end of a discovery render pass.\n * Call this in a `finally` block after the discovery render function returns.\n * @internal\n */\nexport function endDiscoveryRender(): void {\n _discoveryRender = false;\n}\n","import { scheduleDOMUpdate } from './scheduler';\nimport { ProxyOptimizer } from './reactive-proxy-cache';\nimport { devWarn } from './logger';\nimport { isDiscoveryRender } from './discovery-state';\nimport type { WatchOptions } from './types';\n\n// Monotonic counter used to generate deterministic hook IDs.\n// Cheaper than crypto.randomUUID() and produces stable, debuggable identifiers.\nlet _hookIdCounter = 0;\nfunction nextHookId(prefix: string): string {\n return `${prefix}-${++_hookIdCounter}`;\n}\n\n/**\n * Global reactive system for tracking dependencies and triggering updates\n */\nclass ReactiveSystem {\n // Use a stack to support nested callers (component render -> watcher)\n // so that watchers can temporarily become the \"current component\" while\n // establishing dependencies without clobbering the outer component id.\n private currentComponentStack: string[] = [];\n // Consolidated component data: stores dependencies, render function, state index, and last warning time\n private componentData = new Map<\n string,\n {\n dependencies: Set<ReactiveState<unknown>>;\n renderFn: () => void;\n stateIndex: number;\n lastWarnTime: number;\n // watchers registered by the component during render\n watchers: Map<string, string>;\n }\n >();\n // Flat storage: compound key `${componentId}:${stateIndex}` -> ReactiveState\n private stateStorage = new Map<string, ReactiveState<unknown>>();\n private trackingDisabled = false;\n\n /**\n * Set the current component being rendered for dependency tracking\n */\n setCurrentComponent(componentId: string, renderFn: () => void): void {\n // Push onto the stack so nested calls can restore previous component\n this.currentComponentStack.push(componentId);\n // (no-op) push logged in debug builds\n if (!this.componentData.has(componentId)) {\n this.componentData.set(componentId, {\n dependencies: new Set(),\n renderFn,\n stateIndex: 0,\n lastWarnTime: 0,\n watchers: new Map(),\n });\n } else {\n const data = this.componentData.get(componentId)!;\n // Clean up watchers from previous renders so they don't accumulate\n if (data.watchers && data.watchers.size) {\n for (const wid of data.watchers.values()) {\n try {\n this.cleanup(wid);\n } catch {\n // swallow\n }\n }\n data.watchers.clear();\n }\n data.renderFn = renderFn;\n data.stateIndex = 0; // Reset state index for this render\n }\n }\n\n /**\n * Clear the current component after rendering\n */\n clearCurrentComponent(): void {\n // Pop the current component off the stack and restore the previous one\n this.currentComponentStack.pop();\n }\n\n /**\n * Get the current component id (top of stack) or null\n */\n getCurrentComponentId(): string | null {\n return this.currentComponentStack.length\n ? this.currentComponentStack[this.currentComponentStack.length - 1]\n : null;\n }\n\n /**\n * Register a watcher id under a component so it can be cleaned up on re-render\n */\n registerWatcher(componentId: string, watcherId: string): void {\n const data = this.componentData.get(componentId);\n if (!data) return;\n data.watchers.set(watcherId, watcherId);\n }\n\n /**\n * Temporarily disable dependency tracking\n */\n disableTracking(): void {\n this.trackingDisabled = true;\n }\n\n /**\n * Re-enable dependency tracking\n */\n enableTracking(): void {\n this.trackingDisabled = false;\n }\n\n /**\n * Check if a component is currently rendering\n */\n isRenderingComponent(): boolean {\n return this.currentComponentStack.length > 0;\n }\n\n /**\n * Return whether we should emit a render-time warning for the current component.\n * This throttles warnings to avoid spamming the console for legitimate rapid updates.\n */\n shouldEmitRenderWarning(): boolean {\n const current = this.currentComponentStack.length\n ? this.currentComponentStack[this.currentComponentStack.length - 1]\n : null;\n if (!current) return true;\n const data = this.componentData.get(current);\n if (!data) return true;\n\n const now = Date.now();\n const THROTTLE_MS = 1000; // 1 second per component\n if (now - data.lastWarnTime < THROTTLE_MS) return false;\n\n data.lastWarnTime = now;\n return true;\n }\n\n /**\n * Execute a function with tracking disabled\n */\n withoutTracking<T>(fn: () => T): T {\n const wasDisabled = this.trackingDisabled;\n this.trackingDisabled = true;\n try {\n return fn();\n } finally {\n this.trackingDisabled = wasDisabled;\n }\n }\n\n /**\n * Get or create a state instance for the current component\n */\n getOrCreateState<T>(initialValue: T): ReactiveState<T> {\n const current = this.currentComponentStack.length\n ? this.currentComponentStack[this.currentComponentStack.length - 1]\n : null;\n if (!current) {\n return new ReactiveState(initialValue);\n }\n\n const data = this.componentData.get(current);\n if (!data) {\n return new ReactiveState(initialValue);\n }\n const stateKey = `${current}:${data.stateIndex++}`;\n let state = this.stateStorage.get(stateKey) as ReactiveState<T> | undefined;\n\n if (!state) {\n state = new ReactiveState(initialValue);\n this.stateStorage.set(stateKey, state);\n }\n\n return state;\n }\n\n /**\n * Track a dependency for the current component\n */\n trackDependency(state: ReactiveState<unknown>): void {\n if (this.trackingDisabled) return;\n const current = this.currentComponentStack.length\n ? this.currentComponentStack[this.currentComponentStack.length - 1]\n : null;\n if (!current) return;\n\n const data = this.componentData.get(current);\n if (data) {\n data.dependencies.add(state);\n state.addDependent(current);\n // dependency tracked\n }\n }\n\n /**\n * Re-register all reactive dependencies that `fromId` tracks into the\n * currently-active (outer) component context.\n *\n * Used by `computed()` to forward its dep-set to the consuming component\n * without re-executing the getter function a second time.\n */\n propagateDependencies(fromId: string): void {\n if (this.trackingDisabled) return;\n const current = this.currentComponentStack.length\n ? this.currentComponentStack[this.currentComponentStack.length - 1]\n : null;\n if (!current || current === fromId) return;\n const sourceData = this.componentData.get(fromId);\n if (!sourceData) return;\n const targetData = this.componentData.get(current);\n if (!targetData) return;\n for (const state of sourceData.dependencies) {\n targetData.dependencies.add(state);\n state.addDependent(current);\n }\n }\n\n /**\n * Trigger updates for all components that depend on a state\n */\n triggerUpdate(state: ReactiveState<unknown>): void {\n const deps = state.getDependents();\n // trigger update for dependents\n for (const componentId of deps) {\n const data = this.componentData.get(componentId);\n if (data) {\n scheduleDOMUpdate(data.renderFn, componentId);\n }\n }\n }\n\n /**\n * Clean up component dependencies when component is destroyed\n */\n cleanup(componentId: string): void {\n const data = this.componentData.get(componentId);\n if (data) {\n // Cascade cleanup to child watchers (watch/watchEffect/computed) registered\n // during this component's render so their subscriptions are also released.\n if (data.watchers.size) {\n for (const wid of data.watchers.values()) {\n try {\n this.cleanup(wid);\n } catch {\n // swallow — watcher may already be cleaned up\n }\n }\n }\n for (const state of data.dependencies) {\n state.removeDependent(componentId);\n }\n this.componentData.delete(componentId);\n }\n // Remove any flat-stored state keys for this component\n const prefix = componentId + ':';\n for (const key of this.stateStorage.keys()) {\n if (key.startsWith(prefix)) {\n this.stateStorage.delete(key);\n }\n }\n }\n}\n\nconst reactiveSystem = new ReactiveSystem();\n\n// Export for internal use\nexport { reactiveSystem };\n\n/**\n * Internal reactive state class\n */\nexport class ReactiveState<T> {\n private _value: T;\n /** The unwrapped value last assigned — used for Object.is equality checks. */\n private _rawValue: T;\n private dependents = new Set<string>();\n\n constructor(initialValue: T) {\n this._rawValue = initialValue;\n this._value = this.makeReactive(initialValue);\n // Mark instances with a stable cross-bundle symbol so other modules\n // can reliably detect ReactiveState objects even when classes are\n // renamed/minified or when multiple copies of the package exist.\n try {\n // Use a global symbol key to make it resilient across realms/bundles\n const key = Symbol.for('@cer/ReactiveState');\n Object.defineProperty(this, key, {\n value: true,\n enumerable: false,\n configurable: false,\n });\n } catch {\n // ignore if Symbol.for or defineProperty fails in exotic runtimes\n }\n }\n\n get value(): T {\n // Track this state as a dependency when accessed during render\n reactiveSystem.trackDependency(this);\n return this._value;\n }\n\n set value(newValue: T) {\n // Skip update entirely when the new value is identical to the current raw\n // value. This prevents spurious triggerUpdate() calls and downstream\n // re-renders when the same primitive or same object reference is re-assigned\n // (e.g. setting viewYear.value = viewYear.value has zero cost).\n if (Object.is(newValue, this._rawValue)) return;\n\n // Check for state modifications during render (potential infinite loop)\n if (reactiveSystem.isRenderingComponent()) {\n if (reactiveSystem.shouldEmitRenderWarning()) {\n devWarn(\n '🚨 State modification detected during render! This can cause infinite loops.\\n' +\n ' • Move state updates to event handlers\\n' +\n ' • Use watchEffect/watch for side effects\\n' +\n \" • Ensure computed properties don't modify state\",\n );\n }\n }\n\n this._rawValue = newValue;\n this._value = this.makeReactive(newValue);\n // Trigger updates for all dependent components\n reactiveSystem.triggerUpdate(this);\n }\n\n /**\n * Read the current value without registering a reactive dependency.\n * Useful for internal infrastructure (e.g. stable hook slots) that must\n * inspect the stored value without re-triggering the containing component.\n * @internal\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Set the initial value without triggering any reactive updates or warnings.\n * Only intended for internal/infrastructure use (e.g. storing a stable hook\n * handle in a reactive slot without causing a spurious re-render).\n * The value is stored as-is without reactive proxy wrapping so that opaque\n * objects (e.g. TeleportHandle) are not accidentally instrumented.\n * @internal\n */\n initSilent(value: T): void {\n this._rawValue = value;\n this._value = value;\n }\n\n addDependent(componentId: string): void {\n this.dependents.add(componentId);\n }\n\n removeDependent(componentId: string): void {\n this.dependents.delete(componentId);\n }\n\n getDependents(): Set<string> {\n return this.dependents;\n }\n\n private makeReactive<U>(obj: U): U {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n // Skip reactivity for DOM nodes - they should not be made reactive.\n // Guard with typeof to avoid ReferenceError in SSR (Node.js) environments\n // where browser globals like Node, Element, HTMLElement are not defined.\n if (\n (typeof Node !== 'undefined' && (obj as unknown) instanceof Node) ||\n (typeof Element !== 'undefined' && (obj as unknown) instanceof Element) ||\n (typeof HTMLElement !== 'undefined' && (obj as unknown) instanceof HTMLElement)\n ) {\n return obj;\n }\n\n // Use optimized proxy creation\n return ProxyOptimizer.createReactiveProxy(\n obj as unknown as object,\n () => reactiveSystem.triggerUpdate(this),\n (value: unknown) => this.makeReactive(value),\n ) as U;\n }\n}\n\n/**\n * Create reactive state that automatically triggers component re-renders\n * when accessed during render and modified afterwards.\n * Defaults to null if no initial value is provided (Vue-style ref).\n *\n * @example\n * ```ts\n * const counter = ref(0);\n * const user = ref({ name: 'John', age: 30 });\n * const emptyRef = ref(); // defaults to null\n *\n * // Usage in component\n * counter.value++; // triggers re-render\n * user.value.name = 'Jane'; // triggers re-render\n * console.log(emptyRef.value); // null\n * ```\n */\nexport function ref(): ReactiveState<null>;\nexport function ref<T>(initialValue: T): ReactiveState<T>;\nexport function ref<T>(initialValue?: T): ReactiveState<T | null> {\n // Ensure the created state has the union type T | null and explicitly\n // tell getOrCreateState the correct generic to avoid conditional-type recursion.\n return reactiveSystem.getOrCreateState<T | null>(\n (initialValue === undefined ? null : (initialValue as T)) as T | null,\n );\n}\n\n/**\n * Type guard to detect ReactiveState instances in a robust way that works\n * across bundlers, minifiers, and multiple package copies.\n */\nexport function isReactiveState(v: unknown): v is ReactiveState<unknown> {\n if (!v || typeof v !== 'object') return false;\n try {\n const key = Symbol.for('@cer/ReactiveState');\n // Safely check for the presence of the symbol-keyed property without indexing with a unique symbol\n return Object.prototype.hasOwnProperty.call(v, key);\n } catch {\n return false;\n }\n}\n\n/**\n * Create computed state that derives from other reactive state.\n * The result is cached and only recomputed when tracked reactive dependencies change.\n *\n * @example\n * ```ts\n * const firstName = ref('John');\n * const lastName = ref('Doe');\n * const fullName = computed(() => `${firstName.value} ${lastName.value}`);\n * console.log(fullName.value); // 'John Doe' — cached until firstName or lastName changes\n * ```\n */\nexport function computed<T>(fn: () => T): { readonly value: T } {\n let cachedValue: T;\n let isDirty = true;\n\n // Unique identifier used ONLY to track which reactive states this computed depends\n // on (for cache invalidation). It does NOT serve as a \"current component\" for\n // downstream notification — that is handled by running fn() in the outer context.\n const computedId = nextHookId('computed');\n\n // invalidate() only marks the cache stale. It does NOT call triggerUpdate because\n // the calling component is notified directly via the outer fn() call (see get value()).\n const invalidate = (): void => {\n isDirty = true;\n };\n\n // Register under the current component (if inside a render) so cleanup is automatic.\n try {\n const parentComp = reactiveSystem.getCurrentComponentId();\n if (parentComp) {\n reactiveSystem.registerWatcher(parentComp, computedId);\n }\n } catch {\n /* ignore */\n }\n\n // Initial computation: establishes which reactive sources this computed depends on\n // for invalidation tracking.\n reactiveSystem.setCurrentComponent(computedId, invalidate);\n cachedValue = fn();\n reactiveSystem.clearCurrentComponent();\n isDirty = false;\n\n return {\n get value(): T {\n if (isDirty) {\n // Re-run fn() in computedId's context to re-subscribe for future invalidations.\n reactiveSystem.setCurrentComponent(computedId, invalidate);\n cachedValue = fn();\n reactiveSystem.clearCurrentComponent();\n isDirty = false;\n }\n\n // Forward the computed's tracked dependencies into the calling context so\n // that the outer component (or outer computed) is notified directly when any\n // dep changes — without re-executing fn() a second time.\n reactiveSystem.propagateDependencies(computedId);\n\n return cachedValue;\n },\n };\n}\n\n/**\n * Run a side-effect function immediately and automatically re-run it whenever\n * any reactive state accessed inside `fn` changes. Similar to Vue's `watchEffect`.\n *\n * @returns A cleanup function that stops the effect.\n *\n * @example\n * ```ts\n * const count = ref(0);\n * const stop = watchEffect(() => {\n * document.title = `Count: ${count.value}`;\n * });\n * count.value++; // automatically re-runs the effect\n * stop(); // cancel the effect\n * ```\n */\nexport function watchEffect(fn: () => void): () => void {\n // During discovery render, skip setting up effects — fn may have side effects\n // (API calls, mutations) that should only run in real render contexts.\n if (isDiscoveryRender()) return () => {};\n\n const effectId = nextHookId('effect');\n\n // Register under the current component for automatic cleanup on re-render/destroy.\n try {\n const parentComp = reactiveSystem.getCurrentComponentId();\n if (parentComp) {\n reactiveSystem.registerWatcher(parentComp, effectId);\n }\n } catch {\n /* ignore */\n }\n\n const run = (): void => {\n reactiveSystem.setCurrentComponent(effectId, run);\n try {\n fn();\n } finally {\n reactiveSystem.clearCurrentComponent();\n }\n };\n\n // Run immediately to establish dependencies and execute the initial side effect.\n run();\n\n return () => {\n reactiveSystem.cleanup(effectId);\n };\n}\n\n/**\n * Recursively deep-clone a value into a plain (non-reactive) snapshot.\n *\n * Rules:\n * - Primitives and functions are returned as-is.\n * - `Date` instances are cloned.\n * - Arrays are cloned element-by-element (works through Proxy).\n * - Plain objects are cloned key-by-key (works through Proxy `get` traps).\n * - DOM nodes are returned as-is (cloning nodes is out of scope).\n * - Circular references are handled via a `WeakMap` seen-set.\n *\n * @internal — used by deep watchers to capture before/after state snapshots.\n */\nconst DEEP_CLONE_MAX_DEPTH = 50;\n\nfunction deepClone<T>(\n value: T,\n seen = new WeakMap<object, unknown>(),\n depth = 0,\n): T {\n if (value === null || typeof value !== 'object') return value;\n const obj = value as object;\n if (seen.has(obj)) return seen.get(obj) as T;\n if (depth > DEEP_CLONE_MAX_DEPTH) {\n devWarn(\n `[watch] Deep clone exceeded ${DEEP_CLONE_MAX_DEPTH} nesting levels. ` +\n 'Returning a reference at this depth instead of cloning further. ' +\n 'Consider restructuring your state or switching to a shallow watch.',\n );\n return value;\n }\n // Do not attempt to clone DOM nodes\n if (typeof Node !== 'undefined' && obj instanceof Node) return value;\n // Clone Date\n if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T;\n // Clone Array (Array.isArray is Proxy-transparent)\n if (Array.isArray(obj)) {\n const arr: unknown[] = [];\n seen.set(obj, arr);\n for (let i = 0; i < (obj as unknown[]).length; i++) {\n arr.push(deepClone((obj as unknown[])[i], seen, depth + 1));\n }\n return arr as unknown as T;\n }\n // Clone plain object (Object.keys + Reflect.get work through Proxy)\n const copy: Record<string, unknown> = {};\n seen.set(obj, copy);\n for (const key of Object.keys(obj)) {\n try {\n copy[key] = deepClone(\n (obj as Record<string, unknown>)[key],\n seen,\n depth + 1,\n );\n } catch {\n // skip inaccessible or throwing properties\n }\n }\n return copy as unknown as T;\n}\n\n/**\n * Create a watcher that runs when dependencies change\n *\n * @example\n * ```ts\n * const count = ref(0);\n * watch(() => count.value, (newVal, oldVal) => {\n * console.log(`Count changed from ${oldVal} to ${newVal}`);\n * });\n * ```\n */\nexport function watch<T>(\n source: ReactiveState<T>,\n callback: (newValue: T, oldValue?: T) => void,\n options?: WatchOptions,\n): () => void;\nexport function watch<T>(\n source: () => T,\n callback: (newValue: T, oldValue?: T) => void,\n options?: WatchOptions,\n): () => void;\nexport function watch<T>(\n source: ReactiveState<T> | (() => T),\n callback: (newValue: T, oldValue?: T) => void,\n options?: WatchOptions,\n): () => void {\n // During discovery render, skip setting up watchers — callbacks may contain\n // side effects that should only run against real component instances.\n if (isDiscoveryRender()) return () => {};\n\n // Note: we must establish reactive dependencies first (a tracked\n // call) and only then capture the initial `oldValue`. Capturing\n // `oldValue` before registering as a dependent means the first\n // tracked value may differ and lead to missed or spurious callbacks.\n let oldValue: T;\n // Normalize source: accept either a ReactiveState or a getter function\n const getter: () => T = ((): (() => T) => {\n // runtime check for ReactiveState instances\n if (isReactiveState(source)) {\n // cast to ReactiveState<T> and return getter\n return () => (source as ReactiveState<T>).value;\n }\n return source as () => T;\n })();\n\n // Create a dummy component to track dependencies\n const watcherId = nextHookId('watch');\n\n // If called during a component render, register this watcher under that\n // component so watchers created in render are cleaned up on re-render.\n try {\n const parentComp = reactiveSystem.getCurrentComponentId();\n if (parentComp) {\n reactiveSystem.registerWatcher(parentComp, watcherId);\n }\n } catch {\n /* ignore */\n }\n\n const updateWatcher = () => {\n reactiveSystem.setCurrentComponent(watcherId, updateWatcher);\n const newValue = getter();\n reactiveSystem.clearCurrentComponent();\n\n if (options?.deep) {\n // Deep watchers: nested mutations keep the same proxy reference, so\n // reference equality is not a reliable change signal. Always fire\n // the callback and provide independent deep-cloned snapshots so\n // callers receive distinct before/after plain-object values.\n const newSnapshot = reactiveSystem.withoutTracking(() =>\n deepClone(newValue),\n ) as T;\n callback(newSnapshot, oldValue);\n oldValue = newSnapshot;\n } else if (newValue !== oldValue) {\n callback(newValue, oldValue);\n oldValue = newValue;\n }\n };\n\n // Initial run to establish dependencies\n reactiveSystem.setCurrentComponent(watcherId, updateWatcher);\n // Capture the tracked initial value as the baseline\n oldValue = getter();\n reactiveSystem.clearCurrentComponent();\n\n // For deep watchers, snapshot the initial value so that oldValue is a\n // stable plain-object clone that won't be mutated in-place by the user.\n if (options?.deep) {\n oldValue = reactiveSystem.withoutTracking(() => deepClone(oldValue)) as T;\n }\n\n // If immediate is requested, invoke the callback once with the\n // current value as `newValue` and `undefined` as the previous value\n // to match Vue's common semantics.\n if (options && options.immediate) {\n callback(oldValue, undefined);\n }\n\n // Return cleanup function\n return () => {\n reactiveSystem.cleanup(watcherId);\n };\n}\n","/**\n * Safe execution helper - silently ignores errors\n */\nexport const safe = (fn: () => void): void => {\n try {\n fn();\n } catch {\n void 0;\n }\n};\n\nimport { isReactiveState } from './reactive';\nimport { devWarn } from './logger';\n\n// Caches for string transformations to improve performance\nconst KEBAB_CASE_CACHE = new Map<string, string>();\nconst CAMEL_CASE_CACHE = new Map<string, string>();\nconst HTML_ESCAPE_CACHE = new Map<string, string>();\n\n// Cache size limits to prevent memory bloat\nconst MAX_CACHE_SIZE = 500;\n\n// Module-level state for entity map and loader. Using module-level vars avoids\n// reliance on attaching properties to functions which can be brittle when\n// minifiers are configured to mangle properties.\nlet _namedEntityMap: Record<string, string> | undefined;\n// eslint-disable-next-line prefer-const\nlet _namedEntityMapLoader: (() => Promise<Record<string, string>>) | undefined;\nlet _usedEntityFallback = false;\nlet _warnedEntityFallback = false;\n// Module-level decode element used in browser environments to avoid attaching\n// an element to the function object (function properties can be mangled by\n// aggressive minifiers). Keep a function-attached reference only for backward\n// compatibility but prefer `_decodeEl` at runtime.\nlet _decodeEl: HTMLDivElement | undefined;\n// NOTE (internal): The runtime prefers module-level state for the entity map\n// and decode element to ensure minifier-safe behavior in production builds.\n// We intentionally retain assignments to function-attached properties in a\n// few places solely for backward compatibility with older tests and code\n// paths. New code should rely on `registerEntityMap`, `loadEntityMap`, and\n// the exported `decodeEntities` function rather than inspecting internal\n// function properties.\n// Use globalThis to avoid TypeScript requiring Node typings for `process`.\nconst _isNode = !!(globalThis as { process?: { versions?: { node?: string } } })\n .process?.versions?.node;\n\n/**\n * Convert camelCase to kebab-case with caching\n */\nexport function toKebab(str: string): string {\n if (KEBAB_CASE_CACHE.has(str)) {\n return KEBAB_CASE_CACHE.get(str)!;\n }\n\n const result = str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n\n // Prevent memory bloat with size limit\n if (KEBAB_CASE_CACHE.size < MAX_CACHE_SIZE) {\n KEBAB_CASE_CACHE.set(str, result);\n }\n\n return result;\n}\n\n/**\n * Convert kebab-case to camelCase with caching\n */\nexport function toCamel(str: string): string {\n if (CAMEL_CASE_CACHE.has(str)) {\n return CAMEL_CASE_CACHE.get(str)!;\n }\n\n const result = str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\n\n if (CAMEL_CASE_CACHE.size < MAX_CACHE_SIZE) {\n CAMEL_CASE_CACHE.set(str, result);\n }\n\n return result;\n}\n\n/**\n * Clear string transformation caches (useful for testing)\n */\nexport function clearStringCaches(): void {\n KEBAB_CASE_CACHE.clear();\n CAMEL_CASE_CACHE.clear();\n HTML_ESCAPE_CACHE.clear();\n}\n\n/**\n * Get cache statistics for debugging\n */\nexport function getStringCacheStats(): {\n kebabCacheSize: number;\n camelCacheSize: number;\n htmlEscapeCacheSize: number;\n} {\n return {\n kebabCacheSize: KEBAB_CASE_CACHE.size,\n camelCacheSize: CAMEL_CASE_CACHE.size,\n htmlEscapeCacheSize: HTML_ESCAPE_CACHE.size,\n };\n}\n\nexport function escapeHTML(\n str: string | number | boolean,\n): string | number | boolean {\n if (typeof str === 'string') {\n // Check cache first for frequently escaped strings\n if (HTML_ESCAPE_CACHE.has(str)) {\n return HTML_ESCAPE_CACHE.get(str)!;\n }\n\n const result = str.replace(\n /[&<>\"']/g,\n (c) =>\n ({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n })[c]!,\n );\n\n // Only cache strings that contain entities to escape\n if (result !== str && HTML_ESCAPE_CACHE.size < MAX_CACHE_SIZE) {\n HTML_ESCAPE_CACHE.set(str, result);\n }\n\n return result;\n }\n return str;\n}\n\n/**\n * Decode HTML entities (named and numeric) into their character equivalents.\n * - In browser: uses a DOM-based technique to decode entities while preserving\n * existing raw tags.\n * - In non-DOM (SSR) environments: handles numeric references and a conservative\n * named-entity map for common entities.\n *\n * @param str - string containing HTML entities\n * @returns decoded string\n */\nexport function decodeEntities(str: string): string {\n if (!str) return '';\n const s = String(str);\n\n // Browser environment: use a DOM element to decode the full set of named entities.\n if (\n typeof document !== 'undefined' &&\n typeof document.createElement === 'function'\n ) {\n const SENTINEL_L = '\\uF000';\n const SENTINEL_G = '\\uF001';\n // Protect existing literal tags so they won't be parsed as HTML by innerHTML\n const protectedStr = s.replace(/</g, SENTINEL_L).replace(/>/g, SENTINEL_G);\n\n // Prefer module-level el to avoid relying on function-attached properties\n // which can be renamed/mangled by some minifiers. Keep function-attached\n // `_el` for backward compatibility but do not depend on it.\n const el = _decodeEl || (_decodeEl = document.createElement('div'));\n try {\n (decodeEntities as { _el?: HTMLElement })._el = el;\n } catch {\n void 0;\n }\n\n el.innerHTML = protectedStr;\n const decoded = el.textContent || '';\n return decoded\n .replace(new RegExp(SENTINEL_L, 'g'), '<')\n .replace(new RegExp(SENTINEL_G, 'g'), '>');\n }\n\n // SSR / non-DOM fallback: handle numeric refs and named entities via an external JSON map.\n // Keep a tiny inline map for the most common entities so decodeEntities remains sync.\n const tinyMap: Record<string, string> = {\n lt: '<',\n gt: '>',\n amp: '&',\n quot: '\"',\n apos: \"'\",\n nbsp: '\\u00A0',\n };\n\n // Prefer module-level registered map first (minifier-safe). Keep function\n // attached map as a fallback for backward compatibility only.\n const registered =\n _namedEntityMap ??\n (decodeEntities as { _namedMap?: Record<string, string> })._namedMap;\n\n // Select map: module-level registered > function-attached registered > sync require (Node-only) > tinyMap.\n let namedMap: Record<string, string> | undefined = registered;\n\n if (!namedMap && _isNode) {\n // Try to synchronously require the JSON in Node-like environments without importing `require`.\n try {\n // Use globalThis to avoid referencing `require` directly (prevents TS needing node types)\n const maybeRequire = (globalThis as { require?: (id: string) => unknown })\n .require;\n if (typeof maybeRequire === 'function') {\n // Try several common require paths (installed package, dist layout, src layout)\n const candidates = [\n '@jasonshimmy/custom-elements-runtime/entities.json', // installed package export\n '../../entities.json', // dist/runtime -> ../../entities.json\n '../../../entities.json', // src/lib/runtime -> ../../../entities.json\n '../entities.json',\n './entities.json',\n ];\n for (const p of candidates) {\n try {\n const m = maybeRequire(p);\n // Ensure the required value is an object before assigning and cast it to the expected type\n if (m && typeof m === 'object') {\n namedMap = m as Record<string, string>;\n break;\n }\n } catch {\n void 0;\n }\n }\n }\n } catch {\n void 0;\n }\n }\n\n // If we still don't have a map, fall back to tinyMap and trigger background loader if present.\n if (!namedMap) {\n namedMap = tinyMap;\n // Keep both module and function-level flags in sync for backward compatibility.\n // Mark fallback usage primarily on module-level flags (minifier-safe).\n _usedEntityFallback = true;\n try {\n (decodeEntities as { _usedFallback?: boolean })._usedFallback = true;\n } catch {\n void 0;\n }\n const loader =\n (\n decodeEntities as {\n _namedMapLoader?: () => Promise<Record<string, string>>;\n }\n )._namedMapLoader ?? _namedEntityMapLoader;\n if (loader) {\n // Load asynchronously; when ready, cache it for future sync calls and sync to function props.\n loader()\n .then((m: Record<string, string>) => {\n _namedEntityMap = m;\n try {\n (\n decodeEntities as { _namedMap?: Record<string, string> }\n )._namedMap = m;\n } catch {\n void 0;\n }\n })\n .catch(() => {});\n }\n }\n\n // Emit a one-time dev warning if we used the tiny fallback.\n // Prefer module-level flags first, then function-attached fallbacks for\n // backward compatibility. This avoids depending on function property names\n // which some minifiers may mangle.\n if (\n (_usedEntityFallback ||\n (decodeEntities as { _usedFallback?: boolean })._usedFallback) &&\n !(\n _warnedEntityFallback ||\n (decodeEntities as { _warnedFallback?: boolean })._warnedFallback\n )\n ) {\n _warnedEntityFallback = true;\n try {\n (decodeEntities as { _warnedFallback?: boolean })._warnedFallback = true;\n } catch {\n void 0;\n }\n try {\n devWarn(\n 'decodeEntities: using small SSR fallback entity map. Register the full entities.json via registerEntityMap(entities) on the server to enable full HTML5 named-entity decoding.',\n );\n } catch {\n void 0;\n }\n }\n\n // Replace entities: numeric (hex/dec) or named.\n return s.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (_, entity) => {\n if (entity.charCodeAt(0) === 35) {\n // '#'\n const isHex = (entity.charAt(1) || '').toLowerCase() === 'x';\n const num = isHex\n ? parseInt(entity.slice(2), 16)\n : parseInt(entity.slice(1), 10);\n return Number.isNaN(num) ? `&${entity};` : String.fromCodePoint(num);\n }\n const mapped =\n (namedMap as Record<string, string>)[entity] ??\n (registered && registered[entity]);\n return mapped !== undefined ? mapped : `&${entity};`;\n });\n}\n\n/**\n * Dynamically load the full named-entity map (used in SSR). Exported for testing and\n * to allow bundlers to exclude the JSON from client bundles when dynamic import\n * is used behind a DOM check.\n */\nexport async function loadEntityMap(): Promise<Record<string, string>> {\n // Prefer dynamic import so bundlers can code-split or ignore this file for browser bundles.\n // Try the published package export first; in installed packages this is usually the most\n // reliable path. Make the specifier a runtime string to discourage bundlers from inlining.\n const pkgExport = [\n '@jasonshimmy',\n 'custom-elements-runtime',\n 'entities.json',\n ].join('/');\n try {\n // @vite-ignore: dynamic import specifier constructed at runtime\n const mPkg = await import(/* @vite-ignore */ pkgExport as string);\n return (mPkg && (mPkg.default || mPkg)) as Record<string, string>;\n } catch {\n // Next try relative local JSON (useful during development or mono-repo installs)\n try {\n // Try several reasonable local import paths (development vs built layouts)\n const localCandidates = [\n pkgExport, // try package export via dynamic import too (best for installed packages)\n './entities.json',\n '../../entities.json',\n '../../../entities.json',\n ];\n for (const p of localCandidates) {\n try {\n // @vite-ignore: intentionally dynamic path candidates for dev/local resolution\n const mLocal = await import(/* @vite-ignore */ p as string);\n if (mLocal)\n return (mLocal && (mLocal.default || mLocal)) as Record<\n string,\n string\n >;\n } catch {\n void 0;\n }\n }\n // If none of the dynamic imports succeeded, fall back to the small map.\n return {\n lt: '<',\n gt: '>',\n amp: '&',\n quot: '\"',\n apos: \"'\",\n nbsp: '\\u00A0',\n };\n } catch {\n // Final small fallback\n return {\n lt: '<',\n gt: '>',\n amp: '&',\n quot: '\"',\n apos: \"'\",\n nbsp: '\\u00A0',\n };\n }\n }\n}\n\n// Attach loader to module state and (for backward compatibility) to the function\n// as well. Using module-level state avoids property-mangling risks in minified\n// builds; attaching to the function keeps tests that reference the property\n// working until they can be updated.\n_namedEntityMapLoader = loadEntityMap;\n(\n decodeEntities as typeof decodeEntities & {\n _namedMapLoader?: typeof loadEntityMap;\n }\n)._namedMapLoader = loadEntityMap;\n\n/**\n * Register a full named-entity map for SSR. Intended for server startup code to\n * provide the authoritative HTML5 entity mapping. This keeps the client bundle\n * small because the map is only injected on the server side.\n *\n * registerEntityMap should be called once at server startup prior to rendering.\n */\nexport function registerEntityMap(\n map: Record<string, string>,\n options?: { overwrite?: boolean },\n): void {\n if (!map || typeof map !== 'object') return;\n const existing = _namedEntityMap;\n if (existing && !options?.overwrite) return; // first registration wins by default\n _namedEntityMap = map;\n}\n\n/**\n * Clear any registered entity map. Useful for tests or restarting state.\n */\nexport function clearRegisteredEntityMap(): void {\n _namedEntityMap = undefined;\n}\n\n/**\n * Wrap a string as raw HTML. This is intentionally unsafe — callers must\n * sanitize untrusted input before using this. The returned object provides\n * two property names to be compatible with different parts of the runtime.\n */\nexport function unsafeHTML(html: string): {\n __unsafeHTML: string;\n __rawHTML: string;\n} {\n const s = String(html);\n // Provide both property names to be compatible with compiler/renderer expectations\n return { __unsafeHTML: s, __rawHTML: s };\n}\n\n/** Type-guard for unsafeHTML wrapper */\nexport function isUnsafeHTML(\n value: unknown,\n): value is { __unsafeHTML?: string; __rawHTML?: string } {\n return (\n !!value &&\n (typeof (value as { __unsafeHTML?: unknown }).__unsafeHTML === 'string' ||\n typeof (value as { __rawHTML?: unknown }).__rawHTML === 'string')\n );\n}\n\n/**\n * Get nested property value from object using dot notation\n */\nexport function getNestedValue(\n obj: Record<string, unknown>,\n path: string,\n): unknown {\n if (typeof path === 'string') {\n // Handle empty path explicitly: return undefined to indicate no lookup\n if (path === '') return undefined;\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current == null || typeof current !== 'object') {\n current = undefined;\n break;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n // If the result is a ReactiveState object, return its value\n if (isReactiveState(current)) {\n return (current as { value: unknown }).value;\n }\n return current;\n }\n return path;\n}\n\n/**\n * Set nested property value in object using dot notation\n */\nexport function setNestedValue(\n obj: Record<string, unknown>,\n path: string,\n value: unknown,\n): void {\n const keys = String(path).split('.');\n const lastKey = keys.pop();\n if (!lastKey) return;\n const target = keys.reduce(\n (current: Record<string, unknown>, key: string) => {\n if (current[key] == null) current[key] = {};\n return current[key] as Record<string, unknown>;\n },\n obj,\n ) as Record<string, unknown>;\n\n // If target[lastKey] is a ReactiveState object, set its value property\n if (isReactiveState(target[lastKey])) {\n target[lastKey].value = value;\n } else {\n target[lastKey] = value;\n }\n}\n\n/**\n * Safely unwrap reactive-like wrappers to their inner primitive when safe.\n * Returns the original value when it's not safe to coerce to a primitive.\n */\nexport function unwrapIfPrimitive(val: unknown): unknown {\n try {\n if (val && typeof val === 'object') {\n if (isReactiveState(val)) return (val as { value: unknown }).value;\n if ('value' in val) {\n const maybe = (val as { value: unknown }).value;\n // Only return primitive inner values; otherwise return original\n if (\n maybe === null ||\n maybe === undefined ||\n typeof maybe === 'string' ||\n typeof maybe === 'number' ||\n typeof maybe === 'boolean'\n ) {\n return maybe;\n }\n return val;\n }\n }\n } catch {\n // ignore\n }\n return val;\n}\n\n/**\n * Return a serialized string for an attribute value when safe to write to DOM.\n * Returns `null` when the value should not be written as an attribute.\n */\nexport function safeSerializeAttr(val: unknown): string | null {\n const v = unwrapIfPrimitive(val);\n if (v === null || v === undefined) return null;\n const t = typeof v;\n if (t === 'string' || t === 'number' || t === 'boolean') return String(v);\n return null; // complex objects, nodes, functions -> do not serialize\n}\n\n/**\n * Determine if an attribute name is class-like and should be preserved on hosts.\n * Class-like: exactly 'class', camelCase ending with 'Class', or kebab-case ending with '-class'.\n */\nexport function isClassLikeAttr(name: string): boolean {\n if (!name || typeof name !== 'string') return false;\n if (name === 'class') return true;\n if (name.endsWith('Class')) return true;\n // Kebab-case: consider attributes where one of the hyphen-separated tokens is 'class'\n if (name.includes('-')) {\n try {\n const parts = name.split('-');\n if (parts.some((p) => p === 'class')) return true;\n } catch {\n // fallthrough\n }\n }\n return false;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./logger-Dkht1dCX.cjs`),t=require(`./helpers-7zLtbh_q.cjs`),n=require(`./css-utils-CFeP8SK1.cjs`);var r=null;function i(){if(r!==null)throw Error(`[CER] Concurrent SSR render detected: beginSSRGlobalStyleCollection() called while a collection is already active. For concurrent request handling, use worker threads or multiple Node.js processes.`);r=[]}function a(){let e=r??[];return r=null,e}function o(e){return r===null?!1:(e&&!r.includes(e)&&r.push(e),!0)}var s=0;function c(n,r,i=`unknown`,a){let o={};for(let[e,n]of Object.entries(r??{}))o[t.f(e)]=n;let c={getAttribute(e){let n=t.f(e);if(o[n]!==void 0&&o[n]!==null)return String(o[n]);let i=(r??{})[e];return i==null?null:String(i)},hasAttribute(e){return this.getAttribute(e)!==null},shadowRoot:null,tagName:``,parentElement:null},l={...o,_componentId:`cer-ssr-${Object.keys(o).join(`-`)||`root`}-${++s}`,requestRender:()=>void 0,_requestRender:()=>void 0,emit:()=>!0,refs:{}};Object.defineProperty(l,`_host`,{value:c,writable:!0,enumerable:!1,configurable:!0}),a!==void 0&&Object.defineProperty(l,`_router`,{value:a,writable:!1,enumerable:!1,configurable:!0}),f(l);let u=null,d;try{let e=n.render(l);e instanceof Promise?d=e:u=e}catch(t){e.r(`[SSR] Component "${i}" threw during SSR render. The shadow DOM will be empty. Error:`,t)}finally{p()}let m=String(l._computedStyle??``);return{shadowVNode:u,useStyleCSS:m,asyncPromise:d}}function l(){return t.w()}var u=null,d=Symbol(`cer:provides`);function f(e){u=e}function p(){u=null}function m(){return u}function h(){if(!u)throw Error(`useEmit must be called during component render`);if(t.w())return()=>!1;let e=u.emit;if(typeof e!=`function`)throw Error(`useEmit requires an emit function on the component context`);let n=e;return(e,t,r)=>n(e,t,r)}function g(e){e._hookCallbacks||Object.defineProperty(e,`_hookCallbacks`,{value:{},writable:!0,enumerable:!1,configurable:!0})}function _(e){if(!u)throw Error(`useOnConnected must be called during component render`);if(t.w())return;g(u);let n=u._hookCallbacks;n.onConnected||=[],n.onConnected.push(e)}function v(e){if(!u)throw Error(`useOnDisconnected must be called during component render`);if(t.w())return;g(u);let n=u._hookCallbacks;n.onDisconnected||=[],n.onDisconnected.push(e)}function y(e){if(!u)throw Error(`useOnAttributeChanged must be called during component render`);if(t.w())return;g(u);let n=u._hookCallbacks;n.onAttributeChanged||=[],n.onAttributeChanged.push(e)}function b(n){if(!u)throw Error(`useOnError must be called during component render`);if(t.w())return;g(u);let r=u._hookCallbacks;r.onError||=[],r.onError.push(t=>{try{t instanceof Error?n(t):n(Error(String(t)))}catch(t){e.t(`[useOnError] The error handler itself threw an exception:`,t)}})}function x(e){if(!u)throw Error(`useProps must be called during component render`);g(u);let n=u._hookCallbacks;n.props={...n.props||{},...e};let r=u;try{let n=Object.keys(e||{});for(let i of n){if(typeof i!=`string`||i.startsWith(`_`))continue;let n=Object.getOwnPropertyDescriptor(r,i);if(!(n&&!n.configurable))try{let n=Object.prototype.hasOwnProperty.call(r,i)?r[i]:void 0;Object.defineProperty(r,i,{configurable:!0,enumerable:!0,get(){try{let n=r&&r._host;if(n){let r=t.p(i),a=n.getAttribute(r);if(a!==null){let t=typeof e[i];return t===`boolean`?a===``||a===`true`:t===`number`?Number(a):a}if(n[i]!==void 0){let r=n[i];if(t._(r)||r&&typeof r==`object`&&`value`in r&&!(typeof Node<`u`&&r instanceof Node))return r.value;let a=typeof e[i];if(!(a===`string`&&r&&typeof r==`object`))return a===`boolean`&&typeof r==`string`?r===``||r===`true`:r}}}catch{}return n},set(e){n=e}})}catch{}}}catch{}return new Proxy({},{get(n,i){if(typeof i!=`string`)return;let a=e[i];try{let e=r&&r._host;if(e){if(typeof HTMLElement<`u`&&e instanceof HTMLElement||typeof e.getAttribute==`function`&&typeof e.hasAttribute==`function`){let t=i.replace(/([A-Z])/g,`-$1`).toLowerCase(),n=e.getAttribute(t);if(n!==null)return typeof a==`boolean`?n===``||n===`true`:typeof a==`number`?Number(n):n}let n=e[i];if(n!==void 0&&n!==``){let e=n&&typeof n==`object`&&`value`in n&&!(typeof Node<`u`&&n instanceof Node);if(!(typeof a==`string`&&n&&typeof n==`object`&&!e&&!t._(n)))return typeof a==`boolean`&&a===!1&&n===``?a:t._(n)||e?n.value:typeof a==`boolean`&&typeof n==`string`?n===``||n===`true`:typeof a==`number`&&typeof n==`string`&&!Number.isNaN(Number(n))?Number(n):n}}}catch{}let o=r[i];return typeof a==`boolean`&&o===``?a===!1?a:!0:t._(o)||o&&typeof o==`object`&&`value`in o&&!(typeof Node<`u`&&o instanceof Node)?o.value:o!=null&&o!==``?typeof a==`boolean`&&typeof o==`string`?o===`true`:typeof a==`number`&&typeof o==`string`&&!Number.isNaN(Number(o))?Number(o):o:a},has(t,n){return typeof n==`string`&&(n in r||n in e)},ownKeys(){return Array.from(new Set([...Object.keys(e),...Object.keys(r||{})]))},getOwnPropertyDescriptor(){return{configurable:!0,enumerable:!0}}})}function S(n){if(!u)throw Error(`useStyle must be called during component render`);if(!t.w()){g(u);try{let e=n();Object.defineProperty(u,`_computedStyle`,{value:e,writable:!0,enumerable:!1,configurable:!0})}catch(t){e.r(`Error in useStyle callback:`,t),Object.defineProperty(u,`_computedStyle`,{value:``,writable:!0,enumerable:!1,configurable:!0})}}}var C=new Map;function w(t){let r;try{r=t()}catch{return}if(o(r)||typeof document>`u`||typeof CSSStyleSheet>`u`)return;e.r(`[useGlobalStyle] Injecting global styles from a component. This escapes Shadow DOM encapsulation — use sparingly.`);let i=n.d(n.f(r));if(!(!i||C.has(i)))try{let e=new CSSStyleSheet;e.replaceSync(i),document.adoptedStyleSheets=[...document.adoptedStyleSheets,e],C.set(i,e)}catch{let e=document.createElement(`style`);e.textContent=i,(document.head??document.documentElement).appendChild(e)}}function T(e){if(!u)throw Error(`useDesignTokens must be called during component render`);if(t.w())return;let n=[],r={primary:`--cer-color-primary-500`,secondary:`--cer-color-secondary-500`,neutral:`--cer-color-neutral-500`,success:`--cer-color-success-500`,info:`--cer-color-info-500`,warning:`--cer-color-warning-500`,error:`--cer-color-error-500`},i={fontSans:`--cer-font-sans`,fontSerif:`--cer-font-serif`,fontMono:`--cer-font-mono`};for(let[t,a]of Object.entries(e))a!==void 0&&(t in r?n.push(`${r[t]}:${a}`):t in i?n.push(`${i[t]}:${a}`):t.startsWith(`--`)&&n.push(`${t}:${a}`));if(n.length===0)return;let a=`:host{${n.join(`;`)}}`,o=u._computedStyle??``,s=o?`${o}\n${a}`:a;Object.defineProperty(u,`_computedStyle`,{value:s,writable:!0,enumerable:!1,configurable:!0})}function E(e,n){if(!u)throw Error(`provide must be called during component render`);if(t.w())return;let r=u;r[d]||Object.defineProperty(r,d,{value:new Map,writable:!1,enumerable:!1,configurable:!0}),r[d].set(e,n)}function D(e,n){if(!u)throw Error(`inject must be called during component render`);if(t.w())return n;try{let t=u._host;if(t){let n=t.parentNode;n||=t.getRootNode();let r=0;for(;n&&r<50;)if(r++,typeof ShadowRoot<`u`&&n instanceof ShadowRoot){let t=n.host,r=t.context;if(r){let t=r[d];if(t?.has(e))return t.get(e)}if(n=t.parentNode??t.getRootNode(),n===document||n===t)break}else{if(typeof Element<`u`&&n instanceof Element){let t=n.context;if(t){let n=t[d];if(n?.has(e))return n.get(e)}}let t=n;if(n=n.parentNode??n.getRootNode?.(),n===document||n===t)break}}}catch{}return n}function O(e){return t=>{let n=t??u;if(!n)throw Error(`createComposable: no component context available. Pass a context explicitly or call inside a render function.`);let r=u;f(n);try{return e()}finally{r?f(r):p()}}}function k(e){if(!u)throw Error(`useExpose must be called during component render`);if(t.w())return;g(u);let n=u._hookCallbacks;n.expose={...n.expose??{},...e};let r=u._host;if(r)for(let[t,n]of Object.entries(e))try{r[t]=n}catch{}}function A(){if(!u)throw Error(`useSlots must be called during component render`);if(t.w())return{has:()=>!1,getNodes:()=>[],names:()=>[]};let e=u._host,n=()=>{let t=new Map;if(!e)return t;for(let n of e.children){let e=n.getAttribute(`slot`)??`default`,r=t.get(e);r?r.push(n):t.set(e,[n])}return t};return{has(t){if(!e)return!1;let r=!t||t===`default`?`default`:t,i=n().get(r);return i!==void 0&&i.length>0},getNodes(t){if(!e)return[];let r=!t||t===`default`?`default`:t;return n().get(r)??[]},names(){return e?Array.from(n().keys()):[]}}}function j(...e){if(!u)throw Error(`defineModel must be called during component render`);let n=e.length===2?e[0]:`modelValue`,r=e.length===2?e[1]:e.length===1?e[0]:void 0,i=x({[n]:r}),a=t.w()?null:(()=>{let e=u.emit;return typeof e==`function`?e:null})(),o={get value(){return i[n]},set value(e){a&&a(`update:${n}`,e)}};try{Object.defineProperty(o,Symbol.for(`@cer/ReactiveState`),{value:!0,enumerable:!1,configurable:!1})}catch{}return o}Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return S}});
|
|
2
|
+
//# sourceMappingURL=hooks-BY_35J9Y.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks-BY_35J9Y.cjs","names":[],"sources":["../src/lib/runtime/ssr-context.ts","../src/lib/runtime/hooks.ts"],"sourcesContent":["/**\n * SSR execution context for running component render functions server-side.\n *\n * When generating Declarative Shadow DOM (DSD) output, the SSR renderer must\n * call each custom element's render function to obtain its shadow DOM VNode\n * tree and capture any useStyle() / useGlobalStyle() output. This module\n * provides the minimal execution environment that makes that safe.\n *\n * Guarantees:\n * - useStyle() callbacks are executed and their output is captured.\n * - useGlobalStyle() callbacks are captured (not injected into document).\n * - Lifecycle hooks (useOnConnected, watch, …) register harmlessly to arrays\n * that are never invoked.\n * - The reactive system is never permanently mutated — component registration\n * is cleaned up by the render wrapper in factory.ts after each call.\n */\n\nimport type { ComponentConfig, ComponentContext, VNode } from './types';\nimport { toCamel } from './helpers';\nimport {\n setCurrentComponentContext,\n clearCurrentComponentContext,\n} from './hooks';\nimport { devWarn } from './logger';\n\n// ---------------------------------------------------------------------------\n// Global-style SSR collector\n// ---------------------------------------------------------------------------\n\n/**\n * When set, useGlobalStyle() factories write here instead of touching\n * document.adoptedStyleSheets (which doesn't exist in SSR environments).\n */\nlet _ssrGlobalStyleCollector: string[] | null = null;\n\n/** Start collecting useGlobalStyle() output from the current render pass. */\nexport function beginSSRGlobalStyleCollection(): void {\n if (_ssrGlobalStyleCollector !== null) {\n throw new Error(\n '[CER] Concurrent SSR render detected: beginSSRGlobalStyleCollection() called ' +\n 'while a collection is already active. For concurrent request handling, use ' +\n 'worker threads or multiple Node.js processes.',\n );\n }\n _ssrGlobalStyleCollector = [];\n}\n\n/** Stop collecting and return everything gathered so far. */\nexport function endSSRGlobalStyleCollection(): string[] {\n const collected = _ssrGlobalStyleCollector ?? [];\n _ssrGlobalStyleCollector = null;\n return collected;\n}\n\n/**\n * Called by useGlobalStyle() when an SSR collection pass is active.\n * Returns true if the CSS was captured (caller should skip DOM injection).\n */\nexport function captureGlobalStyleForSSR(css: string): boolean {\n if (_ssrGlobalStyleCollector !== null) {\n if (css && !_ssrGlobalStyleCollector.includes(css)) {\n _ssrGlobalStyleCollector.push(css);\n }\n return true;\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// SSR render pass\n// ---------------------------------------------------------------------------\n\nexport interface SSRRenderResult {\n /** VNode tree from the component's render function (shadow DOM content). */\n shadowVNode: VNode | VNode[] | null;\n /** CSS string captured from useStyle() calls during this render. */\n useStyleCSS: string;\n /** Present when the component's render function returned a Promise. */\n asyncPromise?: Promise<VNode | VNode[]>;\n}\n\n/**\n * Run a component's render function in a minimal SSR context to capture its\n * shadow DOM VNode tree and any useStyle() output.\n *\n * The component's render wrapper in factory.ts handles:\n * - setCurrentComponentContext / clearCurrentComponentContext\n * - _hookCallbacks reset\n * - _computedStyle reset\n * - reactiveSystem registration / cleanup\n *\n * We only need to build a context object that satisfies the hooks' expectations.\n */\n// Monotonic counter ensures each SSR render context gets a unique component ID,\n// preventing the reactive system's stateStorage from returning stale cached\n// ref/computed values from a previous request.\nlet _ssrRenderCounter = 0;\n\nexport function runComponentSSRRender(\n config: ComponentConfig<object, object, object, object>,\n attrs: Record<string, string | number | boolean | null | undefined>,\n tag = 'unknown',\n ssrRouter?: unknown,\n): SSRRenderResult {\n // Build camelCase prop map from serialised attribute names.\n const propsFromAttrs: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(attrs ?? {})) {\n propsFromAttrs[toCamel(k)] = v;\n }\n\n // Fake host element: satisfies useProps()'s attribute reads without a real DOM node.\n const fakeHost = {\n getAttribute(name: string): string | null {\n const camel = toCamel(name);\n if (\n propsFromAttrs[camel] !== undefined &&\n propsFromAttrs[camel] !== null\n ) {\n return String(propsFromAttrs[camel]);\n }\n const raw = (attrs ?? {})[name];\n return raw !== undefined && raw !== null ? String(raw) : null;\n },\n hasAttribute(name: string): boolean {\n return this.getAttribute(name) !== null;\n },\n // shadowRoot must be null so useJITCSS() doesn't try to registerJITCSSComponent\n shadowRoot: null as null,\n tagName: '',\n parentElement: null as null,\n };\n\n // Minimal context object — the factory render wrapper will add _hookCallbacks\n // and _computedStyle via Object.defineProperty before calling renderFn().\n const ssrContext: Record<string, unknown> = {\n ...propsFromAttrs,\n // Unique ID per SSR render prevents the reactive system's stateStorage from\n // returning cached ref/computed values from a previous request. Using a\n // monotonic counter is cheaper than crypto.randomUUID() and avoids the\n // Node.js version compatibility concern noted in the original comment.\n _componentId: `cer-ssr-${Object.keys(propsFromAttrs).join('-') || 'root'}-${++_ssrRenderCounter}`,\n requestRender: () => undefined,\n _requestRender: () => undefined,\n emit: () => true,\n refs: {},\n };\n\n // Set _host as non-enumerable to avoid triggering the reactive proxy trap.\n Object.defineProperty(ssrContext, '_host', {\n value: fakeHost,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n\n // Thread the per-request router instance so router-view (and any component\n // that calls getCurrentComponentContext()._router) reads from the correct\n // router rather than the module-level activeRouterProxy singleton.\n // Non-enumerable keeps it out of prop serialisation / Object.keys iteration.\n if (ssrRouter !== undefined) {\n Object.defineProperty(ssrContext, '_router', {\n value: ssrRouter,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n\n // Pre-set the component context so hooks (useStyle, useProps, etc.) work even\n // when config.render is a raw function rather than the factory.ts wrapper.\n // If config.render IS the factory wrapper, it will call setCurrentComponentContext\n // again with the same object — that is harmless.\n setCurrentComponentContext(ssrContext);\n\n let shadowVNode: VNode | VNode[] | null = null;\n let asyncPromise: Promise<VNode | VNode[]> | undefined;\n try {\n const result = config.render(\n ssrContext as ComponentContext<object, object, object, object>,\n );\n // Async render functions cannot be awaited in the synchronous SSR pass.\n // The DSD renderer will emit a streaming placeholder if active; otherwise\n // the shadow DOM will be empty. The caller emits the appropriate warning.\n if (result instanceof Promise) {\n asyncPromise = result;\n } else {\n shadowVNode = result as VNode | VNode[];\n }\n } catch (err) {\n // Best-effort — a render error during SSR should not crash the server.\n // The component will still get a DSD wrapper, just without shadow content.\n devWarn(\n `[SSR] Component \"${tag}\" threw during SSR render. ` +\n `The shadow DOM will be empty. Error:`,\n err,\n );\n } finally {\n // Clear context. The factory wrapper clears it too, but calling clearCurrentComponentContext()\n // twice (null → null) is harmless and ensures clean state if config.render was a raw function.\n clearCurrentComponentContext();\n }\n\n const useStyleCSS = String(\n (ssrContext as { _computedStyle?: string })._computedStyle ?? '',\n );\n\n return { shadowVNode, useStyleCSS, asyncPromise };\n}\n","/**\n * Context-based hooks for functional components\n * Provides React-like hooks with perfect TypeScript inference\n */\n\nimport { isReactiveState } from './reactive';\nimport { toKebab } from './helpers';\nimport { devWarn, devError } from './logger';\nimport { isDiscoveryRender as _isDiscoveryRenderFn } from './discovery-state';\nimport { sanitizeCSS, minifyCSS } from './css-utils';\nimport type { JITCSSOptions } from './style';\nimport { captureGlobalStyleForSSR } from './ssr-context';\n\n// Re-export JITCSSOptions as a type-only re-export so consumers can still\n// import it from './runtime/hooks' without creating a runtime dependency on style.ts.\nexport type { JITCSSOptions };\n\n// Re-export discovery helpers so consumers continue to use the same import path.\nexport { beginDiscoveryRender, endDiscoveryRender } from './discovery-state';\n\n/**\n * Returns true while a discovery render is in progress.\n * Used by `html` and other primitives to short-circuit side effects.\n * @internal\n */\nexport function isDiscoveryRender(): boolean {\n return _isDiscoveryRenderFn();\n}\n\n// Global state to track current component context during render\n// Narrowed internal type for currentComponentContext to expose _hookCallbacks\ninterface InternalHookCallbacks {\n onConnected?: Array<(context?: unknown) => void>;\n onDisconnected?: Array<(context?: unknown) => void>;\n onAttributeChanged?: Array<\n (name: string, oldValue: string | null, newValue: string | null) => void\n >;\n onError?: Array<(err: unknown) => void>;\n props?: Record<string, unknown>;\n style?: () => string;\n expose?: Record<string, unknown>;\n}\n\ntype InternalComponentContext = Record<string, unknown> & {\n _hookCallbacks?: InternalHookCallbacks;\n _computedStyle?: string;\n};\n\nlet currentComponentContext: InternalComponentContext | null = null;\n\n/** Symbol key used to store provides map on a component's context object. */\nconst PROVIDES_KEY = Symbol('cer:provides');\n\n/**\n * Set the current component context (called internally during render)\n * @internal\n */\nexport function setCurrentComponentContext(\n context: Record<string, unknown>,\n): void {\n currentComponentContext = context;\n}\n\n/**\n * Clear the current component context (called internally after render)\n * @internal\n */\nexport function clearCurrentComponentContext(): void {\n currentComponentContext = null;\n}\n\n// ---------- Discovery render probe ----------\n// The actual state and helpers live in discovery-state.ts to avoid\n// circular dependencies with reactive.ts. The re-exports above forward\n// beginDiscoveryRender / endDiscoveryRender / isDiscoveryRender from that\n// module so all existing import sites remain unchanged.\n\n/**\n * Get the current component context. Useful for advanced composable patterns\n * that need to access or pass the context explicitly.\n * @internal\n */\nexport function getCurrentComponentContext(): Record<string, unknown> | null {\n return currentComponentContext;\n}\n\n/**\n * Get the emit function for the current component\n * Must be called during component render\n *\n * @example\n * ```ts\n * component('my-button', () => {\n * const { label } = useProps({ label: 'Click me' });\n * const emit = useEmit();\n *\n * return html`\n * <button @click=\"${() => emit('button-click', { label })}\">\n * ${label}\n * </button>\n * `;\n * });\n * ```\n */\nexport function useEmit(): (\n eventName: string,\n detail?: unknown,\n options?: CustomEventInit,\n) => boolean {\n if (!currentComponentContext) {\n throw new Error('useEmit must be called during component render');\n }\n\n // During discovery render, return a no-op function — no real host exists.\n if (_isDiscoveryRenderFn()) {\n return () => false;\n }\n\n // Capture and validate the emit function from the current context\n const emitCandidate = (currentComponentContext as { emit?: unknown }).emit;\n if (typeof emitCandidate !== 'function') {\n throw new Error(\n 'useEmit requires an emit function on the component context',\n );\n }\n const emitFn = emitCandidate as (\n eventName: string,\n detail?: unknown,\n options?: CustomEventInit,\n ) => boolean;\n\n return (eventName: string, detail?: unknown, options?: CustomEventInit) => {\n return emitFn(eventName, detail, options);\n };\n}\n\n/**\n * Initialize hook callbacks storage on context if not exists\n * Uses Object.defineProperty to avoid triggering reactive updates\n */\nfunction ensureHookCallbacks(context: Record<string, unknown>): void {\n if (!context._hookCallbacks) {\n Object.defineProperty(context, '_hookCallbacks', {\n value: {},\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n}\n\n/**\n * Register a callback to be called when component is connected to DOM\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * useOnConnected(() => {\n * console.log('Component mounted!');\n * });\n *\n * return html`<div>Hello World</div>`;\n * });\n * ```\n */\nexport function useOnConnected(callback: () => void): void {\n if (!currentComponentContext) {\n throw new Error('useOnConnected must be called during component render');\n }\n\n // During discovery render, skip registering lifecycle callbacks — the\n // discoveryContext is ephemeral and its hooks are never invoked.\n if (_isDiscoveryRenderFn()) return;\n\n ensureHookCallbacks(currentComponentContext as InternalComponentContext);\n const hooks = currentComponentContext._hookCallbacks as InternalHookCallbacks;\n if (!hooks.onConnected) hooks.onConnected = [];\n hooks.onConnected.push(callback);\n}\n\n/**\n * Register a callback to be called when component is disconnected from DOM\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * useOnDisconnected(() => {\n * console.log('Component unmounted!');\n * });\n *\n * return html`<div>Goodbye World</div>`;\n * });\n * ```\n */\nexport function useOnDisconnected(callback: () => void): void {\n if (!currentComponentContext) {\n throw new Error('useOnDisconnected must be called during component render');\n }\n\n // During discovery render, skip registering lifecycle callbacks.\n if (_isDiscoveryRenderFn()) return;\n\n ensureHookCallbacks(currentComponentContext as InternalComponentContext);\n const hooks = currentComponentContext._hookCallbacks as InternalHookCallbacks;\n if (!hooks.onDisconnected) hooks.onDisconnected = [];\n hooks.onDisconnected.push(callback);\n}\n\n/**\n * Register a callback to be called when an attribute changes\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * useOnAttributeChanged((name, oldValue, newValue) => {\n * console.log(`Attribute ${name} changed from ${oldValue} to ${newValue}`);\n * });\n *\n * return html`<div>Attribute watcher</div>`;\n * });\n * ```\n */\nexport function useOnAttributeChanged(\n callback: (\n name: string,\n oldValue: string | null,\n newValue: string | null,\n ) => void,\n): void {\n if (!currentComponentContext) {\n throw new Error(\n 'useOnAttributeChanged must be called during component render',\n );\n }\n\n // During discovery render, skip registering lifecycle callbacks.\n if (_isDiscoveryRenderFn()) return;\n\n ensureHookCallbacks(currentComponentContext as InternalComponentContext);\n const hooks = currentComponentContext._hookCallbacks as InternalHookCallbacks;\n if (!hooks.onAttributeChanged) hooks.onAttributeChanged = [];\n hooks.onAttributeChanged.push(callback);\n}\n\n/**\n * Register a callback to be called when an error occurs\n *\n * @example\n * ```ts\n * component('my-component', () => {\n * useOnError((error) => {\n * console.error('Component error:', error);\n * });\n *\n * return html`<div>Error handler</div>`;\n * });\n * ```\n */\nexport function useOnError(callback: (error: Error) => void): void {\n if (!currentComponentContext) {\n throw new Error('useOnError must be called during component render');\n }\n\n // During discovery render, skip registering lifecycle callbacks.\n if (_isDiscoveryRenderFn()) return;\n\n ensureHookCallbacks(currentComponentContext as InternalComponentContext);\n const hooks = currentComponentContext._hookCallbacks as InternalHookCallbacks;\n if (!hooks.onError) hooks.onError = [];\n // Wrap to normalize to Error. If the user's handler itself throws, log it in\n // dev mode so it doesn't vanish silently — the original error is already handled.\n hooks.onError.push((err: unknown) => {\n try {\n if (err instanceof Error) callback(err);\n else callback(new Error(String(err)));\n } catch (handlerErr) {\n devError('[useOnError] The error handler itself threw an exception:', handlerErr);\n }\n });\n}\n\n/**\n * Register prop defaults for the component. Can be called during render.\n * Stores the prop defaults on `context._hookCallbacks.props` so the runtime\n * can pick them up when building the component config.\n *\n * Example:\n * ```ts\n * component('my-comp', () => {\n * useProps({ modelValue: false, label: 'Hello' });\n * return html`<div/>`;\n * });\n * ```\n */\nexport function useProps<T extends Record<string, unknown>>(defaults: T): T {\n if (!currentComponentContext) {\n throw new Error('useProps must be called during component render');\n }\n\n ensureHookCallbacks(currentComponentContext as InternalComponentContext);\n const hooks = currentComponentContext._hookCallbacks as InternalHookCallbacks;\n hooks.props = {\n ...(hooks.props || {}),\n ...defaults,\n };\n\n const ctx = currentComponentContext;\n // Define dynamic getters for declared props so the context property\n // always reflects the host element's property (or reactive ref.value)\n try {\n const declaredKeys = Object.keys(defaults || {});\n for (const key of declaredKeys) {\n if (typeof key !== 'string' || key.startsWith('_')) continue;\n const existing = Object.getOwnPropertyDescriptor(ctx, key);\n // Only define if not present or configurable (allow overriding)\n if (existing && !existing.configurable) continue;\n try {\n // Preserve any existing concrete value on the context in a closure.\n // This avoids recursive getters when we later reference ctx[key].\n const hasOwn = Object.prototype.hasOwnProperty.call(ctx, key);\n let localValue: unknown = hasOwn\n ? (ctx as Record<string, unknown>)[key]\n : undefined;\n\n Object.defineProperty(ctx, key, {\n configurable: true,\n enumerable: true,\n get() {\n try {\n const host = (ctx && (ctx as { _host?: HTMLElement })._host) as\n | HTMLElement\n | undefined;\n if (host) {\n // First, check for attribute value (attributes should take precedence)\n const kebabKey = toKebab(key);\n const attrValue = host.getAttribute(kebabKey);\n if (attrValue !== null) {\n const defaultType = typeof defaults[key];\n if (defaultType === 'boolean') {\n // Standalone boolean attributes have empty string value\n return attrValue === '' || attrValue === 'true';\n }\n if (defaultType === 'number') {\n return Number(attrValue);\n }\n return attrValue;\n }\n\n // If no attribute, check if host has a property value set\n if (\n typeof (host as unknown as Record<string, unknown>)[key] !==\n 'undefined'\n ) {\n const fromHost = (host as unknown as Record<string, unknown>)[\n key\n ];\n // prefer host value when present\n // If the host provided a ReactiveState instance or a wrapper\n // with a .value, unwrap it here so destructured props and\n // useProps return the primitive/current value consistently.\n if (isReactiveState(fromHost)) {\n return (fromHost as { value: unknown }).value;\n }\n if (\n fromHost &&\n typeof fromHost === 'object' &&\n 'value' in fromHost &&\n !(typeof Node !== 'undefined' && fromHost instanceof Node)\n ) {\n return (fromHost as { value?: unknown }).value;\n }\n // For string-typed declared props, avoid returning host\n // object-like properties (for example `element.style` which\n // is a CSSStyleDeclaration). Prefer attribute value or the\n // local default instead of returning a non-primitive host\n // property into templates which expect primitives.\n const defaultType = typeof defaults[key];\n if (\n defaultType === 'string' &&\n fromHost &&\n typeof fromHost === 'object'\n ) {\n // fallthrough to localValue\n } else {\n // For boolean defaults, treat empty string (standalone attribute) or 'true' as true.\n if (\n defaultType === 'boolean' &&\n typeof fromHost === 'string'\n ) {\n return fromHost === '' || fromHost === 'true';\n }\n return fromHost;\n }\n }\n }\n } catch {\n // ignore host read failures and fall back to context\n }\n return localValue;\n },\n set(v: unknown) {\n // allow test/runtime code to set context props during render/init\n localValue = v;\n },\n });\n } catch {\n // ignore\n }\n }\n } catch {\n // ignore\n }\n // Return a Proxy that always reads the latest value from the component\n // context so accesses are reactive. Also unwrap functional refs ({ value })\n // and coerce string attribute values to boolean/number when defaults\n // indicate such types.\n const result = new Proxy({} as Record<string, unknown>, {\n get(_target, prop: string) {\n if (typeof prop !== 'string') return undefined;\n const def = (defaults as Record<string, unknown>)[prop];\n\n // If a host element is available, prefer reading from attributes first,\n // then from properties. This ensures that HTML attributes take precedence\n // over default property values (like the standard \"title\" attribute).\n try {\n const host = (ctx && (ctx as { _host?: HTMLElement })._host) as\n | HTMLElement\n | undefined;\n if (host) {\n // Check attribute first (only if host is an actual HTMLElement)\n if (\n (typeof HTMLElement !== 'undefined' && host instanceof HTMLElement) ||\n (typeof (host as { getAttribute?: (name: string) => string | null })\n .getAttribute === 'function' &&\n typeof (host as { hasAttribute?: (name: string) => boolean })\n .hasAttribute === 'function')\n ) {\n const kebabKey = prop.replace(/([A-Z])/g, '-$1').toLowerCase();\n const attrValue = (\n host as { getAttribute: (name: string) => string | null }\n ).getAttribute(kebabKey);\n if (attrValue !== null) {\n // Attribute exists - convert based on default type\n if (typeof def === 'boolean') {\n return attrValue === '' || attrValue === 'true';\n }\n if (typeof def === 'number') {\n return Number(attrValue);\n }\n return attrValue;\n }\n }\n\n // No attribute - check property value\n const hostValue = (host as unknown as Record<string, unknown>)[prop];\n // Only use host value if it's explicitly set (not undefined AND not empty string for string defaults)\n // Empty strings on standard HTML properties (like 'title') should fall through to defaults\n if (typeof hostValue !== 'undefined' && hostValue !== '') {\n // If the declared default is a string, avoid returning raw DOM\n // object-like properties (such as element.style which is a CSSStyleDeclaration)\n // since templates expect primitives and serializing objects can\n // cause DOMExceptions. However, wrapper-like objects that expose\n // a `.value` property (or ReactiveState instances) should be\n // unwrapped and returned even for string defaults.\n const isWrapperLike =\n hostValue &&\n typeof hostValue === 'object' &&\n 'value' in hostValue &&\n !(typeof Node !== 'undefined' && hostValue instanceof Node);\n if (\n typeof def === 'string' &&\n hostValue &&\n typeof hostValue === 'object' &&\n !isWrapperLike &&\n !isReactiveState(hostValue)\n ) {\n // treat as not present and fall through to ctx/default\n } else {\n // Special handling for boolean props: if default is false and hostValue is empty string,\n // treat it as if the property wasn't set (use default false)\n if (\n typeof def === 'boolean' &&\n def === false &&\n hostValue === ''\n ) {\n return def;\n }\n\n // Unwrap ReactiveState instances and wrapper-like objects coming\n // from the host so useProps mirrors applyProps/destructured props\n // behavior and returns primitive/current values.\n if (isReactiveState(hostValue)) {\n return (hostValue as { value: unknown }).value;\n }\n if (isWrapperLike) {\n return (hostValue as { value: unknown }).value;\n }\n\n // Primitive on host - return directly (but coerce strings if default provided).\n // Use the same rule as the attribute path: empty string (standalone attribute\n // presence) or the literal string 'true' coerce to true; everything else is false.\n if (typeof def === 'boolean' && typeof hostValue === 'string') {\n return hostValue === '' || hostValue === 'true';\n }\n if (\n typeof def === 'number' &&\n typeof hostValue === 'string' &&\n !Number.isNaN(Number(hostValue))\n )\n return Number(hostValue);\n return hostValue;\n }\n }\n }\n } catch {\n // ignore host read failures and fall back to context\n }\n\n // Fall back to reading from the component context itself.\n const raw = ctx[prop];\n // Treat empty-string on context as boolean true (attribute presence)\n // EXCEPT when the default is false - in that case, empty string means \"not set\"\n if (typeof def === 'boolean' && raw === '') {\n if (def === false) {\n // For boolean props with default false, empty string means use the default\n return def;\n }\n // For boolean props with default true, empty string means attribute presence = true\n return true;\n }\n // If the context stores a ReactiveState or wrapper, unwrap it here\n // so components using useProps receive the primitive/current value\n // when the source is the component context itself. Host-provided\n // ReactiveState instances are preserved above; this path is only\n // for ctx values and defaults.\n if (isReactiveState(raw)) return (raw as { value: unknown }).value;\n if (\n raw &&\n typeof raw === 'object' &&\n 'value' in raw &&\n !(typeof Node !== 'undefined' && raw instanceof Node)\n )\n return (raw as { value: unknown }).value;\n if (raw != null && raw !== '') {\n if (typeof def === 'boolean' && typeof raw === 'string') {\n return raw === 'true';\n }\n if (\n typeof def === 'number' &&\n typeof raw === 'string' &&\n !Number.isNaN(Number(raw))\n )\n return Number(raw);\n return raw;\n }\n return def;\n },\n has(_target, prop: string) {\n return typeof prop === 'string' && (prop in ctx || prop in defaults);\n },\n ownKeys() {\n return Array.from(\n new Set([...Object.keys(defaults), ...Object.keys(ctx || {})]),\n );\n },\n getOwnPropertyDescriptor() {\n return { configurable: true, enumerable: true } as PropertyDescriptor;\n },\n });\n\n return result as T;\n}\n\n/**\n * Register prop defaults and return a stable props object for use inside render.\n * The returned object reads values from the current component context at render\n * time and falls back to the provided defaults. This keeps prop access stable\n * in production builds and avoids reliance on parsing the render function.\n *\n * Must be called during render. Example:\n * const props = useProps({ modelValue: false });\n */\n// (useProps now returns the props object directly)\n\n/**\n * Register a style function that will be called during each render\n * to provide reactive styles for the component\n *\n * @example\n * ```ts\n * import { css } from '@lib/style';\n *\n * component('my-component', () => {\n * const { theme } = useProps({ theme: 'light' });\n *\n * useStyle(() => css`\n * :host {\n * background: ${theme === 'light' ? 'white' : 'black'};\n * color: ${theme === 'light' ? 'black' : 'white'};\n * }\n * `);\n *\n * return html`<div>Styled component</div>`;\n * });\n * ```\n */\nexport function useStyle(callback: () => string): void {\n if (!currentComponentContext) {\n throw new Error('useStyle must be called during component render');\n }\n\n // During discovery render, skip style computation — no real DOM to style.\n if (_isDiscoveryRenderFn()) return;\n\n ensureHookCallbacks(currentComponentContext);\n\n // Execute the callback immediately during render to capture the current style\n // This ensures reactive state is read during the render phase, not during style application\n try {\n const computedStyle = callback();\n\n // Store the computed style using Object.defineProperty to avoid triggering reactive updates\n Object.defineProperty(currentComponentContext, '_computedStyle', {\n value: computedStyle,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n } catch (error) {\n devWarn('Error in useStyle callback:', error);\n Object.defineProperty(currentComponentContext, '_computedStyle', {\n value: '',\n writable: true,\n enumerable: false,\n configurable: true,\n });\n }\n}\n\n/**\n * Cache of globally-injected stylesheets keyed by their CSS content.\n * Prevents duplicate `<style>` injections when the same `useGlobalStyle()`\n * factory runs across multiple component instances.\n */\nconst _globalStyleSheets = new Map<string, CSSStyleSheet>();\n\n/**\n * Inject CSS into `document.adoptedStyleSheets`, escaping the Shadow DOM\n * boundary. Suitable for `@font-face` declarations, `:root` variable overrides,\n * and global scroll/scroll-bar styling. Deduplicated by CSS content so calling\n * this in multiple component instances is safe.\n *\n * **Use sparingly** — this intentionally breaks Shadow DOM encapsulation.\n * A dev-mode warning is emitted to make the escape hatch visible.\n *\n * @example\n * ```ts\n * component('app-root', () => {\n * useGlobalStyle(() => css`\n * @font-face {\n * font-family: 'Inter';\n * src: url('/fonts/inter.woff2') format('woff2');\n * }\n * :root {\n * --app-font: 'Inter', sans-serif;\n * }\n * `);\n * return html`<slot></slot>`;\n * });\n * ```\n */\nexport function useGlobalStyle(styleFactory: () => string): void {\n let raw: string;\n try {\n raw = styleFactory();\n } catch {\n return;\n }\n\n // SSR collection pass: when an active collector exists (set up by\n // beginSSRGlobalStyleCollection in ssr.ts), capture here and skip DOM\n // injection regardless of whether document is available. This correctly\n // handles both Node.js SSR (no document) and test environments (document\n // present via happy-dom/jsdom) that call renderToStringWithJITCSS.\n if (captureGlobalStyleForSSR(raw)) return;\n\n if (typeof document === 'undefined' || typeof CSSStyleSheet === 'undefined') {\n // SSR without an active collector — nothing to do.\n return;\n }\n devWarn(\n '[useGlobalStyle] Injecting global styles from a component. ' +\n 'This escapes Shadow DOM encapsulation — use sparingly.',\n );\n const style = minifyCSS(sanitizeCSS(raw!));\n if (!style || _globalStyleSheets.has(style)) return;\n try {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(style);\n document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];\n _globalStyleSheets.set(style, sheet);\n } catch {\n // Fallback: inject a <style> element in <head>\n const el = document.createElement('style');\n el.textContent = style;\n (document.head ?? document.documentElement).appendChild(el);\n }\n}\n\n/**\n * Design token definitions accepted by `useDesignTokens()`.\n * Map high-level token names to CSS custom property overrides.\n */\nexport interface DesignTokens {\n /** Override the primary color scale root (sets --cer-color-primary-500) */\n primary?: string;\n /** Override the secondary color scale root */\n secondary?: string;\n /** Override the neutral color scale root */\n neutral?: string;\n /** Override the success color root */\n success?: string;\n /** Override the info color root */\n info?: string;\n /** Override the warning color root */\n warning?: string;\n /** Override the error color root */\n error?: string;\n /** Override the sans-serif font family */\n fontSans?: string;\n /** Override the serif font family */\n fontSerif?: string;\n /** Override the monospace font family */\n fontMono?: string;\n /** Additional arbitrary CSS custom property overrides */\n [key: string]: string | undefined;\n}\n\n/**\n * Apply design tokens to `:host` as CSS custom property overrides.\n * Must be called during component render. This is a typed, validated\n * alternative to writing `useStyle(() => css\\`:host { ... }\\`)` by hand.\n *\n * Semantic color tokens (e.g. `primary: '#6366f1'`) set the `*-500` shade\n * for that scale. Use arbitrary `'--cer-color-primary-500'` keys to override\n * individual shades.\n *\n * @example\n * ```ts\n * component('app-root', () => {\n * useDesignTokens({\n * primary: '#6366f1',\n * fontSans: '\"Inter\", sans-serif',\n * '--cer-color-neutral-900': '#0a0a0a',\n * });\n * return html`<slot></slot>`;\n * });\n * ```\n */\nexport function useDesignTokens(tokens: DesignTokens): void {\n if (!currentComponentContext) {\n throw new Error('useDesignTokens must be called during component render');\n }\n\n if (_isDiscoveryRenderFn()) return;\n\n const declarations: string[] = [];\n const semanticColorMap: Record<string, string> = {\n primary: '--cer-color-primary-500',\n secondary: '--cer-color-secondary-500',\n neutral: '--cer-color-neutral-500',\n success: '--cer-color-success-500',\n info: '--cer-color-info-500',\n warning: '--cer-color-warning-500',\n error: '--cer-color-error-500',\n };\n const fontMap: Record<string, string> = {\n fontSans: '--cer-font-sans',\n fontSerif: '--cer-font-serif',\n fontMono: '--cer-font-mono',\n };\n\n for (const [key, value] of Object.entries(tokens)) {\n if (value === undefined) continue;\n if (key in semanticColorMap) {\n declarations.push(`${semanticColorMap[key]}:${value}`);\n } else if (key in fontMap) {\n declarations.push(`${fontMap[key]}:${value}`);\n } else if (key.startsWith('--')) {\n declarations.push(`${key}:${value}`);\n }\n }\n\n if (declarations.length === 0) return;\n\n const cssText = `:host{${declarations.join(';')}}`;\n\n // Append to any existing computed style\n const ctx = currentComponentContext as { _computedStyle?: string };\n const existing = ctx._computedStyle ?? '';\n const combined = existing ? `${existing}\\n${cssText}` : cssText;\n\n Object.defineProperty(currentComponentContext, '_computedStyle', {\n value: combined,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n}\n\n// ---------- provide / inject ----------\n\n/**\n * Store a value under a key so that descendant components can retrieve it\n * with `inject()`. Must be called during component render.\n *\n * @example\n * ```ts\n * component('theme-provider', () => {\n * provide('theme', 'dark');\n * return html`<slot></slot>`;\n * });\n * ```\n */\nexport function provide<T>(key: string | symbol, value: T): void {\n if (!currentComponentContext) {\n throw new Error('provide must be called during component render');\n }\n\n // During discovery render, skip provide — the ephemeral context is discarded.\n if (_isDiscoveryRenderFn()) return;\n\n const ctx = currentComponentContext as Record<string | symbol, unknown>;\n if (!ctx[PROVIDES_KEY]) {\n Object.defineProperty(ctx, PROVIDES_KEY, {\n value: new Map<string | symbol, unknown>(),\n writable: false,\n enumerable: false,\n configurable: true,\n });\n }\n (ctx[PROVIDES_KEY] as Map<string | symbol, unknown>).set(key, value);\n}\n\n/**\n * Retrieve a value provided by an ancestor component. Traverses the shadow\n * DOM tree upward through ShadowRoot host elements looking for the nearest\n * `provide()` call with the matching key. Returns `defaultValue` (or\n * `undefined`) when no provider is found. Must be called during render.\n *\n * @example\n * ```ts\n * component('themed-button', () => {\n * const theme = inject<string>('theme', 'light');\n * return html`<button class=\"btn-${theme}\">Click</button>`;\n * });\n * ```\n */\nexport function inject<T>(\n key: string | symbol,\n defaultValue?: T,\n): T | undefined {\n if (!currentComponentContext) {\n throw new Error('inject must be called during component render');\n }\n\n // During discovery render, the host tree is not yet mounted — return the\n // default value to allow prop detection to continue without DOM traversal.\n if (_isDiscoveryRenderFn()) return defaultValue;\n\n try {\n const host = (currentComponentContext as { _host?: HTMLElement })._host;\n if (host) {\n let node: Node | null = host.parentNode as Node | null;\n if (!node) node = host.getRootNode() as Node | null;\n\n // Depth counter prevents infinite loops in detached subtrees where\n // getRootNode() may return a subtree root instead of `document`.\n let depth = 0;\n const MAX_DEPTH = 50;\n\n while (node && depth < MAX_DEPTH) {\n depth++;\n if (typeof ShadowRoot !== 'undefined' && node instanceof ShadowRoot) {\n const shadowHost = node.host;\n const hostCtx = (\n shadowHost as unknown as {\n context?: Record<string | symbol, unknown>;\n }\n ).context;\n if (hostCtx) {\n const provides = hostCtx[PROVIDES_KEY] as\n | Map<string | symbol, unknown>\n | undefined;\n if (provides?.has(key)) {\n return provides.get(key) as T;\n }\n }\n const next: Node | null = shadowHost.parentNode as Node | null;\n node = next ?? (shadowHost.getRootNode() as Node | null);\n if (node === document || node === shadowHost) break;\n } else {\n // Also check light-DOM ancestor elements that may be custom components\n // with provides (e.g. a consumer that is a slotted child of a provider).\n if (typeof Element !== 'undefined' && node instanceof Element) {\n const elCtx = (\n node as unknown as {\n context?: Record<string | symbol, unknown>;\n }\n ).context;\n if (elCtx) {\n const provides = elCtx[PROVIDES_KEY] as\n | Map<string | symbol, unknown>\n | undefined;\n if (provides?.has(key)) {\n return provides.get(key) as T;\n }\n }\n }\n const prevNode = node;\n const next: Node | null = (node as Node).parentNode as Node | null;\n node = next ?? ((node as Node).getRootNode?.() as Node | null);\n // Guard against infinite loops: if getRootNode() returns the same\n // node (disconnected element with no ancestors), stop traversal.\n if (node === document || node === prevNode) break;\n }\n }\n }\n } catch {\n // ignore traversal errors - fall through to default\n }\n\n return defaultValue;\n}\n\n// ---------- createComposable ----------\n\n/**\n * Execute a function that calls hooks (useOnConnected, useOnDisconnected, etc.)\n * using an explicit component context rather than requiring the call to happen\n * directly inside a render function. This enables composable utility functions\n * that register lifecycle callbacks from outside the render body.\n *\n * @example\n * ```ts\n * function useLogger(label: string) {\n * return createComposable(() => {\n * useOnConnected(() => console.log(`${label} connected`));\n * useOnDisconnected(() => console.log(`${label} disconnected`));\n * });\n * }\n *\n * component('my-comp', () => {\n * const stopLogger = useLogger('my-comp');\n * stopLogger(context); // pass the component context explicitly\n * return html`<div>Hello</div>`;\n * });\n * ```\n *\n * More commonly, use it as a direct wrapper inside render:\n * ```ts\n * component('my-comp', () => {\n * // Accepts context automatically from getCurrentComponentContext()\n * createComposable(() => {\n * useOnConnected(() => console.log('connected from composable'));\n * })();\n * return html`<div>Hello</div>`;\n * });\n * ```\n */\nexport function createComposable<T>(\n fn: () => T,\n): (ctx?: Record<string, unknown>) => T {\n return (ctx?: Record<string, unknown>) => {\n const targetCtx = ctx ?? currentComponentContext;\n if (!targetCtx) {\n throw new Error(\n 'createComposable: no component context available. Pass a context explicitly or call inside a render function.',\n );\n }\n\n const prev = currentComponentContext;\n setCurrentComponentContext(targetCtx);\n try {\n return fn();\n } finally {\n // Restore the previous context (supports nested composables)\n if (prev) {\n setCurrentComponentContext(prev);\n } else {\n clearCurrentComponentContext();\n }\n }\n };\n}\n\n/**\n * Expose a public interface from the current component so that parent\n * components holding a template ref to this element can call its methods\n * or read its properties. Must be called during component render.\n *\n * @example\n * ```ts\n * component('my-counter', () => {\n * const count = ref(0);\n * useExpose({ increment: () => count.value++, get count() { return count.value; } });\n * return html`<div>${count.value}</div>`;\n * });\n *\n * // Parent: counterRef.value.increment()\n * ```\n */\nexport function useExpose<T extends Record<string, unknown>>(exposed: T): void {\n if (!currentComponentContext) {\n throw new Error('useExpose must be called during component render');\n }\n\n // During discovery render, skip — no real host to expose properties on\n if (_isDiscoveryRenderFn()) return;\n\n ensureHookCallbacks(currentComponentContext);\n const hooks = currentComponentContext._hookCallbacks as InternalHookCallbacks;\n hooks.expose = { ...(hooks.expose ?? {}), ...exposed };\n\n // Apply exposed properties onto the host element immediately if available\n const host = (currentComponentContext as { _host?: HTMLElement })._host;\n if (host) {\n for (const [key, value] of Object.entries(exposed)) {\n try {\n (host as unknown as Record<string, unknown>)[key] = value;\n } catch {\n // ignore non-writable properties\n }\n }\n }\n}\n\n/**\n * Access named slots provided to the current component. Returns helpers to\n * check slot presence and retrieve slotted elements. Must be called during\n * component render.\n *\n * @example\n * ```ts\n * component('my-card', () => {\n * const slots = useSlots();\n * return html`\n * <div class=\"card\">\n * <slot></slot>\n * ${slots.has('footer') ? html`<footer><slot name=\"footer\"></slot></footer>` : ''}\n * </div>\n * `;\n * });\n * ```\n */\nexport function useSlots(): {\n has(name?: string): boolean;\n getNodes(name?: string): Element[];\n names(): string[];\n} {\n if (!currentComponentContext) {\n throw new Error('useSlots must be called during component render');\n }\n\n // During discovery render, return empty no-op slot object\n if (_isDiscoveryRenderFn()) {\n return { has: () => false, getNodes: () => [], names: () => [] };\n }\n\n const host = (currentComponentContext as { _host?: HTMLElement })._host;\n\n // Single-pass collection: group children by slot name once, reuse for all methods.\n const getSlotMap = (): Map<string, Element[]> => {\n const map = new Map<string, Element[]>();\n if (!host) return map;\n for (const child of host.children) {\n const key = child.getAttribute('slot') ?? 'default';\n const bucket = map.get(key);\n if (bucket) {\n bucket.push(child);\n } else {\n map.set(key, [child]);\n }\n }\n return map;\n };\n\n return {\n /**\n * Returns true if the named slot (or the default slot when name is\n * omitted) has at least one slotted child element.\n */\n has(name?: string): boolean {\n if (!host) return false;\n const slotName = !name || name === 'default' ? 'default' : name;\n const bucket = getSlotMap().get(slotName);\n return bucket !== undefined && bucket.length > 0;\n },\n /**\n * Returns all child elements assigned to the named slot (or the default\n * slot when name is omitted).\n */\n getNodes(name?: string): Element[] {\n if (!host) return [];\n const slotName = !name || name === 'default' ? 'default' : name;\n return getSlotMap().get(slotName) ?? [];\n },\n /** Returns the names of all slots that have content, including 'default'. */\n names(): string[] {\n if (!host) return [];\n return Array.from(getSlotMap().keys());\n },\n };\n}\n\n/**\n * A writable ref that reads from a component prop and emits `update:<propName>`\n * when its value is set, enabling two-way binding with a parent's `:model` or\n * `:model:<propName>` directive.\n *\n * Also recognised by the vdom `:model` directive as a reactive value so it can\n * be passed directly to native inputs inside the child template.\n */\nexport interface ModelRef<T> {\n /** The current prop value. Reactive — reads trigger re-renders. */\n value: T;\n}\n\n/**\n * Define a two-way binding model for a component prop, similar to Vue's\n * `defineModel()`. It combines `useProps` + `useEmit` into a single ergonomic\n * API so child components don't need to wire the plumbing manually.\n *\n * The returned `ModelRef` object:\n * - **reads** `.value` → returns the current prop value (reactive)\n * - **writes** `.value = x` → emits `update:<propName>` so the parent's\n * `:model` / `:model:<propName>` directive can update its reactive state\n *\n * The object is also recognised by the vdom `:model` directive, so you can\n * pass it directly to a native input's `:model` binding inside the child\n * template and the two-way sync is wired up automatically.\n *\n * @example\n * ```ts\n * // Default model — maps to the parent's :model=\"...\"\n * component('my-input', () => {\n * const model = defineModel('');\n *\n * return html`\n * <input :model=\"${model}\" />\n * `;\n * });\n *\n * // Named model — maps to the parent's :model:title=\"...\"\n * component('my-field', () => {\n * const title = defineModel('title', '');\n * const count = defineModel('count', 0);\n *\n * return html`\n * <input :model=\"${title}\" />\n * <input type=\"number\" :model=\"${count}\" />\n * `;\n * });\n * ```\n *\n * @param args - Either:\n * - No arguments → `modelValue` prop, no default.\n * - One argument → treated as the **default value** for the `modelValue` prop;\n * type is inferred from the value.\n * - Two arguments → first is the **prop name**, second is the **default value**;\n * type is inferred from the default value.\n */\nexport function defineModel<T = unknown>(): ModelRef<T | undefined>;\nexport function defineModel<T>(defaultValue: T): ModelRef<T>;\nexport function defineModel<T>(propName: string, defaultValue: T): ModelRef<T>;\nexport function defineModel<T = unknown>(\n ...args: [] | [T] | [string, T]\n): ModelRef<T | undefined> {\n if (!currentComponentContext) {\n throw new Error('defineModel must be called during component render');\n }\n\n const propName = args.length === 2 ? (args[0] as string) : 'modelValue';\n const initialDefault =\n args.length === 2\n ? (args[1] as T)\n : args.length === 1\n ? (args[0] as T)\n : undefined;\n\n // Register the prop so the runtime discovers it during the discovery render\n // and includes it in the component's observed attributes / prop definitions.\n const props = useProps({\n [propName]: initialDefault,\n } as Record<string, unknown>);\n\n // Capture the emit function once — during a discovery render this is a no-op.\n const isDiscovery = _isDiscoveryRenderFn();\n const emitFn = isDiscovery\n ? null\n : (() => {\n const candidate = (currentComponentContext as { emit?: unknown }).emit;\n if (typeof candidate !== 'function') return null;\n return candidate as (\n eventName: string,\n detail?: unknown,\n options?: CustomEventInit,\n ) => boolean;\n })();\n\n // The model ref is marked with the ReactiveState symbol so that\n // processModelDirective treats it as a reactive value and wires up\n // `:model` on native inputs inside the child template correctly.\n const modelRef: ModelRef<T> = {\n get value(): T {\n return props[propName] as T;\n },\n set value(newValue: T) {\n if (emitFn) {\n emitFn(`update:${propName}`, newValue);\n }\n },\n };\n\n try {\n const key = Symbol.for('@cer/ReactiveState');\n Object.defineProperty(modelRef, key, {\n value: true,\n enumerable: false,\n configurable: false,\n });\n } catch {\n // ignore exotic runtimes\n }\n\n return modelRef;\n}\n"],"mappings":"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"}
|