ziko 1.7.0 → 1.9.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 (59) hide show
  1. package/dist/ziko.cjs +458 -174
  2. package/dist/ziko.js +458 -174
  3. package/dist/ziko.min.js +2 -2
  4. package/dist/ziko.mjs +453 -173
  5. package/package.json +1 -1
  6. package/src/dom/{flex → components/Flex}/index.js +1 -1
  7. package/src/dom/components/{for → For}/index.js +1 -1
  8. package/src/dom/{suspense → components/Suspense}/index.js +3 -7
  9. package/src/dom/components/View/index.js +9 -0
  10. package/src/dom/{graphics/canvas.js → components/graphics/Canvas/index.js} +6 -6
  11. package/src/dom/{graphics/svg.js → components/graphics/Svg/index.js} +4 -4
  12. package/src/dom/components/graphics/index.js +2 -0
  13. package/src/dom/components/index.js +10 -3
  14. package/src/dom/{wrappers/html → components/wrappers/HTMLWrapper}/index.js +1 -1
  15. package/src/dom/{wrappers/svg → components/wrappers/SVGWrapper}/index.js +1 -1
  16. package/src/dom/components/wrappers/index.js +2 -0
  17. package/src/dom/constructors/mixins/dom.js +1 -0
  18. package/src/dom/index.js +0 -8
  19. package/src/hooks/index.d.ts +1 -0
  20. package/src/hooks/index.js +1 -0
  21. package/src/hooks/use-derived.js +24 -17
  22. package/src/hooks/use-effect.d.ts +39 -0
  23. package/src/hooks/use-effect.js +40 -0
  24. package/src/hooks/use-state.d.ts +28 -10
  25. package/src/hooks/use-state.js +3 -1
  26. package/src/symbols/index.d.ts +39 -0
  27. package/src/symbols/index.js +5 -0
  28. package/src/dom/graphics/index.js +0 -2
  29. package/src/dom/logic/index.js +0 -1
  30. package/src/dom/view/index.js +0 -13
  31. package/src/dom/wrappers/index.js +0 -2
  32. package/src/events-dep/binders/coordinates-based-event.js +0 -25
  33. package/src/events-dep/binders/custom-event.js +0 -33
  34. package/src/events-dep/binders/index.js +0 -105
  35. package/src/events-dep/custom-events-registry/click-away.js +0 -38
  36. package/src/events-dep/custom-events-registry/index.js +0 -3
  37. package/src/events-dep/custom-events-registry/swipe.js +0 -76
  38. package/src/events-dep/custom-events-registry/view.js +0 -74
  39. package/src/events-dep/customizers/normalise-coordinates.js +0 -0
  40. package/src/events-dep/details-setter/index.js +0 -4
  41. package/src/events-dep/details-setter/key.js +0 -14
  42. package/src/events-dep/details-setter/mouse.js +0 -35
  43. package/src/events-dep/details-setter/pointer.js +0 -35
  44. package/src/events-dep/details-setter/touch.js +0 -37
  45. package/src/events-dep/events-map/index.js +0 -70
  46. package/src/events-dep/index.js +0 -3
  47. package/src/events-dep/types/__Shared__.d.ts +0 -155
  48. package/src/events-dep/types/clipboard.d.ts +0 -20
  49. package/src/events-dep/types/focus.d.ts +0 -19
  50. package/src/events-dep/types/pointer.d.ts +0 -45
  51. package/src/events-dep/utils.js +0 -38
  52. package/src/events-dep/ziko-event.js +0 -108
  53. package/src/watch/dom-observer/ziko-observer.js +0 -15
  54. /package/src/dom/{flex → components/Flex}/utils/index.js +0 -0
  55. /package/src/dom/components/{fragment → Fragment}/index.d.ts +0 -0
  56. /package/src/dom/components/{fragment → Fragment}/index.js +0 -0
  57. /package/src/dom/components/{swap → Swap}/index.d.ts +0 -0
  58. /package/src/dom/components/{swap → Swap}/index.js +0 -0
  59. /package/src/dom/{logic/switch → components/Switch}/index.js +0 -0
package/dist/ziko.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /*
3
3
  Project: ziko.js
4
4
  Author: Zakaria Elalaoui
5
- Date : Fri Aug 07 2026 20:07:58 GMT+0100 (UTC+01:00)
5
+ Date : Wed Aug 26 2026 10:48:40 GMT+0100 (UTC+01:00)
6
6
  Git-Repo : https://github.com/zakarialaoui10/ziko.js
7
7
  Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki
8
8
  Released under MIT License
@@ -2436,11 +2436,10 @@
2436
2436
  unmount: unmount
2437
2437
  });
2438
2438
 
2439
+ const STATE_GETTER = Symbol.for("ziko/hooks/STATE_GETTER");
2440
+
2439
2441
  // import { __init__global__ } from "../__ziko__/index.js";
2440
2442
 
2441
- // if (!globalThis.__Ziko__) __init__global__();
2442
-
2443
- const STATE_GETTER = Symbol.for("ziko.stateGetter");
2444
2443
 
2445
2444
  function useState(initialValue) {
2446
2445
  const state = {
@@ -2644,6 +2643,7 @@
2644
2643
  // Fix Items Latter
2645
2644
  if (ele[i] instanceof Function) {
2646
2645
  if (isStateGetter(ele[i])) {
2646
+ console.log({s : ele[i]()});
2647
2647
  const getter = ele[i]();
2648
2648
  ele[i] = text(getter.value);
2649
2649
  getter._subscribe(
@@ -3336,15 +3336,6 @@
3336
3336
  });
3337
3337
  };
3338
3338
 
3339
- class UIView extends UIElement$1{
3340
- constructor(...items){
3341
- super({element : 'div', name : 'view'});
3342
- this.append(...items);
3343
- }
3344
- }
3345
-
3346
- const View = (...items) => new UIView(...items);
3347
-
3348
3339
  const HTMLTags = [
3349
3340
  'a',
3350
3341
  'abb',
@@ -3504,6 +3495,62 @@
3504
3495
  }
3505
3496
  });
3506
3497
 
3498
+ function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3499
+ if (globalThis.customElements?.get(name)) {
3500
+ console.warn(`Custom element "${name}" is already defined`);
3501
+ return;
3502
+ }
3503
+ if(name.search('-') === -1){
3504
+ console.warn(`"${name}" is not a valid custom element name`);
3505
+ return;
3506
+ }
3507
+ globalThis.customElements?.define(
3508
+ name,
3509
+ class extends HTMLElement {
3510
+ static get observedAttributes() {
3511
+ return ['style', ...Object.keys(props)];
3512
+ }
3513
+
3514
+ constructor() {
3515
+ super();
3516
+ this.attachShadow({ mode });
3517
+ this.props = {};
3518
+ this.mask = {
3519
+ ...props,
3520
+ // style: { type: Object }
3521
+ };
3522
+ }
3523
+
3524
+ connectedCallback() {
3525
+ this.render();
3526
+ }
3527
+
3528
+ render() {
3529
+ this.shadowRoot.innerHTML = '';
3530
+ const item = UI_Constructor(this.props);
3531
+ if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3532
+ else item.mount(this.shadowRoot);
3533
+ }
3534
+
3535
+ attributeChangedCallback(name, _, newValue) {
3536
+ Object.assign(this.props, {
3537
+ [name]: this.mask[name].type(newValue)
3538
+ });
3539
+ this.render();
3540
+ }
3541
+ }
3542
+ );
3543
+ }
3544
+
3545
+ class UIView extends UIElement$1{
3546
+ constructor(...items){
3547
+ super({element : 'div', name : 'view'});
3548
+ this.append(...items);
3549
+ }
3550
+ }
3551
+
3552
+ const View = (...items) => new UIView(...items);
3553
+
3507
3554
  function set_vertical(direction){
3508
3555
  direction == 1
3509
3556
  ? this.style({ flexDirection: "column" })
@@ -3609,7 +3656,7 @@
3609
3656
  }
3610
3657
  }
3611
3658
 
3612
- class ZikoUISuspense extends UIElement{
3659
+ class UISuspense extends UIElement{
3613
3660
  constructor(fallback_ui, callback){
3614
3661
  super({element : "div", name : "suspense"});
3615
3662
  this.setAttr({
@@ -3630,148 +3677,7 @@
3630
3677
  }
3631
3678
  }
3632
3679
 
3633
- const Suspense = (fallback_ui, callback) => new ZikoUISuspense(fallback_ui, callback);
3634
-
3635
- class UIHTMLWrapper extends UIElement$1 {
3636
- constructor(content){
3637
- super({element : 'div', name : 'html_wrappper'});
3638
- this.element.append(html2dom(content));
3639
- this.style({
3640
- display : 'contents'
3641
- });
3642
- }
3643
- }
3644
-
3645
- function html2dom(htmlString) {
3646
- if(globalThis?.DOMParser){
3647
- const parser = new DOMParser();
3648
- const doc = parser.parseFromString(`<div>${htmlString}</div>`, 'text/html');
3649
- doc.body.firstChild.style.display = "contents";
3650
- return doc.body.firstChild;
3651
- }
3652
- }
3653
-
3654
- const HTMLWrapper = (content) => new UIHTMLWrapper(content);
3655
-
3656
- class UISVGWrapper extends UIElement$1 {
3657
- constructor(content){
3658
- super({element : 'div', name : 'html_wrappper'});
3659
- this.element.append(svg2dom(content));
3660
- this.style({
3661
- display : 'contents'
3662
- });
3663
- }
3664
- }
3665
-
3666
- function svg2dom(svgString) {
3667
- if (typeof DOMParser !== "undefined") {
3668
- const parser = new DOMParser();
3669
- const doc = parser.parseFromString(svgString.trim(), "image/svg+xml");
3670
- const svg = doc.documentElement;
3671
-
3672
- if (svg.nodeName === "parsererror") {
3673
- throw new Error("Invalid SVG string");
3674
- }
3675
- if(svg.hasAttribute('xmlns')) return svg
3676
- // TO Fix ...
3677
- const {children, attributes} = svg;
3678
- const element = document.createElementNS("http://www.w3.org/2000/svg", "svg");
3679
- for(let {name, value} of attributes){
3680
- element.setAttribute(name, value);
3681
- }
3682
- element.append(...children);
3683
-
3684
- globalThis.svg = svg;
3685
- globalThis.children = children;
3686
- globalThis.attributes = attributes;
3687
- globalThis.element = element;
3688
- return element;
3689
- }
3690
- throw new Error("DOMParser is not available in this environment");
3691
- }
3692
-
3693
-
3694
-
3695
- const SVGWrapper = (content) => new UISVGWrapper(content);
3696
-
3697
- function define_wc(name, UI_Constructor, props = {}, { mode = 'open'} = {}) {
3698
- if (globalThis.customElements?.get(name)) {
3699
- console.warn(`Custom element "${name}" is already defined`);
3700
- return;
3701
- }
3702
- if(name.search('-') === -1){
3703
- console.warn(`"${name}" is not a valid custom element name`);
3704
- return;
3705
- }
3706
- globalThis.customElements?.define(
3707
- name,
3708
- class extends HTMLElement {
3709
- static get observedAttributes() {
3710
- return ['style', ...Object.keys(props)];
3711
- }
3712
-
3713
- constructor() {
3714
- super();
3715
- this.attachShadow({ mode });
3716
- this.props = {};
3717
- this.mask = {
3718
- ...props,
3719
- // style: { type: Object }
3720
- };
3721
- }
3722
-
3723
- connectedCallback() {
3724
- this.render();
3725
- }
3726
-
3727
- render() {
3728
- this.shadowRoot.innerHTML = '';
3729
- const item = UI_Constructor(this.props);
3730
- if(item instanceof Array) item.forEach(n => n.mount(this.shadowRoot));
3731
- else item.mount(this.shadowRoot);
3732
- }
3733
-
3734
- attributeChangedCallback(name, _, newValue) {
3735
- Object.assign(this.props, {
3736
- [name]: this.mask[name].type(newValue)
3737
- });
3738
- this.render();
3739
- }
3740
- }
3741
- );
3742
- }
3743
-
3744
- class UISwitch extends UIElement$1{
3745
- constructor(key, cases){
3746
- super();
3747
- this.key = key;
3748
- this.cases = cases;
3749
- this.init();
3750
- }
3751
- init(){
3752
- Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3753
- super.init(this.current.element);
3754
- }
3755
- get current(){
3756
- const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3757
- return this.cases[matched]
3758
- }
3759
- updateKey(key){
3760
- this.key = key;
3761
- this.replaceElementWith(this.current.element);
3762
- // this.cache.element.replaceWith(this.current.element)
3763
- // this.cache.element = this.current.element;
3764
- return this;
3765
- }
3766
-
3767
- }
3768
-
3769
- const Switch=({key, cases})=> new UISwitch(key, cases);
3770
-
3771
- // export const Switch=({key, cases}) => {
3772
- // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3773
- // return this.cases[matched]()
3774
- // }
3680
+ const Suspense = (fallback_ui, callback) => new UISuspense(fallback_ui, callback);
3775
3681
 
3776
3682
  class UISwap extends UIElement$1 {
3777
3683
  #DISPLAYS_MAP = new WeakMap()
@@ -3863,6 +3769,335 @@
3863
3769
 
3864
3770
  const For = ({each, fallback, mapFn} = {}) => new UIFor({each, fallback, mapFn});
3865
3771
 
3772
+ class UISwitch extends UIElement$1{
3773
+ constructor(key, cases){
3774
+ super();
3775
+ this.key = key;
3776
+ this.cases = cases;
3777
+ this.init();
3778
+ }
3779
+ init(){
3780
+ Object.values(this.cases).filter(n=>n != this.current).forEach(n=>n.unmount());
3781
+ super.init(this.current.element);
3782
+ }
3783
+ get current(){
3784
+ const matched = Object.keys(this.cases).find(n => n == this.key) ?? 'default';
3785
+ return this.cases[matched]
3786
+ }
3787
+ updateKey(key){
3788
+ this.key = key;
3789
+ this.replaceElementWith(this.current.element);
3790
+ // this.cache.element.replaceWith(this.current.element)
3791
+ // this.cache.element = this.current.element;
3792
+ return this;
3793
+ }
3794
+
3795
+ }
3796
+
3797
+ const Switch=({key, cases})=> new UISwitch(key, cases);
3798
+
3799
+ // export const Switch=({key, cases}) => {
3800
+ // const matched = Object.keys(cases).find(n => n == key) ?? 'default';
3801
+ // return this.cases[matched]()
3802
+ // }
3803
+
3804
+ class UIHTMLWrapper extends UIElement$1 {
3805
+ constructor(content){
3806
+ super({element : 'div', name : 'html_wrappper'});
3807
+ this.element.append(html2dom(content));
3808
+ this.style({
3809
+ display : 'contents'
3810
+ });
3811
+ }
3812
+ }
3813
+
3814
+ function html2dom(htmlString) {
3815
+ if(globalThis?.DOMParser){
3816
+ const parser = new DOMParser();
3817
+ const doc = parser.parseFromString(`<div>${htmlString}</div>`, 'text/html');
3818
+ doc.body.firstChild.style.display = "contents";
3819
+ return doc.body.firstChild;
3820
+ }
3821
+ }
3822
+
3823
+ const HTMLWrapper = (content) => new UIHTMLWrapper(content);
3824
+
3825
+ class UISVGWrapper extends UIElement$1 {
3826
+ constructor(content){
3827
+ super({element : 'div', name : 'html_wrappper'});
3828
+ this.element.append(svg2dom(content));
3829
+ this.style({
3830
+ display : 'contents'
3831
+ });
3832
+ }
3833
+ }
3834
+
3835
+ function svg2dom(svgString) {
3836
+ if (typeof DOMParser !== "undefined") {
3837
+ const parser = new DOMParser();
3838
+ const doc = parser.parseFromString(svgString.trim(), "image/svg+xml");
3839
+ const svg = doc.documentElement;
3840
+
3841
+ if (svg.nodeName === "parsererror") {
3842
+ throw new Error("Invalid SVG string");
3843
+ }
3844
+ if(svg.hasAttribute('xmlns')) return svg
3845
+ // TO Fix ...
3846
+ const {children, attributes} = svg;
3847
+ const element = document.createElementNS("http://www.w3.org/2000/svg", "svg");
3848
+ for(let {name, value} of attributes){
3849
+ element.setAttribute(name, value);
3850
+ }
3851
+ element.append(...children);
3852
+
3853
+ globalThis.svg = svg;
3854
+ globalThis.children = children;
3855
+ globalThis.attributes = attributes;
3856
+ globalThis.element = element;
3857
+ return element;
3858
+ }
3859
+ throw new Error("DOMParser is not available in this environment");
3860
+ }
3861
+
3862
+
3863
+
3864
+ const SVGWrapper = (content) => new UISVGWrapper(content);
3865
+
3866
+ class UICanvas extends UIElement$1{
3867
+ constructor(w,h){
3868
+ super("canvas","canvas");
3869
+ this.ctx = this.element?.getContext("2d");
3870
+ this.style({
3871
+ border:"1px red solid",
3872
+ });
3873
+ this.transformMatrix = new Matrix([
3874
+ [1,0,0],
3875
+ [0,1,0],
3876
+ [0,0,1]
3877
+ ]);
3878
+ this.axisMatrix = new Matrix([
3879
+ [-10,-10],
3880
+ [10,10]
3881
+ ]);
3882
+ // setTimeout(()=>this.resize(w,h),0);
3883
+ requestAnimationFrame(()=>this.resize(w,h),0);
3884
+ this.on("sizeupdated",()=>this.adjust());
3885
+ }
3886
+ get Xmin(){
3887
+ return this.axisMatrix[0][0];
3888
+ }
3889
+ get Ymin(){
3890
+ return this.axisMatrix[0][1];
3891
+ }
3892
+ get Xmax(){
3893
+ return this.axisMatrix[1][0];
3894
+ }
3895
+ get Ymax(){
3896
+ return this.axisMatrix[1][1];
3897
+ }
3898
+ get ImageData(){
3899
+ return this.ctx.getImageData(0,0,c.Width,c.Height);
3900
+ }
3901
+ draw(all=true){
3902
+ if(all){
3903
+ this.clear();
3904
+ this.items.forEach(element => {
3905
+ element.parent=this;
3906
+ element.draw(this.ctx);
3907
+ });
3908
+ }
3909
+ else {
3910
+ this.items.at(-1).parent=this;
3911
+ this.items.at(-1).draw(this.ctx);
3912
+ }
3913
+ this.maintain();
3914
+ return this;
3915
+ }
3916
+ applyTransformMatrix(){
3917
+ this.ctx.setTransform(
3918
+ this.transformMatrix[0][0],
3919
+ this.transformMatrix[1][0],
3920
+ this.transformMatrix[0][1],
3921
+ this.transformMatrix[1][1],
3922
+ this.transformMatrix[0][2],
3923
+ this.transformMatrix[1][2],
3924
+ );
3925
+ return this;
3926
+ }
3927
+ resize(w,h){
3928
+ this.size(w,h);
3929
+ this.lineWidth();
3930
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3931
+ this.emit("sizeupdated");
3932
+ return this;
3933
+ }
3934
+ adjust(){
3935
+ this.element.width =this.element?.getBoundingClientRect().width;
3936
+ this.element.height =this.element?.getBoundingClientRect().height;
3937
+ this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
3938
+ return this;
3939
+ }
3940
+ view(xMin,yMin,xMax,yMax){
3941
+ this.transformMatrix[0][0]=this.width/(xMax-xMin); // scaleX
3942
+ this.transformMatrix[1][1]=-this.height/(yMax-yMin); // scaleY
3943
+ this.transformMatrix[0][2]=this.width/2;
3944
+ this.transformMatrix[1][2]=this.height/2;
3945
+ this.axisMatrix=new Matrix([
3946
+ [xMin,yMin],
3947
+ [xMax,yMax]
3948
+ ]);
3949
+
3950
+ this.applyTransformMatrix();
3951
+ this.clear();
3952
+ this.lineWidth(1);
3953
+ this.draw();
3954
+ return this;
3955
+ }
3956
+ reset(){
3957
+ this.ctx.setTransform(1,0,0,0,0,0);
3958
+ return this;
3959
+ }
3960
+ append(element){
3961
+ this.items.push(element);
3962
+ this.draw(false);
3963
+ return this;
3964
+ }
3965
+ background(color){
3966
+ this.ctx.fillStyle = color;
3967
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3968
+ this.ctx.fillRect(0, 0, this.width, this.height);
3969
+ this.applyTransformMatrix();
3970
+ this.draw();
3971
+ }
3972
+ lineWidth(w){
3973
+ this.ctx.lineWidth=w/this.transformMatrix[0][0];
3974
+ return this
3975
+ }
3976
+ getImageData(x=0,y=0,w=this.width,h=this.height){
3977
+ return this.ctx.getImageData(x,y,w,h);
3978
+ }
3979
+ clear(){
3980
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
3981
+ this.ctx.clearRect(0, 0, this.width, this.height);
3982
+ this.applyTransformMatrix();
3983
+ return this;
3984
+ }
3985
+ clone(){
3986
+ console.log(this.width);
3987
+ const canvas=new UICanvas();
3988
+ canvas.items=this.items;
3989
+ canvas.transformMatrix=this.transformMatrix;
3990
+ canvas.axisMatrix=this.axisMatrix;
3991
+ Object.assign(canvas.cache,{...this.cache});
3992
+ //waitForUIElm(this)
3993
+ //console.log(element)
3994
+ this.size(this.element.style.width,this.element.style.width);
3995
+ this.applyTransformMatrix();
3996
+ this.draw();
3997
+ this.adjust();
3998
+ return canvas;
3999
+ }
4000
+ toImage() {
4001
+ this.img = document?.createElement("img");
4002
+ this.img.src = this.element?.toDataURL("image/png");
4003
+ return this;
4004
+ }
4005
+ toBlob() {
4006
+ var canvas = this.element;
4007
+ canvas.toBlob(function (blob) {
4008
+ var newImg = document?.createElement("img"),
4009
+ url = URL.createObjectURL(blob);
4010
+ newImg.onload = function () {
4011
+ URL.revokeObjectURL(url);
4012
+ };
4013
+ newImg.src = url;
4014
+ console.log(newImg);
4015
+ });
4016
+ }
4017
+ zoomIn(){
4018
+
4019
+ }
4020
+ zoomOut(){
4021
+
4022
+ }
4023
+ undo(n){
4024
+
4025
+ }
4026
+ redo(n){
4027
+
4028
+ }
4029
+ stream(){
4030
+
4031
+ }
4032
+ }
4033
+
4034
+ const Canvas=(w,h)=>new UICanvas(w,h);
4035
+
4036
+ class UISvg extends UIElement$1 {
4037
+ constructor(w=360,h=300) {
4038
+ super("svg","svg");
4039
+ //this.cache={};
4040
+ // this.setAttr("width",w);
4041
+ // this.setAttr("height",h);
4042
+ // this.setAttr({
4043
+ // width : w,
4044
+ // height : h
4045
+ // })
4046
+ this.style({border:"1px black solid"});
4047
+ //this.view(-w/2,-h/2,w/2,h/2);
4048
+ this.size(w, h);
4049
+ this.view(-10,-10,10,10);
4050
+ }
4051
+ size(w, h){
4052
+ this.setAttr({
4053
+ width : w,
4054
+ height : h
4055
+ });
4056
+ return this
4057
+ }
4058
+ view(x1,y1,x2,y2){
4059
+ let width=Math.abs(x2-x1);
4060
+ let height=Math.abs(y2-y1);
4061
+ this.setAttr("viewBox",[x1,y1,width,height].join(" "));
4062
+ this.st.scaleY(-1);
4063
+ return this;
4064
+ }
4065
+ add(...svgElement){
4066
+ for(let i=0;i<svgElement.length;i++){
4067
+ this.element.append(svgElement[i].element);
4068
+ this.items.push(svgElement[i]);
4069
+ }
4070
+ this.maintain();
4071
+ return this;
4072
+ }
4073
+ remove(...svgElement){
4074
+ for(let i=0;i<svgElement.length;i++){
4075
+ this.element?.removeChild(svgElement[i].element);
4076
+ this.items=this.items.filter(n=>!svgElement);
4077
+ }
4078
+ this.maintain();
4079
+ return this;
4080
+ }
4081
+ mask(){
4082
+
4083
+ }
4084
+ toString(){
4085
+ return (new XMLSerializer()).serializeToString(this.element);
4086
+ }
4087
+ btoa(){
4088
+ return btoa(this.toString())
4089
+ }
4090
+ toImg(){
4091
+ return 'data:image/svg+xml;base64,'+this.btoa()
4092
+ }
4093
+ toImg2(){
4094
+ return "data:image/svg+xml;charset=utf8,"+this.toString().replaceAll("<","%3C").replaceAll(">","%3E").replaceAll("#","%23").replaceAll('"',"'");
4095
+ }
4096
+
4097
+ }
4098
+
4099
+ const Svg =(w,h)=>new UISvg(w,h);
4100
+
3866
4101
  const { PI, sqrt: sqrt$1, cos: cos$2, sin: sin$2, acos, pow } = Math;
3867
4102
 
3868
4103
  const linear = t => t;
@@ -4804,23 +5039,29 @@
4804
5039
  let value = deriveFn(...sources.map(s => s().value));
4805
5040
  const subscribers = new Set();
4806
5041
 
4807
- sources.forEach(source => {
4808
- const srcValue = source();
4809
- srcValue._subscribe(() => {
4810
- {
4811
- const newVal = deriveFn(...sources.map(s => s().value));
4812
- if (newVal !== value) {
4813
- value = newVal;
4814
- subscribers.forEach(fn => fn(value));
4815
- }
4816
- }
4817
- });
4818
- });
4819
- return () => ({
5042
+ // const unsubscribers = sources.map(source => {
5043
+ // const srcValue = source();
5044
+
5045
+ // return srcValue._subscribe(() => {
5046
+ // const newVal = deriveFn(...sources.map(s => s().value));
5047
+
5048
+ // if (!Object.is(newVal, value)) {
5049
+ // value = newVal;
5050
+ // subscribers.forEach(fn => fn(value));
5051
+ // }
5052
+ // });
5053
+ // });
5054
+
5055
+ const getter = () => ({
4820
5056
  value,
4821
- isStateGetter : () => true,
4822
- _subscribe: (fn) => subscribers.add(fn)
4823
- })
5057
+ _subscribe: (fn) => {
5058
+ subscribers.add(fn);
5059
+ return () => subscribers.delete(fn);
5060
+ },
5061
+ });
5062
+
5063
+ getter[STATE_GETTER] = true;
5064
+ return getter
4824
5065
  }
4825
5066
 
4826
5067
  const mapfun=(fun,...X)=>{
@@ -4877,6 +5118,45 @@
4877
5118
  nested_value
4878
5119
  );
4879
5120
 
5121
+ const useEffect = (callback, deps = []) =>{
5122
+ const states = deps.filter(isStateGetter);
5123
+
5124
+ let cleanup;
5125
+
5126
+ const execute = () => {
5127
+ // Cleanup previous effect
5128
+ if (typeof cleanup === "function") {
5129
+ cleanup();
5130
+ }
5131
+
5132
+ // Read current state values
5133
+ const values = states.map(state => state().value);
5134
+
5135
+ // Execute effect
5136
+ cleanup = callback(...values);
5137
+ };
5138
+
5139
+ // Subscribe to states
5140
+ const unsubscribers = states.map(state =>
5141
+ state()._subscribe(execute)
5142
+ );
5143
+
5144
+ // Initial execution
5145
+ execute();
5146
+
5147
+ // Return effect cleanup
5148
+ return () => {
5149
+ unsubscribers.forEach(unsubscribe => {
5150
+ unsubscribe();
5151
+ });
5152
+
5153
+ if (typeof cleanup === "function") {
5154
+ cleanup();
5155
+ cleanup = undefined;
5156
+ }
5157
+ };
5158
+ };
5159
+
4880
5160
  class UseThread {
4881
5161
  #worker;
4882
5162
  #callbacks = new Map();
@@ -5300,6 +5580,7 @@
5300
5580
  }
5301
5581
 
5302
5582
  exports.App = App;
5583
+ exports.Canvas = Canvas;
5303
5584
  exports.ClickAwayEvent = ClickAwayEvent;
5304
5585
  exports.ClickListeners = ClickListeners;
5305
5586
  exports.Clock = Clock;
@@ -5319,10 +5600,10 @@
5319
5600
  exports.PtrListeners = PtrListeners;
5320
5601
  exports.Random = Random;
5321
5602
  exports.SPA = SPA;
5322
- exports.STATE_GETTER = STATE_GETTER;
5323
5603
  exports.SVGWrapper = SVGWrapper;
5324
5604
  exports.Scheduler = Scheduler;
5325
5605
  exports.Suspense = Suspense;
5606
+ exports.Svg = Svg;
5326
5607
  exports.Swap = Swap;
5327
5608
  exports.SwipeEvent = SwipeEvent;
5328
5609
  exports.Switch = Switch;
@@ -5330,12 +5611,15 @@
5330
5611
  exports.TimeAnimation = TimeAnimation;
5331
5612
  exports.TimeLoop = TimeLoop;
5332
5613
  exports.TimeScheduler = TimeScheduler;
5614
+ exports.UICanvas = UICanvas;
5333
5615
  exports.UIElement = UIElement$1;
5334
5616
  exports.UIFlex = UIFlex;
5335
5617
  exports.UIFragment = UIFragment;
5336
5618
  exports.UIHTMLWrapper = UIHTMLWrapper;
5337
5619
  exports.UINode = UINode;
5338
5620
  exports.UISVGWrapper = UISVGWrapper;
5621
+ exports.UISuspense = UISuspense;
5622
+ exports.UISvg = UISvg;
5339
5623
  exports.UISwap = UISwap;
5340
5624
  exports.UISwitch = UISwitch;
5341
5625
  exports.UIView = UIView;
@@ -5346,7 +5630,6 @@
5346
5630
  exports.ViewListeners = ViewListeners;
5347
5631
  exports.ZikoApp = ZikoApp;
5348
5632
  exports.ZikoSPA = ZikoSPA;
5349
- exports.ZikoUISuspense = ZikoUISuspense;
5350
5633
  exports.ZikoUIText = ZikoUIText;
5351
5634
  exports.abs = abs;
5352
5635
  exports.accum_max = accum_max;
@@ -5518,6 +5801,7 @@
5518
5801
  exports.trimmed_mean = trimmed_mean;
5519
5802
  exports.trunc = trunc;
5520
5803
  exports.useDerived = useDerived;
5804
+ exports.useEffect = useEffect;
5521
5805
  exports.useEventEmitter = useEventEmitter;
5522
5806
  exports.useIPC = useIPC;
5523
5807
  exports.useLocalStorage = useLocalStorage;