@sigx/runtime-core 0.1.14 → 0.1.15

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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { B as defineProvide, D as isModel, G as getComponentMeta, J as onMounted, K as getCurrentInstance, L as defineDirective, O as defineApp, R as isDirective, T as createModelFromBinding, U as useAppContext, W as component, X as onUpdated, Y as onUnmounted, _ as Text, b as jsxs, f as Suspense, g as Fragment, m as lazy, n as CLIENT_DIRECTIVES, p as isLazyComponent, q as onCreated, r as CLIENT_DIRECTIVE_PREFIX, v as jsx, w as createModel, x as isComponent, y as jsxDEV, z as defineInjectable } from "./renderer-DCe0Y5hd.js";
1
+ import { B as defineProvide, D as isModel, G as getComponentMeta, J as onMounted, K as getCurrentInstance, L as defineDirective, O as defineApp, R as isDirective, T as createModelFromBinding, U as useAppContext, W as component, X as onUpdated, Y as onUnmounted, _ as Text, b as jsxs, f as Suspense, g as Fragment, m as lazy, n as CLIENT_DIRECTIVES, p as isLazyComponent, q as onCreated, r as CLIENT_DIRECTIVE_PREFIX, v as jsx, w as createModel, x as isComponent, y as jsxDEV, z as defineInjectable } from "./renderer-CTRfZytY.js";
2
2
  import { signal } from "@sigx/reactivity";
3
3
  function compound(main, sub) {
4
4
  return Object.assign(main, sub);
package/dist/internals.js CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as runInRequestScope, A as handleComponentError, C as setPlatformModelProcessor, E as getModelSymbol, F as setDefaultMount, H as provideAppContext, I as __DIRECTIVE__, K as getCurrentInstance, M as notifyComponentMounted, N as notifyComponentUnmounted, P as notifyComponentUpdated, Q as hasRequestIsolation, S as getPlatformModelProcessor, V as getAppContextToken, Z as setCurrentInstance, a as filterClientDirectives, c as serializeProps, d as createPropsAccessor, et as applyContextExtensions, h as registerPendingPromise, i as createEmit, j as notifyComponentCreated, k as getDefaultMount, l as normalizeSubTree, nt as registerComponentPlugin, o as getHydrationDirective, rt as registerContextExtension, s as hasClientDirective, t as createRenderer, tt as getComponentPlugins, u as createSlots } from "./renderer-DCe0Y5hd.js";
1
+ import { $ as runInRequestScope, A as handleComponentError, C as setPlatformModelProcessor, E as getModelSymbol, F as setDefaultMount, H as provideAppContext, I as __DIRECTIVE__, K as getCurrentInstance, M as notifyComponentMounted, N as notifyComponentUnmounted, P as notifyComponentUpdated, Q as hasRequestIsolation, S as getPlatformModelProcessor, V as getAppContextToken, Z as setCurrentInstance, a as filterClientDirectives, c as serializeProps, d as createPropsAccessor, et as applyContextExtensions, h as registerPendingPromise, i as createEmit, j as notifyComponentCreated, k as getDefaultMount, l as normalizeSubTree, nt as registerComponentPlugin, o as getHydrationDirective, rt as registerContextExtension, s as hasClientDirective, t as createRenderer, tt as getComponentPlugins, u as createSlots } from "./renderer-CTRfZytY.js";
2
2
  export { __DIRECTIVE__, applyContextExtensions, createEmit, createPropsAccessor, createRenderer, createSlots, filterClientDirectives, getAppContextToken, getComponentPlugins, getCurrentInstance, getDefaultMount, getHydrationDirective, getModelSymbol, getPlatformModelProcessor, handleComponentError, hasClientDirective, hasRequestIsolation, normalizeSubTree, notifyComponentCreated, notifyComponentMounted, notifyComponentUnmounted, notifyComponentUpdated, provideAppContext, registerComponentPlugin, registerContextExtension, registerPendingPromise, runInRequestScope, serializeProps, setCurrentInstance, setDefaultMount, setPlatformModelProcessor };
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAO,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgBxD;;GAEG;AACH,KAAK,iBAAiB,CAAC,CAAC,IAAI;IAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAAC;AAE3C;;GAEG;AACH,KAAK,eAAe,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG;IAC9E,8CAA8C;IAC9C,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,2CAA2C;IAC3C,MAAM,EAAE,IAAI,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,CAAC;CAC9C,CAAC;AAiBF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAerE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1D,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,GAC3B,oBAAoB,CAAC,CAAC,CAAC,CAuGzB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,QAAQ,2CA8EpB,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,GAAG,GAAG,SAAS,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAEtF"}
1
+ {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAO,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAexD;;GAEG;AACH,KAAK,iBAAiB,CAAC,CAAC,IAAI;IAAE,OAAO,EAAE,CAAC,CAAA;CAAE,CAAC;AAE3C;;GAEG;AACH,KAAK,eAAe,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG;IAC9E,8CAA8C;IAC9C,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,uCAAuC;IACvC,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,2CAA2C;IAC3C,MAAM,EAAE,IAAI,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,UAAU,GAAG,CAAC,MAAM,UAAU,CAAC,CAAC;CAC9C,CAAC;AAiBF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAerE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC1D,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,GAC3B,oBAAoB,CAAC,CAAC,CAAC,CAiHzB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,QAAQ,2CA8EpB,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,GAAG,GAAG,SAAS,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAEtF"}
@@ -1,4 +1,4 @@
1
- import { batch, detectAccess, effect, isComputed, signal, untrack } from "@sigx/reactivity";
1
+ import { detectAccess, effect, isComputed, signal, untrack } from "@sigx/reactivity";
2
2
  var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
3
3
  var plugins = [];
4
4
  function registerComponentPlugin(plugin) {
@@ -505,19 +505,26 @@ function lazy(loader) {
505
505
  if (!promise) promise = loader().then((mod) => {
506
506
  Component = "default" in mod ? mod.default : mod;
507
507
  state = "resolved";
508
- batch(() => {
509
- loadState.state = "resolved";
510
- loadState.tick++;
511
- });
508
+ loadState.state = "resolved";
509
+ loadState.tick++;
512
510
  return Component;
513
511
  }).catch((err) => {
514
512
  error = err instanceof Error ? err : new Error(String(err));
515
513
  state = "rejected";
516
- batch(() => {
514
+ loadState.state = "rejected";
515
+ loadState.tick++;
516
+ throw error;
517
+ });
518
+ else if (state === "pending") promise.then(() => {
519
+ if (loadState.state === "pending") {
520
+ loadState.state = "resolved";
521
+ loadState.tick++;
522
+ }
523
+ }).catch(() => {
524
+ if (loadState.state === "pending") {
517
525
  loadState.state = "rejected";
518
526
  loadState.tick++;
519
- });
520
- throw error;
527
+ }
521
528
  });
522
529
  if (state === "resolved" && Component) return () => {
523
530
  return jsx(Component, {});
@@ -1242,4 +1249,4 @@ function createRenderer(options) {
1242
1249
  }
1243
1250
  export { runInRequestScope as $, handleComponentError as A, defineProvide as B, setPlatformModelProcessor as C, isModel as D, getModelSymbol as E, setDefaultMount as F, getComponentMeta as G, provideAppContext as H, __DIRECTIVE__ as I, onMounted as J, getCurrentInstance as K, defineDirective as L, notifyComponentMounted as M, notifyComponentUnmounted as N, defineApp as O, notifyComponentUpdated as P, hasRequestIsolation as Q, isDirective as R, getPlatformModelProcessor as S, createModelFromBinding as T, useAppContext as U, getAppContextToken as V, component as W, onUpdated as X, onUnmounted as Y, setCurrentInstance as Z, Text as _, filterClientDirectives as a, jsxs as b, serializeProps as c, createPropsAccessor as d, applyContextExtensions as et, Suspense as f, Fragment as g, registerPendingPromise as h, createEmit as i, notifyComponentCreated as j, getDefaultMount as k, normalizeSubTree as l, lazy as m, CLIENT_DIRECTIVES as n, registerComponentPlugin as nt, getHydrationDirective as o, isLazyComponent as p, onCreated as q, CLIENT_DIRECTIVE_PREFIX as r, registerContextExtension as rt, hasClientDirective as s, createRenderer as t, getComponentPlugins as tt, createSlots as u, jsx as v, createModel as w, isComponent as x, jsxDEV as y, defineInjectable as z };
1244
1251
 
1245
- //# sourceMappingURL=renderer-DCe0Y5hd.js.map
1252
+ //# sourceMappingURL=renderer-CTRfZytY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer-CTRfZytY.js","names":[],"sources":["../src/plugins.ts","../__vite-browser-external","../src/async-context.ts","../src/component.ts","../src/di/injectable.ts","../src/directives.ts","../src/app.ts","../src/model.ts","../src/platform.ts","../src/utils/is-component.ts","../src/jsx-runtime.ts","../src/lazy.tsx","../src/utils/props-accessor.ts","../src/utils/slots.ts","../src/utils/normalize.ts","../src/hydration/index.ts","../src/renderer.ts"],"sourcesContent":["/**\r\n * Component plugin registry for runtime-core.\r\n * \r\n * This module has NO IMPORTS to ensure it's fully initialized before\r\n * any other module can import from it. This avoids circular dependency\r\n * issues with ES module initialization.\r\n */\r\n\r\n/**\r\n * Plugin system for components (used by HMR, DevTools, SSR, etc.)\r\n * Note: SetupFn type is duplicated here to avoid circular imports\r\n */\r\nexport type ComponentPlugin = {\r\n onDefine?: (name: string | undefined, factory: any, setup: Function) => void;\r\n};\r\n\r\nconst plugins: ComponentPlugin[] = [];\r\n\r\nexport function registerComponentPlugin(plugin: ComponentPlugin): void {\r\n plugins.push(plugin);\r\n}\r\n\r\n/**\r\n * Get all registered plugins (internal use)\r\n */\r\nexport function getComponentPlugins(): readonly ComponentPlugin[] {\r\n return plugins;\r\n}\r\n\r\n/**\r\n * Context extension system for adding properties to ComponentSetupContext\r\n * Used by SSR, DevTools, and other packages that need to extend the context\r\n */\r\ntype ContextExtension = (ctx: any) => void;\r\nconst contextExtensions: ContextExtension[] = [];\r\n\r\n/**\r\n * Register a function that will be called to extend every component context.\r\n * Extensions are called in order of registration.\r\n * \r\n * @example\r\n * ```ts\r\n * // In @sigx/server-renderer/client\r\n * registerContextExtension((ctx) => {\r\n * ctx.ssr = { load: () => {} };\r\n * });\r\n * ```\r\n */\r\nexport function registerContextExtension(extension: ContextExtension): void {\r\n contextExtensions.push(extension);\r\n}\r\n\r\n/**\r\n * Apply all registered context extensions to a context object.\r\n * Called internally by the renderer when creating component contexts.\r\n */\r\nexport function applyContextExtensions(ctx: any): void {\r\n for (const extension of contextExtensions) {\r\n extension(ctx);\r\n }\r\n}\r\n","module.exports = {}","/**\r\n * Async-safe context storage for SSR request isolation.\r\n *\r\n * On Node.js (server), uses AsyncLocalStorage to scope state per-request,\r\n * preventing cross-request contamination when concurrent requests share\r\n * the same process (e.g., async component setup with `await`).\r\n *\r\n * On browsers (client), falls back to simple module-level variables\r\n * since there's only ever one \"request\" in the browser.\r\n */\r\n\r\n// ============= Types =============\r\n\r\ninterface SSRRequestContext {\r\n /** Current component context (replaces module-level singleton) */\r\n currentComponentContext: any | null;\r\n /** Current suspense boundary */\r\n currentSuspenseBoundary: any | null;\r\n}\r\n\r\n// ============= Implementation =============\r\n\r\n/**\r\n * Try to load AsyncLocalStorage from Node.js.\r\n * Returns null in browser environments.\r\n */\r\nlet asyncLocalStorage: any = null;\r\n\r\ntry {\r\n // Use dynamic require-style check — bundlers will tree-shake this for browser builds\r\n if (typeof globalThis !== 'undefined' && typeof (globalThis as any).process !== 'undefined') {\r\n const nodeAsync = (globalThis as any).process?.versions?.node\r\n ? require('node:async_hooks')\r\n : null;\r\n if (nodeAsync?.AsyncLocalStorage) {\r\n asyncLocalStorage = new nodeAsync.AsyncLocalStorage();\r\n }\r\n }\r\n} catch {\r\n // Not in Node.js or AsyncLocalStorage not available — use fallback\r\n}\r\n\r\n// ============= Fallback (browser / older Node.js) =============\r\n\r\nlet _fallbackContext: SSRRequestContext = {\r\n currentComponentContext: null,\r\n currentSuspenseBoundary: null\r\n};\r\n\r\n// ============= Public API =============\r\n\r\n/**\r\n * Get the current request context.\r\n * Returns the AsyncLocalStorage store if available, otherwise the module-level fallback.\r\n */\r\nfunction getRequestContext(): SSRRequestContext {\r\n if (asyncLocalStorage) {\r\n const store = asyncLocalStorage.getStore();\r\n if (store) return store;\r\n }\r\n return _fallbackContext;\r\n}\r\n\r\n/**\r\n * Get the current component context (request-safe).\r\n */\r\nexport function getCurrentInstanceSafe(): any | null {\r\n return getRequestContext().currentComponentContext;\r\n}\r\n\r\n/**\r\n * Set the current component context (request-safe).\r\n * Returns the previous value.\r\n */\r\nexport function setCurrentInstanceSafe(ctx: any | null): any | null {\r\n const reqCtx = getRequestContext();\r\n const prev = reqCtx.currentComponentContext;\r\n reqCtx.currentComponentContext = ctx;\r\n return prev;\r\n}\r\n\r\n/**\r\n * Get the current suspense boundary (request-safe).\r\n */\r\nexport function getCurrentSuspenseBoundarySafe(): any | null {\r\n return getRequestContext().currentSuspenseBoundary;\r\n}\r\n\r\n/**\r\n * Set the current suspense boundary (request-safe).\r\n * Returns the previous value.\r\n */\r\nexport function setCurrentSuspenseBoundarySafe(boundary: any | null): any | null {\r\n const reqCtx = getRequestContext();\r\n const prev = reqCtx.currentSuspenseBoundary;\r\n reqCtx.currentSuspenseBoundary = boundary;\r\n return prev;\r\n}\r\n\r\n/**\r\n * Run a function within a new isolated request context.\r\n * On Node.js, uses AsyncLocalStorage.run() to create a new scope.\r\n * On browsers, simply calls the function (no isolation needed).\r\n *\r\n * @example\r\n * ```ts\r\n * // In SSR request handler:\r\n * const html = await runInRequestScope(async () => {\r\n * return await ssr.render(<App />);\r\n * });\r\n * ```\r\n */\r\nexport function runInRequestScope<T>(fn: () => T): T {\r\n if (asyncLocalStorage) {\r\n const freshContext: SSRRequestContext = {\r\n currentComponentContext: null,\r\n currentSuspenseBoundary: null\r\n };\r\n return asyncLocalStorage.run(freshContext, fn);\r\n }\r\n // Browser fallback — just call the function\r\n return fn();\r\n}\r\n\r\n/**\r\n * Check if AsyncLocalStorage-based request isolation is available.\r\n */\r\nexport function hasRequestIsolation(): boolean {\r\n return asyncLocalStorage !== null;\r\n}\r\n","import { JSXElement } from \"./jsx-runtime.js\";\r\nimport { signal } from \"@sigx/reactivity\";\r\nimport { getComponentPlugins } from \"./plugins.js\";\r\nimport {\r\n getCurrentInstanceSafe,\r\n setCurrentInstanceSafe\r\n} from \"./async-context.js\";\r\nimport type { Model as ModelType } from \"./model.js\";\r\n\r\n// Dev mode - can be set to false in production builds\r\nconst _DEV = true;\r\n\r\n/**\r\n * Extension point for additional component attributes.\r\n * Use module augmentation to add attributes to all components:\r\n * \r\n * @example\r\n * ```ts\r\n * // In @sigx/server-renderer\r\n * declare module '@sigx/runtime-core' {\r\n * interface ComponentAttributeExtensions {\r\n * 'client:load'?: boolean;\r\n * 'client:visible'?: boolean;\r\n * 'client:idle'?: boolean;\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport interface ComponentAttributeExtensions {\r\n // Attributes are added here via module augmentation\r\n}\r\n\r\n/**\r\n * Define a single prop with type, required/optional status\r\n */\r\nexport type DefineProp<TName extends string, TType, Required extends boolean = false> = Required extends false\r\n ? { [K in TName]?: TType }\r\n : { [K in TName]: TType };\r\n\r\n/**\r\n * Model binding tuple type - [stateObject, key] for forwarding\r\n * The state object can be a Signal or any object with the given key\r\n */\r\nexport type ModelBinding<_T> = [object, string];\r\n\r\n/**\r\n * Re-export Model type for convenience\r\n */\r\nexport type { ModelType as Model };\r\n\r\n/**\r\n * Define a 2-way bound model.\r\n * \r\n * The component receives a Model<T> object with:\r\n * - `.value` - Get or set the current value\r\n * - `.binding` - The underlying binding for forwarding\r\n * \r\n * Default form: DefineModel<T>\r\n * - props.model: Model<T> (read/write/forward)\r\n * - props.model.value to read/write\r\n * - <Child model={props.model} /> to forward\r\n * \r\n * Named form: DefineModel<\"name\", T>\r\n * - props.name: Model<T> (read/write/forward)\r\n * - props.name.value to read/write\r\n * - <Child model={props.name} /> to forward\r\n * \r\n * Callers use: model={() => state.prop} or model:name={() => state.prop}\r\n * \r\n * @example\r\n * ```tsx\r\n * interface InputProps extends DefineModel<string> {\r\n * placeholder?: string;\r\n * }\r\n * \r\n * const Input = component<InputProps>(({ props }) => {\r\n * // Read\r\n * console.log(props.model.value);\r\n * \r\n * // Write\r\n * props.model.value = \"new value\";\r\n * \r\n * // Forward\r\n * <Child model={props.model} />\r\n * });\r\n * ```\r\n */\r\nexport type DefineModel<TNameOrType, TType = void> = TType extends void\r\n // Default model: DefineModel<T> → props.model: Model<T>\r\n ? {\r\n model?: ModelType<TNameOrType>;\r\n /** @internal Marker for JSX to accept binding tuples */\r\n __modelBindings?: { model: TNameOrType };\r\n }\r\n & DefineEvent<\"update:modelValue\", TNameOrType>\r\n // Named model: DefineModel<\"name\", T> → props.name: Model<T>\r\n : TNameOrType extends string\r\n ? {\r\n [K in TNameOrType]?: ModelType<TType>;\r\n }\r\n & {\r\n /** @internal Marker for JSX to accept binding tuples */\r\n __modelBindings?: { [K in TNameOrType]: TType };\r\n }\r\n & DefineEvent<`update:${TNameOrType}`, TType>\r\n : never;\r\n\r\n/**\r\n * Extract model binding definitions from a component props type.\r\n * Used at JSX level to allow binding tuples for model props.\r\n */\r\ntype ExtractModelBindings<T> = T extends { __modelBindings?: infer M } ? NonNullable<M> : {};\r\n\r\n/**\r\n * Map model keys to their JSX prop names.\r\n * - \"model\" stays as \"model\" (default model)\r\n * - Other names become \"model:name\" (named models)\r\n */\r\ntype ModelPropName<K extends string> = K extends \"model\" ? \"model\" : `model:${K}`;\r\n\r\n/**\r\n * Transform Model<T> props to also accept binding syntax at JSX level.\r\n * This allows: model={[state, \"value\"]} or model={props.model}\r\n * For named models: model:title={[state, \"title\"]} or model:title={() => state.title}\r\n */\r\ntype ExternalModelProps<T> = {\r\n [K in keyof ExtractModelBindings<T> as K extends string ? ModelPropName<K> : never]?: \r\n | ModelType<ExtractModelBindings<T>[K]> // Forward Model<T>\r\n | ModelBinding<ExtractModelBindings<T>[K]> // Binding tuple\r\n | (() => ExtractModelBindings<T>[K]); // Getter function\r\n};\r\n\r\nexport type EventDefinition<T> = { __eventDetail: T };\r\n\r\n/**\r\n * Define a single custom event with its detail type\r\n */\r\nexport type DefineEvent<TName extends string, TDetail = void> = {\r\n [K in TName]?: EventDefinition<TDetail>;\r\n};\r\n\r\n/**\r\n * Define a slot with optional scoped props.\r\n * - DefineSlot<\"header\"> - a simple slot named \"header\"\r\n * - DefineSlot<\"item\", { item: T; index: number }> - a scoped slot with props\r\n */\r\nexport type DefineSlot<TName extends string, TProps = void> = {\r\n __slots?: {\r\n [K in TName]: TProps extends void\r\n ? () => JSXElement | JSXElement[] | null\r\n : (props: TProps) => JSXElement | JSXElement[] | null\r\n }\r\n};\r\n\r\n/**\r\n * Extract slot definitions from a combined type\r\n */\r\ntype ExtractSlots<T> = T extends { __slots?: infer S } ? S : {};\r\n\r\n/**\r\n * Default slot function type\r\n */\r\ntype DefaultSlot = () => JSXElement[];\r\n\r\n/**\r\n * Slots object passed to components - always has default, plus any declared slots\r\n */\r\nexport type SlotsObject<TSlots = {}> = {\r\n default: DefaultSlot;\r\n} & TSlots;\r\n\r\n/**\r\n * Extract event names from an event definition\r\n */\r\ntype EventNames<TEvents> = {\r\n [K in keyof TEvents]: TEvents[K] extends EventDefinition<any> | undefined ? K : never\r\n}[keyof TEvents] & string;\r\n\r\n/**\r\n * Extract event detail type for a specific event name\r\n */\r\ntype EventDetail<TEvents, TName extends EventNames<TEvents>> = TEvents extends { [K in TName]?: EventDefinition<infer TDetail> }\r\n ? TDetail\r\n : never;\r\n\r\n/**\r\n * Typed emit function for dispatching custom events\r\n */\r\nexport type EmitFn<TEvents extends Record<string, any>> = <TName extends EventNames<TEvents>>(\r\n eventName: TName,\r\n ...args: EventDetail<TEvents, TName> extends void ? [] : [detail: EventDetail<TEvents, TName>]\r\n) => void;\r\n\r\n/**\r\n * Capitalize the first letter of a string\r\n */\r\ntype Capitalize<S extends string> = S extends `${infer First}${infer Rest}`\r\n ? `${Uppercase<First>}${Rest}`\r\n : S;\r\n\r\n/**\r\n * Convert events to event handler props (on{EventName})\r\n */\r\ntype EventHandlers<TEvents extends Record<string, any>> = {\r\n [K in keyof TEvents as TEvents[K] extends EventDefinition<any> | undefined\r\n ? `on${Capitalize<string & K>}`\r\n : never\r\n ]?: (detail: TEvents[K] extends EventDefinition<infer D> | undefined ? D : never) => void;\r\n};\r\n\r\n/**\r\n * Platform registry - platforms add their element type here via declaration merging\r\n */\r\nexport interface PlatformTypes {\r\n // Platforms add: element: HTMLElement (or other element type)\r\n}\r\n\r\n/** Resolves to the platform's element type, or 'any' if not defined */\r\nexport type PlatformElement = PlatformTypes extends { element: infer E } ? E : any;\r\n\r\n/**\r\n * Base mount context - platforms can extend this via declaration merging\r\n */\r\nexport interface MountContext<TElement = PlatformElement> {\r\n el: TElement;\r\n}\r\n\r\n/**\r\n * Base setup context - platforms can extend this via declaration merging\r\n */\r\nexport interface SetupContext {\r\n // Platforms add properties here via module augmentation\r\n}\r\n\r\n/**\r\n * Extract keys from T where undefined is assignable to the value (optional props)\r\n */\r\ntype _OptionalKeys<T> = { [K in keyof T]: undefined extends T[K] ? K : never }[keyof T];\r\n\r\n/**\r\n * Type for defaults object - REQUIRES all optional keys to be provided.\r\n * Required props (where undefined is not assignable) get type 'never' to prevent setting them.\r\n * This ensures you don't forget to add a default when adding a new optional prop.\r\n */\r\ntype _DefaultsFor<TProps> = {\r\n [K in keyof TProps as undefined extends TProps[K] ? K : never]-?: NonNullable<TProps[K]>;\r\n};\r\n\r\n/**\r\n * Props type after defaults are applied - all props become required (non-undefined)\r\n */\r\nexport type PropsWithDefaults<TProps, D> = {\r\n readonly [K in keyof TProps]-?: K extends keyof D ? NonNullable<TProps[K]> : TProps[K];\r\n};\r\n\r\n/**\r\n * Props accessor - a reactive proxy for component props.\r\n * Use destructuring with defaults for optional props.\r\n * \r\n * @example\r\n * ```tsx\r\n * // Destructure with defaults\r\n * const { variant = 'primary', size = 'md' } = ctx.props;\r\n * return () => <button class={variant}>...</button>\r\n * \r\n * // Or spread to forward all props\r\n * return () => <ChildComponent {...ctx.props} />\r\n * ```\r\n */\r\nexport type PropsAccessor<TProps> = {\r\n readonly [K in keyof TProps]: TProps[K];\r\n};\r\n\r\nexport interface ComponentSetupContext<\r\n TElement = PlatformElement,\r\n TProps extends Record<string, any> = {},\r\n TEvents extends Record<string, any> = {},\r\n TRef = any,\r\n TSlots = {}\r\n> extends SetupContext {\r\n el: TElement;\r\n signal: typeof signal;\r\n /**\r\n * Component props - includes regular props and Model<T> objects.\r\n * \r\n * Models are accessed via props: props.model.value, props.title.value\r\n * \r\n * @example\r\n * ```tsx\r\n * // Read model\r\n * const value = props.model.value;\r\n * \r\n * // Write model\r\n * props.model.value = \"new value\";\r\n * \r\n * // Forward to child\r\n * <Child model={props.model} />\r\n * \r\n * // Forward via context\r\n * defineProvide(ctx, () => props.model);\r\n * ```\r\n */\r\n props: PropsAccessor<TProps>;\r\n slots: SlotsObject<TSlots>;\r\n emit: EmitFn<TEvents>;\r\n parent: any | null;\r\n onMounted(fn: (ctx: MountContext<TElement>) => void): void;\r\n onUnmounted(fn: (ctx: MountContext<TElement>) => void): void;\r\n onCreated(fn: () => void): void;\r\n onUpdated(fn: () => void): void;\r\n expose(exposed: TRef): void;\r\n /**\r\n * The current render function. Can be replaced directly for HMR.\r\n * @internal Used by HMR - set this, then call update()\r\n */\r\n renderFn: ViewFn | null;\r\n /**\r\n * Force the component to re-render using the current renderFn.\r\n * For HMR: first set ctx.renderFn to the new render function, then call update().\r\n */\r\n update(): void;\r\n}\r\n\r\nlet currentComponentContext: ComponentSetupContext<any, any, any> | null = null;\r\n\r\n/** Returns the setup context of the currently executing component, or `null` if called outside setup. */\r\nexport function getCurrentInstance() {\r\n // Prefer async-safe storage (AsyncLocalStorage on server), fallback to module-level\r\n return getCurrentInstanceSafe() ?? currentComponentContext;\r\n}\r\n\r\nexport function setCurrentInstance(ctx: ComponentSetupContext<any, any, any> | null) {\r\n // Update both: async-safe storage AND module-level fallback\r\n const prevSafe = setCurrentInstanceSafe(ctx);\r\n const prevModule = currentComponentContext;\r\n currentComponentContext = ctx;\r\n // Return the previous value — prefer async-safe if it was set\r\n return prevSafe ?? prevModule;\r\n}\r\n\r\n/** Register a callback to run after the component is mounted to the DOM. Must be called during setup. */\r\nexport function onMounted(fn: (ctx: MountContext) => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onMounted(fn);\r\n } else {\r\n console.warn(\"onMounted called outside of component setup\");\r\n }\r\n}\r\n\r\n/** Register a callback to run when the component is unmounted from the DOM. Must be called during setup. */\r\nexport function onUnmounted(fn: (ctx: MountContext) => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onUnmounted(fn);\r\n } else {\r\n console.warn(\"onUnmounted called outside of component setup\");\r\n }\r\n}\r\n\r\n/** Register a callback to run immediately after component setup completes. Must be called during setup. */\r\nexport function onCreated(fn: () => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onCreated(fn);\r\n } else {\r\n console.warn(\"onCreated called outside of component setup\");\r\n }\r\n}\r\n\r\n/** Register a callback to run after every reactive re-render of the component. Must be called during setup. */\r\nexport function onUpdated(fn: () => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onUpdated(fn);\r\n } else {\r\n console.warn(\"onUpdated called outside of component setup\");\r\n }\r\n}\r\n\r\nexport type ViewFn = () => JSXElement | JSXElement[] | undefined;\r\n\r\n/**\r\n * Type for component setup functions.\r\n * Includes Props, Events, Ref, and Slots generics to preserve type information.\r\n * Can be sync or async - async setup is awaited on server, runs sync on client hydration.\r\n */\r\nexport type SetupFn<\r\n TProps extends Record<string, any> = {},\r\n TEvents extends Record<string, any> = {},\r\n TRef = any,\r\n TSlots = {}\r\n> = (ctx: ComponentSetupContext<PlatformElement, TProps, TEvents, TRef, TSlots>) => ViewFn | Promise<ViewFn>;\r\n\r\n// Component registry for DevTools and debugging\r\nconst componentRegistry = new Map<Function, { name?: string; setup: SetupFn<any, any, any, any> }>();\r\n\r\n/**\r\n * Get component metadata (for DevTools)\r\n */\r\nexport function getComponentMeta(factory: Function) {\r\n return componentRegistry.get(factory);\r\n}\r\n\r\n/**\r\n * Helper to create a proxy that tracks property access\r\n */\r\nexport function createPropsProxy<T extends Record<string, any>>(target: T, onAccess?: (key: string) => void): T {\r\n return new Proxy(target, {\r\n get(obj, prop) {\r\n if (typeof prop === 'string' && onAccess) {\r\n onAccess(prop);\r\n }\r\n return obj[prop as keyof T];\r\n }\r\n });\r\n}\r\n\r\nexport type DefineExpose<T> = {\r\n __exposed?: { __type: T };\r\n};\r\n\r\ntype ExtractExposed<T> = \"__exposed\" extends keyof T\r\n ? (NonNullable<T[\"__exposed\"]> extends { __type: infer E } ? E : void)\r\n : void;\r\n\r\nexport type Ref<T> = { current: T | null } | ((instance: T | null) => void);\r\n\r\n/**\r\n * Extract the exposed API type from a component.\r\n * Use this to type variables that will hold a component's exposed interface.\r\n * \r\n * @example\r\n * ```tsx\r\n * let api: Exposed<typeof MyComponent>;\r\n * <MyComponent ref={r => api = r!} />\r\n * api.exposedMethod();\r\n * ```\r\n */\r\nexport type Exposed<T extends { __ref: any }> = T[\"__ref\"];\r\n\r\n/**\r\n * Extract the ref (exposed) type from a component (includes function ref option).\r\n * \r\n * @example\r\n * ```tsx\r\n * const myRef = { current: null } as ComponentRef<typeof MyComponent>;\r\n * ```\r\n */\r\nexport type ComponentRef<T extends { __ref: any }> = Ref<T[\"__ref\"]>;\r\n\r\n\r\n/**\r\n * Strip internal type markers from component props for setup context (internal use).\r\n * Preserves model keys so components can access props.model, props.title, etc.\r\n *\r\n * Strips:\r\n * - Internal markers: __exposed, __slots, __models, __modelBindings\r\n * - JSX model:name syntax markers\r\n * - Event markers (update:*)\r\n */\r\ntype StripInternalMarkers<T> = {\r\n [K in keyof T as K extends \"__exposed\" | \"__slots\" | \"__models\" | \"__modelBindings\" ? never\r\n : K extends `model:${string}` ? never // Strip JSX model:name syntax marker\r\n : K extends `update:${string}` ? never\r\n : K]: T[K];\r\n};\r\n\r\n/**\r\n * Strip props for JSX external signature.\r\n * Same as StripInternalMarkers but also strips model keys so ExternalModelProps\r\n * is the sole source (avoiding intersection conflicts between Model<T> and widened union).\r\n */\r\ntype StripForJSX<T> = {\r\n [K in keyof T as K extends \"__exposed\" | \"__slots\" | \"__models\" | \"__modelBindings\" ? never\r\n : K extends `model:${string}` ? never\r\n : K extends `update:${string}` ? never\r\n : K extends keyof ExtractModelBindings<T> ? never // Strip model keys - ExternalModelProps provides them\r\n : K]: T[K];\r\n};\r\n\r\n/**\r\n * Component options (optional second param)\r\n */\r\nexport interface ComponentOptions {\r\n /** Component name for DevTools debugging */\r\n name?: string;\r\n}\r\n\r\n/**\r\n * Slot props type - converts slot definitions to a slots prop object\r\n */\r\ntype SlotProps<TSlots> = TSlots extends Record<string, any>\r\n ? { slots?: Partial<TSlots> }\r\n : {};\r\n\r\n/**\r\n * Sync binding type - used at JSX level to enable two-way binding\r\n * The JSX runtime transforms sync into value + onUpdate:value\r\n */\r\ntype SyncBinding<T> = [object, string] | (() => T);\r\n\r\n/**\r\n * Sync props - if the component has a 'value' prop, allow 'sync' binding\r\n */\r\ntype SyncProps<TCombined> = 'value' extends keyof TCombined\r\n ? { sync?: SyncBinding<TCombined['value']> }\r\n : {};\r\n\r\n// Return type for component - the function IS the component\r\nexport type ComponentFactory<TCombined extends Record<string, any>, TRef, TSlots> = ((props: StripForJSX<Omit<TCombined, EventNames<TCombined>>> & EventHandlers<TCombined> & SlotProps<TSlots> & SyncProps<TCombined> & ExternalModelProps<TCombined> & JSX.IntrinsicAttributes & ComponentAttributeExtensions & {\r\n ref?: Ref<TRef>;\r\n children?: any;\r\n}) => JSXElement) & {\r\n /** @internal Setup function for the renderer */\r\n __setup: SetupFn<StripInternalMarkers<TCombined>, TCombined, TRef, TSlots>;\r\n /** @internal Component name for debugging */\r\n __name?: string;\r\n /** @internal Stable island identity based on file path (injected by sigxIslandsPlugin) */\r\n __islandId?: string;\r\n /** @internal Type brand for props */\r\n __props: StripInternalMarkers<TCombined>;\r\n /** @internal Type brand for events */\r\n __events: TCombined;\r\n /** @internal Type brand for ref */\r\n __ref: TRef;\r\n /** @internal Type brand for slots */\r\n __slots: TSlots;\r\n};\r\n\r\n/**\r\n * Define a component. Returns a JSX factory function.\r\n * \r\n * @param setup - Setup function that receives context and returns a render function\r\n * @param options - Optional configuration (e.g., name for DevTools)\r\n * \r\n * @example\r\n * ```tsx\r\n * type CardProps = DefineProp<\"title\", string> & DefineSlot<\"header\">;\r\n * \r\n * export const Card = component<CardProps>((ctx) => {\r\n * const { title } = ctx.props;\r\n * const { slots } = ctx;\r\n * \r\n * return () => (\r\n * <div class=\"card\">\r\n * {slots.header?.() ?? <h2>{title}</h2>}\r\n * {slots.default()}\r\n * </div>\r\n * );\r\n * });\r\n * ```\r\n */\r\nexport function component<\r\n TCombined extends Record<string, any> = {},\r\n TRef = ExtractExposed<TCombined>,\r\n TSlots = ExtractSlots<TCombined>\r\n>(\r\n setup: (ctx: ComponentSetupContext<PlatformElement, StripInternalMarkers<TCombined>, TCombined, TRef, TSlots>) => ViewFn | Promise<ViewFn>,\r\n options?: ComponentOptions\r\n): ComponentFactory<TCombined, TRef, TSlots> {\r\n // Create the factory function - when called in JSX, it returns itself as a marker\r\n // The renderer will detect __setup and handle it as a component\r\n const factory = function (props: any) {\r\n // Return a VNode-like structure that the renderer can detect\r\n return {\r\n type: factory,\r\n props: props || {},\r\n key: props?.key || null,\r\n children: [],\r\n dom: null\r\n };\r\n } as unknown as ComponentFactory<TCombined, TRef, TSlots>;\r\n\r\n factory.__setup = setup as SetupFn<StripInternalMarkers<TCombined>, TCombined, TRef, TSlots>;\r\n factory.__name = options?.name;\r\n factory.__props = null as any;\r\n factory.__events = null as any;\r\n factory.__ref = null as any;\r\n factory.__slots = null as any;\r\n\r\n // Register in component registry for DevTools\r\n componentRegistry.set(factory, { name: options?.name, setup: setup as unknown as SetupFn<any, any, any, any> });\r\n\r\n // Notify plugins\r\n getComponentPlugins().forEach(p => p.onDefine?.(options?.name, factory, setup as unknown as SetupFn<any, any, any, any>));\r\n\r\n return factory;\r\n}\r\n","import { getCurrentInstance } from \"../component.js\";\r\nimport type { AppContext } from \"../app-types.js\";\r\n\r\n// ============================================================================\r\n// Internal helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Global singleton instances (fallback when no provider found)\r\n */\r\nconst globalInstances = new Map<any, any>();\r\n\r\n/**\r\n * Token for the AppContext injectable.\r\n * Used to provide/lookup the AppContext in the component tree.\r\n */\r\nconst appContextToken = Symbol('sigx:appContext');\r\n\r\n/**\r\n * Lookup a provided value by token, traversing component tree.\r\n * The AppContext is provided at the root component level, so it's found\r\n * just like any other provided value.\r\n * @internal\r\n */\r\nfunction lookupProvided<T>(token: any): T | undefined {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n return undefined;\r\n }\r\n\r\n // Traverse up the component tree looking for provides\r\n let current: any = ctx;\r\n while (current) {\r\n if (current.provides && current.provides.has(token)) {\r\n return current.provides.get(token);\r\n }\r\n current = current.parent;\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Provide a value at the current component level\r\n * @internal\r\n */\r\nfunction provideAtComponent<T>(token: any, value: T): void {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n throw new Error(\"defineProvide must be called inside a component setup function\");\r\n }\r\n\r\n if (!(ctx as any).provides) {\r\n (ctx as any).provides = new Map();\r\n }\r\n (ctx as any).provides.set(token, value);\r\n}\r\n\r\n// ============================================================================\r\n// Public API\r\n// ============================================================================\r\n\r\n/**\r\n * Injectable function type with metadata\r\n */\r\nexport interface InjectableFunction<T> {\r\n (): T;\r\n _factory: () => T;\r\n _token: symbol;\r\n}\r\n\r\n/**\r\n * Define an injectable service/value that can be provided at app or component level.\r\n * \r\n * The returned function can be called to get the current instance:\r\n * - If provided at component level via `defineProvide()`, returns that instance\r\n * - If provided at app level via `app.defineProvide()`, returns that instance \r\n * - Otherwise falls back to a global singleton created by the factory\r\n * \r\n * @example\r\n * ```typescript\r\n * // Define a service\r\n * const useApiConfig = defineInjectable(() => ({ \r\n * baseUrl: 'https://api.example.com' \r\n * }));\r\n * \r\n * // Use it in any component - gets nearest provided instance or global singleton\r\n * const config = useApiConfig();\r\n * console.log(config.baseUrl);\r\n * ```\r\n */\r\nexport function defineInjectable<T>(factory: () => T): InjectableFunction<T> {\r\n // Use a unique symbol as the token for this injectable\r\n const token = Symbol();\r\n\r\n const useFn = (() => {\r\n // Try to find a provided instance\r\n const provided = lookupProvided<T>(token);\r\n if (provided !== undefined) {\r\n return provided;\r\n }\r\n\r\n // Fallback to global singleton\r\n if (!globalInstances.has(token)) {\r\n globalInstances.set(token, factory());\r\n }\r\n return globalInstances.get(token);\r\n }) as InjectableFunction<T>;\r\n\r\n // Attach metadata for defineProvide\r\n useFn._factory = factory;\r\n useFn._token = token;\r\n\r\n return useFn;\r\n}\r\n\r\n/**\r\n * Provide a new instance of an injectable at the current component level.\r\n * Child components will receive this instance when calling the injectable function.\r\n * \r\n * @param useFn - The injectable function created by defineInjectable\r\n * @param factory - Optional custom factory to create the instance (overrides default)\r\n * \r\n * @example\r\n * ```typescript\r\n * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));\r\n * \r\n * const MyComponent = component(() => {\r\n * // Create and provide a new instance for this subtree\r\n * const config = defineProvide(useApiConfig);\r\n * config.baseUrl = 'https://custom.api.com';\r\n * \r\n * return () => <ChildComponent />;\r\n * });\r\n * \r\n * // Or provide a pre-constructed instance:\r\n * const MyComponent2 = component(() => {\r\n * const customService = createMyService({ custom: 'options' });\r\n * defineProvide(useMyService, () => customService);\r\n * \r\n * return () => <ChildComponent />;\r\n * });\r\n * ```\r\n */\r\nexport function defineProvide<T>(useFn: InjectableFunction<T>, factory?: () => T): T {\r\n const actualFactory = factory ?? useFn._factory;\r\n const token = useFn._token;\r\n\r\n if (!actualFactory || !token) {\r\n throw new Error(\"defineProvide must be called with a function created by defineInjectable\");\r\n }\r\n\r\n const instance = actualFactory();\r\n provideAtComponent(token, instance);\r\n return instance;\r\n}\r\n\r\n/**\r\n * Get the current AppContext from the component tree.\r\n * The AppContext is provided at the root component level during mount/hydrate/SSR.\r\n * \r\n * @example\r\n * ```typescript\r\n * const appContext = useAppContext();\r\n * console.log(appContext?.app);\r\n * ```\r\n */\r\nexport function useAppContext(): AppContext | null {\r\n return lookupProvided<AppContext>(appContextToken) ?? null;\r\n}\r\n\r\n/**\r\n * Get the AppContext token.\r\n * Used by renderers to provide the AppContext at the root component level.\r\n * @internal\r\n */\r\nexport function getAppContextToken(): symbol {\r\n return appContextToken;\r\n}\r\n\r\n/**\r\n * Provide the AppContext on a component's provides Map.\r\n * Called by the renderer for the ROOT component only.\r\n * @internal\r\n */\r\nexport function provideAppContext(ctx: any, appContext: AppContext): void {\r\n if (!ctx.provides) {\r\n ctx.provides = new Map();\r\n }\r\n ctx.provides.set(appContextToken, appContext);\r\n \r\n // Also store app-level provides on the root component\r\n // This makes `lookupProvided` find them when traversing up to root\r\n if (appContext.provides) {\r\n for (const [token, value] of appContext.provides) {\r\n ctx.provides.set(token, value);\r\n }\r\n }\r\n}\r\n","/**\r\n * Directive system for SignalX.\r\n *\r\n * Directives provide reusable element-level lifecycle hooks via the `use:name` prop syntax.\r\n * They can be registered globally via `app.directive()` or passed inline as imported values.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { defineDirective } from 'sigx';\r\n *\r\n * const tooltip = defineDirective<string>({\r\n * mounted(el, { value }) {\r\n * el.title = value;\r\n * },\r\n * updated(el, { value }) {\r\n * el.title = value;\r\n * },\r\n * unmounted(el) {\r\n * el.title = '';\r\n * }\r\n * });\r\n *\r\n * // Inline usage:\r\n * <div use:tooltip=\"Hello!\">Hover me</div>\r\n *\r\n * // Or with explicit binding:\r\n * <div use:tooltip={[tooltip, \"Hello!\"]}>Hover me</div>\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * The binding object passed to directive hooks.\r\n */\r\nexport interface DirectiveBinding<T = any> {\r\n /** The current value passed to the directive */\r\n value: T;\r\n /** The previous value (available in `updated` hook) */\r\n oldValue?: T;\r\n}\r\n\r\n/**\r\n * Extension interface for directive definitions.\r\n *\r\n * Other packages (e.g., `@sigx/server-renderer`) can augment this interface\r\n * to add hooks like `getSSRProps` via TypeScript module augmentation.\r\n *\r\n * @example\r\n * ```ts\r\n * // In @sigx/server-renderer\r\n * declare module '@sigx/runtime-core' {\r\n * interface DirectiveDefinitionExtensions<T> {\r\n * getSSRProps?(binding: DirectiveBinding<T>): Record<string, any> | void;\r\n * }\r\n * }\r\n * ```\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unused-vars\r\nexport interface DirectiveDefinitionExtensions<T = any> {\r\n // Intentionally empty — filled via module augmentation by SSR and other packages\r\n}\r\n\r\n/**\r\n * A directive definition object with lifecycle hooks.\r\n *\r\n * All hooks are optional. Additional hooks (e.g., `getSSRProps`) may be\r\n * available when SSR packages augment `DirectiveDefinitionExtensions`.\r\n */\r\nexport interface DirectiveDefinition<T = any, El = any> extends DirectiveDefinitionExtensions<T> {\r\n /** Called after the element is created but before it is inserted into the DOM */\r\n created?(el: El, binding: DirectiveBinding<T>): void;\r\n /** Called after the element is inserted into the DOM */\r\n mounted?(el: El, binding: DirectiveBinding<T>): void;\r\n /** Called when the binding value changes */\r\n updated?(el: El, binding: DirectiveBinding<T>): void;\r\n /** Called before the element is removed from the DOM */\r\n unmounted?(el: El, binding: DirectiveBinding<T>): void;\r\n}\r\n\r\n/**\r\n * A resolved directive binding stored on a VNode.\r\n * Tuple of [definition, value].\r\n */\r\nexport type ResolvedDirective<T = any, El = any> = [DirectiveDefinition<T, El>, T];\r\n\r\n/**\r\n * Marker symbol to identify directive definitions.\r\n * @internal\r\n */\r\nexport const __DIRECTIVE__ = Symbol.for('sigx.directive');\r\n\r\n/**\r\n * Internal type for marked directive definitions.\r\n * @internal\r\n */\r\nexport interface MarkedDirectiveDefinition<T = any, El = any> extends DirectiveDefinition<T, El> {\r\n [__DIRECTIVE__]: true;\r\n}\r\n\r\n// ============================================================================\r\n// Public API\r\n// ============================================================================\r\n\r\n/**\r\n * Define a directive. This is an identity function that marks the definition\r\n * for type inference and runtime identification.\r\n *\r\n * @example\r\n * ```ts\r\n * const highlight = defineDirective<string>({\r\n * mounted(el, { value }) {\r\n * el.style.backgroundColor = value;\r\n * },\r\n * updated(el, { value }) {\r\n * el.style.backgroundColor = value;\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function defineDirective<T = any, El = any>(definition: DirectiveDefinition<T, El>): DirectiveDefinition<T, El> {\r\n (definition as MarkedDirectiveDefinition<T, El>)[__DIRECTIVE__] = true;\r\n return definition;\r\n}\r\n\r\n/**\r\n * Check if a value is a directive definition.\r\n */\r\nexport function isDirective(value: any): value is DirectiveDefinition {\r\n return value != null && typeof value === 'object' && (value as any)[__DIRECTIVE__] === true;\r\n}\r\n\r\n// ============================================================================\r\n// App-level Directive Registry\r\n// ============================================================================\r\n","/**\r\n * Application instance and plugin system for sigx.\r\n * \r\n * This module provides a renderer-agnostic way to configure and bootstrap\r\n * sigx applications with plugins, dependency injection, and lifecycle hooks.\r\n */\r\n\r\n// Re-export all types from the types file\r\nexport type {\r\n ComponentInstance,\r\n AppConfig,\r\n AppLifecycleHooks,\r\n AppContext,\r\n Plugin,\r\n PluginInstallFn,\r\n MountFn,\r\n UnmountFn,\r\n App\r\n} from './app-types.js';\r\n\r\n// Import types for internal use\r\nimport type {\r\n ComponentInstance,\r\n AppConfig,\r\n AppContext,\r\n Plugin,\r\n PluginInstallFn,\r\n MountFn,\r\n App\r\n} from './app-types.js';\r\n\r\nimport { getAppContextToken, type InjectableFunction } from './di/injectable.js';\r\nimport { isDirective } from './directives.js';\r\n\r\n// ============================================================================\r\n// Dev mode flag - must be at top before any usage\r\n// ============================================================================\r\n\r\nconst isDev = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production' || true;\r\n\r\n// ============================================================================\r\n// Constants\r\n// ============================================================================\r\n\r\n// AppContextKey is no longer needed - we use the DI system's token\r\n\r\n// ============================================================================\r\n// Default Mount Function (set by platform packages)\r\n// ============================================================================\r\n\r\nlet defaultMountFn: MountFn<any> | null = null;\r\n\r\n/**\r\n * Set the default mount function for the platform.\r\n * Called by platform packages (runtime-dom, runtime-terminal) on import.\r\n * \r\n * @example\r\n * ```typescript\r\n * // In @sigx/runtime-dom\r\n * import { setDefaultMount } from '@sigx/runtime-core';\r\n * setDefaultMount(domMount);\r\n * ```\r\n */\r\nexport function setDefaultMount<TContainer = any>(mountFn: MountFn<TContainer>): void {\r\n defaultMountFn = mountFn;\r\n}\r\n\r\n/**\r\n * Get the current default mount function.\r\n * @internal\r\n */\r\nexport function getDefaultMount(): MountFn<any> | null {\r\n return defaultMountFn;\r\n}\r\n\r\n// ============================================================================\r\n// Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Create an application instance.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { defineApp, defineInjectable } from '@sigx/runtime-core';\r\n * \r\n * // Define an injectable service\r\n * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));\r\n * \r\n * const app = defineApp(<App />);\r\n * \r\n * app.use(myPlugin, { option: 'value' });\r\n * \r\n * // Provide custom instance at app level\r\n * const config = app.defineProvide(useApiConfig);\r\n * config.baseUrl = 'https://custom.api.com';\r\n * \r\n * app.mount(document.getElementById('app')!);\r\n * ```\r\n */\r\nexport function defineApp<TContainer = any>(rootComponent: any): App<TContainer> {\r\n const installedPlugins = new Set<Plugin | PluginInstallFn>();\r\n\r\n const context: AppContext = {\r\n app: null!, // Will be set below\r\n provides: new Map(),\r\n config: {},\r\n hooks: [],\r\n directives: new Map()\r\n };\r\n\r\n let isMounted = false;\r\n let container: TContainer | null = null;\r\n let unmountFn: (() => void) | null = null;\r\n\r\n const app: App<TContainer> = {\r\n config: context.config,\r\n\r\n use(plugin, options) {\r\n if (installedPlugins.has(plugin)) {\r\n // Plugin already installed, skip\r\n if (isDev) {\r\n console.warn(`Plugin ${(plugin as Plugin).name || 'anonymous'} is already installed.`);\r\n }\r\n return app;\r\n }\r\n\r\n installedPlugins.add(plugin);\r\n\r\n if (typeof plugin === 'function') {\r\n // Function-style plugin\r\n plugin(app, options);\r\n } else if (plugin && typeof plugin.install === 'function') {\r\n // Object-style plugin\r\n plugin.install(app, options);\r\n } else if (isDev) {\r\n console.warn('Invalid plugin: must be a function or have an install() method.');\r\n }\r\n\r\n return app;\r\n },\r\n\r\n defineProvide<T>(useFn: InjectableFunction<T>, factory?: () => T): T {\r\n const actualFactory = factory ?? useFn._factory;\r\n const token = useFn._token;\r\n\r\n if (!actualFactory || !token) {\r\n throw new Error(\"defineProvide must be called with a function created by defineInjectable\");\r\n }\r\n\r\n const instance = actualFactory();\r\n context.provides.set(token, instance);\r\n return instance;\r\n },\r\n\r\n hook(hooks) {\r\n context.hooks.push(hooks);\r\n return app;\r\n },\r\n\r\n directive(name: string, definition?: any): any {\r\n if (definition !== undefined) {\r\n if (isDev && !isDirective(definition)) {\r\n console.warn(\r\n `[sigx] app.directive('${name}', ...) received a value that is not a valid directive definition. ` +\r\n `Use defineDirective() to create directive definitions.`\r\n );\r\n }\r\n context.directives.set(name, definition);\r\n return app;\r\n }\r\n return context.directives.get(name);\r\n },\r\n\r\n mount(target, renderFn?) {\r\n if (isMounted) {\r\n if (isDev) {\r\n console.warn('App is already mounted. Call app.unmount() first.');\r\n }\r\n return app;\r\n }\r\n\r\n // Use provided mount function or fall back to platform default\r\n const mountFn = renderFn ?? defaultMountFn;\r\n\r\n if (!mountFn) {\r\n throw new Error(\r\n 'No mount function provided and no default mount function set. ' +\r\n 'Either pass a mount function to app.mount(), or import a platform package ' +\r\n '(e.g., @sigx/runtime-dom or @sigx/runtime-terminal) that sets the default.'\r\n );\r\n }\r\n\r\n container = target;\r\n isMounted = true;\r\n\r\n // Call the platform-specific render function with our app context\r\n // The render function may return an unmount callback\r\n const result = mountFn(rootComponent, target, context);\r\n if (typeof result === 'function') {\r\n unmountFn = result;\r\n }\r\n\r\n return app;\r\n },\r\n\r\n unmount() {\r\n if (!isMounted) {\r\n if (isDev) {\r\n console.warn('App is not mounted.');\r\n }\r\n return;\r\n }\r\n\r\n if (unmountFn) {\r\n unmountFn();\r\n }\r\n\r\n // Clear provides to help GC\r\n context.provides.clear();\r\n\r\n isMounted = false;\r\n container = null;\r\n },\r\n\r\n get _context() {\r\n return context;\r\n },\r\n\r\n get _isMounted() {\r\n return isMounted;\r\n },\r\n\r\n get _container() {\r\n return container;\r\n },\r\n\r\n get _rootComponent() {\r\n return rootComponent;\r\n }\r\n };\r\n\r\n // Set the app reference in context\r\n context.app = app;\r\n\r\n // Provide the AppContext via the DI system\r\n const appContextToken = getAppContextToken();\r\n context.provides.set(appContextToken, context);\r\n\r\n return app;\r\n}\r\n\r\n// ============================================================================\r\n// Hooks API - Called by renderers to notify plugins\r\n// ============================================================================\r\n\r\n/**\r\n * Notify all app hooks that a component was created.\r\n * Called by the renderer after setup() returns.\r\n */\r\nexport function notifyComponentCreated(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentCreated?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentCreated');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all app hooks that a component was mounted.\r\n * Called by the renderer after mount hooks run.\r\n */\r\nexport function notifyComponentMounted(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentMounted?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentMounted');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all app hooks that a component was unmounted.\r\n * Called by the renderer before cleanup.\r\n */\r\nexport function notifyComponentUnmounted(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentUnmounted?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentUnmounted');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all app hooks that a component updated.\r\n * Called by the renderer after re-render.\r\n */\r\nexport function notifyComponentUpdated(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentUpdated?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentUpdated');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Handle an error in a component. Returns true if the error was handled.\r\n * Called by the renderer when an error occurs in setup or render.\r\n */\r\nexport function handleComponentError(\r\n context: AppContext | null,\r\n err: Error,\r\n instance: ComponentInstance | null,\r\n info: string\r\n): boolean {\r\n if (!context) return false;\r\n\r\n // First, try plugin hooks\r\n for (const hooks of context.hooks) {\r\n try {\r\n const handled = hooks.onComponentError?.(err, instance!, info);\r\n if (handled === true) return true;\r\n } catch (hookErr) {\r\n // Hook itself threw - log and continue\r\n console.error('Error in onComponentError hook:', hookErr);\r\n }\r\n }\r\n\r\n // Then, try app-level error handler\r\n if (context.config.errorHandler) {\r\n try {\r\n const handled = context.config.errorHandler(err, instance, info);\r\n if (handled === true) return true;\r\n } catch (handlerErr) {\r\n console.error('Error in app.config.errorHandler:', handlerErr);\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Handle errors that occur in hooks themselves\r\n */\r\nfunction handleHookError(context: AppContext, err: Error, instance: ComponentInstance, hookName: string): void {\r\n console.error(`Error in ${hookName} hook:`, err);\r\n\r\n // Try the app error handler\r\n if (context.config.errorHandler) {\r\n try {\r\n context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);\r\n } catch {\r\n // Give up - we've done our best\r\n }\r\n }\r\n}\r\n","/**\r\n * Model<T> - Unified two-way binding type for SignalX components.\r\n * \r\n * Provides a single interface for reading, writing, and forwarding model bindings.\r\n * \r\n * @example\r\n * ```tsx\r\n * const Input = component<InputProps>(({ props }) => {\r\n * // Read\r\n * console.log(props.model.value);\r\n * \r\n * // Write\r\n * props.model.value = \"new value\";\r\n * \r\n * // Forward to child\r\n * <Child model={props.model} />\r\n * \r\n * // Forward via context\r\n * defineProvide(inputContext, () => props.model);\r\n * });\r\n * ```\r\n */\r\n\r\n/** Symbol to identify Model objects */\r\nconst MODEL_SYMBOL = Symbol.for(\"sigx.model\");\r\n\r\n/** The binding tuple for Model<T>: [sourceObject, key, updateHandler] */\r\nexport type ModelBindingTuple<T> = readonly [object, string, (value: T) => void];\r\n\r\n/**\r\n * Model<T> - A two-way binding that can be read, written, and forwarded.\r\n * \r\n * - `.value` - Get or set the current value\r\n * - `.binding` - The underlying binding for forwarding\r\n */\r\nexport interface Model<T> {\r\n /** Get or set the current value */\r\n value: T;\r\n /** The underlying binding tuple for forwarding */\r\n readonly binding: ModelBindingTuple<T>;\r\n /** @internal Marker to identify Model objects */\r\n readonly [MODEL_SYMBOL]: true;\r\n}\r\n\r\n/**\r\n * Creates a Model<T> from a binding tuple and update handler.\r\n * \r\n * @param tuple - The [sourceObject, key] tuple from reactivity detection\r\n * @param updateHandler - Function called when value is set (enables parent interception)\r\n * @returns A Model<T> with .value getter/setter and .binding for forwarding\r\n */\r\nexport function createModel<T>(\r\n tuple: [object, string],\r\n updateHandler: (value: T) => void\r\n): Model<T> {\r\n const [obj, key] = tuple;\r\n \r\n return {\r\n get value(): T {\r\n return (obj as Record<string, T>)[key];\r\n },\r\n set value(v: T) {\r\n updateHandler(v);\r\n },\r\n get binding(): ModelBindingTuple<T> {\r\n return [obj, key, updateHandler] as const;\r\n },\r\n [MODEL_SYMBOL]: true as const\r\n };\r\n}\r\n\r\n/**\r\n * Creates a Model<T> from an existing binding (for forwarding scenarios).\r\n * \r\n * @param binding - The full binding tuple [obj, key, handler]\r\n * @returns A new Model<T> wrapping the same binding\r\n */\r\nexport function createModelFromBinding<T>(binding: ModelBindingTuple<T>): Model<T> {\r\n const [obj, key, handler] = binding;\r\n return createModel([obj, key], handler);\r\n}\r\n\r\n/**\r\n * Type guard to check if a value is a Model<T>.\r\n * \r\n * Used by JSX runtime to detect forwarded models and extract their bindings.\r\n */\r\nexport function isModel(value: unknown): value is Model<unknown> {\r\n return (\r\n value !== null &&\r\n typeof value === \"object\" &&\r\n MODEL_SYMBOL in value &&\r\n (value as Model<unknown>)[MODEL_SYMBOL] === true\r\n );\r\n}\r\n\r\n/**\r\n * Gets the Model symbol for external checks.\r\n * @internal\r\n */\r\nexport function getModelSymbol(): symbol {\r\n return MODEL_SYMBOL;\r\n}\r\n","/**\r\n * Platform-specific hooks for runtime-core.\r\n * \r\n * This module has NO IMPORTS to ensure it's fully initialized before\r\n * any other module can import from it. This avoids circular dependency\r\n * issues with ES module initialization.\r\n */\r\n\r\n/**\r\n * Platform-specific model processor for intrinsic elements.\r\n * Platforms (DOM, Terminal) can register their own model handling logic.\r\n * \r\n * @param type - The intrinsic element type (e.g., 'input', 'select')\r\n * @param props - The props object being built (mutable)\r\n * @param modelBinding - The [stateObj, key] tuple for the model binding\r\n * @param originalProps - The original props from JSX (read-only)\r\n * @returns true if handled (skip generic fallback), false to use generic fallback\r\n */\r\nexport type ModelProcessor = (\r\n type: string,\r\n props: Record<string, any>,\r\n modelBinding: [Record<string, any>, string],\r\n originalProps: Record<string, any>\r\n) => boolean;\r\n\r\n// Private holder - no TDZ issues since this module has no circular deps\r\nlet platformModelProcessor: ModelProcessor | null = null;\r\n\r\n/**\r\n * Set the platform-specific model processor for intrinsic elements.\r\n * Called by runtime-dom to handle checkbox/radio/select model bindings.\r\n */\r\nexport function setPlatformModelProcessor(fn: ModelProcessor): void {\r\n platformModelProcessor = fn;\r\n}\r\n\r\n/**\r\n * Get the current platform model processor (for internal use).\r\n */\r\nexport function getPlatformModelProcessor(): ModelProcessor | null {\r\n return platformModelProcessor;\r\n}\r\n","/**\r\n * Component type checking utilities\r\n * \r\n * Separated to avoid circular dependencies between jsx-runtime and renderer.\r\n */\r\n\r\n/**\r\n * Minimal interface for component detection.\r\n * Full ComponentFactory type is generic and complex, so we use this minimal\r\n * interface for the type guard.\r\n */\r\nexport interface ComponentLike {\r\n __setup: Function;\r\n __name?: string;\r\n}\r\n\r\n/**\r\n * Check if a value is a SignalX component (has __setup).\r\n * \r\n * SignalX components are created with component() and have a __setup\r\n * property containing the setup function.\r\n * \r\n * @example\r\n * ```ts\r\n * const MyComponent = component((ctx) => () => <div/>);\r\n * isComponent(MyComponent); // true\r\n * isComponent(() => <div/>); // false (plain function component)\r\n * isComponent('div'); // false\r\n * ```\r\n */\r\nexport function isComponent(type: unknown): type is ComponentLike {\r\n return typeof type === 'function' && '__setup' in type;\r\n}\r\n","// JSX runtime for @sigx/runtime-core\r\n\r\nimport { detectAccess, isComputed } from '@sigx/reactivity';\r\nimport { createModel, isModel, type Model } from './model.js';\r\nimport { getPlatformModelProcessor } from './platform.js';\r\nimport { isComponent } from './utils/is-component.js';\r\n\r\n// Re-export platform types and functions\r\nexport { setPlatformModelProcessor, getPlatformModelProcessor } from './platform.js';\r\nexport type { ModelProcessor } from './platform.js';\r\nexport { createModel, isModel, type Model } from './model.js';\r\n\r\nexport type VNode = {\r\n type: string | typeof Fragment | typeof Text | Function;\r\n props: Record<string, any>;\r\n key: string | number | null;\r\n children: VNode[];\r\n dom: any | null;\r\n text?: string | number;\r\n parent?: VNode | null;\r\n cleanup?: () => void;\r\n};\r\n\r\nexport type JSXChild = VNode | string | number | boolean | null | undefined | JSXChild[];\r\nexport type JSXChildren = JSXChild;\r\nexport type JSXElement = VNode | string | number | boolean | null;\r\n\r\ninterface JSXProps {\r\n children?: JSXChildren;\r\n [key: string]: any;\r\n}\r\n\r\nexport const Fragment = Symbol.for('sigx.Fragment');\r\nexport const Text = Symbol.for('sigx.Text');\r\n\r\nfunction normalizeChildren(children: JSXChildren): VNode[] {\r\n if (children == null || children === false || children === true) {\r\n return [];\r\n }\r\n\r\n // Auto-unwrap computed signals\r\n if (isComputed(children)) {\r\n return normalizeChildren(children.value as JSXChild);\r\n }\r\n\r\n if (Array.isArray(children)) {\r\n return children.flatMap(c => normalizeChildren(c));\r\n }\r\n\r\n if (typeof children === 'string' || typeof children === 'number') {\r\n return [{\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: children\r\n }];\r\n }\r\n\r\n if ((children as VNode).type) {\r\n return [children as VNode];\r\n }\r\n\r\n return [];\r\n}\r\n\r\n// isComponent is imported from ./utils/is-component.js\r\n\r\n/**\r\n * Create a JSX element - this is the core function called by TSX transpilation\r\n */\r\nexport function jsx(\r\n type: string | Function | typeof Fragment,\r\n props: JSXProps | null,\r\n key?: string\r\n): JSXElement {\r\n const processedProps = { ...props };\r\n const models: Record<string, Model<any>> = {};\r\n const isComponentType = isComponent(type);\r\n\r\n // Handle model props (two-way binding)\r\n if (props) {\r\n for (const propKey in props) {\r\n if (propKey === \"model\") {\r\n let modelBinding = props[propKey];\r\n let tuple: [object, string] | null = null;\r\n let updateHandler: ((v: any) => void) | null = null;\r\n\r\n // Check if it's already a Model (forwarding)\r\n if (isModel(modelBinding)) {\r\n const [obj, key, handler] = modelBinding.binding;\r\n tuple = [obj, key];\r\n updateHandler = handler;\r\n }\r\n // Convert getter function to tuple using detectAccess\r\n else if (typeof modelBinding === \"function\") {\r\n const detected = detectAccess(modelBinding);\r\n if (detected && typeof detected[1] === 'string') {\r\n tuple = detected as [object, string];\r\n }\r\n }\r\n // Direct tuple\r\n else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === 'string') {\r\n tuple = modelBinding as [object, string];\r\n }\r\n\r\n if (tuple) {\r\n const [stateObj, stateKey] = tuple;\r\n let handled = false;\r\n\r\n // Create update handler if not forwarding\r\n if (!updateHandler) {\r\n const existingHandler = processedProps[\"onUpdate:modelValue\"];\r\n updateHandler = (v: any) => {\r\n const customHandler = (stateObj as any)[`onUpdate:${stateKey}`];\r\n if (typeof customHandler === \"function\") {\r\n customHandler(v);\r\n } else {\r\n (stateObj as any)[stateKey] = v;\r\n }\r\n if (existingHandler) existingHandler(v);\r\n };\r\n }\r\n\r\n // Let platform handle intrinsic element model (e.g., DOM checkbox/radio)\r\n const platformProcessor = getPlatformModelProcessor();\r\n if (typeof type === \"string\" && platformProcessor) {\r\n handled = platformProcessor(type, processedProps, tuple, props);\r\n }\r\n\r\n // For components: create Model<T> object\r\n if (isComponentType) {\r\n models.model = createModel(tuple, updateHandler);\r\n // Keep onUpdate handler for backward compatibility\r\n processedProps[\"onUpdate:modelValue\"] = updateHandler;\r\n } else if (!handled) {\r\n // Generic fallback for intrinsic elements\r\n processedProps.modelValue = (stateObj as Record<string, any>)[stateKey];\r\n processedProps[\"onUpdate:modelValue\"] = updateHandler;\r\n }\r\n delete processedProps.model;\r\n }\r\n } else if (propKey.startsWith(\"model:\")) {\r\n let modelBinding = props[propKey];\r\n const name = propKey.slice(6); // \"model:title\" → \"title\"\r\n let tuple: [object, string] | null = null;\r\n let updateHandler: ((v: any) => void) | null = null;\r\n\r\n // Check if it's already a Model (forwarding)\r\n if (isModel(modelBinding)) {\r\n const [obj, key, handler] = modelBinding.binding;\r\n tuple = [obj, key];\r\n updateHandler = handler;\r\n }\r\n // Handle function form: model:propName={() => state.prop}\r\n else if (typeof modelBinding === \"function\") {\r\n const detected = detectAccess(modelBinding);\r\n if (detected && typeof detected[1] === 'string') {\r\n tuple = detected as [object, string];\r\n }\r\n }\r\n // Direct tuple\r\n else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === 'string') {\r\n tuple = modelBinding as [object, string];\r\n }\r\n\r\n if (tuple) {\r\n const [stateObj, stateKey] = tuple;\r\n const eventName = `onUpdate:${name}`;\r\n\r\n // Create update handler if not forwarding\r\n if (!updateHandler) {\r\n const existingHandler = processedProps[eventName];\r\n updateHandler = (v: any) => {\r\n const customHandler = (stateObj as any)[`onUpdate:${stateKey}`];\r\n if (typeof customHandler === \"function\") {\r\n customHandler(v);\r\n } else {\r\n (stateObj as any)[stateKey] = v;\r\n }\r\n if (existingHandler) existingHandler(v);\r\n };\r\n }\r\n\r\n // For components: create Model<T> object with the prop name\r\n if (isComponentType) {\r\n models[name] = createModel(tuple, updateHandler);\r\n // Keep onUpdate handler for backward compatibility\r\n processedProps[eventName] = updateHandler;\r\n } else {\r\n // For intrinsic elements: put value directly on props\r\n processedProps[name] = (stateObj as Record<string, any>)[stateKey];\r\n processedProps[eventName] = updateHandler;\r\n }\r\n delete processedProps[propKey];\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Attach models to props for component instantiation\r\n if (Object.keys(models).length > 0) {\r\n processedProps.$models = models;\r\n }\r\n\r\n // Handle sigx components - create a VNode with the component factory as type\r\n // The renderer will detect __setup and call mountComponent\r\n if (isComponent(type)) {\r\n const { children, ...rest } = processedProps;\r\n return {\r\n type: type as Function,\r\n props: { ...rest, children },\r\n key: key || rest.key || null,\r\n children: [], // Children are passed via props for components\r\n dom: null\r\n };\r\n }\r\n\r\n // Handle plain function components (not sigx component)\r\n if (typeof type === 'function' && (type as any) !== Fragment) {\r\n return (type as Function)(processedProps);\r\n }\r\n\r\n const { children, ...rest } = processedProps;\r\n\r\n const vnode: VNode = {\r\n type: type as string | typeof Fragment,\r\n props: rest,\r\n key: key || rest.key || null,\r\n children: normalizeChildren(children),\r\n dom: null\r\n };\r\n\r\n return vnode;\r\n}\r\n\r\n/**\r\n * JSX Factory for fragments\r\n */\r\nexport function jsxs(type: any, props: any, key?: any) {\r\n return jsx(type, props, key);\r\n}\r\n\r\nexport const jsxDEV = jsx;\r\n","/**\r\n * Lazy loading utilities for sigx components.\r\n * \r\n * Provides runtime-only lazy loading with no build dependencies.\r\n * Works with any bundler that supports dynamic import().\r\n */\r\n\r\nimport { component, type ComponentFactory } from './component.js';\r\nimport { jsx, type JSXElement } from './jsx-runtime.js';\r\nimport {\r\n getCurrentSuspenseBoundarySafe,\r\n setCurrentSuspenseBoundarySafe\r\n} from './async-context.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * State for a lazy-loaded component\r\n */\r\ntype LazyState = 'pending' | 'resolved' | 'rejected';\r\n\r\n/**\r\n * Module with default export\r\n */\r\ntype ModuleWithDefault<T> = { default: T };\r\n\r\n/**\r\n * Loader function that returns a component or module with default export\r\n */\r\ntype ComponentLoader<T> = () => Promise<T | ModuleWithDefault<T>>;\r\n\r\n/**\r\n * Extended component factory with lazy loading methods\r\n */\r\nexport type LazyComponentFactory<T extends ComponentFactory<any, any, any>> = T & {\r\n /** Preload the component without rendering */\r\n preload: () => Promise<T>;\r\n /** Check if the component is loaded */\r\n isLoaded: () => boolean;\r\n /** @internal Marker for lazy components */\r\n __lazy: true;\r\n};\r\n\r\n/**\r\n * Props for the Suspense component\r\n */\r\nexport type SuspenseProps = {\r\n /** Fallback content to show while loading */\r\n fallback?: JSXElement | (() => JSXElement);\r\n};\r\n\r\n// ============================================================================\r\n// Suspense Context\r\n// ============================================================================\r\n\r\n/**\r\n * Suspense boundary context for tracking pending async operations\r\n */\r\ntype SuspenseBoundary = {\r\n pending: Set<Promise<any>>;\r\n onResolve: () => void;\r\n};\r\n\r\n// Module-level fallback for browser environments\r\nlet currentSuspenseBoundary: SuspenseBoundary | null = null;\r\n\r\n/**\r\n * Register a promise with the current Suspense boundary\r\n * @internal\r\n */\r\nexport function registerPendingPromise(promise: Promise<any>): boolean {\r\n // Capture the boundary at registration time, not when promise resolves\r\n // Use async-safe storage (server) with module-level fallback (browser)\r\n const boundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;\r\n if (boundary) {\r\n boundary.pending.add(promise);\r\n promise.finally(() => {\r\n boundary.pending.delete(promise);\r\n if (boundary.pending.size === 0) {\r\n boundary.onResolve();\r\n }\r\n });\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n// ============================================================================\r\n// lazy()\r\n// ============================================================================\r\n\r\n/**\r\n * Create a lazy-loaded component wrapper.\r\n * \r\n * The component will be loaded on first render. Use with `<Suspense>` to show\r\n * a fallback while loading.\r\n * \r\n * @param loader - Function that returns a Promise resolving to the component\r\n * @returns A component factory that loads the real component on demand\r\n * \r\n * @example\r\n * ```tsx\r\n * import { lazy, Suspense } from 'sigx';\r\n * \r\n * // Component will be in a separate chunk\r\n * const HeavyChart = lazy(() => import('./components/HeavyChart'));\r\n * \r\n * // Usage\r\n * <Suspense fallback={<Spinner />}>\r\n * <HeavyChart data={chartData} />\r\n * </Suspense>\r\n * \r\n * // Preload on hover\r\n * <button onMouseEnter={() => HeavyChart.preload()}>\r\n * Show Chart\r\n * </button>\r\n * ```\r\n */\r\nexport function lazy<T extends ComponentFactory<any, any, any>>(\r\n loader: ComponentLoader<T>\r\n): LazyComponentFactory<T> {\r\n let Component: T | null = null;\r\n let promise: Promise<T> | null = null;\r\n let error: Error | null = null;\r\n let state: LazyState = 'pending';\r\n\r\n // Create a wrapper component that handles the async loading\r\n const LazyWrapper = component((ctx) => {\r\n // Use object-based signal (sigx signals wrap objects, not primitives)\r\n const loadState = ctx.signal({ state: state as LazyState, tick: 0 });\r\n\r\n // Start loading if not already started\r\n if (!promise) {\r\n promise = loader()\r\n .then((mod) => {\r\n // Handle both default exports and direct exports\r\n Component = 'default' in mod ? (mod as ModuleWithDefault<T>).default : mod;\r\n state = 'resolved';\r\n loadState.state = 'resolved';\r\n loadState.tick++;\r\n return Component;\r\n })\r\n .catch((err) => {\r\n error = err instanceof Error ? err : new Error(String(err));\r\n state = 'rejected';\r\n loadState.state = 'rejected';\r\n loadState.tick++;\r\n throw error;\r\n });\r\n } else if (state === 'pending') {\r\n // The promise was created by a previous instance that may now be\r\n // unmounted (effect stopped). Subscribe THIS instance's loadState\r\n // so it gets notified when the promise resolves.\r\n promise.then(() => {\r\n if (loadState.state === 'pending') {\r\n loadState.state = 'resolved';\r\n loadState.tick++;\r\n }\r\n }).catch(() => {\r\n if (loadState.state === 'pending') {\r\n loadState.state = 'rejected';\r\n loadState.tick++;\r\n }\r\n });\r\n }\r\n\r\n // If already resolved, render immediately\r\n if (state === 'resolved' && Component) {\r\n return () => {\r\n const Comp = Component!;\r\n return jsx(Comp, {});\r\n };\r\n }\r\n\r\n // If already rejected, throw the error\r\n if (state === 'rejected' && error) {\r\n throw error;\r\n }\r\n\r\n // Register with Suspense boundary if available\r\n const registered = registerPendingPromise(promise!);\r\n\r\n // If no Suspense boundary, handle loading state ourselves\r\n if (!registered) {\r\n promise!.catch(() => {\r\n // Error handling done in state update\r\n });\r\n }\r\n\r\n return () => {\r\n // Trigger reactivity by reading state\r\n const currentState = loadState.state;\r\n void loadState.tick;\r\n\r\n // Check current state\r\n if (currentState === 'resolved' && Component) {\r\n return jsx(Component, {});\r\n }\r\n\r\n if (currentState === 'rejected' && error) {\r\n throw error;\r\n }\r\n\r\n // Still loading - render nothing (Suspense boundary handles fallback)\r\n return null;\r\n };\r\n }, { name: 'LazyComponent' }) as unknown as LazyComponentFactory<T>;\r\n\r\n // Add lazy-specific methods\r\n (LazyWrapper as any).__lazy = true;\r\n\r\n (LazyWrapper as any).preload = (): Promise<T> => {\r\n if (!promise) {\r\n promise = loader()\r\n .then((mod) => {\r\n Component = 'default' in mod ? (mod as ModuleWithDefault<T>).default : mod;\r\n state = 'resolved';\r\n return Component;\r\n })\r\n .catch((err) => {\r\n error = err instanceof Error ? err : new Error(String(err));\r\n state = 'rejected';\r\n throw error;\r\n });\r\n }\r\n return promise;\r\n };\r\n\r\n (LazyWrapper as any).isLoaded = (): boolean => {\r\n return state === 'resolved';\r\n };\r\n\r\n return LazyWrapper as LazyComponentFactory<T>;\r\n}\r\n\r\n// ============================================================================\r\n// Suspense Component\r\n// ============================================================================\r\n\r\n/**\r\n * Suspense boundary component for handling async loading states.\r\n * \r\n * Wraps lazy-loaded components and shows a fallback while they load.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { lazy, Suspense } from 'sigx';\r\n * \r\n * const LazyDashboard = lazy(() => import('./Dashboard'));\r\n * \r\n * // Basic usage\r\n * <Suspense fallback={<div>Loading...</div>}>\r\n * <LazyDashboard />\r\n * </Suspense>\r\n * \r\n * // With spinner component\r\n * <Suspense fallback={<Spinner size=\"large\" />}>\r\n * <LazyDashboard />\r\n * <LazyCharts />\r\n * </Suspense>\r\n * ```\r\n */\r\nexport const Suspense = component<SuspenseProps>(\r\n (ctx) => {\r\n const { props, slots } = ctx;\r\n const state = ctx.signal({ isReady: false, pendingCount: 0 });\r\n\r\n // Create a Suspense boundary context\r\n const boundary: SuspenseBoundary = {\r\n pending: new Set(),\r\n onResolve: () => {\r\n state.pendingCount = boundary.pending.size;\r\n if (boundary.pending.size === 0) {\r\n state.isReady = true;\r\n }\r\n }\r\n };\r\n\r\n // Set up the boundary for child components\r\n ctx.onMounted(() => {\r\n // After first render, if no pending promises, we're ready\r\n if (boundary.pending.size === 0) {\r\n state.isReady = true;\r\n }\r\n });\r\n\r\n return () => {\r\n // Read reactive state to trigger re-render when children finish loading\r\n // This is crucial: when onResolve() sets isReady=true, this causes Suspense to re-render\r\n void state.isReady;\r\n void state.pendingCount;\r\n\r\n // Set current boundary for children to register with\r\n const prevBoundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;\r\n currentSuspenseBoundary = boundary;\r\n setCurrentSuspenseBoundarySafe(boundary);\r\n\r\n try {\r\n // Try to render children\r\n const children = slots.default();\r\n\r\n // If we have pending promises (registered during slots.default() call), show fallback\r\n // Check AFTER rendering children because that's when lazy components register\r\n if (boundary.pending.size > 0) {\r\n const fallback = props.fallback;\r\n if (typeof fallback === 'function') {\r\n return (fallback as () => JSXElement)();\r\n }\r\n return fallback ?? null;\r\n }\r\n\r\n // No pending - return children (could be an array, single element, or null)\r\n // Filter out nulls from conditional rendering\r\n if (Array.isArray(children)) {\r\n const filtered = children.filter((c: any) => c != null && c !== false && c !== true);\r\n if (filtered.length === 0) return null;\r\n if (filtered.length === 1) return filtered[0];\r\n return filtered;\r\n }\r\n\r\n return children;\r\n } catch (err) {\r\n // If a promise was thrown (Suspense protocol), handle it\r\n if (err instanceof Promise) {\r\n registerPendingPromise(err);\r\n const fallback = props.fallback;\r\n if (typeof fallback === 'function') {\r\n return (fallback as () => JSXElement)();\r\n }\r\n return fallback ?? null;\r\n }\r\n // Re-throw other errors\r\n throw err;\r\n } finally {\r\n currentSuspenseBoundary = prevBoundary;\r\n setCurrentSuspenseBoundarySafe(prevBoundary);\r\n }\r\n };\r\n },\r\n { name: 'Suspense' }\r\n);\r\n\r\n// ============================================================================\r\n// Utility: isLazyComponent\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a component is a lazy-loaded component\r\n */\r\nexport function isLazyComponent(component: any): component is LazyComponentFactory<any> {\r\n return component && component.__lazy === true;\r\n}\r\n","/**\r\n * Props accessor for component setup functions.\r\n * Provides a reactive proxy for accessing component props.\r\n */\r\n\r\nimport { PropsAccessor } from '../component.js';\r\n\r\n/**\r\n * Creates a props accessor - a simple reactive proxy for props.\r\n * Use destructuring with defaults for optional props.\r\n * \r\n * @example\r\n * ```ts\r\n * // In component setup:\r\n * const { count = 0, label = 'Default' } = ctx.props;\r\n * \r\n * // Or spread to forward props\r\n * <ChildComponent {...ctx.props} />\r\n * ```\r\n */\r\nexport function createPropsAccessor<TProps extends Record<string, any>>(\r\n reactiveProps: TProps\r\n): PropsAccessor<TProps> {\r\n const handler: ProxyHandler<TProps> = {\r\n get(target, key: string | symbol) {\r\n if (typeof key === 'symbol') return undefined;\r\n return (target as any)[key];\r\n },\r\n\r\n has(target, key: string | symbol) {\r\n if (typeof key === 'symbol') return false;\r\n return key in target;\r\n },\r\n\r\n ownKeys(target) {\r\n return Object.keys(target);\r\n },\r\n\r\n getOwnPropertyDescriptor(target, key: string | symbol) {\r\n if (typeof key === 'symbol') return undefined;\r\n if (key in target) {\r\n return { enumerable: true, configurable: true, writable: false };\r\n }\r\n return undefined;\r\n }\r\n };\r\n\r\n // Use a regular object as the proxy target - enables spreading\r\n const proxy = new Proxy(reactiveProps, handler);\r\n\r\n return proxy as PropsAccessor<TProps>;\r\n}\r\n","/**\r\n * Slots system for component children.\r\n * Supports default and named slots with reactivity.\r\n */\r\n\r\nimport { signal } from '@sigx/reactivity';\r\n\r\n/**\r\n * Internal slots object with tracking properties\r\n */\r\nexport interface InternalSlotsObject {\r\n default: () => any[];\r\n _children: any;\r\n _version: { v: number };\r\n _slotsFromProps: Record<string, any>;\r\n _isPatching?: boolean;\r\n [key: string]: any;\r\n}\r\n\r\n/**\r\n * Create slots object from children and slots prop.\r\n * Uses a version signal to trigger re-renders when children change.\r\n * \r\n * Supports named slots via:\r\n * - `slots` prop object (e.g., `slots={{ header: () => <div>...</div> }}`)\r\n * - `slot` prop on children (e.g., `<div slot=\"header\">...</div>`)\r\n * \r\n * @example\r\n * ```tsx\r\n * // Parent component\r\n * <Card slots={{ header: () => <h1>Title</h1> }}>\r\n * <p>Default content</p>\r\n * <span slot=\"footer\">Footer text</span>\r\n * </Card>\r\n * \r\n * // Card component setup\r\n * const slots = createSlots(children, slotsFromProps);\r\n * return () => (\r\n * <div>\r\n * {slots.header()}\r\n * {slots.default()}\r\n * {slots.footer()}\r\n * </div>\r\n * );\r\n * ```\r\n */\r\nexport function createSlots(children: any, slotsFromProps?: Record<string, any>): InternalSlotsObject {\r\n // Use a simple version signal - bump version to trigger reactivity\r\n const versionSignal = signal({ v: 0 });\r\n\r\n // Extract named slots from children with slot prop\r\n function extractNamedSlotsFromChildren(c: any): { defaultChildren: any[]; namedSlots: Record<string, any[]> } {\r\n const defaultChildren: any[] = [];\r\n const namedSlots: Record<string, any[]> = {};\r\n\r\n if (c == null) return { defaultChildren, namedSlots };\r\n\r\n const items = Array.isArray(c) ? c : [c];\r\n\r\n for (const child of items) {\r\n if (child && typeof child === 'object' && child.props && child.props.slot) {\r\n const slotName = child.props.slot;\r\n if (!namedSlots[slotName]) {\r\n namedSlots[slotName] = [];\r\n }\r\n namedSlots[slotName].push(child);\r\n } else {\r\n defaultChildren.push(child);\r\n }\r\n }\r\n\r\n return { defaultChildren, namedSlots };\r\n }\r\n\r\n const slotsObj = {\r\n _children: children,\r\n _slotsFromProps: slotsFromProps || {},\r\n _version: versionSignal,\r\n _isPatching: false, // Flag to prevent infinite loops during patching\r\n default: function () {\r\n // Reading version creates a reactive dependency\r\n void this._version.v;\r\n const c = this._children;\r\n const { defaultChildren } = extractNamedSlotsFromChildren(c);\r\n // Filter out null, undefined, false, true (conditional rendering results)\r\n return defaultChildren.filter((child: any) => child != null && child !== false && child !== true);\r\n }\r\n };\r\n\r\n // Create a proxy to handle named slot access dynamically\r\n return new Proxy(slotsObj, {\r\n get(target, prop) {\r\n if (prop in target) {\r\n return (target as any)[prop];\r\n }\r\n\r\n // Handle named slot access\r\n if (typeof prop === 'string') {\r\n return function (scopedProps?: any) {\r\n // Reading version creates a reactive dependency\r\n const _ = target._version.v;\r\n\r\n // First check for slots from the `slots` prop\r\n if (target._slotsFromProps && typeof target._slotsFromProps[prop] === 'function') {\r\n const result = target._slotsFromProps[prop](scopedProps);\r\n if (result == null) return [];\r\n return Array.isArray(result) ? result : [result];\r\n }\r\n\r\n // Then check for element-based slots (children with slot prop)\r\n const { namedSlots } = extractNamedSlotsFromChildren(target._children);\r\n return namedSlots[prop] || [];\r\n };\r\n }\r\n\r\n return undefined;\r\n }\r\n }) as InternalSlotsObject;\r\n}\r\n","/**\r\n * VNode normalization utilities.\r\n * Converts render results into proper VNode structures.\r\n */\r\n\r\nimport { isComputed } from '@sigx/reactivity';\r\nimport { VNode, Fragment, Text, JSXElement } from '../jsx-runtime.js';\r\n\r\n/**\r\n * Normalize render result to a VNode (wrapping arrays in Fragment).\r\n * Handles null, undefined, false, true by returning an empty Text node.\r\n * \r\n * This is used to normalize the return value of component render functions\r\n * into a consistent VNode structure for the renderer to process.\r\n * \r\n * @example\r\n * ```ts\r\n * // Conditional rendering returns null/false\r\n * normalizeSubTree(null) // → empty Text node\r\n * normalizeSubTree(false) // → empty Text node\r\n * \r\n * // Arrays become Fragments\r\n * normalizeSubTree([<A/>, <B/>]) // → Fragment with children\r\n * \r\n * // Primitives become Text nodes\r\n * normalizeSubTree(\"hello\") // → Text node\r\n * normalizeSubTree(42) // → Text node\r\n * \r\n * // Computed signals are auto-unwrapped\r\n * normalizeSubTree(computed(() => \"hi\")) // → Text node with \"hi\"\r\n * \r\n * // VNodes pass through\r\n * normalizeSubTree(<div/>) // → same VNode\r\n * ```\r\n */\r\nexport function normalizeSubTree(result: JSXElement | JSXElement[] | null | undefined | boolean | (() => any)): VNode {\r\n // Handle falsy values from conditional rendering\r\n if (result == null || result === false || result === true) {\r\n return {\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: ''\r\n };\r\n }\r\n\r\n // Auto-unwrap computed signals\r\n if (isComputed(result)) {\r\n return normalizeSubTree(result.value as JSXElement | JSXElement[] | (() => any) | undefined);\r\n }\r\n\r\n if (Array.isArray(result)) {\r\n return {\r\n type: Fragment,\r\n props: {},\r\n key: null,\r\n children: result as VNode[],\r\n dom: null\r\n };\r\n }\r\n\r\n if (typeof result === 'string' || typeof result === 'number') {\r\n return {\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: result\r\n };\r\n }\r\n\r\n return result as VNode;\r\n}\r\n","/**\r\n * Hydration utilities for SSR\r\n * \r\n * These utilities are shared between server-side rendering (stream.ts)\r\n * and client-side hydration (hydrate.ts). They are placed in runtime-core\r\n * to allow any SSR implementation to use them.\r\n * \r\n * @module\r\n */\r\n\r\n/**\r\n * Client directive prefix used for selective hydration\r\n */\r\nexport const CLIENT_DIRECTIVE_PREFIX = 'client:';\r\n\r\n/**\r\n * Valid client directive names\r\n */\r\nexport const CLIENT_DIRECTIVES = [\r\n 'client:load',\r\n 'client:idle',\r\n 'client:visible',\r\n 'client:media',\r\n 'client:only'\r\n] as const;\r\n\r\nexport type ClientDirective = typeof CLIENT_DIRECTIVES[number];\r\n\r\n/**\r\n * Hydration strategies for client directives\r\n */\r\nexport type HydrationStrategy = 'load' | 'idle' | 'visible' | 'media' | 'only';\r\n\r\n/**\r\n * Result of getHydrationDirective\r\n */\r\nexport interface HydrationDirective {\r\n strategy: HydrationStrategy;\r\n media?: string;\r\n}\r\n\r\n/**\r\n * Filter out client directives from props.\r\n * Used to get the actual component props without hydration hints.\r\n * \r\n * @example\r\n * ```ts\r\n * const props = { 'client:visible': true, name: 'test', count: 5 };\r\n * filterClientDirectives(props); // { name: 'test', count: 5 }\r\n * ```\r\n */\r\nexport function filterClientDirectives(props: Record<string, any>): Record<string, any> {\r\n const filtered: Record<string, any> = {};\r\n for (const key in props) {\r\n if (!key.startsWith(CLIENT_DIRECTIVE_PREFIX)) {\r\n filtered[key] = props[key];\r\n }\r\n }\r\n return filtered;\r\n}\r\n\r\n/**\r\n * Get hydration directive from props.\r\n * Returns the strategy and optional media query for client:media.\r\n * \r\n * @example\r\n * ```ts\r\n * getHydrationDirective({ 'client:visible': true }); // { strategy: 'visible' }\r\n * getHydrationDirective({ 'client:media': '(min-width: 768px)' }); // { strategy: 'media', media: '(min-width: 768px)' }\r\n * getHydrationDirective({ name: 'test' }); // null\r\n * ```\r\n */\r\nexport function getHydrationDirective(props: Record<string, any>): HydrationDirective | null {\r\n if (props['client:load'] !== undefined) return { strategy: 'load' };\r\n if (props['client:idle'] !== undefined) return { strategy: 'idle' };\r\n if (props['client:visible'] !== undefined) return { strategy: 'visible' };\r\n if (props['client:only'] !== undefined) return { strategy: 'only' };\r\n if (props['client:media'] !== undefined) {\r\n return { strategy: 'media', media: props['client:media'] };\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Check if props contain any client directive.\r\n * \r\n * @example\r\n * ```ts\r\n * hasClientDirective({ 'client:visible': true }); // true\r\n * hasClientDirective({ name: 'test' }); // false\r\n * ```\r\n */\r\nexport function hasClientDirective(props: Record<string, any>): boolean {\r\n for (const key in props) {\r\n if (key.startsWith(CLIENT_DIRECTIVE_PREFIX)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Serialize props for client hydration.\r\n * Filters out non-serializable values (functions, symbols, undefined).\r\n * Returns undefined if no serializable props remain.\r\n * \r\n * @example\r\n * ```ts\r\n * serializeProps({ name: 'test', onClick: () => {} }); // { name: 'test' }\r\n * serializeProps({ onClick: () => {} }); // undefined\r\n * ```\r\n */\r\nexport function serializeProps(props: Record<string, any>): Record<string, any> | undefined {\r\n const filtered = filterClientDirectives(props);\r\n\r\n const result: Record<string, any> = {};\r\n let hasProps = false;\r\n\r\n for (const key in filtered) {\r\n const value = filtered[key];\r\n\r\n // Skip internal props\r\n if (key === 'children' || key === 'key' || key === 'ref' || key === 'slots') continue;\r\n\r\n // Skip functions (event handlers, etc.)\r\n if (typeof value === 'function') continue;\r\n\r\n // Skip symbols\r\n if (typeof value === 'symbol') continue;\r\n\r\n // Skip undefined values\r\n if (value === undefined) continue;\r\n\r\n // Skip event handlers (on* props)\r\n if (key.startsWith('on') && key.length > 2 && key[2] === key[2].toUpperCase()) continue;\r\n\r\n // Try to serialize - skip if fails\r\n try {\r\n JSON.stringify(value);\r\n result[key] = value;\r\n hasProps = true;\r\n } catch {\r\n // Non-serializable, skip\r\n }\r\n }\r\n\r\n return hasProps ? result : undefined;\r\n}\r\n\r\n/**\r\n * Create an emit function for component context.\r\n * This is a common pattern used in both mountComponent and hydrateComponent.\r\n * \r\n * @example\r\n * ```ts\r\n * const emit = createEmit(reactiveProps);\r\n * emit('click', eventData); // Calls props.onClick(eventData)\r\n * ```\r\n */\r\nexport function createEmit(reactiveProps: { value?: Record<string, any> } | Record<string, any>): (event: string, ...args: any[]) => void {\r\n return (event: string, ...args: any[]) => {\r\n const eventName = `on${event[0].toUpperCase() + event.slice(1)}`;\r\n // Handle both signal-wrapped props and plain props\r\n const props = 'value' in reactiveProps ? reactiveProps.value : reactiveProps;\r\n const handler = props?.[eventName];\r\n if (handler && typeof handler === 'function') {\r\n handler(...args);\r\n }\r\n };\r\n}\r\n","import { VNode, Fragment, JSXElement, Text } from './jsx-runtime.js';\r\nimport { effect, signal, untrack, EffectRunner } from '@sigx/reactivity';\r\nimport { ComponentSetupContext, setCurrentInstance, getCurrentInstance, MountContext, ViewFn, SetupFn } from './component.js';\r\nimport { createPropsAccessor } from './utils/props-accessor.js';\r\nimport { createSlots, InternalSlotsObject } from './utils/slots.js';\r\nimport { normalizeSubTree } from './utils/normalize.js';\r\nimport { applyContextExtensions } from './plugins.js';\r\nimport { isComponent } from './utils/is-component.js';\r\nimport { createEmit } from './hydration/index.js';\r\nimport { provideAppContext } from './di/injectable.js';\r\nimport { isModel } from './model.js';\r\nimport {\r\n AppContext,\r\n ComponentInstance,\r\n notifyComponentCreated,\r\n notifyComponentMounted,\r\n notifyComponentUnmounted,\r\n notifyComponentUpdated,\r\n handleComponentError\r\n} from './app.js';\r\n\r\n/**\r\n * Internal VNode with renderer-specific properties.\r\n * These properties are used by the renderer to track component state\r\n * but are not part of the public VNode API.\r\n */\r\nexport interface InternalVNode extends VNode {\r\n /** The reactive effect that re-renders the component */\r\n _effect?: EffectRunner;\r\n /** The rendered sub-tree VNode of a component */\r\n _subTree?: VNode | null;\r\n /**\r\n * Shared mutable reference to the current sub-tree.\r\n * Used to keep _subTree in sync across VNode replacements during same-type patches.\r\n * The effect closure writes to this ref, and all aliased VNodes share it.\r\n */\r\n _subTreeRef?: { current: VNode | null };\r\n /** The slots object for component children */\r\n _slots?: InternalSlotsObject;\r\n /** Reactive props signal for the component */\r\n _componentProps?: Record<string, any>;\r\n}\r\n\r\n// InternalSlotsObject is now imported from component-helpers.ts\r\n\r\n/**\r\n * Container element with internal VNode storage\r\n */\r\ninterface InternalContainer {\r\n _vnode?: VNode | null;\r\n}\r\n\r\n/**\r\n * Host node with back-reference to VNode\r\n */\r\ninterface InternalHostNode {\r\n __vnode?: VNode;\r\n}\r\n\r\n/**\r\n * Component factory function with setup and optional name\r\n */\r\ninterface ComponentFactory {\r\n __setup: SetupFn<any, any, any, any>;\r\n __name?: string;\r\n}\r\n\r\n/**\r\n * Internal component context with debug properties\r\n */\r\ninterface InternalComponentContext extends ComponentSetupContext {\r\n __name?: string;\r\n}\r\n\r\n// isComponent is imported from ./utils/is-component.js and re-exported\r\nexport { isComponent } from './utils/is-component.js';\r\n\r\nexport interface RendererOptions<HostNode = any, HostElement = any> {\r\n patchProp(el: HostElement, key: string, prevValue: any, nextValue: any, isSVG?: boolean): void;\r\n insert(child: HostNode, parent: HostElement, anchor?: HostNode | null): void;\r\n remove(child: HostNode): void;\r\n createElement(type: string, isSVG?: boolean, isCustomizedBuiltIn?: string): HostElement;\r\n createText(text: string): HostNode;\r\n createComment(text: string): HostNode;\r\n setText(node: HostNode, text: string): void;\r\n setElementText(node: HostElement, text: string): void;\r\n parentNode(node: HostNode): HostElement | null;\r\n nextSibling(node: HostNode): HostNode | null;\r\n querySelector?(selector: string): HostElement | null;\r\n setScopeId?(el: HostElement, id: string): void;\r\n cloneNode?(node: HostNode): HostNode;\r\n insertStaticContent?(content: string, parent: HostElement, anchor: HostNode | null, isSVG: boolean): [HostNode, HostNode];\r\n\r\n /**\r\n * Optional hook to handle `use:*` directive props.\r\n * Called by the core renderer for each `use:*` prop during mount and patch.\r\n * The platform renderer (e.g., runtime-dom) implements directive lifecycle logic here.\r\n * @param appContext - The current app context, used to resolve custom directives registered via `app.directive()`.\r\n */\r\n patchDirective?(el: HostElement, name: string, prevValue: any, nextValue: any, appContext: AppContext | null): void;\r\n\r\n /**\r\n * Optional hook called after an element is inserted into the DOM.\r\n * Used by runtime-dom for directive `mounted` lifecycle.\r\n */\r\n onElementMounted?(el: HostElement): void;\r\n\r\n /**\r\n * Optional hook called before an element is removed from the DOM.\r\n * Used by runtime-dom for directive `unmounted` lifecycle.\r\n */\r\n onElementUnmounted?(el: HostElement): void;\r\n\r\n /**\r\n * Optional hook to get the currently focused element.\r\n * Used to preserve focus across patch cycles.\r\n */\r\n getActiveElement?(): HostElement | null;\r\n\r\n /**\r\n * Optional hook to restore focus to a previously focused element.\r\n * Called after patching if the active element changed.\r\n */\r\n restoreFocus?(el: HostElement): void;\r\n}\r\n\r\nexport type RootRenderFunction<_HostNode = any, HostElement = any> = (\r\n vnode: JSXElement,\r\n container: HostElement,\r\n appContext?: AppContext\r\n) => void;\r\n\r\n/**\r\n * Function types for renderer operations exposed for plugins/hydration\r\n */\r\nexport type RendererMountFn<HostNode = any, HostElement = any> = (\r\n vnode: VNode,\r\n container: HostElement,\r\n before?: HostNode | null\r\n) => void;\r\n\r\nexport type RendererUnmountFn<_HostNode = any, HostElement = any> = (\r\n vnode: VNode,\r\n container: HostElement\r\n) => void;\r\n\r\nexport type RendererPatchFn<_HostNode = any, HostElement = any> = (\r\n n1: VNode,\r\n n2: VNode,\r\n container: HostElement\r\n) => void;\r\n\r\nexport type RendererMountComponentFn<HostNode = any, HostElement = any> = (\r\n vnode: VNode,\r\n container: HostElement,\r\n before: HostNode | null,\r\n setup: SetupFn<any, any, any, any>\r\n) => void;\r\n\r\n/**\r\n * Renderer instance returned by createRenderer\r\n */\r\nexport interface Renderer<HostNode = any, HostElement = any> {\r\n render: RootRenderFunction<HostNode, HostElement>;\r\n patch: RendererPatchFn<HostNode, HostElement>;\r\n mount: RendererMountFn<HostNode, HostElement>;\r\n unmount: RendererUnmountFn<HostNode, HostElement>;\r\n mountComponent: RendererMountComponentFn<HostNode, HostElement>;\r\n}\r\n\r\nexport function createRenderer<HostNode = any, HostElement = any>(\r\n options: RendererOptions<HostNode, HostElement>\r\n): Renderer<HostNode, HostElement> {\r\n const {\r\n insert: hostInsert,\r\n remove: hostRemove,\r\n patchProp: hostPatchProp,\r\n createElement: hostCreateElement,\r\n createText: hostCreateText,\r\n createComment: hostCreateComment,\r\n setText: hostSetText,\r\n setElementText: _hostSetElementText,\r\n parentNode: hostParentNode,\r\n nextSibling: hostNextSibling,\r\n cloneNode: _hostCloneNode,\r\n insertStaticContent: _hostInsertStaticContent,\r\n patchDirective: hostPatchDirective,\r\n onElementMounted: hostOnElementMounted,\r\n onElementUnmounted: hostOnElementUnmounted,\r\n getActiveElement: hostGetActiveElement,\r\n restoreFocus: hostRestoreFocus\r\n } = options;\r\n\r\n // Current app context (set when rendering via defineApp)\r\n let currentAppContext: AppContext | null = null;\r\n\r\n function render(element: JSXElement, container: HostElement, appContext?: AppContext): void {\r\n // Store app context for this render tree\r\n const _prevAppContext = currentAppContext;\r\n if (appContext) {\r\n currentAppContext = appContext;\r\n }\r\n\r\n const oldVNode = (container as unknown as InternalContainer)._vnode;\r\n\r\n // Normalize element to VNode if it's not\r\n let vnode: VNode | null = null;\r\n if (element != null && element !== false && element !== true) {\r\n if (typeof element === 'string' || typeof element === 'number') {\r\n vnode = {\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: element\r\n };\r\n } else if (isComponent(element)) {\r\n // Handle component factory passed directly (e.g., defineApp(Counter))\r\n vnode = {\r\n type: element as unknown as VNode['type'],\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null\r\n };\r\n } else {\r\n vnode = element as VNode;\r\n }\r\n }\r\n\r\n if (vnode) {\r\n if (oldVNode) {\r\n patch(oldVNode, vnode, container);\r\n } else {\r\n mount(vnode, container);\r\n }\r\n (container as unknown as InternalContainer)._vnode = vnode;\r\n } else {\r\n if (oldVNode) {\r\n unmount(oldVNode, container);\r\n (container as unknown as InternalContainer)._vnode = null;\r\n }\r\n }\r\n }\r\n\r\n // SVG elements that should be created with createElementNS\r\n const svgTags = new Set([\r\n 'svg', 'animate', 'animateMotion', 'animateTransform', 'circle', 'clipPath',\r\n 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer',\r\n 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap',\r\n 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG',\r\n 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology',\r\n 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile',\r\n 'feTurbulence', 'filter', 'foreignObject', 'g', 'image', 'line', 'linearGradient',\r\n 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline',\r\n 'radialGradient', 'rect', 'set', 'stop', 'switch', 'symbol', 'text', 'textPath',\r\n 'title', 'tspan', 'use', 'view'\r\n ]);\r\n\r\n function isSvgTag(tag: string): boolean {\r\n return svgTags.has(tag);\r\n }\r\n function mount(vnode: VNode, container: HostElement, before: HostNode | null = null, parentIsSVG: boolean = false): void {\r\n // Guard against null, undefined, boolean values (from conditional rendering)\r\n if (vnode == null || vnode === (false as unknown as VNode) || vnode === (true as unknown as VNode)) {\r\n return;\r\n }\r\n\r\n if (vnode.type === Text) {\r\n const node = hostCreateText(String(vnode.text));\r\n vnode.dom = node;\r\n (node as unknown as InternalHostNode).__vnode = vnode;\r\n hostInsert(node, container, before);\r\n return;\r\n }\r\n\r\n if (vnode.type === Fragment) {\r\n // For fragments, we need a way to track the children's DOM nodes\r\n // Store the anchor comment for fragments\r\n const anchor = hostCreateComment('');\r\n vnode.dom = anchor;\r\n hostInsert(anchor, container, before);\r\n if (vnode.children) {\r\n vnode.children.forEach((child: VNode) => mount(child, container, anchor, parentIsSVG));\r\n }\r\n return;\r\n }\r\n\r\n // Check for component (function with __setup)\r\n if (isComponent(vnode.type)) {\r\n mountComponent(vnode, container, before, vnode.type.__setup as SetupFn);\r\n return;\r\n }\r\n\r\n // Determine if this element should be created as SVG\r\n const tag = vnode.type as string;\r\n const isSVG = tag === 'svg' || (parentIsSVG && tag !== 'foreignObject');\r\n\r\n const element = hostCreateElement(tag, isSVG);\r\n vnode.dom = element;\r\n (element as unknown as InternalHostNode).__vnode = vnode;\r\n\r\n // Props\r\n if (vnode.props) {\r\n for (const key in vnode.props) {\r\n if (key !== 'children' && key !== 'key' && key !== 'ref') {\r\n if (key.charCodeAt(0) === 117 /* 'u' */ && key.startsWith('use:')) {\r\n // Delegate use:* directive props to the platform renderer\r\n if (hostPatchDirective) {\r\n hostPatchDirective(element, key.slice(4), null, vnode.props[key], currentAppContext);\r\n }\r\n } else {\r\n hostPatchProp(element, key, null, vnode.props[key], isSVG);\r\n }\r\n }\r\n }\r\n\r\n // Handle ref - wrap in untrack to prevent reactive loops\r\n if (vnode.props.ref) {\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(element);\r\n } else if (typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = element;\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Children - pass SVG context (reset for foreignObject)\r\n const childIsSVG = isSVG && tag !== 'foreignObject';\r\n if (vnode.children) {\r\n vnode.children.forEach((child: VNode) => {\r\n child.parent = vnode;\r\n mount(child, element, null, childIsSVG)\r\n });\r\n }\r\n\r\n hostInsert(element as unknown as HostNode, container, before);\r\n\r\n // Invoke platform element lifecycle (e.g., directive mounted hooks in runtime-dom)\r\n if (hostOnElementMounted) {\r\n hostOnElementMounted(element);\r\n }\r\n }\r\n\r\n function unmount(vnode: VNode, container: HostElement): void {\r\n const internalVNode = vnode as InternalVNode;\r\n if (internalVNode._effect) {\r\n internalVNode._effect.stop(); // Stop effect\r\n }\r\n\r\n if (vnode.cleanup) {\r\n vnode.cleanup();\r\n }\r\n\r\n // Handle component unmount - unmount its subTree\r\n if (isComponent(vnode.type)) {\r\n // Use the shared subtree ref if available (handles stale _subTree after same-type patches)\r\n const subTree = internalVNode._subTreeRef?.current ?? internalVNode._subTree;\r\n if (subTree) {\r\n unmount(subTree, container);\r\n }\r\n // Remove the anchor comment\r\n if (vnode.dom) {\r\n hostRemove(vnode.dom);\r\n }\r\n // Handle ref cleanup - wrap in untrack to prevent reactive loops\r\n if (vnode.props?.ref) {\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(null);\r\n } else if (typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = null;\r\n }\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (vnode.type === Fragment) {\r\n if (vnode.children) {\r\n vnode.children.forEach((child: VNode) => unmount(child, container));\r\n }\r\n // Remove anchor comment if exists\r\n if (vnode.dom) {\r\n hostRemove(vnode.dom);\r\n }\r\n return;\r\n }\r\n\r\n // Handle ref cleanup - wrap in untrack to prevent reactive loops\r\n if (vnode.props?.ref) {\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(null);\r\n } else if (vnode.props.ref && typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = null;\r\n }\r\n });\r\n }\r\n\r\n // Invoke platform element lifecycle (e.g., directive unmounted hooks in runtime-dom)\r\n if (hostOnElementUnmounted && vnode.dom) {\r\n hostOnElementUnmounted(vnode.dom);\r\n }\r\n\r\n // Recursively unmount children for regular elements\r\n if (vnode.children && vnode.children.length > 0) {\r\n vnode.children.forEach((child: VNode) => unmount(child, vnode.dom as HostElement));\r\n }\r\n\r\n if (vnode.dom) {\r\n hostRemove(vnode.dom);\r\n }\r\n }\r\n\r\n function patch(oldVNode: VNode, newVNode: VNode, container: HostElement): void {\r\n if (oldVNode === newVNode) return;\r\n\r\n // If types are different, replace completely\r\n if (!isSameVNode(oldVNode, newVNode)) {\r\n const parent = hostParentNode(oldVNode.dom) || container;\r\n // With unified trailing markers, vnode.dom is always the trailing anchor\r\n // so hostNextSibling gives us the correct insertion point\r\n const nextSibling = oldVNode.dom ? hostNextSibling(oldVNode.dom) : null;\r\n unmount(oldVNode, parent as HostElement);\r\n mount(newVNode, parent as HostElement, nextSibling);\r\n return;\r\n }\r\n\r\n // If component\r\n const oldInternal = oldVNode as InternalVNode;\r\n const newInternal = newVNode as InternalVNode;\r\n if (oldInternal._effect) {\r\n newVNode.dom = oldVNode.dom;\r\n newInternal._effect = oldInternal._effect;\r\n newInternal._subTree = oldInternal._subTree;\r\n newInternal._subTreeRef = oldInternal._subTreeRef;\r\n newInternal._slots = oldInternal._slots;\r\n\r\n const props = oldInternal._componentProps;\r\n newInternal._componentProps = props;\r\n\r\n if (props) {\r\n const newProps = newVNode.props || {};\r\n const newModels = newVNode.props?.$models || {};\r\n \r\n // Update props (excluding children, key, ref, $models)\r\n // Also update Model objects from $models into props\r\n untrack(() => {\r\n for (const key in newProps) {\r\n if (key !== \"children\" && key !== \"key\" && key !== \"ref\" && key !== \"$models\") {\r\n if (props[key] !== newProps[key]) {\r\n props[key] = newProps[key];\r\n }\r\n }\r\n }\r\n \r\n // Merge updated Model objects into props\r\n // Only update if the binding changed (different obj or key)\r\n for (const modelKey in newModels) {\r\n const newModel = newModels[modelKey];\r\n const oldModel = props[modelKey];\r\n if (isModel(newModel)) {\r\n // Skip update if binding is the same (same obj and key)\r\n if (isModel(oldModel)) {\r\n const [newObj, newKey] = newModel.binding;\r\n const [oldObj, oldKey] = oldModel.binding;\r\n if (newObj === oldObj && newKey === oldKey) {\r\n continue; // Same binding, reuse old Model\r\n }\r\n }\r\n props[modelKey] = newModel;\r\n }\r\n }\r\n \r\n // Handle removed props (optional but good)\r\n for (const key in props) {\r\n if (!(key in newProps) && !(key in newModels) && key !== \"children\" && key !== \"key\" && key !== \"ref\" && key !== \"$models\") {\r\n delete props[key];\r\n }\r\n }\r\n });\r\n }\r\n\r\n // Update slots with new children and slot functions\r\n const slotsRef = oldInternal._slots;\r\n const newChildren = newVNode.props?.children;\r\n const newSlotsFromProps = newVNode.props?.slots;\r\n\r\n if (slotsRef) {\r\n // Update children for default slot\r\n if (newChildren !== undefined) {\r\n slotsRef._children = newChildren;\r\n }\r\n\r\n // Update slot functions from the slots prop\r\n if (newSlotsFromProps !== undefined) {\r\n slotsRef._slotsFromProps = newSlotsFromProps;\r\n }\r\n\r\n // Trigger component re-render by bumping version\r\n // Use per-component flag to prevent infinite loops on the SAME component\r\n // but allow nested components to update\r\n if (!slotsRef._isPatching) {\r\n slotsRef._isPatching = true;\r\n try {\r\n untrack(() => {\r\n slotsRef._version.v++;\r\n });\r\n } finally {\r\n slotsRef._isPatching = false;\r\n }\r\n }\r\n }\r\n\r\n return;\r\n }\r\n\r\n // If text node\r\n if (newVNode.type === Text) {\r\n newVNode.dom = oldVNode.dom;\r\n \r\n // Guard: if old text node has no DOM (can happen during hydration mismatch),\r\n // create a fresh text node instead of crashing\r\n if (!newVNode.dom) {\r\n const textNode = hostCreateText(String(newVNode.text));\r\n newVNode.dom = textNode;\r\n // Try to insert into container if possible\r\n if (container) {\r\n hostInsert(textNode, container, oldVNode.dom || null);\r\n }\r\n return;\r\n }\r\n \r\n if (oldVNode.text !== newVNode.text) {\r\n hostSetText(newVNode.dom, String(newVNode.text));\r\n }\r\n return;\r\n }\r\n\r\n // If Fragment\r\n if (newVNode.type === Fragment) {\r\n patchChildren(oldVNode, newVNode, container, false);\r\n return;\r\n }\r\n\r\n // Element\r\n const element = (newVNode.dom = oldVNode.dom) as HostElement;\r\n \r\n // Guard: if old element has no DOM (can happen with hydrated slot content),\r\n // recover by mounting fresh instead of crashing\r\n if (!element) {\r\n mount(newVNode, container);\r\n return;\r\n }\r\n \r\n // Determine if this is an SVG element (for proper attribute handling)\r\n const tag = newVNode.type as string;\r\n const isSVG = tag === 'svg' || isSvgTag(tag);\r\n\r\n // Update props\r\n const oldProps = oldVNode.props || {};\r\n const newProps = newVNode.props || {};\r\n\r\n // Remove old props\r\n for (const key in oldProps) {\r\n if (!(key in newProps) && key !== 'children' && key !== 'key' && key !== 'ref') {\r\n if (key.charCodeAt(0) === 117 /* 'u' */ && key.startsWith('use:')) {\r\n if (hostPatchDirective) {\r\n hostPatchDirective(element, key.slice(4), oldProps[key], null, currentAppContext);\r\n }\r\n } else {\r\n hostPatchProp(element, key, oldProps[key], null, isSVG);\r\n }\r\n }\r\n }\r\n\r\n // Set new props\r\n for (const key in newProps) {\r\n const oldValue = oldProps[key];\r\n const newValue = newProps[key];\r\n if (key !== 'children' && key !== 'key' && key !== 'ref' && oldValue !== newValue) {\r\n if (key.charCodeAt(0) === 117 /* 'u' */ && key.startsWith('use:')) {\r\n if (hostPatchDirective) {\r\n hostPatchDirective(element, key.slice(4), oldValue, newValue, currentAppContext);\r\n }\r\n } else {\r\n hostPatchProp(element, key, oldValue, newValue, isSVG);\r\n }\r\n }\r\n }\r\n\r\n // Update children - pass SVG context for child elements (reset for foreignObject)\r\n const childIsSVG = isSVG && tag !== 'foreignObject';\r\n patchChildren(oldVNode, newVNode, element, childIsSVG);\r\n }\r\n\r\n function patchChildren(oldVNode: VNode, newVNode: VNode, container: HostElement, parentIsSVG: boolean = false) {\r\n const oldChildren = oldVNode.children;\r\n const newChildren = newVNode.children;\r\n\r\n newChildren.forEach((c: VNode) => c.parent = newVNode);\r\n\r\n reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);\r\n }\r\n\r\n /**\r\n * Check for duplicate keys in an array of VNodes and warn in development.\r\n */\r\n function checkDuplicateKeys(children: VNode[]): void {\r\n if (process.env.NODE_ENV === 'production') return;\r\n \r\n const seenKeys = new Set<string>();\r\n for (const child of children) {\r\n if (child?.key != null) {\r\n const keyStr = String(child.key);\r\n if (seenKeys.has(keyStr)) {\r\n console.warn(\r\n `[SignalX] Duplicate key \"${child.key}\" detected in list. ` +\r\n `Keys should be unique among siblings to ensure correct reconciliation. ` +\r\n `This may cause unexpected behavior when items are reordered, added, or removed.`\r\n );\r\n }\r\n seenKeys.add(keyStr);\r\n }\r\n }\r\n }\r\n\r\n function reconcileChildrenArray(parent: HostElement, oldChildren: VNode[], newChildren: VNode[], parentIsSVG: boolean = false) {\r\n // Check for duplicate keys in development\r\n if (process.env.NODE_ENV !== 'production') {\r\n checkDuplicateKeys(newChildren);\r\n }\r\n\r\n let oldStartIdx = 0;\r\n let oldEndIdx = oldChildren.length - 1;\r\n let oldStartVNode = oldChildren[0];\r\n let oldEndVNode = oldChildren[oldEndIdx];\r\n\r\n let newStartIdx = 0;\r\n let newEndIdx = newChildren.length - 1;\r\n let newStartVNode = newChildren[0];\r\n let newEndVNode = newChildren[newEndIdx];\r\n\r\n let oldKeyToIdx: Map<string | number, number> | undefined;\r\n\r\n while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\r\n if (oldStartVNode == null) {\r\n oldStartVNode = oldChildren[++oldStartIdx];\r\n } else if (oldEndVNode == null) {\r\n oldEndVNode = oldChildren[--oldEndIdx];\r\n } else if (isSameVNode(oldStartVNode, newStartVNode)) {\r\n patch(oldStartVNode, newStartVNode, parent);\r\n oldStartVNode = oldChildren[++oldStartIdx];\r\n newStartVNode = newChildren[++newStartIdx];\r\n } else if (isSameVNode(oldEndVNode, newEndVNode)) {\r\n patch(oldEndVNode, newEndVNode, parent);\r\n oldEndVNode = oldChildren[--oldEndIdx];\r\n newEndVNode = newChildren[--newEndIdx];\r\n } else if (isSameVNode(oldStartVNode, newEndVNode)) {\r\n patch(oldStartVNode, newEndVNode, parent);\r\n const nodeToMove = oldStartVNode.dom;\r\n const anchor = hostNextSibling(oldEndVNode.dom);\r\n if (nodeToMove) {\r\n hostInsert(nodeToMove, parent, anchor);\r\n }\r\n oldStartVNode = oldChildren[++oldStartIdx];\r\n newEndVNode = newChildren[--newEndIdx];\r\n } else if (isSameVNode(oldEndVNode, newStartVNode)) {\r\n patch(oldEndVNode, newStartVNode, parent);\r\n const nodeToMove = oldEndVNode.dom;\r\n const anchor = oldStartVNode.dom;\r\n if (nodeToMove) {\r\n hostInsert(nodeToMove, parent, anchor);\r\n }\r\n oldEndVNode = oldChildren[--oldEndIdx];\r\n newStartVNode = newChildren[++newStartIdx];\r\n } else {\r\n if (!oldKeyToIdx) {\r\n oldKeyToIdx = createKeyToKeyIndexMap(oldChildren, oldStartIdx, oldEndIdx);\r\n }\r\n const idxInOld = newStartVNode.key != null\r\n ? oldKeyToIdx.get(String(newStartVNode.key))\r\n : findIndexInOld(oldChildren, newStartVNode, oldStartIdx, oldEndIdx);\r\n\r\n if (idxInOld != null) {\r\n const vnodeToMove = oldChildren[idxInOld];\r\n patch(vnodeToMove, newStartVNode, parent);\r\n oldChildren[idxInOld] = undefined!;\r\n if (vnodeToMove.dom && oldStartVNode.dom) {\r\n hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);\r\n }\r\n } else {\r\n mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);\r\n }\r\n newStartVNode = newChildren[++newStartIdx];\r\n }\r\n }\r\n\r\n if (oldStartIdx > oldEndIdx) {\r\n if (newStartIdx <= newEndIdx) {\r\n const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;\r\n for (let i = newStartIdx; i <= newEndIdx; i++) {\r\n mount(newChildren[i], parent, anchor, parentIsSVG);\r\n }\r\n }\r\n } else if (newStartIdx > newEndIdx) {\r\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\r\n if (oldChildren[i]) {\r\n unmount(oldChildren[i], parent);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function isSameVNode(n1: VNode, n2: VNode): boolean {\r\n const k1 = n1.key == null ? null : n1.key;\r\n const k2 = n2.key == null ? null : n2.key;\r\n if (n1.type !== n2.type) return false;\r\n if (k1 === k2) return true;\r\n\r\n return String(k1) === String(k2);\r\n }\r\n\r\n function createKeyToKeyIndexMap(children: VNode[], beginIdx: number, endIdx: number) {\r\n const map = new Map<string | number, number>();\r\n for (let i = beginIdx; i <= endIdx; i++) {\r\n const key = children[i]?.key;\r\n if (key != null) {\r\n const keyStr = String(key);\r\n if (process.env.NODE_ENV !== 'production' && map.has(keyStr)) {\r\n console.warn(\r\n `[SignalX] Duplicate key \"${key}\" detected in list. ` +\r\n `Keys should be unique among siblings to ensure correct reconciliation. ` +\r\n `This may cause unexpected behavior when items are reordered, added, or removed.`\r\n );\r\n }\r\n map.set(keyStr, i);\r\n }\r\n }\r\n return map;\r\n }\r\n\r\n function findIndexInOld(children: VNode[], newChild: VNode, beginIdx: number, endIdx: number): number | null {\r\n for (let i = beginIdx; i <= endIdx; i++) {\r\n if (children[i] && isSameVNode(children[i], newChild)) return i;\r\n }\r\n return null;\r\n }\r\n\r\n // createPropsAccessor is now imported from component-helpers.ts\r\n\r\n function mountComponent(vnode: VNode, container: HostElement, before: HostNode | null, setup: SetupFn<any, any, any, any>) {\r\n // No wrapper element - we render directly into the container\r\n // Use an anchor comment to track the component's position\r\n const anchor = hostCreateComment('');\r\n vnode.dom = anchor; // The anchor serves as the component's \"DOM\" marker\r\n (anchor as unknown as InternalHostNode).__vnode = vnode;\r\n hostInsert(anchor, container, before);\r\n\r\n let exposed: any = null;\r\n let exposeCalled = false;\r\n\r\n const initialProps = vnode.props || {};\r\n // Create reactive props - exclude children, slots, and $models to avoid deep recursion on VNodes\r\n const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = initialProps;\r\n \r\n // Merge Model<T> objects directly into props for unified access: props.model.value\r\n const propsWithModels = { ...propsData };\r\n if (modelsData) {\r\n for (const modelKey in modelsData) {\r\n const modelValue = modelsData[modelKey];\r\n if (isModel(modelValue)) {\r\n propsWithModels[modelKey] = modelValue;\r\n }\r\n }\r\n }\r\n \r\n const reactiveProps = signal(propsWithModels);\r\n const internalVNode = vnode as InternalVNode;\r\n internalVNode._componentProps = reactiveProps;\r\n\r\n // Create slots object from children and the slots prop\r\n const slots = createSlots(children, slotsFromProps);\r\n internalVNode._slots = slots;\r\n\r\n const createdHooks: (() => void)[] = [];\r\n const mountHooks: ((ctx: MountContext) => void)[] = [];\r\n const updatedHooks: (() => void)[] = [];\r\n const unmountHooks: ((ctx: MountContext) => void)[] = [];\r\n\r\n // Capture the parent component context BEFORE creating the new one\r\n // This is crucial for Provide/Inject to work\r\n const parentInstance = getCurrentInstance();\r\n\r\n // Get component name from the factory (if set via options)\r\n const componentFactory = vnode.type as unknown as ComponentFactory;\r\n const componentName = componentFactory.__name;\r\n\r\n // Create props accessor with defaults support\r\n const propsAccessor = createPropsAccessor(reactiveProps);\r\n\r\n const ctx: ComponentSetupContext = {\r\n el: container, // The parent container (since we don't have a wrapper)\r\n signal: signal,\r\n props: propsAccessor,\r\n slots: slots,\r\n emit: createEmit(reactiveProps),\r\n parent: parentInstance, // Link to parent for DI traversal\r\n onMounted: (fn) => { mountHooks.push(fn); },\r\n onUnmounted: (fn) => { unmountHooks.push(fn); },\r\n onCreated: (fn) => { createdHooks.push(fn); },\r\n onUpdated: (fn) => { updatedHooks.push(fn); },\r\n expose: (exposedValue) => {\r\n exposed = exposedValue;\r\n exposeCalled = true;\r\n },\r\n renderFn: null, // Will be set after setup returns\r\n update: () => { } // Placeholder, will be set after effect is created\r\n } as ComponentSetupContext;\r\n\r\n // Apply context extensions from plugins (e.g., SSR helper)\r\n applyContextExtensions(ctx);\r\n\r\n // Store the component name on the context for debugging\r\n (ctx as InternalComponentContext).__name = componentName;\r\n\r\n // For ROOT component only (no parent), provide the AppContext\r\n // This enables the DI system to find app-level provides by traversing up the tree\r\n if (!parentInstance && currentAppContext) {\r\n provideAppContext(ctx, currentAppContext);\r\n }\r\n\r\n // Create component instance info for lifecycle hooks\r\n const componentInstance: ComponentInstance = {\r\n name: componentName,\r\n ctx,\r\n vnode\r\n };\r\n\r\n const prev = setCurrentInstance(ctx);\r\n let renderFn: ViewFn | undefined;\r\n try {\r\n const setupResult = setup(ctx);\r\n // Async setup is only supported on server - check for promise\r\n if (setupResult && typeof (setupResult as any).then === 'function') {\r\n throw new Error(\r\n `Async setup in component \"${componentName}\" is only supported during SSR. ` +\r\n `On the client, use pre-loaded data from hydration or fetch in onMounted.`\r\n );\r\n }\r\n renderFn = setupResult as ViewFn;\r\n // Notify plugins that component was created (setup completed)\r\n notifyComponentCreated(currentAppContext, componentInstance);\r\n // Run component-level created hooks\r\n createdHooks.forEach(hook => hook());\r\n } catch (err) {\r\n // Handle setup errors\r\n const handled = handleComponentError(currentAppContext, err as Error, componentInstance, 'setup');\r\n if (!handled) {\r\n throw err;\r\n }\r\n } finally {\r\n setCurrentInstance(prev);\r\n }\r\n\r\n // Handle ref - wrap in untrack to prevent reactive loops\r\n if (vnode.props?.ref) {\r\n const refValue = exposeCalled ? exposed : null;\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(refValue);\r\n } else if (vnode.props.ref && typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = refValue;\r\n }\r\n });\r\n }\r\n\r\n if (renderFn) {\r\n ctx.renderFn = renderFn;\r\n\r\n // Shared mutable ref for the current subtree.\r\n // This ensures that when same-type patching replaces the VNode,\r\n // the effect closure and all aliased VNodes share the same subtree reference.\r\n const subTreeRef: { current: VNode | null } = { current: null };\r\n internalVNode._subTreeRef = subTreeRef;\r\n\r\n const componentEffect = effect(() => {\r\n // Set current instance during render so child components can find their parent\r\n const prevInstance = setCurrentInstance(ctx);\r\n try {\r\n const subTreeResult = ctx.renderFn!();\r\n if (subTreeResult == null) {\r\n // If render returns null, unmount any existing subtree\r\n // to prevent stale content from remaining in the DOM.\r\n if (subTreeRef.current) {\r\n unmount(subTreeRef.current, container);\r\n subTreeRef.current = null;\r\n internalVNode._subTree = null;\r\n }\r\n return;\r\n }\r\n\r\n // Handle arrays (fragments) or single vnodes\r\n const subTree = normalizeSubTree(subTreeResult);\r\n const prevSubTree = subTreeRef.current;\r\n\r\n if (prevSubTree) {\r\n // Preserve focused element across the entire patch cycle\r\n const prevFocus = hostGetActiveElement ? hostGetActiveElement() : null;\r\n patch(prevSubTree, subTree, container);\r\n if (prevFocus && hostRestoreFocus && hostGetActiveElement!() !== prevFocus) {\r\n hostRestoreFocus(prevFocus);\r\n }\r\n // Notify plugins of component update (re-render)\r\n notifyComponentUpdated(currentAppContext, componentInstance);\r\n // Run component-level updated hooks\r\n updatedHooks.forEach(hook => hook());\r\n } else {\r\n mount(subTree, container, anchor);\r\n }\r\n subTreeRef.current = subTree;\r\n internalVNode._subTree = subTree;\r\n } catch (err) {\r\n // Handle render errors\r\n const handled = handleComponentError(currentAppContext, err as Error, componentInstance, 'render');\r\n if (!handled) {\r\n throw err;\r\n }\r\n } finally {\r\n setCurrentInstance(prevInstance);\r\n }\r\n });\r\n internalVNode._effect = componentEffect;\r\n\r\n // Implement update() - re-runs the current render function\r\n // For HMR: set ctx.renderFn first, then call update()\r\n ctx.update = () => {\r\n componentEffect();\r\n };\r\n }\r\n\r\n // Run mount hooks\r\n const mountCtx = { el: container };\r\n mountHooks.forEach(hook => hook(mountCtx));\r\n\r\n // Notify plugins that component was mounted\r\n notifyComponentMounted(currentAppContext, componentInstance);\r\n\r\n // Store cleanup hooks on vnode for unmount\r\n vnode.cleanup = () => {\r\n // Notify plugins that component is being unmounted\r\n notifyComponentUnmounted(currentAppContext, componentInstance);\r\n unmountHooks.forEach(hook => hook(mountCtx));\r\n };\r\n }\r\n\r\n // createSlots and normalizeSubTree are now imported from component-helpers.ts\r\n\r\n return {\r\n render,\r\n patch,\r\n mount,\r\n unmount,\r\n mountComponent\r\n };\r\n}\r\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigx/runtime-core",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Runtime core for SignalX",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -45,14 +45,14 @@
45
45
  "url": "https://github.com/signalxjs/core/issues"
46
46
  },
47
47
  "dependencies": {
48
- "@sigx/reactivity": "^0.1.14"
48
+ "@sigx/reactivity": "^0.1.15"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^20.0.0",
52
52
  "typescript": "^5.9.3",
53
53
  "vite": "^8.0.0-beta.9",
54
54
  "vitest": "^3.1.1",
55
- "@sigx/vite": "^0.1.14"
55
+ "@sigx/vite": "^0.1.15"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "vite build && tsgo --emitDeclarationOnly",
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderer-DCe0Y5hd.js","names":[],"sources":["../src/plugins.ts","../__vite-browser-external","../src/async-context.ts","../src/component.ts","../src/di/injectable.ts","../src/directives.ts","../src/app.ts","../src/model.ts","../src/platform.ts","../src/utils/is-component.ts","../src/jsx-runtime.ts","../src/lazy.tsx","../src/utils/props-accessor.ts","../src/utils/slots.ts","../src/utils/normalize.ts","../src/hydration/index.ts","../src/renderer.ts"],"sourcesContent":["/**\r\n * Component plugin registry for runtime-core.\r\n * \r\n * This module has NO IMPORTS to ensure it's fully initialized before\r\n * any other module can import from it. This avoids circular dependency\r\n * issues with ES module initialization.\r\n */\r\n\r\n/**\r\n * Plugin system for components (used by HMR, DevTools, SSR, etc.)\r\n * Note: SetupFn type is duplicated here to avoid circular imports\r\n */\r\nexport type ComponentPlugin = {\r\n onDefine?: (name: string | undefined, factory: any, setup: Function) => void;\r\n};\r\n\r\nconst plugins: ComponentPlugin[] = [];\r\n\r\nexport function registerComponentPlugin(plugin: ComponentPlugin): void {\r\n plugins.push(plugin);\r\n}\r\n\r\n/**\r\n * Get all registered plugins (internal use)\r\n */\r\nexport function getComponentPlugins(): readonly ComponentPlugin[] {\r\n return plugins;\r\n}\r\n\r\n/**\r\n * Context extension system for adding properties to ComponentSetupContext\r\n * Used by SSR, DevTools, and other packages that need to extend the context\r\n */\r\ntype ContextExtension = (ctx: any) => void;\r\nconst contextExtensions: ContextExtension[] = [];\r\n\r\n/**\r\n * Register a function that will be called to extend every component context.\r\n * Extensions are called in order of registration.\r\n * \r\n * @example\r\n * ```ts\r\n * // In @sigx/server-renderer/client\r\n * registerContextExtension((ctx) => {\r\n * ctx.ssr = { load: () => {} };\r\n * });\r\n * ```\r\n */\r\nexport function registerContextExtension(extension: ContextExtension): void {\r\n contextExtensions.push(extension);\r\n}\r\n\r\n/**\r\n * Apply all registered context extensions to a context object.\r\n * Called internally by the renderer when creating component contexts.\r\n */\r\nexport function applyContextExtensions(ctx: any): void {\r\n for (const extension of contextExtensions) {\r\n extension(ctx);\r\n }\r\n}\r\n","module.exports = {}","/**\r\n * Async-safe context storage for SSR request isolation.\r\n *\r\n * On Node.js (server), uses AsyncLocalStorage to scope state per-request,\r\n * preventing cross-request contamination when concurrent requests share\r\n * the same process (e.g., async component setup with `await`).\r\n *\r\n * On browsers (client), falls back to simple module-level variables\r\n * since there's only ever one \"request\" in the browser.\r\n */\r\n\r\n// ============= Types =============\r\n\r\ninterface SSRRequestContext {\r\n /** Current component context (replaces module-level singleton) */\r\n currentComponentContext: any | null;\r\n /** Current suspense boundary */\r\n currentSuspenseBoundary: any | null;\r\n}\r\n\r\n// ============= Implementation =============\r\n\r\n/**\r\n * Try to load AsyncLocalStorage from Node.js.\r\n * Returns null in browser environments.\r\n */\r\nlet asyncLocalStorage: any = null;\r\n\r\ntry {\r\n // Use dynamic require-style check — bundlers will tree-shake this for browser builds\r\n if (typeof globalThis !== 'undefined' && typeof (globalThis as any).process !== 'undefined') {\r\n const nodeAsync = (globalThis as any).process?.versions?.node\r\n ? require('node:async_hooks')\r\n : null;\r\n if (nodeAsync?.AsyncLocalStorage) {\r\n asyncLocalStorage = new nodeAsync.AsyncLocalStorage();\r\n }\r\n }\r\n} catch {\r\n // Not in Node.js or AsyncLocalStorage not available — use fallback\r\n}\r\n\r\n// ============= Fallback (browser / older Node.js) =============\r\n\r\nlet _fallbackContext: SSRRequestContext = {\r\n currentComponentContext: null,\r\n currentSuspenseBoundary: null\r\n};\r\n\r\n// ============= Public API =============\r\n\r\n/**\r\n * Get the current request context.\r\n * Returns the AsyncLocalStorage store if available, otherwise the module-level fallback.\r\n */\r\nfunction getRequestContext(): SSRRequestContext {\r\n if (asyncLocalStorage) {\r\n const store = asyncLocalStorage.getStore();\r\n if (store) return store;\r\n }\r\n return _fallbackContext;\r\n}\r\n\r\n/**\r\n * Get the current component context (request-safe).\r\n */\r\nexport function getCurrentInstanceSafe(): any | null {\r\n return getRequestContext().currentComponentContext;\r\n}\r\n\r\n/**\r\n * Set the current component context (request-safe).\r\n * Returns the previous value.\r\n */\r\nexport function setCurrentInstanceSafe(ctx: any | null): any | null {\r\n const reqCtx = getRequestContext();\r\n const prev = reqCtx.currentComponentContext;\r\n reqCtx.currentComponentContext = ctx;\r\n return prev;\r\n}\r\n\r\n/**\r\n * Get the current suspense boundary (request-safe).\r\n */\r\nexport function getCurrentSuspenseBoundarySafe(): any | null {\r\n return getRequestContext().currentSuspenseBoundary;\r\n}\r\n\r\n/**\r\n * Set the current suspense boundary (request-safe).\r\n * Returns the previous value.\r\n */\r\nexport function setCurrentSuspenseBoundarySafe(boundary: any | null): any | null {\r\n const reqCtx = getRequestContext();\r\n const prev = reqCtx.currentSuspenseBoundary;\r\n reqCtx.currentSuspenseBoundary = boundary;\r\n return prev;\r\n}\r\n\r\n/**\r\n * Run a function within a new isolated request context.\r\n * On Node.js, uses AsyncLocalStorage.run() to create a new scope.\r\n * On browsers, simply calls the function (no isolation needed).\r\n *\r\n * @example\r\n * ```ts\r\n * // In SSR request handler:\r\n * const html = await runInRequestScope(async () => {\r\n * return await ssr.render(<App />);\r\n * });\r\n * ```\r\n */\r\nexport function runInRequestScope<T>(fn: () => T): T {\r\n if (asyncLocalStorage) {\r\n const freshContext: SSRRequestContext = {\r\n currentComponentContext: null,\r\n currentSuspenseBoundary: null\r\n };\r\n return asyncLocalStorage.run(freshContext, fn);\r\n }\r\n // Browser fallback — just call the function\r\n return fn();\r\n}\r\n\r\n/**\r\n * Check if AsyncLocalStorage-based request isolation is available.\r\n */\r\nexport function hasRequestIsolation(): boolean {\r\n return asyncLocalStorage !== null;\r\n}\r\n","import { JSXElement } from \"./jsx-runtime.js\";\r\nimport { signal } from \"@sigx/reactivity\";\r\nimport { getComponentPlugins } from \"./plugins.js\";\r\nimport {\r\n getCurrentInstanceSafe,\r\n setCurrentInstanceSafe\r\n} from \"./async-context.js\";\r\nimport type { Model as ModelType } from \"./model.js\";\r\n\r\n// Dev mode - can be set to false in production builds\r\nconst _DEV = true;\r\n\r\n/**\r\n * Extension point for additional component attributes.\r\n * Use module augmentation to add attributes to all components:\r\n * \r\n * @example\r\n * ```ts\r\n * // In @sigx/server-renderer\r\n * declare module '@sigx/runtime-core' {\r\n * interface ComponentAttributeExtensions {\r\n * 'client:load'?: boolean;\r\n * 'client:visible'?: boolean;\r\n * 'client:idle'?: boolean;\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport interface ComponentAttributeExtensions {\r\n // Attributes are added here via module augmentation\r\n}\r\n\r\n/**\r\n * Define a single prop with type, required/optional status\r\n */\r\nexport type DefineProp<TName extends string, TType, Required extends boolean = false> = Required extends false\r\n ? { [K in TName]?: TType }\r\n : { [K in TName]: TType };\r\n\r\n/**\r\n * Model binding tuple type - [stateObject, key] for forwarding\r\n * The state object can be a Signal or any object with the given key\r\n */\r\nexport type ModelBinding<_T> = [object, string];\r\n\r\n/**\r\n * Re-export Model type for convenience\r\n */\r\nexport type { ModelType as Model };\r\n\r\n/**\r\n * Define a 2-way bound model.\r\n * \r\n * The component receives a Model<T> object with:\r\n * - `.value` - Get or set the current value\r\n * - `.binding` - The underlying binding for forwarding\r\n * \r\n * Default form: DefineModel<T>\r\n * - props.model: Model<T> (read/write/forward)\r\n * - props.model.value to read/write\r\n * - <Child model={props.model} /> to forward\r\n * \r\n * Named form: DefineModel<\"name\", T>\r\n * - props.name: Model<T> (read/write/forward)\r\n * - props.name.value to read/write\r\n * - <Child model={props.name} /> to forward\r\n * \r\n * Callers use: model={() => state.prop} or model:name={() => state.prop}\r\n * \r\n * @example\r\n * ```tsx\r\n * interface InputProps extends DefineModel<string> {\r\n * placeholder?: string;\r\n * }\r\n * \r\n * const Input = component<InputProps>(({ props }) => {\r\n * // Read\r\n * console.log(props.model.value);\r\n * \r\n * // Write\r\n * props.model.value = \"new value\";\r\n * \r\n * // Forward\r\n * <Child model={props.model} />\r\n * });\r\n * ```\r\n */\r\nexport type DefineModel<TNameOrType, TType = void> = TType extends void\r\n // Default model: DefineModel<T> → props.model: Model<T>\r\n ? {\r\n model?: ModelType<TNameOrType>;\r\n /** @internal Marker for JSX to accept binding tuples */\r\n __modelBindings?: { model: TNameOrType };\r\n }\r\n & DefineEvent<\"update:modelValue\", TNameOrType>\r\n // Named model: DefineModel<\"name\", T> → props.name: Model<T>\r\n : TNameOrType extends string\r\n ? {\r\n [K in TNameOrType]?: ModelType<TType>;\r\n }\r\n & {\r\n /** @internal Marker for JSX to accept binding tuples */\r\n __modelBindings?: { [K in TNameOrType]: TType };\r\n }\r\n & DefineEvent<`update:${TNameOrType}`, TType>\r\n : never;\r\n\r\n/**\r\n * Extract model binding definitions from a component props type.\r\n * Used at JSX level to allow binding tuples for model props.\r\n */\r\ntype ExtractModelBindings<T> = T extends { __modelBindings?: infer M } ? NonNullable<M> : {};\r\n\r\n/**\r\n * Map model keys to their JSX prop names.\r\n * - \"model\" stays as \"model\" (default model)\r\n * - Other names become \"model:name\" (named models)\r\n */\r\ntype ModelPropName<K extends string> = K extends \"model\" ? \"model\" : `model:${K}`;\r\n\r\n/**\r\n * Transform Model<T> props to also accept binding syntax at JSX level.\r\n * This allows: model={[state, \"value\"]} or model={props.model}\r\n * For named models: model:title={[state, \"title\"]} or model:title={() => state.title}\r\n */\r\ntype ExternalModelProps<T> = {\r\n [K in keyof ExtractModelBindings<T> as K extends string ? ModelPropName<K> : never]?: \r\n | ModelType<ExtractModelBindings<T>[K]> // Forward Model<T>\r\n | ModelBinding<ExtractModelBindings<T>[K]> // Binding tuple\r\n | (() => ExtractModelBindings<T>[K]); // Getter function\r\n};\r\n\r\nexport type EventDefinition<T> = { __eventDetail: T };\r\n\r\n/**\r\n * Define a single custom event with its detail type\r\n */\r\nexport type DefineEvent<TName extends string, TDetail = void> = {\r\n [K in TName]?: EventDefinition<TDetail>;\r\n};\r\n\r\n/**\r\n * Define a slot with optional scoped props.\r\n * - DefineSlot<\"header\"> - a simple slot named \"header\"\r\n * - DefineSlot<\"item\", { item: T; index: number }> - a scoped slot with props\r\n */\r\nexport type DefineSlot<TName extends string, TProps = void> = {\r\n __slots?: {\r\n [K in TName]: TProps extends void\r\n ? () => JSXElement | JSXElement[] | null\r\n : (props: TProps) => JSXElement | JSXElement[] | null\r\n }\r\n};\r\n\r\n/**\r\n * Extract slot definitions from a combined type\r\n */\r\ntype ExtractSlots<T> = T extends { __slots?: infer S } ? S : {};\r\n\r\n/**\r\n * Default slot function type\r\n */\r\ntype DefaultSlot = () => JSXElement[];\r\n\r\n/**\r\n * Slots object passed to components - always has default, plus any declared slots\r\n */\r\nexport type SlotsObject<TSlots = {}> = {\r\n default: DefaultSlot;\r\n} & TSlots;\r\n\r\n/**\r\n * Extract event names from an event definition\r\n */\r\ntype EventNames<TEvents> = {\r\n [K in keyof TEvents]: TEvents[K] extends EventDefinition<any> | undefined ? K : never\r\n}[keyof TEvents] & string;\r\n\r\n/**\r\n * Extract event detail type for a specific event name\r\n */\r\ntype EventDetail<TEvents, TName extends EventNames<TEvents>> = TEvents extends { [K in TName]?: EventDefinition<infer TDetail> }\r\n ? TDetail\r\n : never;\r\n\r\n/**\r\n * Typed emit function for dispatching custom events\r\n */\r\nexport type EmitFn<TEvents extends Record<string, any>> = <TName extends EventNames<TEvents>>(\r\n eventName: TName,\r\n ...args: EventDetail<TEvents, TName> extends void ? [] : [detail: EventDetail<TEvents, TName>]\r\n) => void;\r\n\r\n/**\r\n * Capitalize the first letter of a string\r\n */\r\ntype Capitalize<S extends string> = S extends `${infer First}${infer Rest}`\r\n ? `${Uppercase<First>}${Rest}`\r\n : S;\r\n\r\n/**\r\n * Convert events to event handler props (on{EventName})\r\n */\r\ntype EventHandlers<TEvents extends Record<string, any>> = {\r\n [K in keyof TEvents as TEvents[K] extends EventDefinition<any> | undefined\r\n ? `on${Capitalize<string & K>}`\r\n : never\r\n ]?: (detail: TEvents[K] extends EventDefinition<infer D> | undefined ? D : never) => void;\r\n};\r\n\r\n/**\r\n * Platform registry - platforms add their element type here via declaration merging\r\n */\r\nexport interface PlatformTypes {\r\n // Platforms add: element: HTMLElement (or other element type)\r\n}\r\n\r\n/** Resolves to the platform's element type, or 'any' if not defined */\r\nexport type PlatformElement = PlatformTypes extends { element: infer E } ? E : any;\r\n\r\n/**\r\n * Base mount context - platforms can extend this via declaration merging\r\n */\r\nexport interface MountContext<TElement = PlatformElement> {\r\n el: TElement;\r\n}\r\n\r\n/**\r\n * Base setup context - platforms can extend this via declaration merging\r\n */\r\nexport interface SetupContext {\r\n // Platforms add properties here via module augmentation\r\n}\r\n\r\n/**\r\n * Extract keys from T where undefined is assignable to the value (optional props)\r\n */\r\ntype _OptionalKeys<T> = { [K in keyof T]: undefined extends T[K] ? K : never }[keyof T];\r\n\r\n/**\r\n * Type for defaults object - REQUIRES all optional keys to be provided.\r\n * Required props (where undefined is not assignable) get type 'never' to prevent setting them.\r\n * This ensures you don't forget to add a default when adding a new optional prop.\r\n */\r\ntype _DefaultsFor<TProps> = {\r\n [K in keyof TProps as undefined extends TProps[K] ? K : never]-?: NonNullable<TProps[K]>;\r\n};\r\n\r\n/**\r\n * Props type after defaults are applied - all props become required (non-undefined)\r\n */\r\nexport type PropsWithDefaults<TProps, D> = {\r\n readonly [K in keyof TProps]-?: K extends keyof D ? NonNullable<TProps[K]> : TProps[K];\r\n};\r\n\r\n/**\r\n * Props accessor - a reactive proxy for component props.\r\n * Use destructuring with defaults for optional props.\r\n * \r\n * @example\r\n * ```tsx\r\n * // Destructure with defaults\r\n * const { variant = 'primary', size = 'md' } = ctx.props;\r\n * return () => <button class={variant}>...</button>\r\n * \r\n * // Or spread to forward all props\r\n * return () => <ChildComponent {...ctx.props} />\r\n * ```\r\n */\r\nexport type PropsAccessor<TProps> = {\r\n readonly [K in keyof TProps]: TProps[K];\r\n};\r\n\r\nexport interface ComponentSetupContext<\r\n TElement = PlatformElement,\r\n TProps extends Record<string, any> = {},\r\n TEvents extends Record<string, any> = {},\r\n TRef = any,\r\n TSlots = {}\r\n> extends SetupContext {\r\n el: TElement;\r\n signal: typeof signal;\r\n /**\r\n * Component props - includes regular props and Model<T> objects.\r\n * \r\n * Models are accessed via props: props.model.value, props.title.value\r\n * \r\n * @example\r\n * ```tsx\r\n * // Read model\r\n * const value = props.model.value;\r\n * \r\n * // Write model\r\n * props.model.value = \"new value\";\r\n * \r\n * // Forward to child\r\n * <Child model={props.model} />\r\n * \r\n * // Forward via context\r\n * defineProvide(ctx, () => props.model);\r\n * ```\r\n */\r\n props: PropsAccessor<TProps>;\r\n slots: SlotsObject<TSlots>;\r\n emit: EmitFn<TEvents>;\r\n parent: any | null;\r\n onMounted(fn: (ctx: MountContext<TElement>) => void): void;\r\n onUnmounted(fn: (ctx: MountContext<TElement>) => void): void;\r\n onCreated(fn: () => void): void;\r\n onUpdated(fn: () => void): void;\r\n expose(exposed: TRef): void;\r\n /**\r\n * The current render function. Can be replaced directly for HMR.\r\n * @internal Used by HMR - set this, then call update()\r\n */\r\n renderFn: ViewFn | null;\r\n /**\r\n * Force the component to re-render using the current renderFn.\r\n * For HMR: first set ctx.renderFn to the new render function, then call update().\r\n */\r\n update(): void;\r\n}\r\n\r\nlet currentComponentContext: ComponentSetupContext<any, any, any> | null = null;\r\n\r\n/** Returns the setup context of the currently executing component, or `null` if called outside setup. */\r\nexport function getCurrentInstance() {\r\n // Prefer async-safe storage (AsyncLocalStorage on server), fallback to module-level\r\n return getCurrentInstanceSafe() ?? currentComponentContext;\r\n}\r\n\r\nexport function setCurrentInstance(ctx: ComponentSetupContext<any, any, any> | null) {\r\n // Update both: async-safe storage AND module-level fallback\r\n const prevSafe = setCurrentInstanceSafe(ctx);\r\n const prevModule = currentComponentContext;\r\n currentComponentContext = ctx;\r\n // Return the previous value — prefer async-safe if it was set\r\n return prevSafe ?? prevModule;\r\n}\r\n\r\n/** Register a callback to run after the component is mounted to the DOM. Must be called during setup. */\r\nexport function onMounted(fn: (ctx: MountContext) => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onMounted(fn);\r\n } else {\r\n console.warn(\"onMounted called outside of component setup\");\r\n }\r\n}\r\n\r\n/** Register a callback to run when the component is unmounted from the DOM. Must be called during setup. */\r\nexport function onUnmounted(fn: (ctx: MountContext) => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onUnmounted(fn);\r\n } else {\r\n console.warn(\"onUnmounted called outside of component setup\");\r\n }\r\n}\r\n\r\n/** Register a callback to run immediately after component setup completes. Must be called during setup. */\r\nexport function onCreated(fn: () => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onCreated(fn);\r\n } else {\r\n console.warn(\"onCreated called outside of component setup\");\r\n }\r\n}\r\n\r\n/** Register a callback to run after every reactive re-render of the component. Must be called during setup. */\r\nexport function onUpdated(fn: () => void) {\r\n if (currentComponentContext) {\r\n currentComponentContext.onUpdated(fn);\r\n } else {\r\n console.warn(\"onUpdated called outside of component setup\");\r\n }\r\n}\r\n\r\nexport type ViewFn = () => JSXElement | JSXElement[] | undefined;\r\n\r\n/**\r\n * Type for component setup functions.\r\n * Includes Props, Events, Ref, and Slots generics to preserve type information.\r\n * Can be sync or async - async setup is awaited on server, runs sync on client hydration.\r\n */\r\nexport type SetupFn<\r\n TProps extends Record<string, any> = {},\r\n TEvents extends Record<string, any> = {},\r\n TRef = any,\r\n TSlots = {}\r\n> = (ctx: ComponentSetupContext<PlatformElement, TProps, TEvents, TRef, TSlots>) => ViewFn | Promise<ViewFn>;\r\n\r\n// Component registry for DevTools and debugging\r\nconst componentRegistry = new Map<Function, { name?: string; setup: SetupFn<any, any, any, any> }>();\r\n\r\n/**\r\n * Get component metadata (for DevTools)\r\n */\r\nexport function getComponentMeta(factory: Function) {\r\n return componentRegistry.get(factory);\r\n}\r\n\r\n/**\r\n * Helper to create a proxy that tracks property access\r\n */\r\nexport function createPropsProxy<T extends Record<string, any>>(target: T, onAccess?: (key: string) => void): T {\r\n return new Proxy(target, {\r\n get(obj, prop) {\r\n if (typeof prop === 'string' && onAccess) {\r\n onAccess(prop);\r\n }\r\n return obj[prop as keyof T];\r\n }\r\n });\r\n}\r\n\r\nexport type DefineExpose<T> = {\r\n __exposed?: { __type: T };\r\n};\r\n\r\ntype ExtractExposed<T> = \"__exposed\" extends keyof T\r\n ? (NonNullable<T[\"__exposed\"]> extends { __type: infer E } ? E : void)\r\n : void;\r\n\r\nexport type Ref<T> = { current: T | null } | ((instance: T | null) => void);\r\n\r\n/**\r\n * Extract the exposed API type from a component.\r\n * Use this to type variables that will hold a component's exposed interface.\r\n * \r\n * @example\r\n * ```tsx\r\n * let api: Exposed<typeof MyComponent>;\r\n * <MyComponent ref={r => api = r!} />\r\n * api.exposedMethod();\r\n * ```\r\n */\r\nexport type Exposed<T extends { __ref: any }> = T[\"__ref\"];\r\n\r\n/**\r\n * Extract the ref (exposed) type from a component (includes function ref option).\r\n * \r\n * @example\r\n * ```tsx\r\n * const myRef = { current: null } as ComponentRef<typeof MyComponent>;\r\n * ```\r\n */\r\nexport type ComponentRef<T extends { __ref: any }> = Ref<T[\"__ref\"]>;\r\n\r\n\r\n/**\r\n * Strip internal type markers from component props for setup context (internal use).\r\n * Preserves model keys so components can access props.model, props.title, etc.\r\n *\r\n * Strips:\r\n * - Internal markers: __exposed, __slots, __models, __modelBindings\r\n * - JSX model:name syntax markers\r\n * - Event markers (update:*)\r\n */\r\ntype StripInternalMarkers<T> = {\r\n [K in keyof T as K extends \"__exposed\" | \"__slots\" | \"__models\" | \"__modelBindings\" ? never\r\n : K extends `model:${string}` ? never // Strip JSX model:name syntax marker\r\n : K extends `update:${string}` ? never\r\n : K]: T[K];\r\n};\r\n\r\n/**\r\n * Strip props for JSX external signature.\r\n * Same as StripInternalMarkers but also strips model keys so ExternalModelProps\r\n * is the sole source (avoiding intersection conflicts between Model<T> and widened union).\r\n */\r\ntype StripForJSX<T> = {\r\n [K in keyof T as K extends \"__exposed\" | \"__slots\" | \"__models\" | \"__modelBindings\" ? never\r\n : K extends `model:${string}` ? never\r\n : K extends `update:${string}` ? never\r\n : K extends keyof ExtractModelBindings<T> ? never // Strip model keys - ExternalModelProps provides them\r\n : K]: T[K];\r\n};\r\n\r\n/**\r\n * Component options (optional second param)\r\n */\r\nexport interface ComponentOptions {\r\n /** Component name for DevTools debugging */\r\n name?: string;\r\n}\r\n\r\n/**\r\n * Slot props type - converts slot definitions to a slots prop object\r\n */\r\ntype SlotProps<TSlots> = TSlots extends Record<string, any>\r\n ? { slots?: Partial<TSlots> }\r\n : {};\r\n\r\n/**\r\n * Sync binding type - used at JSX level to enable two-way binding\r\n * The JSX runtime transforms sync into value + onUpdate:value\r\n */\r\ntype SyncBinding<T> = [object, string] | (() => T);\r\n\r\n/**\r\n * Sync props - if the component has a 'value' prop, allow 'sync' binding\r\n */\r\ntype SyncProps<TCombined> = 'value' extends keyof TCombined\r\n ? { sync?: SyncBinding<TCombined['value']> }\r\n : {};\r\n\r\n// Return type for component - the function IS the component\r\nexport type ComponentFactory<TCombined extends Record<string, any>, TRef, TSlots> = ((props: StripForJSX<Omit<TCombined, EventNames<TCombined>>> & EventHandlers<TCombined> & SlotProps<TSlots> & SyncProps<TCombined> & ExternalModelProps<TCombined> & JSX.IntrinsicAttributes & ComponentAttributeExtensions & {\r\n ref?: Ref<TRef>;\r\n children?: any;\r\n}) => JSXElement) & {\r\n /** @internal Setup function for the renderer */\r\n __setup: SetupFn<StripInternalMarkers<TCombined>, TCombined, TRef, TSlots>;\r\n /** @internal Component name for debugging */\r\n __name?: string;\r\n /** @internal Stable island identity based on file path (injected by sigxIslandsPlugin) */\r\n __islandId?: string;\r\n /** @internal Type brand for props */\r\n __props: StripInternalMarkers<TCombined>;\r\n /** @internal Type brand for events */\r\n __events: TCombined;\r\n /** @internal Type brand for ref */\r\n __ref: TRef;\r\n /** @internal Type brand for slots */\r\n __slots: TSlots;\r\n};\r\n\r\n/**\r\n * Define a component. Returns a JSX factory function.\r\n * \r\n * @param setup - Setup function that receives context and returns a render function\r\n * @param options - Optional configuration (e.g., name for DevTools)\r\n * \r\n * @example\r\n * ```tsx\r\n * type CardProps = DefineProp<\"title\", string> & DefineSlot<\"header\">;\r\n * \r\n * export const Card = component<CardProps>((ctx) => {\r\n * const { title } = ctx.props;\r\n * const { slots } = ctx;\r\n * \r\n * return () => (\r\n * <div class=\"card\">\r\n * {slots.header?.() ?? <h2>{title}</h2>}\r\n * {slots.default()}\r\n * </div>\r\n * );\r\n * });\r\n * ```\r\n */\r\nexport function component<\r\n TCombined extends Record<string, any> = {},\r\n TRef = ExtractExposed<TCombined>,\r\n TSlots = ExtractSlots<TCombined>\r\n>(\r\n setup: (ctx: ComponentSetupContext<PlatformElement, StripInternalMarkers<TCombined>, TCombined, TRef, TSlots>) => ViewFn | Promise<ViewFn>,\r\n options?: ComponentOptions\r\n): ComponentFactory<TCombined, TRef, TSlots> {\r\n // Create the factory function - when called in JSX, it returns itself as a marker\r\n // The renderer will detect __setup and handle it as a component\r\n const factory = function (props: any) {\r\n // Return a VNode-like structure that the renderer can detect\r\n return {\r\n type: factory,\r\n props: props || {},\r\n key: props?.key || null,\r\n children: [],\r\n dom: null\r\n };\r\n } as unknown as ComponentFactory<TCombined, TRef, TSlots>;\r\n\r\n factory.__setup = setup as SetupFn<StripInternalMarkers<TCombined>, TCombined, TRef, TSlots>;\r\n factory.__name = options?.name;\r\n factory.__props = null as any;\r\n factory.__events = null as any;\r\n factory.__ref = null as any;\r\n factory.__slots = null as any;\r\n\r\n // Register in component registry for DevTools\r\n componentRegistry.set(factory, { name: options?.name, setup: setup as unknown as SetupFn<any, any, any, any> });\r\n\r\n // Notify plugins\r\n getComponentPlugins().forEach(p => p.onDefine?.(options?.name, factory, setup as unknown as SetupFn<any, any, any, any>));\r\n\r\n return factory;\r\n}\r\n","import { getCurrentInstance } from \"../component.js\";\r\nimport type { AppContext } from \"../app-types.js\";\r\n\r\n// ============================================================================\r\n// Internal helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Global singleton instances (fallback when no provider found)\r\n */\r\nconst globalInstances = new Map<any, any>();\r\n\r\n/**\r\n * Token for the AppContext injectable.\r\n * Used to provide/lookup the AppContext in the component tree.\r\n */\r\nconst appContextToken = Symbol('sigx:appContext');\r\n\r\n/**\r\n * Lookup a provided value by token, traversing component tree.\r\n * The AppContext is provided at the root component level, so it's found\r\n * just like any other provided value.\r\n * @internal\r\n */\r\nfunction lookupProvided<T>(token: any): T | undefined {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n return undefined;\r\n }\r\n\r\n // Traverse up the component tree looking for provides\r\n let current: any = ctx;\r\n while (current) {\r\n if (current.provides && current.provides.has(token)) {\r\n return current.provides.get(token);\r\n }\r\n current = current.parent;\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Provide a value at the current component level\r\n * @internal\r\n */\r\nfunction provideAtComponent<T>(token: any, value: T): void {\r\n const ctx = getCurrentInstance();\r\n if (!ctx) {\r\n throw new Error(\"defineProvide must be called inside a component setup function\");\r\n }\r\n\r\n if (!(ctx as any).provides) {\r\n (ctx as any).provides = new Map();\r\n }\r\n (ctx as any).provides.set(token, value);\r\n}\r\n\r\n// ============================================================================\r\n// Public API\r\n// ============================================================================\r\n\r\n/**\r\n * Injectable function type with metadata\r\n */\r\nexport interface InjectableFunction<T> {\r\n (): T;\r\n _factory: () => T;\r\n _token: symbol;\r\n}\r\n\r\n/**\r\n * Define an injectable service/value that can be provided at app or component level.\r\n * \r\n * The returned function can be called to get the current instance:\r\n * - If provided at component level via `defineProvide()`, returns that instance\r\n * - If provided at app level via `app.defineProvide()`, returns that instance \r\n * - Otherwise falls back to a global singleton created by the factory\r\n * \r\n * @example\r\n * ```typescript\r\n * // Define a service\r\n * const useApiConfig = defineInjectable(() => ({ \r\n * baseUrl: 'https://api.example.com' \r\n * }));\r\n * \r\n * // Use it in any component - gets nearest provided instance or global singleton\r\n * const config = useApiConfig();\r\n * console.log(config.baseUrl);\r\n * ```\r\n */\r\nexport function defineInjectable<T>(factory: () => T): InjectableFunction<T> {\r\n // Use a unique symbol as the token for this injectable\r\n const token = Symbol();\r\n\r\n const useFn = (() => {\r\n // Try to find a provided instance\r\n const provided = lookupProvided<T>(token);\r\n if (provided !== undefined) {\r\n return provided;\r\n }\r\n\r\n // Fallback to global singleton\r\n if (!globalInstances.has(token)) {\r\n globalInstances.set(token, factory());\r\n }\r\n return globalInstances.get(token);\r\n }) as InjectableFunction<T>;\r\n\r\n // Attach metadata for defineProvide\r\n useFn._factory = factory;\r\n useFn._token = token;\r\n\r\n return useFn;\r\n}\r\n\r\n/**\r\n * Provide a new instance of an injectable at the current component level.\r\n * Child components will receive this instance when calling the injectable function.\r\n * \r\n * @param useFn - The injectable function created by defineInjectable\r\n * @param factory - Optional custom factory to create the instance (overrides default)\r\n * \r\n * @example\r\n * ```typescript\r\n * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));\r\n * \r\n * const MyComponent = component(() => {\r\n * // Create and provide a new instance for this subtree\r\n * const config = defineProvide(useApiConfig);\r\n * config.baseUrl = 'https://custom.api.com';\r\n * \r\n * return () => <ChildComponent />;\r\n * });\r\n * \r\n * // Or provide a pre-constructed instance:\r\n * const MyComponent2 = component(() => {\r\n * const customService = createMyService({ custom: 'options' });\r\n * defineProvide(useMyService, () => customService);\r\n * \r\n * return () => <ChildComponent />;\r\n * });\r\n * ```\r\n */\r\nexport function defineProvide<T>(useFn: InjectableFunction<T>, factory?: () => T): T {\r\n const actualFactory = factory ?? useFn._factory;\r\n const token = useFn._token;\r\n\r\n if (!actualFactory || !token) {\r\n throw new Error(\"defineProvide must be called with a function created by defineInjectable\");\r\n }\r\n\r\n const instance = actualFactory();\r\n provideAtComponent(token, instance);\r\n return instance;\r\n}\r\n\r\n/**\r\n * Get the current AppContext from the component tree.\r\n * The AppContext is provided at the root component level during mount/hydrate/SSR.\r\n * \r\n * @example\r\n * ```typescript\r\n * const appContext = useAppContext();\r\n * console.log(appContext?.app);\r\n * ```\r\n */\r\nexport function useAppContext(): AppContext | null {\r\n return lookupProvided<AppContext>(appContextToken) ?? null;\r\n}\r\n\r\n/**\r\n * Get the AppContext token.\r\n * Used by renderers to provide the AppContext at the root component level.\r\n * @internal\r\n */\r\nexport function getAppContextToken(): symbol {\r\n return appContextToken;\r\n}\r\n\r\n/**\r\n * Provide the AppContext on a component's provides Map.\r\n * Called by the renderer for the ROOT component only.\r\n * @internal\r\n */\r\nexport function provideAppContext(ctx: any, appContext: AppContext): void {\r\n if (!ctx.provides) {\r\n ctx.provides = new Map();\r\n }\r\n ctx.provides.set(appContextToken, appContext);\r\n \r\n // Also store app-level provides on the root component\r\n // This makes `lookupProvided` find them when traversing up to root\r\n if (appContext.provides) {\r\n for (const [token, value] of appContext.provides) {\r\n ctx.provides.set(token, value);\r\n }\r\n }\r\n}\r\n","/**\r\n * Directive system for SignalX.\r\n *\r\n * Directives provide reusable element-level lifecycle hooks via the `use:name` prop syntax.\r\n * They can be registered globally via `app.directive()` or passed inline as imported values.\r\n *\r\n * @example\r\n * ```tsx\r\n * import { defineDirective } from 'sigx';\r\n *\r\n * const tooltip = defineDirective<string>({\r\n * mounted(el, { value }) {\r\n * el.title = value;\r\n * },\r\n * updated(el, { value }) {\r\n * el.title = value;\r\n * },\r\n * unmounted(el) {\r\n * el.title = '';\r\n * }\r\n * });\r\n *\r\n * // Inline usage:\r\n * <div use:tooltip=\"Hello!\">Hover me</div>\r\n *\r\n * // Or with explicit binding:\r\n * <div use:tooltip={[tooltip, \"Hello!\"]}>Hover me</div>\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * The binding object passed to directive hooks.\r\n */\r\nexport interface DirectiveBinding<T = any> {\r\n /** The current value passed to the directive */\r\n value: T;\r\n /** The previous value (available in `updated` hook) */\r\n oldValue?: T;\r\n}\r\n\r\n/**\r\n * Extension interface for directive definitions.\r\n *\r\n * Other packages (e.g., `@sigx/server-renderer`) can augment this interface\r\n * to add hooks like `getSSRProps` via TypeScript module augmentation.\r\n *\r\n * @example\r\n * ```ts\r\n * // In @sigx/server-renderer\r\n * declare module '@sigx/runtime-core' {\r\n * interface DirectiveDefinitionExtensions<T> {\r\n * getSSRProps?(binding: DirectiveBinding<T>): Record<string, any> | void;\r\n * }\r\n * }\r\n * ```\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unused-vars\r\nexport interface DirectiveDefinitionExtensions<T = any> {\r\n // Intentionally empty — filled via module augmentation by SSR and other packages\r\n}\r\n\r\n/**\r\n * A directive definition object with lifecycle hooks.\r\n *\r\n * All hooks are optional. Additional hooks (e.g., `getSSRProps`) may be\r\n * available when SSR packages augment `DirectiveDefinitionExtensions`.\r\n */\r\nexport interface DirectiveDefinition<T = any, El = any> extends DirectiveDefinitionExtensions<T> {\r\n /** Called after the element is created but before it is inserted into the DOM */\r\n created?(el: El, binding: DirectiveBinding<T>): void;\r\n /** Called after the element is inserted into the DOM */\r\n mounted?(el: El, binding: DirectiveBinding<T>): void;\r\n /** Called when the binding value changes */\r\n updated?(el: El, binding: DirectiveBinding<T>): void;\r\n /** Called before the element is removed from the DOM */\r\n unmounted?(el: El, binding: DirectiveBinding<T>): void;\r\n}\r\n\r\n/**\r\n * A resolved directive binding stored on a VNode.\r\n * Tuple of [definition, value].\r\n */\r\nexport type ResolvedDirective<T = any, El = any> = [DirectiveDefinition<T, El>, T];\r\n\r\n/**\r\n * Marker symbol to identify directive definitions.\r\n * @internal\r\n */\r\nexport const __DIRECTIVE__ = Symbol.for('sigx.directive');\r\n\r\n/**\r\n * Internal type for marked directive definitions.\r\n * @internal\r\n */\r\nexport interface MarkedDirectiveDefinition<T = any, El = any> extends DirectiveDefinition<T, El> {\r\n [__DIRECTIVE__]: true;\r\n}\r\n\r\n// ============================================================================\r\n// Public API\r\n// ============================================================================\r\n\r\n/**\r\n * Define a directive. This is an identity function that marks the definition\r\n * for type inference and runtime identification.\r\n *\r\n * @example\r\n * ```ts\r\n * const highlight = defineDirective<string>({\r\n * mounted(el, { value }) {\r\n * el.style.backgroundColor = value;\r\n * },\r\n * updated(el, { value }) {\r\n * el.style.backgroundColor = value;\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport function defineDirective<T = any, El = any>(definition: DirectiveDefinition<T, El>): DirectiveDefinition<T, El> {\r\n (definition as MarkedDirectiveDefinition<T, El>)[__DIRECTIVE__] = true;\r\n return definition;\r\n}\r\n\r\n/**\r\n * Check if a value is a directive definition.\r\n */\r\nexport function isDirective(value: any): value is DirectiveDefinition {\r\n return value != null && typeof value === 'object' && (value as any)[__DIRECTIVE__] === true;\r\n}\r\n\r\n// ============================================================================\r\n// App-level Directive Registry\r\n// ============================================================================\r\n","/**\r\n * Application instance and plugin system for sigx.\r\n * \r\n * This module provides a renderer-agnostic way to configure and bootstrap\r\n * sigx applications with plugins, dependency injection, and lifecycle hooks.\r\n */\r\n\r\n// Re-export all types from the types file\r\nexport type {\r\n ComponentInstance,\r\n AppConfig,\r\n AppLifecycleHooks,\r\n AppContext,\r\n Plugin,\r\n PluginInstallFn,\r\n MountFn,\r\n UnmountFn,\r\n App\r\n} from './app-types.js';\r\n\r\n// Import types for internal use\r\nimport type {\r\n ComponentInstance,\r\n AppConfig,\r\n AppContext,\r\n Plugin,\r\n PluginInstallFn,\r\n MountFn,\r\n App\r\n} from './app-types.js';\r\n\r\nimport { getAppContextToken, type InjectableFunction } from './di/injectable.js';\r\nimport { isDirective } from './directives.js';\r\n\r\n// ============================================================================\r\n// Dev mode flag - must be at top before any usage\r\n// ============================================================================\r\n\r\nconst isDev = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production' || true;\r\n\r\n// ============================================================================\r\n// Constants\r\n// ============================================================================\r\n\r\n// AppContextKey is no longer needed - we use the DI system's token\r\n\r\n// ============================================================================\r\n// Default Mount Function (set by platform packages)\r\n// ============================================================================\r\n\r\nlet defaultMountFn: MountFn<any> | null = null;\r\n\r\n/**\r\n * Set the default mount function for the platform.\r\n * Called by platform packages (runtime-dom, runtime-terminal) on import.\r\n * \r\n * @example\r\n * ```typescript\r\n * // In @sigx/runtime-dom\r\n * import { setDefaultMount } from '@sigx/runtime-core';\r\n * setDefaultMount(domMount);\r\n * ```\r\n */\r\nexport function setDefaultMount<TContainer = any>(mountFn: MountFn<TContainer>): void {\r\n defaultMountFn = mountFn;\r\n}\r\n\r\n/**\r\n * Get the current default mount function.\r\n * @internal\r\n */\r\nexport function getDefaultMount(): MountFn<any> | null {\r\n return defaultMountFn;\r\n}\r\n\r\n// ============================================================================\r\n// Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Create an application instance.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { defineApp, defineInjectable } from '@sigx/runtime-core';\r\n * \r\n * // Define an injectable service\r\n * const useApiConfig = defineInjectable(() => ({ baseUrl: 'https://api.example.com' }));\r\n * \r\n * const app = defineApp(<App />);\r\n * \r\n * app.use(myPlugin, { option: 'value' });\r\n * \r\n * // Provide custom instance at app level\r\n * const config = app.defineProvide(useApiConfig);\r\n * config.baseUrl = 'https://custom.api.com';\r\n * \r\n * app.mount(document.getElementById('app')!);\r\n * ```\r\n */\r\nexport function defineApp<TContainer = any>(rootComponent: any): App<TContainer> {\r\n const installedPlugins = new Set<Plugin | PluginInstallFn>();\r\n\r\n const context: AppContext = {\r\n app: null!, // Will be set below\r\n provides: new Map(),\r\n config: {},\r\n hooks: [],\r\n directives: new Map()\r\n };\r\n\r\n let isMounted = false;\r\n let container: TContainer | null = null;\r\n let unmountFn: (() => void) | null = null;\r\n\r\n const app: App<TContainer> = {\r\n config: context.config,\r\n\r\n use(plugin, options) {\r\n if (installedPlugins.has(plugin)) {\r\n // Plugin already installed, skip\r\n if (isDev) {\r\n console.warn(`Plugin ${(plugin as Plugin).name || 'anonymous'} is already installed.`);\r\n }\r\n return app;\r\n }\r\n\r\n installedPlugins.add(plugin);\r\n\r\n if (typeof plugin === 'function') {\r\n // Function-style plugin\r\n plugin(app, options);\r\n } else if (plugin && typeof plugin.install === 'function') {\r\n // Object-style plugin\r\n plugin.install(app, options);\r\n } else if (isDev) {\r\n console.warn('Invalid plugin: must be a function or have an install() method.');\r\n }\r\n\r\n return app;\r\n },\r\n\r\n defineProvide<T>(useFn: InjectableFunction<T>, factory?: () => T): T {\r\n const actualFactory = factory ?? useFn._factory;\r\n const token = useFn._token;\r\n\r\n if (!actualFactory || !token) {\r\n throw new Error(\"defineProvide must be called with a function created by defineInjectable\");\r\n }\r\n\r\n const instance = actualFactory();\r\n context.provides.set(token, instance);\r\n return instance;\r\n },\r\n\r\n hook(hooks) {\r\n context.hooks.push(hooks);\r\n return app;\r\n },\r\n\r\n directive(name: string, definition?: any): any {\r\n if (definition !== undefined) {\r\n if (isDev && !isDirective(definition)) {\r\n console.warn(\r\n `[sigx] app.directive('${name}', ...) received a value that is not a valid directive definition. ` +\r\n `Use defineDirective() to create directive definitions.`\r\n );\r\n }\r\n context.directives.set(name, definition);\r\n return app;\r\n }\r\n return context.directives.get(name);\r\n },\r\n\r\n mount(target, renderFn?) {\r\n if (isMounted) {\r\n if (isDev) {\r\n console.warn('App is already mounted. Call app.unmount() first.');\r\n }\r\n return app;\r\n }\r\n\r\n // Use provided mount function or fall back to platform default\r\n const mountFn = renderFn ?? defaultMountFn;\r\n\r\n if (!mountFn) {\r\n throw new Error(\r\n 'No mount function provided and no default mount function set. ' +\r\n 'Either pass a mount function to app.mount(), or import a platform package ' +\r\n '(e.g., @sigx/runtime-dom or @sigx/runtime-terminal) that sets the default.'\r\n );\r\n }\r\n\r\n container = target;\r\n isMounted = true;\r\n\r\n // Call the platform-specific render function with our app context\r\n // The render function may return an unmount callback\r\n const result = mountFn(rootComponent, target, context);\r\n if (typeof result === 'function') {\r\n unmountFn = result;\r\n }\r\n\r\n return app;\r\n },\r\n\r\n unmount() {\r\n if (!isMounted) {\r\n if (isDev) {\r\n console.warn('App is not mounted.');\r\n }\r\n return;\r\n }\r\n\r\n if (unmountFn) {\r\n unmountFn();\r\n }\r\n\r\n // Clear provides to help GC\r\n context.provides.clear();\r\n\r\n isMounted = false;\r\n container = null;\r\n },\r\n\r\n get _context() {\r\n return context;\r\n },\r\n\r\n get _isMounted() {\r\n return isMounted;\r\n },\r\n\r\n get _container() {\r\n return container;\r\n },\r\n\r\n get _rootComponent() {\r\n return rootComponent;\r\n }\r\n };\r\n\r\n // Set the app reference in context\r\n context.app = app;\r\n\r\n // Provide the AppContext via the DI system\r\n const appContextToken = getAppContextToken();\r\n context.provides.set(appContextToken, context);\r\n\r\n return app;\r\n}\r\n\r\n// ============================================================================\r\n// Hooks API - Called by renderers to notify plugins\r\n// ============================================================================\r\n\r\n/**\r\n * Notify all app hooks that a component was created.\r\n * Called by the renderer after setup() returns.\r\n */\r\nexport function notifyComponentCreated(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentCreated?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentCreated');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all app hooks that a component was mounted.\r\n * Called by the renderer after mount hooks run.\r\n */\r\nexport function notifyComponentMounted(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentMounted?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentMounted');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all app hooks that a component was unmounted.\r\n * Called by the renderer before cleanup.\r\n */\r\nexport function notifyComponentUnmounted(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentUnmounted?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentUnmounted');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Notify all app hooks that a component updated.\r\n * Called by the renderer after re-render.\r\n */\r\nexport function notifyComponentUpdated(context: AppContext | null, instance: ComponentInstance): void {\r\n if (!context) return;\r\n for (const hooks of context.hooks) {\r\n try {\r\n hooks.onComponentUpdated?.(instance);\r\n } catch (err) {\r\n handleHookError(context, err as Error, instance, 'onComponentUpdated');\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Handle an error in a component. Returns true if the error was handled.\r\n * Called by the renderer when an error occurs in setup or render.\r\n */\r\nexport function handleComponentError(\r\n context: AppContext | null,\r\n err: Error,\r\n instance: ComponentInstance | null,\r\n info: string\r\n): boolean {\r\n if (!context) return false;\r\n\r\n // First, try plugin hooks\r\n for (const hooks of context.hooks) {\r\n try {\r\n const handled = hooks.onComponentError?.(err, instance!, info);\r\n if (handled === true) return true;\r\n } catch (hookErr) {\r\n // Hook itself threw - log and continue\r\n console.error('Error in onComponentError hook:', hookErr);\r\n }\r\n }\r\n\r\n // Then, try app-level error handler\r\n if (context.config.errorHandler) {\r\n try {\r\n const handled = context.config.errorHandler(err, instance, info);\r\n if (handled === true) return true;\r\n } catch (handlerErr) {\r\n console.error('Error in app.config.errorHandler:', handlerErr);\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Handle errors that occur in hooks themselves\r\n */\r\nfunction handleHookError(context: AppContext, err: Error, instance: ComponentInstance, hookName: string): void {\r\n console.error(`Error in ${hookName} hook:`, err);\r\n\r\n // Try the app error handler\r\n if (context.config.errorHandler) {\r\n try {\r\n context.config.errorHandler(err, instance, `plugin hook: ${hookName}`);\r\n } catch {\r\n // Give up - we've done our best\r\n }\r\n }\r\n}\r\n","/**\r\n * Model<T> - Unified two-way binding type for SignalX components.\r\n * \r\n * Provides a single interface for reading, writing, and forwarding model bindings.\r\n * \r\n * @example\r\n * ```tsx\r\n * const Input = component<InputProps>(({ props }) => {\r\n * // Read\r\n * console.log(props.model.value);\r\n * \r\n * // Write\r\n * props.model.value = \"new value\";\r\n * \r\n * // Forward to child\r\n * <Child model={props.model} />\r\n * \r\n * // Forward via context\r\n * defineProvide(inputContext, () => props.model);\r\n * });\r\n * ```\r\n */\r\n\r\n/** Symbol to identify Model objects */\r\nconst MODEL_SYMBOL = Symbol.for(\"sigx.model\");\r\n\r\n/** The binding tuple for Model<T>: [sourceObject, key, updateHandler] */\r\nexport type ModelBindingTuple<T> = readonly [object, string, (value: T) => void];\r\n\r\n/**\r\n * Model<T> - A two-way binding that can be read, written, and forwarded.\r\n * \r\n * - `.value` - Get or set the current value\r\n * - `.binding` - The underlying binding for forwarding\r\n */\r\nexport interface Model<T> {\r\n /** Get or set the current value */\r\n value: T;\r\n /** The underlying binding tuple for forwarding */\r\n readonly binding: ModelBindingTuple<T>;\r\n /** @internal Marker to identify Model objects */\r\n readonly [MODEL_SYMBOL]: true;\r\n}\r\n\r\n/**\r\n * Creates a Model<T> from a binding tuple and update handler.\r\n * \r\n * @param tuple - The [sourceObject, key] tuple from reactivity detection\r\n * @param updateHandler - Function called when value is set (enables parent interception)\r\n * @returns A Model<T> with .value getter/setter and .binding for forwarding\r\n */\r\nexport function createModel<T>(\r\n tuple: [object, string],\r\n updateHandler: (value: T) => void\r\n): Model<T> {\r\n const [obj, key] = tuple;\r\n \r\n return {\r\n get value(): T {\r\n return (obj as Record<string, T>)[key];\r\n },\r\n set value(v: T) {\r\n updateHandler(v);\r\n },\r\n get binding(): ModelBindingTuple<T> {\r\n return [obj, key, updateHandler] as const;\r\n },\r\n [MODEL_SYMBOL]: true as const\r\n };\r\n}\r\n\r\n/**\r\n * Creates a Model<T> from an existing binding (for forwarding scenarios).\r\n * \r\n * @param binding - The full binding tuple [obj, key, handler]\r\n * @returns A new Model<T> wrapping the same binding\r\n */\r\nexport function createModelFromBinding<T>(binding: ModelBindingTuple<T>): Model<T> {\r\n const [obj, key, handler] = binding;\r\n return createModel([obj, key], handler);\r\n}\r\n\r\n/**\r\n * Type guard to check if a value is a Model<T>.\r\n * \r\n * Used by JSX runtime to detect forwarded models and extract their bindings.\r\n */\r\nexport function isModel(value: unknown): value is Model<unknown> {\r\n return (\r\n value !== null &&\r\n typeof value === \"object\" &&\r\n MODEL_SYMBOL in value &&\r\n (value as Model<unknown>)[MODEL_SYMBOL] === true\r\n );\r\n}\r\n\r\n/**\r\n * Gets the Model symbol for external checks.\r\n * @internal\r\n */\r\nexport function getModelSymbol(): symbol {\r\n return MODEL_SYMBOL;\r\n}\r\n","/**\r\n * Platform-specific hooks for runtime-core.\r\n * \r\n * This module has NO IMPORTS to ensure it's fully initialized before\r\n * any other module can import from it. This avoids circular dependency\r\n * issues with ES module initialization.\r\n */\r\n\r\n/**\r\n * Platform-specific model processor for intrinsic elements.\r\n * Platforms (DOM, Terminal) can register their own model handling logic.\r\n * \r\n * @param type - The intrinsic element type (e.g., 'input', 'select')\r\n * @param props - The props object being built (mutable)\r\n * @param modelBinding - The [stateObj, key] tuple for the model binding\r\n * @param originalProps - The original props from JSX (read-only)\r\n * @returns true if handled (skip generic fallback), false to use generic fallback\r\n */\r\nexport type ModelProcessor = (\r\n type: string,\r\n props: Record<string, any>,\r\n modelBinding: [Record<string, any>, string],\r\n originalProps: Record<string, any>\r\n) => boolean;\r\n\r\n// Private holder - no TDZ issues since this module has no circular deps\r\nlet platformModelProcessor: ModelProcessor | null = null;\r\n\r\n/**\r\n * Set the platform-specific model processor for intrinsic elements.\r\n * Called by runtime-dom to handle checkbox/radio/select model bindings.\r\n */\r\nexport function setPlatformModelProcessor(fn: ModelProcessor): void {\r\n platformModelProcessor = fn;\r\n}\r\n\r\n/**\r\n * Get the current platform model processor (for internal use).\r\n */\r\nexport function getPlatformModelProcessor(): ModelProcessor | null {\r\n return platformModelProcessor;\r\n}\r\n","/**\r\n * Component type checking utilities\r\n * \r\n * Separated to avoid circular dependencies between jsx-runtime and renderer.\r\n */\r\n\r\n/**\r\n * Minimal interface for component detection.\r\n * Full ComponentFactory type is generic and complex, so we use this minimal\r\n * interface for the type guard.\r\n */\r\nexport interface ComponentLike {\r\n __setup: Function;\r\n __name?: string;\r\n}\r\n\r\n/**\r\n * Check if a value is a SignalX component (has __setup).\r\n * \r\n * SignalX components are created with component() and have a __setup\r\n * property containing the setup function.\r\n * \r\n * @example\r\n * ```ts\r\n * const MyComponent = component((ctx) => () => <div/>);\r\n * isComponent(MyComponent); // true\r\n * isComponent(() => <div/>); // false (plain function component)\r\n * isComponent('div'); // false\r\n * ```\r\n */\r\nexport function isComponent(type: unknown): type is ComponentLike {\r\n return typeof type === 'function' && '__setup' in type;\r\n}\r\n","// JSX runtime for @sigx/runtime-core\r\n\r\nimport { detectAccess, isComputed } from '@sigx/reactivity';\r\nimport { createModel, isModel, type Model } from './model.js';\r\nimport { getPlatformModelProcessor } from './platform.js';\r\nimport { isComponent } from './utils/is-component.js';\r\n\r\n// Re-export platform types and functions\r\nexport { setPlatformModelProcessor, getPlatformModelProcessor } from './platform.js';\r\nexport type { ModelProcessor } from './platform.js';\r\nexport { createModel, isModel, type Model } from './model.js';\r\n\r\nexport type VNode = {\r\n type: string | typeof Fragment | typeof Text | Function;\r\n props: Record<string, any>;\r\n key: string | number | null;\r\n children: VNode[];\r\n dom: any | null;\r\n text?: string | number;\r\n parent?: VNode | null;\r\n cleanup?: () => void;\r\n};\r\n\r\nexport type JSXChild = VNode | string | number | boolean | null | undefined | JSXChild[];\r\nexport type JSXChildren = JSXChild;\r\nexport type JSXElement = VNode | string | number | boolean | null;\r\n\r\ninterface JSXProps {\r\n children?: JSXChildren;\r\n [key: string]: any;\r\n}\r\n\r\nexport const Fragment = Symbol.for('sigx.Fragment');\r\nexport const Text = Symbol.for('sigx.Text');\r\n\r\nfunction normalizeChildren(children: JSXChildren): VNode[] {\r\n if (children == null || children === false || children === true) {\r\n return [];\r\n }\r\n\r\n // Auto-unwrap computed signals\r\n if (isComputed(children)) {\r\n return normalizeChildren(children.value as JSXChild);\r\n }\r\n\r\n if (Array.isArray(children)) {\r\n return children.flatMap(c => normalizeChildren(c));\r\n }\r\n\r\n if (typeof children === 'string' || typeof children === 'number') {\r\n return [{\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: children\r\n }];\r\n }\r\n\r\n if ((children as VNode).type) {\r\n return [children as VNode];\r\n }\r\n\r\n return [];\r\n}\r\n\r\n// isComponent is imported from ./utils/is-component.js\r\n\r\n/**\r\n * Create a JSX element - this is the core function called by TSX transpilation\r\n */\r\nexport function jsx(\r\n type: string | Function | typeof Fragment,\r\n props: JSXProps | null,\r\n key?: string\r\n): JSXElement {\r\n const processedProps = { ...props };\r\n const models: Record<string, Model<any>> = {};\r\n const isComponentType = isComponent(type);\r\n\r\n // Handle model props (two-way binding)\r\n if (props) {\r\n for (const propKey in props) {\r\n if (propKey === \"model\") {\r\n let modelBinding = props[propKey];\r\n let tuple: [object, string] | null = null;\r\n let updateHandler: ((v: any) => void) | null = null;\r\n\r\n // Check if it's already a Model (forwarding)\r\n if (isModel(modelBinding)) {\r\n const [obj, key, handler] = modelBinding.binding;\r\n tuple = [obj, key];\r\n updateHandler = handler;\r\n }\r\n // Convert getter function to tuple using detectAccess\r\n else if (typeof modelBinding === \"function\") {\r\n const detected = detectAccess(modelBinding);\r\n if (detected && typeof detected[1] === 'string') {\r\n tuple = detected as [object, string];\r\n }\r\n }\r\n // Direct tuple\r\n else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === 'string') {\r\n tuple = modelBinding as [object, string];\r\n }\r\n\r\n if (tuple) {\r\n const [stateObj, stateKey] = tuple;\r\n let handled = false;\r\n\r\n // Create update handler if not forwarding\r\n if (!updateHandler) {\r\n const existingHandler = processedProps[\"onUpdate:modelValue\"];\r\n updateHandler = (v: any) => {\r\n const customHandler = (stateObj as any)[`onUpdate:${stateKey}`];\r\n if (typeof customHandler === \"function\") {\r\n customHandler(v);\r\n } else {\r\n (stateObj as any)[stateKey] = v;\r\n }\r\n if (existingHandler) existingHandler(v);\r\n };\r\n }\r\n\r\n // Let platform handle intrinsic element model (e.g., DOM checkbox/radio)\r\n const platformProcessor = getPlatformModelProcessor();\r\n if (typeof type === \"string\" && platformProcessor) {\r\n handled = platformProcessor(type, processedProps, tuple, props);\r\n }\r\n\r\n // For components: create Model<T> object\r\n if (isComponentType) {\r\n models.model = createModel(tuple, updateHandler);\r\n // Keep onUpdate handler for backward compatibility\r\n processedProps[\"onUpdate:modelValue\"] = updateHandler;\r\n } else if (!handled) {\r\n // Generic fallback for intrinsic elements\r\n processedProps.modelValue = (stateObj as Record<string, any>)[stateKey];\r\n processedProps[\"onUpdate:modelValue\"] = updateHandler;\r\n }\r\n delete processedProps.model;\r\n }\r\n } else if (propKey.startsWith(\"model:\")) {\r\n let modelBinding = props[propKey];\r\n const name = propKey.slice(6); // \"model:title\" → \"title\"\r\n let tuple: [object, string] | null = null;\r\n let updateHandler: ((v: any) => void) | null = null;\r\n\r\n // Check if it's already a Model (forwarding)\r\n if (isModel(modelBinding)) {\r\n const [obj, key, handler] = modelBinding.binding;\r\n tuple = [obj, key];\r\n updateHandler = handler;\r\n }\r\n // Handle function form: model:propName={() => state.prop}\r\n else if (typeof modelBinding === \"function\") {\r\n const detected = detectAccess(modelBinding);\r\n if (detected && typeof detected[1] === 'string') {\r\n tuple = detected as [object, string];\r\n }\r\n }\r\n // Direct tuple\r\n else if (Array.isArray(modelBinding) && modelBinding.length === 2 && typeof modelBinding[1] === 'string') {\r\n tuple = modelBinding as [object, string];\r\n }\r\n\r\n if (tuple) {\r\n const [stateObj, stateKey] = tuple;\r\n const eventName = `onUpdate:${name}`;\r\n\r\n // Create update handler if not forwarding\r\n if (!updateHandler) {\r\n const existingHandler = processedProps[eventName];\r\n updateHandler = (v: any) => {\r\n const customHandler = (stateObj as any)[`onUpdate:${stateKey}`];\r\n if (typeof customHandler === \"function\") {\r\n customHandler(v);\r\n } else {\r\n (stateObj as any)[stateKey] = v;\r\n }\r\n if (existingHandler) existingHandler(v);\r\n };\r\n }\r\n\r\n // For components: create Model<T> object with the prop name\r\n if (isComponentType) {\r\n models[name] = createModel(tuple, updateHandler);\r\n // Keep onUpdate handler for backward compatibility\r\n processedProps[eventName] = updateHandler;\r\n } else {\r\n // For intrinsic elements: put value directly on props\r\n processedProps[name] = (stateObj as Record<string, any>)[stateKey];\r\n processedProps[eventName] = updateHandler;\r\n }\r\n delete processedProps[propKey];\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Attach models to props for component instantiation\r\n if (Object.keys(models).length > 0) {\r\n processedProps.$models = models;\r\n }\r\n\r\n // Handle sigx components - create a VNode with the component factory as type\r\n // The renderer will detect __setup and call mountComponent\r\n if (isComponent(type)) {\r\n const { children, ...rest } = processedProps;\r\n return {\r\n type: type as Function,\r\n props: { ...rest, children },\r\n key: key || rest.key || null,\r\n children: [], // Children are passed via props for components\r\n dom: null\r\n };\r\n }\r\n\r\n // Handle plain function components (not sigx component)\r\n if (typeof type === 'function' && (type as any) !== Fragment) {\r\n return (type as Function)(processedProps);\r\n }\r\n\r\n const { children, ...rest } = processedProps;\r\n\r\n const vnode: VNode = {\r\n type: type as string | typeof Fragment,\r\n props: rest,\r\n key: key || rest.key || null,\r\n children: normalizeChildren(children),\r\n dom: null\r\n };\r\n\r\n return vnode;\r\n}\r\n\r\n/**\r\n * JSX Factory for fragments\r\n */\r\nexport function jsxs(type: any, props: any, key?: any) {\r\n return jsx(type, props, key);\r\n}\r\n\r\nexport const jsxDEV = jsx;\r\n","/**\r\n * Lazy loading utilities for sigx components.\r\n * \r\n * Provides runtime-only lazy loading with no build dependencies.\r\n * Works with any bundler that supports dynamic import().\r\n */\r\n\r\nimport { component, type ComponentFactory } from './component.js';\r\nimport { jsx, type JSXElement } from './jsx-runtime.js';\r\nimport { batch } from '@sigx/reactivity';\r\nimport {\r\n getCurrentSuspenseBoundarySafe,\r\n setCurrentSuspenseBoundarySafe\r\n} from './async-context.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * State for a lazy-loaded component\r\n */\r\ntype LazyState = 'pending' | 'resolved' | 'rejected';\r\n\r\n/**\r\n * Module with default export\r\n */\r\ntype ModuleWithDefault<T> = { default: T };\r\n\r\n/**\r\n * Loader function that returns a component or module with default export\r\n */\r\ntype ComponentLoader<T> = () => Promise<T | ModuleWithDefault<T>>;\r\n\r\n/**\r\n * Extended component factory with lazy loading methods\r\n */\r\nexport type LazyComponentFactory<T extends ComponentFactory<any, any, any>> = T & {\r\n /** Preload the component without rendering */\r\n preload: () => Promise<T>;\r\n /** Check if the component is loaded */\r\n isLoaded: () => boolean;\r\n /** @internal Marker for lazy components */\r\n __lazy: true;\r\n};\r\n\r\n/**\r\n * Props for the Suspense component\r\n */\r\nexport type SuspenseProps = {\r\n /** Fallback content to show while loading */\r\n fallback?: JSXElement | (() => JSXElement);\r\n};\r\n\r\n// ============================================================================\r\n// Suspense Context\r\n// ============================================================================\r\n\r\n/**\r\n * Suspense boundary context for tracking pending async operations\r\n */\r\ntype SuspenseBoundary = {\r\n pending: Set<Promise<any>>;\r\n onResolve: () => void;\r\n};\r\n\r\n// Module-level fallback for browser environments\r\nlet currentSuspenseBoundary: SuspenseBoundary | null = null;\r\n\r\n/**\r\n * Register a promise with the current Suspense boundary\r\n * @internal\r\n */\r\nexport function registerPendingPromise(promise: Promise<any>): boolean {\r\n // Capture the boundary at registration time, not when promise resolves\r\n // Use async-safe storage (server) with module-level fallback (browser)\r\n const boundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;\r\n if (boundary) {\r\n boundary.pending.add(promise);\r\n promise.finally(() => {\r\n boundary.pending.delete(promise);\r\n if (boundary.pending.size === 0) {\r\n boundary.onResolve();\r\n }\r\n });\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n// ============================================================================\r\n// lazy()\r\n// ============================================================================\r\n\r\n/**\r\n * Create a lazy-loaded component wrapper.\r\n * \r\n * The component will be loaded on first render. Use with `<Suspense>` to show\r\n * a fallback while loading.\r\n * \r\n * @param loader - Function that returns a Promise resolving to the component\r\n * @returns A component factory that loads the real component on demand\r\n * \r\n * @example\r\n * ```tsx\r\n * import { lazy, Suspense } from 'sigx';\r\n * \r\n * // Component will be in a separate chunk\r\n * const HeavyChart = lazy(() => import('./components/HeavyChart'));\r\n * \r\n * // Usage\r\n * <Suspense fallback={<Spinner />}>\r\n * <HeavyChart data={chartData} />\r\n * </Suspense>\r\n * \r\n * // Preload on hover\r\n * <button onMouseEnter={() => HeavyChart.preload()}>\r\n * Show Chart\r\n * </button>\r\n * ```\r\n */\r\nexport function lazy<T extends ComponentFactory<any, any, any>>(\r\n loader: ComponentLoader<T>\r\n): LazyComponentFactory<T> {\r\n let Component: T | null = null;\r\n let promise: Promise<T> | null = null;\r\n let error: Error | null = null;\r\n let state: LazyState = 'pending';\r\n\r\n // Create a wrapper component that handles the async loading\r\n const LazyWrapper = component((ctx) => {\r\n // Use object-based signal (sigx signals wrap objects, not primitives)\r\n const loadState = ctx.signal({ state: state as LazyState, tick: 0 });\r\n\r\n // Start loading if not already started\r\n if (!promise) {\r\n promise = loader()\r\n .then((mod) => {\r\n // Handle both default exports and direct exports\r\n Component = 'default' in mod ? (mod as ModuleWithDefault<T>).default : mod;\r\n state = 'resolved';\r\n // Batch both mutations to avoid triggering the render effect twice\r\n batch(() => {\r\n loadState.state = 'resolved';\r\n loadState.tick++;\r\n });\r\n return Component;\r\n })\r\n .catch((err) => {\r\n error = err instanceof Error ? err : new Error(String(err));\r\n state = 'rejected';\r\n batch(() => {\r\n loadState.state = 'rejected';\r\n loadState.tick++;\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n // If already resolved, render immediately\r\n if (state === 'resolved' && Component) {\r\n return () => {\r\n const Comp = Component!;\r\n return jsx(Comp, {});\r\n };\r\n }\r\n\r\n // If already rejected, throw the error\r\n if (state === 'rejected' && error) {\r\n throw error;\r\n }\r\n\r\n // Register with Suspense boundary if available\r\n const registered = registerPendingPromise(promise!);\r\n\r\n // If no Suspense boundary, handle loading state ourselves\r\n if (!registered) {\r\n promise!.catch(() => {\r\n // Error handling done in state update\r\n });\r\n }\r\n\r\n return () => {\r\n // Trigger reactivity by reading state\r\n const currentState = loadState.state;\r\n void loadState.tick;\r\n\r\n // Check current state\r\n if (currentState === 'resolved' && Component) {\r\n return jsx(Component, {});\r\n }\r\n\r\n if (currentState === 'rejected' && error) {\r\n throw error;\r\n }\r\n\r\n // Still loading - render nothing (Suspense boundary handles fallback)\r\n return null;\r\n };\r\n }, { name: 'LazyComponent' }) as unknown as LazyComponentFactory<T>;\r\n\r\n // Add lazy-specific methods\r\n (LazyWrapper as any).__lazy = true;\r\n\r\n (LazyWrapper as any).preload = (): Promise<T> => {\r\n if (!promise) {\r\n promise = loader()\r\n .then((mod) => {\r\n Component = 'default' in mod ? (mod as ModuleWithDefault<T>).default : mod;\r\n state = 'resolved';\r\n return Component;\r\n })\r\n .catch((err) => {\r\n error = err instanceof Error ? err : new Error(String(err));\r\n state = 'rejected';\r\n throw error;\r\n });\r\n }\r\n return promise;\r\n };\r\n\r\n (LazyWrapper as any).isLoaded = (): boolean => {\r\n return state === 'resolved';\r\n };\r\n\r\n return LazyWrapper as LazyComponentFactory<T>;\r\n}\r\n\r\n// ============================================================================\r\n// Suspense Component\r\n// ============================================================================\r\n\r\n/**\r\n * Suspense boundary component for handling async loading states.\r\n * \r\n * Wraps lazy-loaded components and shows a fallback while they load.\r\n * \r\n * @example\r\n * ```tsx\r\n * import { lazy, Suspense } from 'sigx';\r\n * \r\n * const LazyDashboard = lazy(() => import('./Dashboard'));\r\n * \r\n * // Basic usage\r\n * <Suspense fallback={<div>Loading...</div>}>\r\n * <LazyDashboard />\r\n * </Suspense>\r\n * \r\n * // With spinner component\r\n * <Suspense fallback={<Spinner size=\"large\" />}>\r\n * <LazyDashboard />\r\n * <LazyCharts />\r\n * </Suspense>\r\n * ```\r\n */\r\nexport const Suspense = component<SuspenseProps>(\r\n (ctx) => {\r\n const { props, slots } = ctx;\r\n const state = ctx.signal({ isReady: false, pendingCount: 0 });\r\n\r\n // Create a Suspense boundary context\r\n const boundary: SuspenseBoundary = {\r\n pending: new Set(),\r\n onResolve: () => {\r\n state.pendingCount = boundary.pending.size;\r\n if (boundary.pending.size === 0) {\r\n state.isReady = true;\r\n }\r\n }\r\n };\r\n\r\n // Set up the boundary for child components\r\n ctx.onMounted(() => {\r\n // After first render, if no pending promises, we're ready\r\n if (boundary.pending.size === 0) {\r\n state.isReady = true;\r\n }\r\n });\r\n\r\n return () => {\r\n // Read reactive state to trigger re-render when children finish loading\r\n // This is crucial: when onResolve() sets isReady=true, this causes Suspense to re-render\r\n void state.isReady;\r\n void state.pendingCount;\r\n\r\n // Set current boundary for children to register with\r\n const prevBoundary = getCurrentSuspenseBoundarySafe() ?? currentSuspenseBoundary;\r\n currentSuspenseBoundary = boundary;\r\n setCurrentSuspenseBoundarySafe(boundary);\r\n\r\n try {\r\n // Try to render children\r\n const children = slots.default();\r\n\r\n // If we have pending promises (registered during slots.default() call), show fallback\r\n // Check AFTER rendering children because that's when lazy components register\r\n if (boundary.pending.size > 0) {\r\n const fallback = props.fallback;\r\n if (typeof fallback === 'function') {\r\n return (fallback as () => JSXElement)();\r\n }\r\n return fallback ?? null;\r\n }\r\n\r\n // No pending - return children (could be an array, single element, or null)\r\n // Filter out nulls from conditional rendering\r\n if (Array.isArray(children)) {\r\n const filtered = children.filter((c: any) => c != null && c !== false && c !== true);\r\n if (filtered.length === 0) return null;\r\n if (filtered.length === 1) return filtered[0];\r\n return filtered;\r\n }\r\n\r\n return children;\r\n } catch (err) {\r\n // If a promise was thrown (Suspense protocol), handle it\r\n if (err instanceof Promise) {\r\n registerPendingPromise(err);\r\n const fallback = props.fallback;\r\n if (typeof fallback === 'function') {\r\n return (fallback as () => JSXElement)();\r\n }\r\n return fallback ?? null;\r\n }\r\n // Re-throw other errors\r\n throw err;\r\n } finally {\r\n currentSuspenseBoundary = prevBoundary;\r\n setCurrentSuspenseBoundarySafe(prevBoundary);\r\n }\r\n };\r\n },\r\n { name: 'Suspense' }\r\n);\r\n\r\n// ============================================================================\r\n// Utility: isLazyComponent\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a component is a lazy-loaded component\r\n */\r\nexport function isLazyComponent(component: any): component is LazyComponentFactory<any> {\r\n return component && component.__lazy === true;\r\n}\r\n","/**\r\n * Props accessor for component setup functions.\r\n * Provides a reactive proxy for accessing component props.\r\n */\r\n\r\nimport { PropsAccessor } from '../component.js';\r\n\r\n/**\r\n * Creates a props accessor - a simple reactive proxy for props.\r\n * Use destructuring with defaults for optional props.\r\n * \r\n * @example\r\n * ```ts\r\n * // In component setup:\r\n * const { count = 0, label = 'Default' } = ctx.props;\r\n * \r\n * // Or spread to forward props\r\n * <ChildComponent {...ctx.props} />\r\n * ```\r\n */\r\nexport function createPropsAccessor<TProps extends Record<string, any>>(\r\n reactiveProps: TProps\r\n): PropsAccessor<TProps> {\r\n const handler: ProxyHandler<TProps> = {\r\n get(target, key: string | symbol) {\r\n if (typeof key === 'symbol') return undefined;\r\n return (target as any)[key];\r\n },\r\n\r\n has(target, key: string | symbol) {\r\n if (typeof key === 'symbol') return false;\r\n return key in target;\r\n },\r\n\r\n ownKeys(target) {\r\n return Object.keys(target);\r\n },\r\n\r\n getOwnPropertyDescriptor(target, key: string | symbol) {\r\n if (typeof key === 'symbol') return undefined;\r\n if (key in target) {\r\n return { enumerable: true, configurable: true, writable: false };\r\n }\r\n return undefined;\r\n }\r\n };\r\n\r\n // Use a regular object as the proxy target - enables spreading\r\n const proxy = new Proxy(reactiveProps, handler);\r\n\r\n return proxy as PropsAccessor<TProps>;\r\n}\r\n","/**\r\n * Slots system for component children.\r\n * Supports default and named slots with reactivity.\r\n */\r\n\r\nimport { signal } from '@sigx/reactivity';\r\n\r\n/**\r\n * Internal slots object with tracking properties\r\n */\r\nexport interface InternalSlotsObject {\r\n default: () => any[];\r\n _children: any;\r\n _version: { v: number };\r\n _slotsFromProps: Record<string, any>;\r\n _isPatching?: boolean;\r\n [key: string]: any;\r\n}\r\n\r\n/**\r\n * Create slots object from children and slots prop.\r\n * Uses a version signal to trigger re-renders when children change.\r\n * \r\n * Supports named slots via:\r\n * - `slots` prop object (e.g., `slots={{ header: () => <div>...</div> }}`)\r\n * - `slot` prop on children (e.g., `<div slot=\"header\">...</div>`)\r\n * \r\n * @example\r\n * ```tsx\r\n * // Parent component\r\n * <Card slots={{ header: () => <h1>Title</h1> }}>\r\n * <p>Default content</p>\r\n * <span slot=\"footer\">Footer text</span>\r\n * </Card>\r\n * \r\n * // Card component setup\r\n * const slots = createSlots(children, slotsFromProps);\r\n * return () => (\r\n * <div>\r\n * {slots.header()}\r\n * {slots.default()}\r\n * {slots.footer()}\r\n * </div>\r\n * );\r\n * ```\r\n */\r\nexport function createSlots(children: any, slotsFromProps?: Record<string, any>): InternalSlotsObject {\r\n // Use a simple version signal - bump version to trigger reactivity\r\n const versionSignal = signal({ v: 0 });\r\n\r\n // Extract named slots from children with slot prop\r\n function extractNamedSlotsFromChildren(c: any): { defaultChildren: any[]; namedSlots: Record<string, any[]> } {\r\n const defaultChildren: any[] = [];\r\n const namedSlots: Record<string, any[]> = {};\r\n\r\n if (c == null) return { defaultChildren, namedSlots };\r\n\r\n const items = Array.isArray(c) ? c : [c];\r\n\r\n for (const child of items) {\r\n if (child && typeof child === 'object' && child.props && child.props.slot) {\r\n const slotName = child.props.slot;\r\n if (!namedSlots[slotName]) {\r\n namedSlots[slotName] = [];\r\n }\r\n namedSlots[slotName].push(child);\r\n } else {\r\n defaultChildren.push(child);\r\n }\r\n }\r\n\r\n return { defaultChildren, namedSlots };\r\n }\r\n\r\n const slotsObj = {\r\n _children: children,\r\n _slotsFromProps: slotsFromProps || {},\r\n _version: versionSignal,\r\n _isPatching: false, // Flag to prevent infinite loops during patching\r\n default: function () {\r\n // Reading version creates a reactive dependency\r\n void this._version.v;\r\n const c = this._children;\r\n const { defaultChildren } = extractNamedSlotsFromChildren(c);\r\n // Filter out null, undefined, false, true (conditional rendering results)\r\n return defaultChildren.filter((child: any) => child != null && child !== false && child !== true);\r\n }\r\n };\r\n\r\n // Create a proxy to handle named slot access dynamically\r\n return new Proxy(slotsObj, {\r\n get(target, prop) {\r\n if (prop in target) {\r\n return (target as any)[prop];\r\n }\r\n\r\n // Handle named slot access\r\n if (typeof prop === 'string') {\r\n return function (scopedProps?: any) {\r\n // Reading version creates a reactive dependency\r\n const _ = target._version.v;\r\n\r\n // First check for slots from the `slots` prop\r\n if (target._slotsFromProps && typeof target._slotsFromProps[prop] === 'function') {\r\n const result = target._slotsFromProps[prop](scopedProps);\r\n if (result == null) return [];\r\n return Array.isArray(result) ? result : [result];\r\n }\r\n\r\n // Then check for element-based slots (children with slot prop)\r\n const { namedSlots } = extractNamedSlotsFromChildren(target._children);\r\n return namedSlots[prop] || [];\r\n };\r\n }\r\n\r\n return undefined;\r\n }\r\n }) as InternalSlotsObject;\r\n}\r\n","/**\r\n * VNode normalization utilities.\r\n * Converts render results into proper VNode structures.\r\n */\r\n\r\nimport { isComputed } from '@sigx/reactivity';\r\nimport { VNode, Fragment, Text, JSXElement } from '../jsx-runtime.js';\r\n\r\n/**\r\n * Normalize render result to a VNode (wrapping arrays in Fragment).\r\n * Handles null, undefined, false, true by returning an empty Text node.\r\n * \r\n * This is used to normalize the return value of component render functions\r\n * into a consistent VNode structure for the renderer to process.\r\n * \r\n * @example\r\n * ```ts\r\n * // Conditional rendering returns null/false\r\n * normalizeSubTree(null) // → empty Text node\r\n * normalizeSubTree(false) // → empty Text node\r\n * \r\n * // Arrays become Fragments\r\n * normalizeSubTree([<A/>, <B/>]) // → Fragment with children\r\n * \r\n * // Primitives become Text nodes\r\n * normalizeSubTree(\"hello\") // → Text node\r\n * normalizeSubTree(42) // → Text node\r\n * \r\n * // Computed signals are auto-unwrapped\r\n * normalizeSubTree(computed(() => \"hi\")) // → Text node with \"hi\"\r\n * \r\n * // VNodes pass through\r\n * normalizeSubTree(<div/>) // → same VNode\r\n * ```\r\n */\r\nexport function normalizeSubTree(result: JSXElement | JSXElement[] | null | undefined | boolean | (() => any)): VNode {\r\n // Handle falsy values from conditional rendering\r\n if (result == null || result === false || result === true) {\r\n return {\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: ''\r\n };\r\n }\r\n\r\n // Auto-unwrap computed signals\r\n if (isComputed(result)) {\r\n return normalizeSubTree(result.value as JSXElement | JSXElement[] | (() => any) | undefined);\r\n }\r\n\r\n if (Array.isArray(result)) {\r\n return {\r\n type: Fragment,\r\n props: {},\r\n key: null,\r\n children: result as VNode[],\r\n dom: null\r\n };\r\n }\r\n\r\n if (typeof result === 'string' || typeof result === 'number') {\r\n return {\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: result\r\n };\r\n }\r\n\r\n return result as VNode;\r\n}\r\n","/**\r\n * Hydration utilities for SSR\r\n * \r\n * These utilities are shared between server-side rendering (stream.ts)\r\n * and client-side hydration (hydrate.ts). They are placed in runtime-core\r\n * to allow any SSR implementation to use them.\r\n * \r\n * @module\r\n */\r\n\r\n/**\r\n * Client directive prefix used for selective hydration\r\n */\r\nexport const CLIENT_DIRECTIVE_PREFIX = 'client:';\r\n\r\n/**\r\n * Valid client directive names\r\n */\r\nexport const CLIENT_DIRECTIVES = [\r\n 'client:load',\r\n 'client:idle',\r\n 'client:visible',\r\n 'client:media',\r\n 'client:only'\r\n] as const;\r\n\r\nexport type ClientDirective = typeof CLIENT_DIRECTIVES[number];\r\n\r\n/**\r\n * Hydration strategies for client directives\r\n */\r\nexport type HydrationStrategy = 'load' | 'idle' | 'visible' | 'media' | 'only';\r\n\r\n/**\r\n * Result of getHydrationDirective\r\n */\r\nexport interface HydrationDirective {\r\n strategy: HydrationStrategy;\r\n media?: string;\r\n}\r\n\r\n/**\r\n * Filter out client directives from props.\r\n * Used to get the actual component props without hydration hints.\r\n * \r\n * @example\r\n * ```ts\r\n * const props = { 'client:visible': true, name: 'test', count: 5 };\r\n * filterClientDirectives(props); // { name: 'test', count: 5 }\r\n * ```\r\n */\r\nexport function filterClientDirectives(props: Record<string, any>): Record<string, any> {\r\n const filtered: Record<string, any> = {};\r\n for (const key in props) {\r\n if (!key.startsWith(CLIENT_DIRECTIVE_PREFIX)) {\r\n filtered[key] = props[key];\r\n }\r\n }\r\n return filtered;\r\n}\r\n\r\n/**\r\n * Get hydration directive from props.\r\n * Returns the strategy and optional media query for client:media.\r\n * \r\n * @example\r\n * ```ts\r\n * getHydrationDirective({ 'client:visible': true }); // { strategy: 'visible' }\r\n * getHydrationDirective({ 'client:media': '(min-width: 768px)' }); // { strategy: 'media', media: '(min-width: 768px)' }\r\n * getHydrationDirective({ name: 'test' }); // null\r\n * ```\r\n */\r\nexport function getHydrationDirective(props: Record<string, any>): HydrationDirective | null {\r\n if (props['client:load'] !== undefined) return { strategy: 'load' };\r\n if (props['client:idle'] !== undefined) return { strategy: 'idle' };\r\n if (props['client:visible'] !== undefined) return { strategy: 'visible' };\r\n if (props['client:only'] !== undefined) return { strategy: 'only' };\r\n if (props['client:media'] !== undefined) {\r\n return { strategy: 'media', media: props['client:media'] };\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Check if props contain any client directive.\r\n * \r\n * @example\r\n * ```ts\r\n * hasClientDirective({ 'client:visible': true }); // true\r\n * hasClientDirective({ name: 'test' }); // false\r\n * ```\r\n */\r\nexport function hasClientDirective(props: Record<string, any>): boolean {\r\n for (const key in props) {\r\n if (key.startsWith(CLIENT_DIRECTIVE_PREFIX)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Serialize props for client hydration.\r\n * Filters out non-serializable values (functions, symbols, undefined).\r\n * Returns undefined if no serializable props remain.\r\n * \r\n * @example\r\n * ```ts\r\n * serializeProps({ name: 'test', onClick: () => {} }); // { name: 'test' }\r\n * serializeProps({ onClick: () => {} }); // undefined\r\n * ```\r\n */\r\nexport function serializeProps(props: Record<string, any>): Record<string, any> | undefined {\r\n const filtered = filterClientDirectives(props);\r\n\r\n const result: Record<string, any> = {};\r\n let hasProps = false;\r\n\r\n for (const key in filtered) {\r\n const value = filtered[key];\r\n\r\n // Skip internal props\r\n if (key === 'children' || key === 'key' || key === 'ref' || key === 'slots') continue;\r\n\r\n // Skip functions (event handlers, etc.)\r\n if (typeof value === 'function') continue;\r\n\r\n // Skip symbols\r\n if (typeof value === 'symbol') continue;\r\n\r\n // Skip undefined values\r\n if (value === undefined) continue;\r\n\r\n // Skip event handlers (on* props)\r\n if (key.startsWith('on') && key.length > 2 && key[2] === key[2].toUpperCase()) continue;\r\n\r\n // Try to serialize - skip if fails\r\n try {\r\n JSON.stringify(value);\r\n result[key] = value;\r\n hasProps = true;\r\n } catch {\r\n // Non-serializable, skip\r\n }\r\n }\r\n\r\n return hasProps ? result : undefined;\r\n}\r\n\r\n/**\r\n * Create an emit function for component context.\r\n * This is a common pattern used in both mountComponent and hydrateComponent.\r\n * \r\n * @example\r\n * ```ts\r\n * const emit = createEmit(reactiveProps);\r\n * emit('click', eventData); // Calls props.onClick(eventData)\r\n * ```\r\n */\r\nexport function createEmit(reactiveProps: { value?: Record<string, any> } | Record<string, any>): (event: string, ...args: any[]) => void {\r\n return (event: string, ...args: any[]) => {\r\n const eventName = `on${event[0].toUpperCase() + event.slice(1)}`;\r\n // Handle both signal-wrapped props and plain props\r\n const props = 'value' in reactiveProps ? reactiveProps.value : reactiveProps;\r\n const handler = props?.[eventName];\r\n if (handler && typeof handler === 'function') {\r\n handler(...args);\r\n }\r\n };\r\n}\r\n","import { VNode, Fragment, JSXElement, Text } from './jsx-runtime.js';\r\nimport { effect, signal, untrack, EffectRunner } from '@sigx/reactivity';\r\nimport { ComponentSetupContext, setCurrentInstance, getCurrentInstance, MountContext, ViewFn, SetupFn } from './component.js';\r\nimport { createPropsAccessor } from './utils/props-accessor.js';\r\nimport { createSlots, InternalSlotsObject } from './utils/slots.js';\r\nimport { normalizeSubTree } from './utils/normalize.js';\r\nimport { applyContextExtensions } from './plugins.js';\r\nimport { isComponent } from './utils/is-component.js';\r\nimport { createEmit } from './hydration/index.js';\r\nimport { provideAppContext } from './di/injectable.js';\r\nimport { isModel } from './model.js';\r\nimport {\r\n AppContext,\r\n ComponentInstance,\r\n notifyComponentCreated,\r\n notifyComponentMounted,\r\n notifyComponentUnmounted,\r\n notifyComponentUpdated,\r\n handleComponentError\r\n} from './app.js';\r\n\r\n/**\r\n * Internal VNode with renderer-specific properties.\r\n * These properties are used by the renderer to track component state\r\n * but are not part of the public VNode API.\r\n */\r\nexport interface InternalVNode extends VNode {\r\n /** The reactive effect that re-renders the component */\r\n _effect?: EffectRunner;\r\n /** The rendered sub-tree VNode of a component */\r\n _subTree?: VNode | null;\r\n /**\r\n * Shared mutable reference to the current sub-tree.\r\n * Used to keep _subTree in sync across VNode replacements during same-type patches.\r\n * The effect closure writes to this ref, and all aliased VNodes share it.\r\n */\r\n _subTreeRef?: { current: VNode | null };\r\n /** The slots object for component children */\r\n _slots?: InternalSlotsObject;\r\n /** Reactive props signal for the component */\r\n _componentProps?: Record<string, any>;\r\n}\r\n\r\n// InternalSlotsObject is now imported from component-helpers.ts\r\n\r\n/**\r\n * Container element with internal VNode storage\r\n */\r\ninterface InternalContainer {\r\n _vnode?: VNode | null;\r\n}\r\n\r\n/**\r\n * Host node with back-reference to VNode\r\n */\r\ninterface InternalHostNode {\r\n __vnode?: VNode;\r\n}\r\n\r\n/**\r\n * Component factory function with setup and optional name\r\n */\r\ninterface ComponentFactory {\r\n __setup: SetupFn<any, any, any, any>;\r\n __name?: string;\r\n}\r\n\r\n/**\r\n * Internal component context with debug properties\r\n */\r\ninterface InternalComponentContext extends ComponentSetupContext {\r\n __name?: string;\r\n}\r\n\r\n// isComponent is imported from ./utils/is-component.js and re-exported\r\nexport { isComponent } from './utils/is-component.js';\r\n\r\nexport interface RendererOptions<HostNode = any, HostElement = any> {\r\n patchProp(el: HostElement, key: string, prevValue: any, nextValue: any, isSVG?: boolean): void;\r\n insert(child: HostNode, parent: HostElement, anchor?: HostNode | null): void;\r\n remove(child: HostNode): void;\r\n createElement(type: string, isSVG?: boolean, isCustomizedBuiltIn?: string): HostElement;\r\n createText(text: string): HostNode;\r\n createComment(text: string): HostNode;\r\n setText(node: HostNode, text: string): void;\r\n setElementText(node: HostElement, text: string): void;\r\n parentNode(node: HostNode): HostElement | null;\r\n nextSibling(node: HostNode): HostNode | null;\r\n querySelector?(selector: string): HostElement | null;\r\n setScopeId?(el: HostElement, id: string): void;\r\n cloneNode?(node: HostNode): HostNode;\r\n insertStaticContent?(content: string, parent: HostElement, anchor: HostNode | null, isSVG: boolean): [HostNode, HostNode];\r\n\r\n /**\r\n * Optional hook to handle `use:*` directive props.\r\n * Called by the core renderer for each `use:*` prop during mount and patch.\r\n * The platform renderer (e.g., runtime-dom) implements directive lifecycle logic here.\r\n * @param appContext - The current app context, used to resolve custom directives registered via `app.directive()`.\r\n */\r\n patchDirective?(el: HostElement, name: string, prevValue: any, nextValue: any, appContext: AppContext | null): void;\r\n\r\n /**\r\n * Optional hook called after an element is inserted into the DOM.\r\n * Used by runtime-dom for directive `mounted` lifecycle.\r\n */\r\n onElementMounted?(el: HostElement): void;\r\n\r\n /**\r\n * Optional hook called before an element is removed from the DOM.\r\n * Used by runtime-dom for directive `unmounted` lifecycle.\r\n */\r\n onElementUnmounted?(el: HostElement): void;\r\n\r\n /**\r\n * Optional hook to get the currently focused element.\r\n * Used to preserve focus across patch cycles.\r\n */\r\n getActiveElement?(): HostElement | null;\r\n\r\n /**\r\n * Optional hook to restore focus to a previously focused element.\r\n * Called after patching if the active element changed.\r\n */\r\n restoreFocus?(el: HostElement): void;\r\n}\r\n\r\nexport type RootRenderFunction<_HostNode = any, HostElement = any> = (\r\n vnode: JSXElement,\r\n container: HostElement,\r\n appContext?: AppContext\r\n) => void;\r\n\r\n/**\r\n * Function types for renderer operations exposed for plugins/hydration\r\n */\r\nexport type RendererMountFn<HostNode = any, HostElement = any> = (\r\n vnode: VNode,\r\n container: HostElement,\r\n before?: HostNode | null\r\n) => void;\r\n\r\nexport type RendererUnmountFn<_HostNode = any, HostElement = any> = (\r\n vnode: VNode,\r\n container: HostElement\r\n) => void;\r\n\r\nexport type RendererPatchFn<_HostNode = any, HostElement = any> = (\r\n n1: VNode,\r\n n2: VNode,\r\n container: HostElement\r\n) => void;\r\n\r\nexport type RendererMountComponentFn<HostNode = any, HostElement = any> = (\r\n vnode: VNode,\r\n container: HostElement,\r\n before: HostNode | null,\r\n setup: SetupFn<any, any, any, any>\r\n) => void;\r\n\r\n/**\r\n * Renderer instance returned by createRenderer\r\n */\r\nexport interface Renderer<HostNode = any, HostElement = any> {\r\n render: RootRenderFunction<HostNode, HostElement>;\r\n patch: RendererPatchFn<HostNode, HostElement>;\r\n mount: RendererMountFn<HostNode, HostElement>;\r\n unmount: RendererUnmountFn<HostNode, HostElement>;\r\n mountComponent: RendererMountComponentFn<HostNode, HostElement>;\r\n}\r\n\r\nexport function createRenderer<HostNode = any, HostElement = any>(\r\n options: RendererOptions<HostNode, HostElement>\r\n): Renderer<HostNode, HostElement> {\r\n const {\r\n insert: hostInsert,\r\n remove: hostRemove,\r\n patchProp: hostPatchProp,\r\n createElement: hostCreateElement,\r\n createText: hostCreateText,\r\n createComment: hostCreateComment,\r\n setText: hostSetText,\r\n setElementText: _hostSetElementText,\r\n parentNode: hostParentNode,\r\n nextSibling: hostNextSibling,\r\n cloneNode: _hostCloneNode,\r\n insertStaticContent: _hostInsertStaticContent,\r\n patchDirective: hostPatchDirective,\r\n onElementMounted: hostOnElementMounted,\r\n onElementUnmounted: hostOnElementUnmounted,\r\n getActiveElement: hostGetActiveElement,\r\n restoreFocus: hostRestoreFocus\r\n } = options;\r\n\r\n // Current app context (set when rendering via defineApp)\r\n let currentAppContext: AppContext | null = null;\r\n\r\n function render(element: JSXElement, container: HostElement, appContext?: AppContext): void {\r\n // Store app context for this render tree\r\n const _prevAppContext = currentAppContext;\r\n if (appContext) {\r\n currentAppContext = appContext;\r\n }\r\n\r\n const oldVNode = (container as unknown as InternalContainer)._vnode;\r\n\r\n // Normalize element to VNode if it's not\r\n let vnode: VNode | null = null;\r\n if (element != null && element !== false && element !== true) {\r\n if (typeof element === 'string' || typeof element === 'number') {\r\n vnode = {\r\n type: Text,\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null,\r\n text: element\r\n };\r\n } else if (isComponent(element)) {\r\n // Handle component factory passed directly (e.g., defineApp(Counter))\r\n vnode = {\r\n type: element as unknown as VNode['type'],\r\n props: {},\r\n key: null,\r\n children: [],\r\n dom: null\r\n };\r\n } else {\r\n vnode = element as VNode;\r\n }\r\n }\r\n\r\n if (vnode) {\r\n if (oldVNode) {\r\n patch(oldVNode, vnode, container);\r\n } else {\r\n mount(vnode, container);\r\n }\r\n (container as unknown as InternalContainer)._vnode = vnode;\r\n } else {\r\n if (oldVNode) {\r\n unmount(oldVNode, container);\r\n (container as unknown as InternalContainer)._vnode = null;\r\n }\r\n }\r\n }\r\n\r\n // SVG elements that should be created with createElementNS\r\n const svgTags = new Set([\r\n 'svg', 'animate', 'animateMotion', 'animateTransform', 'circle', 'clipPath',\r\n 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer',\r\n 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap',\r\n 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG',\r\n 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology',\r\n 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile',\r\n 'feTurbulence', 'filter', 'foreignObject', 'g', 'image', 'line', 'linearGradient',\r\n 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline',\r\n 'radialGradient', 'rect', 'set', 'stop', 'switch', 'symbol', 'text', 'textPath',\r\n 'title', 'tspan', 'use', 'view'\r\n ]);\r\n\r\n function isSvgTag(tag: string): boolean {\r\n return svgTags.has(tag);\r\n }\r\n function mount(vnode: VNode, container: HostElement, before: HostNode | null = null, parentIsSVG: boolean = false): void {\r\n // Guard against null, undefined, boolean values (from conditional rendering)\r\n if (vnode == null || vnode === (false as unknown as VNode) || vnode === (true as unknown as VNode)) {\r\n return;\r\n }\r\n\r\n if (vnode.type === Text) {\r\n const node = hostCreateText(String(vnode.text));\r\n vnode.dom = node;\r\n (node as unknown as InternalHostNode).__vnode = vnode;\r\n hostInsert(node, container, before);\r\n return;\r\n }\r\n\r\n if (vnode.type === Fragment) {\r\n // For fragments, we need a way to track the children's DOM nodes\r\n // Store the anchor comment for fragments\r\n const anchor = hostCreateComment('');\r\n vnode.dom = anchor;\r\n hostInsert(anchor, container, before);\r\n if (vnode.children) {\r\n vnode.children.forEach((child: VNode) => mount(child, container, anchor, parentIsSVG));\r\n }\r\n return;\r\n }\r\n\r\n // Check for component (function with __setup)\r\n if (isComponent(vnode.type)) {\r\n mountComponent(vnode, container, before, vnode.type.__setup as SetupFn);\r\n return;\r\n }\r\n\r\n // Determine if this element should be created as SVG\r\n const tag = vnode.type as string;\r\n const isSVG = tag === 'svg' || (parentIsSVG && tag !== 'foreignObject');\r\n\r\n const element = hostCreateElement(tag, isSVG);\r\n vnode.dom = element;\r\n (element as unknown as InternalHostNode).__vnode = vnode;\r\n\r\n // Props\r\n if (vnode.props) {\r\n for (const key in vnode.props) {\r\n if (key !== 'children' && key !== 'key' && key !== 'ref') {\r\n if (key.charCodeAt(0) === 117 /* 'u' */ && key.startsWith('use:')) {\r\n // Delegate use:* directive props to the platform renderer\r\n if (hostPatchDirective) {\r\n hostPatchDirective(element, key.slice(4), null, vnode.props[key], currentAppContext);\r\n }\r\n } else {\r\n hostPatchProp(element, key, null, vnode.props[key], isSVG);\r\n }\r\n }\r\n }\r\n\r\n // Handle ref - wrap in untrack to prevent reactive loops\r\n if (vnode.props.ref) {\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(element);\r\n } else if (typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = element;\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Children - pass SVG context (reset for foreignObject)\r\n const childIsSVG = isSVG && tag !== 'foreignObject';\r\n if (vnode.children) {\r\n vnode.children.forEach((child: VNode) => {\r\n child.parent = vnode;\r\n mount(child, element, null, childIsSVG)\r\n });\r\n }\r\n\r\n hostInsert(element as unknown as HostNode, container, before);\r\n\r\n // Invoke platform element lifecycle (e.g., directive mounted hooks in runtime-dom)\r\n if (hostOnElementMounted) {\r\n hostOnElementMounted(element);\r\n }\r\n }\r\n\r\n function unmount(vnode: VNode, container: HostElement): void {\r\n const internalVNode = vnode as InternalVNode;\r\n if (internalVNode._effect) {\r\n internalVNode._effect.stop(); // Stop effect\r\n }\r\n\r\n if (vnode.cleanup) {\r\n vnode.cleanup();\r\n }\r\n\r\n // Handle component unmount - unmount its subTree\r\n if (isComponent(vnode.type)) {\r\n // Use the shared subtree ref if available (handles stale _subTree after same-type patches)\r\n const subTree = internalVNode._subTreeRef?.current ?? internalVNode._subTree;\r\n if (subTree) {\r\n unmount(subTree, container);\r\n }\r\n // Remove the anchor comment\r\n if (vnode.dom) {\r\n hostRemove(vnode.dom);\r\n }\r\n // Handle ref cleanup - wrap in untrack to prevent reactive loops\r\n if (vnode.props?.ref) {\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(null);\r\n } else if (typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = null;\r\n }\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (vnode.type === Fragment) {\r\n if (vnode.children) {\r\n vnode.children.forEach((child: VNode) => unmount(child, container));\r\n }\r\n // Remove anchor comment if exists\r\n if (vnode.dom) {\r\n hostRemove(vnode.dom);\r\n }\r\n return;\r\n }\r\n\r\n // Handle ref cleanup - wrap in untrack to prevent reactive loops\r\n if (vnode.props?.ref) {\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(null);\r\n } else if (vnode.props.ref && typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = null;\r\n }\r\n });\r\n }\r\n\r\n // Invoke platform element lifecycle (e.g., directive unmounted hooks in runtime-dom)\r\n if (hostOnElementUnmounted && vnode.dom) {\r\n hostOnElementUnmounted(vnode.dom);\r\n }\r\n\r\n // Recursively unmount children for regular elements\r\n if (vnode.children && vnode.children.length > 0) {\r\n vnode.children.forEach((child: VNode) => unmount(child, vnode.dom as HostElement));\r\n }\r\n\r\n if (vnode.dom) {\r\n hostRemove(vnode.dom);\r\n }\r\n }\r\n\r\n function patch(oldVNode: VNode, newVNode: VNode, container: HostElement): void {\r\n if (oldVNode === newVNode) return;\r\n\r\n // If types are different, replace completely\r\n if (!isSameVNode(oldVNode, newVNode)) {\r\n const parent = hostParentNode(oldVNode.dom) || container;\r\n // With unified trailing markers, vnode.dom is always the trailing anchor\r\n // so hostNextSibling gives us the correct insertion point\r\n const nextSibling = oldVNode.dom ? hostNextSibling(oldVNode.dom) : null;\r\n unmount(oldVNode, parent as HostElement);\r\n mount(newVNode, parent as HostElement, nextSibling);\r\n return;\r\n }\r\n\r\n // If component\r\n const oldInternal = oldVNode as InternalVNode;\r\n const newInternal = newVNode as InternalVNode;\r\n if (oldInternal._effect) {\r\n newVNode.dom = oldVNode.dom;\r\n newInternal._effect = oldInternal._effect;\r\n newInternal._subTree = oldInternal._subTree;\r\n newInternal._subTreeRef = oldInternal._subTreeRef;\r\n newInternal._slots = oldInternal._slots;\r\n\r\n const props = oldInternal._componentProps;\r\n newInternal._componentProps = props;\r\n\r\n if (props) {\r\n const newProps = newVNode.props || {};\r\n const newModels = newVNode.props?.$models || {};\r\n \r\n // Update props (excluding children, key, ref, $models)\r\n // Also update Model objects from $models into props\r\n untrack(() => {\r\n for (const key in newProps) {\r\n if (key !== \"children\" && key !== \"key\" && key !== \"ref\" && key !== \"$models\") {\r\n if (props[key] !== newProps[key]) {\r\n props[key] = newProps[key];\r\n }\r\n }\r\n }\r\n \r\n // Merge updated Model objects into props\r\n // Only update if the binding changed (different obj or key)\r\n for (const modelKey in newModels) {\r\n const newModel = newModels[modelKey];\r\n const oldModel = props[modelKey];\r\n if (isModel(newModel)) {\r\n // Skip update if binding is the same (same obj and key)\r\n if (isModel(oldModel)) {\r\n const [newObj, newKey] = newModel.binding;\r\n const [oldObj, oldKey] = oldModel.binding;\r\n if (newObj === oldObj && newKey === oldKey) {\r\n continue; // Same binding, reuse old Model\r\n }\r\n }\r\n props[modelKey] = newModel;\r\n }\r\n }\r\n \r\n // Handle removed props (optional but good)\r\n for (const key in props) {\r\n if (!(key in newProps) && !(key in newModels) && key !== \"children\" && key !== \"key\" && key !== \"ref\" && key !== \"$models\") {\r\n delete props[key];\r\n }\r\n }\r\n });\r\n }\r\n\r\n // Update slots with new children and slot functions\r\n const slotsRef = oldInternal._slots;\r\n const newChildren = newVNode.props?.children;\r\n const newSlotsFromProps = newVNode.props?.slots;\r\n\r\n if (slotsRef) {\r\n // Update children for default slot\r\n if (newChildren !== undefined) {\r\n slotsRef._children = newChildren;\r\n }\r\n\r\n // Update slot functions from the slots prop\r\n if (newSlotsFromProps !== undefined) {\r\n slotsRef._slotsFromProps = newSlotsFromProps;\r\n }\r\n\r\n // Trigger component re-render by bumping version\r\n // Use per-component flag to prevent infinite loops on the SAME component\r\n // but allow nested components to update\r\n if (!slotsRef._isPatching) {\r\n slotsRef._isPatching = true;\r\n try {\r\n untrack(() => {\r\n slotsRef._version.v++;\r\n });\r\n } finally {\r\n slotsRef._isPatching = false;\r\n }\r\n }\r\n }\r\n\r\n return;\r\n }\r\n\r\n // If text node\r\n if (newVNode.type === Text) {\r\n newVNode.dom = oldVNode.dom;\r\n \r\n // Guard: if old text node has no DOM (can happen during hydration mismatch),\r\n // create a fresh text node instead of crashing\r\n if (!newVNode.dom) {\r\n const textNode = hostCreateText(String(newVNode.text));\r\n newVNode.dom = textNode;\r\n // Try to insert into container if possible\r\n if (container) {\r\n hostInsert(textNode, container, oldVNode.dom || null);\r\n }\r\n return;\r\n }\r\n \r\n if (oldVNode.text !== newVNode.text) {\r\n hostSetText(newVNode.dom, String(newVNode.text));\r\n }\r\n return;\r\n }\r\n\r\n // If Fragment\r\n if (newVNode.type === Fragment) {\r\n patchChildren(oldVNode, newVNode, container, false);\r\n return;\r\n }\r\n\r\n // Element\r\n const element = (newVNode.dom = oldVNode.dom) as HostElement;\r\n \r\n // Guard: if old element has no DOM (can happen with hydrated slot content),\r\n // recover by mounting fresh instead of crashing\r\n if (!element) {\r\n mount(newVNode, container);\r\n return;\r\n }\r\n \r\n // Determine if this is an SVG element (for proper attribute handling)\r\n const tag = newVNode.type as string;\r\n const isSVG = tag === 'svg' || isSvgTag(tag);\r\n\r\n // Update props\r\n const oldProps = oldVNode.props || {};\r\n const newProps = newVNode.props || {};\r\n\r\n // Remove old props\r\n for (const key in oldProps) {\r\n if (!(key in newProps) && key !== 'children' && key !== 'key' && key !== 'ref') {\r\n if (key.charCodeAt(0) === 117 /* 'u' */ && key.startsWith('use:')) {\r\n if (hostPatchDirective) {\r\n hostPatchDirective(element, key.slice(4), oldProps[key], null, currentAppContext);\r\n }\r\n } else {\r\n hostPatchProp(element, key, oldProps[key], null, isSVG);\r\n }\r\n }\r\n }\r\n\r\n // Set new props\r\n for (const key in newProps) {\r\n const oldValue = oldProps[key];\r\n const newValue = newProps[key];\r\n if (key !== 'children' && key !== 'key' && key !== 'ref' && oldValue !== newValue) {\r\n if (key.charCodeAt(0) === 117 /* 'u' */ && key.startsWith('use:')) {\r\n if (hostPatchDirective) {\r\n hostPatchDirective(element, key.slice(4), oldValue, newValue, currentAppContext);\r\n }\r\n } else {\r\n hostPatchProp(element, key, oldValue, newValue, isSVG);\r\n }\r\n }\r\n }\r\n\r\n // Update children - pass SVG context for child elements (reset for foreignObject)\r\n const childIsSVG = isSVG && tag !== 'foreignObject';\r\n patchChildren(oldVNode, newVNode, element, childIsSVG);\r\n }\r\n\r\n function patchChildren(oldVNode: VNode, newVNode: VNode, container: HostElement, parentIsSVG: boolean = false) {\r\n const oldChildren = oldVNode.children;\r\n const newChildren = newVNode.children;\r\n\r\n newChildren.forEach((c: VNode) => c.parent = newVNode);\r\n\r\n reconcileChildrenArray(container, oldChildren, newChildren, parentIsSVG);\r\n }\r\n\r\n /**\r\n * Check for duplicate keys in an array of VNodes and warn in development.\r\n */\r\n function checkDuplicateKeys(children: VNode[]): void {\r\n if (process.env.NODE_ENV === 'production') return;\r\n \r\n const seenKeys = new Set<string>();\r\n for (const child of children) {\r\n if (child?.key != null) {\r\n const keyStr = String(child.key);\r\n if (seenKeys.has(keyStr)) {\r\n console.warn(\r\n `[SignalX] Duplicate key \"${child.key}\" detected in list. ` +\r\n `Keys should be unique among siblings to ensure correct reconciliation. ` +\r\n `This may cause unexpected behavior when items are reordered, added, or removed.`\r\n );\r\n }\r\n seenKeys.add(keyStr);\r\n }\r\n }\r\n }\r\n\r\n function reconcileChildrenArray(parent: HostElement, oldChildren: VNode[], newChildren: VNode[], parentIsSVG: boolean = false) {\r\n // Check for duplicate keys in development\r\n if (process.env.NODE_ENV !== 'production') {\r\n checkDuplicateKeys(newChildren);\r\n }\r\n\r\n let oldStartIdx = 0;\r\n let oldEndIdx = oldChildren.length - 1;\r\n let oldStartVNode = oldChildren[0];\r\n let oldEndVNode = oldChildren[oldEndIdx];\r\n\r\n let newStartIdx = 0;\r\n let newEndIdx = newChildren.length - 1;\r\n let newStartVNode = newChildren[0];\r\n let newEndVNode = newChildren[newEndIdx];\r\n\r\n let oldKeyToIdx: Map<string | number, number> | undefined;\r\n\r\n while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {\r\n if (oldStartVNode == null) {\r\n oldStartVNode = oldChildren[++oldStartIdx];\r\n } else if (oldEndVNode == null) {\r\n oldEndVNode = oldChildren[--oldEndIdx];\r\n } else if (isSameVNode(oldStartVNode, newStartVNode)) {\r\n patch(oldStartVNode, newStartVNode, parent);\r\n oldStartVNode = oldChildren[++oldStartIdx];\r\n newStartVNode = newChildren[++newStartIdx];\r\n } else if (isSameVNode(oldEndVNode, newEndVNode)) {\r\n patch(oldEndVNode, newEndVNode, parent);\r\n oldEndVNode = oldChildren[--oldEndIdx];\r\n newEndVNode = newChildren[--newEndIdx];\r\n } else if (isSameVNode(oldStartVNode, newEndVNode)) {\r\n patch(oldStartVNode, newEndVNode, parent);\r\n const nodeToMove = oldStartVNode.dom;\r\n const anchor = hostNextSibling(oldEndVNode.dom);\r\n if (nodeToMove) {\r\n hostInsert(nodeToMove, parent, anchor);\r\n }\r\n oldStartVNode = oldChildren[++oldStartIdx];\r\n newEndVNode = newChildren[--newEndIdx];\r\n } else if (isSameVNode(oldEndVNode, newStartVNode)) {\r\n patch(oldEndVNode, newStartVNode, parent);\r\n const nodeToMove = oldEndVNode.dom;\r\n const anchor = oldStartVNode.dom;\r\n if (nodeToMove) {\r\n hostInsert(nodeToMove, parent, anchor);\r\n }\r\n oldEndVNode = oldChildren[--oldEndIdx];\r\n newStartVNode = newChildren[++newStartIdx];\r\n } else {\r\n if (!oldKeyToIdx) {\r\n oldKeyToIdx = createKeyToKeyIndexMap(oldChildren, oldStartIdx, oldEndIdx);\r\n }\r\n const idxInOld = newStartVNode.key != null\r\n ? oldKeyToIdx.get(String(newStartVNode.key))\r\n : findIndexInOld(oldChildren, newStartVNode, oldStartIdx, oldEndIdx);\r\n\r\n if (idxInOld != null) {\r\n const vnodeToMove = oldChildren[idxInOld];\r\n patch(vnodeToMove, newStartVNode, parent);\r\n oldChildren[idxInOld] = undefined!;\r\n if (vnodeToMove.dom && oldStartVNode.dom) {\r\n hostInsert(vnodeToMove.dom, parent, oldStartVNode.dom);\r\n }\r\n } else {\r\n mount(newStartVNode, parent, oldStartVNode.dom, parentIsSVG);\r\n }\r\n newStartVNode = newChildren[++newStartIdx];\r\n }\r\n }\r\n\r\n if (oldStartIdx > oldEndIdx) {\r\n if (newStartIdx <= newEndIdx) {\r\n const anchor = newChildren[newEndIdx + 1] == null ? null : newChildren[newEndIdx + 1].dom;\r\n for (let i = newStartIdx; i <= newEndIdx; i++) {\r\n mount(newChildren[i], parent, anchor, parentIsSVG);\r\n }\r\n }\r\n } else if (newStartIdx > newEndIdx) {\r\n for (let i = oldStartIdx; i <= oldEndIdx; i++) {\r\n if (oldChildren[i]) {\r\n unmount(oldChildren[i], parent);\r\n }\r\n }\r\n }\r\n }\r\n\r\n function isSameVNode(n1: VNode, n2: VNode): boolean {\r\n const k1 = n1.key == null ? null : n1.key;\r\n const k2 = n2.key == null ? null : n2.key;\r\n if (n1.type !== n2.type) return false;\r\n if (k1 === k2) return true;\r\n\r\n return String(k1) === String(k2);\r\n }\r\n\r\n function createKeyToKeyIndexMap(children: VNode[], beginIdx: number, endIdx: number) {\r\n const map = new Map<string | number, number>();\r\n for (let i = beginIdx; i <= endIdx; i++) {\r\n const key = children[i]?.key;\r\n if (key != null) {\r\n const keyStr = String(key);\r\n if (process.env.NODE_ENV !== 'production' && map.has(keyStr)) {\r\n console.warn(\r\n `[SignalX] Duplicate key \"${key}\" detected in list. ` +\r\n `Keys should be unique among siblings to ensure correct reconciliation. ` +\r\n `This may cause unexpected behavior when items are reordered, added, or removed.`\r\n );\r\n }\r\n map.set(keyStr, i);\r\n }\r\n }\r\n return map;\r\n }\r\n\r\n function findIndexInOld(children: VNode[], newChild: VNode, beginIdx: number, endIdx: number): number | null {\r\n for (let i = beginIdx; i <= endIdx; i++) {\r\n if (children[i] && isSameVNode(children[i], newChild)) return i;\r\n }\r\n return null;\r\n }\r\n\r\n // createPropsAccessor is now imported from component-helpers.ts\r\n\r\n function mountComponent(vnode: VNode, container: HostElement, before: HostNode | null, setup: SetupFn<any, any, any, any>) {\r\n // No wrapper element - we render directly into the container\r\n // Use an anchor comment to track the component's position\r\n const anchor = hostCreateComment('');\r\n vnode.dom = anchor; // The anchor serves as the component's \"DOM\" marker\r\n (anchor as unknown as InternalHostNode).__vnode = vnode;\r\n hostInsert(anchor, container, before);\r\n\r\n let exposed: any = null;\r\n let exposeCalled = false;\r\n\r\n const initialProps = vnode.props || {};\r\n // Create reactive props - exclude children, slots, and $models to avoid deep recursion on VNodes\r\n const { children, slots: slotsFromProps, $models: modelsData, ...propsData } = initialProps;\r\n \r\n // Merge Model<T> objects directly into props for unified access: props.model.value\r\n const propsWithModels = { ...propsData };\r\n if (modelsData) {\r\n for (const modelKey in modelsData) {\r\n const modelValue = modelsData[modelKey];\r\n if (isModel(modelValue)) {\r\n propsWithModels[modelKey] = modelValue;\r\n }\r\n }\r\n }\r\n \r\n const reactiveProps = signal(propsWithModels);\r\n const internalVNode = vnode as InternalVNode;\r\n internalVNode._componentProps = reactiveProps;\r\n\r\n // Create slots object from children and the slots prop\r\n const slots = createSlots(children, slotsFromProps);\r\n internalVNode._slots = slots;\r\n\r\n const createdHooks: (() => void)[] = [];\r\n const mountHooks: ((ctx: MountContext) => void)[] = [];\r\n const updatedHooks: (() => void)[] = [];\r\n const unmountHooks: ((ctx: MountContext) => void)[] = [];\r\n\r\n // Capture the parent component context BEFORE creating the new one\r\n // This is crucial for Provide/Inject to work\r\n const parentInstance = getCurrentInstance();\r\n\r\n // Get component name from the factory (if set via options)\r\n const componentFactory = vnode.type as unknown as ComponentFactory;\r\n const componentName = componentFactory.__name;\r\n\r\n // Create props accessor with defaults support\r\n const propsAccessor = createPropsAccessor(reactiveProps);\r\n\r\n const ctx: ComponentSetupContext = {\r\n el: container, // The parent container (since we don't have a wrapper)\r\n signal: signal,\r\n props: propsAccessor,\r\n slots: slots,\r\n emit: createEmit(reactiveProps),\r\n parent: parentInstance, // Link to parent for DI traversal\r\n onMounted: (fn) => { mountHooks.push(fn); },\r\n onUnmounted: (fn) => { unmountHooks.push(fn); },\r\n onCreated: (fn) => { createdHooks.push(fn); },\r\n onUpdated: (fn) => { updatedHooks.push(fn); },\r\n expose: (exposedValue) => {\r\n exposed = exposedValue;\r\n exposeCalled = true;\r\n },\r\n renderFn: null, // Will be set after setup returns\r\n update: () => { } // Placeholder, will be set after effect is created\r\n } as ComponentSetupContext;\r\n\r\n // Apply context extensions from plugins (e.g., SSR helper)\r\n applyContextExtensions(ctx);\r\n\r\n // Store the component name on the context for debugging\r\n (ctx as InternalComponentContext).__name = componentName;\r\n\r\n // For ROOT component only (no parent), provide the AppContext\r\n // This enables the DI system to find app-level provides by traversing up the tree\r\n if (!parentInstance && currentAppContext) {\r\n provideAppContext(ctx, currentAppContext);\r\n }\r\n\r\n // Create component instance info for lifecycle hooks\r\n const componentInstance: ComponentInstance = {\r\n name: componentName,\r\n ctx,\r\n vnode\r\n };\r\n\r\n const prev = setCurrentInstance(ctx);\r\n let renderFn: ViewFn | undefined;\r\n try {\r\n const setupResult = setup(ctx);\r\n // Async setup is only supported on server - check for promise\r\n if (setupResult && typeof (setupResult as any).then === 'function') {\r\n throw new Error(\r\n `Async setup in component \"${componentName}\" is only supported during SSR. ` +\r\n `On the client, use pre-loaded data from hydration or fetch in onMounted.`\r\n );\r\n }\r\n renderFn = setupResult as ViewFn;\r\n // Notify plugins that component was created (setup completed)\r\n notifyComponentCreated(currentAppContext, componentInstance);\r\n // Run component-level created hooks\r\n createdHooks.forEach(hook => hook());\r\n } catch (err) {\r\n // Handle setup errors\r\n const handled = handleComponentError(currentAppContext, err as Error, componentInstance, 'setup');\r\n if (!handled) {\r\n throw err;\r\n }\r\n } finally {\r\n setCurrentInstance(prev);\r\n }\r\n\r\n // Handle ref - wrap in untrack to prevent reactive loops\r\n if (vnode.props?.ref) {\r\n const refValue = exposeCalled ? exposed : null;\r\n untrack(() => {\r\n if (typeof vnode.props.ref === 'function') {\r\n vnode.props.ref(refValue);\r\n } else if (vnode.props.ref && typeof vnode.props.ref === 'object') {\r\n vnode.props.ref.current = refValue;\r\n }\r\n });\r\n }\r\n\r\n if (renderFn) {\r\n ctx.renderFn = renderFn;\r\n\r\n // Shared mutable ref for the current subtree.\r\n // This ensures that when same-type patching replaces the VNode,\r\n // the effect closure and all aliased VNodes share the same subtree reference.\r\n const subTreeRef: { current: VNode | null } = { current: null };\r\n internalVNode._subTreeRef = subTreeRef;\r\n\r\n const componentEffect = effect(() => {\r\n // Set current instance during render so child components can find their parent\r\n const prevInstance = setCurrentInstance(ctx);\r\n try {\r\n const subTreeResult = ctx.renderFn!();\r\n if (subTreeResult == null) {\r\n // If render returns null, unmount any existing subtree\r\n // to prevent stale content from remaining in the DOM.\r\n if (subTreeRef.current) {\r\n unmount(subTreeRef.current, container);\r\n subTreeRef.current = null;\r\n internalVNode._subTree = null;\r\n }\r\n return;\r\n }\r\n\r\n // Handle arrays (fragments) or single vnodes\r\n const subTree = normalizeSubTree(subTreeResult);\r\n const prevSubTree = subTreeRef.current;\r\n\r\n if (prevSubTree) {\r\n // Preserve focused element across the entire patch cycle\r\n const prevFocus = hostGetActiveElement ? hostGetActiveElement() : null;\r\n patch(prevSubTree, subTree, container);\r\n if (prevFocus && hostRestoreFocus && hostGetActiveElement!() !== prevFocus) {\r\n hostRestoreFocus(prevFocus);\r\n }\r\n // Notify plugins of component update (re-render)\r\n notifyComponentUpdated(currentAppContext, componentInstance);\r\n // Run component-level updated hooks\r\n updatedHooks.forEach(hook => hook());\r\n } else {\r\n mount(subTree, container, anchor);\r\n }\r\n subTreeRef.current = subTree;\r\n internalVNode._subTree = subTree;\r\n } catch (err) {\r\n // Handle render errors\r\n const handled = handleComponentError(currentAppContext, err as Error, componentInstance, 'render');\r\n if (!handled) {\r\n throw err;\r\n }\r\n } finally {\r\n setCurrentInstance(prevInstance);\r\n }\r\n });\r\n internalVNode._effect = componentEffect;\r\n\r\n // Implement update() - re-runs the current render function\r\n // For HMR: set ctx.renderFn first, then call update()\r\n ctx.update = () => {\r\n componentEffect();\r\n };\r\n }\r\n\r\n // Run mount hooks\r\n const mountCtx = { el: container };\r\n mountHooks.forEach(hook => hook(mountCtx));\r\n\r\n // Notify plugins that component was mounted\r\n notifyComponentMounted(currentAppContext, componentInstance);\r\n\r\n // Store cleanup hooks on vnode for unmount\r\n vnode.cleanup = () => {\r\n // Notify plugins that component is being unmounted\r\n notifyComponentUnmounted(currentAppContext, componentInstance);\r\n unmountHooks.forEach(hook => hook(mountCtx));\r\n };\r\n }\r\n\r\n // createSlots and normalizeSubTree are now imported from component-helpers.ts\r\n\r\n return {\r\n render,\r\n patch,\r\n mount,\r\n unmount,\r\n mountComponent\r\n };\r\n}\r\n"],"mappings":"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"}