kiru 0.46.1 → 0.47.1

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 (105) hide show
  1. package/dist/appContext.d.ts +6 -17
  2. package/dist/appContext.d.ts.map +1 -1
  3. package/dist/appContext.js +39 -95
  4. package/dist/appContext.js.map +1 -1
  5. package/dist/constants.d.ts +3 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +3 -1
  8. package/dist/constants.js.map +1 -1
  9. package/dist/context.d.ts.map +1 -1
  10. package/dist/context.js +0 -2
  11. package/dist/context.js.map +1 -1
  12. package/dist/dom.d.ts.map +1 -1
  13. package/dist/dom.js +12 -14
  14. package/dist/dom.js.map +1 -1
  15. package/dist/element.js +2 -2
  16. package/dist/element.js.map +1 -1
  17. package/dist/hmr.d.ts +3 -3
  18. package/dist/hmr.d.ts.map +1 -1
  19. package/dist/hmr.js +0 -2
  20. package/dist/hmr.js.map +1 -1
  21. package/dist/index.d.ts +1 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1 -21
  24. package/dist/index.js.map +1 -1
  25. package/dist/memo.d.ts.map +1 -1
  26. package/dist/memo.js +1 -3
  27. package/dist/memo.js.map +1 -1
  28. package/dist/portal.d.ts +2 -5
  29. package/dist/portal.d.ts.map +1 -1
  30. package/dist/portal.js +22 -22
  31. package/dist/portal.js.map +1 -1
  32. package/dist/profiling.d.ts +1 -1
  33. package/dist/props.js +1 -1
  34. package/dist/props.js.map +1 -1
  35. package/dist/reconciler.d.ts.map +1 -1
  36. package/dist/reconciler.js +3 -3
  37. package/dist/reconciler.js.map +1 -1
  38. package/dist/renderToString.d.ts +1 -1
  39. package/dist/renderToString.d.ts.map +1 -1
  40. package/dist/renderToString.js +4 -7
  41. package/dist/renderToString.js.map +1 -1
  42. package/dist/scheduler.d.ts +3 -3
  43. package/dist/scheduler.d.ts.map +1 -1
  44. package/dist/scheduler.js +55 -71
  45. package/dist/scheduler.js.map +1 -1
  46. package/dist/signals/base.d.ts +1 -1
  47. package/dist/signals/base.d.ts.map +1 -1
  48. package/dist/signals/base.js +2 -2
  49. package/dist/signals/base.js.map +1 -1
  50. package/dist/signals/computed.d.ts +1 -1
  51. package/dist/signals/computed.d.ts.map +1 -1
  52. package/dist/signals/computed.js +3 -3
  53. package/dist/signals/computed.js.map +1 -1
  54. package/dist/signals/effect.d.ts +1 -1
  55. package/dist/signals/effect.d.ts.map +1 -1
  56. package/dist/signals/effect.js +3 -2
  57. package/dist/signals/effect.js.map +1 -1
  58. package/dist/signals/globals.d.ts +1 -1
  59. package/dist/signals/globals.d.ts.map +1 -1
  60. package/dist/signals/jsx.d.ts +1 -1
  61. package/dist/signals/jsx.d.ts.map +1 -1
  62. package/dist/signals/types.d.ts +1 -1
  63. package/dist/signals/types.d.ts.map +1 -1
  64. package/dist/signals/utils.d.ts +1 -1
  65. package/dist/signals/utils.d.ts.map +1 -1
  66. package/dist/signals/utils.js +1 -1
  67. package/dist/signals/utils.js.map +1 -1
  68. package/dist/ssr/client.d.ts +1 -2
  69. package/dist/ssr/client.d.ts.map +1 -1
  70. package/dist/ssr/client.js +6 -4
  71. package/dist/ssr/client.js.map +1 -1
  72. package/dist/ssr/server.d.ts +1 -1
  73. package/dist/ssr/server.d.ts.map +1 -1
  74. package/dist/ssr/server.js +23 -26
  75. package/dist/ssr/server.js.map +1 -1
  76. package/dist/types.d.ts +0 -1
  77. package/dist/types.d.ts.map +1 -1
  78. package/dist/utils.d.ts.map +1 -1
  79. package/dist/utils.js +4 -2
  80. package/dist/utils.js.map +1 -1
  81. package/package.json +1 -1
  82. package/src/appContext.ts +50 -117
  83. package/src/constants.ts +4 -0
  84. package/src/context.ts +0 -1
  85. package/src/dom.ts +12 -11
  86. package/src/element.ts +2 -2
  87. package/src/hmr.ts +4 -5
  88. package/src/index.ts +1 -41
  89. package/src/memo.ts +1 -3
  90. package/src/portal.ts +22 -26
  91. package/src/props.ts +1 -1
  92. package/src/reconciler.ts +3 -2
  93. package/src/renderToString.ts +4 -10
  94. package/src/scheduler.ts +54 -72
  95. package/src/signals/base.ts +4 -4
  96. package/src/signals/computed.ts +4 -4
  97. package/src/signals/effect.ts +4 -3
  98. package/src/signals/globals.ts +1 -1
  99. package/src/signals/jsx.ts +1 -1
  100. package/src/signals/types.ts +1 -1
  101. package/src/signals/utils.ts +1 -1
  102. package/src/ssr/client.ts +13 -19
  103. package/src/ssr/server.ts +24 -34
  104. package/src/types.ts +0 -1
  105. package/src/utils.ts +3 -1
package/src/appContext.ts CHANGED
@@ -1,140 +1,73 @@
1
+ import { FLAG_STATIC_DOM } from "./constants.js"
1
2
  import { createElement } from "./element.js"
2
3
  import { __DEV__ } from "./env.js"
3
- import { KiruError } from "./error.js"
4
- import { renderMode } from "./globals.js"
5
- import { hydrationStack } from "./hydration.js"
6
- import {
7
- requestDelete,
8
- requestUpdate,
9
- flushSync,
10
- nextIdle,
11
- } from "./scheduler.js"
12
- import { generateRandomID } from "./generateId.js"
4
+ import { requestUpdate, flushSync } from "./scheduler.js"
13
5
 
14
6
  type VNode = Kiru.VNode
15
7
 
16
8
  export interface AppContextOptions {
17
- root?: HTMLElement
18
- /**
19
- * @internal
20
- * Sets the root node type for the app. Used for SSR & rendering without the DOM.
21
- */
22
- rootType?: ({ children }: { children: JSX.Children }) => JSX.Element
23
9
  name?: string
24
10
  }
25
11
 
26
- export interface AppContext<T extends Record<string, unknown> = {}> {
27
- id: string
12
+ export interface AppContext {
13
+ id: number
28
14
  name: string
29
- rootNode?: VNode
30
- root?: HTMLElement
31
- mounted: boolean
32
- mount(): Promise<AppContext<T>>
33
- unmount(): Promise<AppContext<T>>
34
- setProps(fn: (oldProps: T) => T): Promise<AppContext<T>>
15
+ rootNode: VNode
16
+ render(children: JSX.Element): void
17
+ unmount(): void
35
18
  }
36
19
 
37
- export function createAppContext<T extends Record<string, unknown> = {}>(
38
- appFunc: (props: T) => JSX.Element,
39
- appProps = {} as T,
40
- options?: AppContextOptions
41
- ): AppContext<T> {
42
- const id = generateRandomID()
43
- const name = options?.name ?? "App-" + id
44
- let root = options?.root
45
- let mounted = false
46
- let appContext: AppContext<T>
20
+ let appId = 0
47
21
 
48
- const appNode = createElement(appFunc, appProps as T)
49
- appNode.depth = 1
50
- const rootNode = options?.rootType
51
- ? createElement(options.rootType, {}, appNode)
52
- : root
53
- ? createElement(root!.nodeName.toLowerCase(), {}, appNode)
54
- : void 0
55
- if (rootNode) {
56
- rootNode.depth = 0
22
+ export function mount(
23
+ children: JSX.Element,
24
+ container: HTMLElement,
25
+ options?: AppContextOptions
26
+ ): AppContext {
27
+ const rootNode = createElement(container.nodeName.toLowerCase(), {})
28
+ if (__DEV__) {
29
+ if (container.__kiruNode) {
30
+ throw new Error(
31
+ "[kiru]: container in use - call unmount on the previous app first."
32
+ )
33
+ }
34
+ container.__kiruNode = rootNode
57
35
  }
36
+ rootNode.dom = container
37
+ rootNode.flags |= FLAG_STATIC_DOM
58
38
 
59
- function mount(): Promise<AppContext<T>> {
60
- return new Promise<AppContext<T>>((resolve, reject) => {
61
- if (mounted) return resolve(appContext)
62
- if (!rootNode) return reject(new KiruError("Root node not configured"))
63
- root ??= document.body
64
- rootNode.dom = root
65
- rootNode.app = appContext
66
-
67
- if (__DEV__) {
68
- root.__kiruNode = rootNode
69
- }
70
- if (renderMode.current === "hydrate") {
71
- hydrationStack.captureEvents(root!)
72
- }
73
- nextIdle(() => {
74
- if (renderMode.current === "hydrate") {
75
- hydrationStack.releaseEvents(root!)
76
- }
77
- mounted = true
78
- if (__DEV__) {
79
- window.__kiru?.emit("mount", appContext)
80
- }
81
- resolve(appContext)
82
- }, false)
83
- requestUpdate(rootNode)
84
- flushSync()
85
- })
39
+ const id = appId++
40
+ const name = options?.name ?? `App-${id}`
41
+ const appContext: AppContext = {
42
+ id,
43
+ name,
44
+ rootNode,
45
+ render,
46
+ unmount,
86
47
  }
87
48
 
88
- function unmount(): Promise<AppContext<T>> {
89
- return new Promise<AppContext<T>>((resolve) => {
90
- if (!mounted) return resolve(appContext)
91
- if (!rootNode?.child) return resolve(appContext)
92
- requestDelete(rootNode.child)
49
+ if (__DEV__) {
50
+ rootNode.app = appContext
51
+ window.__kiru?.emit("mount", appContext)
52
+ }
93
53
 
94
- nextIdle(() => {
95
- rootNode && (rootNode.child = null)
96
- mounted = false
97
- if (__DEV__) {
98
- window.__kiru?.emit("unmount", appContext)
99
- }
100
- resolve(appContext)
101
- })
102
- })
54
+ function render(children: JSX.Element) {
55
+ rootNode.props.children = children
56
+ requestUpdate(rootNode)
57
+ flushSync()
103
58
  }
104
59
 
105
- function setProps(fn: (oldProps: T) => T): Promise<AppContext<T>> {
106
- const rootChild = rootNode?.child
107
- if (!mounted || !rootChild)
108
- throw new KiruError(
109
- "Failed to apply new props - ensure the app is mounted"
110
- )
111
- return new Promise<AppContext<T>>((resolve) => {
112
- const { children, ref, key, ...rest } = rootChild.props
113
- rootChild.props = {
114
- ...Object.assign(rest, fn(rest as T)),
115
- children,
116
- ref,
117
- key,
118
- }
119
- requestUpdate(rootChild)
120
- nextIdle(() => resolve(appContext))
121
- })
60
+ function unmount() {
61
+ rootNode.props.children = null
62
+ requestUpdate(rootNode)
63
+ flushSync()
64
+ if (__DEV__) {
65
+ delete container.__kiruNode
66
+ delete rootNode.app
67
+ window.__kiru?.emit("unmount", appContext)
68
+ }
122
69
  }
123
70
 
124
- return (appContext = {
125
- id,
126
- name,
127
- get rootNode() {
128
- return rootNode
129
- },
130
- get root() {
131
- return root
132
- },
133
- get mounted() {
134
- return mounted
135
- },
136
- mount,
137
- unmount,
138
- setProps,
139
- })
71
+ render(children)
72
+ return appContext
140
73
  }
package/src/constants.ts CHANGED
@@ -13,6 +13,8 @@ export {
13
13
  FLAG_PLACEMENT,
14
14
  FLAG_DELETION,
15
15
  FLAG_HAS_MEMO_ANCESTOR,
16
+ FLAG_STATIC_DOM,
17
+ FLAG_MEMO,
16
18
  }
17
19
 
18
20
  export { voidElements, svgTags, booleanAttributes }
@@ -32,6 +34,8 @@ const FLAG_UPDATE = 1 << 1
32
34
  const FLAG_PLACEMENT = 1 << 2
33
35
  const FLAG_DELETION = 1 << 3
34
36
  const FLAG_HAS_MEMO_ANCESTOR = 1 << 4
37
+ const FLAG_STATIC_DOM = 1 << 5
38
+ const FLAG_MEMO = 1 << 6
35
39
 
36
40
  const REGEX_UNIT = {
37
41
  AMP_G: /&/g,
package/src/context.ts CHANGED
@@ -31,7 +31,6 @@ export function createContext<T>(defaultValue: T): Kiru.Context<T> {
31
31
  inject: (prev) => {
32
32
  const newProvider = ctx.Provider
33
33
  window.__kiru!.apps.forEach((ctx) => {
34
- if (!ctx.mounted || !ctx.rootNode) return
35
34
  traverseApply(ctx.rootNode, (vNode) => {
36
35
  if (vNode.type === prev.Provider) {
37
36
  vNode.type = newProvider
package/src/dom.ts CHANGED
@@ -11,13 +11,14 @@ import {
11
11
  FLAG_DELETION,
12
12
  FLAG_PLACEMENT,
13
13
  FLAG_UPDATE,
14
+ FLAG_STATIC_DOM,
14
15
  svgTags,
15
16
  } from "./constants.js"
16
- import { Signal, unwrap } from "./signals/index.js"
17
+ import { Signal } from "./signals/base.js"
18
+ import { unwrap } from "./signals/utils.js"
17
19
  import { renderMode } from "./globals.js"
18
20
  import { hydrationStack } from "./hydration.js"
19
21
  import { StyleObject } from "./types.dom.js"
20
- import { isPortal } from "./portal.js"
21
22
  import { __DEV__ } from "./env.js"
22
23
  import { KiruError } from "./error.js"
23
24
  import type {
@@ -146,7 +147,6 @@ const vNodeToWrappedFocusEventHandlersMap = new WeakMap<
146
147
  >()
147
148
 
148
149
  function updateDom(vNode: VNode) {
149
- if (isPortal(vNode)) return
150
150
  const dom = vNode.dom as SomeDom
151
151
  const prevProps: Record<string, any> = vNode.prev?.props ?? {}
152
152
  const nextProps: Record<string, any> = vNode.props ?? {}
@@ -363,7 +363,7 @@ function hydrateDom(vNode: VNode) {
363
363
  })
364
364
  }
365
365
  vNode.dom = dom
366
- if (vNode.type !== "#text") {
366
+ if (vNode.type !== "#text" && !(vNode.flags & FLAG_STATIC_DOM)) {
367
367
  updateDom(vNode)
368
368
  return
369
369
  }
@@ -571,8 +571,8 @@ function getNextSiblingDom(vNode: VNode, parent: ElementVNode): MaybeDom {
571
571
  let sibling = node.sibling
572
572
 
573
573
  while (sibling) {
574
- // Skip unmounted, to-be-placed & portal nodes
575
- if (!(sibling.flags & FLAG_PLACEMENT) && !isPortal(sibling)) {
574
+ // Skip unmounted, to-be-placed & static nodes
575
+ if (!(sibling.flags & (FLAG_PLACEMENT | FLAG_STATIC_DOM))) {
576
576
  // Descend into the child to find host dom
577
577
  const dom = findFirstHostDom(sibling)
578
578
  if (dom?.isConnected) return dom
@@ -582,7 +582,7 @@ function getNextSiblingDom(vNode: VNode, parent: ElementVNode): MaybeDom {
582
582
 
583
583
  // Move up to parent — but don't escape portal boundary
584
584
  node = node.parent
585
- if (!node || isPortal(node) || node === parent) {
585
+ if (!node || node.flags & FLAG_STATIC_DOM || node === parent) {
586
586
  return
587
587
  }
588
588
  }
@@ -595,7 +595,7 @@ function findFirstHostDom(vNode: VNode): MaybeDom {
595
595
 
596
596
  while (node) {
597
597
  if (node.dom) return node.dom
598
- if (isPortal(node)) return // Don't descend into portals
598
+ if (node.flags & FLAG_STATIC_DOM) return // Don't descend into portals
599
599
  node = node.child
600
600
  }
601
601
  return
@@ -656,7 +656,9 @@ function commitWork(vNode: VNode) {
656
656
  currentHostNode = { node: getDomParent(node) }
657
657
  hostNodes.push(currentHostNode)
658
658
  }
659
- commitDom(node as DomVNode, currentHostNode, inheritsPlacement)
659
+ if (!(node.flags & FLAG_STATIC_DOM)) {
660
+ commitDom(node as DomVNode, currentHostNode, inheritsPlacement)
661
+ }
660
662
  }
661
663
  commitSnapshot(node)
662
664
  },
@@ -680,7 +682,6 @@ function commitDom(
680
682
  hostNode: HostNode,
681
683
  inheritsPlacement: boolean
682
684
  ) {
683
- if (isPortal(vNode)) return
684
685
  if (
685
686
  inheritsPlacement ||
686
687
  !vNode.dom.isConnected ||
@@ -720,7 +721,7 @@ function commitDeletion(vNode: VNode) {
720
721
 
721
722
  if (dom) {
722
723
  if (ref) setDomRef(ref as Kiru.Ref<SomeDom>, null)
723
- if (dom.isConnected && !isPortal(node)) {
724
+ if (dom.isConnected && !(node.flags & FLAG_STATIC_DOM)) {
724
725
  dom.remove()
725
726
  }
726
727
  delete node.dom
package/src/element.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $FRAGMENT, $MEMO } from "./constants.js"
1
+ import { $FRAGMENT, $MEMO, FLAG_MEMO } from "./constants.js"
2
2
  import { isMemoFn } from "./memo.js"
3
3
  import { isValidElementKeyProp, isValidElementRefProp } from "./props.js"
4
4
 
@@ -23,7 +23,7 @@ export function createElement<T extends Kiru.VNode["type"]>(
23
23
  deletions: null,
24
24
  }
25
25
  if (isMemoFn(type)) {
26
- node.isMemoized = true
26
+ node.flags |= FLAG_MEMO
27
27
  node.arePropsEqual = type[$MEMO].arePropsEqual
28
28
  }
29
29
 
package/src/hmr.ts CHANGED
@@ -1,11 +1,11 @@
1
- import type { Store } from "./store"
2
- import type { WatchEffect } from "./signals/watch"
3
1
  import { $HMR_ACCEPT } from "./constants.js"
4
2
  import { __DEV__ } from "./env.js"
5
3
  import { traverseApply } from "./utils.js"
6
4
  import { requestUpdate } from "./scheduler.js"
7
- import { Signal } from "./signals/index.js"
8
- import type { AppContext } from "./appContext"
5
+ import { Signal } from "./signals/base.js"
6
+ import type { WatchEffect } from "./signals/watch.js"
7
+ import type { Store } from "./store.js"
8
+ import type { AppContext } from "./appContext.js"
9
9
 
10
10
  export type HMRAccept<T = {}> = {
11
11
  provide: () => T
@@ -119,7 +119,6 @@ export function createHMRContext() {
119
119
  }
120
120
  if (oldEntry.type === "component" && newEntry.type === "component") {
121
121
  window.__kiru!.apps.forEach((ctx) => {
122
- if (!ctx.mounted || !ctx.rootNode) return
123
122
  traverseApply(ctx.rootNode, (vNode) => {
124
123
  if (vNode.type === oldEntry.value) {
125
124
  vNode.type = newEntry.value as any
package/src/index.ts CHANGED
@@ -1,13 +1,8 @@
1
- import {
2
- createAppContext,
3
- type AppContext,
4
- type AppContextOptions,
5
- } from "./appContext.js"
6
1
  import { createKiruGlobalContext } from "./globalContext.js"
7
2
  import { __DEV__ } from "./env.js"
8
- import { KiruError } from "./error.js"
9
3
 
10
4
  export type * from "./types"
5
+ export * from "./signals/index.js"
11
6
  export * from "./appContext.js"
12
7
  export * from "./context.js"
13
8
  export * from "./cloneVNode.js"
@@ -17,7 +12,6 @@ export * from "./lazy.js"
17
12
  export { memo } from "./memo.js"
18
13
  export * from "./portal.js"
19
14
  export * from "./renderToString.js"
20
- export * from "./signals/index.js"
21
15
  export { nextIdle, flushSync, requestUpdate } from "./scheduler.js"
22
16
  export * from "./store.js"
23
17
  export * from "./transition.js"
@@ -25,37 +19,3 @@ export * from "./transition.js"
25
19
  if ("window" in globalThis) {
26
20
  globalThis.window.__kiru ??= createKiruGlobalContext()
27
21
  }
28
-
29
- export function mount<T extends Record<string, unknown>>(
30
- appFunc: (props: T) => JSX.Element,
31
- options: AppContextOptions,
32
- appProps?: T
33
- ): Promise<AppContext<T>>
34
-
35
- export function mount<T extends Record<string, unknown>>(
36
- appFunc: (props: T) => JSX.Element,
37
- root: HTMLElement,
38
- appProps?: T
39
- ): Promise<AppContext<T>>
40
-
41
- export function mount<T extends Record<string, unknown>>(
42
- appFunc: (props: T) => JSX.Element,
43
- optionsOrRoot: HTMLElement | AppContextOptions,
44
- appProps = {} as T
45
- ): Promise<AppContext<T>> {
46
- let root: HTMLElement, opts: AppContextOptions | undefined
47
- if (optionsOrRoot instanceof HTMLElement) {
48
- root = optionsOrRoot
49
- opts = { root }
50
- } else {
51
- opts = optionsOrRoot
52
- root = optionsOrRoot.root!
53
- if (__DEV__) {
54
- if (!(root instanceof HTMLElement)) {
55
- throw new KiruError("Root node must be an HTMLElement")
56
- }
57
- }
58
- }
59
-
60
- return createAppContext<T>(appFunc, appProps, opts).mount()
61
- }
package/src/memo.ts CHANGED
@@ -41,8 +41,6 @@ export function memo<T extends Record<string, unknown> = {}>(
41
41
 
42
42
  export function isMemoFn(fn: any): fn is MemoFn {
43
43
  return (
44
- typeof fn === "function" &&
45
- fn[$MEMO] &&
46
- typeof fn[$MEMO].arePropsEqual === "function"
44
+ typeof fn === "function" && typeof fn[$MEMO]?.arePropsEqual === "function"
47
45
  )
48
46
  }
package/src/portal.ts CHANGED
@@ -1,42 +1,38 @@
1
+ import { FLAG_STATIC_DOM } from "./constants.js"
1
2
  import { __DEV__ } from "./env.js"
2
3
  import { KiruError } from "./error.js"
3
4
  import { renderMode } from "./globals.js"
4
5
  import { useVNode } from "./hooks/utils.js"
5
6
  import { nextIdle, requestUpdate } from "./scheduler.js"
6
7
 
7
- export { Portal, isPortal }
8
-
9
8
  type PortalProps = {
10
9
  children?: JSX.Children
11
10
  container: HTMLElement | (() => HTMLElement)
12
11
  }
13
12
 
14
- function Portal({ children, container }: PortalProps) {
13
+ export function Portal({ children, container }: PortalProps) {
15
14
  const vNode = useVNode()
16
- switch (renderMode.current) {
17
- case "dom":
18
- vNode.dom = typeof container === "function" ? container() : container
19
- if (!(vNode.dom instanceof HTMLElement)) {
20
- if (__DEV__) {
21
- throw new KiruError({
22
- message: `Invalid portal container, expected HTMLElement, got ${vNode.dom}`,
23
- vNode: vNode,
24
- })
15
+ if (!vNode.dom) {
16
+ vNode.flags |= FLAG_STATIC_DOM
17
+ switch (renderMode.current) {
18
+ case "dom":
19
+ vNode.dom = typeof container === "function" ? container() : container
20
+ if (!(vNode.dom instanceof HTMLElement)) {
21
+ if (__DEV__) {
22
+ throw new KiruError({
23
+ message: `Invalid portal container, expected HTMLElement, got ${vNode.dom}`,
24
+ vNode: vNode,
25
+ })
26
+ }
27
+ return null
25
28
  }
29
+ return children
30
+ case "hydrate":
31
+ nextIdle(() => requestUpdate(vNode))
32
+ case "stream":
33
+ case "string":
26
34
  return null
27
- }
28
- return children
29
- case "hydrate":
30
- nextIdle(() => requestUpdate(vNode))
31
- return null
32
- case "stream":
33
- case "string":
34
- return null
35
+ }
35
36
  }
36
- }
37
-
38
- function isPortal(
39
- node: Kiru.VNode
40
- ): node is Kiru.VNode & { type: typeof Portal } {
41
- return node.type === Portal
37
+ return children
42
38
  }
package/src/props.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { KiruError } from "./error.js"
2
- import { Signal } from "./signals/index.js"
2
+ import { Signal } from "./signals/base.js"
3
3
 
4
4
  export function assertValidElementProps(vNode: Kiru.VNode) {
5
5
  if ("children" in vNode.props && vNode.props.innerHTML) {
package/src/reconciler.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  $FRAGMENT,
3
3
  FLAG_HAS_MEMO_ANCESTOR,
4
+ FLAG_MEMO,
4
5
  FLAG_PLACEMENT,
5
6
  FLAG_UPDATE,
6
7
  } from "./constants.js"
7
8
  import { getVNodeAppContext, isVNode, latest } from "./utils.js"
8
- import { Signal } from "./signals/index.js"
9
+ import { Signal } from "./signals/base.js"
9
10
  import { __DEV__ } from "./env.js"
10
11
  import { createElement, Fragment } from "./element.js"
11
12
  import type { AppContext } from "./appContext.js"
@@ -459,7 +460,7 @@ function propsChanged(oldProps: VNode["props"], newProps: VNode["props"]) {
459
460
  function setParent(child: VNode, parent: VNode) {
460
461
  child.parent = parent
461
462
  child.depth = parent.depth + 1
462
- if (parent.isMemoized || parent.flags & FLAG_HAS_MEMO_ANCESTOR) {
463
+ if (parent.flags & (FLAG_MEMO | FLAG_HAS_MEMO_ANCESTOR)) {
463
464
  child.flags |= FLAG_HAS_MEMO_ANCESTOR
464
465
  }
465
466
  }
@@ -1,5 +1,4 @@
1
1
  import { node, renderMode } from "./globals.js"
2
- import { createAppContext } from "./appContext.js"
3
2
  import { Fragment } from "./element.js"
4
3
  import {
5
4
  isVNode,
@@ -7,22 +6,17 @@ import {
7
6
  propsToElementAttributes,
8
7
  isExoticType,
9
8
  } from "./utils.js"
10
- import { Signal } from "./signals/index.js"
9
+ import { Signal } from "./signals/base.js"
11
10
  import { $HYDRATION_BOUNDARY, voidElements } from "./constants.js"
12
11
  import { assertValidElementProps } from "./props.js"
13
12
  import { HYDRATION_BOUNDARY_MARKER } from "./ssr/hydrationBoundary.js"
14
13
  import { __DEV__ } from "./env.js"
15
14
 
16
- export function renderToString<T extends Record<string, unknown>>(
17
- appFunc: (props: T) => JSX.Element,
18
- appProps = {} as T
19
- ) {
15
+ export function renderToString(element: JSX.Element) {
20
16
  const prev = renderMode.current
21
17
  renderMode.current = "string"
22
- const ctx = createAppContext(appFunc, appProps, {
23
- rootType: Fragment,
24
- })
25
- const res = renderToString_internal(ctx.rootNode, null, 0)
18
+ const rootNode = Fragment({ children: element })
19
+ const res = renderToString_internal(rootNode, null, 0)
26
20
  renderMode.current = prev
27
21
  return res
28
22
  }