@fictjs/runtime 0.0.7 → 0.0.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fictjs/runtime",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Fict reactive runtime",
5
5
  "publishConfig": {
6
6
  "access": "public",
package/src/binding.ts CHANGED
@@ -38,6 +38,7 @@ import {
38
38
  } from './lifecycle'
39
39
  import { toNodeArray, removeNodes, insertNodesBefore } from './node-ops'
40
40
  import { computed, createSignal, untrack, type Signal } from './signal'
41
+ import { createVersionedSignalAccessor } from './list-helpers'
41
42
  import type { Cleanup, FictNode } from './types'
42
43
 
43
44
  // ============================================================================
@@ -66,10 +67,8 @@ interface ManagedBlock<T = unknown> {
66
67
  root: RootContext
67
68
  value: Signal<T>
68
69
  index: Signal<number>
69
- version: Signal<number>
70
70
  start: Comment
71
71
  end: Comment
72
- valueProxy: T
73
72
  renderCurrent: () => FictNode
74
73
  }
75
74
 
@@ -165,7 +164,7 @@ export function unwrapPrimitive<T>(value: T): T {
165
164
  return value
166
165
  }
167
166
 
168
- function createValueProxy<T>(read: () => T): T {
167
+ function _createValueProxy<T>(read: () => T): T {
169
168
  const getPrimitivePrototype = (value: unknown): Record<PropertyKey, unknown> | undefined => {
170
169
  switch (typeof value) {
171
170
  case 'string':
@@ -339,7 +338,7 @@ function formatTextValue(value: unknown): string {
339
338
  // ============================================================================
340
339
 
341
340
  /** Attribute setter function type */
342
- export type AttributeSetter = (el: HTMLElement, key: string, value: unknown) => void
341
+ export type AttributeSetter = (el: Element, key: string, value: unknown) => void
343
342
 
344
343
  /**
345
344
  * Create a reactive attribute binding on an element.
@@ -354,7 +353,7 @@ export type AttributeSetter = (el: HTMLElement, key: string, value: unknown) =>
354
353
  * ```
355
354
  */
356
355
  export function createAttributeBinding(
357
- el: HTMLElement,
356
+ el: Element,
358
357
  key: string,
359
358
  value: MaybeReactive<unknown>,
360
359
  setter: AttributeSetter,
@@ -373,7 +372,7 @@ export function createAttributeBinding(
373
372
  /**
374
373
  * Bind a reactive value to an element's attribute.
375
374
  */
376
- export function bindAttribute(el: HTMLElement, key: string, getValue: () => unknown): Cleanup {
375
+ export function bindAttribute(el: Element, key: string, getValue: () => unknown): Cleanup {
377
376
  let prevValue: unknown = undefined
378
377
  return createRenderEffect(() => {
379
378
  const value = getValue()
@@ -393,7 +392,7 @@ export function bindAttribute(el: HTMLElement, key: string, getValue: () => unkn
393
392
  /**
394
393
  * Bind a reactive value to an element's property.
395
394
  */
396
- export function bindProperty(el: HTMLElement, key: string, getValue: () => unknown): Cleanup {
395
+ export function bindProperty(el: Element, key: string, getValue: () => unknown): Cleanup {
397
396
  // Keep behavior aligned with the legacy createElement+applyProps path in `dom.ts`,
398
397
  // where certain keys must behave like DOM properties and nullish clears should
399
398
  // reset to sensible defaults (e.g. value -> '', checked -> false).
@@ -430,18 +429,19 @@ export function bindProperty(el: HTMLElement, key: string, getValue: () => unkno
430
429
  * Apply styles to an element, supporting reactive style objects/strings.
431
430
  */
432
431
  export function createStyleBinding(
433
- el: HTMLElement,
432
+ el: Element,
434
433
  value: MaybeReactive<string | Record<string, string | number> | null | undefined>,
435
434
  ): void {
435
+ const target = el as Element & { style: CSSStyleDeclaration }
436
436
  if (isReactive(value)) {
437
437
  let prev: unknown
438
438
  createRenderEffect(() => {
439
439
  const next = (value as () => unknown)()
440
- applyStyle(el, next, prev)
440
+ applyStyle(target, next, prev)
441
441
  prev = next
442
442
  })
443
443
  } else {
444
- applyStyle(el, value, undefined)
444
+ applyStyle(target, value, undefined)
445
445
  }
446
446
  }
447
447
 
@@ -449,13 +449,14 @@ export function createStyleBinding(
449
449
  * Bind a reactive style value to an existing element.
450
450
  */
451
451
  export function bindStyle(
452
- el: HTMLElement,
452
+ el: Element,
453
453
  getValue: () => string | Record<string, string | number> | null | undefined,
454
454
  ): Cleanup {
455
+ const target = el as Element & { style: CSSStyleDeclaration }
455
456
  let prev: unknown
456
457
  return createRenderEffect(() => {
457
458
  const next = getValue()
458
- applyStyle(el, next, prev)
459
+ applyStyle(target, next, prev)
459
460
  prev = next
460
461
  })
461
462
  }
@@ -463,7 +464,11 @@ export function bindStyle(
463
464
  /**
464
465
  * Apply a style value to an element
465
466
  */
466
- function applyStyle(el: HTMLElement, value: unknown, prev: unknown): void {
467
+ function applyStyle(
468
+ el: Element & { style: CSSStyleDeclaration },
469
+ value: unknown,
470
+ prev: unknown,
471
+ ): void {
467
472
  if (typeof value === 'string') {
468
473
  el.style.cssText = value
469
474
  } else if (value && typeof value === 'object') {
@@ -525,7 +530,7 @@ function isUnitlessStyleProperty(prop: string): boolean {
525
530
  * Apply class to an element, supporting reactive class values.
526
531
  */
527
532
  export function createClassBinding(
528
- el: HTMLElement,
533
+ el: Element,
529
534
  value: MaybeReactive<string | Record<string, boolean> | null | undefined>,
530
535
  ): void {
531
536
  if (isReactive(value)) {
@@ -543,7 +548,7 @@ export function createClassBinding(
543
548
  * Bind a reactive class value to an existing element.
544
549
  */
545
550
  export function bindClass(
546
- el: HTMLElement,
551
+ el: Element,
547
552
  getValue: () => string | Record<string, boolean> | null | undefined,
548
553
  ): Cleanup {
549
554
  let prev: Record<string, boolean> = {}
@@ -556,7 +561,7 @@ export function bindClass(
556
561
  /**
557
562
  * Toggle a class key (supports space-separated class names)
558
563
  */
559
- function toggleClassKey(node: HTMLElement, key: string, value: boolean): void {
564
+ function toggleClassKey(node: Element, key: string, value: boolean): void {
560
565
  const classNames = key.trim().split(/\s+/)
561
566
  for (let i = 0, len = classNames.length; i < len; i++) {
562
567
  node.classList.toggle(classNames[i]!, value)
@@ -567,7 +572,7 @@ function toggleClassKey(node: HTMLElement, key: string, value: boolean): void {
567
572
  * Apply a class value to an element using classList.toggle for efficient updates.
568
573
  * Returns the new prev state for tracking.
569
574
  */
570
- function applyClass(el: HTMLElement, value: unknown, prev: unknown): Record<string, boolean> {
575
+ function applyClass(el: Element, value: unknown, prev: unknown): Record<string, boolean> {
571
576
  const prevState = (prev && typeof prev === 'object' ? prev : {}) as Record<string, boolean>
572
577
 
573
578
  // Handle string value - full replacement
@@ -620,7 +625,7 @@ function applyClass(el: HTMLElement, value: unknown, prev: unknown): Record<stri
620
625
  * Exported classList function for direct use (compatible with dom-expressions)
621
626
  */
622
627
  export function classList(
623
- node: HTMLElement,
628
+ node: Element,
624
629
  value: Record<string, boolean> | null | undefined,
625
630
  prev: Record<string, boolean> = {},
626
631
  ): Record<string, boolean> {
@@ -631,19 +636,6 @@ export function classList(
631
636
  // Child/Insert Binding (Dynamic Children)
632
637
  // ============================================================================
633
638
 
634
- /** Managed child node with its dispose function */
635
- interface ManagedBlock<T = unknown> {
636
- nodes: Node[]
637
- root: RootContext
638
- value: Signal<T>
639
- index: Signal<number>
640
- version: Signal<number>
641
- start: Comment
642
- end: Comment
643
- valueProxy: T
644
- renderCurrent: () => FictNode
645
- }
646
-
647
639
  /**
648
640
  * Insert reactive content into a parent element.
649
641
  * This is a simpler API than createChildBinding for basic cases.
@@ -654,11 +646,12 @@ interface ManagedBlock<T = unknown> {
654
646
  * @param createElementFn - Optional function to create DOM elements (when marker is provided)
655
647
  */
656
648
  export function insert(
657
- parent: HTMLElement | DocumentFragment,
649
+ parent: ParentNode & Node,
658
650
  getValue: () => FictNode,
659
651
  markerOrCreateElement?: Node | CreateElementFn,
660
652
  createElementFn?: CreateElementFn,
661
653
  ): Cleanup {
654
+ const hostRoot = getCurrentRoot()
662
655
  let marker: Node
663
656
  let ownsMarker = false
664
657
  let createFn: CreateElementFn | undefined = createElementFn
@@ -736,7 +729,7 @@ export function insert(
736
729
  }
737
730
  clearCurrentNodes()
738
731
 
739
- const root = createRootContext()
732
+ const root = createRootContext(hostRoot)
740
733
  const prev = pushRoot(root)
741
734
  let nodes: Node[] = []
742
735
  try {
@@ -748,7 +741,15 @@ export function insert(
748
741
  if (value.every(v => v instanceof Node)) {
749
742
  newNode = value as Node[]
750
743
  } else {
751
- newNode = createFn ? createFn(value) : document.createTextNode(String(value))
744
+ if (createFn) {
745
+ const mapped: Node[] = []
746
+ for (const item of value) {
747
+ mapped.push(...toNodeArray(createFn(item as any)))
748
+ }
749
+ newNode = mapped
750
+ } else {
751
+ newNode = document.createTextNode(String(value))
752
+ }
752
753
  }
753
754
  } else {
754
755
  newNode = createFn ? createFn(value) : document.createTextNode(String(value))
@@ -794,15 +795,16 @@ export function insert(
794
795
  * ```
795
796
  */
796
797
  export function createChildBinding(
797
- parent: HTMLElement | DocumentFragment,
798
+ parent: ParentNode & Node,
798
799
  getValue: () => FictNode,
799
800
  createElementFn: CreateElementFn,
800
801
  ): BindingHandle {
801
802
  const marker = document.createComment('fict:child')
802
803
  parent.appendChild(marker)
804
+ const hostRoot = getCurrentRoot()
803
805
 
804
806
  const dispose = createRenderEffect(() => {
805
- const root = createRootContext()
807
+ const root = createRootContext(hostRoot)
806
808
  const prev = pushRoot(root)
807
809
  let nodes: Node[] = []
808
810
  let handledError = false
@@ -857,10 +859,10 @@ export function createChildBinding(
857
859
  // Event Delegation System
858
860
  // ============================================================================
859
861
 
860
- // Extend HTMLElement/Document type to support event delegation
862
+ // Extend Element/Document type to support event delegation
861
863
  declare global {
862
- interface HTMLElement {
863
- _$host?: HTMLElement
864
+ interface Element {
865
+ _$host?: Element
864
866
  [key: `$$${string}`]: EventListener | [EventListener, unknown] | undefined
865
867
  [key: `$$${string}Data`]: unknown
866
868
  }
@@ -912,7 +914,7 @@ export function clearDelegatedEvents(doc: Document = window.document): void {
912
914
  * Walks up the DOM tree to find and call handlers stored as $$eventName properties.
913
915
  */
914
916
  function globalEventHandler(e: Event): void {
915
- let node = e.target as HTMLElement | null
917
+ let node = e.target as Element | null
916
918
  const key = `$$${e.type}` as const
917
919
  const dataKey = `${key}Data` as `$$${string}Data`
918
920
  const oriTarget = e.target
@@ -958,7 +960,7 @@ function globalEventHandler(e: Event): void {
958
960
  if (
959
961
  shadowHost &&
960
962
  typeof shadowHost !== 'string' &&
961
- !(shadowHost as HTMLElement)._$host &&
963
+ !(shadowHost as Element)._$host &&
962
964
  node.contains(e.target as Node)
963
965
  ) {
964
966
  retarget(shadowHost as EventTarget)
@@ -971,7 +973,7 @@ function globalEventHandler(e: Event): void {
971
973
  while (handleNode() && node) {
972
974
  node = (node._$host ||
973
975
  node.parentNode ||
974
- (node as unknown as ShadowRoot).host) as HTMLElement | null
976
+ (node as unknown as ShadowRoot).host) as Element | null
975
977
  }
976
978
  }
977
979
 
@@ -988,7 +990,7 @@ function globalEventHandler(e: Event): void {
988
990
  const path = e.composedPath()
989
991
  retarget(path[0] as EventTarget)
990
992
  for (let i = 0; i < path.length - 2; i++) {
991
- node = path[i] as HTMLElement
993
+ node = path[i] as Element
992
994
  if (!handleNode()) break
993
995
  // Handle portal event bubbling
994
996
  if (node._$host) {
@@ -1020,7 +1022,7 @@ function globalEventHandler(e: Event): void {
1020
1022
  * @param delegate - Whether to use delegation (auto-detected based on event name)
1021
1023
  */
1022
1024
  export function addEventListener(
1023
- node: HTMLElement,
1025
+ node: Element,
1024
1026
  name: string,
1025
1027
  handler: EventListener | [EventListener, unknown] | null | undefined,
1026
1028
  delegate?: boolean,
@@ -1066,7 +1068,7 @@ export function addEventListener(
1066
1068
  * ```
1067
1069
  */
1068
1070
  export function bindEvent(
1069
- el: HTMLElement,
1071
+ el: Element,
1070
1072
  eventName: string,
1071
1073
  handler: EventListenerOrEventListenerObject | null | undefined,
1072
1074
  options?: boolean | AddEventListenerOptions,
@@ -1153,7 +1155,7 @@ export function bindEvent(
1153
1155
  * bindRef(el, () => props.ref)
1154
1156
  * ```
1155
1157
  */
1156
- export function bindRef(el: HTMLElement, ref: unknown): Cleanup {
1158
+ export function bindRef(el: Element, ref: unknown): Cleanup {
1157
1159
  if (ref == null) return () => {}
1158
1160
 
1159
1161
  // Handle reactive refs (getters)
@@ -1164,10 +1166,10 @@ export function bindRef(el: HTMLElement, ref: unknown): Cleanup {
1164
1166
 
1165
1167
  if (typeof refValue === 'function') {
1166
1168
  // Callback ref: call with element
1167
- ;(refValue as (el: HTMLElement) => void)(el)
1169
+ ;(refValue as (el: Element) => void)(el)
1168
1170
  } else if (typeof refValue === 'object' && 'current' in refValue) {
1169
1171
  // Ref object: set current property
1170
- ;(refValue as { current: HTMLElement | null }).current = el
1172
+ ;(refValue as { current: Element | null }).current = el
1171
1173
  }
1172
1174
  }
1173
1175
 
@@ -1187,7 +1189,7 @@ export function bindRef(el: HTMLElement, ref: unknown): Cleanup {
1187
1189
  const nullifyCleanup = () => {
1188
1190
  const currentRef = getRef()
1189
1191
  if (currentRef && typeof currentRef === 'object' && 'current' in currentRef) {
1190
- ;(currentRef as { current: HTMLElement | null }).current = null
1192
+ ;(currentRef as { current: Element | null }).current = null
1191
1193
  }
1192
1194
  }
1193
1195
  registerRootCleanup(nullifyCleanup)
@@ -1202,7 +1204,7 @@ export function bindRef(el: HTMLElement, ref: unknown): Cleanup {
1202
1204
  const cleanup = () => {
1203
1205
  const refValue = getRef()
1204
1206
  if (refValue && typeof refValue === 'object' && 'current' in refValue) {
1205
- ;(refValue as { current: HTMLElement | null }).current = null
1207
+ ;(refValue as { current: Element | null }).current = null
1206
1208
  }
1207
1209
  }
1208
1210
  registerRootCleanup(cleanup)
@@ -1231,7 +1233,7 @@ export function bindRef(el: HTMLElement, ref: unknown): Cleanup {
1231
1233
  * ```
1232
1234
  */
1233
1235
  export function spread(
1234
- node: HTMLElement,
1236
+ node: Element,
1235
1237
  props: Record<string, unknown> = {},
1236
1238
  isSVG = false,
1237
1239
  skipChildren = false,
@@ -1248,7 +1250,7 @@ export function spread(
1248
1250
  // Handle ref
1249
1251
  createRenderEffect(() => {
1250
1252
  if (typeof props.ref === 'function') {
1251
- ;(props.ref as (el: HTMLElement) => void)(node)
1253
+ ;(props.ref as (el: Element) => void)(node)
1252
1254
  }
1253
1255
  })
1254
1256
 
@@ -1272,7 +1274,7 @@ export function spread(
1272
1274
  * @param skipRef - Whether to skip ref handling
1273
1275
  */
1274
1276
  export function assign(
1275
- node: HTMLElement,
1277
+ node: Element,
1276
1278
  props: Record<string, unknown>,
1277
1279
  isSVG = false,
1278
1280
  skipChildren = false,
@@ -1307,7 +1309,7 @@ export function assign(
1307
1309
  * Assign a single prop to a node.
1308
1310
  */
1309
1311
  function assignProp(
1310
- node: HTMLElement,
1312
+ node: Element,
1311
1313
  prop: string,
1312
1314
  value: unknown,
1313
1315
  prev: unknown,
@@ -1317,7 +1319,7 @@ function assignProp(
1317
1319
  ): unknown {
1318
1320
  // Style handling
1319
1321
  if (prop === 'style') {
1320
- applyStyle(node, value, prev)
1322
+ applyStyle(node as Element & { style: CSSStyleDeclaration }, value, prev)
1321
1323
  return value
1322
1324
  }
1323
1325
 
@@ -1332,7 +1334,7 @@ function assignProp(
1332
1334
  // Ref handling
1333
1335
  if (prop === 'ref') {
1334
1336
  if (!skipRef && typeof value === 'function') {
1335
- ;(value as (el: HTMLElement) => void)(node)
1337
+ ;(value as (el: Element) => void)(node)
1336
1338
  }
1337
1339
  return value
1338
1340
  }
@@ -1472,6 +1474,7 @@ export function createConditional(
1472
1474
  const endMarker = document.createComment('fict:cond:end')
1473
1475
  const fragment = document.createDocumentFragment()
1474
1476
  fragment.append(startMarker, endMarker)
1477
+ const hostRoot = getCurrentRoot()
1475
1478
 
1476
1479
  let currentNodes: Node[] = []
1477
1480
  let currentRoot: RootContext | null = null
@@ -1513,7 +1516,7 @@ export function createConditional(
1513
1516
  return
1514
1517
  }
1515
1518
 
1516
- const root = createRootContext()
1519
+ const root = createRootContext(hostRoot)
1517
1520
  const prev = pushRoot(root)
1518
1521
  let handledError = false
1519
1522
  try {
@@ -1583,10 +1586,11 @@ export type KeyFn<T> = (item: T, index: number) => string | number
1583
1586
 
1584
1587
  /**
1585
1588
  * Create a reactive list rendering binding with optional keying.
1589
+ * The render callback receives signal accessors for the item and index.
1586
1590
  */
1587
1591
  export function createList<T>(
1588
1592
  items: () => T[],
1589
- renderItem: (item: T, index: number) => FictNode,
1593
+ renderItem: (item: Signal<T>, index: Signal<number>) => FictNode,
1590
1594
  createElementFn: CreateElementFn,
1591
1595
  getKey?: KeyFn<T>,
1592
1596
  ): BindingHandle {
@@ -1594,6 +1598,7 @@ export function createList<T>(
1594
1598
  const endMarker = document.createComment('fict:list:end')
1595
1599
  const fragment = document.createDocumentFragment()
1596
1600
  fragment.append(startMarker, endMarker)
1601
+ const hostRoot = getCurrentRoot()
1597
1602
 
1598
1603
  const nodeMap = new Map<string | number, ManagedBlock<T>>()
1599
1604
  let pendingItems: T[] | null = null
@@ -1621,21 +1626,17 @@ export function createList<T>(
1621
1626
  if (!getKey && previousValue !== item) {
1622
1627
  destroyRoot(existing.root)
1623
1628
  removeBlockNodes(existing)
1624
- block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn)
1629
+ block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn, hostRoot)
1625
1630
  } else {
1626
1631
  const previousIndex = existing.index()
1627
1632
  existing.value(item)
1628
1633
  existing.index(i)
1629
1634
 
1630
- if (previousValue === item) {
1631
- bumpBlockVersion(existing)
1632
- }
1633
-
1634
1635
  const needsRerender = getKey ? true : previousValue !== item || previousIndex !== i
1635
1636
  block = needsRerender ? rerenderBlock(existing, createElementFn) : existing
1636
1637
  }
1637
1638
  } else {
1638
- block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn)
1639
+ block = mountBlock(item, i, renderItem, parent, endMarker, createElementFn, hostRoot)
1639
1640
  }
1640
1641
 
1641
1642
  newNodeMap.set(key, block)
@@ -1699,7 +1700,11 @@ export function createList<T>(
1699
1700
  * createShow(container, () => $visible())
1700
1701
  * ```
1701
1702
  */
1702
- export function createShow(el: HTMLElement, condition: () => boolean, displayValue?: string): void {
1703
+ export function createShow(
1704
+ el: Element & { style: CSSStyleDeclaration },
1705
+ condition: () => boolean,
1706
+ displayValue?: string,
1707
+ ): void {
1703
1708
  const originalDisplay = displayValue ?? el.style.display
1704
1709
  createRenderEffect(() => {
1705
1710
  el.style.display = condition() ? originalDisplay : 'none'
@@ -1723,7 +1728,7 @@ export function createShow(el: HTMLElement, condition: () => boolean, displayVal
1723
1728
  * ```
1724
1729
  */
1725
1730
  export function createPortal(
1726
- container: HTMLElement,
1731
+ container: ParentNode & Node,
1727
1732
  render: () => FictNode,
1728
1733
  createElementFn: CreateElementFn,
1729
1734
  ): BindingHandle {
@@ -1749,7 +1754,7 @@ export function createPortal(
1749
1754
  }
1750
1755
 
1751
1756
  // Create new content
1752
- const root = createRootContext()
1757
+ const root = createRootContext(parentRoot)
1753
1758
  const prev = pushRoot(root)
1754
1759
  let handledError = false
1755
1760
  try {
@@ -1820,22 +1825,18 @@ export function createPortal(
1820
1825
  function mountBlock<T>(
1821
1826
  initialValue: T,
1822
1827
  initialIndex: number,
1823
- renderItem: (item: T, index: number) => FictNode,
1828
+ renderItem: (item: Signal<T>, index: Signal<number>) => FictNode,
1824
1829
  parent: ParentNode & Node,
1825
1830
  anchor: Node,
1826
1831
  createElementFn: CreateElementFn,
1832
+ hostRoot?: RootContext | undefined,
1827
1833
  ): ManagedBlock<T> {
1828
1834
  const start = document.createComment('fict:block:start')
1829
1835
  const end = document.createComment('fict:block:end')
1830
- const valueSig = createSignal<T>(initialValue)
1836
+ const valueSig = createVersionedSignalAccessor<T>(initialValue)
1831
1837
  const indexSig = createSignal<number>(initialIndex)
1832
- const versionSig = createSignal(0)
1833
- const valueProxy = createValueProxy(() => {
1834
- versionSig()
1835
- return valueSig()
1836
- }) as T
1837
- const renderCurrent = () => renderItem(valueProxy, indexSig())
1838
- const root = createRootContext()
1838
+ const renderCurrent = () => renderItem(valueSig, indexSig)
1839
+ const root = createRootContext(hostRoot)
1839
1840
  const prev = pushRoot(root)
1840
1841
  const nodes: Node[] = [start]
1841
1842
  let handledError = false
@@ -1873,10 +1874,8 @@ function mountBlock<T>(
1873
1874
  root,
1874
1875
  value: valueSig,
1875
1876
  index: indexSig,
1876
- version: versionSig,
1877
1877
  start,
1878
1878
  end,
1879
- valueProxy,
1880
1879
  renderCurrent,
1881
1880
  }
1882
1881
  }
@@ -1981,7 +1980,7 @@ function patchElement(el: Element, output: FictNode): boolean {
1981
1980
  if (key === 'class' || key === 'className') {
1982
1981
  el.setAttribute('class', value === false || value === null ? '' : String(value))
1983
1982
  } else if (key === 'style' && typeof value === 'string') {
1984
- ;(el as HTMLElement).style.cssText = value
1983
+ ;(el as Element & { style: CSSStyleDeclaration }).style.cssText = value
1985
1984
  } else if (value === false || value === null || value === undefined) {
1986
1985
  el.removeAttribute(key)
1987
1986
  } else if (value === true) {
@@ -2138,8 +2137,4 @@ function removeBlockNodes<T>(block: ManagedBlock<T>): void {
2138
2137
  }
2139
2138
  }
2140
2139
 
2141
- function bumpBlockVersion<T>(block: ManagedBlock<T>): void {
2142
- block.version(block.version() + 1)
2143
- }
2144
-
2145
2140
  // DOM utility functions are imported from './node-ops' to avoid duplication