ks-fwork 3.0.5 → 4.1.0
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/ks-fwork.js +43 -2
- package/package.json +1 -1
- package/src/component.js +11 -1
- package/src/destroy-dom.js +2 -0
- package/src/index.js +1 -0
- package/src/mount-dom.js +2 -0
- package/src/scheduler.js +37 -0
package/dist/ks-fwork.js
CHANGED
|
@@ -195,6 +195,38 @@ function extractChildren(vNode) {
|
|
|
195
195
|
return children;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
let isScheduled = false;
|
|
199
|
+
const jobs = [];
|
|
200
|
+
function enqueueJob(job) {
|
|
201
|
+
jobs.push(job);
|
|
202
|
+
scheduleUpdate();
|
|
203
|
+
}
|
|
204
|
+
function scheduleUpdate() {
|
|
205
|
+
if (isScheduled) return;
|
|
206
|
+
isScheduled = true;
|
|
207
|
+
queueMicrotask(processJobs);
|
|
208
|
+
}
|
|
209
|
+
function processJobs() {
|
|
210
|
+
while (jobs.length > 0) {
|
|
211
|
+
const job = jobs.shift();
|
|
212
|
+
try {
|
|
213
|
+
Promise.resolve(job()).catch((error) => {
|
|
214
|
+
console.error(`[scheduler]: ${error}`);
|
|
215
|
+
});
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.error(`[scheduler]: ${error}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
isScheduled = false;
|
|
221
|
+
}
|
|
222
|
+
function nextTick() {
|
|
223
|
+
scheduleUpdate();
|
|
224
|
+
return flushPromises();
|
|
225
|
+
}
|
|
226
|
+
function flushPromises() {
|
|
227
|
+
return new Promise((resolve) => setTimeout(resolve));
|
|
228
|
+
}
|
|
229
|
+
|
|
198
230
|
function destroyDOM(vNode) {
|
|
199
231
|
const { type } = vNode;
|
|
200
232
|
switch (type) {
|
|
@@ -212,6 +244,7 @@ function destroyDOM(vNode) {
|
|
|
212
244
|
}
|
|
213
245
|
case DOM_TYPES.COMPONENT: {
|
|
214
246
|
vNode.component.unmount();
|
|
247
|
+
enqueueJob(() => vNode.component.onUnmounted());
|
|
215
248
|
break;
|
|
216
249
|
}
|
|
217
250
|
default: {
|
|
@@ -303,6 +336,7 @@ function mountDOM(vNode, parentEl, index, hostComponent = null) {
|
|
|
303
336
|
}
|
|
304
337
|
case DOM_TYPES.COMPONENT: {
|
|
305
338
|
createComponentNode(vNode, parentEl, index, hostComponent);
|
|
339
|
+
enqueueJob(() => vNode.component.onMounted());
|
|
306
340
|
break;
|
|
307
341
|
}
|
|
308
342
|
default: {
|
|
@@ -641,7 +675,8 @@ class Dispatcher {
|
|
|
641
675
|
}
|
|
642
676
|
}
|
|
643
677
|
|
|
644
|
-
|
|
678
|
+
const emptyFn = () => {};
|
|
679
|
+
function defineComponent({ render, state, onMounted = emptyFn, onUnmounted = emptyFn, ...methods }) {
|
|
645
680
|
class Component {
|
|
646
681
|
#isMounted = false;
|
|
647
682
|
#vNode = null;
|
|
@@ -656,6 +691,12 @@ function defineComponent({ render, state, ...methods }) {
|
|
|
656
691
|
this.#eventHandlers = eventHandlers;
|
|
657
692
|
this.#parentComponent = parentComponent;
|
|
658
693
|
}
|
|
694
|
+
onMounted() {
|
|
695
|
+
return Promise.resolve(onMounted.call(this));
|
|
696
|
+
}
|
|
697
|
+
onUnmounted() {
|
|
698
|
+
return Promise.resolve(onUnmounted.call(this));
|
|
699
|
+
}
|
|
659
700
|
get elements() {
|
|
660
701
|
if (this.#vNode == null) {
|
|
661
702
|
return [];
|
|
@@ -750,4 +791,4 @@ function defineComponent({ render, state, ...methods }) {
|
|
|
750
791
|
return Component;
|
|
751
792
|
}
|
|
752
793
|
|
|
753
|
-
export { createApp, defineComponent, h, hFragment, hString };
|
|
794
|
+
export { createApp, defineComponent, h, hFragment, hString, nextTick };
|
package/package.json
CHANGED
package/src/component.js
CHANGED
|
@@ -7,7 +7,9 @@ import { hasOwnProperty } from "./utils/objects.js";
|
|
|
7
7
|
import equal from 'fast-deep-equal';
|
|
8
8
|
import { Dispatcher } from "./dispatcher.js";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const emptyFn = () => {};
|
|
11
|
+
|
|
12
|
+
export function defineComponent({ render, state, onMounted = emptyFn, onUnmounted = emptyFn, ...methods }) {
|
|
11
13
|
class Component {
|
|
12
14
|
#isMounted = false;
|
|
13
15
|
#vNode = null;
|
|
@@ -24,6 +26,14 @@ export function defineComponent({ render, state, ...methods }) {
|
|
|
24
26
|
this.#parentComponent = parentComponent;
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
onMounted() {
|
|
30
|
+
return Promise.resolve(onMounted.call(this));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
onUnmounted() {
|
|
34
|
+
return Promise.resolve(onUnmounted.call(this));
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
get elements() {
|
|
28
38
|
// If vNode is null, return an empty array
|
|
29
39
|
if (this.#vNode == null) {
|
package/src/destroy-dom.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { removeEventListeners } from './events.js'
|
|
2
2
|
import { DOM_TYPES } from "./h.js";
|
|
3
|
+
import { enqueueJob } from "./scheduler.js";
|
|
3
4
|
|
|
4
5
|
// Recursively destroy a virtual node (and its subtree).
|
|
5
6
|
export function destroyDOM(vNode) {
|
|
@@ -23,6 +24,7 @@ export function destroyDOM(vNode) {
|
|
|
23
24
|
|
|
24
25
|
case DOM_TYPES.COMPONENT: {
|
|
25
26
|
vNode.component.unmount();
|
|
27
|
+
enqueueJob(() => vNode.component.onUnmounted());
|
|
26
28
|
break;
|
|
27
29
|
}
|
|
28
30
|
|
package/src/index.js
CHANGED
package/src/mount-dom.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DOM_TYPES } from "./h.js";
|
|
2
2
|
import { setAttributes } from './attributes.js'
|
|
3
3
|
import { addEventListeners } from "./events.js";
|
|
4
|
+
import { enqueueJob } from "./scheduler.js";
|
|
4
5
|
import { extractPropsAndEvents } from "./utils/props.js";
|
|
5
6
|
|
|
6
7
|
// Recursively mount a virtual node (and its subtree) into a real parent DOM element.
|
|
@@ -23,6 +24,7 @@ export function mountDOM(vNode, parentEl, index, hostComponent = null) {
|
|
|
23
24
|
|
|
24
25
|
case DOM_TYPES.COMPONENT: {
|
|
25
26
|
createComponentNode(vNode, parentEl, index, hostComponent);
|
|
27
|
+
enqueueJob(() => vNode.component.onMounted());
|
|
26
28
|
break;
|
|
27
29
|
}
|
|
28
30
|
|
package/src/scheduler.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
let isScheduled = false;
|
|
2
|
+
const jobs = [];
|
|
3
|
+
|
|
4
|
+
export function enqueueJob(job) {
|
|
5
|
+
jobs.push(job);
|
|
6
|
+
scheduleUpdate();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function scheduleUpdate() {
|
|
10
|
+
if (isScheduled) return;
|
|
11
|
+
|
|
12
|
+
isScheduled = true;
|
|
13
|
+
queueMicrotask(processJobs);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function processJobs() {
|
|
17
|
+
while (jobs.length > 0) {
|
|
18
|
+
const job = jobs.shift();
|
|
19
|
+
try {
|
|
20
|
+
Promise.resolve(job()).catch((error) => {
|
|
21
|
+
console.error(`[scheduler]: ${error}`);
|
|
22
|
+
});
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(`[scheduler]: ${error}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
isScheduled = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function nextTick() {
|
|
31
|
+
scheduleUpdate();
|
|
32
|
+
return flushPromises();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function flushPromises() {
|
|
36
|
+
return new Promise((resolve) => setTimeout(resolve));
|
|
37
|
+
}
|