@faiwer/react 0.8.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 (246) hide show
  1. package/README.md +90 -0
  2. package/dist/core/actions/applyAction.d.ts +11 -0
  3. package/dist/core/actions/applyAction.d.ts.map +1 -0
  4. package/dist/core/actions/applyAction.js +35 -0
  5. package/dist/core/actions/applyAction.js.map +1 -0
  6. package/dist/core/actions/createComment.action.d.ts +7 -0
  7. package/dist/core/actions/createComment.action.d.ts.map +1 -0
  8. package/dist/core/actions/createComment.action.js +20 -0
  9. package/dist/core/actions/createComment.action.js.map +1 -0
  10. package/dist/core/actions/createTag.action.d.ts +10 -0
  11. package/dist/core/actions/createTag.action.d.ts.map +1 -0
  12. package/dist/core/actions/createTag.action.js +27 -0
  13. package/dist/core/actions/createTag.action.js.map +1 -0
  14. package/dist/core/actions/createText.action.d.ts +6 -0
  15. package/dist/core/actions/createText.action.d.ts.map +1 -0
  16. package/dist/core/actions/createText.action.js +16 -0
  17. package/dist/core/actions/createText.action.js.map +1 -0
  18. package/dist/core/actions/helpers.d.ts +43 -0
  19. package/dist/core/actions/helpers.d.ts.map +1 -0
  20. package/dist/core/actions/helpers.js +141 -0
  21. package/dist/core/actions/helpers.js.map +1 -0
  22. package/dist/core/actions/relayout.action.d.ts +20 -0
  23. package/dist/core/actions/relayout.action.d.ts.map +1 -0
  24. package/dist/core/actions/relayout.action.js +113 -0
  25. package/dist/core/actions/relayout.action.js.map +1 -0
  26. package/dist/core/actions/remove.action.d.ts +7 -0
  27. package/dist/core/actions/remove.action.d.ts.map +1 -0
  28. package/dist/core/actions/remove.action.js +64 -0
  29. package/dist/core/actions/remove.action.js.map +1 -0
  30. package/dist/core/actions/replace.action.d.ts +18 -0
  31. package/dist/core/actions/replace.action.d.ts.map +1 -0
  32. package/dist/core/actions/replace.action.js +57 -0
  33. package/dist/core/actions/replace.action.js.map +1 -0
  34. package/dist/core/actions/setAttr.action.d.ts +9 -0
  35. package/dist/core/actions/setAttr.action.d.ts.map +1 -0
  36. package/dist/core/actions/setAttr.action.js +62 -0
  37. package/dist/core/actions/setAttr.action.js.map +1 -0
  38. package/dist/core/actions/setProps.action.d.ts +8 -0
  39. package/dist/core/actions/setProps.action.d.ts.map +1 -0
  40. package/dist/core/actions/setProps.action.js +13 -0
  41. package/dist/core/actions/setProps.action.js.map +1 -0
  42. package/dist/core/actions/setRef.action.d.ts +11 -0
  43. package/dist/core/actions/setRef.action.d.ts.map +1 -0
  44. package/dist/core/actions/setRef.action.js +38 -0
  45. package/dist/core/actions/setRef.action.js.map +1 -0
  46. package/dist/core/actions/setText.action.d.ts +7 -0
  47. package/dist/core/actions/setText.action.d.ts.map +1 -0
  48. package/dist/core/actions/setText.action.js +12 -0
  49. package/dist/core/actions/setText.action.js.map +1 -0
  50. package/dist/core/compact.d.ts +38 -0
  51. package/dist/core/compact.d.ts.map +1 -0
  52. package/dist/core/compact.js +112 -0
  53. package/dist/core/compact.js.map +1 -0
  54. package/dist/core/components.d.ts +32 -0
  55. package/dist/core/components.d.ts.map +1 -0
  56. package/dist/core/components.js +57 -0
  57. package/dist/core/components.js.map +1 -0
  58. package/dist/core/createElement.d.ts +47 -0
  59. package/dist/core/createElement.d.ts.map +1 -0
  60. package/dist/core/createElement.js +73 -0
  61. package/dist/core/createElement.js.map +1 -0
  62. package/dist/core/createRoot.d.ts +13 -0
  63. package/dist/core/createRoot.d.ts.map +1 -0
  64. package/dist/core/createRoot.js +33 -0
  65. package/dist/core/createRoot.js.map +1 -0
  66. package/dist/core/reactNodeToFiberNode.d.ts +8 -0
  67. package/dist/core/reactNodeToFiberNode.d.ts.map +1 -0
  68. package/dist/core/reactNodeToFiberNode.js +132 -0
  69. package/dist/core/reactNodeToFiberNode.js.map +1 -0
  70. package/dist/core/reconciliation/app.d.ts +5 -0
  71. package/dist/core/reconciliation/app.d.ts.map +1 -0
  72. package/dist/core/reconciliation/app.js +20 -0
  73. package/dist/core/reconciliation/app.js.map +1 -0
  74. package/dist/core/reconciliation/applyActions.d.ts +8 -0
  75. package/dist/core/reconciliation/applyActions.d.ts.map +1 -0
  76. package/dist/core/reconciliation/applyActions.js +12 -0
  77. package/dist/core/reconciliation/applyActions.js.map +1 -0
  78. package/dist/core/reconciliation/collect/fromApp.d.ts +9 -0
  79. package/dist/core/reconciliation/collect/fromApp.d.ts.map +1 -0
  80. package/dist/core/reconciliation/collect/fromApp.js +39 -0
  81. package/dist/core/reconciliation/collect/fromApp.js.map +1 -0
  82. package/dist/core/reconciliation/collect/fromChildrenPair.d.ts +9 -0
  83. package/dist/core/reconciliation/collect/fromChildrenPair.d.ts.map +1 -0
  84. package/dist/core/reconciliation/collect/fromChildrenPair.js +127 -0
  85. package/dist/core/reconciliation/collect/fromChildrenPair.js.map +1 -0
  86. package/dist/core/reconciliation/collect/fromComponent.d.ts +10 -0
  87. package/dist/core/reconciliation/collect/fromComponent.d.ts.map +1 -0
  88. package/dist/core/reconciliation/collect/fromComponent.js +22 -0
  89. package/dist/core/reconciliation/collect/fromComponent.js.map +1 -0
  90. package/dist/core/reconciliation/collect/fromFiberPair.d.ts +9 -0
  91. package/dist/core/reconciliation/collect/fromFiberPair.d.ts.map +1 -0
  92. package/dist/core/reconciliation/collect/fromFiberPair.js +125 -0
  93. package/dist/core/reconciliation/collect/fromFiberPair.js.map +1 -0
  94. package/dist/core/reconciliation/collect/fromNewFiber.d.ts +7 -0
  95. package/dist/core/reconciliation/collect/fromNewFiber.d.ts.map +1 -0
  96. package/dist/core/reconciliation/collect/fromNewFiber.js +45 -0
  97. package/dist/core/reconciliation/collect/fromNewFiber.js.map +1 -0
  98. package/dist/core/reconciliation/comments.d.ts +3 -0
  99. package/dist/core/reconciliation/comments.d.ts.map +1 -0
  100. package/dist/core/reconciliation/comments.js +3 -0
  101. package/dist/core/reconciliation/comments.js.map +1 -0
  102. package/dist/core/reconciliation/compare/areFiberNodesEq.d.ts +7 -0
  103. package/dist/core/reconciliation/compare/areFiberNodesEq.d.ts.map +1 -0
  104. package/dist/core/reconciliation/compare/areFiberNodesEq.js +14 -0
  105. package/dist/core/reconciliation/compare/areFiberNodesEq.js.map +1 -0
  106. package/dist/core/reconciliation/compare/areFiberPropsEq.d.ts +7 -0
  107. package/dist/core/reconciliation/compare/areFiberPropsEq.d.ts.map +1 -0
  108. package/dist/core/reconciliation/compare/areFiberPropsEq.js +18 -0
  109. package/dist/core/reconciliation/compare/areFiberPropsEq.js.map +1 -0
  110. package/dist/core/reconciliation/effects.d.ts +14 -0
  111. package/dist/core/reconciliation/effects.d.ts.map +1 -0
  112. package/dist/core/reconciliation/effects.js +26 -0
  113. package/dist/core/reconciliation/effects.js.map +1 -0
  114. package/dist/core/reconciliation/fibers.d.ts +35 -0
  115. package/dist/core/reconciliation/fibers.d.ts.map +1 -0
  116. package/dist/core/reconciliation/fibers.js +51 -0
  117. package/dist/core/reconciliation/fibers.js.map +1 -0
  118. package/dist/core/reconciliation/invalidateFiber.d.ts +8 -0
  119. package/dist/core/reconciliation/invalidateFiber.d.ts.map +1 -0
  120. package/dist/core/reconciliation/invalidateFiber.js +28 -0
  121. package/dist/core/reconciliation/invalidateFiber.js.map +1 -0
  122. package/dist/core/reconciliation/mount.d.ts +7 -0
  123. package/dist/core/reconciliation/mount.d.ts.map +1 -0
  124. package/dist/core/reconciliation/mount.js +53 -0
  125. package/dist/core/reconciliation/mount.js.map +1 -0
  126. package/dist/core/reconciliation/postCommit.d.ts +11 -0
  127. package/dist/core/reconciliation/postCommit.d.ts.map +1 -0
  128. package/dist/core/reconciliation/postCommit.js +47 -0
  129. package/dist/core/reconciliation/postCommit.js.map +1 -0
  130. package/dist/core/reconciliation/render.d.ts +11 -0
  131. package/dist/core/reconciliation/render.d.ts.map +1 -0
  132. package/dist/core/reconciliation/render.js +35 -0
  133. package/dist/core/reconciliation/render.js.map +1 -0
  134. package/dist/core/reconciliation/runFiberComponents.d.ts +10 -0
  135. package/dist/core/reconciliation/runFiberComponents.d.ts.map +1 -0
  136. package/dist/core/reconciliation/runFiberComponents.js +37 -0
  137. package/dist/core/reconciliation/runFiberComponents.js.map +1 -0
  138. package/dist/core/reconciliation/typeGuards.d.ts +12 -0
  139. package/dist/core/reconciliation/typeGuards.d.ts.map +1 -0
  140. package/dist/core/reconciliation/typeGuards.js +32 -0
  141. package/dist/core/reconciliation/typeGuards.js.map +1 -0
  142. package/dist/core/reconciliation/validateTree.d.ts +6 -0
  143. package/dist/core/reconciliation/validateTree.d.ts.map +1 -0
  144. package/dist/core/reconciliation/validateTree.js +48 -0
  145. package/dist/core/reconciliation/validateTree.js.map +1 -0
  146. package/dist/hooks/helpers.d.ts +19 -0
  147. package/dist/hooks/helpers.d.ts.map +1 -0
  148. package/dist/hooks/helpers.js +40 -0
  149. package/dist/hooks/helpers.js.map +1 -0
  150. package/dist/hooks/index.d.ts +9 -0
  151. package/dist/hooks/index.d.ts.map +1 -0
  152. package/dist/hooks/index.js +9 -0
  153. package/dist/hooks/index.js.map +1 -0
  154. package/dist/hooks/useCallback.d.ts +2 -0
  155. package/dist/hooks/useCallback.d.ts.map +1 -0
  156. package/dist/hooks/useCallback.js +5 -0
  157. package/dist/hooks/useCallback.js.map +1 -0
  158. package/dist/hooks/useContext.d.ts +37 -0
  159. package/dist/hooks/useContext.d.ts.map +1 -0
  160. package/dist/hooks/useContext.js +101 -0
  161. package/dist/hooks/useContext.js.map +1 -0
  162. package/dist/hooks/useEffect.d.ts +48 -0
  163. package/dist/hooks/useEffect.d.ts.map +1 -0
  164. package/dist/hooks/useEffect.js +100 -0
  165. package/dist/hooks/useEffect.js.map +1 -0
  166. package/dist/hooks/useId.d.ts +2 -0
  167. package/dist/hooks/useId.d.ts.map +1 -0
  168. package/dist/hooks/useId.js +10 -0
  169. package/dist/hooks/useId.js.map +1 -0
  170. package/dist/hooks/useMemo.d.ts +20 -0
  171. package/dist/hooks/useMemo.d.ts.map +1 -0
  172. package/dist/hooks/useMemo.js +33 -0
  173. package/dist/hooks/useMemo.js.map +1 -0
  174. package/dist/hooks/useRef.d.ts +4 -0
  175. package/dist/hooks/useRef.d.ts.map +1 -0
  176. package/dist/hooks/useRef.js +9 -0
  177. package/dist/hooks/useRef.js.map +1 -0
  178. package/dist/hooks/useStableCallback.d.ts +45 -0
  179. package/dist/hooks/useStableCallback.d.ts.map +1 -0
  180. package/dist/hooks/useStableCallback.js +66 -0
  181. package/dist/hooks/useStableCallback.js.map +1 -0
  182. package/dist/hooks/useState.d.ts +15 -0
  183. package/dist/hooks/useState.d.ts.map +1 -0
  184. package/dist/hooks/useState.js +39 -0
  185. package/dist/hooks/useState.js.map +1 -0
  186. package/dist/index.d.ts +8 -0
  187. package/dist/index.d.ts.map +1 -0
  188. package/dist/index.js +13 -0
  189. package/dist/index.js.map +1 -0
  190. package/dist/jsx-dev-runtime.d.ts +6 -0
  191. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  192. package/dist/jsx-dev-runtime.js +7 -0
  193. package/dist/jsx-dev-runtime.js.map +1 -0
  194. package/dist/jsx-runtime.d.ts +31 -0
  195. package/dist/jsx-runtime.d.ts.map +1 -0
  196. package/dist/jsx-runtime.js +32 -0
  197. package/dist/jsx-runtime.js.map +1 -0
  198. package/dist/testing.d.ts +8 -0
  199. package/dist/testing.d.ts.map +1 -0
  200. package/dist/testing.js +10 -0
  201. package/dist/testing.js.map +1 -0
  202. package/dist/types/actions.d.ts +53 -0
  203. package/dist/types/actions.d.ts.map +1 -0
  204. package/dist/types/actions.js +2 -0
  205. package/dist/types/actions.js.map +1 -0
  206. package/dist/types/app.d.ts +74 -0
  207. package/dist/types/app.d.ts.map +1 -0
  208. package/dist/types/app.js +2 -0
  209. package/dist/types/app.js.map +1 -0
  210. package/dist/types/component.d.ts +11 -0
  211. package/dist/types/component.d.ts.map +1 -0
  212. package/dist/types/component.js +2 -0
  213. package/dist/types/component.js.map +1 -0
  214. package/dist/types/context.d.ts +28 -0
  215. package/dist/types/context.d.ts.map +1 -0
  216. package/dist/types/context.js +2 -0
  217. package/dist/types/context.js.map +1 -0
  218. package/dist/types/core.d.ts +51 -0
  219. package/dist/types/core.d.ts.map +1 -0
  220. package/dist/types/core.js +2 -0
  221. package/dist/types/core.js.map +1 -0
  222. package/dist/types/dom.d.ts +48 -0
  223. package/dist/types/dom.d.ts.map +1 -0
  224. package/dist/types/dom.js +2 -0
  225. package/dist/types/dom.js.map +1 -0
  226. package/dist/types/fiber.d.ts +169 -0
  227. package/dist/types/fiber.d.ts.map +1 -0
  228. package/dist/types/fiber.js +2 -0
  229. package/dist/types/fiber.js.map +1 -0
  230. package/dist/types/hooks.d.ts +47 -0
  231. package/dist/types/hooks.d.ts.map +1 -0
  232. package/dist/types/hooks.js +2 -0
  233. package/dist/types/hooks.js.map +1 -0
  234. package/dist/types/index.d.ts +9 -0
  235. package/dist/types/index.d.ts.map +1 -0
  236. package/dist/types/index.js +9 -0
  237. package/dist/types/index.js.map +1 -0
  238. package/dist/types/refs.d.ts +19 -0
  239. package/dist/types/refs.d.ts.map +1 -0
  240. package/dist/types/refs.js +2 -0
  241. package/dist/types/refs.js.map +1 -0
  242. package/dist/utils.d.ts +2 -0
  243. package/dist/utils.d.ts.map +1 -0
  244. package/dist/utils.js +7 -0
  245. package/dist/utils.js.map +1 -0
  246. package/package.json +67 -0
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ ## What is it?
2
+
3
+ A naive React implementation. Why? What's wrong with the existing one? Nothing. I just wanted to implement it from scratch by myself. It can be used as a drop-in replacement for some simple React apps. May require some trivial changes, though.
4
+
5
+ ## It supports
6
+
7
+ - JSX
8
+ - Functional components
9
+ - Hooks:
10
+ - `useState`
11
+ - `useRef`
12
+ - `useMemo`, `useCallback`
13
+ - `useStableCallback` (better version of `useEffectEvent`)
14
+ - `useLayoutEffect`, `useEffect` (improved versions)
15
+ - `useId`
16
+ - `useContext`
17
+ - Tag-based refs
18
+ - Context
19
+ - Portals
20
+ - Fragments
21
+
22
+ ## Installation
23
+
24
+ - `npm i --save @faiwer/react`
25
+ - Update your `tsconfig.json`:
26
+ ```json
27
+ "compilerOptions": {
28
+ "jsx": "react-jsx",
29
+ "jsxImportSource": "@faiwer/react"
30
+ }
31
+ ```
32
+
33
+ ### Usage
34
+
35
+ To mount an app:
36
+
37
+ ```tsx
38
+ const container = document.getElementById('root');
39
+ createRoot(container).render(<App />);
40
+ ```
41
+
42
+ ## TODO
43
+
44
+ - 1st line
45
+ - Support tag-`style` attribute
46
+ - Events:
47
+ - "capture"-kind of events
48
+ - camelCase events
49
+ - custom `onChange` like in ReactDOM
50
+ - Error handling
51
+ - Direct component refs, `forwardRef`, `useImperativeHandle`
52
+ - 2nd line
53
+ - prepare an NPM-package
54
+ - 3rd line
55
+ - `RunComponent` is not pure. Some hooks change the state during the rendering phase. Fix it.
56
+ - `useReducer`
57
+
58
+ ## It does NOT support
59
+
60
+ … and probably never will:
61
+
62
+ - Class Components
63
+ - Synthetic events
64
+ - Portals:
65
+ - Event bubbling from portals
66
+ - Rendering multiple portals in the same DOM node
67
+ - `memo` (because components are memoized by default)
68
+ - Some less popular tools
69
+ - `useInsertionEffect`
70
+ - `useOptimistic` (could be polyfilled)
71
+ - `useDeferredValue` (could be polyfilled)
72
+ - `useDebugValue` (dev tools are not supported)
73
+ - `<StrictMode/>`.
74
+ - `<Profiler/>`.
75
+ - `preconnect`, `prefetchDNS`, `preinit`, `preinitModule`, `preload`, `preloadModule`
76
+ - Modern stuff:
77
+ - `useTransition`, `startTransition`
78
+ - `<Suspense/>`, `lazy`.
79
+ - Form-based hooks (like `useActionState`, `useFormStatus`)
80
+ - React Dev Tools. Just take a look at `__REACT_DEVTOOLS_GLOBAL_HOOK__`, it's huge. E.g., it has `reactDevtoolsAgent`, a class with 20-30 methods…
81
+ - `flushSync` (not supported by the engine)
82
+ - SSR
83
+
84
+ ## Major differences
85
+
86
+ - It renders HTML-comment for nullable nodes and some fragments. Why? It helps a lot to keep the reconciliation algorithm simple. Took this idea from Angular.
87
+ - No synthetic events. I don't see any reason to implement them.
88
+ - All components are memoized by default. Why not?
89
+ - No custom DOM-related code. This library is supposed to be simple and silly. Whereas React-DOM lib is huge.
90
+ - No modern fiber-driven stuff like `<Suspense>`, `cacheSignal`, or `use`. Too much work. It took React many years to cook it well :)
@@ -0,0 +1,11 @@
1
+ import type { Action } from '../../types/actions';
2
+ /**
3
+ * The commit phase of the rendering process contains two parts:
4
+ * - Applying DOM changes
5
+ * - Running effects
6
+ *
7
+ * DOM changes are described in actions. This function applies the given action
8
+ * to the DOM and updates the bound fiber node accordingly.
9
+ */
10
+ export declare const applyAction: (action: Action) => void;
11
+ //# sourceMappingURL=applyAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyAction.d.ts","sourceRoot":"","sources":["../../../src/core/actions/applyAction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAYzD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,0BAGvB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { createTagAction } from './createTag.action';
2
+ import { createTextAction } from './createText.action';
3
+ import { createCommentAction } from './createComment.action';
4
+ import { setPropsAction } from './setProps.action';
5
+ import { setRefAction } from './setRef.action';
6
+ import { setAttrAction } from './setAttr.action';
7
+ import { setTextAction } from './setText.action';
8
+ import { removeAction } from './remove.action';
9
+ import { replaceAction } from './replace.action';
10
+ import { relayoutAction } from './relayout.action';
11
+ /**
12
+ * The commit phase of the rendering process contains two parts:
13
+ * - Applying DOM changes
14
+ * - Running effects
15
+ *
16
+ * DOM changes are described in actions. This function applies the given action
17
+ * to the DOM and updates the bound fiber node accordingly.
18
+ */
19
+ export const applyAction = (action) => {
20
+ // @ts-ignore -- too complex type.
21
+ actionHandlers[action.type](action.fiber, action);
22
+ };
23
+ const actionHandlers = {
24
+ CreateTag: createTagAction,
25
+ CreateText: createTextAction,
26
+ CreateComment: createCommentAction,
27
+ SetProps: setPropsAction,
28
+ SetRef: setRefAction,
29
+ SetAttr: setAttrAction,
30
+ SetText: setTextAction,
31
+ Remove: removeAction,
32
+ Replace: replaceAction,
33
+ Relayout: relayoutAction,
34
+ };
35
+ //# sourceMappingURL=applyAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyAction.js","sourceRoot":"","sources":["../../../src/core/actions/applyAction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAc,EAAQ,EAAE,CAAC;IACnD,kCAAkC;IAClC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAa,CAAC,CAAC;AAAA,CAC1D,CAAC;AAEF,MAAM,cAAc,GAKhB;IACF,SAAS,EAAE,eAAe;IAC1B,UAAU,EAAE,gBAAgB;IAC5B,aAAa,EAAE,mBAAmB;IAClC,QAAQ,EAAE,cAAc;IACxB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,cAAc;CACzB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { FiberNode } from '../../types';
2
+ import type { CreateCommentAction } from '../../types/actions';
3
+ /**
4
+ * Creates a new comment DOM node (<!--r:${mode}:${fiber.id}-->).
5
+ */
6
+ export declare function createCommentAction(fiber: FiberNode, { mode }: CreateCommentAction): void;
7
+ //# sourceMappingURL=createComment.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createComment.action.d.ts","sourceRoot":"","sources":["../../../src/core/actions/createComment.action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKtE;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,EAChB,EAAE,IAAI,EAAE,EAAE,mBAAmB,QAc9B"}
@@ -0,0 +1,20 @@
1
+ import { getParentElement } from './helpers';
2
+ import { tryToCompactNode } from '../compact';
3
+ import { buildComment } from '../reconciliation/comments';
4
+ /**
5
+ * Creates a new comment DOM node (<!--r:${mode}:${fiber.id}-->).
6
+ */
7
+ export function createCommentAction(fiber, { mode }) {
8
+ // Only two scenarios lead here:
9
+ // - First render of a fragment or component. The parent's element is a
10
+ // comment `r:begin:{id}`
11
+ // - Render of a portal. The parent element is the portal target node.
12
+ fiber.element = buildComment(mode, fiber.id);
13
+ getParentElement(fiber).appendChild(fiber.element);
14
+ if (mode === 'end') {
15
+ // All children are added. If the current fiber is the only child, we can
16
+ // compact the parent node: "<!--begin-->child<!--end-->" -> "child".
17
+ tryToCompactNode(fiber);
18
+ }
19
+ }
20
+ //# sourceMappingURL=createComment.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createComment.action.js","sourceRoot":"","sources":["../../../src/core/actions/createComment.action.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAgB,EAChB,EAAE,IAAI,EAAuB,EAC7B;IACA,gCAAgC;IAChC,uEAAuE;IACvE,2BAA2B;IAC3B,sEAAsE;IACtE,KAAK,CAAC,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7C,gBAAgB,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEnD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,yEAAyE;QACzE,qEAAqE;QACrE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;AAAA,CACF"}
@@ -0,0 +1,10 @@
1
+ import type { FiberNode } from '../../types';
2
+ /**
3
+ * Handles two scenarios:
4
+ * - Creates a <!--r:portal:id--> comment for portal fibers
5
+ * - Creates a new tag DOM element for tag fibers
6
+ *
7
+ * This doesn't create child nodes or set attributes/event handlers.
8
+ */
9
+ export declare function createTagAction(fiber: FiberNode): void;
10
+ //# sourceMappingURL=createTag.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTag.action.d.ts","sourceRoot":"","sources":["../../../src/core/actions/createTag.action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAIpD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAgBtD"}
@@ -0,0 +1,27 @@
1
+ import { getParentElement } from './helpers';
2
+ import { applyAction } from './applyAction';
3
+ /**
4
+ * Handles two scenarios:
5
+ * - Creates a <!--r:portal:id--> comment for portal fibers
6
+ * - Creates a new tag DOM element for tag fibers
7
+ *
8
+ * This doesn't create child nodes or set attributes/event handlers.
9
+ */
10
+ export function createTagAction(fiber) {
11
+ if (fiber.type !== 'tag') {
12
+ throw new Error(`createTagAction supports only tag-fiber-nodes.`);
13
+ }
14
+ if (fiber.data instanceof HTMLElement) {
15
+ // This is a portal, not a regular tag. We shouldn't create it since it
16
+ // already exists outside the app's DOM subtree. Instead, create a
17
+ // <!--r:portal:id--> comment node.
18
+ applyAction({ type: 'CreateComment', fiber, mode: 'portal' });
19
+ }
20
+ else if (fiber.tag !== 'root') {
21
+ // 'root' is a special case - it's the node where the app is mounted.
22
+ const tag = document.createElement(fiber.tag);
23
+ fiber.element = tag;
24
+ getParentElement(fiber).appendChild(fiber.element);
25
+ }
26
+ }
27
+ //# sourceMappingURL=createTag.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createTag.action.js","sourceRoot":"","sources":["../../../src/core/actions/createTag.action.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAgB,EAAQ;IACtD,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,YAAY,WAAW,EAAE,CAAC;QACtC,uEAAuE;QACvE,kEAAkE;QAClE,mCAAmC;QACnC,WAAW,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChE,CAAC;SAAM,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;QAChC,qEAAqE;QACrE,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;QACpB,gBAAgB,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;AAAA,CACF"}
@@ -0,0 +1,6 @@
1
+ import type { FiberNode } from '../../types';
2
+ /**
3
+ * Creates a new text DOM node.
4
+ */
5
+ export declare function createTextAction(fiber: FiberNode): void;
6
+ //# sourceMappingURL=createText.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createText.action.d.ts","sourceRoot":"","sources":["../../../src/core/actions/createText.action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,QAWhD"}
@@ -0,0 +1,16 @@
1
+ import { getParentElement } from './helpers';
2
+ /**
3
+ * Creates a new text DOM node.
4
+ */
5
+ export function createTextAction(fiber) {
6
+ if (fiber.type !== 'text') {
7
+ throw new Error(`Can't apply CreateText for a ${fiber.type} node`);
8
+ }
9
+ // Only two scenarios lead here:
10
+ // - First render of a fragment or component. The parent's element is
11
+ // a comment `r:begin:{id}`
12
+ // - Render of a portal. The parent element is the portal target node.
13
+ fiber.element = new Text(fiber.props.text);
14
+ getParentElement(fiber).appendChild(fiber.element);
15
+ }
16
+ //# sourceMappingURL=createText.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createText.action.js","sourceRoot":"","sources":["../../../src/core/actions/createText.action.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAgB,EAAE;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,gCAAgC;IAChC,qEAAqE;IACrE,6BAA6B;IAC7B,sEAAsE;IACtE,KAAK,CAAC,OAAO,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3C,gBAAgB,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAAA,CACpD"}
@@ -0,0 +1,43 @@
1
+ import type { DomNode, FiberNode, Ref, RefSetter } from '../../types';
2
+ /**
3
+ * Determines if a prop name represents an event handler by checking if it
4
+ * starts with "on". This follows React's convention where any prop beginning
5
+ * with "on" is treated as an event listener rather than a regular DOM
6
+ * attribute.
7
+ *
8
+ * While HTML technically allows non-event attributes starting with "on", no
9
+ * such attributes could be found in practice. React filters out all "on*" props
10
+ * as event handlers, and this implementation follows the same pattern for
11
+ * consistency.
12
+ */
13
+ export declare const isEventName: (name: string) => boolean;
14
+ /**
15
+ * Returns the DOM container for the given fiber node. This isn't always the
16
+ * direct parent's element since the parent might be a compact node or a
17
+ * fragment-like range (<!--begin|end-->), or it could be a portal node.
18
+ */
19
+ export declare const getParentElement: (fiber: FiberNode) => Element;
20
+ /**
21
+ * Finds the anchor node for attaching other nodes. There are two scenarios:
22
+ * 1) [element, null] - the new node should be added to the beginning of the
23
+ * element;
24
+ * 2) [element, child] - the new node should be added right after `child`.
25
+ */
26
+ export declare const getAnchor: (fiber: FiberNode) => [Element, Node | null];
27
+ /**
28
+ * Returns all direct DOM nodes associated with the given fiber. This isn't
29
+ * always a single node since components and fragments may be in expanded state
30
+ * (<!--begin--> + content + <!--end-->).
31
+ */
32
+ export declare const getFiberDomNodes: (fiber: FiberNode) => DomNode[];
33
+ /**
34
+ * When a node leaves the DOM tree, we need to update all associated ref
35
+ * objects and ref handlers.
36
+ */
37
+ export declare const unsetRef: <T>(ref: Ref<T | null> | RefSetter<T | null>) => void;
38
+ /**
39
+ * To help avoid memory leaks, this method removes fiber properties that
40
+ * can hold references to other objects.
41
+ */
42
+ export declare const emptyFiberNode: (fiber: FiberNode) => void;
43
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/core/actions/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAM7E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,2BAAmD,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,+BAa5B,CAAC;AA6BF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,8CAiCrB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,iCAwB5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,mDAMzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,4BAQ1B,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { nullthrows } from '../../utils';
2
+ import { isBeginOf, isCompactNone, isCompactSingleChild } from '../compact';
3
+ import { NULL_FIBER } from '../reconciliation/fibers';
4
+ import { buildCommentText } from '../reconciliation/comments';
5
+ /**
6
+ * Determines if a prop name represents an event handler by checking if it
7
+ * starts with "on". This follows React's convention where any prop beginning
8
+ * with "on" is treated as an event listener rather than a regular DOM
9
+ * attribute.
10
+ *
11
+ * While HTML technically allows non-event attributes starting with "on", no
12
+ * such attributes could be found in practice. React filters out all "on*" props
13
+ * as event handlers, and this implementation follows the same pattern for
14
+ * consistency.
15
+ */
16
+ export const isEventName = (name) => name.startsWith('on');
17
+ /**
18
+ * Returns the DOM container for the given fiber node. This isn't always the
19
+ * direct parent's element since the parent might be a compact node or a
20
+ * fragment-like range (<!--begin|end-->), or it could be a portal node.
21
+ */
22
+ export const getParentElement = (fiber) => {
23
+ while (fiber.parent.type === 'component' ||
24
+ fiber.parent.type === 'fragment') {
25
+ fiber = fiber.parent; // Has to be "tag".
26
+ }
27
+ if (fiber.parent.data instanceof HTMLElement) {
28
+ return fiber.parent.data; // Portal.
29
+ }
30
+ return nullthrows(fiber.parent?.element);
31
+ };
32
+ /**
33
+ * Finds the !--begin comment for the given !--end comment.
34
+ */
35
+ const getBeginComment = (fiber) => {
36
+ let node = asComment(fiber.element).previousSibling;
37
+ const text = buildCommentText('begin', fiber.id);
38
+ while (!(node instanceof Comment) || node.textContent !== text)
39
+ node = nullthrows(node.previousSibling);
40
+ return node;
41
+ };
42
+ const asElement = (node) => {
43
+ if (!(node instanceof Element)) {
44
+ throw new Error(`node is not element`);
45
+ }
46
+ return node;
47
+ };
48
+ const asComment = (node) => {
49
+ if (!(node instanceof Comment)) {
50
+ throw new Error(`node is not comment`);
51
+ }
52
+ return node;
53
+ };
54
+ /**
55
+ * Finds the anchor node for attaching other nodes. There are two scenarios:
56
+ * 1) [element, null] - the new node should be added to the beginning of the
57
+ * element;
58
+ * 2) [element, child] - the new node should be added right after `child`.
59
+ */
60
+ export const getAnchor = (fiber) => {
61
+ if (fiber.type === 'tag') {
62
+ return [
63
+ asElement(fiber.data instanceof HTMLElement
64
+ ? fiber.data // Portal's `element` is !--r:portal
65
+ : fiber.element),
66
+ null,
67
+ ];
68
+ }
69
+ if (fiber.type === 'component' || fiber.type === 'fragment') {
70
+ if (isCompactSingleChild(fiber)) {
71
+ throw new Error(`Solo-compact fibers cannot be used as an anchor`);
72
+ }
73
+ if (isCompactNone(fiber)) {
74
+ throw new Error(`Cannot use !--empty node as an anchor`);
75
+ }
76
+ // E.g.
77
+ // <div>
78
+ // <something/>
79
+ // <!--r:begin:1--> // a component or a fragment
80
+ // … // the content of the `fiber`
81
+ // <!--r:end:1-->
82
+ // <something/>
83
+ return [getParentElement(fiber), getBeginComment(fiber)];
84
+ }
85
+ // "text" & "null" types cannot contain children.
86
+ throw new Error(`Unsupported anchor type: ${fiber.type}`);
87
+ };
88
+ /**
89
+ * Returns all direct DOM nodes associated with the given fiber. This isn't
90
+ * always a single node since components and fragments may be in expanded state
91
+ * (<!--begin--> + content + <!--end-->).
92
+ */
93
+ export const getFiberDomNodes = (fiber) => {
94
+ switch (fiber.type) {
95
+ case 'component':
96
+ case 'fragment': {
97
+ if (isCompactSingleChild(fiber) || isCompactNone(fiber)) {
98
+ return [fiber.element];
99
+ }
100
+ // Collect [!--begin, …content, !--end]:
101
+ const list = [nullthrows(fiber.element)];
102
+ let prev = nullthrows(list[0].previousSibling);
103
+ while (prev && !isBeginOf(prev, fiber)) {
104
+ list.push(prev);
105
+ prev = nullthrows(prev.previousSibling);
106
+ }
107
+ list.push(prev);
108
+ return list.reverse();
109
+ }
110
+ case 'null':
111
+ case 'tag':
112
+ case 'text':
113
+ return [nullthrows(fiber.element)];
114
+ }
115
+ };
116
+ /**
117
+ * When a node leaves the DOM tree, we need to update all associated ref
118
+ * objects and ref handlers.
119
+ */
120
+ export const unsetRef = (ref) => {
121
+ if (typeof ref === 'function') {
122
+ ref(null);
123
+ }
124
+ else {
125
+ ref.current = null;
126
+ }
127
+ };
128
+ /**
129
+ * To help avoid memory leaks, this method removes fiber properties that
130
+ * can hold references to other objects.
131
+ */
132
+ export const emptyFiberNode = (fiber) => {
133
+ fiber.data = null;
134
+ fiber.element = null;
135
+ fiber.component = null;
136
+ fiber.children = [];
137
+ fiber.props = null;
138
+ fiber.ref = null;
139
+ fiber.parent = NULL_FIBER;
140
+ };
141
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/core/actions/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { FiberNode } from '../../types';
2
+ import type { RelayoutAction } from '../../types/actions';
3
+ /**
4
+ * Handles fiber tree layout updates when children have been modified. This
5
+ * action is triggered when:
6
+ * - A direct child was removed or replaced
7
+ * - Child order changed (for keyed children)
8
+ * - A new child was added
9
+ *
10
+ * The relayout process:
11
+ * - Moves new children from temporary containers (`<x-container/>`) to their
12
+ * final DOM position
13
+ * - Repositions existing children to match the new order
14
+ * - Updates the fiber's children array to reflect the new structure
15
+ *
16
+ * Note: This action only handles positioning and insertion. All node removals
17
+ * must be completed before this action runs.
18
+ */
19
+ export declare function relayoutAction(fiber: FiberNode, { before, after }: RelayoutAction): void;
20
+ //# sourceMappingURL=relayout.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relayout.action.d.ts","sourceRoot":"","sources":["../../../src/core/actions/relayout.action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAUjE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,EAChB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,cAAc,QAuClC"}
@@ -0,0 +1,113 @@
1
+ import { isCompactNone, isCompactSingleChild, tryToCompactNode, unwrapCompactFiber, } from '../compact';
2
+ import { getAnchor, getFiberDomNodes } from './helpers';
3
+ import { nullthrows } from '../../utils';
4
+ /**
5
+ * Handles fiber tree layout updates when children have been modified. This
6
+ * action is triggered when:
7
+ * - A direct child was removed or replaced
8
+ * - Child order changed (for keyed children)
9
+ * - A new child was added
10
+ *
11
+ * The relayout process:
12
+ * - Moves new children from temporary containers (`<x-container/>`) to their
13
+ * final DOM position
14
+ * - Repositions existing children to match the new order
15
+ * - Updates the fiber's children array to reflect the new structure
16
+ *
17
+ * Note: This action only handles positioning and insertion. All node removals
18
+ * must be completed before this action runs.
19
+ */
20
+ export function relayoutAction(fiber, { before, after }) {
21
+ if (after.size > 0) {
22
+ // If `fiber` is in compact mode we may need to unwrap it.
23
+ expandFiberWhenNeeded(fiber, after);
24
+ }
25
+ if (after.size > 0) {
26
+ // Determine what can be used as a starting point for inserting new children.
27
+ // If `prev` is `null`, new nodes should be added to the beginning.
28
+ // Otherwise, add them right after the `prev` node.
29
+ let [container, prev] = getAnchor(fiber);
30
+ for (const [key, r] of after) {
31
+ const l = before.get(key);
32
+ if (!l) {
33
+ // No nodes from `left` correlate with this node from `right`.
34
+ // Consider it a brand new node and put it at the current position.
35
+ prev = insertNewFiber(fiber, container, prev, r.fiber);
36
+ }
37
+ else {
38
+ // Keep DOM nodes from the previous render. Any requested updates for
39
+ // them are already applied, but we might need to reposition them
40
+ // within their parent.
41
+ prev = repositionFiberWhenNeeded(l.fiber, container, prev);
42
+ }
43
+ }
44
+ }
45
+ // Replace fiber.children with fibers from the `after` set.
46
+ // Skip any nodes whose keys exist in `before`, since those are either
47
+ // unchanged or already updated (their `after` entries served only as
48
+ // references for the update process).
49
+ fiber.children = [...after.keys()].map((key) => nullthrows(before.get(key) ?? after.get(key)).fiber);
50
+ // If `fiber` has 0 or 1 DOM children, we can remove <!--begin|end--> brackets.
51
+ tryToCompactNode(fiber);
52
+ }
53
+ /**
54
+ * If the given fiber (a container) is in the compact mode we might need to
55
+ * unwrap it.
56
+ */
57
+ const expandFiberWhenNeeded = (fiber, after) => {
58
+ if (isCompactNone(fiber)) {
59
+ // Case 1: it's <!--empty-->. It can't have children, so fix it.
60
+ unwrapCompactFiber(fiber);
61
+ }
62
+ else if (isCompactSingleChild(fiber)) {
63
+ if (after.size > 1) {
64
+ // Case 2: It's in "single child" mode. Fix it to support multiple children.
65
+ unwrapCompactFiber(fiber);
66
+ }
67
+ else {
68
+ throw new Error(`Invalid state: "remove" action didn't unwrap the parent container node during deletion of the only child`);
69
+ }
70
+ }
71
+ };
72
+ /**
73
+ * Puts the given `child` DOM nodes into the `parent`'s DOM area at the anchor
74
+ * position (`container` + `prev`). Updates the `child`'s parent node.
75
+ */
76
+ const insertNewFiber = (parent, container, prev, child) => {
77
+ const newChildren = [...child.parent.element.childNodes];
78
+ if (!prev) {
79
+ container.prepend(...newChildren);
80
+ prev = nullthrows(newChildren.at(-1));
81
+ }
82
+ else {
83
+ for (const n of newChildren) {
84
+ container.insertBefore(n, prev.nextSibling);
85
+ prev = n;
86
+ }
87
+ }
88
+ child.parent = parent; // <x-container/> -> real parent.
89
+ return prev;
90
+ };
91
+ /**
92
+ * Repositioning is needed in such situations:
93
+ * - before: <a/><b/><c key="c"/> -> <c key="c"/><a/><b/>.
94
+ */
95
+ const repositionFiberWhenNeeded = (fiber, container, prev) => {
96
+ const nodes = getFiberDomNodes(fiber);
97
+ if (nodes[0].previousSibling !== prev) {
98
+ for (const n of nodes) {
99
+ if (!prev) {
100
+ // Couldn't find a way to test this, because even without this move the
101
+ // following `repositionFiberWhenNeeded` will heal this gap. Anyway,
102
+ // it seems right to keep it.
103
+ container.prepend(n);
104
+ }
105
+ else {
106
+ container.insertBefore(n, prev.nextSibling);
107
+ }
108
+ prev = n;
109
+ }
110
+ }
111
+ return nullthrows(fiber.element);
112
+ };
113
+ //# sourceMappingURL=relayout.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relayout.action.js","sourceRoot":"","sources":["../../../src/core/actions/relayout.action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { FiberNode } from '../../types';
2
+ /**
3
+ * This action can be called directly (<div/> -> []), or indirectly (<div/> ->
4
+ * false) from the replace action. `replaced` is `true` in the 2nd scenario.
5
+ */
6
+ export declare function removeAction(fiber: FiberNode): void;
7
+ //# sourceMappingURL=remove.action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove.action.d.ts","sourceRoot":"","sources":["../../../src/core/actions/remove.action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,EAEV,MAAM,oBAAoB,CAAC;AAK5B;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,QAkC5C"}