@bquery/bquery 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/README.md +586 -527
  2. package/dist/component/component.d.ts +13 -5
  3. package/dist/component/component.d.ts.map +1 -1
  4. package/dist/component/html.d.ts +40 -3
  5. package/dist/component/html.d.ts.map +1 -1
  6. package/dist/component/index.d.ts +4 -2
  7. package/dist/component/index.d.ts.map +1 -1
  8. package/dist/component/library.d.ts +34 -0
  9. package/dist/component/library.d.ts.map +1 -0
  10. package/dist/component/types.d.ts +132 -13
  11. package/dist/component/types.d.ts.map +1 -1
  12. package/dist/component-BEQgt5hl.js +600 -0
  13. package/dist/component-BEQgt5hl.js.map +1 -0
  14. package/dist/component.es.mjs +7 -184
  15. package/dist/config-DRmZZno3.js +40 -0
  16. package/dist/config-DRmZZno3.js.map +1 -0
  17. package/dist/core-BGQJVw0-.js +35 -0
  18. package/dist/core-BGQJVw0-.js.map +1 -0
  19. package/dist/core-CCEabVHl.js +648 -0
  20. package/dist/core-CCEabVHl.js.map +1 -0
  21. package/dist/core.es.mjs +45 -1261
  22. package/dist/effect-AFRW_Plg.js +84 -0
  23. package/dist/effect-AFRW_Plg.js.map +1 -0
  24. package/dist/full.d.ts +8 -8
  25. package/dist/full.d.ts.map +1 -1
  26. package/dist/full.es.mjs +101 -91
  27. package/dist/full.iife.js +173 -3
  28. package/dist/full.iife.js.map +1 -1
  29. package/dist/full.umd.js +173 -3
  30. package/dist/full.umd.js.map +1 -1
  31. package/dist/index.es.mjs +147 -139
  32. package/dist/motion/transition.d.ts +1 -1
  33. package/dist/motion/transition.d.ts.map +1 -1
  34. package/dist/motion/types.d.ts +11 -1
  35. package/dist/motion/types.d.ts.map +1 -1
  36. package/dist/motion-D9TcHxOF.js +415 -0
  37. package/dist/motion-D9TcHxOF.js.map +1 -0
  38. package/dist/motion.es.mjs +25 -361
  39. package/dist/object-qGpWr6-J.js +38 -0
  40. package/dist/object-qGpWr6-J.js.map +1 -0
  41. package/dist/platform/announcer.d.ts +59 -0
  42. package/dist/platform/announcer.d.ts.map +1 -0
  43. package/dist/platform/config.d.ts +92 -0
  44. package/dist/platform/config.d.ts.map +1 -0
  45. package/dist/platform/cookies.d.ts +45 -0
  46. package/dist/platform/cookies.d.ts.map +1 -0
  47. package/dist/platform/index.d.ts +8 -0
  48. package/dist/platform/index.d.ts.map +1 -1
  49. package/dist/platform/meta.d.ts +62 -0
  50. package/dist/platform/meta.d.ts.map +1 -0
  51. package/dist/platform-Dr9b6fsq.js +362 -0
  52. package/dist/platform-Dr9b6fsq.js.map +1 -0
  53. package/dist/platform.es.mjs +11 -248
  54. package/dist/reactive/async-data.d.ts +114 -0
  55. package/dist/reactive/async-data.d.ts.map +1 -0
  56. package/dist/reactive/index.d.ts +2 -2
  57. package/dist/reactive/index.d.ts.map +1 -1
  58. package/dist/reactive/signal.d.ts +2 -0
  59. package/dist/reactive/signal.d.ts.map +1 -1
  60. package/dist/reactive-DSkct0dO.js +254 -0
  61. package/dist/reactive-DSkct0dO.js.map +1 -0
  62. package/dist/reactive.es.mjs +18 -32
  63. package/dist/router-CbDhl8rS.js +188 -0
  64. package/dist/router-CbDhl8rS.js.map +1 -0
  65. package/dist/router.es.mjs +11 -200
  66. package/dist/sanitize-Bs2dkMby.js +313 -0
  67. package/dist/sanitize-Bs2dkMby.js.map +1 -0
  68. package/dist/security/constants.d.ts.map +1 -1
  69. package/dist/security/index.d.ts +4 -2
  70. package/dist/security/index.d.ts.map +1 -1
  71. package/dist/security/sanitize.d.ts +4 -1
  72. package/dist/security/sanitize.d.ts.map +1 -1
  73. package/dist/security/trusted-html.d.ts +53 -0
  74. package/dist/security/trusted-html.d.ts.map +1 -0
  75. package/dist/security.es.mjs +11 -56
  76. package/dist/store/define-store.d.ts +1 -1
  77. package/dist/store/define-store.d.ts.map +1 -1
  78. package/dist/store/mapping.d.ts +1 -1
  79. package/dist/store/mapping.d.ts.map +1 -1
  80. package/dist/store/persisted.d.ts +1 -1
  81. package/dist/store/persisted.d.ts.map +1 -1
  82. package/dist/store/types.d.ts +2 -2
  83. package/dist/store/types.d.ts.map +1 -1
  84. package/dist/store/watch.d.ts +1 -1
  85. package/dist/store/watch.d.ts.map +1 -1
  86. package/dist/store-BwDvI45q.js +263 -0
  87. package/dist/store-BwDvI45q.js.map +1 -0
  88. package/dist/store.es.mjs +12 -25
  89. package/dist/storybook/index.d.ts +37 -0
  90. package/dist/storybook/index.d.ts.map +1 -0
  91. package/dist/storybook.es.mjs +151 -0
  92. package/dist/storybook.es.mjs.map +1 -0
  93. package/dist/untrack-B0rVscTc.js +7 -0
  94. package/dist/untrack-B0rVscTc.js.map +1 -0
  95. package/dist/view-C70lA3vf.js +397 -0
  96. package/dist/view-C70lA3vf.js.map +1 -0
  97. package/dist/view.es.mjs +11 -430
  98. package/package.json +141 -132
  99. package/src/component/component.ts +524 -289
  100. package/src/component/html.ts +153 -53
  101. package/src/component/index.ts +50 -40
  102. package/src/component/library.ts +518 -0
  103. package/src/component/types.ts +256 -85
  104. package/src/core/collection.ts +628 -628
  105. package/src/core/element.ts +774 -774
  106. package/src/core/index.ts +48 -48
  107. package/src/core/utils/function.ts +151 -151
  108. package/src/full.ts +229 -187
  109. package/src/motion/animate.ts +113 -113
  110. package/src/motion/flip.ts +176 -176
  111. package/src/motion/scroll.ts +57 -57
  112. package/src/motion/spring.ts +150 -150
  113. package/src/motion/timeline.ts +246 -246
  114. package/src/motion/transition.ts +97 -51
  115. package/src/motion/types.ts +11 -1
  116. package/src/platform/announcer.ts +208 -0
  117. package/src/platform/config.ts +163 -0
  118. package/src/platform/cookies.ts +165 -0
  119. package/src/platform/index.ts +21 -0
  120. package/src/platform/meta.ts +168 -0
  121. package/src/platform/storage.ts +215 -215
  122. package/src/reactive/async-data.ts +486 -0
  123. package/src/reactive/core.ts +114 -114
  124. package/src/reactive/effect.ts +54 -54
  125. package/src/reactive/index.ts +15 -1
  126. package/src/reactive/internals.ts +122 -122
  127. package/src/reactive/signal.ts +9 -0
  128. package/src/security/constants.ts +3 -1
  129. package/src/security/index.ts +17 -10
  130. package/src/security/sanitize-core.ts +364 -364
  131. package/src/security/sanitize.ts +70 -66
  132. package/src/security/trusted-html.ts +71 -0
  133. package/src/store/define-store.ts +49 -48
  134. package/src/store/mapping.ts +74 -73
  135. package/src/store/persisted.ts +62 -61
  136. package/src/store/types.ts +92 -94
  137. package/src/store/watch.ts +53 -52
  138. package/src/storybook/index.ts +479 -0
  139. package/src/view/evaluate.ts +290 -290
  140. package/dist/batch-x7b2eZST.js +0 -13
  141. package/dist/batch-x7b2eZST.js.map +0 -1
  142. package/dist/component.es.mjs.map +0 -1
  143. package/dist/core-BhpuvPhy.js +0 -170
  144. package/dist/core-BhpuvPhy.js.map +0 -1
  145. package/dist/core.es.mjs.map +0 -1
  146. package/dist/full.es.mjs.map +0 -1
  147. package/dist/index.es.mjs.map +0 -1
  148. package/dist/motion.es.mjs.map +0 -1
  149. package/dist/persisted-DHoi3uEs.js +0 -278
  150. package/dist/persisted-DHoi3uEs.js.map +0 -1
  151. package/dist/platform.es.mjs.map +0 -1
  152. package/dist/reactive.es.mjs.map +0 -1
  153. package/dist/router.es.mjs.map +0 -1
  154. package/dist/sanitize-Cxvxa-DX.js +0 -283
  155. package/dist/sanitize-Cxvxa-DX.js.map +0 -1
  156. package/dist/security.es.mjs.map +0 -1
  157. package/dist/store.es.mjs.map +0 -1
  158. package/dist/type-guards-BdKlYYlS.js +0 -32
  159. package/dist/type-guards-BdKlYYlS.js.map +0 -1
  160. package/dist/untrack-DNnnqdlR.js +0 -6
  161. package/dist/untrack-DNnnqdlR.js.map +0 -1
  162. package/dist/view.es.mjs.map +0 -1
  163. package/dist/watch-DXXv3iAI.js +0 -58
  164. package/dist/watch-DXXv3iAI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-BEQgt5hl.js","names":[],"sources":["../src/component/props.ts","../src/component/component.ts","../src/component/html.ts","../src/component/library.ts"],"sourcesContent":["/**\n * Prop coercion utilities.\n *\n * @module bquery/component\n */\n\nimport type { PropDefinition } from './types';\n\n/**\n * Coerces a string attribute value into a typed prop value.\n * Supports String, Number, Boolean, Object, Array, and custom converters.\n *\n * @internal\n * @template T - The target type\n * @param rawValue - The raw string value from the attribute\n * @param config - The prop definition with type information\n * @returns The coerced value of type T\n */\nexport const coercePropValue = <T>(rawValue: string, config: PropDefinition<T>): T => {\n const { type } = config;\n\n if (type === String) return rawValue as T;\n\n if (type === Number) {\n return Number(rawValue) as T;\n }\n\n if (type === Boolean) {\n const normalized = rawValue.trim().toLowerCase();\n if (normalized === '' || normalized === 'true' || normalized === '1') {\n return true as T;\n }\n if (normalized === 'false' || normalized === '0') {\n return false as T;\n }\n return Boolean(rawValue) as T;\n }\n\n if (type === Object || type === Array) {\n try {\n return JSON.parse(rawValue) as T;\n } catch {\n return rawValue as T;\n }\n }\n\n if (typeof type === 'function') {\n const callable = type as (value: unknown) => T;\n const constructable = type as new (value: unknown) => T;\n\n // Explicit construct mode takes precedence\n if (config.construct === true) {\n return Reflect.construct(constructable, [rawValue]) as T;\n }\n if (config.construct === false) {\n return callable(rawValue);\n }\n\n // Auto-detect: Check if type is constructable\n // A function is considered constructable if:\n // 1. It has a prototype with properties beyond just constructor, OR\n // 2. Its prototype.constructor is not itself (inherited), OR\n // 3. It's a class (toString starts with \"class\")\n const hasPrototype = type.prototype !== undefined && type.prototype !== null;\n const prototypeProps = hasPrototype ? Object.getOwnPropertyNames(type.prototype) : [];\n const hasPrototypeMethods = prototypeProps.length > 1;\n const hasInheritedConstructor = hasPrototype && type.prototype.constructor !== type;\n const isClassSyntax = /^class\\s/.test(Function.prototype.toString.call(type));\n\n const isConstructable = hasPrototypeMethods || hasInheritedConstructor || isClassSyntax;\n\n // For constructable types (e.g. Date, custom classes), prefer `new` to avoid\n // silent wrong-type returns (Date() returns string, new Date() returns Date)\n if (isConstructable) {\n try {\n return Reflect.construct(constructable, [rawValue]) as T;\n } catch {\n // Fall back to calling as function if construction fails\n return callable(rawValue);\n }\n }\n\n // For non-constructable types (arrow functions, plain functions), call directly\n // but fall back to constructor if result is undefined (common for function constructors)\n try {\n const result = callable(rawValue);\n\n // If calling without `new` returned undefined and the function has a prototype,\n // it's likely a function constructor that should be called with `new`\n if (result === undefined && hasPrototype) {\n try {\n return Reflect.construct(constructable, [rawValue]) as T;\n } catch {\n // Construction also failed, return the undefined\n return result as T;\n }\n }\n\n return result as T;\n } catch (error) {\n // Fall back to constructor if error indicates 'new' is required\n const isNewRequired =\n error instanceof TypeError &&\n /cannot be invoked without 'new'|is not a function/i.test(error.message);\n\n if (isNewRequired) {\n return Reflect.construct(constructable, [rawValue]) as T;\n }\n\n // Rethrow original error for non-constructable converters\n throw error;\n }\n }\n\n return rawValue as T;\n};\n","/**\r\n * Web Component factory and registry.\r\n *\r\n * @module bquery/component\r\n */\r\n\r\nimport { sanitizeHtml } from '../security/sanitize';\r\nimport { effect, untrack } from '../reactive/signal';\r\nimport type { CleanupFn } from '../reactive/signal';\r\nimport { coercePropValue } from './props';\r\nimport type {\r\n AttributeChange,\r\n ComponentClass,\r\n ComponentDefinition,\r\n ComponentSignalLike,\r\n ComponentSignals,\r\n ComponentStateShape,\r\n PropDefinition,\r\n} from './types';\r\n\r\n/**\r\n * Base extra tags preserved for component shadow DOM renders in addition to the\r\n * global sanitizer defaults. `slot` must remain allowed here because shadow DOM\r\n * content projection depends on authored `<slot>` elements in component render\r\n * output.\r\n */\r\nconst COMPONENT_ALLOWED_TAGS = ['slot'];\r\n\r\n/**\r\n * Base extra attributes preserved for component shadow DOM renders in addition\r\n * to the global sanitizer defaults.\r\n */\r\nconst COMPONENT_ALLOWED_ATTRIBUTES = [\r\n 'part',\r\n // Standard form attributes required by interactive shadow DOM content\r\n 'disabled',\r\n 'checked',\r\n 'placeholder',\r\n 'value',\r\n 'rows',\r\n 'cols',\r\n 'readonly',\r\n 'required',\r\n 'maxlength',\r\n 'minlength',\r\n 'max',\r\n 'min',\r\n 'step',\r\n 'pattern',\r\n 'autocomplete',\r\n 'autofocus',\r\n 'for',\r\n 'multiple',\r\n 'selected',\r\n 'wrap',\r\n];\r\n\r\n/**\r\n * Creates a custom element class for a component definition.\r\n *\r\n * This is useful when you want to extend or register the class manually\r\n * (e.g. with different tag names in tests or custom registries).\r\n *\r\n * @template TProps - Type of the component's props\r\n * @param tagName - The custom element tag name (used for diagnostics)\r\n * @param definition - The component configuration\r\n */\r\nconst createComponentClass = <\r\n TProps extends Record<string, unknown>,\r\n TState extends Record<string, unknown> | undefined = undefined,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, TState, TSignals>\r\n): ComponentClass<TState> => {\r\n const componentAllowedTags = [...COMPONENT_ALLOWED_TAGS, ...(definition.sanitize?.allowTags ?? [])];\r\n const componentAllowedAttributes = [\r\n ...COMPONENT_ALLOWED_ATTRIBUTES,\r\n ...(definition.sanitize?.allowAttributes ?? []),\r\n ];\r\n const signalSources = Object.values(definition.signals ?? {}) as ComponentSignalLike<unknown>[];\r\n\r\n class BQueryComponent extends HTMLElement {\r\n /** Internal state object for the component */\r\n private readonly state: ComponentStateShape<TState> = {\r\n ...(definition.state ?? {}),\r\n } as ComponentStateShape<TState>;\r\n /** Typed props object populated from attributes */\r\n private props = {} as TProps;\r\n /** Tracks missing required props for validation during connectedCallback */\r\n private missingRequiredProps = new Set<string>();\r\n /** Tracks whether the component has completed its initial mount */\r\n private hasMounted = false;\r\n /** Cleanup for external signal subscriptions */\r\n private signalEffectCleanup?: CleanupFn;\r\n\r\n constructor() {\r\n super();\r\n this.attachShadow({ mode: 'open' });\r\n this.syncProps();\r\n }\r\n\r\n /**\r\n * Returns the list of attributes to observe for changes.\r\n */\r\n static get observedAttributes(): string[] {\r\n return Object.keys(definition.props ?? {});\r\n }\r\n\r\n /**\r\n * Called when the element is added to the DOM.\r\n */\r\n connectedCallback(): void {\r\n try {\r\n // Defer only the initial mount until all required props are present.\r\n // Already-mounted components must still reconnect their signal\r\n // subscriptions so reactive updates can resume after reattachment.\r\n if (!this.hasMounted && this.missingRequiredProps.size > 0) {\r\n // Component will mount once all required props are satisfied\r\n // via attributeChangedCallback\r\n return;\r\n }\r\n if (this.hasMounted) {\r\n try {\r\n definition.connected?.call(this);\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n this.setupSignalSubscriptions(true);\r\n return;\r\n }\r\n this.mount();\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Performs the initial mount of the component.\r\n * Called when the element is connected and all required props are present.\r\n * @internal\r\n */\r\n private mount(): void {\r\n if (this.hasMounted) return;\r\n definition.beforeMount?.call(this);\r\n definition.connected?.call(this);\r\n this.render();\r\n this.setupSignalSubscriptions();\r\n this.hasMounted = true;\r\n }\r\n\r\n /**\r\n * Called when the element is removed from the DOM.\r\n */\r\n disconnectedCallback(): void {\r\n try {\r\n this.signalEffectCleanup?.();\r\n this.signalEffectCleanup = undefined;\r\n definition.disconnected?.call(this);\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Called when an observed attribute changes.\r\n */\r\n attributeChangedCallback(\r\n name: string,\r\n oldValue: string | null,\r\n newValue: string | null\r\n ): void {\r\n try {\r\n const previousProps = this.cloneProps();\r\n this.syncProps();\r\n\r\n if (this.hasMounted) {\r\n // Component already mounted - trigger update render\r\n this.render(true, previousProps, { name, oldValue, newValue });\r\n } else if (this.isConnected && this.missingRequiredProps.size === 0) {\r\n // All required props are now satisfied and element is connected\r\n // Trigger the deferred initial mount\r\n this.mount();\r\n }\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Handles errors during component lifecycle.\r\n * @internal\r\n */\r\n private handleError(error: Error): void {\r\n if (definition.onError) {\r\n definition.onError.call(this, error);\r\n } else {\r\n console.error(`bQuery component error in <${tagName}>:`, error);\r\n }\r\n }\r\n\r\n /**\r\n * Updates a state property and triggers a re-render.\r\n *\r\n * @param key - The state property key\r\n * @param value - The new value\r\n */\r\n setState<TKey extends keyof ComponentStateShape<TState>>(\r\n key: TKey,\r\n value: ComponentStateShape<TState>[TKey]\r\n ): void {\r\n this.state[key] = value;\r\n this.render(true, this.cloneProps(), undefined, false);\r\n }\r\n\r\n /**\r\n * Gets a state property value.\r\n *\r\n * @param key - The state property key\r\n * @returns The current value\r\n */\r\n getState<TKey extends keyof ComponentStateShape<TState>>(\r\n key: TKey\r\n ): ComponentStateShape<TState>[TKey];\r\n getState<TResult = unknown>(key: string): TResult;\r\n getState(key: string): unknown {\r\n return (this.state as Record<string, unknown>)[key];\r\n }\r\n\r\n /**\r\n * Subscribes to declared reactive sources and re-renders on change.\r\n *\r\n * @param renderOnInitialRun - When true, immediately re-renders after\r\n * re-subscribing so detached components resync with any signal changes\r\n * that happened while they were disconnected.\r\n * @internal\r\n */\r\n private setupSignalSubscriptions(renderOnInitialRun = false): void {\r\n if (this.signalEffectCleanup || signalSources.length === 0) return;\r\n\r\n let isInitialRun = true;\r\n this.signalEffectCleanup = effect(() => {\r\n try {\r\n for (const source of signalSources) {\r\n // Intentionally read each source to register this effect as a subscriber.\r\n void source.value;\r\n }\r\n\r\n if (isInitialRun) {\r\n isInitialRun = false;\r\n if (renderOnInitialRun && this.hasMounted && this.isConnected) {\r\n // Signal-driven reconnect renders do not change props, so the\r\n // previous-props snapshot is the current prop set at reconnect time.\r\n const previousProps = this.cloneProps();\r\n untrack(() => {\r\n this.render(true, previousProps, undefined, false);\r\n });\r\n }\r\n return;\r\n }\r\n\r\n if (!this.hasMounted || !this.isConnected) return;\r\n\r\n // Signal updates leave props unchanged, so cloning the current props\r\n // provides the previous-props snapshot expected by beforeUpdate().\r\n const previousProps = this.cloneProps();\r\n untrack(() => {\r\n this.render(true, previousProps, undefined, false);\r\n });\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Synchronizes props from attributes.\r\n * @internal\r\n */\r\n private syncProps(): void {\r\n const props = definition.props ?? {};\r\n for (const [key, config] of Object.entries(props) as [string, PropDefinition][]) {\r\n const attrValue = this.getAttribute(key);\r\n let value: unknown;\r\n\r\n if (attrValue == null) {\r\n if (config.required && config.default === undefined) {\r\n // Mark as missing instead of throwing - validate during connectedCallback\r\n this.missingRequiredProps.add(key);\r\n value = undefined;\r\n } else {\r\n value = config.default ?? undefined;\r\n }\r\n } else {\r\n // Attribute is present, remove from missing set if it was there\r\n if (this.missingRequiredProps.has(key)) {\r\n this.missingRequiredProps.delete(key);\r\n }\r\n value = coercePropValue(attrValue, config);\r\n }\r\n\r\n if (config.validator && value !== undefined) {\r\n const isValid = config.validator(value);\r\n if (!isValid) {\r\n throw new Error(\r\n `bQuery component: validation failed for prop \"${key}\" with value ${JSON.stringify(value)}`\r\n );\r\n }\r\n }\r\n\r\n (this.props as Record<string, unknown>)[key] = value;\r\n }\r\n }\r\n\r\n /**\r\n * Creates a shallow snapshot of the current props for lifecycle diffing.\r\n * A shallow copy is sufficient because component props are re-derived from\r\n * reflected attributes on each update, so nested object mutation is not\r\n * tracked as part of this lifecycle diff.\r\n * @internal\r\n */\r\n private cloneProps(): TProps {\r\n return { ...(this.props as Record<string, unknown>) } as TProps;\r\n }\r\n\r\n /**\r\n * Renders the component to its shadow root.\r\n * @internal\r\n */\r\n private render(): void;\r\n private render(triggerUpdated: true, oldProps: TProps, change?: AttributeChange): void;\r\n private render(\r\n triggerUpdated: true,\r\n oldProps: TProps,\r\n change: AttributeChange | undefined,\r\n runBeforeUpdate: boolean\r\n ): void;\r\n private render(\r\n triggerUpdated = false,\r\n oldProps?: TProps,\r\n change?: AttributeChange,\r\n runBeforeUpdate = true\r\n ): void {\r\n try {\r\n if (triggerUpdated && runBeforeUpdate && definition.beforeUpdate) {\r\n if (!oldProps) {\r\n throw new Error('bQuery component: previous props are required for update renders');\r\n }\r\n const shouldUpdate = definition.beforeUpdate.call(this, this.props, oldProps);\r\n if (shouldUpdate === false) return;\r\n }\r\n\r\n const emit = (event: string, detail?: unknown): void => {\r\n this.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, composed: true }));\r\n };\r\n\r\n if (!this.shadowRoot) return;\r\n\r\n const markup = definition.render({\r\n props: this.props,\r\n state: this.state,\r\n signals: (definition.signals ?? {}) as TSignals,\r\n emit,\r\n });\r\n\r\n // Component render output is authored by the component definition itself,\r\n // so we can explicitly preserve shadow-DOM-specific markup such as <slot>,\r\n // the stylistic `part` attribute, and standard form/input attributes without\r\n // relaxing the global DOM sanitization rules.\r\n const sanitizedMarkup = sanitizeHtml(markup, {\r\n allowTags: componentAllowedTags,\r\n allowAttributes: componentAllowedAttributes,\r\n });\r\n let existingStyleElement: HTMLStyleElement | null = null;\r\n if (definition.styles) {\r\n existingStyleElement = this.shadowRoot.querySelector<HTMLStyleElement>(\r\n 'style[data-bquery-component-style]'\r\n );\r\n }\r\n\r\n this.shadowRoot.innerHTML = sanitizedMarkup;\r\n\r\n if (definition.styles) {\r\n const styleElement = existingStyleElement ?? document.createElement('style');\r\n if (!existingStyleElement) {\r\n styleElement.setAttribute('data-bquery-component-style', '');\r\n }\r\n styleElement.textContent = definition.styles;\r\n this.shadowRoot.prepend(styleElement);\r\n }\r\n\r\n if (triggerUpdated) {\r\n definition.updated?.call(this, change);\r\n }\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n }\r\n\r\n return BQueryComponent as ComponentClass<TState>;\r\n};\r\n\r\n/**\r\n * Creates a custom element class for a component definition.\r\n *\r\n * This is useful when you want to extend or register the class manually\r\n * (e.g. with different tag names in tests or custom registries).\r\n *\r\n * @template TProps - Type of the component's props\r\n * @template TState - Type of the component's internal state. When provided,\r\n * `definition.state` is required, `render({ state })` is strongly typed, and\r\n * returned instances expose typed `getState()` / `setState()` helpers.\r\n * @param tagName - The custom element tag name (used for diagnostics)\r\n * @param definition - The component configuration\r\n */\r\nexport function defineComponent<\r\n TProps extends Record<string, unknown>,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, undefined, TSignals>\r\n): ComponentClass<undefined>;\r\nexport function defineComponent<\r\n TProps extends Record<string, unknown>,\r\n TState extends Record<string, unknown>,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, TState, TSignals>\r\n): ComponentClass<TState>;\r\nexport function defineComponent<\r\n TProps extends Record<string, unknown>,\r\n TState extends Record<string, unknown> | undefined = undefined,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, TState, TSignals>\r\n): ComponentClass<TState> {\r\n return createComponentClass(tagName, definition);\r\n}\r\n\r\n/**\r\n * Defines and registers a custom Web Component.\r\n *\r\n * This function creates a new custom element with the given tag name\r\n * and configuration. The component uses Shadow DOM for encapsulation\r\n * and automatically re-renders when observed attributes change.\r\n *\r\n * @template TProps - Type of the component's props\r\n * @template TState - Type of the component's internal state. When provided,\r\n * `definition.state` is required and lifecycle hooks receive typed state\r\n * helpers via `this.getState()` / `this.setState()`.\r\n * @param tagName - The custom element tag name (must contain a hyphen)\r\n * @param definition - The component configuration\r\n *\r\n * @example\r\n * ```ts\r\n * component<{ start: number }, { count: number }>('counter-button', {\r\n * props: {\r\n * start: { type: Number, default: 0 },\r\n * },\r\n * state: { count: 0 },\r\n * styles: `\r\n * button { padding: 0.5rem 1rem; }\r\n * `,\r\n * connected() {\r\n * // Use event delegation on shadow root so handler survives re-renders\r\n * const handleClick = (event: Event) => {\r\n * const target = event.target as HTMLElement | null;\r\n * if (target?.matches('button')) {\r\n * this.setState('count', this.getState('count') + 1);\r\n * }\r\n * };\r\n * this.shadowRoot?.addEventListener('click', handleClick);\r\n * // Store handler for cleanup\r\n * (this as any)._handleClick = handleClick;\r\n * },\r\n * disconnected() {\r\n * // Clean up event listener to prevent memory leaks\r\n * const handleClick = (this as any)._handleClick;\r\n * if (handleClick) {\r\n * this.shadowRoot?.removeEventListener('click', handleClick);\r\n * }\r\n * },\r\n * render({ props, state }) {\r\n * return html`\r\n * <button>\r\n * Count: ${state.count}\r\n * </button>\r\n * `;\r\n * },\r\n * });\r\n * ```\r\n */\r\nexport function component<\r\n TProps extends Record<string, unknown>,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, undefined, TSignals>\r\n): void;\r\nexport function component<\r\n TProps extends Record<string, unknown>,\r\n TState extends Record<string, unknown>,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, TState, TSignals>\r\n): void;\r\nexport function component<\r\n TProps extends Record<string, unknown>,\r\n TState extends Record<string, unknown> | undefined = undefined,\r\n TSignals extends ComponentSignals = Record<string, never>,\r\n>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps, TState, TSignals>\r\n): void {\r\n const elementClass = createComponentClass(tagName, definition);\r\n\r\n if (!customElements.get(tagName)) {\r\n customElements.define(tagName, elementClass);\r\n }\r\n}\r\n","import {\r\n isTrustedHtml,\r\n type SanitizedHtml,\r\n toSanitizedHtml,\r\n unwrapTrustedHtml,\r\n} from '../security/trusted-html';\r\nconst BOOLEAN_ATTRIBUTE_MARKER: unique symbol = Symbol('bquery.booleanAttribute');\r\nconst BOOLEAN_ATTRIBUTE_NAME = /^[^\\0-\\x20\"'/>=]+$/;\r\n\r\n/**\r\n * Public shape of a boolean HTML attribute created by {@link bool}.\r\n *\r\n * This type is returned from {@link bool} and can be interpolated into\r\n * {@link html} / {@link safeHtml} templates to conditionally include or omit\r\n * an attribute by name. The internal marker property used for runtime checks\r\n * remains private and is not part of the public API.\r\n *\r\n * @example\r\n * ```ts\r\n * const disabled = bool('disabled', isDisabled);\r\n * const button = html`<button ${disabled}>Click</button>`;\r\n * ```\r\n */\r\nexport interface BooleanAttribute {\r\n readonly enabled: boolean;\r\n readonly name: string;\r\n}\r\n\r\ninterface BooleanAttributeValue extends BooleanAttribute {\r\n readonly [BOOLEAN_ATTRIBUTE_MARKER]: true;\r\n}\r\n\r\nconst isBooleanAttributeValue = (value: unknown): value is BooleanAttributeValue => {\r\n if (typeof value !== 'object' || value === null) {\r\n return false;\r\n }\r\n\r\n const candidate = value as Partial<BooleanAttributeValue>;\r\n return (\r\n candidate[BOOLEAN_ATTRIBUTE_MARKER] === true &&\r\n typeof candidate.enabled === 'boolean' &&\r\n typeof candidate.name === 'string'\r\n );\r\n};\r\n\r\nconst stringifyTemplateValue = (value: unknown): string => {\r\n if (isBooleanAttributeValue(value)) {\r\n return value.enabled ? value.name : '';\r\n }\r\n\r\n return String(value ?? '');\r\n};\r\n\r\nconst escapeMap: Record<string, string> = {\r\n '&': '&amp;',\r\n '<': '&lt;',\r\n '>': '&gt;',\r\n '\"': '&quot;',\r\n \"'\": '&#x27;',\r\n '`': '&#x60;',\r\n};\r\n\r\nconst escapeTemplateValue = (value: unknown): string => {\r\n if (isBooleanAttributeValue(value)) {\r\n return value.enabled ? value.name : '';\r\n }\r\n\r\n return stringifyTemplateValue(value).replace(/[&<>\"'`]/g, (char) => escapeMap[char]);\r\n};\r\n\r\n/**\r\n * Creates a boolean-attribute marker for the {@link html} and {@link safeHtml} template tags.\r\n *\r\n * When the condition is truthy, the attribute name is rendered without a value.\r\n * When the condition is falsy, an empty string is rendered and any surrounding\r\n * template-literal whitespace is preserved.\r\n *\r\n * @param name - HTML attribute name to emit\r\n * @param enabled - Whether the boolean attribute should be present\r\n * @returns Internal marker consumed by template tags\r\n *\r\n * @example\r\n * ```ts\r\n * html`<button ${bool('disabled', isDisabled)}>Save</button>`;\r\n * // Result when isDisabled = true: '<button disabled>Save</button>'\r\n * ```\r\n */\r\nexport const bool = (name: string, enabled: unknown): BooleanAttribute => {\r\n if (!BOOLEAN_ATTRIBUTE_NAME.test(name)) {\r\n throw new TypeError(`Invalid boolean attribute name: ${name}`);\r\n }\r\n\r\n const attribute: BooleanAttributeValue = {\r\n [BOOLEAN_ATTRIBUTE_MARKER]: true,\r\n enabled: Boolean(enabled),\r\n name,\r\n };\r\n\r\n return Object.freeze(attribute);\r\n};\r\n\r\n/**\r\n * Tagged template literal for creating HTML strings.\r\n *\r\n * This function handles interpolation of values into HTML templates,\r\n * converting null/undefined to empty strings.\r\n *\r\n * @param strings - Template literal string parts\r\n * @param values - Interpolated values\r\n * @returns Combined HTML string\r\n *\r\n * @example\r\n * ```ts\r\n * const name = 'World';\r\n * const greeting = html`<h1>Hello, ${name}!</h1>`;\r\n * // Result: '<h1>Hello, World!</h1>'\r\n * ```\r\n */\r\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): string => {\r\n return strings.reduce((acc, part, index) => `${acc}${part}${stringifyTemplateValue(values[index])}`, '');\r\n};\r\n\r\n/**\r\n * Escapes HTML entities in interpolated values for XSS prevention.\r\n * Use this when you need to safely embed user content in templates.\r\n *\r\n * @param strings - Template literal string parts\r\n * @param values - Interpolated values to escape\r\n * @returns Branded escaped HTML string safe for bQuery template composition\r\n *\r\n * @example\r\n * ```ts\r\n * const userInput = '<script>alert(\"xss\")</script>';\r\n * const safe = safeHtml`<div>${userInput}</div>`;\r\n * // Result: '<div>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</div>'\r\n * ```\r\n */\r\nexport const safeHtml = (\r\n strings: TemplateStringsArray,\r\n ...values: unknown[]\r\n): SanitizedHtml => {\r\n const escape = (value: unknown): string => {\r\n if (isTrustedHtml(value)) return unwrapTrustedHtml(value);\r\n return escapeTemplateValue(value);\r\n };\r\n\r\n return toSanitizedHtml(\r\n strings.reduce(\r\n (acc, part, index) => `${acc}${part}${index < values.length ? escape(values[index]) : ''}`,\r\n ''\r\n )\r\n );\r\n};\r\n","/**\r\n * Default component library based on native Web Components.\r\n *\r\n * @module bquery/component\r\n */\r\n\r\nimport { getBqueryConfig } from '../platform/config';\r\nimport { escapeHtml } from '../security';\r\nimport { component } from './component';\r\nimport { html } from './html';\r\n\r\n/** Options for registering the default component library. */\r\nexport interface DefaultComponentLibraryOptions {\r\n /** Prefix used for all registered component tags. Defaults to `bq`. */\r\n prefix?: string;\r\n}\r\n\r\n/** Tag names returned by registerDefaultComponents(). */\r\nexport interface RegisteredDefaultComponents {\r\n /** Button component tag name. */\r\n button: string;\r\n /** Card component tag name. */\r\n card: string;\r\n /** Input component tag name. */\r\n input: string;\r\n /** Textarea component tag name. */\r\n textarea: string;\r\n /** Checkbox component tag name. */\r\n checkbox: string;\r\n}\r\n\r\nconst baseStyles = `\r\n :host {\r\n color: inherit;\r\n font: inherit;\r\n }\r\n`;\r\n\r\nconst controlStyles = `\r\n ${baseStyles}\r\n .field {\r\n display: inline-flex;\r\n flex-direction: column;\r\n gap: 0.375rem;\r\n width: 100%;\r\n }\r\n .label {\r\n color: #334155;\r\n font-size: 0.875rem;\r\n font-weight: 600;\r\n }\r\n .control {\r\n border: 1px solid #cbd5e1;\r\n border-radius: 0.75rem;\r\n box-sizing: border-box;\r\n font: inherit;\r\n min-height: 2.75rem;\r\n outline: none;\r\n padding: 0.75rem 0.875rem;\r\n width: 100%;\r\n background: #fff;\r\n color: #0f172a;\r\n transition: border-color 160ms ease, box-shadow 160ms ease;\r\n }\r\n .control:focus {\r\n border-color: #2563eb;\r\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);\r\n }\r\n .control:disabled {\r\n background: #f8fafc;\r\n color: #94a3b8;\r\n cursor: not-allowed;\r\n }\r\n`;\r\n\r\nconst escapeProp = (value: string): string => escapeHtml(value);\r\n\r\nconst handlerStore = new WeakMap<HTMLElement, Record<string, EventListener>>();\r\n\r\nconst readHandler = (element: HTMLElement, key: string): EventListener | undefined => {\r\n return handlerStore.get(element)?.[key];\r\n};\r\n\r\nconst storeHandler = (element: HTMLElement, key: string, value: EventListener): void => {\r\n const handlers = handlerStore.get(element) ?? {};\r\n handlers[key] = value;\r\n handlerStore.set(element, handlers);\r\n};\r\n\r\n/**\r\n * Detect a value-only input update, patch the live control in place, and\r\n * return whether the component can skip a full shadow DOM re-render.\r\n *\r\n * @param element - The host custom element whose shadow DOM is being updated\r\n * @param newProps - The next reflected input props for the pending update\r\n * @param oldProps - The previous reflected input props from the last render\r\n */\r\nconst canSkipInputRender = (\r\n element: HTMLElement,\r\n newProps: {\r\n label: string;\r\n type: string;\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n disabled: boolean;\r\n },\r\n oldProps: {\r\n label: string;\r\n type: string;\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n disabled: boolean;\r\n }\r\n): boolean => {\r\n if (oldProps.label !== newProps.label) return false;\r\n if (oldProps.type !== newProps.type) return false;\r\n if (oldProps.placeholder !== newProps.placeholder) return false;\r\n if (oldProps.name !== newProps.name) return false;\r\n if (oldProps.disabled !== newProps.disabled) return false;\r\n\r\n const control = element.shadowRoot?.querySelector('input.control') as HTMLInputElement | null;\r\n if (!control) return false;\r\n\r\n if (control.value !== newProps.value) {\r\n control.value = newProps.value;\r\n }\r\n\r\n return true;\r\n};\r\n\r\n/**\r\n * Detect a value-only textarea update, patch the live control in place, and\r\n * return whether the component can skip a full shadow DOM re-render.\r\n *\r\n * @param element - The host custom element whose shadow DOM is being updated\r\n * @param newProps - The next reflected textarea props for the pending update\r\n * @param oldProps - The previous reflected textarea props from the last render\r\n */\r\nconst canSkipTextareaRender = (\r\n element: HTMLElement,\r\n newProps: {\r\n label: string;\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n rows: number;\r\n disabled: boolean;\r\n },\r\n oldProps: {\r\n label: string;\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n rows: number;\r\n disabled: boolean;\r\n }\r\n): boolean => {\r\n if (oldProps.label !== newProps.label) return false;\r\n if (oldProps.placeholder !== newProps.placeholder) return false;\r\n if (oldProps.name !== newProps.name) return false;\r\n if (oldProps.rows !== newProps.rows) return false;\r\n if (oldProps.disabled !== newProps.disabled) return false;\r\n\r\n const control = element.shadowRoot?.querySelector(\r\n 'textarea.control'\r\n ) as HTMLTextAreaElement | null;\r\n if (!control) return false;\r\n\r\n if (control.value !== newProps.value) {\r\n control.value = newProps.value;\r\n }\r\n return true;\r\n};\r\n\r\nconst renderTextareaControl = (props: {\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n rows: number;\r\n disabled: boolean;\r\n}): string => {\r\n return [\r\n '<textarea',\r\n ' part=\"control\"',\r\n ' class=\"control\"',\r\n ` placeholder=\"${escapeProp(props.placeholder)}\"`,\r\n ` name=\"${escapeProp(props.name)}\"`,\r\n ` rows=\"${props.rows}\"`,\r\n props.disabled ? ' disabled' : '',\r\n `>${escapeProp(props.value)}</textarea>`,\r\n ].join('');\r\n};\r\n\r\n/**\r\n * Register a default set of foundational UI components.\r\n *\r\n * The library is intentionally small and dependency-free, providing common\r\n * primitives that can be themed via shadow parts and CSS custom properties.\r\n *\r\n * @param options - Optional registration settings such as a custom tag prefix\r\n * @returns The registered tag names for each component\r\n */\r\nexport const registerDefaultComponents = (\r\n options: DefaultComponentLibraryOptions = {}\r\n): RegisteredDefaultComponents => {\r\n const prefix = options.prefix ?? getBqueryConfig().components?.prefix ?? 'bq';\r\n const tags: RegisteredDefaultComponents = {\r\n button: `${prefix}-button`,\r\n card: `${prefix}-card`,\r\n input: `${prefix}-input`,\r\n textarea: `${prefix}-textarea`,\r\n checkbox: `${prefix}-checkbox`,\r\n };\r\n\r\n component<{\r\n label: string;\r\n variant: string;\r\n size: string;\r\n type: string;\r\n disabled: boolean;\r\n }>(tags.button, {\r\n props: {\r\n label: { type: String, default: '' },\r\n variant: { type: String, default: 'primary' },\r\n size: { type: String, default: 'md' },\r\n type: { type: String, default: 'button' },\r\n disabled: { type: Boolean, default: false },\r\n },\r\n styles: `\r\n ${baseStyles}\r\n button {\r\n appearance: none;\r\n border: 0;\r\n border-radius: 999px;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n font: inherit;\r\n font-weight: 600;\r\n gap: 0.5rem;\r\n min-height: 2.5rem;\r\n padding: 0.65rem 1rem;\r\n transition: transform 160ms ease, opacity 160ms ease, background 160ms ease;\r\n background: #2563eb;\r\n color: #fff;\r\n }\r\n button[data-variant='secondary'] {\r\n background: #e2e8f0;\r\n color: #0f172a;\r\n }\r\n button[data-size='sm'] {\r\n min-height: 2.125rem;\r\n padding: 0.5rem 0.875rem;\r\n }\r\n button[data-size='lg'] {\r\n min-height: 3rem;\r\n padding: 0.875rem 1.25rem;\r\n }\r\n button:hover:not(:disabled) {\r\n transform: translateY(-1px);\r\n }\r\n button:disabled {\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n }\r\n `,\r\n render: ({ props }) => html`\r\n <button\r\n part=\"button\"\r\n type=\"${escapeProp(props.type)}\"\r\n data-variant=\"${escapeProp(props.variant)}\"\r\n data-size=\"${escapeProp(props.size)}\"\r\n ${props.disabled ? 'disabled' : ''}\r\n >\r\n <slot>${escapeProp(props.label)}</slot>\r\n </button>\r\n `,\r\n });\r\n\r\n component<{ title: string; footer: string; elevated: boolean }>(tags.card, {\r\n props: {\r\n title: { type: String, default: '' },\r\n footer: { type: String, default: '' },\r\n elevated: { type: Boolean, default: true },\r\n },\r\n styles: `\r\n ${baseStyles}\r\n article {\r\n background: #fff;\r\n border: 1px solid #e2e8f0;\r\n border-radius: 1rem;\r\n box-shadow: 0 10px 25px rgba(15, 23, 42, 0.08);\r\n color: #0f172a;\r\n display: block;\r\n padding: 1rem;\r\n }\r\n article[data-elevated='false'] {\r\n box-shadow: none;\r\n }\r\n header, footer {\r\n color: #475569;\r\n font-size: 0.95rem;\r\n font-weight: 600;\r\n }\r\n header {\r\n margin-bottom: 0.75rem;\r\n }\r\n footer {\r\n margin-top: 0.75rem;\r\n }\r\n `,\r\n render: ({ props }) => html`\r\n <article part=\"card\" data-elevated=\"${String(props.elevated)}\">\r\n ${props.title ? `<header part=\"header\">${escapeProp(props.title)}</header>` : ''}\r\n <section part=\"body\"><slot></slot></section>\r\n ${props.footer ? `<footer part=\"footer\">${escapeProp(props.footer)}</footer>` : ''}\r\n </article>\r\n `,\r\n });\r\n\r\n component<{\r\n label: string;\r\n type: string;\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n disabled: boolean;\r\n }>(tags.input, {\r\n props: {\r\n label: { type: String, default: '' },\r\n type: { type: String, default: 'text' },\r\n value: { type: String, default: '' },\r\n placeholder: { type: String, default: '' },\r\n name: { type: String, default: '' },\r\n disabled: { type: Boolean, default: false },\r\n },\r\n styles: controlStyles,\r\n /**\r\n * Skip the full shadow DOM re-render when only the reflected input value\r\n * changed, because the live control has already been patched in place.\r\n */\r\n beforeUpdate(newProps, oldProps) {\r\n if (canSkipInputRender(this, newProps, oldProps)) {\r\n return false;\r\n }\r\n return true;\r\n },\r\n connected() {\r\n const handleInput = (event: Event) => {\r\n const target = event.target as HTMLInputElement | null;\r\n if (!target?.matches('input')) return;\r\n event.stopPropagation();\r\n this.setAttribute('value', target.value);\r\n this.dispatchEvent(\r\n new CustomEvent('input', {\r\n detail: { value: target.value },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n };\r\n storeHandler(this, '__bqueryInputHandler', handleInput);\r\n this.shadowRoot?.addEventListener('input', handleInput);\r\n },\r\n disconnected() {\r\n const handleInput = readHandler(this, '__bqueryInputHandler');\r\n if (handleInput) {\r\n this.shadowRoot?.removeEventListener('input', handleInput);\r\n }\r\n },\r\n render: ({ props }) => html`\r\n <label part=\"field\" class=\"field\">\r\n ${props.label ? `<span part=\"label\" class=\"label\">${escapeProp(props.label)}</span>` : ''}\r\n <input\r\n part=\"control\"\r\n class=\"control\"\r\n type=\"${escapeProp(props.type)}\"\r\n value=\"${escapeProp(props.value)}\"\r\n placeholder=\"${escapeProp(props.placeholder)}\"\r\n name=\"${escapeProp(props.name)}\"\r\n ${props.disabled ? 'disabled' : ''}\r\n />\r\n </label>\r\n `,\r\n });\r\n\r\n component<{\r\n label: string;\r\n value: string;\r\n placeholder: string;\r\n name: string;\r\n rows: number;\r\n disabled: boolean;\r\n }>(tags.textarea, {\r\n props: {\r\n label: { type: String, default: '' },\r\n value: { type: String, default: '' },\r\n placeholder: { type: String, default: '' },\r\n name: { type: String, default: '' },\r\n rows: { type: Number, default: 4 },\r\n disabled: { type: Boolean, default: false },\r\n },\r\n styles: `${controlStyles}\r\n textarea.control {\r\n min-height: 6rem;\r\n resize: vertical;\r\n }\r\n `,\r\n /**\r\n * Skip the full shadow DOM re-render when only the reflected textarea value\r\n * changed, because the live control has already been patched in place.\r\n */\r\n beforeUpdate(newProps, oldProps) {\r\n if (canSkipTextareaRender(this, newProps, oldProps)) {\r\n return false;\r\n }\r\n return true;\r\n },\r\n connected() {\r\n const handleInput = (event: Event) => {\r\n const target = event.target as HTMLTextAreaElement | null;\r\n if (!target?.matches('textarea')) return;\r\n event.stopPropagation();\r\n this.setAttribute('value', target.value);\r\n this.dispatchEvent(\r\n new CustomEvent('input', {\r\n detail: { value: target.value },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n };\r\n storeHandler(this, '__bqueryTextareaHandler', handleInput);\r\n this.shadowRoot?.addEventListener('input', handleInput);\r\n },\r\n disconnected() {\r\n const handleInput = readHandler(this, '__bqueryTextareaHandler');\r\n if (handleInput) {\r\n this.shadowRoot?.removeEventListener('input', handleInput);\r\n }\r\n },\r\n render: ({ props }) => html`\r\n <label part=\"field\" class=\"field\">\r\n ${props.label ? `<span part=\"label\" class=\"label\">${escapeProp(props.label)}</span>` : ''}\r\n ${renderTextareaControl(props)}\r\n </label>\r\n `,\r\n });\r\n\r\n component<{ label: string; checked: boolean; disabled: boolean }>(tags.checkbox, {\r\n props: {\r\n label: { type: String, default: '' },\r\n checked: { type: Boolean, default: false },\r\n disabled: { type: Boolean, default: false },\r\n },\r\n styles: `\r\n ${baseStyles}\r\n label {\r\n align-items: center;\r\n color: #0f172a;\r\n cursor: pointer;\r\n display: inline-flex;\r\n gap: 0.625rem;\r\n }\r\n input {\r\n accent-color: #2563eb;\r\n block-size: 1rem;\r\n inline-size: 1rem;\r\n }\r\n input:disabled {\r\n cursor: not-allowed;\r\n }\r\n `,\r\n connected() {\r\n const handleChange = (event: Event) => {\r\n const target = event.target as HTMLInputElement | null;\r\n if (!target?.matches('input[type=\"checkbox\"]')) return;\r\n event.stopPropagation();\r\n if (target.checked) {\r\n this.setAttribute('checked', 'true');\r\n } else {\r\n this.removeAttribute('checked');\r\n }\r\n this.dispatchEvent(\r\n new CustomEvent('change', {\r\n detail: { checked: target.checked },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n };\r\n storeHandler(this, '__bqueryCheckboxHandler', handleChange);\r\n this.shadowRoot?.addEventListener('change', handleChange);\r\n },\r\n disconnected() {\r\n const handleChange = readHandler(this, '__bqueryCheckboxHandler');\r\n if (handleChange) {\r\n this.shadowRoot?.removeEventListener('change', handleChange);\r\n }\r\n },\r\n render: ({ props }) => html`\r\n <label part=\"label\">\r\n <input\r\n part=\"control\"\r\n type=\"checkbox\"\r\n ${props.checked ? 'checked' : ''}\r\n ${props.disabled ? 'disabled' : ''}\r\n />\r\n <span part=\"text\"><slot>${escapeProp(props.label)}</slot></span>\r\n </label>\r\n `,\r\n });\r\n\r\n return tags;\r\n};\r\n"],"mappings":"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"}
@@ -1,186 +1,9 @@
1
- import { s as h } from "./sanitize-Cxvxa-DX.js";
2
- const p = (e, r) => {
3
- const { type: s } = r;
4
- if (s === String) return e;
5
- if (s === Number)
6
- return Number(e);
7
- if (s === Boolean) {
8
- const c = e.trim().toLowerCase();
9
- return c === "" || c === "true" || c === "1" ? !0 : c === "false" || c === "0" ? !1 : !!e;
10
- }
11
- if (s === Object || s === Array)
12
- try {
13
- return JSON.parse(e);
14
- } catch {
15
- return e;
16
- }
17
- if (typeof s == "function") {
18
- const c = s, t = s;
19
- if (r.construct === !0)
20
- return Reflect.construct(t, [e]);
21
- if (r.construct === !1)
22
- return c(e);
23
- const o = s.prototype !== void 0 && s.prototype !== null, u = (o ? Object.getOwnPropertyNames(s.prototype) : []).length > 1, n = o && s.prototype.constructor !== s, l = /^class\s/.test(Function.prototype.toString.call(s));
24
- if (u || n || l)
25
- try {
26
- return Reflect.construct(t, [e]);
27
- } catch {
28
- return c(e);
29
- }
30
- try {
31
- const a = c(e);
32
- if (a === void 0 && o)
33
- try {
34
- return Reflect.construct(t, [e]);
35
- } catch {
36
- return a;
37
- }
38
- return a;
39
- } catch (a) {
40
- if (a instanceof TypeError && /cannot be invoked without 'new'|is not a function/i.test(a.message))
41
- return Reflect.construct(t, [e]);
42
- throw a;
43
- }
44
- }
45
- return e;
46
- }, d = (e, r) => {
47
- class s extends HTMLElement {
48
- constructor() {
49
- super(), this.state = { ...r.state ?? {} }, this.props = {}, this.missingRequiredProps = /* @__PURE__ */ new Set(), this.hasMounted = !1, this.attachShadow({ mode: "open" }), this.syncProps();
50
- }
51
- /**
52
- * Returns the list of attributes to observe for changes.
53
- */
54
- static get observedAttributes() {
55
- return Object.keys(r.props ?? {});
56
- }
57
- /**
58
- * Called when the element is added to the DOM.
59
- */
60
- connectedCallback() {
61
- try {
62
- if (this.missingRequiredProps.size > 0)
63
- return;
64
- this.mount();
65
- } catch (t) {
66
- this.handleError(t);
67
- }
68
- }
69
- /**
70
- * Performs the initial mount of the component.
71
- * Called when the element is connected and all required props are present.
72
- * @internal
73
- */
74
- mount() {
75
- this.hasMounted || (r.beforeMount?.call(this), r.connected?.call(this), this.render(), this.hasMounted = !0);
76
- }
77
- /**
78
- * Called when the element is removed from the DOM.
79
- */
80
- disconnectedCallback() {
81
- try {
82
- r.disconnected?.call(this);
83
- } catch (t) {
84
- this.handleError(t);
85
- }
86
- }
87
- /**
88
- * Called when an observed attribute changes.
89
- */
90
- attributeChangedCallback(t, o, i) {
91
- try {
92
- this.syncProps(), this.hasMounted ? this.render(!0) : this.isConnected && this.missingRequiredProps.size === 0 && this.mount();
93
- } catch (u) {
94
- this.handleError(u);
95
- }
96
- }
97
- /**
98
- * Handles errors during component lifecycle.
99
- * @internal
100
- */
101
- handleError(t) {
102
- r.onError ? r.onError.call(this, t) : console.error(`bQuery component error in <${e}>:`, t);
103
- }
104
- /**
105
- * Updates a state property and triggers a re-render.
106
- *
107
- * @param key - The state property key
108
- * @param value - The new value
109
- */
110
- setState(t, o) {
111
- this.state[t] = o, this.render(!0);
112
- }
113
- /**
114
- * Gets a state property value.
115
- *
116
- * @param key - The state property key
117
- * @returns The current value
118
- */
119
- getState(t) {
120
- return this.state[t];
121
- }
122
- /**
123
- * Synchronizes props from attributes.
124
- * @internal
125
- */
126
- syncProps() {
127
- const t = r.props ?? {};
128
- for (const [o, i] of Object.entries(t)) {
129
- const u = this.getAttribute(o);
130
- let n;
131
- if (u == null ? i.required && i.default === void 0 ? (this.missingRequiredProps.add(o), n = void 0) : n = i.default ?? void 0 : (this.missingRequiredProps.has(o) && this.missingRequiredProps.delete(o), n = p(u, i)), i.validator && n !== void 0 && !i.validator(n))
132
- throw new Error(
133
- `bQuery component: validation failed for prop "${o}" with value ${JSON.stringify(n)}`
134
- );
135
- this.props[o] = n;
136
- }
137
- }
138
- /**
139
- * Renders the component to its shadow root.
140
- * @internal
141
- */
142
- render(t = !1) {
143
- try {
144
- if (t && r.beforeUpdate && r.beforeUpdate.call(this, this.props) === !1)
145
- return;
146
- const o = (n, l) => {
147
- this.dispatchEvent(new CustomEvent(n, { detail: l, bubbles: !0, composed: !0 }));
148
- };
149
- if (!this.shadowRoot) return;
150
- const i = r.render({
151
- props: this.props,
152
- state: this.state,
153
- emit: o
154
- }), u = h(i);
155
- if (this.shadowRoot.innerHTML = u, r.styles) {
156
- const n = document.createElement("style");
157
- n.textContent = r.styles, this.shadowRoot.prepend(n);
158
- }
159
- t && r.updated?.call(this);
160
- } catch (o) {
161
- this.handleError(o);
162
- }
163
- }
164
- }
165
- return s;
166
- }, b = (e, r) => {
167
- const s = d(e, r);
168
- customElements.get(e) || customElements.define(e, s);
169
- }, E = (e, ...r) => e.reduce((s, c, t) => `${s}${c}${r[t] ?? ""}`, ""), g = (e, ...r) => {
170
- const s = {
171
- "&": "&amp;",
172
- "<": "&lt;",
173
- ">": "&gt;",
174
- '"': "&quot;",
175
- "'": "&#x27;",
176
- "`": "&#x60;"
177
- }, c = (t) => String(t ?? "").replace(/[&<>"'`]/g, (i) => s[i]);
178
- return e.reduce((t, o, i) => `${t}${o}${c(r[i])}`, "");
179
- };
1
+ import { a as e, i as t, n as a, o as s, r as n, t as m } from "./component-BEQgt5hl.js";
180
2
  export {
181
- b as component,
182
- d as defineComponent,
183
- E as html,
184
- g as safeHtml
3
+ a as bool,
4
+ e as component,
5
+ s as defineComponent,
6
+ n as html,
7
+ m as registerDefaultComponents,
8
+ t as safeHtml
185
9
  };
186
- //# sourceMappingURL=component.es.mjs.map
@@ -0,0 +1,40 @@
1
+ import { i as o, r as f } from "./object-qGpWr6-J.js";
2
+ var s = {
3
+ fetch: {
4
+ headers: {},
5
+ parseAs: "json"
6
+ },
7
+ cookies: {
8
+ path: "/",
9
+ sameSite: "Lax",
10
+ secure: !1
11
+ },
12
+ announcer: {
13
+ politeness: "polite",
14
+ atomic: !0,
15
+ delay: 16,
16
+ clearDelay: 1e3
17
+ },
18
+ pageMeta: {},
19
+ transitions: {
20
+ skipOnReducedMotion: !1,
21
+ classes: [],
22
+ types: []
23
+ },
24
+ components: { prefix: "bq" }
25
+ }, r = (e) => {
26
+ if (typeof Headers < "u" && e instanceof Headers) return new Headers(e);
27
+ if (Array.isArray(e)) return e.map((n) => r(n));
28
+ if (f(e)) {
29
+ const n = {};
30
+ for (const [a, i] of Object.entries(e)) n[a] = r(i);
31
+ return n;
32
+ }
33
+ return e;
34
+ }, t = r(s), d = (e) => (t = r(o(s, t, e)), c()), c = () => r(t);
35
+ export {
36
+ c as n,
37
+ d as t
38
+ };
39
+
40
+ //# sourceMappingURL=config-DRmZZno3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-DRmZZno3.js","names":[],"sources":["../src/platform/config.ts"],"sourcesContent":["/**\n * Global bQuery configuration helpers.\n *\n * @module bquery/platform\n */\n\nimport { isPlainObject, merge } from '../core/utils/object';\n\n/** Supported response parsing strategies for fetch composables. */\nexport type BqueryFetchParseAs = 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData' | 'response';\n\n/** Global fetch defaults used by useFetch(). */\nexport interface BqueryFetchConfig {\n /** Optional base URL prepended to relative request URLs. */\n baseUrl?: string;\n /** Default request headers. */\n headers?: HeadersInit;\n /** Default response parser. */\n parseAs?: BqueryFetchParseAs;\n}\n\n/** Global cookie defaults used by useCookie(). */\nexport interface BqueryCookieConfig {\n /** Default cookie path. */\n path?: string;\n /** Default SameSite mode. */\n sameSite?: 'Strict' | 'Lax' | 'None';\n /** Whether cookies should be marked secure by default. */\n secure?: boolean;\n}\n\n/** Global announcer defaults used by useAnnouncer(). */\nexport interface BqueryAnnouncerConfig {\n /** Default politeness level. */\n politeness?: 'polite' | 'assertive';\n /** Whether announcements should be treated atomically. */\n atomic?: boolean;\n /** Delay before writing the message into the live region. */\n delay?: number;\n /** Delay after which the live region is cleared automatically. */\n clearDelay?: number;\n}\n\n/** Global page meta defaults used by definePageMeta(). */\nexport interface BqueryPageMetaConfig {\n /** Optional title template function. */\n titleTemplate?: (title: string) => string;\n}\n\n/** Global motion defaults used by transition(). */\nexport interface BqueryTransitionConfig {\n /** Skip transitions when reduced motion is preferred. */\n skipOnReducedMotion?: boolean;\n /** Classes applied to the root element during transitions. */\n classes?: string[];\n /** Transition type identifiers added when supported by the browser. */\n types?: string[];\n}\n\n/** Global default component library configuration. */\nexport interface BqueryComponentLibraryConfig {\n /** Prefix used by registerDefaultComponents(). */\n prefix?: string;\n}\n\n/** Complete global bQuery configuration object. */\nexport interface BqueryConfig {\n /** Fetch composable defaults. */\n fetch?: BqueryFetchConfig;\n /** Cookie composable defaults. */\n cookies?: BqueryCookieConfig;\n /** Announcer composable defaults. */\n announcer?: BqueryAnnouncerConfig;\n /** Page metadata defaults. */\n pageMeta?: BqueryPageMetaConfig;\n /** View transition defaults. */\n transitions?: BqueryTransitionConfig;\n /** Default component library options. */\n components?: BqueryComponentLibraryConfig;\n}\n\nconst defaultConfig: BqueryConfig = {\n fetch: {\n headers: {},\n parseAs: 'json',\n },\n cookies: {\n path: '/',\n sameSite: 'Lax',\n secure: false,\n },\n announcer: {\n politeness: 'polite',\n atomic: true,\n delay: 16,\n clearDelay: 1000,\n },\n pageMeta: {},\n transitions: {\n skipOnReducedMotion: false,\n classes: [],\n types: [],\n },\n components: {\n prefix: 'bq',\n },\n};\n\nconst cloneConfigValue = <T>(value: T): T => {\n if (typeof Headers !== 'undefined' && value instanceof Headers) {\n return new Headers(value) as T;\n }\n\n if (Array.isArray(value)) {\n return value.map((entry) => cloneConfigValue(entry)) as T;\n }\n\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = cloneConfigValue(entry);\n }\n return result as T;\n }\n\n return value;\n};\n\nlet currentConfig: BqueryConfig = cloneConfigValue(defaultConfig);\n\n/**\n * Define or extend the global bQuery configuration.\n *\n * @param config - Partial configuration values to merge into the current config\n * @returns The resolved configuration after merging\n *\n * @example\n * ```ts\n * defineBqueryConfig({\n * fetch: { baseUrl: 'https://api.example.com' },\n * components: { prefix: 'ui' },\n * });\n * ```\n */\nexport const defineBqueryConfig = (config: BqueryConfig): BqueryConfig => {\n currentConfig = cloneConfigValue(\n merge(\n defaultConfig as Record<string, unknown>,\n currentConfig as Record<string, unknown>,\n config as Record<string, unknown>\n ) as BqueryConfig\n );\n return getBqueryConfig();\n};\n\n/**\n * Get the currently resolved bQuery configuration.\n *\n * @returns A cloned snapshot of the active configuration\n */\nexport const getBqueryConfig = (): BqueryConfig => {\n return cloneConfigValue(currentConfig);\n};\n"],"mappings":";AAiFA,IAAM,IAA8B;AAAA,EAClC,OAAO;AAAA,IACL,SAAS,CAAA;AAAA,IACT,SAAS;AAAA;EAEX,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA;EAEV,WAAW;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA;EAEd,UAAU,CAAA;AAAA,EACV,aAAa;AAAA,IACX,qBAAqB;AAAA,IACrB,SAAS,CAAA;AAAA,IACT,OAAO,CAAA;AAAA;EAET,YAAY,EACV,QAAQ,KAAA;GAIN,IAAA,CAAuB,MAAgB;AAC3C,MAAI,OAAO,UAAY,OAAe,aAAiB,QACrD,QAAO,IAAI,QAAQ,CAAA;AAGrB,MAAI,MAAM,QAAQ,CAAA,EAChB,QAAO,EAAM,IAAA,CAAK,MAAU,EAAiB,CAAA,CAAM;AAGrD,MAAI,EAAc,CAAA,GAAQ;AACxB,UAAM,IAAkC,CAAA;AACxC,eAAW,CAAC,GAAK,CAAA,KAAU,OAAO,QAAQ,CAAA,EACxC,CAAA,EAAO,CAAA,IAAO,EAAiB,CAAA;AAEjC,WAAO;AAAA;AAGT,SAAO;GAGL,IAA8B,EAAiB,CAAA,GAgBtC,IAAA,CAAsB,OACjC,IAAgB,EACd,EACE,GACA,GACA,CAAA,CACD,GAEI,EAAA,IAQI,IAAA,MACJ,EAAiB,CAAA"}
@@ -0,0 +1,35 @@
1
+ import { a as t, c as i, o as u, s as a } from "./effect-AFRW_Plg.js";
2
+ var c = class {
3
+ constructor(s) {
4
+ this._value = s, this.subscribers = /* @__PURE__ */ new Set();
5
+ }
6
+ get value() {
7
+ const s = t();
8
+ return s && (this.subscribers.add(s), u(s, this)), this._value;
9
+ }
10
+ set value(s) {
11
+ if (Object.is(this._value, s)) return;
12
+ this._value = s;
13
+ const e = Array.from(this.subscribers);
14
+ for (const r of e) i(r);
15
+ }
16
+ peek() {
17
+ return this._value;
18
+ }
19
+ update(s) {
20
+ this.value = s(this._value);
21
+ }
22
+ dispose() {
23
+ for (const s of this.subscribers) a(s, this);
24
+ this.subscribers.clear();
25
+ }
26
+ unsubscribe(s) {
27
+ this.subscribers.delete(s);
28
+ }
29
+ }, n = (s) => new c(s);
30
+ export {
31
+ n,
32
+ c as t
33
+ };
34
+
35
+ //# sourceMappingURL=core-BGQJVw0-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-BGQJVw0-.js","names":[],"sources":["../src/reactive/core.ts"],"sourcesContent":["/**\n * Core reactive signals.\n */\n\nimport {\n getCurrentObserver,\n registerDependency,\n removeDependency,\n scheduleObserver,\n type ReactiveSource,\n} from './internals';\n\n/**\n * A reactive value container that notifies subscribers on change.\n *\n * Signals are the foundational primitive of the reactive system.\n * Reading a signal's value inside an effect or computed automatically\n * establishes a reactive dependency.\n *\n * @template T - The type of the stored value\n */\nexport class Signal<T> implements ReactiveSource {\n private subscribers = new Set<() => void>();\n\n /**\n * Creates a new signal with an initial value.\n * @param _value - The initial value\n */\n constructor(private _value: T) {}\n\n /**\n * Gets the current value and tracks the read if inside an observer.\n * During untrack calls, getCurrentObserver returns undefined, preventing dependency tracking.\n */\n get value(): T {\n const current = getCurrentObserver();\n if (current) {\n this.subscribers.add(current);\n registerDependency(current, this);\n }\n return this._value;\n }\n\n /**\n * Sets a new value and notifies all subscribers if the value changed.\n * Uses Object.is for equality comparison.\n */\n set value(next: T) {\n if (Object.is(this._value, next)) return;\n this._value = next;\n // Create snapshot to avoid issues with subscribers modifying the set during iteration\n const subscribersSnapshot = Array.from(this.subscribers);\n for (const subscriber of subscribersSnapshot) {\n scheduleObserver(subscriber);\n }\n }\n\n /**\n * Reads the current value without tracking.\n * Useful when you need the value but don't want to create a dependency.\n *\n * @returns The current value\n */\n peek(): T {\n return this._value;\n }\n\n /**\n * Updates the value using a function.\n * Useful for updates based on the current value.\n *\n * @param updater - Function that receives current value and returns new value\n */\n update(updater: (current: T) => T): void {\n this.value = updater(this._value);\n }\n\n /**\n * Removes all subscribers from this signal.\n * Use this when a signal is no longer needed to prevent memory leaks.\n *\n * @example\n * ```ts\n * const count = signal(0);\n * effect(() => console.log(count.value));\n * count.dispose(); // All subscribers removed\n * ```\n */\n dispose(): void {\n // Remove this signal from each subscriber's dependency set\n // so the observer no longer holds a strong reference to it\n for (const subscriber of this.subscribers) {\n removeDependency(subscriber, this);\n }\n this.subscribers.clear();\n }\n\n /**\n * Removes an observer from this signal's subscriber set.\n * @internal\n */\n unsubscribe(observer: () => void): void {\n this.subscribers.delete(observer);\n }\n}\n\n/**\n * Creates a new reactive signal.\n *\n * @template T - The type of the signal value\n * @param value - The initial value\n * @returns A new Signal instance\n */\nexport const signal = <T>(value: T): Signal<T> => new Signal(value);\n"],"mappings":";AAqBA,IAAa,IAAb,MAAiD;AAAA,EAO/C,YAAY,GAAmB;AAAX,SAAA,SAAA,sBANE,oBAAI,IAAA;AAAA;EAY1B,IAAI,QAAW;AACb,UAAM,IAAU,EAAA;AAChB,WAAI,MACF,KAAK,YAAY,IAAI,CAAA,GACrB,EAAmB,GAAS,IAAA,IAEvB,KAAK;AAAA;EAOd,IAAI,MAAM,GAAS;AACjB,QAAI,OAAO,GAAG,KAAK,QAAQ,CAAA,EAAO;AAClC,SAAK,SAAS;AAEd,UAAM,IAAsB,MAAM,KAAK,KAAK,WAAA;AAC5C,eAAW,KAAc,EACvB,CAAA,EAAiB,CAAA;AAAA;EAUrB,OAAU;AACR,WAAO,KAAK;AAAA;EASd,OAAO,GAAkC;AACvC,SAAK,QAAQ,EAAQ,KAAK,MAAA;AAAA;EAc5B,UAAgB;AAGd,eAAW,KAAc,KAAK,YAC5B,CAAA,EAAiB,GAAY,IAAA;AAE/B,SAAK,YAAY,MAAA;AAAA;EAOnB,YAAY,GAA4B;AACtC,SAAK,YAAY,OAAO,CAAA;AAAA;GAWf,IAAA,CAAa,MAAwB,IAAI,EAAO,CAAA"}