lithent 0.36.2 → 1.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.
Files changed (56) hide show
  1. package/README.md +51 -1
  2. package/dist/hook/mountCallback.d.ts +3 -1
  3. package/dist/hook/ref.d.ts +1 -0
  4. package/dist/index.d.ts +2 -2
  5. package/dist/lithent.mjs +67 -44
  6. package/dist/lithent.mjs.map +1 -1
  7. package/dist/lithent.umd.js +1 -1
  8. package/dist/lithent.umd.js.map +1 -1
  9. package/dist/types/index.d.ts +3 -2
  10. package/dist/utils/index.d.ts +1 -0
  11. package/dist/utils/predicator.d.ts +2 -1
  12. package/dist/utils/universalRef.d.ts +3 -9
  13. package/dist/wDom.d.ts +0 -1
  14. package/examples/dist/assets/index.2b484d3b.js +2 -0
  15. package/examples/dist/assets/index.2b484d3b.js.map +1 -0
  16. package/examples/dist/index.html +1 -1
  17. package/package.json +11 -5
  18. package/src/diff.ts +5 -12
  19. package/src/hook/mountCallback.ts +11 -4
  20. package/src/hook/ref.ts +1 -0
  21. package/src/hook/updateCallback.ts +1 -9
  22. package/src/index.ts +11 -2
  23. package/src/render.ts +48 -31
  24. package/src/{examples → tests}/callback.tsx +0 -1
  25. package/src/tests/example1.tsx +75 -0
  26. package/src/tests/example10.tsx +90 -0
  27. package/src/tests/example11.tsx +82 -0
  28. package/src/tests/example12.tsx +76 -0
  29. package/src/tests/example13.tsx +59 -0
  30. package/src/tests/example14.tsx +115 -0
  31. package/src/tests/example15.tsx +68 -0
  32. package/src/tests/example16.tsx +49 -0
  33. package/src/tests/example17.tsx +50 -0
  34. package/src/tests/example2.tsx +104 -0
  35. package/src/tests/example3.tsx +96 -0
  36. package/src/tests/example4.tsx +138 -0
  37. package/src/tests/example5.tsx +63 -0
  38. package/src/tests/example6.tsx +54 -0
  39. package/src/tests/example7.tsx +21 -0
  40. package/src/tests/example8.tsx +68 -0
  41. package/src/tests/example9.tsx +46 -0
  42. package/src/tests/renew.tsx +56 -0
  43. package/src/tests/svg.tsx +44 -0
  44. package/src/types/index.ts +12 -13
  45. package/src/utils/index.ts +3 -0
  46. package/src/utils/predicator.ts +6 -2
  47. package/src/utils/universalRef.ts +15 -9
  48. package/src/wDom.ts +5 -7
  49. package/examples/dist/assets/index.f15c0062.js +0 -2
  50. package/examples/dist/assets/index.f15c0062.js.map +0 -1
  51. package/src/examples/renew.tsx +0 -29
  52. /package/src/{examples → tests}/insert.tsx +0 -0
  53. /package/src/{examples → tests}/loop.tsx +0 -0
  54. /package/src/{examples → tests}/nested.tsx +0 -0
  55. /package/src/{examples → tests}/selectbox.tsx +0 -0
  56. /package/src/{examples → tests}/textarea.tsx +0 -0
package/README.md CHANGED
@@ -9,7 +9,7 @@ used lightly in a variety of situations.
9
9
  - https://superlucky84.github.io/lithent
10
10
  - (This guide page is written in lithent.)
11
11
 
12
- `(9.47 KiB / gzip: 3.49 KiB)`
12
+ `(9.62 KiB / gzip: 3.58 KiB)`
13
13
 
14
14
 
15
15
  ## 🚩 Table of Contents
@@ -17,9 +17,13 @@ used lightly in a variety of situations.
17
17
  - [Why Use Lithent](#why-use-lithent)
18
18
  - [Basic Guide](#basic-guide)
19
19
  - [How To Install](#how-to-install)
20
+ - [Use NPM](#use-npm)
21
+ - [Use CDN](#or-use-cdn)
20
22
  - [With HTM](#with-htm)
21
23
  - [With JSX](#with-jsx)
22
24
  - [Examples](#examples)
25
+ - [With ESM](#with-esm)
26
+ - [With UMD](#with-umd)
23
27
  - [Develop Guide](#develop-guide)
24
28
 
25
29
  ## Why use Lithent?
@@ -48,10 +52,20 @@ JavaScript users are used to using closures and love to develop with them.
48
52
 
49
53
  ## How To Install
50
54
 
55
+ #### Use NPM
56
+
51
57
  ```bash
52
58
  pnpm add lithent
53
59
  ```
54
60
 
61
+ #### Or Use CDN
62
+
63
+ * UMD : https://cdn.jsdelivr.net/npm/lithent@1.0.0/dist/lithent.umd.js
64
+ * UMD-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.0.0/helper/dist/lithentHelper.umd.js
65
+ * ESM : https://cdn.jsdelivr.net/npm/lithent@1.0.0/dist/lithent.mjs
66
+ * ESM-HELPER: https://cdn.jsdelivr.net/npm/lithent@1.0.0/helper/dist/lithentHelper.mjs
67
+
68
+
55
69
  It's easier to use lithent with JSX or HTM.
56
70
 
57
71
  #### With HTM
@@ -76,6 +90,7 @@ const html = htm.bind(h);
76
90
 
77
91
  - [More Examples](https://superlucky84.github.io/lithent/#examples)
78
92
 
93
+ #### With ESM
79
94
  ```js
80
95
  import { h, render, mount, Fragment } from 'lithent';
81
96
  import { state } from 'lithent/helper';
@@ -103,6 +118,41 @@ const Component = mount((r, _props) => {
103
118
  render(html`<${Component} />`, document.getElementById('root'));
104
119
  ```
105
120
 
121
+ #### With UMD
122
+
123
+ ```html
124
+ <script src="https://cdn.jsdelivr.net/npm/lithent@1.0.0/dist/lithent.umd.js"></script>
125
+ <!--script src="https://cdn.jsdelivr.net/npm/lithent@1.0.0/helper/dist/lithentHelper.umd.js"></script-->
126
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/htm/3.1.1/htm.js"></script>
127
+
128
+ <div id="root"></div>
129
+
130
+ <script>
131
+ const { h, Fragment, render, mount } = lithent;
132
+ // const { state } = lithentHelper;
133
+ const html = htm.bind(h);
134
+
135
+ const Component = mount(renew => {
136
+ count = 0;
137
+
138
+ const change = () => {
139
+ count += 1;
140
+ renew();
141
+ };
142
+
143
+ // Updater
144
+ return () => html`
145
+ <${Fragment}>
146
+ <li>count: ${count}</li>
147
+ <button onClick=${change}>increase</button>
148
+ <//>
149
+ `;
150
+ });
151
+
152
+ render(html`<${Component} />`, document.getElementById('root'));
153
+ </script>
154
+ ```
155
+
106
156
  ## Develop Guide
107
157
 
108
158
  It's open source, so you can develop and contribute together.
@@ -1,3 +1,5 @@
1
1
  import { WDom } from '../types';
2
- export declare const mountCallback: (effectAction: () => void) => void;
2
+ export declare const execMountedQueue: () => void;
3
+ export declare const addMountedQueue: (wDom: WDom) => void;
4
+ export declare const mountCallback: (effectAction: () => void) => number;
3
5
  export declare const runMountedQueueFromWDom: (newWDom: WDom) => void;
@@ -1,3 +1,4 @@
1
1
  export declare const ref: <T>(initValue: T) => {
2
2
  value: T;
3
3
  };
4
+ export declare const nextTick: () => Promise<void>;
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { h, Fragment, mount } from './wDom';
2
2
  import { render } from './render';
3
3
  import { mountCallback } from './hook/mountCallback';
4
4
  import { updateCallback } from './hook/updateCallback';
5
- import { ref } from './hook/ref';
5
+ import { ref, nextTick } from './hook/ref';
6
6
  export type { WDom, TagFunction, TagFunctionResolver, FragmentFunction, ComponentSubKey, ComponentRef, Props, Renew, MiddleStateWDomChildren, MiddleStateWDom, NodePointer, Param, } from './types';
7
7
  declare global {
8
8
  namespace JSX {
@@ -11,4 +11,4 @@ declare global {
11
11
  }
12
12
  }
13
13
  }
14
- export { h, Fragment, render, mount, mountCallback, updateCallback, ref };
14
+ export { h, Fragment, render, mount, mountCallback, updateCallback, ref, nextTick, };
package/dist/lithent.mjs CHANGED
@@ -13,6 +13,7 @@ const checkNormalTypeElement = (newWDom, originalWDom) => {
13
13
  var _a, _b;
14
14
  return checkPlainWDomType(newWDom) && (originalWDom == null ? void 0 : originalWDom.type) === newWDom.type && (((_a = originalWDom == null ? void 0 : originalWDom.children) == null ? void 0 : _a.length) === ((_b = newWDom == null ? void 0 : newWDom.children) == null ? void 0 : _b.length) || newWDom.type === "loop");
15
15
  };
16
+ const checkVirtualType = (type) => type && ["fragment", "loop"].includes(type);
16
17
  const checkCustemComponentFunction = (target) => typeof target === "function" && !checkFragmentFunction(target) || typeof target === "object" && "resolve" in target;
17
18
  const checkFragmentFunction = (target) => typeof target === "function" && target === Fragment;
18
19
  const checkEmptyElement = (wDom) => checkPlainWDomType(wDom) && !wDom.type;
@@ -65,6 +66,7 @@ const reRender = (vDom, infoVdom) => {
65
66
  return newVDom;
66
67
  };
67
68
  const getEventName = (eventKey) => eventKey.replace(/^on(.*)/, (_match, p1) => p1.toLowerCase());
69
+ const getAttrKey = (keyName) => keyName === "className" ? "class" : keyName;
68
70
  const updateProps$1 = (props, infoProps) => {
69
71
  if (props && infoProps !== props) {
70
72
  Object.keys(props).forEach((key) => delete props[key]);
@@ -81,11 +83,12 @@ const updateChildren = (children, infoChidren) => {
81
83
  }
82
84
  }
83
85
  };
86
+ let redrawQueue = [];
87
+ let redrawQueueTimeout = false;
88
+ const xmlnsRef = { value: "" };
84
89
  const componentKeyRef = { value: {} };
85
90
  const needDiffRef = { value: false };
86
91
  const componentRef = /* @__PURE__ */ new WeakMap();
87
- const redrawQueue = { value: [] };
88
- const redrawQueueTimeout = { value: null };
89
92
  const componentRender = (componentKey) => () => {
90
93
  var _a;
91
94
  const up = (_a = componentRef.get(componentKey)) == null ? void 0 : _a.up;
@@ -113,12 +116,13 @@ const getComponentKey = () => componentKeyRef.value;
113
116
  const getComponentSubInfo = (componentKey, subKey) => componentRef.get(componentKey)[subKey];
114
117
  const setRedrawAction = (componentKey, exec) => {
115
118
  componentRef.get(componentKey).up = () => {
116
- redrawQueue.value.push({
119
+ redrawQueue.push({
117
120
  componentKey,
118
121
  exec
119
122
  });
120
- if (!redrawQueueTimeout.value) {
121
- redrawQueueTimeout.value = setTimeout(execRedrawQueue);
123
+ if (!redrawQueueTimeout) {
124
+ redrawQueueTimeout = true;
125
+ queueMicrotask(execRedrawQueue);
122
126
  }
123
127
  };
124
128
  };
@@ -138,7 +142,7 @@ const recursiveGetChildKeys = (wDom, result) => {
138
142
  };
139
143
  const execRedrawQueue = () => {
140
144
  let childItemList = [];
141
- redrawQueue.value.forEach((item) => {
145
+ redrawQueue.forEach((item) => {
142
146
  var _a, _b;
143
147
  const childVd = (_b = (_a = componentRef.get(item.componentKey)) == null ? void 0 : _a.vd) == null ? void 0 : _b.value;
144
148
  if (childVd) {
@@ -146,7 +150,7 @@ const execRedrawQueue = () => {
146
150
  }
147
151
  });
148
152
  const addedKey = [];
149
- const result = redrawQueue.value.reduce((acc, item) => {
153
+ const result = redrawQueue.reduce((acc, item) => {
150
154
  const { componentKey } = item;
151
155
  if (childItemList.includes(componentKey) || addedKey.includes(componentKey)) {
152
156
  return acc;
@@ -161,6 +165,8 @@ const execRedrawQueue = () => {
161
165
  action.exec();
162
166
  }
163
167
  }
168
+ redrawQueue = [];
169
+ redrawQueueTimeout = false;
164
170
  };
165
171
  const unmount = (effectAction) => {
166
172
  componentRef.get(getComponentKey()).umts.push(effectAction);
@@ -190,10 +196,17 @@ const removeItem = (componentKey) => {
190
196
  componentRef.delete(componentKey);
191
197
  }
192
198
  };
193
- const mountCallback = (effectAction) => {
194
- const mts = componentRef.get(getComponentKey()).mts;
195
- mts.push(effectAction);
199
+ let mountedQueue = [];
200
+ const execMountedQueue = () => {
201
+ mountedQueue.forEach((item) => runMountedQueueFromWDom(item));
202
+ mountedQueue = [];
196
203
  };
204
+ const addMountedQueue = (wDom) => {
205
+ if (wDom.componentKey) {
206
+ mountedQueue.push(wDom);
207
+ }
208
+ };
209
+ const mountCallback = (effectAction) => componentRef.get(getComponentKey()).mts.push(effectAction);
197
210
  const runMountedQueueFromWDom = (newWDom) => {
198
211
  const { componentKey } = newWDom;
199
212
  if (componentKey) {
@@ -256,15 +269,14 @@ const render = (wDom, wrapElement, afterElement) => {
256
269
  } else {
257
270
  wrapElement.appendChild(Dom);
258
271
  }
272
+ execMountedQueue();
259
273
  return () => {
260
274
  var _a;
261
- if (wDom.componentProps) {
262
- const component = (_a = componentRef.get(wDom.componentProps)) == null ? void 0 : _a.vd.value;
263
- if (component) {
264
- runUnmountQueueFromWDom(component);
265
- recursiveRemoveEvent(component);
266
- rootDelete(component);
267
- }
275
+ const component = (_a = componentRef.get(wDom.componentProps || {})) == null ? void 0 : _a.vd.value;
276
+ if (component) {
277
+ runUnmountQueueFromWDom(component);
278
+ recursiveRemoveEvent(component);
279
+ rootDelete(component);
268
280
  }
269
281
  };
270
282
  };
@@ -345,9 +357,9 @@ const typeAdd = (newWDom, newElement) => {
345
357
  } else {
346
358
  parentEl.appendChild(newElement);
347
359
  }
360
+ execMountedQueue();
348
361
  }
349
362
  }
350
- runMountedQueueFromWDom(newWDom);
351
363
  };
352
364
  const startFindNextBrotherElement = (wDom, parentWDom) => {
353
365
  const brothers = parentWDom.children || [];
@@ -359,7 +371,7 @@ const startFindNextBrotherElement = (wDom, parentWDom) => {
359
371
  if (finedNextEl) {
360
372
  return finedNextEl;
361
373
  }
362
- if (!parentWDom.isRoot && ["fragment", "loop"].includes(parentType)) {
374
+ if (!parentWDom.isRoot && checkVirtualType(parentType)) {
363
375
  return startFindNextBrotherElement(parentWDom, getParent(parentWDom));
364
376
  } else if (parentWDom.isRoot && parentWDom.afterElement) {
365
377
  return parentWDom.afterElement;
@@ -370,7 +382,7 @@ const findChildFragmentNextElement = (candidiateBrothers) => candidiateBrothers.
370
382
  (targetEl, bItem) => {
371
383
  const type = bItem.type;
372
384
  const el = bItem.el;
373
- const isFragment = type && ["fragment", "loop"].includes(type);
385
+ const isFragment = type && checkVirtualType(type);
374
386
  if (targetEl) {
375
387
  return targetEl;
376
388
  } else if (isFragment) {
@@ -394,9 +406,9 @@ const typeReplace = (newWDom) => {
394
406
  if (parentElement) {
395
407
  parentElement.replaceChild(newElement, orignalElement);
396
408
  }
409
+ execMountedQueue();
397
410
  }
398
411
  }
399
- runMountedQueueFromWDom(newWDom);
400
412
  };
401
413
  const removeEvent = (oldProps, element) => {
402
414
  Object.entries(oldProps || {}).forEach(
@@ -440,7 +452,7 @@ const updateProps = (props, element, oldProps) => {
440
452
  ([dataKey, dataValue]) => {
441
453
  if (dataKey === "key")
442
454
  ;
443
- else if (dataKey === "innerHTML" && element && typeof dataValue === "string") {
455
+ else if (dataKey === "innerHTML" && typeof dataValue === "string") {
444
456
  element.innerHTML = dataValue;
445
457
  } else if (checkStyleData(dataKey, dataValue)) {
446
458
  updateStyle(
@@ -464,7 +476,18 @@ const updateProps = (props, element, oldProps) => {
464
476
  } else if (checkOptionElement(element) && dataKey === "selected") {
465
477
  element.selected = !!dataValue;
466
478
  } else if (checkNormalAttribute(dataValue)) {
467
- element.setAttribute(dataKey, String(dataValue));
479
+ if (xmlnsRef.value && dataKey !== "xmlns") {
480
+ element.setAttributeNS(
481
+ null,
482
+ getAttrKey(dataKey),
483
+ String(dataValue)
484
+ );
485
+ } else {
486
+ element.setAttribute(
487
+ getAttrKey(dataKey),
488
+ String(dataValue)
489
+ );
490
+ }
468
491
  }
469
492
  delete originalProps[dataKey];
470
493
  }
@@ -476,11 +499,14 @@ const updateProps = (props, element, oldProps) => {
476
499
  const wDomToDom = (wDom) => {
477
500
  let element;
478
501
  const { type, tag, text, props, children = [] } = wDom;
479
- const isVirtualType = type === "fragment" || type === "loop";
502
+ const isVirtualType = checkVirtualType(type);
503
+ if (tag === "svg") {
504
+ xmlnsRef.value = String(props == null ? void 0 : props.xmlns);
505
+ }
480
506
  if (isVirtualType) {
481
507
  element = new DocumentFragment();
482
508
  } else if (type === "element" && tag) {
483
- element = document.createElement(tag);
509
+ element = xmlnsRef.value ? document.createElementNS(xmlnsRef.value, tag) : document.createElement(tag);
484
510
  } else if (type === "text" && checkExisty(text)) {
485
511
  element = document.createTextNode(String(text));
486
512
  } else {
@@ -489,7 +515,10 @@ const wDomToDom = (wDom) => {
489
515
  wDomChildrenToDom(children, element);
490
516
  updateProps(props, element);
491
517
  wDom.el = element;
492
- runMountedQueueFromWDom(wDom);
518
+ addMountedQueue(wDom);
519
+ if (tag === "svg") {
520
+ xmlnsRef.value = "";
521
+ }
493
522
  return element;
494
523
  };
495
524
  const wDomChildrenToDom = (children, parentElement) => {
@@ -531,7 +560,7 @@ const updateStyle = (style, oldStyle, element) => {
531
560
  }
532
561
  };
533
562
  const findRealParentElement = (vDom) => {
534
- const isVirtualType = vDom.type === "fragment" || vDom.type === "loop";
563
+ const isVirtualType = checkVirtualType(vDom.type);
535
564
  if (vDom.isRoot && isVirtualType) {
536
565
  return vDom.wrapElement;
537
566
  }
@@ -617,7 +646,7 @@ const remakeChildrenForUpdate = (newWDom, originalWDom) => {
617
646
  });
618
647
  };
619
648
  const remakeChildrenForLoopUpdate = (newWDom, originalWDom) => {
620
- const { remakedChildren, unUsedChildren } = diffLoopChildren(
649
+ const [remakedChildren, unUsedChildren] = diffLoopChildren(
621
650
  newWDom,
622
651
  originalWDom
623
652
  );
@@ -641,17 +670,11 @@ const diffLoopChildren = (newWDom, originalWDom) => {
641
670
  childItem.getParent = () => newWDom;
642
671
  return childItem;
643
672
  });
644
- return {
645
- remakedChildren,
646
- unUsedChildren: originalChildren
647
- };
648
- };
649
- const findSameKeyOriginalItem = (item, originalChildren) => {
650
- const key = getKey(item);
651
- return originalChildren.find(
652
- (orignalChildItem) => getKey(orignalChildItem) === key
653
- );
673
+ return [remakedChildren, originalChildren];
654
674
  };
675
+ const findSameKeyOriginalItem = (item, originalChildren) => originalChildren.find(
676
+ (orignalChildItem) => getKey(orignalChildItem) === getKey(item)
677
+ );
655
678
  const getKey = (target) => {
656
679
  var _a, _b, _c;
657
680
  return (_c = (_a = target == null ? void 0 : target.componentProps) == null ? void 0 : _a.key) != null ? _c : (_b = target == null ? void 0 : target.props) == null ? void 0 : _b.key;
@@ -667,8 +690,6 @@ const runUpdateCallback = () => {
667
690
  if (updateReqs == null ? void 0 : updateReqs.length) {
668
691
  updateReqs.forEach((callback) => callback());
669
692
  }
670
- redrawQueue.value = [];
671
- redrawQueueTimeout.value = null;
672
693
  };
673
694
  const Fragment = (_props, ...children) => ({
674
695
  type: "fragment",
@@ -734,14 +755,14 @@ const makeWDomResolver = (tag, props, children) => {
734
755
  };
735
756
  const makeCustomNode = (componentMaker, componentKey, tag, props, children) => {
736
757
  const customNode = componentMaker(props);
737
- const reRender2 = makeReRender(
738
- componentMaker,
758
+ addComponentProps(
759
+ customNode,
739
760
  componentKey,
740
761
  tag,
741
762
  props,
742
- children
763
+ children,
764
+ makeReRender(componentMaker, componentKey, tag, props, children)
743
765
  );
744
- addComponentProps(customNode, componentKey, tag, props, children, reRender2);
745
766
  return customNode;
746
767
  };
747
768
  const makeReRender = (componentMaker, componentKey, tag, props, children) => {
@@ -807,11 +828,13 @@ const makeChildrenItem = (item) => {
807
828
  return item;
808
829
  };
809
830
  const ref = (initValue) => ({ value: initValue });
831
+ const nextTick = () => Promise.resolve();
810
832
  export {
811
833
  Fragment,
812
834
  h,
813
835
  mount,
814
836
  mountCallback,
837
+ nextTick,
815
838
  ref,
816
839
  render,
817
840
  updateCallback