@unsetsoft/ryunixjs 1.0.3-nightly.7 → 1.0.3-nightly.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Ryunix.js +402 -346
- package/package.json +1 -1
- package/src/lib/commits.js +32 -84
- package/src/lib/components.js +21 -19
- package/src/lib/createElement.js +28 -25
- package/src/lib/dom.js +39 -66
- package/src/lib/effects.js +10 -35
- package/src/lib/hooks.js +156 -35
- package/src/lib/index.js +19 -2
- package/src/lib/reconciler.js +22 -8
- package/src/lib/render.js +15 -18
- package/src/lib/workers.js +31 -18
- package/src/main.js +2 -0
- package/src/utils/index.js +8 -17
package/dist/Ryunix.js
CHANGED
|
@@ -9,13 +9,12 @@
|
|
|
9
9
|
nextUnitOfWork: undefined,
|
|
10
10
|
currentRoot: undefined,
|
|
11
11
|
wipRoot: undefined,
|
|
12
|
-
deletions:
|
|
13
|
-
|
|
14
|
-
hookIndex:
|
|
15
|
-
errorBoundary: null, // New property to hold error boundary references
|
|
12
|
+
deletions: undefined,
|
|
13
|
+
wipFiber: undefined,
|
|
14
|
+
hookIndex: undefined,
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
const
|
|
17
|
+
const reg = /[A-Z]/g;
|
|
19
18
|
|
|
20
19
|
const RYUNIX_TYPES = Object.freeze({
|
|
21
20
|
TEXT_ELEMENT: Symbol('text.element'),
|
|
@@ -23,7 +22,6 @@
|
|
|
23
22
|
RYUNIX_MEMO: Symbol('ryunix.memo'),
|
|
24
23
|
RYUNIX_URL_QUERY: Symbol('ryunix.urlQuery'),
|
|
25
24
|
RYUNIX_REF: Symbol('ryunix.ref'),
|
|
26
|
-
RYUNIX_ERROR_BOUNDARY: Symbol('ryunix.errorBoundary'), // New Error Boundary Type
|
|
27
25
|
});
|
|
28
26
|
|
|
29
27
|
const STRINGS = Object.freeze({
|
|
@@ -41,24 +39,21 @@
|
|
|
41
39
|
});
|
|
42
40
|
|
|
43
41
|
const EFFECT_TAGS = Object.freeze({
|
|
44
|
-
PLACEMENT: Symbol(
|
|
45
|
-
UPDATE: Symbol(
|
|
46
|
-
DELETION: Symbol(
|
|
42
|
+
PLACEMENT: Symbol(),
|
|
43
|
+
UPDATE: Symbol(),
|
|
44
|
+
DELETION: Symbol(),
|
|
47
45
|
});
|
|
48
46
|
|
|
49
47
|
const Fragment = (props) => {
|
|
50
48
|
return props.children
|
|
51
49
|
};
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const childArray = (children, out = []) => {
|
|
60
|
-
if (children == undefined || typeof children === STRINGS.boolean) ; else if (Array.isArray(children)) {
|
|
61
|
-
children.forEach((child) => childArray(child, out)); // Use forEach instead of some
|
|
51
|
+
const childArray = (children, out) => {
|
|
52
|
+
out = out || [];
|
|
53
|
+
if (children == undefined || typeof children == STRINGS.boolean) ; else if (Array.isArray(children)) {
|
|
54
|
+
children.some((child) => {
|
|
55
|
+
childArray(child, out);
|
|
56
|
+
});
|
|
62
57
|
} else {
|
|
63
58
|
out.push(children);
|
|
64
59
|
}
|
|
@@ -66,12 +61,22 @@
|
|
|
66
61
|
};
|
|
67
62
|
|
|
68
63
|
/**
|
|
69
|
-
* The function creates a new element with
|
|
70
|
-
* @param type - The type of element to
|
|
71
|
-
* @param props - The properties of the
|
|
72
|
-
*
|
|
73
|
-
*
|
|
64
|
+
* The function creates a new element with the given type, props, and children.
|
|
65
|
+
* @param type - The type of the element to be created, such as "div", "span", "h1", etc.
|
|
66
|
+
* @param props - The `props` parameter is an object that contains the properties or attributes of the
|
|
67
|
+
* element being created. These properties can include things like `className`, `id`, `style`, and any
|
|
68
|
+
* other custom attributes that the user wants to add to the element. The `props` object is spread
|
|
69
|
+
* using the spread
|
|
70
|
+
* @param children - The `children` parameter is a rest parameter that allows the function to accept
|
|
71
|
+
* any number of arguments after the `props` parameter. These arguments will be treated as children
|
|
72
|
+
* elements of the created element. The `map` function is used to iterate over each child and create a
|
|
73
|
+
* new element if it is not
|
|
74
|
+
* @returns A JavaScript object with a `type` property and a `props` property. The `type` property is
|
|
75
|
+
* set to the `type` argument passed into the function, and the `props` property is an object that
|
|
76
|
+
* includes any additional properties passed in the `props` argument, as well as a `children` property
|
|
77
|
+
* that is an array of any child elements passed in the `...children` argument
|
|
74
78
|
*/
|
|
79
|
+
|
|
75
80
|
const createElement = (type, props, ...children) => {
|
|
76
81
|
children = childArray(children, []);
|
|
77
82
|
return {
|
|
@@ -86,52 +91,254 @@
|
|
|
86
91
|
};
|
|
87
92
|
|
|
88
93
|
/**
|
|
89
|
-
* The function creates a text element
|
|
90
|
-
* @param text - The text content to create
|
|
91
|
-
* @returns
|
|
94
|
+
* The function creates a text element with a given text value.
|
|
95
|
+
* @param text - The text content that will be used to create a new text element.
|
|
96
|
+
* @returns A JavaScript object with a `type` property set to `"TEXT_ELEMENT"` and a `props` property
|
|
97
|
+
* that contains a `nodeValue` property set to the `text` parameter and an empty `children` array.
|
|
92
98
|
*/
|
|
99
|
+
|
|
93
100
|
const createTextElement = (text) => {
|
|
94
101
|
return {
|
|
95
102
|
type: RYUNIX_TYPES.TEXT_ELEMENT,
|
|
96
103
|
props: {
|
|
97
104
|
nodeValue: text,
|
|
98
|
-
children: [],
|
|
105
|
+
children: [],
|
|
99
106
|
},
|
|
100
107
|
}
|
|
101
108
|
};
|
|
102
109
|
|
|
103
110
|
/**
|
|
104
|
-
*
|
|
105
|
-
* @param
|
|
106
|
-
*
|
|
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().
|
|
107
116
|
*/
|
|
108
|
-
const
|
|
117
|
+
const render = (element, container) => {
|
|
118
|
+
vars.wipRoot = {
|
|
119
|
+
dom: vars.containerRoot || container,
|
|
120
|
+
props: {
|
|
121
|
+
children: [element],
|
|
122
|
+
},
|
|
123
|
+
alternate: vars.currentRoot,
|
|
124
|
+
};
|
|
125
|
+
vars.deletions = [];
|
|
126
|
+
vars.nextUnitOfWork = vars.wipRoot;
|
|
127
|
+
};
|
|
109
128
|
|
|
110
129
|
/**
|
|
111
|
-
*
|
|
112
|
-
* @
|
|
113
|
-
* @
|
|
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.
|
|
114
134
|
*/
|
|
115
|
-
const
|
|
135
|
+
const init = (root) => {
|
|
136
|
+
const rootElement = root || '__ryunix';
|
|
137
|
+
vars.containerRoot = document.getElementById(rootElement);
|
|
138
|
+
return undefined
|
|
139
|
+
};
|
|
116
140
|
|
|
117
141
|
/**
|
|
118
|
-
*
|
|
119
|
-
* @param
|
|
120
|
-
* @
|
|
121
|
-
*
|
|
142
|
+
* @description The function creates a state.
|
|
143
|
+
* @param initial - The initial value of the state for the hook.
|
|
144
|
+
* @returns The `useStore` function returns an array with two elements: the current state value and a
|
|
145
|
+
* `setState` function that can be used to update the state.
|
|
122
146
|
*/
|
|
123
|
-
const
|
|
147
|
+
const useStore = (initial) => {
|
|
148
|
+
const oldHook =
|
|
149
|
+
vars.wipFiber.alternate &&
|
|
150
|
+
vars.wipFiber.alternate.hooks &&
|
|
151
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
152
|
+
const hook = {
|
|
153
|
+
state: oldHook ? oldHook.state : initial,
|
|
154
|
+
queue: [],
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const actions = oldHook ? oldHook.queue : [];
|
|
158
|
+
actions.forEach((action) => {
|
|
159
|
+
hook.state =
|
|
160
|
+
typeof action === STRINGS.function ? action(hook.state) : action;
|
|
161
|
+
});
|
|
162
|
+
|
|
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
|
+
*/
|
|
170
|
+
const setState = (action) => {
|
|
171
|
+
hook.queue.push(action);
|
|
172
|
+
vars.wipRoot = {
|
|
173
|
+
dom: vars.currentRoot.dom,
|
|
174
|
+
props: vars.currentRoot.props,
|
|
175
|
+
alternate: vars.currentRoot,
|
|
176
|
+
};
|
|
177
|
+
vars.nextUnitOfWork = vars.wipRoot;
|
|
178
|
+
vars.deletions = [];
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
if (vars.wipFiber && vars.wipFiber.hooks) {
|
|
182
|
+
vars.wipFiber.hooks.push(hook);
|
|
183
|
+
vars.hookIndex++;
|
|
184
|
+
}
|
|
185
|
+
return [hook.state, setState]
|
|
186
|
+
};
|
|
124
187
|
|
|
125
188
|
/**
|
|
126
|
-
*
|
|
127
|
-
* @param
|
|
128
|
-
*
|
|
189
|
+
* This is a function that creates a hook for managing side effects in Ryunix components.
|
|
190
|
+
* @param effect - The effect function that will be executed after the component has rendered or when
|
|
191
|
+
* the dependencies have changed. It can perform side effects such as fetching data, updating the DOM,
|
|
192
|
+
* or subscribing to events.
|
|
193
|
+
* @param deps - An array of dependencies that the effect depends on. If any of the dependencies change
|
|
194
|
+
* between renders, the effect will be re-run. If the array is empty, the effect will only run once on
|
|
195
|
+
* mount and never again.
|
|
129
196
|
*/
|
|
197
|
+
|
|
198
|
+
const useEffect = (callback, deps) => {
|
|
199
|
+
const oldHook =
|
|
200
|
+
vars.wipFiber.alternate &&
|
|
201
|
+
vars.wipFiber.alternate.hooks &&
|
|
202
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
203
|
+
|
|
204
|
+
const hook = {
|
|
205
|
+
type: RYUNIX_TYPES.RYUNIX_EFFECT,
|
|
206
|
+
deps,
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
if (!oldHook) {
|
|
210
|
+
// invoke callback if this is the first time
|
|
211
|
+
callback();
|
|
212
|
+
} else {
|
|
213
|
+
if (!lodash.isEqual(oldHook.deps, hook.deps)) {
|
|
214
|
+
callback();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (vars.wipFiber.hooks) {
|
|
219
|
+
vars.wipFiber.hooks.push(hook);
|
|
220
|
+
vars.hookIndex++;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const useRef = (initial) => {
|
|
225
|
+
const oldHook =
|
|
226
|
+
vars.wipFiber.alternate &&
|
|
227
|
+
vars.wipFiber.alternate.hooks &&
|
|
228
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
229
|
+
|
|
230
|
+
const hook = {
|
|
231
|
+
type: RYUNIX_TYPES.RYUNIX_REF,
|
|
232
|
+
value: oldHook ? oldHook.value : { current: initial },
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
if (vars.wipFiber.hooks) {
|
|
236
|
+
vars.wipFiber.hooks.push(hook);
|
|
237
|
+
vars.hookIndex++;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return hook.value
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const useMemo = (comp, deps) => {
|
|
244
|
+
const oldHook =
|
|
245
|
+
vars.wipFiber.alternate &&
|
|
246
|
+
vars.wipFiber.alternate.hooks &&
|
|
247
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
248
|
+
|
|
249
|
+
const hook = {
|
|
250
|
+
type: RYUNIX_TYPES.RYUNIX_MEMO,
|
|
251
|
+
value: null,
|
|
252
|
+
deps,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
if (oldHook) {
|
|
256
|
+
if (lodash.isEqual(oldHook.deps, hook.deps)) {
|
|
257
|
+
hook.value = oldHook.value;
|
|
258
|
+
} else {
|
|
259
|
+
hook.value = comp();
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
hook.value = comp();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (vars.wipFiber.hooks) {
|
|
266
|
+
vars.wipFiber.hooks.push(hook);
|
|
267
|
+
vars.hookIndex++;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return hook.value
|
|
271
|
+
};
|
|
272
|
+
const useCallback = (callback, deps) => {
|
|
273
|
+
return useMemo(() => callback, deps)
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const useRouter = (routes) => {
|
|
277
|
+
const [location, setLocation] = useStore(window.location.pathname);
|
|
278
|
+
|
|
279
|
+
const navigate = (path) => {
|
|
280
|
+
window.history.pushState({}, '', path);
|
|
281
|
+
setLocation(path);
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
useEffect(() => {
|
|
285
|
+
const onPopState = () => {
|
|
286
|
+
setLocation(window.location.pathname);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
window.addEventListener('popstate', onPopState);
|
|
290
|
+
return () => {
|
|
291
|
+
window.removeEventListener('popstate', onPopState);
|
|
292
|
+
}
|
|
293
|
+
}, []);
|
|
294
|
+
|
|
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];
|
|
311
|
+
|
|
312
|
+
const hasOld = oldHook ? oldHook : undefined;
|
|
313
|
+
|
|
314
|
+
const urlSearchParams = new URLSearchParams(window.location.search);
|
|
315
|
+
const params = Object.fromEntries(urlSearchParams.entries());
|
|
316
|
+
const Query = hasOld ? hasOld : params;
|
|
317
|
+
|
|
318
|
+
const hook = {
|
|
319
|
+
type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
|
|
320
|
+
query: Query,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
if (vars.wipFiber.hooks) {
|
|
324
|
+
vars.wipFiber.hooks.push(hook);
|
|
325
|
+
vars.hookIndex++;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return hook.query
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const isEvent = (key) => key.startsWith('on');
|
|
332
|
+
const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
|
|
333
|
+
const isNew = (prev, next) => (key) => prev[key] !== next[key];
|
|
130
334
|
const isGone = (next) => (key) => !(key in next);
|
|
131
335
|
|
|
132
336
|
/**
|
|
133
|
-
*
|
|
134
|
-
* @param fiber - The fiber
|
|
337
|
+
* The function cancels all effect hooks in a given fiber.
|
|
338
|
+
* @param fiber - The "fiber" parameter is likely referring to a data structure used in React.js to
|
|
339
|
+
* represent a component and its state. It contains information about the component's props, state, and
|
|
340
|
+
* children, as well as metadata used by React to manage updates and rendering. The function
|
|
341
|
+
* "cancelEffects" is likely intended
|
|
135
342
|
*/
|
|
136
343
|
const cancelEffects = (fiber) => {
|
|
137
344
|
if (fiber.hooks) {
|
|
@@ -144,8 +351,11 @@
|
|
|
144
351
|
};
|
|
145
352
|
|
|
146
353
|
/**
|
|
147
|
-
*
|
|
148
|
-
* @param fiber - The fiber
|
|
354
|
+
* The function runs all effect hooks in a given fiber.
|
|
355
|
+
* @param fiber - The "fiber" parameter is likely referring to a data structure used in the
|
|
356
|
+
* implementation of a fiber-based reconciliation algorithm, such as the one used in React. A fiber
|
|
357
|
+
* represents a unit of work that needs to be performed by the reconciliation algorithm, and it
|
|
358
|
+
* contains information about a component and its children, as
|
|
149
359
|
*/
|
|
150
360
|
const runEffects = (fiber) => {
|
|
151
361
|
if (fiber.hooks) {
|
|
@@ -158,38 +368,34 @@
|
|
|
158
368
|
};
|
|
159
369
|
|
|
160
370
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
371
|
+
* The function creates a new DOM element based on the given fiber object and updates its properties.
|
|
372
|
+
* @param fiber - The fiber parameter is an object that represents a node in the fiber tree. It
|
|
373
|
+
* contains information about the element type, props, and children of the node.
|
|
374
|
+
* @returns The `createDom` function returns a newly created DOM element based on the `fiber` object
|
|
375
|
+
* passed as an argument. If the `fiber` object represents a text element, a text node is created using
|
|
376
|
+
* `document.createTextNode("")`. Otherwise, a new element is created using
|
|
377
|
+
* `document.createElement(fiber.type)`. The function then calls the `updateDom` function to update the
|
|
378
|
+
* properties of the newly created
|
|
166
379
|
*/
|
|
167
380
|
const createDom = (fiber) => {
|
|
168
|
-
// Log to verify fiber type before creating DOM
|
|
169
|
-
console.log('Creating DOM for fiber:', fiber);
|
|
170
|
-
|
|
171
|
-
// Check if the fiber is a text element or a regular element
|
|
172
381
|
const dom =
|
|
173
|
-
fiber.type
|
|
174
|
-
? document.createTextNode(
|
|
382
|
+
fiber.type == RYUNIX_TYPES.TEXT_ELEMENT
|
|
383
|
+
? document.createTextNode('')
|
|
175
384
|
: document.createElement(fiber.type);
|
|
176
385
|
|
|
177
|
-
// Update the newly created DOM element with its initial props
|
|
178
386
|
updateDom(dom, {}, fiber.props);
|
|
179
387
|
|
|
180
388
|
return dom
|
|
181
389
|
};
|
|
182
390
|
|
|
183
391
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* @param
|
|
188
|
-
* @param
|
|
189
|
-
* @param nextProps - The new properties that should be applied to the DOM element.
|
|
392
|
+
* The function updates the DOM by removing old event listeners and properties, and adding new ones
|
|
393
|
+
* based on the previous and next props.
|
|
394
|
+
* @param dom - The DOM element that needs to be updated with new props.
|
|
395
|
+
* @param prevProps - An object representing the previous props (properties) of a DOM element.
|
|
396
|
+
* @param nextProps - An object containing the new props that need to be updated in the DOM.
|
|
190
397
|
*/
|
|
191
398
|
const updateDom = (dom, prevProps, nextProps) => {
|
|
192
|
-
// Remove old or changed event listeners
|
|
193
399
|
Object.keys(prevProps)
|
|
194
400
|
.filter(isEvent)
|
|
195
401
|
.filter((key) => isGone(nextProps)(key) || isNew(prevProps, nextProps)(key))
|
|
@@ -198,7 +404,6 @@
|
|
|
198
404
|
dom.removeEventListener(eventType, prevProps[name]);
|
|
199
405
|
});
|
|
200
406
|
|
|
201
|
-
// Remove old properties
|
|
202
407
|
Object.keys(prevProps)
|
|
203
408
|
.filter(isProperty)
|
|
204
409
|
.filter(isGone(nextProps))
|
|
@@ -206,21 +411,35 @@
|
|
|
206
411
|
dom[name] = '';
|
|
207
412
|
});
|
|
208
413
|
|
|
209
|
-
// Set new or changed properties
|
|
210
414
|
Object.keys(nextProps)
|
|
211
415
|
.filter(isProperty)
|
|
212
416
|
.filter(isNew(prevProps, nextProps))
|
|
213
417
|
.forEach((name) => {
|
|
214
|
-
if (name === STRINGS.style
|
|
215
|
-
DomStyle(dom, nextProps[
|
|
216
|
-
} else if (name ===
|
|
217
|
-
|
|
418
|
+
if (name === STRINGS.style) {
|
|
419
|
+
DomStyle(dom, nextProps['ryunix-style']);
|
|
420
|
+
} else if (name === OLD_STRINGS.style) {
|
|
421
|
+
DomStyle(dom, nextProps.style);
|
|
422
|
+
} else if (name === STRINGS.className) {
|
|
423
|
+
if (nextProps['ryunix-class'] === '') {
|
|
424
|
+
throw new Error('data-class cannot be empty.')
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
prevProps['ryunix-class'] &&
|
|
428
|
+
dom.classList.remove(...prevProps['ryunix-class'].split(/\s+/));
|
|
429
|
+
dom.classList.add(...nextProps['ryunix-class'].split(/\s+/));
|
|
430
|
+
} else if (name === OLD_STRINGS.className) {
|
|
431
|
+
if (nextProps.className === '') {
|
|
432
|
+
throw new Error('className cannot be empty.')
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
prevProps.className &&
|
|
436
|
+
dom.classList.remove(...prevProps.className.split(/\s+/));
|
|
437
|
+
dom.classList.add(...nextProps.className.split(/\s+/));
|
|
218
438
|
} else {
|
|
219
439
|
dom[name] = nextProps[name];
|
|
220
440
|
}
|
|
221
441
|
});
|
|
222
442
|
|
|
223
|
-
// Add new event listeners
|
|
224
443
|
Object.keys(nextProps)
|
|
225
444
|
.filter(isEvent)
|
|
226
445
|
.filter(isNew(prevProps, nextProps))
|
|
@@ -230,47 +449,16 @@
|
|
|
230
449
|
});
|
|
231
450
|
};
|
|
232
451
|
|
|
233
|
-
/**
|
|
234
|
-
* Updates the DOM element's style by applying the provided styles.
|
|
235
|
-
*
|
|
236
|
-
* @param dom - The DOM element that needs to be styled.
|
|
237
|
-
* @param style - An object containing the styles to be applied.
|
|
238
|
-
*/
|
|
239
452
|
const DomStyle = (dom, style) => {
|
|
240
453
|
dom.style = Object.keys(style).reduce((acc, styleName) => {
|
|
241
|
-
const key = styleName.replace(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
);
|
|
454
|
+
const key = styleName.replace(reg, function (v) {
|
|
455
|
+
return '-' + v.toLowerCase()
|
|
456
|
+
});
|
|
245
457
|
acc += `${key}: ${style[styleName]};`;
|
|
246
458
|
return acc
|
|
247
459
|
}, '');
|
|
248
460
|
};
|
|
249
461
|
|
|
250
|
-
/**
|
|
251
|
-
* Handles updating the className or ryunix-class properties, ensuring
|
|
252
|
-
* that the old class names are removed and the new ones are applied.
|
|
253
|
-
*
|
|
254
|
-
* @param dom - The DOM element to be updated.
|
|
255
|
-
* @param prevProps - The previous properties, including className.
|
|
256
|
-
* @param nextProps - The new properties, including className.
|
|
257
|
-
* @param name - The name of the class property (className or ryunix-class).
|
|
258
|
-
*/
|
|
259
|
-
const handleClassName = (dom, prevProps, nextProps, name) => {
|
|
260
|
-
const classProp = name === STRINGS.className ? 'ryunix-class' : 'className';
|
|
261
|
-
|
|
262
|
-
if (nextProps[classProp] === '') {
|
|
263
|
-
throw new Error(`${classProp} cannot be empty.`)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Remove old class names if they exist
|
|
267
|
-
prevProps[classProp] &&
|
|
268
|
-
dom.classList.remove(...prevProps[classProp].split(/\s+/));
|
|
269
|
-
|
|
270
|
-
// Add new class names
|
|
271
|
-
dom.classList.add(...nextProps[classProp].split(/\s+/));
|
|
272
|
-
};
|
|
273
|
-
|
|
274
462
|
var Dom = /*#__PURE__*/Object.freeze({
|
|
275
463
|
__proto__: null,
|
|
276
464
|
DomStyle: DomStyle,
|
|
@@ -282,10 +470,8 @@
|
|
|
282
470
|
* The function commits changes made to the virtual DOM to the actual DOM.
|
|
283
471
|
*/
|
|
284
472
|
const commitRoot = () => {
|
|
285
|
-
console.log('Committing root...');
|
|
286
473
|
vars.deletions.forEach(commitWork);
|
|
287
474
|
if (vars.wipRoot && vars.wipRoot.child) {
|
|
288
|
-
console.log('Committing child...');
|
|
289
475
|
commitWork(vars.wipRoot.child);
|
|
290
476
|
vars.currentRoot = vars.wipRoot;
|
|
291
477
|
}
|
|
@@ -293,107 +479,57 @@
|
|
|
293
479
|
};
|
|
294
480
|
|
|
295
481
|
/**
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
*
|
|
300
|
-
|
|
301
|
-
const findDomParent = (fiber) => {
|
|
302
|
-
let domParentFiber = fiber.parent;
|
|
303
|
-
// Walk up the tree until a DOM node is found or the root is reached
|
|
304
|
-
while (domParentFiber && !domParentFiber.dom) {
|
|
305
|
-
domParentFiber = domParentFiber.parent;
|
|
306
|
-
}
|
|
307
|
-
return domParentFiber ? domParentFiber.dom : null
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Safely removes a child DOM node from its parent, with error handling.
|
|
312
|
-
* @param {HTMLElement} domParent - The parent DOM node.
|
|
313
|
-
* @param {HTMLElement} childDom - The child DOM node to be removed.
|
|
314
|
-
*/
|
|
315
|
-
const safeRemoveChild = (domParent, childDom) => {
|
|
316
|
-
try {
|
|
317
|
-
domParent.removeChild(childDom);
|
|
318
|
-
} catch (error) {
|
|
319
|
-
console.error('Error removing DOM child:', error);
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* The function handles the deletion of a fiber's corresponding DOM node.
|
|
325
|
-
* It removes the fiber's DOM element or recursively removes its child.
|
|
326
|
-
* @param {Object} fiber - The fiber node to be deleted.
|
|
327
|
-
* @param {HTMLElement} domParent - The parent DOM node from which the fiber's DOM node will be removed.
|
|
482
|
+
* The function commits changes made to the DOM based on the effect tag of the fiber.
|
|
483
|
+
* @param fiber - A fiber is a unit of work in Ryunix's reconciliation process. It represents a
|
|
484
|
+
* component and its state at a particular point in time. The `commitWork` function takes a fiber as a
|
|
485
|
+
* parameter to commit the changes made during the reconciliation process to the actual DOM.
|
|
486
|
+
* @returns The function does not return anything, it performs side effects by manipulating the DOM.
|
|
328
487
|
*/
|
|
329
|
-
const
|
|
330
|
-
if (fiber
|
|
331
|
-
|
|
332
|
-
} else if (fiber && fiber.child) {
|
|
333
|
-
commitDeletion(fiber.child, domParent);
|
|
488
|
+
const commitWork = (fiber) => {
|
|
489
|
+
if (!fiber) {
|
|
490
|
+
return
|
|
334
491
|
}
|
|
335
|
-
};
|
|
336
492
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
* @param {Object} fiber - The fiber node whose effects need to be cleaned up.
|
|
341
|
-
*/
|
|
342
|
-
const cleanupEffects = (fiber) => {
|
|
343
|
-
if (
|
|
344
|
-
fiber.effectTag === EFFECT_TAGS.UPDATE ||
|
|
345
|
-
fiber.effectTag === EFFECT_TAGS.DELETION
|
|
346
|
-
) {
|
|
347
|
-
cancelEffects(fiber);
|
|
493
|
+
let domParentFiber = fiber.parent;
|
|
494
|
+
while (!domParentFiber.dom) {
|
|
495
|
+
domParentFiber = domParentFiber.parent;
|
|
348
496
|
}
|
|
349
|
-
|
|
497
|
+
const domParent = domParentFiber.dom;
|
|
350
498
|
|
|
351
|
-
|
|
352
|
-
* An object that maps effect tags to their corresponding handling functions.
|
|
353
|
-
* Each function takes a fiber node and a DOM parent, and applies the necessary changes to the DOM.
|
|
354
|
-
*/
|
|
355
|
-
const effectHandlers = {
|
|
356
|
-
[EFFECT_TAGS.PLACEMENT]: (fiber, domParent) => {
|
|
499
|
+
if (fiber.effectTag === EFFECT_TAGS.PLACEMENT) {
|
|
357
500
|
if (fiber.dom != undefined) {
|
|
358
501
|
domParent.appendChild(fiber.dom);
|
|
359
|
-
console.log('Appending child DOM node:', fiber.dom);
|
|
360
|
-
} else {
|
|
361
|
-
console.error('Failed to append DOM. Fiber has no DOM:', fiber);
|
|
362
502
|
}
|
|
363
503
|
runEffects(fiber);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
cleanupEffects(fiber); // Cleanup effects before updating
|
|
504
|
+
} else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
|
|
505
|
+
cancelEffects(fiber);
|
|
367
506
|
if (fiber.dom != undefined) {
|
|
368
507
|
updateDom(fiber.dom, fiber.alternate.props, fiber.props);
|
|
369
508
|
}
|
|
370
509
|
runEffects(fiber);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
cleanupEffects(fiber);
|
|
510
|
+
} else if (fiber.effectTag === EFFECT_TAGS.DELETION) {
|
|
511
|
+
cancelEffects(fiber);
|
|
374
512
|
commitDeletion(fiber, domParent);
|
|
375
|
-
|
|
513
|
+
return
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
commitWork(fiber.child);
|
|
517
|
+
commitWork(fiber.sibling);
|
|
376
518
|
};
|
|
377
519
|
|
|
378
520
|
/**
|
|
379
|
-
* The function
|
|
380
|
-
*
|
|
381
|
-
* @param
|
|
521
|
+
* The function removes a fiber's corresponding DOM node from its parent node or recursively removes
|
|
522
|
+
* its child's DOM node until it finds a node to remove.
|
|
523
|
+
* @param fiber - a fiber node in a fiber tree, which represents a component or an element in the Ryunix
|
|
524
|
+
* application.
|
|
525
|
+
* @param domParent - The parent DOM element from which the fiber's DOM element needs to be removed.
|
|
382
526
|
*/
|
|
383
|
-
const
|
|
384
|
-
if (
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
const effectHandler = effectHandlers[fiber.effectTag];
|
|
390
|
-
if (effectHandler) {
|
|
391
|
-
effectHandler(fiber, domParent);
|
|
527
|
+
const commitDeletion = (fiber, domParent) => {
|
|
528
|
+
if (fiber && fiber.dom) {
|
|
529
|
+
domParent.removeChild(fiber.dom);
|
|
530
|
+
} else if (fiber && fiber.child) {
|
|
531
|
+
commitDeletion(fiber.child, domParent);
|
|
392
532
|
}
|
|
393
|
-
|
|
394
|
-
// Process child and sibling fibers recursively
|
|
395
|
-
commitWork(fiber.child);
|
|
396
|
-
commitWork(fiber.sibling);
|
|
397
533
|
};
|
|
398
534
|
|
|
399
535
|
var Commits = /*#__PURE__*/Object.freeze({
|
|
@@ -403,6 +539,20 @@
|
|
|
403
539
|
commitWork: commitWork
|
|
404
540
|
});
|
|
405
541
|
|
|
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
|
+
|
|
406
556
|
/**
|
|
407
557
|
* This function reconciles the children of a fiber node with a new set of elements, creating new
|
|
408
558
|
* fibers for new elements, updating existing fibers for elements with the same type, and marking old
|
|
@@ -420,20 +570,20 @@
|
|
|
420
570
|
while (index < elements.length || oldFiber != undefined) {
|
|
421
571
|
const element = elements[index];
|
|
422
572
|
let newFiber;
|
|
423
|
-
|
|
424
573
|
const sameType = oldFiber && element && element.type == oldFiber.type;
|
|
425
574
|
|
|
426
575
|
if (sameType) {
|
|
427
576
|
newFiber = {
|
|
428
|
-
type: oldFiber.type,
|
|
577
|
+
type: oldFiber ? oldFiber.type : undefined,
|
|
429
578
|
props: element.props,
|
|
430
|
-
dom: oldFiber.dom,
|
|
579
|
+
dom: oldFiber ? oldFiber.dom : undefined,
|
|
431
580
|
parent: wipFiber,
|
|
432
581
|
alternate: oldFiber,
|
|
433
|
-
effectTag:
|
|
582
|
+
effectTag: isPropsChanged(oldFiber.props, element.props)
|
|
583
|
+
? EFFECT_TAGS.UPDATE
|
|
584
|
+
: null,
|
|
434
585
|
};
|
|
435
|
-
}
|
|
436
|
-
if (element && !sameType) {
|
|
586
|
+
} else if (element) {
|
|
437
587
|
newFiber = {
|
|
438
588
|
type: element.type,
|
|
439
589
|
props: element.props,
|
|
@@ -442,8 +592,7 @@
|
|
|
442
592
|
alternate: undefined,
|
|
443
593
|
effectTag: EFFECT_TAGS.PLACEMENT,
|
|
444
594
|
};
|
|
445
|
-
}
|
|
446
|
-
if (!element && oldFiber) {
|
|
595
|
+
} else if (oldFiber) {
|
|
447
596
|
oldFiber.effectTag = EFFECT_TAGS.DELETION;
|
|
448
597
|
vars.deletions.push(oldFiber);
|
|
449
598
|
}
|
|
@@ -469,36 +618,38 @@
|
|
|
469
618
|
});
|
|
470
619
|
|
|
471
620
|
/**
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* properties such as the component type, props, and hooks.
|
|
621
|
+
* This function updates a function component by setting up a work-in-progress fiber, resetting the
|
|
622
|
+
* hook index, creating an empty hooks array, rendering the component, and reconciling its children.
|
|
623
|
+
* @param fiber - The fiber parameter is an object that represents a node in the fiber tree. It
|
|
624
|
+
* contains information about the component, its props, state, and children. In this function, it is
|
|
625
|
+
* used to update the state of the component and its children.
|
|
478
626
|
*/
|
|
479
627
|
const updateFunctionComponent = (fiber) => {
|
|
480
|
-
|
|
481
|
-
vars.workInProgressFiber = fiber;
|
|
628
|
+
vars.wipFiber = fiber;
|
|
482
629
|
vars.hookIndex = 0;
|
|
483
|
-
vars.
|
|
484
|
-
|
|
630
|
+
vars.wipFiber.hooks = [];
|
|
485
631
|
const children = fiber.type(fiber.props);
|
|
486
|
-
|
|
632
|
+
let childArr = [];
|
|
633
|
+
if (Array.isArray(children)) {
|
|
634
|
+
// Fragment results returns array
|
|
635
|
+
childArr = [...children];
|
|
636
|
+
} else {
|
|
637
|
+
// Normal function component returns single root node
|
|
638
|
+
childArr = [children];
|
|
639
|
+
}
|
|
640
|
+
reconcileChildren(fiber, childArr);
|
|
487
641
|
};
|
|
642
|
+
|
|
488
643
|
/**
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
644
|
+
* This function updates a host component's DOM element and reconciles its children.
|
|
645
|
+
* @param fiber - A fiber is a unit of work in Ryunix that represents a component and its state. It
|
|
646
|
+
* contains information about the component's type, props, and children, as well as pointers to other
|
|
647
|
+
* fibers in the tree.
|
|
493
648
|
*/
|
|
494
649
|
const updateHostComponent = (fiber) => {
|
|
495
|
-
// If the fiber doesn't already have a DOM node, create one
|
|
496
650
|
if (!fiber.dom) {
|
|
497
651
|
fiber.dom = createDom(fiber);
|
|
498
|
-
console.log('DOM node created:', fiber.dom);
|
|
499
652
|
}
|
|
500
|
-
|
|
501
|
-
// Reconcile the fiber's children with its new or updated props
|
|
502
653
|
reconcileChildren(fiber, fiber.props.children);
|
|
503
654
|
};
|
|
504
655
|
|
|
@@ -509,13 +660,15 @@
|
|
|
509
660
|
});
|
|
510
661
|
|
|
511
662
|
/**
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* @param
|
|
663
|
+
* This function uses requestIdleCallback to perform work on a fiber tree until it is complete or the
|
|
664
|
+
* browser needs to yield to other tasks.
|
|
665
|
+
* @param deadline - The `deadline` parameter is an object that represents the amount of time the
|
|
666
|
+
* browser has to perform work before it needs to handle other tasks. It has a `timeRemaining()` method
|
|
667
|
+
* that returns the amount of time remaining before the deadline is reached. The `shouldYield` variable
|
|
668
|
+
* is used to determine
|
|
515
669
|
*/
|
|
516
670
|
const workLoop = (deadline) => {
|
|
517
671
|
let shouldYield = false;
|
|
518
|
-
|
|
519
672
|
while (vars.nextUnitOfWork && !shouldYield) {
|
|
520
673
|
vars.nextUnitOfWork = performUnitOfWork(vars.nextUnitOfWork);
|
|
521
674
|
shouldYield = deadline.timeRemaining() < 1;
|
|
@@ -525,32 +678,43 @@
|
|
|
525
678
|
commitRoot();
|
|
526
679
|
}
|
|
527
680
|
|
|
528
|
-
|
|
681
|
+
if (vars.nextUnitOfWork) {
|
|
682
|
+
requestIdleCallback(workLoop, { timeout: 100 });
|
|
683
|
+
}
|
|
529
684
|
};
|
|
530
685
|
|
|
531
|
-
// Start the work loop for the first time
|
|
532
686
|
requestIdleCallback(workLoop);
|
|
533
687
|
|
|
534
688
|
/**
|
|
535
|
-
*
|
|
536
|
-
*
|
|
537
|
-
* @param
|
|
538
|
-
*
|
|
689
|
+
* The function performs a unit of work by updating either a function component or a host component and
|
|
690
|
+
* returns the next fiber to be processed.
|
|
691
|
+
* @param fiber - A fiber is a unit of work in Ryunix that represents a component and its state. It
|
|
692
|
+
* contains information about the component's type, props, and children, as well as pointers to its
|
|
693
|
+
* parent, child, and sibling fibers. The `performUnitOfWork` function takes a fiber as a parameter and
|
|
694
|
+
* performs work
|
|
695
|
+
* @returns The function `performUnitOfWork` returns the next fiber to be processed. If the current
|
|
696
|
+
* fiber has a child, it returns the child. Otherwise, it looks for the next sibling of the current
|
|
697
|
+
* fiber. If there are no more siblings, it goes up the tree to the parent and looks for the next
|
|
698
|
+
* sibling of the parent. The function returns `undefined` if there are no more fibers to process.
|
|
539
699
|
*/
|
|
540
700
|
const performUnitOfWork = (fiber) => {
|
|
541
|
-
console.log('Performing unit of work for fiber:', fiber);
|
|
542
701
|
const isFunctionComponent = fiber.type instanceof Function;
|
|
543
|
-
isFunctionComponent
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
702
|
+
if (isFunctionComponent) {
|
|
703
|
+
updateFunctionComponent(fiber);
|
|
704
|
+
} else {
|
|
705
|
+
updateHostComponent(fiber);
|
|
706
|
+
}
|
|
707
|
+
if (fiber.child) {
|
|
708
|
+
return fiber.child
|
|
709
|
+
}
|
|
548
710
|
let nextFiber = fiber;
|
|
549
711
|
while (nextFiber) {
|
|
550
|
-
if (nextFiber.sibling)
|
|
712
|
+
if (nextFiber.sibling) {
|
|
713
|
+
return nextFiber.sibling
|
|
714
|
+
}
|
|
551
715
|
nextFiber = nextFiber.parent;
|
|
552
716
|
}
|
|
553
|
-
return
|
|
717
|
+
return undefined
|
|
554
718
|
};
|
|
555
719
|
|
|
556
720
|
var Workers = /*#__PURE__*/Object.freeze({
|
|
@@ -559,116 +723,6 @@
|
|
|
559
723
|
workLoop: workLoop
|
|
560
724
|
});
|
|
561
725
|
|
|
562
|
-
/**
|
|
563
|
-
* Renders an element into the specified container or the default root element.
|
|
564
|
-
*/
|
|
565
|
-
const render = (element, container) => {
|
|
566
|
-
vars.wipRoot = {
|
|
567
|
-
dom: vars.containerRoot || container,
|
|
568
|
-
props: { children: [element] },
|
|
569
|
-
alternate: vars.currentRoot,
|
|
570
|
-
};
|
|
571
|
-
|
|
572
|
-
console.log('Rendering element:', element);
|
|
573
|
-
console.log('Rendering to container:', vars.wipRoot.dom);
|
|
574
|
-
|
|
575
|
-
vars.deletions = [];
|
|
576
|
-
vars.nextUnitOfWork = vars.wipRoot;
|
|
577
|
-
requestIdleCallback(workLoop);
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
* Initializes the app with a root container.
|
|
582
|
-
*/
|
|
583
|
-
const init = (rootId = '__ryunix') => {
|
|
584
|
-
const rootElement = document.getElementById(rootId);
|
|
585
|
-
if (!rootElement) {
|
|
586
|
-
console.error(`Root element with ID '${rootId}' not found.`);
|
|
587
|
-
return null
|
|
588
|
-
}
|
|
589
|
-
console.log('Container initialized:', vars.containerRoot);
|
|
590
|
-
|
|
591
|
-
vars.containerRoot = rootElement;
|
|
592
|
-
return undefined
|
|
593
|
-
};
|
|
594
|
-
|
|
595
|
-
/**
|
|
596
|
-
* useStore is similar to useState in React, managing local state within a functional component.
|
|
597
|
-
*/
|
|
598
|
-
const useStore = (initial) => {
|
|
599
|
-
const oldHook = vars.workInProgressFiber.alternate?.hooks?.[vars.hookIndex];
|
|
600
|
-
const hook = { state: oldHook ? oldHook.state : initial, queue: [] };
|
|
601
|
-
|
|
602
|
-
const actions = oldHook ? oldHook.queue : [];
|
|
603
|
-
actions.forEach((action) => {
|
|
604
|
-
hook.state = typeof action === 'function' ? action(hook.state) : action;
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
const setState = (action) => {
|
|
608
|
-
hook.queue.push(action);
|
|
609
|
-
vars.wipRoot = {
|
|
610
|
-
dom: vars.currentRoot.dom,
|
|
611
|
-
props: vars.currentRoot.props,
|
|
612
|
-
alternate: vars.currentRoot,
|
|
613
|
-
};
|
|
614
|
-
vars.nextUnitOfWork = vars.wipRoot;
|
|
615
|
-
vars.deletions = [];
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
vars.workInProgressFiber.hooks.push(hook);
|
|
619
|
-
vars.hookIndex++;
|
|
620
|
-
return [hook.state, setState]
|
|
621
|
-
};
|
|
622
|
-
|
|
623
|
-
/**
|
|
624
|
-
* useEffect runs side effects after rendering based on dependencies.
|
|
625
|
-
*/
|
|
626
|
-
const useEffect = (callback, deps) => {
|
|
627
|
-
const oldHook = vars.workInProgressFiber.alternate?.hooks?.[vars.hookIndex];
|
|
628
|
-
const hook = { type: 'effect', deps };
|
|
629
|
-
|
|
630
|
-
const hasChanged = !oldHook || !lodash.isEqual(oldHook.deps, deps);
|
|
631
|
-
if (hasChanged) {
|
|
632
|
-
const cleanup = callback();
|
|
633
|
-
hook.cleanup = cleanup;
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
vars.workInProgressFiber.hooks.push(hook);
|
|
637
|
-
vars.hookIndex++;
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
/**
|
|
641
|
-
* useRef creates a mutable ref object to store values across renders.
|
|
642
|
-
*/
|
|
643
|
-
const useRef = (initialValue) => {
|
|
644
|
-
const oldHook = vars.workInProgressFiber.alternate?.hooks?.[vars.hookIndex];
|
|
645
|
-
const hook = { value: oldHook ? oldHook.value : { current: initialValue } };
|
|
646
|
-
|
|
647
|
-
vars.workInProgressFiber.hooks.push(hook);
|
|
648
|
-
vars.hookIndex++;
|
|
649
|
-
return hook.value
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* useMemo memoizes a value to avoid recomputations.
|
|
654
|
-
*/
|
|
655
|
-
const useMemo = (computeFn, deps) => {
|
|
656
|
-
const oldHook = vars.workInProgressFiber.alternate?.hooks?.[vars.hookIndex];
|
|
657
|
-
const hook = {
|
|
658
|
-
deps,
|
|
659
|
-
value: oldHook && lodash.isEqual(deps, oldHook.deps) ? oldHook.value : computeFn(),
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
vars.workInProgressFiber.hooks.push(hook);
|
|
663
|
-
vars.hookIndex++;
|
|
664
|
-
return hook.value
|
|
665
|
-
};
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
* useCallback memoizes a callback function to avoid unnecessary recreations.
|
|
669
|
-
*/
|
|
670
|
-
const useCallback = (callback, deps) => useMemo(() => callback, deps);
|
|
671
|
-
|
|
672
726
|
var Ryunix = {
|
|
673
727
|
createElement,
|
|
674
728
|
render,
|
|
@@ -688,7 +742,9 @@
|
|
|
688
742
|
exports.useCallback = useCallback;
|
|
689
743
|
exports.useEffect = useEffect;
|
|
690
744
|
exports.useMemo = useMemo;
|
|
745
|
+
exports.useQuery = useQuery;
|
|
691
746
|
exports.useRef = useRef;
|
|
747
|
+
exports.useRouter = useRouter;
|
|
692
748
|
exports.useStore = useStore;
|
|
693
749
|
|
|
694
750
|
Object.defineProperty(exports, '__esModule', { value: true });
|