@unsetsoft/ryunixjs 1.0.3-nightly.9 → 1.1.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.
package/dist/Ryunix.js CHANGED
@@ -79,10 +79,16 @@
79
79
 
80
80
  const createElement = (type, props, ...children) => {
81
81
  children = childArray(children, []);
82
+ const key =
83
+ props && props.key
84
+ ? props.key
85
+ : `${type}-${Math.random().toString(36).substring(2, 9)}`;
86
+
82
87
  return {
83
88
  type,
84
89
  props: {
85
90
  ...props,
91
+ key,
86
92
  children: children.map((child) =>
87
93
  typeof child === STRINGS.object ? child : createTextElement(child),
88
94
  ),
@@ -108,11 +114,12 @@
108
114
  };
109
115
 
110
116
  /**
111
- * The function renders an element into a container using a work-in-progress root.
112
- * @param element - The element parameter is the component or element that needs to be rendered in the
113
- * container. It could be a Ryunix component or a DOM element.
114
- * @param container - The container parameter is the DOM element where the rendered element will be
115
- * appended to. this parameter is optional if you use createRoot().
117
+ * Renders an element into a container using a work-in-progress (WIP) root.
118
+ * @function render
119
+ * @param {Object|HTMLElement} element - The element to be rendered in the container. It can be a Ryunix component (custom element) or a standard DOM element.
120
+ * @param {HTMLElement} container - The container where the element will be rendered. This parameter is optional if `createRoot()` is used beforehand to set up the container.
121
+ * @description The function assigns the `container` to a work-in-progress root and sets up properties for reconciliation, including children and the reference to the current root.
122
+ * It also clears any scheduled deletions and establishes the next unit of work for incremental rendering.
116
123
  */
117
124
  const render = (element, container) => {
118
125
  vars.wipRoot = {
@@ -122,20 +129,24 @@
122
129
  },
123
130
  alternate: vars.currentRoot,
124
131
  };
132
+
125
133
  vars.deletions = [];
126
134
  vars.nextUnitOfWork = vars.wipRoot;
127
135
  };
128
136
 
129
137
  /**
130
- * @description The function creates a reference to a DOM element with the specified ID. This will be used to initialize the app.
131
- * @example Ryunix.init("root") -> <div id="root" />
132
- * @param root - The parameter "root" is the id of the HTML element that will serve as the container
133
- * for the root element.
138
+ * Initializes the application by creating a reference to a DOM element with the specified ID and rendering the main component.
139
+ * @function init
140
+ * @param {Object} MainElement - The main component to render, typically the root component of the application.
141
+ * @param {string} [root='__ryunix'] - The ID of the HTML element that serves as the container for the root element. Defaults to `'__ryunix'` if not provided.
142
+ * @example
143
+ * Ryunix.init(App, "__ryunix"); // Initializes and renders the App component into the <div id="__ryunix"></div> element.
144
+ * @description This function retrieves the container element by its ID and invokes the `render` function to render the main component into it.
134
145
  */
135
- const init = (root) => {
136
- const rootElement = root || '__ryunix';
137
- vars.containerRoot = document.getElementById(rootElement);
138
- return undefined
146
+ const init = (MainElement, root = '__ryunix') => {
147
+ vars.containerRoot = document.getElementById(root);
148
+
149
+ render(MainElement, vars.containerRoot);
139
150
  };
140
151
 
141
152
  /**
@@ -151,24 +162,19 @@
151
162
  vars.wipFiber.alternate.hooks[vars.hookIndex];
152
163
  const hook = {
153
164
  state: oldHook ? oldHook.state : initial,
154
- queue: [],
165
+ queue: oldHook ? [...oldHook.queue] : [],
155
166
  };
156
167
 
157
- const actions = oldHook ? oldHook.queue : [];
158
- actions.forEach((action) => {
168
+ hook.queue.forEach((action) => {
159
169
  hook.state =
160
170
  typeof action === STRINGS.function ? action(hook.state) : action;
161
171
  });
162
172
 
163
- /**
164
- * The function `setState` updates the state of a component in Ryunix by adding an action to a queue
165
- * and setting up a new work-in-progress root.
166
- * @param action - The `action` parameter is an object that represents a state update to be performed
167
- * on a component. It contains information about the type of update to be performed and any new data
168
- * that needs to be applied to the component's state.
169
- */
173
+ hook.queue = [];
174
+
170
175
  const setState = (action) => {
171
176
  hook.queue.push(action);
177
+
172
178
  vars.wipRoot = {
173
179
  dom: vars.currentRoot.dom,
174
180
  props: vars.currentRoot.props,
@@ -182,6 +188,7 @@
182
188
  vars.wipFiber.hooks.push(hook);
183
189
  vars.hookIndex++;
184
190
  }
191
+
185
192
  return [hook.state, setState]
186
193
  };
187
194
 
@@ -221,6 +228,36 @@
221
228
  }
222
229
  };
223
230
 
231
+ /**
232
+ * The `useQuery` function is a custom hook in JavaScript that retrieves query parameters from the URL
233
+ * and stores them in a hook for easy access.
234
+ * @returns The `useQuery` function returns the `query` property of the `hook` object.
235
+ */
236
+ const useQuery = () => {
237
+ const oldHook =
238
+ vars.wipFiber.alternate &&
239
+ vars.wipFiber.alternate.hooks &&
240
+ vars.wipFiber.alternate.hooks[vars.hookIndex];
241
+
242
+ const hasOld = oldHook ? oldHook : undefined;
243
+
244
+ const urlSearchParams = new URLSearchParams(window.location.search);
245
+ const params = Object.fromEntries(urlSearchParams.entries());
246
+ const Query = hasOld ? hasOld : params;
247
+
248
+ const hook = {
249
+ type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
250
+ query: Query,
251
+ };
252
+
253
+ if (vars.wipFiber.hooks) {
254
+ vars.wipFiber.hooks.push(hook);
255
+ vars.hookIndex++;
256
+ }
257
+
258
+ return hook.query
259
+ };
260
+
224
261
  const useRef = (initial) => {
225
262
  const oldHook =
226
263
  vars.wipFiber.alternate &&
@@ -292,40 +329,31 @@
292
329
  }
293
330
  }, []);
294
331
 
295
- const currentRoute = routes.find((route) => route.path === location);
296
- const Children = () => (currentRoute ? currentRoute.component : null);
297
-
298
- return { Children, navigate }
299
- };
300
-
301
- /**
302
- * The `useQuery` function is a custom hook in JavaScript that retrieves query parameters from the URL
303
- * and stores them in a hook for easy access.
304
- * @returns The `useQuery` function returns the `query` property of the `hook` object.
305
- */
306
- const useQuery = () => {
307
- const oldHook =
308
- vars.wipFiber.alternate &&
309
- vars.wipFiber.alternate.hooks &&
310
- vars.wipFiber.alternate.hooks[vars.hookIndex];
332
+ let currentRoute = routes.find((route) => route.path === location);
333
+ if (!currentRoute) {
334
+ currentRoute = {
335
+ component: routes.find((route) => route.NotFound)?.NotFound || null,
336
+ };
337
+ }
311
338
 
312
- const hasOld = oldHook ? oldHook : undefined;
339
+ const Children = () =>
340
+ currentRoute.component ? currentRoute.component : null;
313
341
 
314
- const urlSearchParams = new URLSearchParams(window.location.search);
315
- const params = Object.fromEntries(urlSearchParams.entries());
316
- const Query = hasOld ? hasOld : params;
342
+ const NavLink = ({ to, ...props }) => {
343
+ const { children, ...restProps } = props;
317
344
 
318
- const hook = {
319
- type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
320
- query: Query,
345
+ const NewProps = {
346
+ href: to,
347
+ onClick: (e) => {
348
+ e.preventDefault();
349
+ navigate(to);
350
+ },
351
+ ...restProps,
352
+ };
353
+ return createElement('a', NewProps, children)
321
354
  };
322
355
 
323
- if (vars.wipFiber.hooks) {
324
- vars.wipFiber.hooks.push(hook);
325
- vars.hookIndex++;
326
- }
327
-
328
- return hook.query
356
+ return { Children, navigate, NavLink }
329
357
  };
330
358
 
331
359
  const isEvent = (key) => key.startsWith('on');
@@ -486,9 +514,7 @@
486
514
  * @returns The function does not return anything, it performs side effects by manipulating the DOM.
487
515
  */
488
516
  const commitWork = (fiber) => {
489
- if (!fiber) {
490
- return
491
- }
517
+ if (!fiber) return
492
518
 
493
519
  let domParentFiber = fiber.parent;
494
520
  while (!domParentFiber.dom) {
@@ -501,15 +527,19 @@
501
527
  domParent.appendChild(fiber.dom);
502
528
  }
503
529
  runEffects(fiber);
504
- } else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
530
+ }
531
+
532
+ if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
505
533
  cancelEffects(fiber);
506
534
  if (fiber.dom != undefined) {
507
535
  updateDom(fiber.dom, fiber.alternate.props, fiber.props);
508
536
  }
509
537
  runEffects(fiber);
510
- } else if (fiber.effectTag === EFFECT_TAGS.DELETION) {
511
- cancelEffects(fiber);
538
+ }
539
+
540
+ if (fiber.effectTag === EFFECT_TAGS.DELETION) {
512
541
  commitDeletion(fiber, domParent);
542
+ cancelEffects(fiber);
513
543
  return
514
544
  }
515
545
 
@@ -525,9 +555,9 @@
525
555
  * @param domParent - The parent DOM element from which the fiber's DOM element needs to be removed.
526
556
  */
527
557
  const commitDeletion = (fiber, domParent) => {
528
- if (fiber && fiber.dom) {
558
+ if (fiber.dom) {
529
559
  domParent.removeChild(fiber.dom);
530
- } else if (fiber && fiber.child) {
560
+ } else {
531
561
  commitDeletion(fiber.child, domParent);
532
562
  }
533
563
  };
@@ -539,20 +569,6 @@
539
569
  commitWork: commitWork
540
570
  });
541
571
 
542
- const isPropsChanged = (prevProps, nextProps) => {
543
- for (let key in prevProps) {
544
- if (prevProps[key] !== nextProps[key]) {
545
- return true
546
- }
547
- }
548
- for (let key in nextProps) {
549
- if (!(key in prevProps)) {
550
- return true
551
- }
552
- }
553
- return false
554
- };
555
-
556
572
  /**
557
573
  * This function reconciles the children of a fiber node with a new set of elements, creating new
558
574
  * fibers for new elements, updating existing fibers for elements with the same type, and marking old
@@ -565,24 +581,33 @@
565
581
  const reconcileChildren = (wipFiber, elements) => {
566
582
  let index = 0;
567
583
  let oldFiber = wipFiber.alternate && wipFiber.alternate.child;
568
- let prevSibling;
584
+ let prevSibling = null;
585
+
586
+ const oldFibersMap = new Map();
587
+ while (oldFiber) {
588
+ const oldKey = oldFiber.props.key || oldFiber.type;
589
+ oldFibersMap.set(oldKey, oldFiber);
590
+ oldFiber = oldFiber.sibling;
591
+ }
569
592
 
570
- while (index < elements.length || oldFiber != undefined) {
593
+ while (index < elements.length) {
571
594
  const element = elements[index];
595
+ const key = element.props.key || element.type;
596
+ const oldFiber = oldFibersMap.get(key);
597
+
572
598
  let newFiber;
573
- const sameType = oldFiber && element && element.type == oldFiber.type;
599
+ const sameType = oldFiber && element && element.type === oldFiber.type;
574
600
 
575
601
  if (sameType) {
576
602
  newFiber = {
577
- type: oldFiber ? oldFiber.type : undefined,
603
+ type: oldFiber.type,
578
604
  props: element.props,
579
- dom: oldFiber ? oldFiber.dom : undefined,
605
+ dom: oldFiber.dom,
580
606
  parent: wipFiber,
581
607
  alternate: oldFiber,
582
- effectTag: isPropsChanged(oldFiber.props, element.props)
583
- ? EFFECT_TAGS.UPDATE
584
- : null,
608
+ effectTag: EFFECT_TAGS.UPDATE,
585
609
  };
610
+ oldFibersMap.delete(key);
586
611
  } else if (element) {
587
612
  newFiber = {
588
613
  type: element.type,
@@ -592,18 +617,16 @@
592
617
  alternate: undefined,
593
618
  effectTag: EFFECT_TAGS.PLACEMENT,
594
619
  };
595
- } else if (oldFiber) {
596
- oldFiber.effectTag = EFFECT_TAGS.DELETION;
597
- vars.deletions.push(oldFiber);
598
620
  }
599
621
 
600
- if (oldFiber) {
601
- oldFiber = oldFiber.sibling;
602
- }
622
+ oldFibersMap.forEach((oldFiber) => {
623
+ oldFiber.effectTag = EFFECT_TAGS.DELETION;
624
+ vars.deletions.push(oldFiber);
625
+ });
603
626
 
604
627
  if (index === 0) {
605
628
  wipFiber.child = newFiber;
606
- } else if (element && prevSibling) {
629
+ } else if (prevSibling) {
607
630
  prevSibling.sibling = newFiber;
608
631
  }
609
632
 
@@ -678,9 +701,7 @@
678
701
  commitRoot();
679
702
  }
680
703
 
681
- if (vars.nextUnitOfWork) {
682
- requestIdleCallback(workLoop, { timeout: 100 });
683
- }
704
+ requestIdleCallback(workLoop);
684
705
  };
685
706
 
686
707
  requestIdleCallback(workLoop);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unsetsoft/ryunixjs",
3
- "version": "1.0.3-nightly.9",
3
+ "version": "1.1.1",
4
4
  "license": "MIT",
5
5
  "main": "./dist/Ryunix.js",
6
6
  "types": "./dist/Ryunix.d.ts",
@@ -22,9 +22,7 @@ const commitRoot = () => {
22
22
  * @returns The function does not return anything, it performs side effects by manipulating the DOM.
23
23
  */
24
24
  const commitWork = (fiber) => {
25
- if (!fiber) {
26
- return
27
- }
25
+ if (!fiber) return
28
26
 
29
27
  let domParentFiber = fiber.parent
30
28
  while (!domParentFiber.dom) {
@@ -37,15 +35,19 @@ const commitWork = (fiber) => {
37
35
  domParent.appendChild(fiber.dom)
38
36
  }
39
37
  runEffects(fiber)
40
- } else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
38
+ }
39
+
40
+ if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
41
41
  cancelEffects(fiber)
42
42
  if (fiber.dom != undefined) {
43
43
  updateDom(fiber.dom, fiber.alternate.props, fiber.props)
44
44
  }
45
45
  runEffects(fiber)
46
- } else if (fiber.effectTag === EFFECT_TAGS.DELETION) {
47
- cancelEffects(fiber)
46
+ }
47
+
48
+ if (fiber.effectTag === EFFECT_TAGS.DELETION) {
48
49
  commitDeletion(fiber, domParent)
50
+ cancelEffects(fiber)
49
51
  return
50
52
  }
51
53
 
@@ -61,11 +63,10 @@ const commitWork = (fiber) => {
61
63
  * @param domParent - The parent DOM element from which the fiber's DOM element needs to be removed.
62
64
  */
63
65
  const commitDeletion = (fiber, domParent) => {
64
- if (fiber && fiber.dom) {
66
+ if (fiber.dom) {
65
67
  domParent.removeChild(fiber.dom)
66
- } else if (fiber && fiber.child) {
68
+ } else {
67
69
  commitDeletion(fiber.child, domParent)
68
70
  }
69
71
  }
70
-
71
72
  export { commitDeletion, commitWork, commitRoot }
@@ -47,10 +47,16 @@ const cloneElement = (element, props) => {
47
47
 
48
48
  const createElement = (type, props, ...children) => {
49
49
  children = childArray(children, [])
50
+ const key =
51
+ props && props.key
52
+ ? props.key
53
+ : `${type}-${Math.random().toString(36).substring(2, 9)}`
54
+
50
55
  return {
51
56
  type,
52
57
  props: {
53
58
  ...props,
59
+ key,
54
60
  children: children.map((child) =>
55
61
  typeof child === STRINGS.object ? child : createTextElement(child),
56
62
  ),
package/src/lib/hooks.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { RYUNIX_TYPES, STRINGS, vars } from '../utils/index'
2
2
  import { isEqual } from 'lodash'
3
-
3
+ import { createElement } from './createElement'
4
4
  /**
5
5
  * @description The function creates a state.
6
6
  * @param initial - The initial value of the state for the hook.
@@ -14,24 +14,19 @@ const useStore = (initial) => {
14
14
  vars.wipFiber.alternate.hooks[vars.hookIndex]
15
15
  const hook = {
16
16
  state: oldHook ? oldHook.state : initial,
17
- queue: [],
17
+ queue: oldHook ? [...oldHook.queue] : [],
18
18
  }
19
19
 
20
- const actions = oldHook ? oldHook.queue : []
21
- actions.forEach((action) => {
20
+ hook.queue.forEach((action) => {
22
21
  hook.state =
23
22
  typeof action === STRINGS.function ? action(hook.state) : action
24
23
  })
25
24
 
26
- /**
27
- * The function `setState` updates the state of a component in Ryunix by adding an action to a queue
28
- * and setting up a new work-in-progress root.
29
- * @param action - The `action` parameter is an object that represents a state update to be performed
30
- * on a component. It contains information about the type of update to be performed and any new data
31
- * that needs to be applied to the component's state.
32
- */
25
+ hook.queue = []
26
+
33
27
  const setState = (action) => {
34
28
  hook.queue.push(action)
29
+
35
30
  vars.wipRoot = {
36
31
  dom: vars.currentRoot.dom,
37
32
  props: vars.currentRoot.props,
@@ -45,6 +40,7 @@ const useStore = (initial) => {
45
40
  vars.wipFiber.hooks.push(hook)
46
41
  vars.hookIndex++
47
42
  }
43
+
48
44
  return [hook.state, setState]
49
45
  }
50
46
 
@@ -84,6 +80,36 @@ const useEffect = (callback, deps) => {
84
80
  }
85
81
  }
86
82
 
83
+ /**
84
+ * The `useQuery` function is a custom hook in JavaScript that retrieves query parameters from the URL
85
+ * and stores them in a hook for easy access.
86
+ * @returns The `useQuery` function returns the `query` property of the `hook` object.
87
+ */
88
+ const useQuery = () => {
89
+ const oldHook =
90
+ vars.wipFiber.alternate &&
91
+ vars.wipFiber.alternate.hooks &&
92
+ vars.wipFiber.alternate.hooks[vars.hookIndex]
93
+
94
+ const hasOld = oldHook ? oldHook : undefined
95
+
96
+ const urlSearchParams = new URLSearchParams(window.location.search)
97
+ const params = Object.fromEntries(urlSearchParams.entries())
98
+ const Query = hasOld ? hasOld : params
99
+
100
+ const hook = {
101
+ type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
102
+ query: Query,
103
+ }
104
+
105
+ if (vars.wipFiber.hooks) {
106
+ vars.wipFiber.hooks.push(hook)
107
+ vars.hookIndex++
108
+ }
109
+
110
+ return hook.query
111
+ }
112
+
87
113
  const useRef = (initial) => {
88
114
  const oldHook =
89
115
  vars.wipFiber.alternate &&
@@ -155,40 +181,31 @@ const useRouter = (routes) => {
155
181
  }
156
182
  }, [])
157
183
 
158
- const currentRoute = routes.find((route) => route.path === location)
159
- const Children = () => (currentRoute ? currentRoute.component : null)
160
-
161
- return { Children, navigate }
162
- }
163
-
164
- /**
165
- * The `useQuery` function is a custom hook in JavaScript that retrieves query parameters from the URL
166
- * and stores them in a hook for easy access.
167
- * @returns The `useQuery` function returns the `query` property of the `hook` object.
168
- */
169
- const useQuery = () => {
170
- const oldHook =
171
- vars.wipFiber.alternate &&
172
- vars.wipFiber.alternate.hooks &&
173
- vars.wipFiber.alternate.hooks[vars.hookIndex]
174
-
175
- const hasOld = oldHook ? oldHook : undefined
184
+ let currentRoute = routes.find((route) => route.path === location)
185
+ if (!currentRoute) {
186
+ currentRoute = {
187
+ component: routes.find((route) => route.NotFound)?.NotFound || null,
188
+ }
189
+ }
176
190
 
177
- const urlSearchParams = new URLSearchParams(window.location.search)
178
- const params = Object.fromEntries(urlSearchParams.entries())
179
- const Query = hasOld ? hasOld : params
191
+ const Children = () =>
192
+ currentRoute.component ? currentRoute.component : null
180
193
 
181
- const hook = {
182
- type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
183
- query: Query,
184
- }
194
+ const NavLink = ({ to, ...props }) => {
195
+ const { children, ...restProps } = props
185
196
 
186
- if (vars.wipFiber.hooks) {
187
- vars.wipFiber.hooks.push(hook)
188
- vars.hookIndex++
197
+ const NewProps = {
198
+ href: to,
199
+ onClick: (e) => {
200
+ e.preventDefault()
201
+ navigate(to)
202
+ },
203
+ ...restProps,
204
+ }
205
+ return createElement('a', NewProps, children)
189
206
  }
190
207
 
191
- return hook.query
208
+ return { Children, navigate, NavLink }
192
209
  }
193
210
 
194
211
  export {
@@ -1,19 +1,5 @@
1
1
  import { EFFECT_TAGS, vars } from '../utils/index'
2
2
 
3
- const isPropsChanged = (prevProps, nextProps) => {
4
- for (let key in prevProps) {
5
- if (prevProps[key] !== nextProps[key]) {
6
- return true
7
- }
8
- }
9
- for (let key in nextProps) {
10
- if (!(key in prevProps)) {
11
- return true
12
- }
13
- }
14
- return false
15
- }
16
-
17
3
  /**
18
4
  * This function reconciles the children of a fiber node with a new set of elements, creating new
19
5
  * fibers for new elements, updating existing fibers for elements with the same type, and marking old
@@ -26,24 +12,33 @@ const isPropsChanged = (prevProps, nextProps) => {
26
12
  const reconcileChildren = (wipFiber, elements) => {
27
13
  let index = 0
28
14
  let oldFiber = wipFiber.alternate && wipFiber.alternate.child
29
- let prevSibling
15
+ let prevSibling = null
16
+
17
+ const oldFibersMap = new Map()
18
+ while (oldFiber) {
19
+ const oldKey = oldFiber.props.key || oldFiber.type
20
+ oldFibersMap.set(oldKey, oldFiber)
21
+ oldFiber = oldFiber.sibling
22
+ }
30
23
 
31
- while (index < elements.length || oldFiber != undefined) {
24
+ while (index < elements.length) {
32
25
  const element = elements[index]
26
+ const key = element.props.key || element.type
27
+ const oldFiber = oldFibersMap.get(key)
28
+
33
29
  let newFiber
34
- const sameType = oldFiber && element && element.type == oldFiber.type
30
+ const sameType = oldFiber && element && element.type === oldFiber.type
35
31
 
36
32
  if (sameType) {
37
33
  newFiber = {
38
- type: oldFiber ? oldFiber.type : undefined,
34
+ type: oldFiber.type,
39
35
  props: element.props,
40
- dom: oldFiber ? oldFiber.dom : undefined,
36
+ dom: oldFiber.dom,
41
37
  parent: wipFiber,
42
38
  alternate: oldFiber,
43
- effectTag: isPropsChanged(oldFiber.props, element.props)
44
- ? EFFECT_TAGS.UPDATE
45
- : null,
39
+ effectTag: EFFECT_TAGS.UPDATE,
46
40
  }
41
+ oldFibersMap.delete(key)
47
42
  } else if (element) {
48
43
  newFiber = {
49
44
  type: element.type,
@@ -53,18 +48,16 @@ const reconcileChildren = (wipFiber, elements) => {
53
48
  alternate: undefined,
54
49
  effectTag: EFFECT_TAGS.PLACEMENT,
55
50
  }
56
- } else if (oldFiber) {
57
- oldFiber.effectTag = EFFECT_TAGS.DELETION
58
- vars.deletions.push(oldFiber)
59
51
  }
60
52
 
61
- if (oldFiber) {
62
- oldFiber = oldFiber.sibling
63
- }
53
+ oldFibersMap.forEach((oldFiber) => {
54
+ oldFiber.effectTag = EFFECT_TAGS.DELETION
55
+ vars.deletions.push(oldFiber)
56
+ })
64
57
 
65
58
  if (index === 0) {
66
59
  wipFiber.child = newFiber
67
- } else if (element && prevSibling) {
60
+ } else if (prevSibling) {
68
61
  prevSibling.sibling = newFiber
69
62
  }
70
63
 
package/src/lib/render.js CHANGED
@@ -1,11 +1,18 @@
1
1
  import { vars } from '../utils/index'
2
2
 
3
+ const clearContainer = (container) => {
4
+ while (container.firstChild) {
5
+ container.removeChild(container.firstChild)
6
+ }
7
+ }
8
+
3
9
  /**
4
- * The function renders an element into a container using a work-in-progress root.
5
- * @param element - The element parameter is the component or element that needs to be rendered in the
6
- * container. It could be a Ryunix component or a DOM element.
7
- * @param container - The container parameter is the DOM element where the rendered element will be
8
- * appended to. this parameter is optional if you use createRoot().
10
+ * Renders an element into a container using a work-in-progress (WIP) root.
11
+ * @function render
12
+ * @param {Object|HTMLElement} element - The element to be rendered in the container. It can be a Ryunix component (custom element) or a standard DOM element.
13
+ * @param {HTMLElement} container - The container where the element will be rendered. This parameter is optional if `createRoot()` is used beforehand to set up the container.
14
+ * @description The function assigns the `container` to a work-in-progress root and sets up properties for reconciliation, including children and the reference to the current root.
15
+ * It also clears any scheduled deletions and establishes the next unit of work for incremental rendering.
9
16
  */
10
17
  const render = (element, container) => {
11
18
  vars.wipRoot = {
@@ -15,20 +22,24 @@ const render = (element, container) => {
15
22
  },
16
23
  alternate: vars.currentRoot,
17
24
  }
25
+
18
26
  vars.deletions = []
19
27
  vars.nextUnitOfWork = vars.wipRoot
20
28
  }
21
29
 
22
30
  /**
23
- * @description The function creates a reference to a DOM element with the specified ID. This will be used to initialize the app.
24
- * @example Ryunix.init("root") -> <div id="root" />
25
- * @param root - The parameter "root" is the id of the HTML element that will serve as the container
26
- * for the root element.
31
+ * Initializes the application by creating a reference to a DOM element with the specified ID and rendering the main component.
32
+ * @function init
33
+ * @param {Object} MainElement - The main component to render, typically the root component of the application.
34
+ * @param {string} [root='__ryunix'] - The ID of the HTML element that serves as the container for the root element. Defaults to `'__ryunix'` if not provided.
35
+ * @example
36
+ * Ryunix.init(App, "__ryunix"); // Initializes and renders the App component into the <div id="__ryunix"></div> element.
37
+ * @description This function retrieves the container element by its ID and invokes the `render` function to render the main component into it.
27
38
  */
28
- const init = (root) => {
29
- const rootElement = root || '__ryunix'
30
- vars.containerRoot = document.getElementById(rootElement)
31
- return this
39
+ const init = (MainElement, root = '__ryunix') => {
40
+ vars.containerRoot = document.getElementById(root)
41
+
42
+ render(MainElement, vars.containerRoot)
32
43
  }
33
44
 
34
45
  export { render, init }
@@ -21,9 +21,7 @@ const workLoop = (deadline) => {
21
21
  commitRoot()
22
22
  }
23
23
 
24
- if (vars.nextUnitOfWork) {
25
- requestIdleCallback(workLoop, { timeout: 100 })
26
- }
24
+ requestIdleCallback(workLoop)
27
25
  }
28
26
 
29
27
  requestIdleCallback(workLoop)