ks-fwork 3.0.5 → 4.0.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 CHANGED
@@ -195,6 +195,31 @@ 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
+
198
223
  function destroyDOM(vNode) {
199
224
  const { type } = vNode;
200
225
  switch (type) {
@@ -212,6 +237,7 @@ function destroyDOM(vNode) {
212
237
  }
213
238
  case DOM_TYPES.COMPONENT: {
214
239
  vNode.component.unmount();
240
+ enqueueJob(() => vNode.component.onUnmounted());
215
241
  break;
216
242
  }
217
243
  default: {
@@ -303,6 +329,7 @@ function mountDOM(vNode, parentEl, index, hostComponent = null) {
303
329
  }
304
330
  case DOM_TYPES.COMPONENT: {
305
331
  createComponentNode(vNode, parentEl, index, hostComponent);
332
+ enqueueJob(() => vNode.component.onMounted());
306
333
  break;
307
334
  }
308
335
  default: {
@@ -641,7 +668,8 @@ class Dispatcher {
641
668
  }
642
669
  }
643
670
 
644
- function defineComponent({ render, state, ...methods }) {
671
+ const emptyFn = () => {};
672
+ function defineComponent({ render, state, onMounted = emptyFn, onUnmounted = emptyFn, ...methods }) {
645
673
  class Component {
646
674
  #isMounted = false;
647
675
  #vNode = null;
@@ -656,6 +684,12 @@ function defineComponent({ render, state, ...methods }) {
656
684
  this.#eventHandlers = eventHandlers;
657
685
  this.#parentComponent = parentComponent;
658
686
  }
687
+ onMounted() {
688
+ return Promise.resolve(onMounted.call(this));
689
+ }
690
+ onUnmounted() {
691
+ return Promise.resolve(onUnmounted.call(this));
692
+ }
659
693
  get elements() {
660
694
  if (this.#vNode == null) {
661
695
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ks-fwork",
3
- "version": "3.0.5",
3
+ "version": "4.0.0",
4
4
  "description": "Demo Frontend Framework",
5
5
  "license": "ISC",
6
6
  "author": "",
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
- export function defineComponent({ render, state, ...methods }) {
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) {
@@ -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/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
 
@@ -0,0 +1,28 @@
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
+ }