@unsetsoft/ryunixjs 0.4.15-nightly.8 → 0.5.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 +177 -177
- package/package.json +3 -9
- package/src/lib/commits.js +9 -7
- package/src/lib/components.js +11 -3
- package/src/lib/createElement.js +23 -13
- package/src/lib/hooks.js +79 -17
- package/src/lib/index.js +18 -4
- package/src/lib/reconciler.js +6 -6
- package/src/lib/workers.js +2 -1
- package/src/main.js +3 -3
- package/src/utils/index.js +11 -7
- package/src/lib/navigation.js +0 -91
package/dist/Ryunix.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Ryunix = {}));
|
|
5
|
-
})(this, (function (exports) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('lodash')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'lodash'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Ryunix = {}, global.lodash));
|
|
5
|
+
})(this, (function (exports, lodash) { 'use strict';
|
|
6
6
|
|
|
7
7
|
const vars = {
|
|
8
|
-
containerRoot:
|
|
9
|
-
nextUnitOfWork:
|
|
10
|
-
currentRoot:
|
|
11
|
-
wipRoot:
|
|
12
|
-
deletions:
|
|
13
|
-
wipFiber:
|
|
14
|
-
hookIndex:
|
|
8
|
+
containerRoot: undefined,
|
|
9
|
+
nextUnitOfWork: undefined,
|
|
10
|
+
currentRoot: undefined,
|
|
11
|
+
wipRoot: undefined,
|
|
12
|
+
deletions: undefined,
|
|
13
|
+
wipFiber: undefined,
|
|
14
|
+
hookIndex: undefined,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
const reg = /[A-Z]/g;
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
const RYUNIX_TYPES = Object.freeze({
|
|
20
20
|
TEXT_ELEMENT: Symbol('text.element'),
|
|
21
21
|
RYUNIX_EFFECT: Symbol('ryunix.effect'),
|
|
22
|
+
RYUNIX_MEMO: Symbol('ryunix.memo'),
|
|
23
|
+
RYUNIX_URL_QUERY: Symbol('ryunix.urlQuery'),
|
|
24
|
+
RYUNIX_REF: Symbol('ryunix.ref'),
|
|
22
25
|
});
|
|
23
26
|
|
|
24
27
|
const STRINGS = Object.freeze({
|
|
@@ -27,6 +30,7 @@
|
|
|
27
30
|
style: 'ryunix-style',
|
|
28
31
|
className: 'ryunix-class',
|
|
29
32
|
children: 'children',
|
|
33
|
+
boolean: 'boolean',
|
|
30
34
|
});
|
|
31
35
|
|
|
32
36
|
const OLD_STRINGS = Object.freeze({
|
|
@@ -40,14 +44,20 @@
|
|
|
40
44
|
DELETION: Symbol(),
|
|
41
45
|
});
|
|
42
46
|
|
|
43
|
-
const
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const Fragments = (props) => {
|
|
48
|
+
return props.children
|
|
49
|
+
};
|
|
50
|
+
|
|
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
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
out.push(children);
|
|
50
59
|
}
|
|
60
|
+
return out
|
|
51
61
|
};
|
|
52
62
|
|
|
53
63
|
/**
|
|
@@ -68,24 +78,33 @@
|
|
|
68
78
|
*/
|
|
69
79
|
|
|
70
80
|
const createElement = (type, props, ...children) => {
|
|
81
|
+
children = childArray(children, []);
|
|
71
82
|
return {
|
|
72
83
|
type,
|
|
73
84
|
props: {
|
|
74
85
|
...props,
|
|
75
|
-
children: children
|
|
76
|
-
.
|
|
77
|
-
|
|
78
|
-
typeof child === STRINGS.object && child !== null
|
|
79
|
-
? cloneElement(child, { key: index })
|
|
80
|
-
: child,
|
|
81
|
-
),
|
|
86
|
+
children: children.map((child) =>
|
|
87
|
+
typeof child === STRINGS.object ? child : createTextElement(child),
|
|
88
|
+
),
|
|
82
89
|
},
|
|
83
90
|
}
|
|
84
91
|
};
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
93
|
+
/**
|
|
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.
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
const createTextElement = (text) => {
|
|
101
|
+
return {
|
|
102
|
+
type: RYUNIX_TYPES.TEXT_ELEMENT,
|
|
103
|
+
props: {
|
|
104
|
+
nodeValue: text,
|
|
105
|
+
children: [],
|
|
106
|
+
},
|
|
107
|
+
}
|
|
89
108
|
};
|
|
90
109
|
|
|
91
110
|
/**
|
|
@@ -118,50 +137,6 @@
|
|
|
118
137
|
vars.containerRoot = document.getElementById(rootElement);
|
|
119
138
|
};
|
|
120
139
|
|
|
121
|
-
const isEvent = (key) => key.startsWith('on');
|
|
122
|
-
const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
|
|
123
|
-
const isNew = (prev, next) => (key) => prev[key] !== next[key];
|
|
124
|
-
const isGone = (next) => (key) => !(key in next);
|
|
125
|
-
const hasDepsChanged = (prevDeps, nextDeps) =>
|
|
126
|
-
!prevDeps ||
|
|
127
|
-
!nextDeps ||
|
|
128
|
-
prevDeps.length !== nextDeps.length ||
|
|
129
|
-
prevDeps.some((dep, index) => dep !== nextDeps[index]);
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* The function cancels all effect hooks in a given fiber.
|
|
133
|
-
* @param fiber - The "fiber" parameter is likely referring to a data structure used in React.js to
|
|
134
|
-
* represent a component and its state. It contains information about the component's props, state, and
|
|
135
|
-
* children, as well as metadata used by React to manage updates and rendering. The function
|
|
136
|
-
* "cancelEffects" is likely intended
|
|
137
|
-
*/
|
|
138
|
-
const cancelEffects = (fiber) => {
|
|
139
|
-
if (fiber.hooks) {
|
|
140
|
-
fiber.hooks
|
|
141
|
-
.filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.cancel)
|
|
142
|
-
.forEach((effectHook) => {
|
|
143
|
-
effectHook.cancel();
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* The function runs all effect hooks in a given fiber.
|
|
150
|
-
* @param fiber - The "fiber" parameter is likely referring to a data structure used in the
|
|
151
|
-
* implementation of a fiber-based reconciliation algorithm, such as the one used in React. A fiber
|
|
152
|
-
* represents a unit of work that needs to be performed by the reconciliation algorithm, and it
|
|
153
|
-
* contains information about a component and its children, as
|
|
154
|
-
*/
|
|
155
|
-
const runEffects = (fiber) => {
|
|
156
|
-
if (fiber.hooks) {
|
|
157
|
-
fiber.hooks
|
|
158
|
-
.filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.effect)
|
|
159
|
-
.forEach((effectHook) => {
|
|
160
|
-
effectHook.cancel = effectHook.effect();
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
140
|
/**
|
|
166
141
|
* @description The function creates a state.
|
|
167
142
|
* @param initial - The initial value of the state for the hook.
|
|
@@ -202,8 +177,10 @@
|
|
|
202
177
|
vars.deletions = [];
|
|
203
178
|
};
|
|
204
179
|
|
|
205
|
-
vars.wipFiber.hooks
|
|
206
|
-
|
|
180
|
+
if (vars.wipFiber && vars.wipFiber.hooks) {
|
|
181
|
+
vars.wipFiber.hooks.push(hook);
|
|
182
|
+
vars.hookIndex++;
|
|
183
|
+
}
|
|
207
184
|
return [hook.state, setState]
|
|
208
185
|
};
|
|
209
186
|
|
|
@@ -216,23 +193,31 @@
|
|
|
216
193
|
* between renders, the effect will be re-run. If the array is empty, the effect will only run once on
|
|
217
194
|
* mount and never again.
|
|
218
195
|
*/
|
|
219
|
-
|
|
196
|
+
|
|
197
|
+
const useEffect = (callback, deps) => {
|
|
220
198
|
const oldHook =
|
|
221
199
|
vars.wipFiber.alternate &&
|
|
222
200
|
vars.wipFiber.alternate.hooks &&
|
|
223
201
|
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
224
202
|
|
|
225
|
-
const hasChanged = hasDepsChanged(oldHook ? oldHook.deps : undefined, deps);
|
|
226
|
-
|
|
227
203
|
const hook = {
|
|
228
|
-
|
|
229
|
-
effect: hasChanged ? effect : null,
|
|
230
|
-
cancel: hasChanged && oldHook && oldHook.cancel,
|
|
204
|
+
type: RYUNIX_TYPES.RYUNIX_EFFECT,
|
|
231
205
|
deps,
|
|
232
206
|
};
|
|
233
207
|
|
|
234
|
-
|
|
235
|
-
|
|
208
|
+
if (!oldHook) {
|
|
209
|
+
// invoke callback if this is the first time
|
|
210
|
+
callback();
|
|
211
|
+
} else {
|
|
212
|
+
if (!lodash.isEqual(oldHook.deps, hook.deps)) {
|
|
213
|
+
callback();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (vars.wipFiber.hooks) {
|
|
218
|
+
vars.wipFiber.hooks.push(hook);
|
|
219
|
+
vars.hookIndex++;
|
|
220
|
+
}
|
|
236
221
|
};
|
|
237
222
|
|
|
238
223
|
/**
|
|
@@ -241,8 +226,6 @@
|
|
|
241
226
|
* @returns The `useQuery` function returns the `query` property of the `hook` object.
|
|
242
227
|
*/
|
|
243
228
|
const useQuery = () => {
|
|
244
|
-
vars.hookIndex++;
|
|
245
|
-
|
|
246
229
|
const oldHook =
|
|
247
230
|
vars.wipFiber.alternate &&
|
|
248
231
|
vars.wipFiber.alternate.hooks &&
|
|
@@ -255,101 +238,107 @@
|
|
|
255
238
|
const Query = hasOld ? hasOld : params;
|
|
256
239
|
|
|
257
240
|
const hook = {
|
|
258
|
-
|
|
241
|
+
type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
|
|
259
242
|
query: Query,
|
|
260
243
|
};
|
|
261
244
|
|
|
262
|
-
vars.wipFiber.hooks
|
|
245
|
+
if (vars.wipFiber.hooks) {
|
|
246
|
+
vars.wipFiber.hooks.push(hook);
|
|
247
|
+
vars.hookIndex++;
|
|
248
|
+
}
|
|
263
249
|
|
|
264
250
|
return hook.query
|
|
265
251
|
};
|
|
266
252
|
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
setCurrentPath(() => window.location.pathname);
|
|
273
|
-
};
|
|
253
|
+
const useRef = (initial) => {
|
|
254
|
+
const oldHook =
|
|
255
|
+
vars.wipFiber.alternate &&
|
|
256
|
+
vars.wipFiber.alternate.hooks &&
|
|
257
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
274
258
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
259
|
+
const hook = {
|
|
260
|
+
type: RYUNIX_TYPES.RYUNIX_REF,
|
|
261
|
+
value: oldHook ? oldHook.value : { current: initial },
|
|
262
|
+
};
|
|
278
263
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
window.removeEventListener('popstate', onLocationChange);
|
|
284
|
-
}, 100);
|
|
285
|
-
}
|
|
286
|
-
}, [currentPath]);
|
|
264
|
+
if (vars.wipFiber.hooks) {
|
|
265
|
+
vars.wipFiber.hooks.push(hook);
|
|
266
|
+
vars.hookIndex++;
|
|
267
|
+
}
|
|
287
268
|
|
|
288
|
-
return
|
|
269
|
+
return hook.value
|
|
289
270
|
};
|
|
290
271
|
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
* navigate.
|
|
297
|
-
* @param [state] - The `state` parameter is an optional object that represents the state associated
|
|
298
|
-
* with the new history entry. It can be used to store any data that you want to associate with the
|
|
299
|
-
* new URL. When you navigate back or forward in the browser history, this state object will be
|
|
300
|
-
* passed to the `popstate
|
|
301
|
-
* @returns The function `push` does not have a return statement, so it returns `undefined` by
|
|
302
|
-
* default.
|
|
303
|
-
*/
|
|
304
|
-
const push = (to, state = {}) => {
|
|
305
|
-
if (window.location.pathname === to) return
|
|
272
|
+
const useMemo = (comp, deps) => {
|
|
273
|
+
const oldHook =
|
|
274
|
+
vars.wipFiber.alternate &&
|
|
275
|
+
vars.wipFiber.alternate.hooks &&
|
|
276
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
306
277
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
278
|
+
const hook = {
|
|
279
|
+
type: RYUNIX_TYPES.RYUNIX_MEMO,
|
|
280
|
+
value: null,
|
|
281
|
+
deps,
|
|
310
282
|
};
|
|
311
283
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
)
|
|
320
|
-
}
|
|
321
|
-
if (props.to === '') {
|
|
322
|
-
throw new Error("'to=' cannot be empty.")
|
|
323
|
-
}
|
|
324
|
-
if (props.className === '') {
|
|
325
|
-
throw new Error('className cannot be empty.')
|
|
326
|
-
}
|
|
327
|
-
if (props.label === '' && !props.children) {
|
|
328
|
-
throw new Error("'label=' cannot be empty.")
|
|
284
|
+
if (oldHook) {
|
|
285
|
+
if (lodash.isEqual(oldHook.deps, hook.deps)) {
|
|
286
|
+
hook.value = oldHook.value;
|
|
287
|
+
} else {
|
|
288
|
+
hook.value = comp();
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
hook.value = comp();
|
|
329
292
|
}
|
|
330
293
|
|
|
331
|
-
if (
|
|
332
|
-
|
|
294
|
+
if (vars.wipFiber.hooks) {
|
|
295
|
+
vars.wipFiber.hooks.push(hook);
|
|
296
|
+
vars.hookIndex++;
|
|
333
297
|
}
|
|
334
|
-
const preventReload = (event) => {
|
|
335
|
-
if (event.metaKey || event.ctrlKey) {
|
|
336
|
-
return
|
|
337
|
-
}
|
|
338
298
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
299
|
+
return hook.value
|
|
300
|
+
};
|
|
301
|
+
const useCallback = (callback, deps) => {
|
|
302
|
+
return useMemo(() => callback, deps)
|
|
303
|
+
};
|
|
343
304
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
};
|
|
305
|
+
const isEvent = (key) => key.startsWith('on');
|
|
306
|
+
const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
|
|
307
|
+
const isNew = (prev, next) => (key) => prev[key] !== next[key];
|
|
308
|
+
const isGone = (next) => (key) => !(key in next);
|
|
349
309
|
|
|
350
|
-
|
|
310
|
+
/**
|
|
311
|
+
* The function cancels all effect hooks in a given fiber.
|
|
312
|
+
* @param fiber - The "fiber" parameter is likely referring to a data structure used in React.js to
|
|
313
|
+
* represent a component and its state. It contains information about the component's props, state, and
|
|
314
|
+
* children, as well as metadata used by React to manage updates and rendering. The function
|
|
315
|
+
* "cancelEffects" is likely intended
|
|
316
|
+
*/
|
|
317
|
+
const cancelEffects = (fiber) => {
|
|
318
|
+
if (fiber.hooks) {
|
|
319
|
+
fiber.hooks
|
|
320
|
+
.filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.cancel)
|
|
321
|
+
.forEach((effectHook) => {
|
|
322
|
+
effectHook.cancel();
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
};
|
|
351
326
|
|
|
352
|
-
|
|
327
|
+
/**
|
|
328
|
+
* The function runs all effect hooks in a given fiber.
|
|
329
|
+
* @param fiber - The "fiber" parameter is likely referring to a data structure used in the
|
|
330
|
+
* implementation of a fiber-based reconciliation algorithm, such as the one used in React. A fiber
|
|
331
|
+
* represents a unit of work that needs to be performed by the reconciliation algorithm, and it
|
|
332
|
+
* contains information about a component and its children, as
|
|
333
|
+
*/
|
|
334
|
+
const runEffects = (fiber) => {
|
|
335
|
+
if (fiber.hooks) {
|
|
336
|
+
fiber.hooks
|
|
337
|
+
.filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.effect)
|
|
338
|
+
.forEach((effectHook) => {
|
|
339
|
+
effectHook.cancel = effectHook.effect();
|
|
340
|
+
});
|
|
341
|
+
}
|
|
353
342
|
};
|
|
354
343
|
|
|
355
344
|
/**
|
|
@@ -456,9 +445,11 @@
|
|
|
456
445
|
*/
|
|
457
446
|
const commitRoot = () => {
|
|
458
447
|
vars.deletions.forEach(commitWork);
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
448
|
+
if (vars.wipRoot && vars.wipRoot.child) {
|
|
449
|
+
commitWork(vars.wipRoot.child);
|
|
450
|
+
vars.currentRoot = vars.wipRoot;
|
|
451
|
+
}
|
|
452
|
+
vars.wipRoot = undefined;
|
|
462
453
|
};
|
|
463
454
|
|
|
464
455
|
/**
|
|
@@ -480,13 +471,13 @@
|
|
|
480
471
|
const domParent = domParentFiber.dom;
|
|
481
472
|
|
|
482
473
|
if (fiber.effectTag === EFFECT_TAGS.PLACEMENT) {
|
|
483
|
-
if (fiber.dom !=
|
|
474
|
+
if (fiber.dom != undefined) {
|
|
484
475
|
domParent.appendChild(fiber.dom);
|
|
485
476
|
}
|
|
486
477
|
runEffects(fiber);
|
|
487
478
|
} else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
|
|
488
479
|
cancelEffects(fiber);
|
|
489
|
-
if (fiber.dom !=
|
|
480
|
+
if (fiber.dom != undefined) {
|
|
490
481
|
updateDom(fiber.dom, fiber.alternate.props, fiber.props);
|
|
491
482
|
}
|
|
492
483
|
runEffects(fiber);
|
|
@@ -508,9 +499,9 @@
|
|
|
508
499
|
* @param domParent - The parent DOM element from which the fiber's DOM element needs to be removed.
|
|
509
500
|
*/
|
|
510
501
|
const commitDeletion = (fiber, domParent) => {
|
|
511
|
-
if (fiber.dom) {
|
|
502
|
+
if (fiber && fiber.dom) {
|
|
512
503
|
domParent.removeChild(fiber.dom);
|
|
513
|
-
} else {
|
|
504
|
+
} else if (fiber && fiber.child) {
|
|
514
505
|
commitDeletion(fiber.child, domParent);
|
|
515
506
|
}
|
|
516
507
|
};
|
|
@@ -536,7 +527,7 @@
|
|
|
536
527
|
let oldFiber = wipFiber.alternate && wipFiber.alternate.child;
|
|
537
528
|
let prevSibling;
|
|
538
529
|
|
|
539
|
-
while (index < elements.length || oldFiber !=
|
|
530
|
+
while (index < elements.length || oldFiber != undefined) {
|
|
540
531
|
const element = elements[index];
|
|
541
532
|
let newFiber;
|
|
542
533
|
|
|
@@ -544,9 +535,9 @@
|
|
|
544
535
|
|
|
545
536
|
if (sameType) {
|
|
546
537
|
newFiber = {
|
|
547
|
-
type: oldFiber.type,
|
|
538
|
+
type: oldFiber ? oldFiber.type : undefined,
|
|
548
539
|
props: element.props,
|
|
549
|
-
dom: oldFiber.dom,
|
|
540
|
+
dom: oldFiber ? oldFiber.dom : undefined,
|
|
550
541
|
parent: wipFiber,
|
|
551
542
|
alternate: oldFiber,
|
|
552
543
|
effectTag: EFFECT_TAGS.UPDATE,
|
|
@@ -556,9 +547,9 @@
|
|
|
556
547
|
newFiber = {
|
|
557
548
|
type: element.type,
|
|
558
549
|
props: element.props,
|
|
559
|
-
dom:
|
|
550
|
+
dom: undefined,
|
|
560
551
|
parent: wipFiber,
|
|
561
|
-
alternate:
|
|
552
|
+
alternate: undefined,
|
|
562
553
|
effectTag: EFFECT_TAGS.PLACEMENT,
|
|
563
554
|
};
|
|
564
555
|
}
|
|
@@ -573,7 +564,7 @@
|
|
|
573
564
|
|
|
574
565
|
if (index === 0) {
|
|
575
566
|
wipFiber.child = newFiber;
|
|
576
|
-
} else if (element) {
|
|
567
|
+
} else if (element && prevSibling) {
|
|
577
568
|
prevSibling.sibling = newFiber;
|
|
578
569
|
}
|
|
579
570
|
|
|
@@ -598,8 +589,16 @@
|
|
|
598
589
|
vars.wipFiber = fiber;
|
|
599
590
|
vars.hookIndex = 0;
|
|
600
591
|
vars.wipFiber.hooks = [];
|
|
601
|
-
const children =
|
|
602
|
-
|
|
592
|
+
const children = fiber.type(fiber.props);
|
|
593
|
+
let childArr = [];
|
|
594
|
+
if (Array.isArray(children)) {
|
|
595
|
+
// Fragment results returns array
|
|
596
|
+
childArr = [...children];
|
|
597
|
+
} else {
|
|
598
|
+
// Normal function component returns single root node
|
|
599
|
+
childArr = [children];
|
|
600
|
+
}
|
|
601
|
+
reconcileChildren(fiber, childArr);
|
|
603
602
|
};
|
|
604
603
|
|
|
605
604
|
/**
|
|
@@ -612,7 +611,7 @@
|
|
|
612
611
|
if (!fiber.dom) {
|
|
613
612
|
fiber.dom = createDom(fiber);
|
|
614
613
|
}
|
|
615
|
-
reconcileChildren(fiber, fiber.props.children
|
|
614
|
+
reconcileChildren(fiber, fiber.props.children);
|
|
616
615
|
};
|
|
617
616
|
|
|
618
617
|
var Components = /*#__PURE__*/Object.freeze({
|
|
@@ -655,7 +654,7 @@
|
|
|
655
654
|
* @returns The function `performUnitOfWork` returns the next fiber to be processed. If the current
|
|
656
655
|
* fiber has a child, it returns the child. Otherwise, it looks for the next sibling of the current
|
|
657
656
|
* fiber. If there are no more siblings, it goes up the tree to the parent and looks for the next
|
|
658
|
-
* sibling of the parent. The function returns `
|
|
657
|
+
* sibling of the parent. The function returns `undefined` if there are no more fibers to process.
|
|
659
658
|
*/
|
|
660
659
|
const performUnitOfWork = (fiber) => {
|
|
661
660
|
const isFunctionComponent = fiber.type instanceof Function;
|
|
@@ -674,6 +673,7 @@
|
|
|
674
673
|
}
|
|
675
674
|
nextFiber = nextFiber.parent;
|
|
676
675
|
}
|
|
676
|
+
return undefined
|
|
677
677
|
};
|
|
678
678
|
|
|
679
679
|
var Workers = /*#__PURE__*/Object.freeze({
|
|
@@ -697,12 +697,12 @@
|
|
|
697
697
|
window.Ryunix = Ryunix;
|
|
698
698
|
|
|
699
699
|
exports.Fragments = Fragments;
|
|
700
|
-
exports.Link = Link;
|
|
701
|
-
exports.Navigate = Navigate;
|
|
702
|
-
exports.Router = Router;
|
|
703
700
|
exports.default = Ryunix;
|
|
701
|
+
exports.useCallback = useCallback;
|
|
704
702
|
exports.useEffect = useEffect;
|
|
703
|
+
exports.useMemo = useMemo;
|
|
705
704
|
exports.useQuery = useQuery;
|
|
705
|
+
exports.useRef = useRef;
|
|
706
706
|
exports.useStore = useStore;
|
|
707
707
|
|
|
708
708
|
Object.defineProperty(exports, '__esModule', { value: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unsetsoft/ryunixjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "./dist/Ryunix.js",
|
|
6
6
|
"types": "./dist/Ryunix.d.ts",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
},
|
|
11
11
|
"homepage": "https://github.com/UnSetSoft/Ryunixjs#readme",
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build:ts": "npm run lint && tsc",
|
|
14
13
|
"build:js": "rollup ./src/main.js --file ./dist/Ryunix.js --format umd --name Ryunix",
|
|
15
14
|
"prepublishOnly": "npm run build:js",
|
|
16
15
|
"postinstall": "npm run build:js",
|
|
@@ -20,13 +19,8 @@
|
|
|
20
19
|
},
|
|
21
20
|
"dependencies": {
|
|
22
21
|
"eslint": "8.56.0",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"rollup": "4.9.2",
|
|
26
|
-
"ts-node": "10.9.2",
|
|
27
|
-
"tsup": "8.0.1",
|
|
28
|
-
"typescript": "5.3.3",
|
|
29
|
-
"tslint": "6.1.3"
|
|
22
|
+
"lodash": "^4.17.20",
|
|
23
|
+
"rollup": "4.9.2"
|
|
30
24
|
},
|
|
31
25
|
"engines": {
|
|
32
26
|
"node": ">=18.16.0"
|
package/src/lib/commits.js
CHANGED
|
@@ -7,9 +7,11 @@ import { EFFECT_TAGS, vars } from '../utils/index'
|
|
|
7
7
|
*/
|
|
8
8
|
const commitRoot = () => {
|
|
9
9
|
vars.deletions.forEach(commitWork)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
if (vars.wipRoot && vars.wipRoot.child) {
|
|
11
|
+
commitWork(vars.wipRoot.child)
|
|
12
|
+
vars.currentRoot = vars.wipRoot
|
|
13
|
+
}
|
|
14
|
+
vars.wipRoot = undefined
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
@@ -31,13 +33,13 @@ const commitWork = (fiber) => {
|
|
|
31
33
|
const domParent = domParentFiber.dom
|
|
32
34
|
|
|
33
35
|
if (fiber.effectTag === EFFECT_TAGS.PLACEMENT) {
|
|
34
|
-
if (fiber.dom !=
|
|
36
|
+
if (fiber.dom != undefined) {
|
|
35
37
|
domParent.appendChild(fiber.dom)
|
|
36
38
|
}
|
|
37
39
|
runEffects(fiber)
|
|
38
40
|
} else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
|
|
39
41
|
cancelEffects(fiber)
|
|
40
|
-
if (fiber.dom !=
|
|
42
|
+
if (fiber.dom != undefined) {
|
|
41
43
|
updateDom(fiber.dom, fiber.alternate.props, fiber.props)
|
|
42
44
|
}
|
|
43
45
|
runEffects(fiber)
|
|
@@ -59,9 +61,9 @@ const commitWork = (fiber) => {
|
|
|
59
61
|
* @param domParent - The parent DOM element from which the fiber's DOM element needs to be removed.
|
|
60
62
|
*/
|
|
61
63
|
const commitDeletion = (fiber, domParent) => {
|
|
62
|
-
if (fiber.dom) {
|
|
64
|
+
if (fiber && fiber.dom) {
|
|
63
65
|
domParent.removeChild(fiber.dom)
|
|
64
|
-
} else {
|
|
66
|
+
} else if (fiber && fiber.child) {
|
|
65
67
|
commitDeletion(fiber.child, domParent)
|
|
66
68
|
}
|
|
67
69
|
}
|
package/src/lib/components.js
CHANGED
|
@@ -13,8 +13,16 @@ const updateFunctionComponent = (fiber) => {
|
|
|
13
13
|
vars.wipFiber = fiber
|
|
14
14
|
vars.hookIndex = 0
|
|
15
15
|
vars.wipFiber.hooks = []
|
|
16
|
-
const children =
|
|
17
|
-
|
|
16
|
+
const children = fiber.type(fiber.props)
|
|
17
|
+
let childArr = []
|
|
18
|
+
if (Array.isArray(children)) {
|
|
19
|
+
// Fragment results returns array
|
|
20
|
+
childArr = [...children]
|
|
21
|
+
} else {
|
|
22
|
+
// Normal function component returns single root node
|
|
23
|
+
childArr = [children]
|
|
24
|
+
}
|
|
25
|
+
reconcileChildren(fiber, childArr)
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
/**
|
|
@@ -27,7 +35,7 @@ const updateHostComponent = (fiber) => {
|
|
|
27
35
|
if (!fiber.dom) {
|
|
28
36
|
fiber.dom = createDom(fiber)
|
|
29
37
|
}
|
|
30
|
-
reconcileChildren(fiber, fiber.props.children
|
|
38
|
+
reconcileChildren(fiber, fiber.props.children)
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
export { updateFunctionComponent, updateHostComponent }
|
package/src/lib/createElement.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { RYUNIX_TYPES, STRINGS } from '../utils/index'
|
|
2
2
|
|
|
3
|
+
const Fragments = (props) => {
|
|
4
|
+
return props.children
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const childArray = (children, out) => {
|
|
8
|
+
out = out || []
|
|
9
|
+
if (children == undefined || typeof children == STRINGS.boolean) {
|
|
10
|
+
// pass
|
|
11
|
+
} else if (Array.isArray(children)) {
|
|
12
|
+
children.some((child) => {
|
|
13
|
+
childArray(child, out)
|
|
14
|
+
})
|
|
15
|
+
} else {
|
|
16
|
+
out.push(children)
|
|
17
|
+
}
|
|
18
|
+
return out
|
|
19
|
+
}
|
|
20
|
+
|
|
3
21
|
const cloneElement = (element, props) => {
|
|
4
22
|
return {
|
|
5
23
|
...element,
|
|
@@ -28,17 +46,14 @@ const cloneElement = (element, props) => {
|
|
|
28
46
|
*/
|
|
29
47
|
|
|
30
48
|
const createElement = (type, props, ...children) => {
|
|
49
|
+
children = childArray(children, [])
|
|
31
50
|
return {
|
|
32
51
|
type,
|
|
33
52
|
props: {
|
|
34
53
|
...props,
|
|
35
|
-
children: children
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
typeof child === STRINGS.object && child !== null
|
|
39
|
-
? cloneElement(child, { key: index })
|
|
40
|
-
: child,
|
|
41
|
-
),
|
|
54
|
+
children: children.map((child) =>
|
|
55
|
+
typeof child === STRINGS.object ? child : createTextElement(child),
|
|
56
|
+
),
|
|
42
57
|
},
|
|
43
58
|
}
|
|
44
59
|
}
|
|
@@ -60,9 +75,4 @@ const createTextElement = (text) => {
|
|
|
60
75
|
}
|
|
61
76
|
}
|
|
62
77
|
|
|
63
|
-
|
|
64
|
-
console.log(props)
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export { createElement, createTextElement, Fragments }
|
|
78
|
+
export { createElement, createTextElement, Fragments, cloneElement }
|
package/src/lib/hooks.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { hasDepsChanged } from './effects'
|
|
2
1
|
import { RYUNIX_TYPES, STRINGS, vars } from '../utils/index'
|
|
3
|
-
|
|
2
|
+
import { isEqual } from 'lodash'
|
|
4
3
|
/**
|
|
5
4
|
* @description The function creates a state.
|
|
6
5
|
* @param initial - The initial value of the state for the hook.
|
|
@@ -41,8 +40,10 @@ const useStore = (initial) => {
|
|
|
41
40
|
vars.deletions = []
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
vars.wipFiber.hooks
|
|
45
|
-
|
|
43
|
+
if (vars.wipFiber && vars.wipFiber.hooks) {
|
|
44
|
+
vars.wipFiber.hooks.push(hook)
|
|
45
|
+
vars.hookIndex++
|
|
46
|
+
}
|
|
46
47
|
return [hook.state, setState]
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -55,23 +56,31 @@ const useStore = (initial) => {
|
|
|
55
56
|
* between renders, the effect will be re-run. If the array is empty, the effect will only run once on
|
|
56
57
|
* mount and never again.
|
|
57
58
|
*/
|
|
58
|
-
|
|
59
|
+
|
|
60
|
+
const useEffect = (callback, deps) => {
|
|
59
61
|
const oldHook =
|
|
60
62
|
vars.wipFiber.alternate &&
|
|
61
63
|
vars.wipFiber.alternate.hooks &&
|
|
62
64
|
vars.wipFiber.alternate.hooks[vars.hookIndex]
|
|
63
65
|
|
|
64
|
-
const hasChanged = hasDepsChanged(oldHook ? oldHook.deps : undefined, deps)
|
|
65
|
-
|
|
66
66
|
const hook = {
|
|
67
|
-
|
|
68
|
-
effect: hasChanged ? effect : null,
|
|
69
|
-
cancel: hasChanged && oldHook && oldHook.cancel,
|
|
67
|
+
type: RYUNIX_TYPES.RYUNIX_EFFECT,
|
|
70
68
|
deps,
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
if (!oldHook) {
|
|
72
|
+
// invoke callback if this is the first time
|
|
73
|
+
callback()
|
|
74
|
+
} else {
|
|
75
|
+
if (!isEqual(oldHook.deps, hook.deps)) {
|
|
76
|
+
callback()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (vars.wipFiber.hooks) {
|
|
81
|
+
vars.wipFiber.hooks.push(hook)
|
|
82
|
+
vars.hookIndex++
|
|
83
|
+
}
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
/**
|
|
@@ -80,8 +89,6 @@ const useEffect = (effect, deps) => {
|
|
|
80
89
|
* @returns The `useQuery` function returns the `query` property of the `hook` object.
|
|
81
90
|
*/
|
|
82
91
|
const useQuery = () => {
|
|
83
|
-
vars.hookIndex++
|
|
84
|
-
|
|
85
92
|
const oldHook =
|
|
86
93
|
vars.wipFiber.alternate &&
|
|
87
94
|
vars.wipFiber.alternate.hooks &&
|
|
@@ -94,13 +101,68 @@ const useQuery = () => {
|
|
|
94
101
|
const Query = hasOld ? hasOld : params
|
|
95
102
|
|
|
96
103
|
const hook = {
|
|
97
|
-
|
|
104
|
+
type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
|
|
98
105
|
query: Query,
|
|
99
106
|
}
|
|
100
107
|
|
|
101
|
-
vars.wipFiber.hooks
|
|
108
|
+
if (vars.wipFiber.hooks) {
|
|
109
|
+
vars.wipFiber.hooks.push(hook)
|
|
110
|
+
vars.hookIndex++
|
|
111
|
+
}
|
|
102
112
|
|
|
103
113
|
return hook.query
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
|
|
116
|
+
const useRef = (initial) => {
|
|
117
|
+
const oldHook =
|
|
118
|
+
vars.wipFiber.alternate &&
|
|
119
|
+
vars.wipFiber.alternate.hooks &&
|
|
120
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex]
|
|
121
|
+
|
|
122
|
+
const hook = {
|
|
123
|
+
type: RYUNIX_TYPES.RYUNIX_REF,
|
|
124
|
+
value: oldHook ? oldHook.value : { current: initial },
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (vars.wipFiber.hooks) {
|
|
128
|
+
vars.wipFiber.hooks.push(hook)
|
|
129
|
+
vars.hookIndex++
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return hook.value
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const useMemo = (comp, deps) => {
|
|
136
|
+
const oldHook =
|
|
137
|
+
vars.wipFiber.alternate &&
|
|
138
|
+
vars.wipFiber.alternate.hooks &&
|
|
139
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex]
|
|
140
|
+
|
|
141
|
+
const hook = {
|
|
142
|
+
type: RYUNIX_TYPES.RYUNIX_MEMO,
|
|
143
|
+
value: null,
|
|
144
|
+
deps,
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (oldHook) {
|
|
148
|
+
if (isEqual(oldHook.deps, hook.deps)) {
|
|
149
|
+
hook.value = oldHook.value
|
|
150
|
+
} else {
|
|
151
|
+
hook.value = comp()
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
hook.value = comp()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (vars.wipFiber.hooks) {
|
|
158
|
+
vars.wipFiber.hooks.push(hook)
|
|
159
|
+
vars.hookIndex++
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return hook.value
|
|
163
|
+
}
|
|
164
|
+
const useCallback = (callback, deps) => {
|
|
165
|
+
return useMemo(() => callback, deps)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export { useStore, useEffect, useQuery, useRef, useMemo, useCallback }
|
package/src/lib/index.js
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
import { createElement, Fragments } from './createElement'
|
|
1
|
+
import { createElement, cloneElement, Fragments } from './createElement'
|
|
2
2
|
import { render, init } from './render'
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
useStore,
|
|
5
|
+
useEffect,
|
|
6
|
+
useQuery,
|
|
7
|
+
useRef,
|
|
8
|
+
useMemo,
|
|
9
|
+
useCallback,
|
|
10
|
+
} from './hooks'
|
|
5
11
|
import * as Dom from './dom'
|
|
6
12
|
import * as Workers from './workers'
|
|
7
13
|
import * as Reconciler from './reconciler'
|
|
8
14
|
import * as Components from './components'
|
|
9
15
|
import * as Commits from './commits'
|
|
10
16
|
|
|
11
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
useStore,
|
|
19
|
+
useEffect,
|
|
20
|
+
useQuery,
|
|
21
|
+
useRef,
|
|
22
|
+
useMemo,
|
|
23
|
+
useCallback,
|
|
24
|
+
Fragments,
|
|
25
|
+
}
|
|
12
26
|
|
|
13
27
|
export default {
|
|
14
28
|
createElement,
|
package/src/lib/reconciler.js
CHANGED
|
@@ -14,7 +14,7 @@ const reconcileChildren = (wipFiber, elements) => {
|
|
|
14
14
|
let oldFiber = wipFiber.alternate && wipFiber.alternate.child
|
|
15
15
|
let prevSibling
|
|
16
16
|
|
|
17
|
-
while (index < elements.length || oldFiber !=
|
|
17
|
+
while (index < elements.length || oldFiber != undefined) {
|
|
18
18
|
const element = elements[index]
|
|
19
19
|
let newFiber
|
|
20
20
|
|
|
@@ -22,9 +22,9 @@ const reconcileChildren = (wipFiber, elements) => {
|
|
|
22
22
|
|
|
23
23
|
if (sameType) {
|
|
24
24
|
newFiber = {
|
|
25
|
-
type: oldFiber.type,
|
|
25
|
+
type: oldFiber ? oldFiber.type : undefined,
|
|
26
26
|
props: element.props,
|
|
27
|
-
dom: oldFiber.dom,
|
|
27
|
+
dom: oldFiber ? oldFiber.dom : undefined,
|
|
28
28
|
parent: wipFiber,
|
|
29
29
|
alternate: oldFiber,
|
|
30
30
|
effectTag: EFFECT_TAGS.UPDATE,
|
|
@@ -34,9 +34,9 @@ const reconcileChildren = (wipFiber, elements) => {
|
|
|
34
34
|
newFiber = {
|
|
35
35
|
type: element.type,
|
|
36
36
|
props: element.props,
|
|
37
|
-
dom:
|
|
37
|
+
dom: undefined,
|
|
38
38
|
parent: wipFiber,
|
|
39
|
-
alternate:
|
|
39
|
+
alternate: undefined,
|
|
40
40
|
effectTag: EFFECT_TAGS.PLACEMENT,
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -51,7 +51,7 @@ const reconcileChildren = (wipFiber, elements) => {
|
|
|
51
51
|
|
|
52
52
|
if (index === 0) {
|
|
53
53
|
wipFiber.child = newFiber
|
|
54
|
-
} else if (element) {
|
|
54
|
+
} else if (element && prevSibling) {
|
|
55
55
|
prevSibling.sibling = newFiber
|
|
56
56
|
}
|
|
57
57
|
|
package/src/lib/workers.js
CHANGED
|
@@ -36,7 +36,7 @@ requestIdleCallback(workLoop)
|
|
|
36
36
|
* @returns The function `performUnitOfWork` returns the next fiber to be processed. If the current
|
|
37
37
|
* fiber has a child, it returns the child. Otherwise, it looks for the next sibling of the current
|
|
38
38
|
* fiber. If there are no more siblings, it goes up the tree to the parent and looks for the next
|
|
39
|
-
* sibling of the parent. The function returns `
|
|
39
|
+
* sibling of the parent. The function returns `undefined` if there are no more fibers to process.
|
|
40
40
|
*/
|
|
41
41
|
const performUnitOfWork = (fiber) => {
|
|
42
42
|
const isFunctionComponent = fiber.type instanceof Function
|
|
@@ -55,6 +55,7 @@ const performUnitOfWork = (fiber) => {
|
|
|
55
55
|
}
|
|
56
56
|
nextFiber = nextFiber.parent
|
|
57
57
|
}
|
|
58
|
+
return undefined
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export { performUnitOfWork, workLoop }
|
package/src/main.js
CHANGED
package/src/utils/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const vars = {
|
|
2
|
-
containerRoot:
|
|
3
|
-
nextUnitOfWork:
|
|
4
|
-
currentRoot:
|
|
5
|
-
wipRoot:
|
|
6
|
-
deletions:
|
|
7
|
-
wipFiber:
|
|
8
|
-
hookIndex:
|
|
2
|
+
containerRoot: undefined,
|
|
3
|
+
nextUnitOfWork: undefined,
|
|
4
|
+
currentRoot: undefined,
|
|
5
|
+
wipRoot: undefined,
|
|
6
|
+
deletions: undefined,
|
|
7
|
+
wipFiber: undefined,
|
|
8
|
+
hookIndex: undefined,
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
const reg = /[A-Z]/g
|
|
@@ -13,6 +13,9 @@ const reg = /[A-Z]/g
|
|
|
13
13
|
const RYUNIX_TYPES = Object.freeze({
|
|
14
14
|
TEXT_ELEMENT: Symbol('text.element'),
|
|
15
15
|
RYUNIX_EFFECT: Symbol('ryunix.effect'),
|
|
16
|
+
RYUNIX_MEMO: Symbol('ryunix.memo'),
|
|
17
|
+
RYUNIX_URL_QUERY: Symbol('ryunix.urlQuery'),
|
|
18
|
+
RYUNIX_REF: Symbol('ryunix.ref'),
|
|
16
19
|
})
|
|
17
20
|
|
|
18
21
|
const STRINGS = Object.freeze({
|
|
@@ -21,6 +24,7 @@ const STRINGS = Object.freeze({
|
|
|
21
24
|
style: 'ryunix-style',
|
|
22
25
|
className: 'ryunix-class',
|
|
23
26
|
children: 'children',
|
|
27
|
+
boolean: 'boolean',
|
|
24
28
|
})
|
|
25
29
|
|
|
26
30
|
const OLD_STRINGS = Object.freeze({
|
package/src/lib/navigation.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { useStore, useEffect } from './hooks'
|
|
2
|
-
import { createElement } from './createElement'
|
|
3
|
-
const Router = ({ path, component, children }) => {
|
|
4
|
-
const [currentPath, setCurrentPath] = useStore(window.location.pathname)
|
|
5
|
-
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
const onLocationChange = () => {
|
|
8
|
-
setCurrentPath(() => window.location.pathname)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
window.addEventListener('navigate', onLocationChange)
|
|
12
|
-
window.addEventListener('pushsatate', onLocationChange)
|
|
13
|
-
window.addEventListener('popstate', onLocationChange)
|
|
14
|
-
|
|
15
|
-
return () => {
|
|
16
|
-
setTimeout(() => {
|
|
17
|
-
window.removeEventListener('navigate', onLocationChange)
|
|
18
|
-
window.removeEventListener('pushsatate', onLocationChange)
|
|
19
|
-
window.removeEventListener('popstate', onLocationChange)
|
|
20
|
-
}, 100)
|
|
21
|
-
}
|
|
22
|
-
}, [currentPath])
|
|
23
|
-
|
|
24
|
-
return currentPath === path ? component() : null
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const Navigate = () => {
|
|
28
|
-
/**
|
|
29
|
-
* The function `push` is used to push a new state to the browser's history and trigger a custom
|
|
30
|
-
* event called 'pushstate'.
|
|
31
|
-
* @param to - The `to` parameter is a string representing the URL path to which you want to
|
|
32
|
-
* navigate.
|
|
33
|
-
* @param [state] - The `state` parameter is an optional object that represents the state associated
|
|
34
|
-
* with the new history entry. It can be used to store any data that you want to associate with the
|
|
35
|
-
* new URL. When you navigate back or forward in the browser history, this state object will be
|
|
36
|
-
* passed to the `popstate
|
|
37
|
-
* @returns The function `push` does not have a return statement, so it returns `undefined` by
|
|
38
|
-
* default.
|
|
39
|
-
*/
|
|
40
|
-
const push = (to, state = {}) => {
|
|
41
|
-
if (window.location.pathname === to) return
|
|
42
|
-
|
|
43
|
-
window.history.pushState(state, '', to)
|
|
44
|
-
const navigationEvent = new PopStateEvent('popstate')
|
|
45
|
-
window.dispatchEvent(navigationEvent)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return { push }
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const Link = (props) => {
|
|
52
|
-
if (props.style) {
|
|
53
|
-
throw new Error(
|
|
54
|
-
'The style attribute is not supported on internal components, use className.',
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
if (props.to === '') {
|
|
58
|
-
throw new Error("'to=' cannot be empty.")
|
|
59
|
-
}
|
|
60
|
-
if (props.className === '') {
|
|
61
|
-
throw new Error('className cannot be empty.')
|
|
62
|
-
}
|
|
63
|
-
if (props.label === '' && !props.children) {
|
|
64
|
-
throw new Error("'label=' cannot be empty.")
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (!props.to) {
|
|
68
|
-
throw new Error("Missig 'to' param.")
|
|
69
|
-
}
|
|
70
|
-
const preventReload = (event) => {
|
|
71
|
-
if (event.metaKey || event.ctrlKey) {
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
event.preventDefault()
|
|
76
|
-
const { push } = Navigate()
|
|
77
|
-
push(props.to)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const anchor = {
|
|
81
|
-
href: props.to,
|
|
82
|
-
onClick: preventReload,
|
|
83
|
-
...props,
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const children = props.label ? props.label : props.children
|
|
87
|
-
|
|
88
|
-
return createElement('a', anchor, children)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export { Router, Navigate, Link }
|