xote 6.4.0 → 7.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/README.md +146 -36
- package/dist/RuntimeAttr.res-Cr5Qmz0i.js +1 -0
- package/dist/RuntimeAttr.res-DAZkL5CF.mjs +539 -0
- package/dist/RuntimeHydrationMarkers.res-C5-ieaOS.js +1 -0
- package/dist/RuntimeHydrationMarkers.res-DHikAvHr.mjs +6 -0
- package/dist/RuntimeJsxProp.res-A6N-qWoK.js +1 -0
- package/dist/RuntimeJsxProp.res-D3W5GXqT.mjs +64 -0
- package/dist/Stdlib_Array-1YCQzU_Y.mjs +22 -0
- package/dist/Stdlib_Array-BeBVUIuY.js +1 -0
- package/dist/View.res-C36--SJD.js +1 -0
- package/dist/View.res-SuqJrQPC.mjs +777 -0
- package/dist/client.cjs +1 -0
- package/dist/client.mjs +131 -0
- package/dist/hydration.cjs +1 -0
- package/dist/hydration.mjs +385 -0
- package/dist/mdx.cjs +1 -0
- package/dist/mdx.mjs +50 -0
- package/dist/router.cjs +1 -0
- package/dist/router.mjs +276 -0
- package/dist/ssr.cjs +17 -0
- package/dist/ssr.mjs +321 -0
- package/dist/xote.cjs +1 -17
- package/dist/xote.mjs +1456 -2467
- package/dist/xote.umd.js +1 -17
- package/package.json +42 -10
- package/rescript.json +2 -2
- package/src/Mdx.res +77 -0
- package/src/Mdx.res.mjs +93 -0
- package/src/Router.res +62 -8
- package/src/Router.res.mjs +60 -6
- package/src/RuntimeDom.res +7 -0
- package/src/RuntimeDom.res.mjs +8 -0
- package/src/RuntimeJsxProp.res +5 -8
- package/src/RuntimeJsxProp.res.mjs +9 -10
- package/src/RuntimeValue.res +35 -0
- package/src/RuntimeValue.res.mjs +67 -0
- package/src/SSRState.res +1 -4
- package/src/SSRState.res.mjs +4 -10
- package/src/View.res +224 -34
- package/src/View.res.mjs +306 -32
- package/src/jsx-dev-runtime.mjs +7 -0
- package/src/jsx-runtime.mjs +276 -0
- package/src/Node.res +0 -2
- package/src/Node.res.mjs +0 -82
- package/src/ReactiveProp.res +0 -2
- package/src/ReactiveProp.res.mjs +0 -19
package/src/View.res
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
module DOM = RuntimeDom
|
|
2
2
|
module Reactivity = RuntimeOwner
|
|
3
|
+
module Core = RescriptCore
|
|
3
4
|
|
|
4
5
|
/* ============================================================================
|
|
5
6
|
* Type Definitions
|
|
@@ -85,30 +86,32 @@ module Render = {
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
/* Recursively dispose children */
|
|
88
|
-
|
|
89
|
-
childNodes->Array.forEach(disposeElement)
|
|
89
|
+
el->DOM.childNodesToArray->Array.forEach(disposeElement)
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
let shallowEqualIdentity = (a: Obj.t, b: Obj.t): bool =>
|
|
93
93
|
if a === b {
|
|
94
94
|
true
|
|
95
|
-
} else if typeof(a) != #object || typeof(b) != #object {
|
|
96
|
-
false
|
|
97
95
|
} else {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
switch (a->Core.Type.Classify.classify, b->Core.Type.Classify.classify) {
|
|
97
|
+
| (Object(objA), Object(objB)) => {
|
|
98
|
+
let dictA: Dict.t<Obj.t> = Obj.magic(objA)
|
|
99
|
+
let dictB: Dict.t<Obj.t> = Obj.magic(objB)
|
|
100
|
+
let keysA = dictA->Dict.keysToArray
|
|
101
|
+
let keysB = dictB->Dict.keysToArray
|
|
102
|
+
|
|
103
|
+
if keysA->Array.length !== keysB->Array.length {
|
|
104
|
+
false
|
|
105
|
+
} else {
|
|
106
|
+
keysA->Array.every(key =>
|
|
107
|
+
switch (dictA->Dict.get(key), dictB->Dict.get(key)) {
|
|
108
|
+
| (Some(valueA), Some(valueB)) => valueA === valueB
|
|
109
|
+
| _ => false
|
|
110
|
+
}
|
|
111
|
+
)
|
|
110
112
|
}
|
|
111
|
-
|
|
113
|
+
}
|
|
114
|
+
| _ => false
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
|
|
@@ -117,21 +120,17 @@ module Render = {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
let getKeyedChildren = (children: array<node>): option<array<keyedChild>> => {
|
|
120
|
-
if Array.length
|
|
123
|
+
if children->Core.Array.length == 0 {
|
|
121
124
|
None
|
|
122
125
|
} else {
|
|
123
|
-
let keyedChildren =
|
|
124
|
-
let allKeyed = ref(true)
|
|
125
|
-
|
|
126
|
-
children->Array.forEach(child => {
|
|
126
|
+
let keyedChildren = children->Core.Array.filterMap(child => {
|
|
127
127
|
switch child {
|
|
128
|
-
| Keyed({key, identity, child}) =>
|
|
129
|
-
|
|
130
|
-
| _ => allKeyed := false
|
|
128
|
+
| Keyed({key, identity, child}) => Some({key, identity, child})
|
|
129
|
+
| _ => None
|
|
131
130
|
}
|
|
132
131
|
})
|
|
133
132
|
|
|
134
|
-
if
|
|
133
|
+
if keyedChildren->Core.Array.length == children->Core.Array.length {
|
|
135
134
|
Some(keyedChildren)
|
|
136
135
|
} else {
|
|
137
136
|
None
|
|
@@ -288,8 +287,7 @@ module Render = {
|
|
|
288
287
|
clearKeyedItems(keyedItems)
|
|
289
288
|
|
|
290
289
|
/* Dispose existing children */
|
|
291
|
-
|
|
292
|
-
childNodes->Array.forEach(disposeElement)
|
|
290
|
+
container->DOM.childNodesToArray->Array.forEach(disposeElement)
|
|
293
291
|
|
|
294
292
|
/* Clear existing children */
|
|
295
293
|
DOM.setInnerHTML(container, "")
|
|
@@ -547,11 +545,21 @@ let int = (value: int): node => Text(Int.toString(value))
|
|
|
547
545
|
|
|
548
546
|
let float = (value: float): node => Text(Float.toString(value))
|
|
549
547
|
|
|
548
|
+
let bool = (value: bool): node => Text(value ? "true" : "false")
|
|
549
|
+
|
|
550
550
|
/* Fragments */
|
|
551
551
|
let fragment = (children: array<node>): node => Fragment(children)
|
|
552
552
|
|
|
553
553
|
let signalFragment = (signal: Signal.t<array<node>>): node => SignalFragment(signal)
|
|
554
554
|
|
|
555
|
+
let childrenToArray = (child: option<node>): array<node> => {
|
|
556
|
+
switch child {
|
|
557
|
+
| Some(Fragment(children)) => children
|
|
558
|
+
| Some(child) => [child]
|
|
559
|
+
| None => []
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
555
563
|
/* Lists */
|
|
556
564
|
let each = (signal: Signal.t<array<'a>>, renderItem: 'a => node): node => {
|
|
557
565
|
let nodesSignal = Computed.make(() => {
|
|
@@ -560,8 +568,6 @@ let each = (signal: Signal.t<array<'a>>, renderItem: 'a => node): node => {
|
|
|
560
568
|
SignalFragment(nodesSignal)
|
|
561
569
|
}
|
|
562
570
|
|
|
563
|
-
let list = each
|
|
564
|
-
|
|
565
571
|
let eachWithKey = (
|
|
566
572
|
signal: Signal.t<array<'a>>,
|
|
567
573
|
keyFn: 'a => string,
|
|
@@ -574,14 +580,116 @@ let eachWithKey = (
|
|
|
574
580
|
})
|
|
575
581
|
}
|
|
576
582
|
|
|
577
|
-
|
|
583
|
+
/* JSX rendering primitives */
|
|
584
|
+
module For = {
|
|
585
|
+
type props<'item> = {
|
|
586
|
+
each: Prop.t<array<'item>>,
|
|
587
|
+
by?: 'item => string,
|
|
588
|
+
render: 'item => node,
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
let make = (props: props<'item>): node => {
|
|
592
|
+
switch (props.each, props.by) {
|
|
593
|
+
| (Static(items), Some(keyFn)) =>
|
|
594
|
+
fragment(
|
|
595
|
+
items->Array.map(item =>
|
|
596
|
+
Keyed({key: keyFn(item), identity: Obj.magic(item), child: props.render(item)})
|
|
597
|
+
),
|
|
598
|
+
)
|
|
599
|
+
| (Static(items), None) => fragment(items->Array.map(props.render))
|
|
600
|
+
| (Reactive(signal), Some(keyFn)) => eachWithKey(signal, keyFn, props.render)
|
|
601
|
+
| (Reactive(signal), None) => each(signal, props.render)
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
module KeyedFor = {
|
|
607
|
+
type props<'item> = {
|
|
608
|
+
each: Prop.t<array<'item>>,
|
|
609
|
+
by: 'item => string,
|
|
610
|
+
render: 'item => node,
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
let make = (props: props<'item>): node => {
|
|
614
|
+
switch props.each {
|
|
615
|
+
| Static(items) =>
|
|
616
|
+
fragment(
|
|
617
|
+
items->Array.map(item =>
|
|
618
|
+
Keyed({key: props.by(item), identity: Obj.magic(item), child: props.render(item)})
|
|
619
|
+
),
|
|
620
|
+
)
|
|
621
|
+
| Reactive(signal) => eachWithKey(signal, props.by, props.render)
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
module Show = {
|
|
627
|
+
type props = {
|
|
628
|
+
when_: Prop.t<bool>,
|
|
629
|
+
children?: node,
|
|
630
|
+
fallback?: node,
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
let make = (props: props): node => {
|
|
634
|
+
switch props.when_ {
|
|
635
|
+
| Static(true) => fragment(childrenToArray(props.children))
|
|
636
|
+
| Static(false) => fragment(childrenToArray(props.fallback))
|
|
637
|
+
| Reactive(signal) =>
|
|
638
|
+
signalFragment(
|
|
639
|
+
Computed.make(() =>
|
|
640
|
+
if Signal.get(signal) {
|
|
641
|
+
childrenToArray(props.children)
|
|
642
|
+
} else {
|
|
643
|
+
childrenToArray(props.fallback)
|
|
644
|
+
}
|
|
645
|
+
),
|
|
646
|
+
)
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
module Maybe = {
|
|
652
|
+
type props<'value> = {
|
|
653
|
+
value: Prop.t<option<'value>>,
|
|
654
|
+
render: 'value => node,
|
|
655
|
+
fallback?: node,
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
let renderValue = (props: props<'value>, value: option<'value>): array<node> => {
|
|
659
|
+
switch value {
|
|
660
|
+
| Some(value) => [props.render(value)]
|
|
661
|
+
| None => childrenToArray(props.fallback)
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
let make = (props: props<'value>): node => {
|
|
666
|
+
switch props.value {
|
|
667
|
+
| Static(value) => fragment(renderValue(props, value))
|
|
668
|
+
| Reactive(signal) => signalFragment(Computed.make(() => renderValue(props, Signal.get(signal))))
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
module Value = {
|
|
674
|
+
type props<'value> = {
|
|
675
|
+
value: Prop.t<'value>,
|
|
676
|
+
render: 'value => node,
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
let make = (props: props<'value>): node => {
|
|
680
|
+
switch props.value {
|
|
681
|
+
| Static(value) => props.render(value)
|
|
682
|
+
| Reactive(signal) => signalFragment(Computed.make(() => [props.render(Signal.get(signal))]))
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
578
686
|
|
|
579
687
|
/* Element constructor */
|
|
580
688
|
let element = (
|
|
581
689
|
tag: string,
|
|
582
|
-
~attrs: array<(string, attrValue)>=[]
|
|
583
|
-
~events: array<(string, Dom.event => unit)>=[]
|
|
584
|
-
~children: array<node>=[]
|
|
690
|
+
~attrs: array<(string, attrValue)>=[],
|
|
691
|
+
~events: array<(string, Dom.event => unit)>=[],
|
|
692
|
+
~children: array<node>=[],
|
|
585
693
|
(),
|
|
586
694
|
): node => Element({tag, attrs, events, children})
|
|
587
695
|
|
|
@@ -601,3 +709,85 @@ let mountById = (node: node, containerId: string): unit => {
|
|
|
601
709
|
| None => Console.error("Container element not found: " ++ containerId)
|
|
602
710
|
}
|
|
603
711
|
}
|
|
712
|
+
|
|
713
|
+
let isReactiveProp = RuntimeValue.isReactiveProp
|
|
714
|
+
|
|
715
|
+
let valuePrimitive = (value: 'input, stringify: 'value => string): node => {
|
|
716
|
+
if isReactiveProp(value) {
|
|
717
|
+
let prop: Prop.t<'value> = Obj.magic(value)
|
|
718
|
+
switch prop {
|
|
719
|
+
| Static(value) => text(stringify(value))
|
|
720
|
+
| Reactive(signal) => SignalText(Computed.make(() => stringify(Signal.get(signal))))
|
|
721
|
+
}
|
|
722
|
+
} else {
|
|
723
|
+
switch value->Core.Type.Classify.classify {
|
|
724
|
+
| Function(_) => {
|
|
725
|
+
let compute: unit => 'value = Obj.magic(value)
|
|
726
|
+
signalText(() => stringify(compute()))
|
|
727
|
+
}
|
|
728
|
+
| Object(_) => {
|
|
729
|
+
let signal: Signal.t<'value> = Obj.magic(value)
|
|
730
|
+
SignalText(Computed.make(() => stringify(Signal.get(signal))))
|
|
731
|
+
}
|
|
732
|
+
| Null | Undefined => null()
|
|
733
|
+
| _ => {
|
|
734
|
+
let value: 'value = Obj.magic(value)
|
|
735
|
+
text(stringify(value))
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
let renderValuePrimitiveProps = (props: 'props, stringify: 'scalar => string): node => {
|
|
742
|
+
switch (props->RuntimeValue.getField("children"), props->RuntimeValue.getField("value")) {
|
|
743
|
+
| (Some(children), _) => valuePrimitive(children, stringify)
|
|
744
|
+
| (None, Some(value)) => valuePrimitive(value, stringify)
|
|
745
|
+
| (None, None) => null()
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
module Text = {
|
|
750
|
+
type props<'value, 'children> = {
|
|
751
|
+
value?: 'value,
|
|
752
|
+
children?: 'children,
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
let make = (props: props<'value, 'children>): node => {
|
|
756
|
+
renderValuePrimitiveProps(props, value => value)
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
module Int = {
|
|
761
|
+
type props<'value, 'children> = {
|
|
762
|
+
value?: 'value,
|
|
763
|
+
children?: 'children,
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
let make = (props: props<'value, 'children>): node => {
|
|
767
|
+
renderValuePrimitiveProps(props, value => value->Int.toString)
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
module Float = {
|
|
772
|
+
type props<'value, 'children> = {
|
|
773
|
+
value?: 'value,
|
|
774
|
+
children?: 'children,
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
let make = (props: props<'value, 'children>): node => {
|
|
778
|
+
renderValuePrimitiveProps(props, value => value->Float.toString)
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
module Bool = {
|
|
783
|
+
type props<'value, 'children> = {
|
|
784
|
+
value?: 'value,
|
|
785
|
+
children?: 'children,
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
let toString = value => value ? "true" : "false"
|
|
789
|
+
|
|
790
|
+
let make = (props: props<'value, 'children>): node => {
|
|
791
|
+
renderValuePrimitiveProps(props, toString)
|
|
792
|
+
}
|
|
793
|
+
}
|