@unsetsoft/ryunixjs 0.4.15-nightly.9 → 0.5.2
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 -178
- 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 -14
- 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,25 +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
|
-
|
|
89
|
-
|
|
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
|
+
}
|
|
90
108
|
};
|
|
91
109
|
|
|
92
110
|
/**
|
|
@@ -119,50 +137,6 @@
|
|
|
119
137
|
vars.containerRoot = document.getElementById(rootElement);
|
|
120
138
|
};
|
|
121
139
|
|
|
122
|
-
const isEvent = (key) => key.startsWith('on');
|
|
123
|
-
const isProperty = (key) => key !== STRINGS.children && !isEvent(key);
|
|
124
|
-
const isNew = (prev, next) => (key) => prev[key] !== next[key];
|
|
125
|
-
const isGone = (next) => (key) => !(key in next);
|
|
126
|
-
const hasDepsChanged = (prevDeps, nextDeps) =>
|
|
127
|
-
!prevDeps ||
|
|
128
|
-
!nextDeps ||
|
|
129
|
-
prevDeps.length !== nextDeps.length ||
|
|
130
|
-
prevDeps.some((dep, index) => dep !== nextDeps[index]);
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* The function cancels all effect hooks in a given fiber.
|
|
134
|
-
* @param fiber - The "fiber" parameter is likely referring to a data structure used in React.js to
|
|
135
|
-
* represent a component and its state. It contains information about the component's props, state, and
|
|
136
|
-
* children, as well as metadata used by React to manage updates and rendering. The function
|
|
137
|
-
* "cancelEffects" is likely intended
|
|
138
|
-
*/
|
|
139
|
-
const cancelEffects = (fiber) => {
|
|
140
|
-
if (fiber.hooks) {
|
|
141
|
-
fiber.hooks
|
|
142
|
-
.filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.cancel)
|
|
143
|
-
.forEach((effectHook) => {
|
|
144
|
-
effectHook.cancel();
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* The function runs all effect hooks in a given fiber.
|
|
151
|
-
* @param fiber - The "fiber" parameter is likely referring to a data structure used in the
|
|
152
|
-
* implementation of a fiber-based reconciliation algorithm, such as the one used in React. A fiber
|
|
153
|
-
* represents a unit of work that needs to be performed by the reconciliation algorithm, and it
|
|
154
|
-
* contains information about a component and its children, as
|
|
155
|
-
*/
|
|
156
|
-
const runEffects = (fiber) => {
|
|
157
|
-
if (fiber.hooks) {
|
|
158
|
-
fiber.hooks
|
|
159
|
-
.filter((hook) => hook.tag === RYUNIX_TYPES.RYUNIX_EFFECT && hook.effect)
|
|
160
|
-
.forEach((effectHook) => {
|
|
161
|
-
effectHook.cancel = effectHook.effect();
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
|
|
166
140
|
/**
|
|
167
141
|
* @description The function creates a state.
|
|
168
142
|
* @param initial - The initial value of the state for the hook.
|
|
@@ -203,8 +177,10 @@
|
|
|
203
177
|
vars.deletions = [];
|
|
204
178
|
};
|
|
205
179
|
|
|
206
|
-
vars.wipFiber.hooks
|
|
207
|
-
|
|
180
|
+
if (vars.wipFiber && vars.wipFiber.hooks) {
|
|
181
|
+
vars.wipFiber.hooks.push(hook);
|
|
182
|
+
vars.hookIndex++;
|
|
183
|
+
}
|
|
208
184
|
return [hook.state, setState]
|
|
209
185
|
};
|
|
210
186
|
|
|
@@ -217,23 +193,31 @@
|
|
|
217
193
|
* between renders, the effect will be re-run. If the array is empty, the effect will only run once on
|
|
218
194
|
* mount and never again.
|
|
219
195
|
*/
|
|
220
|
-
|
|
196
|
+
|
|
197
|
+
const useEffect = (callback, deps) => {
|
|
221
198
|
const oldHook =
|
|
222
199
|
vars.wipFiber.alternate &&
|
|
223
200
|
vars.wipFiber.alternate.hooks &&
|
|
224
201
|
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
225
202
|
|
|
226
|
-
const hasChanged = hasDepsChanged(oldHook ? oldHook.deps : undefined, deps);
|
|
227
|
-
|
|
228
203
|
const hook = {
|
|
229
|
-
|
|
230
|
-
effect: hasChanged ? effect : null,
|
|
231
|
-
cancel: hasChanged && oldHook && oldHook.cancel,
|
|
204
|
+
type: RYUNIX_TYPES.RYUNIX_EFFECT,
|
|
232
205
|
deps,
|
|
233
206
|
};
|
|
234
207
|
|
|
235
|
-
|
|
236
|
-
|
|
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
|
+
}
|
|
237
221
|
};
|
|
238
222
|
|
|
239
223
|
/**
|
|
@@ -242,8 +226,6 @@
|
|
|
242
226
|
* @returns The `useQuery` function returns the `query` property of the `hook` object.
|
|
243
227
|
*/
|
|
244
228
|
const useQuery = () => {
|
|
245
|
-
vars.hookIndex++;
|
|
246
|
-
|
|
247
229
|
const oldHook =
|
|
248
230
|
vars.wipFiber.alternate &&
|
|
249
231
|
vars.wipFiber.alternate.hooks &&
|
|
@@ -256,101 +238,107 @@
|
|
|
256
238
|
const Query = hasOld ? hasOld : params;
|
|
257
239
|
|
|
258
240
|
const hook = {
|
|
259
|
-
|
|
241
|
+
type: RYUNIX_TYPES.RYUNIX_URL_QUERY,
|
|
260
242
|
query: Query,
|
|
261
243
|
};
|
|
262
244
|
|
|
263
|
-
vars.wipFiber.hooks
|
|
245
|
+
if (vars.wipFiber.hooks) {
|
|
246
|
+
vars.wipFiber.hooks.push(hook);
|
|
247
|
+
vars.hookIndex++;
|
|
248
|
+
}
|
|
264
249
|
|
|
265
250
|
return hook.query
|
|
266
251
|
};
|
|
267
252
|
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
setCurrentPath(() => window.location.pathname);
|
|
274
|
-
};
|
|
253
|
+
const useRef = (initial) => {
|
|
254
|
+
const oldHook =
|
|
255
|
+
vars.wipFiber.alternate &&
|
|
256
|
+
vars.wipFiber.alternate.hooks &&
|
|
257
|
+
vars.wipFiber.alternate.hooks[vars.hookIndex];
|
|
275
258
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
259
|
+
const hook = {
|
|
260
|
+
type: RYUNIX_TYPES.RYUNIX_REF,
|
|
261
|
+
value: oldHook ? oldHook.value : { current: initial },
|
|
262
|
+
};
|
|
279
263
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
window.removeEventListener('popstate', onLocationChange);
|
|
285
|
-
}, 100);
|
|
286
|
-
}
|
|
287
|
-
}, [currentPath]);
|
|
264
|
+
if (vars.wipFiber.hooks) {
|
|
265
|
+
vars.wipFiber.hooks.push(hook);
|
|
266
|
+
vars.hookIndex++;
|
|
267
|
+
}
|
|
288
268
|
|
|
289
|
-
return
|
|
269
|
+
return hook.value
|
|
290
270
|
};
|
|
291
271
|
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
* navigate.
|
|
298
|
-
* @param [state] - The `state` parameter is an optional object that represents the state associated
|
|
299
|
-
* with the new history entry. It can be used to store any data that you want to associate with the
|
|
300
|
-
* new URL. When you navigate back or forward in the browser history, this state object will be
|
|
301
|
-
* passed to the `popstate
|
|
302
|
-
* @returns The function `push` does not have a return statement, so it returns `undefined` by
|
|
303
|
-
* default.
|
|
304
|
-
*/
|
|
305
|
-
const push = (to, state = {}) => {
|
|
306
|
-
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];
|
|
307
277
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
278
|
+
const hook = {
|
|
279
|
+
type: RYUNIX_TYPES.RYUNIX_MEMO,
|
|
280
|
+
value: null,
|
|
281
|
+
deps,
|
|
311
282
|
};
|
|
312
283
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
)
|
|
321
|
-
}
|
|
322
|
-
if (props.to === '') {
|
|
323
|
-
throw new Error("'to=' cannot be empty.")
|
|
324
|
-
}
|
|
325
|
-
if (props.className === '') {
|
|
326
|
-
throw new Error('className cannot be empty.')
|
|
327
|
-
}
|
|
328
|
-
if (props.label === '' && !props.children) {
|
|
329
|
-
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();
|
|
330
292
|
}
|
|
331
293
|
|
|
332
|
-
if (
|
|
333
|
-
|
|
294
|
+
if (vars.wipFiber.hooks) {
|
|
295
|
+
vars.wipFiber.hooks.push(hook);
|
|
296
|
+
vars.hookIndex++;
|
|
334
297
|
}
|
|
335
|
-
const preventReload = (event) => {
|
|
336
|
-
if (event.metaKey || event.ctrlKey) {
|
|
337
|
-
return
|
|
338
|
-
}
|
|
339
298
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
299
|
+
return hook.value
|
|
300
|
+
};
|
|
301
|
+
const useCallback = (callback, deps) => {
|
|
302
|
+
return useMemo(() => callback, deps)
|
|
303
|
+
};
|
|
344
304
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
};
|
|
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);
|
|
350
309
|
|
|
351
|
-
|
|
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
|
+
};
|
|
352
326
|
|
|
353
|
-
|
|
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
|
+
}
|
|
354
342
|
};
|
|
355
343
|
|
|
356
344
|
/**
|
|
@@ -457,9 +445,11 @@
|
|
|
457
445
|
*/
|
|
458
446
|
const commitRoot = () => {
|
|
459
447
|
vars.deletions.forEach(commitWork);
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
448
|
+
if (vars.wipRoot && vars.wipRoot.child) {
|
|
449
|
+
commitWork(vars.wipRoot.child);
|
|
450
|
+
vars.currentRoot = vars.wipRoot;
|
|
451
|
+
}
|
|
452
|
+
vars.wipRoot = undefined;
|
|
463
453
|
};
|
|
464
454
|
|
|
465
455
|
/**
|
|
@@ -481,13 +471,13 @@
|
|
|
481
471
|
const domParent = domParentFiber.dom;
|
|
482
472
|
|
|
483
473
|
if (fiber.effectTag === EFFECT_TAGS.PLACEMENT) {
|
|
484
|
-
if (fiber.dom !=
|
|
474
|
+
if (fiber.dom != undefined) {
|
|
485
475
|
domParent.appendChild(fiber.dom);
|
|
486
476
|
}
|
|
487
477
|
runEffects(fiber);
|
|
488
478
|
} else if (fiber.effectTag === EFFECT_TAGS.UPDATE) {
|
|
489
479
|
cancelEffects(fiber);
|
|
490
|
-
if (fiber.dom !=
|
|
480
|
+
if (fiber.dom != undefined) {
|
|
491
481
|
updateDom(fiber.dom, fiber.alternate.props, fiber.props);
|
|
492
482
|
}
|
|
493
483
|
runEffects(fiber);
|
|
@@ -509,9 +499,9 @@
|
|
|
509
499
|
* @param domParent - The parent DOM element from which the fiber's DOM element needs to be removed.
|
|
510
500
|
*/
|
|
511
501
|
const commitDeletion = (fiber, domParent) => {
|
|
512
|
-
if (fiber.dom) {
|
|
502
|
+
if (fiber && fiber.dom) {
|
|
513
503
|
domParent.removeChild(fiber.dom);
|
|
514
|
-
} else {
|
|
504
|
+
} else if (fiber && fiber.child) {
|
|
515
505
|
commitDeletion(fiber.child, domParent);
|
|
516
506
|
}
|
|
517
507
|
};
|
|
@@ -537,7 +527,7 @@
|
|
|
537
527
|
let oldFiber = wipFiber.alternate && wipFiber.alternate.child;
|
|
538
528
|
let prevSibling;
|
|
539
529
|
|
|
540
|
-
while (index < elements.length || oldFiber !=
|
|
530
|
+
while (index < elements.length || oldFiber != undefined) {
|
|
541
531
|
const element = elements[index];
|
|
542
532
|
let newFiber;
|
|
543
533
|
|
|
@@ -545,9 +535,9 @@
|
|
|
545
535
|
|
|
546
536
|
if (sameType) {
|
|
547
537
|
newFiber = {
|
|
548
|
-
type: oldFiber.type,
|
|
538
|
+
type: oldFiber ? oldFiber.type : undefined,
|
|
549
539
|
props: element.props,
|
|
550
|
-
dom: oldFiber.dom,
|
|
540
|
+
dom: oldFiber ? oldFiber.dom : undefined,
|
|
551
541
|
parent: wipFiber,
|
|
552
542
|
alternate: oldFiber,
|
|
553
543
|
effectTag: EFFECT_TAGS.UPDATE,
|
|
@@ -557,9 +547,9 @@
|
|
|
557
547
|
newFiber = {
|
|
558
548
|
type: element.type,
|
|
559
549
|
props: element.props,
|
|
560
|
-
dom:
|
|
550
|
+
dom: undefined,
|
|
561
551
|
parent: wipFiber,
|
|
562
|
-
alternate:
|
|
552
|
+
alternate: undefined,
|
|
563
553
|
effectTag: EFFECT_TAGS.PLACEMENT,
|
|
564
554
|
};
|
|
565
555
|
}
|
|
@@ -574,7 +564,7 @@
|
|
|
574
564
|
|
|
575
565
|
if (index === 0) {
|
|
576
566
|
wipFiber.child = newFiber;
|
|
577
|
-
} else if (element) {
|
|
567
|
+
} else if (element && prevSibling) {
|
|
578
568
|
prevSibling.sibling = newFiber;
|
|
579
569
|
}
|
|
580
570
|
|
|
@@ -599,8 +589,16 @@
|
|
|
599
589
|
vars.wipFiber = fiber;
|
|
600
590
|
vars.hookIndex = 0;
|
|
601
591
|
vars.wipFiber.hooks = [];
|
|
602
|
-
const children =
|
|
603
|
-
|
|
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);
|
|
604
602
|
};
|
|
605
603
|
|
|
606
604
|
/**
|
|
@@ -613,7 +611,7 @@
|
|
|
613
611
|
if (!fiber.dom) {
|
|
614
612
|
fiber.dom = createDom(fiber);
|
|
615
613
|
}
|
|
616
|
-
reconcileChildren(fiber, fiber.props.children
|
|
614
|
+
reconcileChildren(fiber, fiber.props.children);
|
|
617
615
|
};
|
|
618
616
|
|
|
619
617
|
var Components = /*#__PURE__*/Object.freeze({
|
|
@@ -656,7 +654,7 @@
|
|
|
656
654
|
* @returns The function `performUnitOfWork` returns the next fiber to be processed. If the current
|
|
657
655
|
* fiber has a child, it returns the child. Otherwise, it looks for the next sibling of the current
|
|
658
656
|
* fiber. If there are no more siblings, it goes up the tree to the parent and looks for the next
|
|
659
|
-
* sibling of the parent. The function returns `
|
|
657
|
+
* sibling of the parent. The function returns `undefined` if there are no more fibers to process.
|
|
660
658
|
*/
|
|
661
659
|
const performUnitOfWork = (fiber) => {
|
|
662
660
|
const isFunctionComponent = fiber.type instanceof Function;
|
|
@@ -675,6 +673,7 @@
|
|
|
675
673
|
}
|
|
676
674
|
nextFiber = nextFiber.parent;
|
|
677
675
|
}
|
|
676
|
+
return undefined
|
|
678
677
|
};
|
|
679
678
|
|
|
680
679
|
var Workers = /*#__PURE__*/Object.freeze({
|
|
@@ -698,12 +697,12 @@
|
|
|
698
697
|
window.Ryunix = Ryunix;
|
|
699
698
|
|
|
700
699
|
exports.Fragments = Fragments;
|
|
701
|
-
exports.Link = Link;
|
|
702
|
-
exports.Navigate = Navigate;
|
|
703
|
-
exports.Router = Router;
|
|
704
700
|
exports.default = Ryunix;
|
|
701
|
+
exports.useCallback = useCallback;
|
|
705
702
|
exports.useEffect = useEffect;
|
|
703
|
+
exports.useMemo = useMemo;
|
|
706
704
|
exports.useQuery = useQuery;
|
|
705
|
+
exports.useRef = useRef;
|
|
707
706
|
exports.useStore = useStore;
|
|
708
707
|
|
|
709
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.2",
|
|
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,10 +75,4 @@ const createTextElement = (text) => {
|
|
|
60
75
|
}
|
|
61
76
|
}
|
|
62
77
|
|
|
63
|
-
|
|
64
|
-
return children.map((c, index) =>
|
|
65
|
-
createElement(c.type, c.props, c.props.children),
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
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 }
|