rask-ui 0.2.4 → 0.2.6

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 (195) hide show
  1. package/dist/vdom/AbstractVNode.d.ts +24 -2
  2. package/dist/vdom/AbstractVNode.d.ts.map +1 -1
  3. package/dist/vdom/AbstractVNode.js +153 -13
  4. package/dist/vdom/ComponentVNode.d.ts +2 -2
  5. package/dist/vdom/ComponentVNode.d.ts.map +1 -1
  6. package/dist/vdom/ComponentVNode.js +11 -13
  7. package/dist/vdom/ElementVNode.d.ts +2 -8
  8. package/dist/vdom/ElementVNode.d.ts.map +1 -1
  9. package/dist/vdom/ElementVNode.js +15 -32
  10. package/dist/vdom/FragmentVNode.d.ts +2 -2
  11. package/dist/vdom/FragmentVNode.d.ts.map +1 -1
  12. package/dist/vdom/FragmentVNode.js +12 -3
  13. package/dist/vdom/RootVNode.d.ts +2 -2
  14. package/dist/vdom/RootVNode.d.ts.map +1 -1
  15. package/dist/vdom/RootVNode.js +7 -5
  16. package/package.json +1 -1
  17. package/dist/component.d.ts +0 -38
  18. package/dist/component.d.ts.map +0 -1
  19. package/dist/component.js +0 -130
  20. package/dist/context.d.ts +0 -5
  21. package/dist/context.d.ts.map +0 -1
  22. package/dist/context.js +0 -29
  23. package/dist/createAsync.test.d.ts +0 -2
  24. package/dist/createAsync.test.d.ts.map +0 -1
  25. package/dist/createAsync.test.js +0 -110
  26. package/dist/createAsyncState.d.ts +0 -16
  27. package/dist/createAsyncState.d.ts.map +0 -1
  28. package/dist/createAsyncState.js +0 -24
  29. package/dist/createContext.test.d.ts +0 -2
  30. package/dist/createContext.test.d.ts.map +0 -1
  31. package/dist/createContext.test.js +0 -136
  32. package/dist/createMutation.test.d.ts +0 -2
  33. package/dist/createMutation.test.d.ts.map +0 -1
  34. package/dist/createMutation.test.js +0 -168
  35. package/dist/createQuery.test.d.ts +0 -2
  36. package/dist/createQuery.test.d.ts.map +0 -1
  37. package/dist/createQuery.test.js +0 -156
  38. package/dist/createRef.test.d.ts +0 -2
  39. package/dist/createRef.test.d.ts.map +0 -1
  40. package/dist/createRef.test.js +0 -80
  41. package/dist/createState.test.d.ts +0 -2
  42. package/dist/createState.test.d.ts.map +0 -1
  43. package/dist/createState.test.js +0 -111
  44. package/dist/createView.test.d.ts +0 -2
  45. package/dist/createView.test.d.ts.map +0 -1
  46. package/dist/createView.test.js +0 -203
  47. package/dist/error.test.d.ts +0 -2
  48. package/dist/error.test.d.ts.map +0 -1
  49. package/dist/error.test.js +0 -144
  50. package/dist/integration.test.d.ts +0 -2
  51. package/dist/integration.test.d.ts.map +0 -1
  52. package/dist/integration.test.js +0 -155
  53. package/dist/jsx.d.ts.map +0 -1
  54. package/dist/jsx.js +0 -42
  55. package/dist/observation.test.d.ts +0 -2
  56. package/dist/observation.test.d.ts.map +0 -1
  57. package/dist/observation.test.js +0 -113
  58. package/dist/render-test.d.ts +0 -2
  59. package/dist/render-test.d.ts.map +0 -1
  60. package/dist/render-test.js +0 -21
  61. package/dist/render.d.ts +0 -7
  62. package/dist/render.d.ts.map +0 -1
  63. package/dist/render.js +0 -77
  64. package/dist/suspense.d.ts +0 -25
  65. package/dist/suspense.d.ts.map +0 -1
  66. package/dist/suspense.js +0 -97
  67. package/dist/tests/class.test.d.ts +0 -2
  68. package/dist/tests/class.test.d.ts.map +0 -1
  69. package/dist/tests/class.test.js +0 -185
  70. package/dist/tests/complex-rendering.test.d.ts +0 -2
  71. package/dist/tests/complex-rendering.test.d.ts.map +0 -1
  72. package/dist/tests/complex-rendering.test.js +0 -400
  73. package/dist/tests/component.cleanup.test.d.ts +0 -2
  74. package/dist/tests/component.cleanup.test.d.ts.map +0 -1
  75. package/dist/tests/component.cleanup.test.js +0 -325
  76. package/dist/tests/component.counter.test.d.ts +0 -2
  77. package/dist/tests/component.counter.test.d.ts.map +0 -1
  78. package/dist/tests/component.counter.test.js +0 -124
  79. package/dist/tests/component.interaction.test.d.ts +0 -2
  80. package/dist/tests/component.interaction.test.d.ts.map +0 -1
  81. package/dist/tests/component.interaction.test.js +0 -73
  82. package/dist/tests/component.props.test.d.ts +0 -2
  83. package/dist/tests/component.props.test.d.ts.map +0 -1
  84. package/dist/tests/component.props.test.js +0 -334
  85. package/dist/tests/component.return-types.test.d.ts +0 -2
  86. package/dist/tests/component.return-types.test.d.ts.map +0 -1
  87. package/dist/tests/component.return-types.test.js +0 -357
  88. package/dist/tests/component.state.test.d.ts +0 -2
  89. package/dist/tests/component.state.test.d.ts.map +0 -1
  90. package/dist/tests/component.state.test.js +0 -135
  91. package/dist/tests/component.test.d.ts +0 -2
  92. package/dist/tests/component.test.d.ts.map +0 -1
  93. package/dist/tests/component.test.js +0 -63
  94. package/dist/tests/createAsync.test.d.ts +0 -2
  95. package/dist/tests/createAsync.test.d.ts.map +0 -1
  96. package/dist/tests/createAsync.test.js +0 -110
  97. package/dist/tests/createContext.test.d.ts +0 -2
  98. package/dist/tests/createContext.test.d.ts.map +0 -1
  99. package/dist/tests/createContext.test.js +0 -141
  100. package/dist/tests/createMutation.test.d.ts +0 -2
  101. package/dist/tests/createMutation.test.d.ts.map +0 -1
  102. package/dist/tests/createMutation.test.js +0 -168
  103. package/dist/tests/createQuery.test.d.ts +0 -2
  104. package/dist/tests/createQuery.test.d.ts.map +0 -1
  105. package/dist/tests/createQuery.test.js +0 -156
  106. package/dist/tests/createRef.test.d.ts +0 -2
  107. package/dist/tests/createRef.test.d.ts.map +0 -1
  108. package/dist/tests/createRef.test.js +0 -84
  109. package/dist/tests/createState.test.d.ts +0 -2
  110. package/dist/tests/createState.test.d.ts.map +0 -1
  111. package/dist/tests/createState.test.js +0 -103
  112. package/dist/tests/createView.test.d.ts +0 -2
  113. package/dist/tests/createView.test.d.ts.map +0 -1
  114. package/dist/tests/createView.test.js +0 -203
  115. package/dist/tests/edge-cases.test.d.ts +0 -2
  116. package/dist/tests/edge-cases.test.d.ts.map +0 -1
  117. package/dist/tests/edge-cases.test.js +0 -637
  118. package/dist/tests/error-no-boundary.test.d.ts +0 -2
  119. package/dist/tests/error-no-boundary.test.d.ts.map +0 -1
  120. package/dist/tests/error-no-boundary.test.js +0 -174
  121. package/dist/tests/error.test.d.ts +0 -2
  122. package/dist/tests/error.test.d.ts.map +0 -1
  123. package/dist/tests/error.test.js +0 -199
  124. package/dist/tests/fragment.test.d.ts +0 -2
  125. package/dist/tests/fragment.test.d.ts.map +0 -1
  126. package/dist/tests/fragment.test.js +0 -618
  127. package/dist/tests/integration.test.d.ts +0 -2
  128. package/dist/tests/integration.test.d.ts.map +0 -1
  129. package/dist/tests/integration.test.js +0 -192
  130. package/dist/tests/keys.test.d.ts +0 -2
  131. package/dist/tests/keys.test.d.ts.map +0 -1
  132. package/dist/tests/keys.test.js +0 -293
  133. package/dist/tests/mount.test.d.ts +0 -2
  134. package/dist/tests/mount.test.d.ts.map +0 -1
  135. package/dist/tests/mount.test.js +0 -91
  136. package/dist/tests/observation.test.d.ts +0 -2
  137. package/dist/tests/observation.test.d.ts.map +0 -1
  138. package/dist/tests/observation.test.js +0 -113
  139. package/dist/tests/patch.test.d.ts +0 -2
  140. package/dist/tests/patch.test.d.ts.map +0 -1
  141. package/dist/tests/patch.test.js +0 -498
  142. package/dist/tests/patchChildren.test.d.ts +0 -2
  143. package/dist/tests/patchChildren.test.d.ts.map +0 -1
  144. package/dist/tests/patchChildren.test.js +0 -387
  145. package/dist/tests/primitives.test.d.ts +0 -2
  146. package/dist/tests/primitives.test.d.ts.map +0 -1
  147. package/dist/tests/primitives.test.js +0 -132
  148. package/dist/vdom/class.test.d.ts +0 -2
  149. package/dist/vdom/class.test.d.ts.map +0 -1
  150. package/dist/vdom/class.test.js +0 -143
  151. package/dist/vdom/complex-rendering.test.d.ts +0 -2
  152. package/dist/vdom/complex-rendering.test.d.ts.map +0 -1
  153. package/dist/vdom/complex-rendering.test.js +0 -400
  154. package/dist/vdom/component.cleanup.test.d.ts +0 -2
  155. package/dist/vdom/component.cleanup.test.d.ts.map +0 -1
  156. package/dist/vdom/component.cleanup.test.js +0 -323
  157. package/dist/vdom/component.counter.test.d.ts +0 -2
  158. package/dist/vdom/component.counter.test.d.ts.map +0 -1
  159. package/dist/vdom/component.counter.test.js +0 -124
  160. package/dist/vdom/component.interaction.test.d.ts +0 -2
  161. package/dist/vdom/component.interaction.test.d.ts.map +0 -1
  162. package/dist/vdom/component.interaction.test.js +0 -73
  163. package/dist/vdom/component.props.test.d.ts +0 -2
  164. package/dist/vdom/component.props.test.d.ts.map +0 -1
  165. package/dist/vdom/component.props.test.js +0 -88
  166. package/dist/vdom/component.return-types.test.d.ts +0 -2
  167. package/dist/vdom/component.return-types.test.d.ts.map +0 -1
  168. package/dist/vdom/component.return-types.test.js +0 -357
  169. package/dist/vdom/component.state.test.d.ts +0 -2
  170. package/dist/vdom/component.state.test.d.ts.map +0 -1
  171. package/dist/vdom/component.state.test.js +0 -129
  172. package/dist/vdom/component.test.d.ts +0 -2
  173. package/dist/vdom/component.test.d.ts.map +0 -1
  174. package/dist/vdom/component.test.js +0 -63
  175. package/dist/vdom/edge-cases.test.d.ts +0 -2
  176. package/dist/vdom/edge-cases.test.d.ts.map +0 -1
  177. package/dist/vdom/edge-cases.test.js +0 -637
  178. package/dist/vdom/fragment.test.d.ts +0 -2
  179. package/dist/vdom/fragment.test.d.ts.map +0 -1
  180. package/dist/vdom/fragment.test.js +0 -618
  181. package/dist/vdom/keys.test.d.ts +0 -2
  182. package/dist/vdom/keys.test.d.ts.map +0 -1
  183. package/dist/vdom/keys.test.js +0 -293
  184. package/dist/vdom/mount.test.d.ts +0 -2
  185. package/dist/vdom/mount.test.d.ts.map +0 -1
  186. package/dist/vdom/mount.test.js +0 -91
  187. package/dist/vdom/patch.test.d.ts +0 -2
  188. package/dist/vdom/patch.test.d.ts.map +0 -1
  189. package/dist/vdom/patch.test.js +0 -498
  190. package/dist/vdom/patchChildren.test.d.ts +0 -2
  191. package/dist/vdom/patchChildren.test.d.ts.map +0 -1
  192. package/dist/vdom/patchChildren.test.js +0 -392
  193. package/dist/vdom/primitives.test.d.ts +0 -2
  194. package/dist/vdom/primitives.test.d.ts.map +0 -1
  195. package/dist/vdom/primitives.test.js +0 -132
@@ -1,498 +0,0 @@
1
- import { describe, it, expect, vi } from "vitest";
2
- import { jsx, render } from "./index";
3
- import { createState } from "../createState";
4
- describe("VDOM Patch", () => {
5
- it("should patch a div element with a span element", async () => {
6
- const container = document.createElement("div");
7
- let stateFn;
8
- const App = () => {
9
- const state = createState({ useSpan: false });
10
- stateFn = state;
11
- return () => state.useSpan
12
- ? jsx("span", { id: "patched" })
13
- : jsx("div", { id: "initial" });
14
- };
15
- render(jsx(App, {}), container);
16
- // Verify initial render
17
- expect(container.children.length).toBe(1);
18
- expect(container.children[0].tagName).toBe("DIV");
19
- // Trigger patch by changing state
20
- stateFn.useSpan = true;
21
- await new Promise((resolve) => setTimeout(resolve, 0));
22
- // Verify the element was replaced
23
- expect(container.children.length).toBe(1);
24
- expect(container.children[0].tagName).toBe("SPAN");
25
- });
26
- it("should patch element by adding children", async () => {
27
- const container = document.createElement("div");
28
- let stateFn;
29
- const App = () => {
30
- const state = createState({ hasChildren: false });
31
- stateFn = state;
32
- return () => state.hasChildren
33
- ? jsx("div", {
34
- id: "parent",
35
- children: [
36
- jsx("span", { id: "child1" }),
37
- jsx("div", { id: "child2" }),
38
- ],
39
- })
40
- : jsx("div", { id: "parent" });
41
- };
42
- render(jsx(App, {}), container);
43
- // Verify initial state (no children)
44
- const parent = container.children[0];
45
- expect(parent.children.length).toBe(0);
46
- // Trigger patch to add children
47
- stateFn.hasChildren = true;
48
- await new Promise((resolve) => setTimeout(resolve, 0));
49
- // Verify children were added
50
- expect(parent.children.length).toBe(2);
51
- expect(parent.children[0].tagName).toBe("SPAN");
52
- expect(parent.children[1].tagName).toBe("DIV");
53
- });
54
- it("should patch element by removing children", async () => {
55
- const container = document.createElement("div");
56
- let stateFn;
57
- const App = () => {
58
- const state = createState({ hasChildren: true });
59
- stateFn = state;
60
- return () => state.hasChildren
61
- ? jsx("div", {
62
- id: "parent",
63
- children: [
64
- jsx("span", { id: "child1" }),
65
- jsx("div", { id: "child2" }),
66
- jsx("span", { id: "child3" }),
67
- ],
68
- })
69
- : jsx("div", { id: "parent" });
70
- };
71
- render(jsx(App, {}), container);
72
- // Verify initial state (3 children)
73
- const parent = container.children[0];
74
- expect(parent.children.length).toBe(3);
75
- // Trigger patch to remove children
76
- stateFn.hasChildren = false;
77
- await new Promise((resolve) => setTimeout(resolve, 0));
78
- // Verify children were removed
79
- expect(parent.children.length).toBe(0);
80
- });
81
- it("should patch element by changing child types", async () => {
82
- const container = document.createElement("div");
83
- let stateFn;
84
- const App = () => {
85
- const state = createState({ version: 1 });
86
- stateFn = state;
87
- return () => state.version === 1
88
- ? jsx("div", {
89
- id: "parent",
90
- children: [
91
- jsx("span", { id: "child1" }),
92
- jsx("span", { id: "child2" }),
93
- ],
94
- })
95
- : jsx("div", {
96
- id: "parent",
97
- children: [
98
- jsx("div", { id: "child1" }),
99
- jsx("button", { id: "child2" }),
100
- ],
101
- });
102
- };
103
- render(jsx(App, {}), container);
104
- // Verify initial state (2 span children)
105
- const parent = container.children[0];
106
- expect(parent.children.length).toBe(2);
107
- expect(parent.children[0].tagName).toBe("SPAN");
108
- expect(parent.children[1].tagName).toBe("SPAN");
109
- // Trigger patch to change child types
110
- stateFn.version = 2;
111
- await new Promise((resolve) => setTimeout(resolve, 0));
112
- // Verify children types were changed
113
- expect(parent.children.length).toBe(2);
114
- expect(parent.children[0].tagName).toBe("DIV");
115
- expect(parent.children[1].tagName).toBe("BUTTON");
116
- });
117
- it("should patch element by adding data/aria attributes", async () => {
118
- const container = document.createElement("div");
119
- let stateFn;
120
- const App = () => {
121
- const state = createState({ hasAttributes: false });
122
- stateFn = state;
123
- return () => state.hasAttributes
124
- ? jsx("div", {
125
- "data-testid": "test-component",
126
- "aria-label": "Test element",
127
- })
128
- : jsx("div", {});
129
- };
130
- render(jsx(App, {}), container);
131
- const div = container.children[0];
132
- // Verify no attributes initially
133
- expect(div.getAttribute("data-testid")).toBeNull();
134
- expect(div.getAttribute("aria-label")).toBeNull();
135
- // Trigger patch to add attributes
136
- stateFn.hasAttributes = true;
137
- await new Promise((resolve) => setTimeout(resolve, 0));
138
- // Verify attributes were added
139
- expect(div.getAttribute("data-testid")).toBe("test-component");
140
- expect(div.getAttribute("aria-label")).toBe("Test element");
141
- });
142
- it("should patch element by removing data/aria attributes", async () => {
143
- const container = document.createElement("div");
144
- let stateFn;
145
- const App = () => {
146
- const state = createState({ hasAttributes: true });
147
- stateFn = state;
148
- return () => state.hasAttributes
149
- ? jsx("div", {
150
- "data-testid": "test-component",
151
- "data-value": "123",
152
- "aria-label": "Test element",
153
- })
154
- : jsx("div", {});
155
- };
156
- render(jsx(App, {}), container);
157
- const div = container.children[0];
158
- // Verify attributes exist
159
- expect(div.getAttribute("data-testid")).toBe("test-component");
160
- expect(div.getAttribute("data-value")).toBe("123");
161
- expect(div.getAttribute("aria-label")).toBe("Test element");
162
- // Trigger patch to remove attributes
163
- stateFn.hasAttributes = false;
164
- await new Promise((resolve) => setTimeout(resolve, 0));
165
- // Verify attributes were removed
166
- expect(div.getAttribute("data-testid")).toBeNull();
167
- expect(div.getAttribute("data-value")).toBeNull();
168
- expect(div.getAttribute("aria-label")).toBeNull();
169
- });
170
- it("should patch element by updating data/aria attributes", async () => {
171
- const container = document.createElement("div");
172
- let stateFn;
173
- const App = () => {
174
- const state = createState({ version: 1 });
175
- stateFn = state;
176
- return () => state.version === 1
177
- ? jsx("div", {
178
- "data-testid": "old-id",
179
- "data-value": "old-value",
180
- "aria-label": "Old label",
181
- })
182
- : jsx("div", {
183
- "data-testid": "new-id",
184
- "data-value": "new-value",
185
- "aria-label": "New label",
186
- });
187
- };
188
- render(jsx(App, {}), container);
189
- const div = container.children[0];
190
- // Verify initial attributes
191
- expect(div.getAttribute("data-testid")).toBe("old-id");
192
- expect(div.getAttribute("data-value")).toBe("old-value");
193
- expect(div.getAttribute("aria-label")).toBe("Old label");
194
- // Trigger patch to update attributes
195
- stateFn.version = 2;
196
- await new Promise((resolve) => setTimeout(resolve, 0));
197
- // Verify attributes were updated
198
- expect(div.getAttribute("data-testid")).toBe("new-id");
199
- expect(div.getAttribute("data-value")).toBe("new-value");
200
- expect(div.getAttribute("aria-label")).toBe("New label");
201
- });
202
- it("should patch element by updating event listeners", async () => {
203
- const container = document.createElement("div");
204
- let stateFn;
205
- const oldHandler = vi.fn();
206
- const newHandler = vi.fn();
207
- const App = () => {
208
- const state = createState({ version: 1 });
209
- stateFn = state;
210
- return () => jsx("button", {
211
- onClick: state.version === 1 ? oldHandler : newHandler,
212
- });
213
- };
214
- render(jsx(App, {}), container);
215
- const button = container.children[0];
216
- // Trigger click to verify old handler works
217
- button.click();
218
- expect(oldHandler).toHaveBeenCalledTimes(1);
219
- expect(newHandler).toHaveBeenCalledTimes(0);
220
- // Trigger patch to update event listener
221
- stateFn.version = 2;
222
- await new Promise((resolve) => setTimeout(resolve, 0));
223
- // Trigger click again
224
- button.click();
225
- // Verify old handler was not called again and new handler was called
226
- expect(oldHandler).toHaveBeenCalledTimes(1);
227
- expect(newHandler).toHaveBeenCalledTimes(1);
228
- });
229
- it("should patch complex nested UI structure", async () => {
230
- const container = document.createElement("div");
231
- let stateFn;
232
- const App = () => {
233
- const state = createState({ version: 1 });
234
- stateFn = state;
235
- return () => state.version === 1
236
- ? jsx("div", {
237
- className: "app",
238
- children: [
239
- jsx("header", {
240
- className: "header",
241
- children: [
242
- jsx("h1", { children: ["Title"] }),
243
- jsx("nav", {
244
- children: [
245
- jsx("a", { href: "#home", children: ["Home"] }),
246
- jsx("a", { href: "#about", children: ["About"] }),
247
- ],
248
- }),
249
- ],
250
- }),
251
- jsx("main", {
252
- className: "content",
253
- children: [
254
- jsx("p", { children: ["Paragraph 1"] }),
255
- jsx("p", { children: ["Paragraph 2"] }),
256
- ],
257
- }),
258
- ],
259
- })
260
- : jsx("div", {
261
- className: "app-updated",
262
- children: [
263
- jsx("header", {
264
- className: "header-updated",
265
- children: [
266
- jsx("h1", { children: ["New Title"] }),
267
- jsx("nav", {
268
- children: [
269
- jsx("a", { href: "#home", children: ["Home"] }),
270
- jsx("a", { href: "#about", children: ["About"] }),
271
- jsx("a", { href: "#contact", children: ["Contact"] }),
272
- ],
273
- }),
274
- ],
275
- }),
276
- jsx("main", {
277
- className: "content",
278
- children: [
279
- jsx("p", { children: ["Updated Paragraph 1"] }),
280
- jsx("div", { children: ["New div element"] }),
281
- jsx("p", { children: ["Paragraph 3"] }),
282
- ],
283
- }),
284
- ],
285
- });
286
- };
287
- render(jsx(App, {}), container);
288
- const app = container.children[0];
289
- // Verify initial structure
290
- expect(app.children.length).toBe(2);
291
- expect(app.children[0].tagName).toBe("HEADER");
292
- expect(app.children[1].tagName).toBe("MAIN");
293
- const initialHeader = app.children[0];
294
- expect(initialHeader.children.length).toBe(2);
295
- expect(initialHeader.children[0].textContent).toBe("Title");
296
- const initialNav = initialHeader.children[1];
297
- expect(initialNav.children.length).toBe(2);
298
- const initialMain = app.children[1];
299
- expect(initialMain.children.length).toBe(2);
300
- // Trigger patch
301
- stateFn.version = 2;
302
- await new Promise((resolve) => setTimeout(resolve, 0));
303
- // Verify patched structure
304
- expect(app.className).toBe("app-updated");
305
- expect(app.children.length).toBe(2);
306
- const patchedHeader = app.children[0];
307
- expect(patchedHeader.className).toBe("header-updated");
308
- expect(patchedHeader.children[0].textContent).toBe("New Title");
309
- const patchedNav = patchedHeader.children[1];
310
- expect(patchedNav.children.length).toBe(3);
311
- expect(patchedNav.children[2].textContent).toBe("Contact");
312
- const patchedMain = app.children[1];
313
- expect(patchedMain.children.length).toBe(3);
314
- expect(patchedMain.children[0].textContent).toBe("Updated Paragraph 1");
315
- expect(patchedMain.children[1].tagName).toBe("DIV");
316
- expect(patchedMain.children[2].textContent).toBe("Paragraph 3");
317
- });
318
- it("should patch nested elements independently", async () => {
319
- const container = document.createElement("div");
320
- let stateFn;
321
- const App = () => {
322
- const state = createState({ sidebarVersion: 1, contentVersion: 1 });
323
- stateFn = state;
324
- return () => jsx("div", {
325
- className: "layout",
326
- children: [
327
- state.sidebarVersion === 1
328
- ? jsx("aside", {
329
- className: "sidebar",
330
- children: [
331
- jsx("div", { className: "widget", children: ["Widget 1"] }),
332
- jsx("div", { className: "widget", children: ["Widget 2"] }),
333
- ],
334
- })
335
- : jsx("aside", {
336
- className: "sidebar-updated",
337
- children: [
338
- jsx("div", {
339
- className: "widget",
340
- children: ["Widget 1 Updated"],
341
- }),
342
- jsx("div", { className: "widget", children: ["Widget 2"] }),
343
- jsx("div", { className: "widget", children: ["Widget 3"] }),
344
- ],
345
- }),
346
- state.contentVersion === 1
347
- ? jsx("main", {
348
- children: [
349
- jsx("article", {
350
- children: [
351
- jsx("h2", { children: ["Article Title"] }),
352
- jsx("p", { children: ["Article content"] }),
353
- ],
354
- }),
355
- ],
356
- })
357
- : jsx("main", {
358
- children: [
359
- jsx("article", {
360
- children: [
361
- jsx("h2", { children: ["Updated Article Title"] }),
362
- jsx("p", { children: ["Updated article content"] }),
363
- jsx("footer", { children: ["Article footer"] }),
364
- ],
365
- }),
366
- ],
367
- }),
368
- ],
369
- });
370
- };
371
- render(jsx(App, {}), container);
372
- const layout = container.children[0];
373
- const initialSidebar = layout.children[0];
374
- const initialMain = layout.children[1];
375
- // First patch: Update only the sidebar
376
- stateFn.sidebarVersion = 2;
377
- await new Promise((resolve) => setTimeout(resolve, 0));
378
- // Verify only sidebar changed
379
- expect(initialSidebar.className).toBe("sidebar-updated");
380
- expect(initialSidebar.children.length).toBe(3);
381
- expect(initialSidebar.children[0].textContent).toBe("Widget 1 Updated");
382
- expect(initialSidebar.children[2].textContent).toBe("Widget 3");
383
- // Main content should be unchanged
384
- const article = initialMain.children[0];
385
- expect(article.children[0].textContent).toBe("Article Title");
386
- expect(article.children[1].textContent).toBe("Article content");
387
- // Second patch: Update only the content
388
- stateFn.contentVersion = 2;
389
- await new Promise((resolve) => setTimeout(resolve, 0));
390
- // Sidebar should remain from first patch
391
- expect(initialSidebar.className).toBe("sidebar-updated");
392
- expect(initialSidebar.children.length).toBe(3);
393
- // Main content should now be updated
394
- const updatedArticle = initialMain.children[0];
395
- expect(updatedArticle.children.length).toBe(3);
396
- expect(updatedArticle.children[0].textContent).toBe("Updated Article Title");
397
- expect(updatedArticle.children[1].textContent).toBe("Updated article content");
398
- expect(updatedArticle.children[2].tagName).toBe("FOOTER");
399
- });
400
- it("should handle multiple sequential patches", async () => {
401
- const container = document.createElement("div");
402
- let stateFn;
403
- const App = () => {
404
- const state = createState({ count: 0 });
405
- stateFn = state;
406
- return () => jsx("div", {
407
- className: "counter",
408
- children: [
409
- jsx("span", { children: [`Count: ${state.count}`] }),
410
- jsx("button", {
411
- children: [state.count < 3 ? "Increment" : "Reset"],
412
- }),
413
- ],
414
- });
415
- };
416
- render(jsx(App, {}), container);
417
- const counterDiv = container.children[0];
418
- // Verify initial state
419
- expect(counterDiv.children[0].textContent).toBe("Count: 0");
420
- // Patch 1: Update count to 1
421
- stateFn.count = 1;
422
- await new Promise((resolve) => setTimeout(resolve, 0));
423
- expect(counterDiv.children[0].textContent).toBe("Count: 1");
424
- // Patch 2: Update count to 2
425
- stateFn.count = 2;
426
- await new Promise((resolve) => setTimeout(resolve, 0));
427
- expect(counterDiv.children[0].textContent).toBe("Count: 2");
428
- // Patch 3: Update count to 3 and change button text
429
- stateFn.count = 3;
430
- await new Promise((resolve) => setTimeout(resolve, 0));
431
- expect(counterDiv.children[0].textContent).toBe("Count: 3");
432
- expect(counterDiv.children[1].textContent).toBe("Reset");
433
- // Patch 4: Reset to 0 and add a new element
434
- stateFn.count = 0;
435
- await new Promise((resolve) => setTimeout(resolve, 0));
436
- expect(counterDiv.children[0].textContent).toBe("Count: 0");
437
- expect(counterDiv.children[1].textContent).toBe("Increment");
438
- });
439
- it("should patch deeply nested child independently", async () => {
440
- const container = document.createElement("div");
441
- let stateFn;
442
- const App = () => {
443
- const state = createState({ version: 1 });
444
- stateFn = state;
445
- return () => jsx("div", {
446
- className: "root",
447
- children: [
448
- jsx("div", {
449
- className: "level-1",
450
- children: [
451
- jsx("div", {
452
- className: "level-2",
453
- children: [
454
- jsx("div", {
455
- className: "level-3",
456
- children: [
457
- jsx("span", {
458
- children: [
459
- state.version === 1
460
- ? "Deep content"
461
- : "Updated deep content",
462
- ],
463
- id: state.version === 1 ? "target" : "target-updated",
464
- }),
465
- ],
466
- }),
467
- jsx("div", { children: ["Sibling at level-3"] }),
468
- ],
469
- }),
470
- jsx("div", { children: ["Sibling at level-2"] }),
471
- ],
472
- }),
473
- jsx("div", { children: ["Sibling at level-1"] }),
474
- ],
475
- });
476
- };
477
- render(jsx(App, {}), container);
478
- const root = container.children[0];
479
- // Navigate to the deep element
480
- const level1 = root.children[0];
481
- const level2 = level1.children[0];
482
- const level3 = level2.children[0];
483
- const targetSpan = level3.children[0];
484
- // Verify initial state
485
- expect(targetSpan.textContent).toBe("Deep content");
486
- expect(targetSpan.id).toBe("target");
487
- // Trigger patch
488
- stateFn.version = 2;
489
- await new Promise((resolve) => setTimeout(resolve, 0));
490
- // Verify the deep element was updated
491
- expect(targetSpan.textContent).toBe("Updated deep content");
492
- expect(targetSpan.id).toBe("target-updated");
493
- // Verify siblings remained unchanged
494
- expect(level2.children[1].textContent).toBe("Sibling at level-3");
495
- expect(level1.children[1].textContent).toBe("Sibling at level-2");
496
- expect(root.children[1].textContent).toBe("Sibling at level-1");
497
- });
498
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=patchChildren.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"patchChildren.test.d.ts","sourceRoot":"","sources":["../../src/vdom/patchChildren.test.ts"],"names":[],"mappings":""}