xote 6.3.0 → 7.0.0-beta.1
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 +132 -33
- 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 +1450 -2459
- 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 +233 -39
- package/src/View.res.mjs +309 -32
- package/src/XoteJSX.res +214 -0
- package/src/XoteJSX.res.mjs +63 -0
- 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,21 @@ module Render = {
|
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
let getKeyedChildren = (children: array<node>): option<array<keyedChild>> => {
|
|
120
|
-
|
|
121
|
-
let allKeyed = ref(true)
|
|
122
|
-
|
|
123
|
-
children->Array.forEach(child => {
|
|
124
|
-
switch child {
|
|
125
|
-
| Keyed({key, identity, child}) =>
|
|
126
|
-
keyedChildren->Array.push({key, identity, child})->ignore
|
|
127
|
-
| _ => allKeyed := false
|
|
128
|
-
}
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
if allKeyed.contents {
|
|
132
|
-
Some(keyedChildren)
|
|
133
|
-
} else {
|
|
123
|
+
if children->Core.Array.length == 0 {
|
|
134
124
|
None
|
|
125
|
+
} else {
|
|
126
|
+
let keyedChildren = children->Core.Array.filterMap(child => {
|
|
127
|
+
switch child {
|
|
128
|
+
| Keyed({key, identity, child}) => Some({key, identity, child})
|
|
129
|
+
| _ => None
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
if keyedChildren->Core.Array.length == children->Core.Array.length {
|
|
134
|
+
Some(keyedChildren)
|
|
135
|
+
} else {
|
|
136
|
+
None
|
|
137
|
+
}
|
|
135
138
|
}
|
|
136
139
|
}
|
|
137
140
|
|
|
@@ -284,8 +287,7 @@ module Render = {
|
|
|
284
287
|
clearKeyedItems(keyedItems)
|
|
285
288
|
|
|
286
289
|
/* Dispose existing children */
|
|
287
|
-
|
|
288
|
-
childNodes->Array.forEach(disposeElement)
|
|
290
|
+
container->DOM.childNodesToArray->Array.forEach(disposeElement)
|
|
289
291
|
|
|
290
292
|
/* Clear existing children */
|
|
291
293
|
DOM.setInnerHTML(container, "")
|
|
@@ -543,11 +545,21 @@ let int = (value: int): node => Text(Int.toString(value))
|
|
|
543
545
|
|
|
544
546
|
let float = (value: float): node => Text(Float.toString(value))
|
|
545
547
|
|
|
548
|
+
let bool = (value: bool): node => Text(value ? "true" : "false")
|
|
549
|
+
|
|
546
550
|
/* Fragments */
|
|
547
551
|
let fragment = (children: array<node>): node => Fragment(children)
|
|
548
552
|
|
|
549
553
|
let signalFragment = (signal: Signal.t<array<node>>): node => SignalFragment(signal)
|
|
550
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
|
+
|
|
551
563
|
/* Lists */
|
|
552
564
|
let each = (signal: Signal.t<array<'a>>, renderItem: 'a => node): node => {
|
|
553
565
|
let nodesSignal = Computed.make(() => {
|
|
@@ -556,8 +568,6 @@ let each = (signal: Signal.t<array<'a>>, renderItem: 'a => node): node => {
|
|
|
556
568
|
SignalFragment(nodesSignal)
|
|
557
569
|
}
|
|
558
570
|
|
|
559
|
-
let list = each
|
|
560
|
-
|
|
561
571
|
let eachWithKey = (
|
|
562
572
|
signal: Signal.t<array<'a>>,
|
|
563
573
|
keyFn: 'a => string,
|
|
@@ -570,14 +580,116 @@ let eachWithKey = (
|
|
|
570
580
|
})
|
|
571
581
|
}
|
|
572
582
|
|
|
573
|
-
|
|
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
|
+
}
|
|
574
686
|
|
|
575
687
|
/* Element constructor */
|
|
576
688
|
let element = (
|
|
577
689
|
tag: string,
|
|
578
|
-
~attrs: array<(string, attrValue)>=[]
|
|
579
|
-
~events: array<(string, Dom.event => unit)>=[]
|
|
580
|
-
~children: array<node>=[]
|
|
690
|
+
~attrs: array<(string, attrValue)>=[],
|
|
691
|
+
~events: array<(string, Dom.event => unit)>=[],
|
|
692
|
+
~children: array<node>=[],
|
|
581
693
|
(),
|
|
582
694
|
): node => Element({tag, attrs, events, children})
|
|
583
695
|
|
|
@@ -597,3 +709,85 @@ let mountById = (node: node, containerId: string): unit => {
|
|
|
597
709
|
| None => Console.error("Container element not found: " ++ containerId)
|
|
598
710
|
}
|
|
599
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
|
+
}
|