builtin.km 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. namespace ::
  2. type <InvalidType> interface {}
  3. type <GenericType> native
  4. type IntoReflectType[T] native
  5. type IntoReflectValue[T] native
  6. type DummyReflectType native
  7. const ReflectType DummyReflectType native('ReflectType')
  8. function DebugInspect[T] { hint String, v IntoReflectValue[T] } T native('DebugInspect')
  9. function DebugExpose[T] { name String, v IntoReflectValue[T] } $[Null] native('DebugExpose')
  10. function DebugTrace[T] { hint String, o IntoReflectValue[$[T]] } $[T] native('DebugTrace')
  11. function DebugWatch[T] { hint String, o IntoReflectValue[$[T]] } $[Null] native('DebugWatch')
  12. function Serialize[T] { v IntoReflectValue[T] } $[String] native('Serialize')
  13. function Deserialize[T] { s String, t IntoReflectType[T] } $[T] native('Deserialize')
  14. function <ObjectPairEqualities>[T] { o $[Pair[T,T]] } $[Bool] native('ObjectPairEqualities')
  15. type Null native
  16. const Null Null native('Null')
  17. type Error native
  18. function <Error> { msg String } Error native('Error')
  19. function variadic Error { msg List[~String] } Error { <Error>(String{fragments:msg}) }
  20. method Error.Message String native('ErrorMessage')
  21. method Error.IsCancel Bool native('ErrorIsCancel')
  22. operator wrap { err Error, msg String } Error native('ErrorWrap')
  23. function Undefined[T] { msg String('') } T native('Undefined')
  24. type Bool(~String) native
  25. const No Bool native('BoolNo')
  26. const Yes Bool native('BoolYes')
  27. function Not { p Bool } Bool native('BoolNot')
  28. operator and { p Bool, q Bool } Bool native('BoolAnd')
  29. operator or { p Bool, q Bool } Bool native('BoolOr')
  30. operator == { p Bool, q Bool } Bool native('BoolEqual')
  31. operator assert[T] { ok Bool, k Lambda[Null,T] } T native('BoolAssert')
  32. type Ordering(~String) enum { L<R, L=R, L>R }
  33. operator == { o1 Ordering, o2 Ordering } Bool { (([Int]) o1 == o2) }
  34. type == [T] interface { Operator Lambda[Pair[T,T],Bool] }
  35. type < [T] interface { Operator Lambda[Pair[T,T],Bool] }
  36. type <> [T] interface { Operator Lambda[Pair[T,T],Ordering] }
  37. operator != [T] { a T, b T } { T/== ==[T] } Bool { Not(T/==(a,b)) }
  38. operator > [T] { a T, b T } { T/< <[T] } Bool { T/<(b,a) }
  39. operator <= [T] { a T, b T } { T/< <[T] } Bool { Not(T/<(b,a)) }
  40. operator >= [T] { a T, b T } { T/< <[T] } Bool { Not(T/<(a,b)) }
  41. function Min[T] { a T, b T } { T/< <[T] } T { if (T/<(a,b)) { a } else { b } }
  42. function Max[T] { a T, b T } { T/< <[T] } T { if (T/<(b,a)) { a } else { b } }
  43. type Int(~String) native
  44. operator + { a Int, b Int } Int native('IntPlus')
  45. operator - { a Int, b Int } Int native('IntMinus')
  46. operator * { a Int, b Int } Int native('IntTimes')
  47. operator / { a Int, b Int } Int native('IntQuo')
  48. operator % { a Int, b Int } Int native('IntRem')
  49. operator ^ { a Int, b Int } Int native('IntPow')
  50. operator == { a Int, b Int } Bool native('IntEqual')
  51. operator < { a Int, b Int } Bool native('IntLessThan')
  52. operator <> { a Int, b Int } Ordering native('IntCompare')
  53. type Float(~String) native
  54. operator + { x Float, y Float } Float native('FloatPlus')
  55. operator - { x Float, y Float } Float native('FloatMinus')
  56. operator * { x Float, y Float } Float native('FloatTimes')
  57. operator / { x Float, y Float } Float native('FloatQuo')
  58. operator % { x Float, y Float } Float native('FloatRem')
  59. operator ^ { x Float, y Float } Float native('FloatPow')
  60. operator == { x Float, y Float } Bool native('FloatEqual')
  61. operator < { x Float, y Float } Bool native('FloatLessThan')
  62. function Floor { x Float } Float native('Floor')
  63. function Ceil { x Float } Float native('Ceil')
  64. function Round { x Float } Float native('Round')
  65. function Sqrt { x Float } Float native('Sqrt')
  66. function Cbrt { x Float } Float native('Cbrt')
  67. function Exp { x Float } Float native('Exp')
  68. function Log { x Float } Float native('Log')
  69. function Sin { x Float } Float native('Sin')
  70. function Cos { x Float } Float native('Cos')
  71. function Tan { x Float } Float native('Tan')
  72. function Asin { x Float } Float native('Asin')
  73. function Acos { x Float } Float native('Acos')
  74. function Atan { x Float } Float native('Atan')
  75. function Atan2 { y Float, x Float } Float native('Atan2')
  76. const E Float { Exp(1) }
  77. const PI Float { Acos(-1) }
  78. method Float.Int Int native('FloatInt')
  79. method Int.Float Float native('IntFloat')
  80. method Float.Normal Bool native('FloatNormal')
  81. method Float.NaN Bool native('FloatNaN')
  82. method Float.Infinite Bool native('FloatInfinite')
  83. const NaN Float { (0.0 / 0) }
  84. const +Inf Float { (1.0 / 0) }
  85. const -Inf Float { (-1.0 / 0) }
  86. type Char(~String) native
  87. function Char { value Int } Char native('Char')
  88. method Char.Int Int native('CharInt')
  89. method Char.Utf8Size Int native('CharUtf8Size')
  90. operator == { a Char, b Char } Bool native('CharEqual')
  91. operator < { a Char, b Char } Bool native('CharLessThan')
  92. operator <> { a Char, b Char } Ordering native('CharCompare')
  93. type String native
  94. function variadic String { fragments List[~String] } String native('String')
  95. function StringFromChars { chars List[Char] } String native('StringFromChars')
  96. function Quote { s String } String native('Quote')
  97. function Unquote { s String } Maybe[String] native('Unquote')
  98. method String.Empty Bool native('StringEmpty')
  99. method String.Chars List[Char] native('StringChars')
  100. method String.FirstChar Maybe[Char] native('StringFirstChar')
  101. method String.NumberOfChars Int native('StringNumberOfChars')
  102. method String.Utf8Size Int native('StringUtf8Size')
  103. operator == { a String, b String } Bool native('StringEqual')
  104. operator < { a String, b String } Bool native('StringLessThan')
  105. operator <> { a String, b String } Ordering native('StringCompare')
  106. operator shift { s String } Maybe[Pair[Char,String]] native('StringShift')
  107. operator reverse { s String } String native('StringReverse')
  108. operator join { l List[String], sep String } String native('ListStringJoin')
  109. operator split { s String, sep String } List[String] native('StringSplit')
  110. operator cut { s String, sep String } Maybe[Pair[String,String]] native('StringCut')
  111. operator has-prefix { s String, prefix String } Bool native('StringHasPrefix')
  112. operator has-suffix { s String, suffix String } Bool native('StringHasSuffix')
  113. operator trim-prefix { s String, prefix String } String native('StringTrimPrefix')
  114. operator trim-suffix { s String, suffix String } String native('StringTrimSuffix')
  115. operator trim { s String, chars List[Char] } String native('StringTrim')
  116. operator trim-left { s String, chars List[Char] } String native('StringTrimLeft')
  117. operator trim-right { s String, chars List[Char] } String native('StringTrimRight')
  118. type RegExp(~String) native
  119. method RegExp.String String native('RegExpString')
  120. operator advance { s String, re RegExp } Maybe[Pair[String,String]] native('StringAdvance')
  121. operator satisfy { s String, re RegExp } Bool native('StringSatisfy')
  122. operator replace { s String, re RegExp, f Lambda[String,String] } String native('StringReplace')
  123. type ~String interface { String String }
  124. method Bool.String String native('BoolString')
  125. method Ordering.String String native('OrderingString')
  126. method Int.String String native('IntString')
  127. method Float.String String native('FloatString')
  128. method Char.String String native('CharString')
  129. function ParseInt { s String } Maybe[Int] native('ParseInt')
  130. function ParseFloat { s String } Maybe[Float] native('ParseFloat')
  131. type Bytes native
  132. // no bytes api for now
  133. type List[T] native
  134. function variadic List[T] { items List[T] } List[T] { items }
  135. function variadic ListConcat[T] { lists List[List[T]] } List[T] native('ListConcat')
  136. function Cons[T] { head T, tail List[T] } List[T] native('Cons')
  137. function Count { n Int } List[Int] native('Count')
  138. method List.Empty Bool native('ListEmpty')
  139. method List.First Maybe[T] native('ListFirst')
  140. method List.Length Int native('ListLength')
  141. method List.Seq Seq[T] native('ListSeq')
  142. method List.$ $[T] { ${items:this} }
  143. operator shift[T] { l List[T] } Maybe[Pair[T,List[T]]] native('ListShift')
  144. operator prepend[T] { l List[T], item T } List[T] { Cons(item, l) }
  145. operator reverse[T] { l List[T] } List[T] native('ListReverse')
  146. operator sort[T] { l List[T] } { T/< <[T] } List[T] native('ListSort')
  147. operator take[T] { l List[T], n Int } List[T] native('ListTake')
  148. operator with-index[T] { l List[T] } List[Pair[T,Int]] native('ListWithIndex')
  149. operator map[A,B] { l List[A], f Lambda[A,B] } List[B] native('ListMap')
  150. operator map?[A,B] { l List[A], f Lambda[A,Maybe[B]] } List[B] native('ListDeflateMap')
  151. operator map*[A,B] { l List[A], f Lambda[A,List[B]] } List[B] native('ListFlatMap')
  152. operator filter[T] { l List[T], f Lambda[T,Bool] } List[T] native('ListFilter')
  153. operator scan[A,B] { l List[A], v B, f Lambda[Pair[B,A],B] } List[B] native('ListScan')
  154. operator fold[A,B] { l List[A], v B, f Lambda[Pair[B,A],B] } B native('ListFold')
  155. type Seq[T] native
  156. function variadic Seq[T] { items List[T] } Seq[T] { items.Seq }
  157. method Seq.Empty Bool native('SeqEmpty')
  158. method Seq.Last Maybe[T] native('SeqLast')
  159. method Seq.Length Int native('SeqLength')
  160. method Seq.List List[T] native('SeqList')
  161. operator append[T] { s Seq[T], item T } Seq[T] native('SeqAppend')
  162. operator append?[T] { s Seq[T], item? Maybe[T] } Seq[T] native('SeqDeflateAppend')
  163. operator append*[T] { s Seq[T], items List[T] } Seq[T] native('SeqFlatAppend')
  164. operator sort[T] { s Seq[T] } { T/< <[T] } Seq[T] native('SeqSort')
  165. operator filter[T] { s Seq[T], f Lambda[T,Bool] } Seq[T] native('SeqFilter')
  166. type Queue[T] native
  167. function variadic Queue[T] { items List[T] } Queue[T] native('Queue')
  168. method Queue.Empty Bool native('QueueEmpty')
  169. method Queue.Size Int native('QueueSize')
  170. method Queue.First Maybe[T] native('QueueFirst')
  171. method Queue.List List[T] native('QueueList')
  172. operator shift[T] { q Queue[T] } Maybe[Pair[T,Queue[T]]] native('QueueShift')
  173. operator append[T] { q Queue[T], item T } Queue[T] native('QueueAppend')
  174. type Heap[T] native
  175. function variadic Heap[T] { items List[T] } { T/< <[T] } Heap[T] native('Heap')
  176. method Heap.Empty Bool native('HeapEmpty')
  177. method Heap.Size Int native('HeapSize')
  178. method Heap.First Maybe[T] native('HeapFirst')
  179. method Heap.List List[T] native('HeapList')
  180. operator shift[T] { h Heap[T] } Maybe[Pair[T,Heap[T]]] native('HeapShift')
  181. operator insert[T] { h Heap[T], item T } Heap[T] native('HeapInsert')
  182. type Set[T] native
  183. function variadic Set[T] { items List[T] } { T/<> <>[T] } Set[T] native('Set')
  184. method Set.Empty Bool native('SetEmpty')
  185. method Set.Size Int native('SetSize')
  186. method Set.List List[T] native('SetList')
  187. operator has[T] { s Set[T], item T } Bool native('SetHas')
  188. operator delete[T] { s Set[T], item T } Set[T] native('SetDelete')
  189. operator insert[T] { s Set[T], item T } Set[T] native('SetInsert')
  190. type Map[K,V] native
  191. function variadic Map[K,V] { entries List[Pair[K,V]] } { K/<> <>[K] } Map[K,V] native('Map')
  192. method Map.Empty Bool native('MapEmpty')
  193. method Map.Size Int native('MapSize')
  194. method Map.Keys List[K] native('MapKeys')
  195. method Map.Values List[V] native('MapValues')
  196. method Map.Entries List[Pair[K,V]] native('MapEntries')
  197. operator has[K,V] { m Map[K,V], key K } Bool native('MapHas')
  198. operator lookup[K,V] { m Map[K,V], key K } Maybe[V] native('MapLookup')
  199. operator delete[K,V] { m Map[K,V], key K } Map[K,V] native('MapDelete')
  200. operator insert[K,V] { m Map[K,V], pair Pair[K,V] } Map[K,V] native('MapInsert')
  201. type Has[X,T] interface { Operator Lambda[Pair[X,T],Bool] }
  202. operator in[X,T] { item T, x X } { X/has Has[X,T] } Bool { X/has(x,item) }
  203. operator not-in[X,T] { item T, x X } { X/has Has[X,T] } Bool { Not((item in x)) }
  204. /// Observable
  205. type $[T] native
  206. function variadic $[T] { items List[T] } $[T] native('Observable')
  207. function variadic return[T] { items List[T] } $[T] { ${items} }
  208. function variadic Merge[T] { items List[$[T]] } $[T] { items | merge() }
  209. function variadic Concat[T] { items List[$[T]] } $[T] { items | concat() }
  210. function StartWith[T] { v T, o $[T] } $[T] { o | start-with(v) }
  211. function Go[T] { k Lambda[Null,T] } $[T] native('Go')
  212. function ForkJoin[T] { items List[$[T]], n Int(NumCPU) } $[List[T]] { items | fork-join(n) }
  213. function WithChildContext[T] { o $[T] } $[T] native('WithChildContext')
  214. function WithCancelTrigger[T] { cancel $[Null], o $[T] } $[T] native('WithCancelTrigger')
  215. function WithCancelTimeout[T] { ms Int, o $[T] } $[T] native('WithCancelTimeout')
  216. function SetTimeout { ms Int } $[Null] native('SetTimeout')
  217. function SetInterval { ms Int, n Int(-1) } $[Int] native('SetInterval')
  218. function Throw[T] { err Error } $[T] native('Throw')
  219. function Crash[T] { err Error } $[T] native('Crash')
  220. method $.Result $[Result[T]] { this | take-last() | map({ value => Success(value) }) | catch ({ (err,_) => $(err) }) }
  221. operator catch[T] { o $[T], f Lambda[Pair[Error,$[T]],$[T]] } $[T] native('ObservableCatch')
  222. operator retry[T] { o $[T], n Int(-1) } $[T] native('ObservableRetry')
  223. operator log-error[T] { o $[T] } $[T] native('ObservableLogError')
  224. operator distinct-until-changed[T] { o $[T] } { T/== ==[T] } $[T] native('ObservableDistinctUntilChanged')
  225. operator with-latest-from[T,X] { o $[T], x $[X] } $[Pair[T,X]] native('ObservableWithLatestFrom')
  226. operator map-to-latest-from[X] { o $[Null], x $[X] } $[X] native('ObservableMapToLatestFrom')
  227. operator with-cycle[T,X] { o $[T], l List[X] } $[Pair[T,X]] native('ObservableWithCycle')
  228. operator with-index[T] { o $[T] } $[Pair[T,Int]] native('ObservableWithIndex')
  229. operator with-time[T] { o $[T] } $[Pair[T,Time]] native('ObservableWithTime')
  230. operator delay-subscription[T] { o $[T], ms Int } $[T] native('ObservableDelaySubscription')
  231. operator delay-values[T] { o $[T], ms Int } $[T] native('ObservableDelayValues')
  232. operator start-with[T] { o $[T], item T } $[T] native('ObservableStartWith')
  233. operator end-with[T] { o $[T], item T } $[T] native('ObservableEndWith')
  234. operator throttle[T] { o $[T], f Lambda[T,$[Null]] } $[T] native('ObservableThrottle')
  235. operator debounce[T] { o $[T], f Lambda[T,$[Null]] } $[T] native('ObservableDebounce')
  236. operator throttle-time[T] { o $[T], ms Int } $[T] native('ObservableThrottleTime')
  237. operator debounce-time[T] { o $[T], ms Int } $[T] native('ObservableDebounceTime')
  238. operator complete-on-emit[T] { o $[T] } $[Null] native('ObservableCompleteOnEmit')
  239. operator skip[T] { o $[T], n Int } $[T] native('ObservableSkip')
  240. operator take[T] { o $[T], n Int } $[T] native('ObservableTake')
  241. operator take-last[T] { o $[T] } $[T] native('ObservableTakeLast')
  242. operator take-last?[T] { o $[T] } $[Maybe[T]] native('ObservableTakeLastAsMaybe')
  243. operator take-while[T] { o $[T], f Lambda[T,Bool] } $[T] native('ObservableTakeWhile')
  244. operator take-while?[T] { o $[Maybe[T]] } $[T] native('ObservableTakeWhileMaybeOK')
  245. operator take-until[T] { o $[T], stop $[Null] } $[T] native('ObservableTakeUntil')
  246. operator count[T] { o $[T] } $[Int] native('ObservableCount')
  247. operator collect[T] { o $[T], n Int(-1) } $[List[T]] native('ObservableCollect')
  248. operator buffer-time[T] { o $[T], ms Int } $[List[T]] native('ObservableBufferTime')
  249. operator pairwise[T] { o $[T] } $[Pair[T,T]] native('ObservablePairwise')
  250. operator buffer-count[T] { o $[T], n Int } $[Queue[T]] native('ObservableBufferCount')
  251. operator map[A,B] { o $[A], f Lambda[A,B] } $[B] native('ObservableMap')
  252. operator map-to[A,B] { o $[A], v B } $[B] native('ObservableMapTo')
  253. operator filter[T] { o $[T], f Lambda[T,Bool] } $[T] native('ObservableFilter')
  254. operator scan[A,B] { o $[A], v B, f Lambda[Pair[B,A],B] } $[B] native('ObservableScan')
  255. operator reduce[A,B] { o $[A], v B, f Lambda[Pair[B,A],B] } $[B] native('ObservableReduce')
  256. operator combine-latest[A,B] { a $[A], b $[B] } $[Pair[A,B]] native('ObservableCombineLatest')
  257. operator combine-latest[T] { l List[$[T]] } $[List[T]] native('ListObservableCombineLatest')
  258. operator await[A,B] { o $[A], k Lambda[A,$[B]] } $[B] native('ObservableAwait')
  259. operator await-noexcept[A,B] { o $[A], k Lambda[A,$[B]] } $[B] native('ObservableAwaitNoexcept')
  260. operator then[T] { o $[Null], k $[T] } $[T] native('ObservableThen')
  261. operator with[T] { o $[T], bg $[Null] } $[T] native('ObservableWith')
  262. operator and[T] { o $[T], bg $[Null] } $[T] native('ObservableAnd')
  263. operator auto-map[A,B] { o $[A], f Lambda[A,$[B]] } $[B] native('ObservableAutoMap')
  264. operator merge[T] { l List[$[T]] } $[T] native('ListObservableMerge')
  265. operator concat[T] { l List[$[T]] } $[T] native('ListObservableConcat')
  266. operator merge[T] { o1 $[T], o2 $[T] } $[T] native('ObservableMerge')
  267. operator concat[T] { o1 $[T], o2 $[T] } $[T] native('ObservableConcat')
  268. operator merge-map[A,B] { o $[A], f Lambda[A,$[B]] } $[B] native('ObservableMergeMap')
  269. operator concat-map[A,B] { o $[A], f Lambda[A,$[B]] } $[B] native('ObservableConcatMap')
  270. operator switch-map[A,B] { o $[A], f Lambda[A,$[B]] } $[B] native('ObservableSwitchMap')
  271. operator exhaust-map[A,B] { o $[A], f Lambda[A,$[B]] } $[B] native('ObservableExhaustMap')
  272. const NumCPU Int native('NumCPU')
  273. operator concurrent[T] { l List[$[T]], n Int(NumCPU) } $[T] native('ListObservableConcurrent')
  274. operator concurrent-map[A,B] { o $[A], f Lambda[A,$[B]], n Int(NumCPU) } $[B] native('ObservableConcurrentMap')
  275. operator fork-join[T] { l List[$[T]], n Int(NumCPU) } $[List[T]] native('ListObservableForkJoin')
  276. operator fork-join[A,B] { a $[A], b $[B], n Int(NumCPU) } $[Pair[A,B]] native('ObservableForkJoin')
  277. const UUID $[String] native('UUID')
  278. function Random { supremum Int } $[Int] native('Random')
  279. function Shuffle[T] { l List[T] } $[List[T]] native('Shuffle')
  280. type Subject[T] native
  281. function variadic CreateSubject[T] { replay Int(0), items List[T] } $[Subject[T]] native('CreateSubject')
  282. method Subject.$ $[T] { this.Values }
  283. method Subject.Values $[T] native('SubjectValues')
  284. operator << [T] { s Subject[T], o $[T] } $[Null] { (s plug o) }
  285. operator <- [T] { s Subject[T], v T } $[Null] { (s push v) }
  286. operator plug[T] { s Subject[T], o $[T] } $[Null] native('SubjectPlug')
  287. operator push [T] { s Subject[T], v T } $[Null] { s | plug($(v)) | end-with(Null) }
  288. function Multicast[T] { o $[T] } $[$[T]] native('Multicast')
  289. function Loopback[T] { k Lambda[$[T],$[T]] } $[T] native('Loopback')
  290. function SkipSync[T] { o $[T] } $[T] native('SkipSync')
  291. type State[T] record {
  292. <Subject> Subject[T]
  293. }
  294. function CreateState[T] { initial T } $[State[T]] {
  295. @map subject = CreateSubject[T](1, initial),
  296. new State(subject)
  297. }
  298. method State.$ $[T] { this.Value }
  299. method State.Value $[T] {
  300. this.<Subject>.Values
  301. }
  302. operator bind-update[T] { state State[T], updates $[Lambda[T,T]] } $[Null] {
  303. (state bind-override {
  304. updates | with-latest-from(state.$) | map({ (f,v) => f(v) })
  305. })
  306. }
  307. operator bind-override[T] { state State[T], values $[T] } $[Null] {
  308. (state.<Subject> plug values)
  309. }
  310. operator update[T] { state State[T], update Lambda[T,T] } $[Null] {
  311. state | bind-update($(update)) | end-with(Null)
  312. }
  313. operator override[T] { state State[T], value T } $[Null] {
  314. state | bind-override($(value)) | end-with(Null)
  315. }
  316. function MakeMemo[T] { o $[T] } $[$[T]] {
  317. @await subject = CreateSubject[T](1),
  318. $(subject.Values) | with((subject plug o))
  319. }
  320. type Time(~String) native
  321. method Time.String String native('TimeString')
  322. operator -ms { t Time, u Time } Int native('TimeSubtractMillisecond')
  323. const Now $[Time] native('Now')
  324. function TimeOf[T] { o $[T] } $[Time] { ({o | with-time()} map { (_,t) => t }) }
  325. type Lambda[A,B] native
  326. operator * [A,B,C] { f Lambda[B,C], g Lambda[A,B] } Lambda[A,C] {{ x => f(g(x)) }}
  327. operator -> [A,B] { x A, f Lambda[A,B] } B { f(x) }
  328. operator call [A,B] { f Lambda[A,B], x A } B { f(x) }
  329. type Pair[A,B] record {
  330. First A,
  331. Second B
  332. }
  333. type Triple[A,B,C] record {
  334. First A,
  335. Second B,
  336. Third C
  337. }
  338. function Pair[A,B] { first A, second B } Pair[A,B] {
  339. new Pair(first, second)
  340. }
  341. function Triple[A,B,C] { first A, second B, third C } Triple[A,B,C] {
  342. new Triple(first, second, third)
  343. }
  344. type Maybe[OK] union {
  345. Null,
  346. OK
  347. }
  348. function Nothing[T] {} Maybe[T] {
  349. Null
  350. }
  351. function Just[T] { value T } Maybe[T] {
  352. value
  353. }
  354. method Maybe.List List[OK] {
  355. if (let value = this) { List(value) }
  356. else { List() }
  357. }
  358. method Maybe.$ $[OK] {
  359. if (let value = this) { $(value) }
  360. else { $() }
  361. }
  362. operator ??[T] { value? Maybe[T], fallback T } T {
  363. if (let value = value?) { value }
  364. else { fallback }
  365. }
  366. operator map[A,B] { v? Maybe[A], f Lambda[A,B] } Maybe[B] {
  367. if (let v = v?) { f(v) }
  368. else { Null }
  369. }
  370. operator filter[T] { v? Maybe[T], f Lambda[T,Bool] } Maybe[T] {
  371. if (let v = v?) {
  372. if (f(v)) { v }
  373. else { Null }
  374. }
  375. else { Null }
  376. }
  377. operator maybe[A,B] { v? Maybe[A], k Lambda[A,Maybe[B]] } Maybe[B] {
  378. if (let v = v?) {
  379. if (let w = k(v)) { w }
  380. else { Null }
  381. }
  382. else { Null }
  383. }
  384. type Result[OK] union {
  385. Error,
  386. OK
  387. }
  388. function Success[T] { value T } Result[T] {
  389. value
  390. }
  391. method Result.Maybe Maybe[OK] {
  392. when (this) {
  393. Error => Null,
  394. OK value => value
  395. }
  396. }
  397. operator map[A,B] { r Result[A], f Lambda[A,B] } Result[B] {
  398. when (r) {
  399. OK a => f(a),
  400. Error e => e
  401. }
  402. }
  403. type Lens1[Whole,Part] record {
  404. Value Part,
  405. Assign Lambda[Part,Whole]
  406. }
  407. type Lens2[Abstract,Concrete] record {
  408. Value Maybe[Concrete],
  409. Assign Lambda[Concrete,Abstract]
  410. }
  411. method Lens1.Update Lambda[Lambda[Part,Part],Whole] {{
  412. f => this.Assign(f(this.Value))
  413. }}
  414. method Lens2.Update Lambda[Lambda[Maybe[Concrete],Concrete],Abstract] {{
  415. f => this.Assign(f(this.Value))
  416. }}
  417. method Lens1.Update? Lambda[Lambda[Part,Maybe[Part]],Maybe[Whole]] {{
  418. f => (f(this.Value) map this.Assign)
  419. }}
  420. method Lens2.Update? Lambda[Lambda[Maybe[Concrete],Maybe[Concrete]],Maybe[Abstract]] {{
  421. f => (f(this.Value) map this.Assign)
  422. }}
  423. operator compose1[A,B,C] { ab Lens1[A,B], f Lambda[B,Lens1[B,C]] } Lens1[A,C] {
  424. new Lens1 {
  425. Value: f(ab.Value).Value,
  426. Assign: { c => ab.Assign(f(ab.Value).Assign(c)) }
  427. }
  428. }
  429. operator compose2[A,B,C] { ab Lens1[A,B], f Lambda[B,Lens2[B,C]] } Lens2[A,C] {
  430. new Lens2 {
  431. Value: f(ab.Value).Value,
  432. Assign: { c => ab.Assign(f(ab.Value).Assign(c)) }
  433. }
  434. }
  435. operator compose[A,B,C] { ab Lens2[A,B], f Lambda[Maybe[B],Lens2[B,C]] } Lens2[A,C] {
  436. new Lens2 {
  437. Value: f(ab.Value).Value,
  438. Assign: { c => ab.Assign(f(ab.Value).Assign(c)) }
  439. }
  440. }
  441. function Get[Resp] { endpoint String, t IntoReflectType[Resp], token String('') } $[Resp] native('Get')
  442. function Post[Req,Resp] { data IntoReflectValue[Req], endpoint String, t IntoReflectType[Resp], token String('') } $[Resp] native('Post')
  443. function Put[Req,Resp] { data IntoReflectValue[Req], endpoint String, t IntoReflectType[Resp], token String('') } $[Resp] native('Put')
  444. function Delete[Resp] { endpoint String, t IntoReflectType[Resp], token String('') } $[Resp] native('Delete')
  445. function Subscribe[Resp] { endpoint String, t IntoReflectType[Resp], token String('') } $[Resp] native('Subscribe')
  446. /// opaque file path type
  447. type File(~String) native
  448. method File.String String native('FileString')
  449. operator == { f File, g File } Bool native('FileEqual')
  450. function ReadTextFile { f File } $[String] native('ReadTextFile')
  451. function WriteTextFile { f File, text String } $[Null] native('WriteTextFile')
  452. function ReadConfig[T] { dir String, name String, default IntoReflectValue[T] } $[T] native('ReadConfig')
  453. function WriteConfig[T] { dir String, name String, value IntoReflectValue[T] } $[Null] native('WriteConfig')
  454. const Arguments List[String] native('Arguments')
  455. const Environment List[String] native('Environment')
  456. const FontSize Int native('FontSize')
  457. function ShowInfo { content String, title String('Info') } $[Null] native('ShowInfo')
  458. function ShowWarning { content String, title String('Warning') } $[Null] native('ShowWarning')
  459. function ShowCritical { content String, title String('Error') } $[Null] native('ShowCritical')
  460. function ShowYesNo { content String, title String('Question') } $[Bool] native('ShowYesNo')
  461. function ShowAbortRetryIgnore { content String, title String('Error') } $[Retry/Ignore] native('ShowAbortRetryIgnore')
  462. function ShowSaveDiscardCancel { content String, title String('Save Changes') } $[Save/Discard] native('ShowSaveDiscardCancel')
  463. type Retry/Ignore enum { Retry, Ignore }
  464. type Save/Discard enum { Save, Discard }
  465. function GetChoice[T] { prompt String, items List[ComboBoxItem[T]], title String('Select') } $[T] native('GetChoice')
  466. function GetLine { prompt String, initial String(''), title String('Input') } $[String] native('GetLine')
  467. function GetText { prompt String, initial String(''), title String('Input') } $[String] native('GetText')
  468. function GetInt { prompt String, initial Int(0), title String('Input') } $[Int] native('GetInt')
  469. function GetFloat { prompt String, initial Float(0), title String('Input') } $[Float] native('GetFloat')
  470. function GetFileListToOpen[T] { filter String } $[List[File]] native('GetFileListToOpen')
  471. function GetFileToOpen[T] { filter String } $[File] native('GetFileToOpen')
  472. function GetFileToSave[T] { filter String } $[File] native('GetFileToSave')
  473. type Action native
  474. function Action {
  475. icon Icon,
  476. text String,
  477. shortcut String (''),
  478. repeat Bool (No),
  479. enable $[Bool] ($())
  480. } Hook[Action]
  481. native ('Action')
  482. //
  483. method Action.Triggers $[Null] native('ActionTriggers')
  484. type ActionCheckBox record { Checked $[Bool] }
  485. function ActionCheckBox { action Action, checked Bool } Hook[ActionCheckBox] native('ActionCheckBox')
  486. type ActionComboBox[T] record { SelectedItem $[T] }
  487. function ActionComboBox[T] { items List[ActionComboBoxItem[T]] } Hook[ActionComboBox[T]] native('ActionComboBox')
  488. type ActionComboBoxItem[T] record { Action Action, Value T, Selected Bool }
  489. function ActionComboBoxItem[T] { action Action, value T, selected Bool } ActionComboBoxItem[T] { new ActionComboBoxItem(action, value, selected) }
  490. type MenuBar record { Menus List[Menu] }
  491. function variadic MenuBar { menus List[Menu] } MenuBar { new MenuBar(menus) }
  492. type ToolBar record { Mode ToolBarMode, Items List[ToolBarItem] }
  493. function variadic ToolBar { mode ToolBarMode(IconOnly), items List[ToolBarItem] } ToolBar { new ToolBar(mode, items) }
  494. type ToolBarMode enum { IconOnly, TextOnly, TextBesideIcon, TextUnderIcon }
  495. type Menu record { Icon Icon, Name String, Items List[MenuItem] }
  496. function variadic Menu { icon Icon, name String, items List[MenuItem] } Menu { new Menu(icon,name,items) }
  497. type MenuItem union { Menu, Action, Separator }
  498. type ToolBarItem union { Menu, Action, Separator, Widget, Spacer }
  499. type Separator record {}
  500. function Separator {} Separator { new Separator() }
  501. function <BindContextMenu> { w Widget, m Menu } $[Null] native('BindContextMenu')
  502. function ContextMenu { w Widget, m Menu } Hook[Null] { Effect(<BindContextMenu>(w,m)) }
  503. type Widget native
  504. type Widgets union { Widget, List[Widget] }
  505. function <ShowAndActivate> { w Widget } $[Null] native('ShowAndActivate')
  506. function <BindInlineStyleSheet> { w Widget, o $[String] } $[Null] native('BindInlineStyleSheet')
  507. function <ComboBoxSelectedItem>[T] { w Widget, items List[ComboBoxItem[T]] } $[T] native('ComboBoxSelectedItem')
  508. function <CreateDynamicWidget> { widgets $[Widget] } Hook[Widget] native('CreateDynamicWidget')
  509. function <CreateWidget> { l Layout, margin-x Int, margin-y Int, policy-x SizePolicy, policy-y SizePolicy } Hook[Widget] native('CreateWidget')
  510. function <CreateScrollArea> { scroll Scroll, l Layout, margin-x Int, margin-y Int } Hook[Widget] native('CreateScrollArea')
  511. function <CreateGroupBox> { title String, l Layout, margin-x Int, margin-y Int } Hook[Widget] native('CreateGroupBox')
  512. function <CreateSplitter> { l List[Widget] } Hook[Widget] native('CreateSplitter')
  513. function <CreateMainWindow> { menu-bar MenuBar, tool-bar ToolBar, l Layout, margin-x Int, margin-y Int, width Int, height Int, icon Icon } Hook[Widget] native('CreateMainWindow')
  514. function <CreateDialog> { l Layout, margin-x Int, margin-y Int, width Int, height Int, icon Icon } Hook[Widget] native('CreateDialog')
  515. function <CreateLabel> { align Align, selectable Bool } Hook[Widget] native('CreateLabel')
  516. function <CreateIconLabel> { icon Icon, size Int } Hook[Widget] native('CreateIconLabel')
  517. function <CreateElidedLabel> {} Hook[Widget] native('CreateElidedLabel')
  518. function <CreateTextView> { format TextFormat } Hook[Widget] native('CreateTextView')
  519. function <CreateCheckBox> { text String, checked Bool } Hook[Widget] native('CreateCheckBox')
  520. function <CreateComboBox>[T] { items List[ComboBoxItem[T]] } Hook[Widget] native('CreateComboBox')
  521. function <CreatePushButton> { icon Icon, text String, tooltip String } Hook[Widget] native('CreatePushButton')
  522. function <CreateLineEdit> { text String } Hook[Widget] native('CreateLineEdit')
  523. function <CreatePlainTextEdit> { text String } Hook[Widget] native('CreatePlainTextEdit')
  524. function <CreateSlider> { value Int, min Int, max Int } Hook[Widget] native('CreateSlider')
  525. function <CreateProgressBar> { max Int, format String } Hook[Widget] native('CreateProgressBar')
  526. type <Signal>[T] native
  527. type <Events>[T] native
  528. function <Connect>[T] { s <Signal>[T], w Widget } $[T] native('Connect')
  529. function <Listen>[T] { s <Events>[T], w Widget } $[T] native('Listen')
  530. const <<Toggled>> <Signal>[Null] native('SignalToggled')
  531. const <<Clicked>> <Signal>[Null] native('SignalClicked')
  532. const <<TextChanged0>> <Signal>[Null] native('SignalTextChanged0')
  533. const <<TextChanged1>> <Signal>[Null] native('SignalTextChanged1')
  534. const <<ReturnPressed>> <Signal>[Null] native('SignalReturnPressed')
  535. const <<ValueChanged>> <Signal>[Null] native('SignalValueChanged')
  536. const <<Show>> <Events>[Null] native('EventsShow')
  537. const <<Close>> <Events>[Null] native('EventsClose')
  538. type <Prop>[T] native
  539. function <Read>[T] { p <Prop>[T], s <Signal>[Null] } <Signal>[T] native('Read')
  540. function <Bind>[T] { p <Prop>[T], o $[T], w Widget } $[Null] native('Bind')
  541. function <ClearTextLater>[T] { w Widget, o $[T] } $[T] native('ClearTextLater')
  542. const <<Enabled>> <Prop>[Bool] native('PropEnabled')
  543. const <<WindowTitle>> <Prop>[String] native('PropWindowTitle')
  544. const <<Text>> <Prop>[String] native('PropText')
  545. const <<Checked>> <Prop>[Bool] native('PropChecked')
  546. const <<PlainText>> <Prop>[String] native('PropPlainText')
  547. const <<Value>> <Prop>[Int] native('PropValue')
  548. type Icon record { Name String }
  549. function Icon { name String('') } Icon { new Icon(name) }
  550. type SizePolicy enum { Rigid, Controlled, Incompressible, IncompressibleExpanding, Free, FreeExpanding, Bounded }
  551. type Align enum { Default, Center, Left, Right, Top, Bottom, LeftTop, LeftBottom, RightTop, RightBottom }
  552. type Scroll enum { BothDirection, VerticalOnly, HorizontalOnly }
  553. type TextFormat enum { Plain, Html, Markdown }
  554. type Layout union { Row, Column, Grid }
  555. type LayoutItem union { Layout, Widget, Spacer, String }
  556. type Row record { Items List[LayoutItem], Spacing Int(4) }
  557. type Column record { Items List[LayoutItem], Spacing Int(4) }
  558. type Grid record { Items List[Span], RowSpacing Int(4), ColumnSpacing Int(4) }
  559. type Span record { Item LayoutItem, Row Int, Column Int, RowSpan Int, ColumnSpan Int, Align Align }
  560. type Spacer record { Width Int, Height Int, Expand Bool }
  561. function variadic Row { items List[LayoutItem] } Layout { new Row(items) }
  562. function variadic Column { items List[LayoutItem] } Layout { new Column(items) }
  563. function variadic Grid { spans List[Span] } Layout { new Grid(spans) }
  564. function Span { item LayoutItem, row Int, column Int, align Align(Default), row-span Int(1), column-span Int(1) } Span { new Span(item,row,column,row-span,column-span,align) }
  565. function Spacer { width Int(0), height Int(0), expand Bool(Yes) } LayoutItem { new Spacer(width,height,expand) }
  566. function Aligned { align Align, item LayoutItem } Layout {
  567. Grid(Span(item, 0, 0, align))
  568. }
  569. function variadic Form { pairs List[Pair[LayoutItem,LayoutItem]] } Layout {
  570. Grid { spans: {
  571. @map* (pair, row) = { pairs | with-index() },
  572. let (left, right) = pair,
  573. List(Span(left, row, 0, Right), Span(right, row, 1))
  574. }}
  575. }
  576. type Wrapper record { Widget Widget }
  577. function Wrapper { layout Layout, policy-x SizePolicy(Free), policy-y SizePolicy(Free) } Hook[Wrapper] {
  578. WrapperWithMargins(layout, 0, 0, policy-x, policy-y)
  579. }
  580. function WrapperWithMargins { layout Layout, margin-x Int(6), margin-y Int(4), policy-x SizePolicy(Free), policy-y SizePolicy(Free) } Hook[Wrapper] {
  581. @use widget = <CreateWidget>(layout, margin-x, margin-y, policy-x, policy-y),
  582. Hook(new Wrapper(widget))
  583. }
  584. type ScrollArea record { Widget Widget }
  585. function ScrollArea { scroll Scroll, layout Layout } Hook[ScrollArea] {
  586. ScrollAreaWithMargins(scroll, layout, 0, 0)
  587. }
  588. function ScrollAreaWithMargins { scroll Scroll, layout Layout, margin-x Int(6), margin-y Int(4) } Hook[ScrollArea] {
  589. @use widget = <CreateScrollArea>(scroll, layout, margin-x, margin-y),
  590. Hook(new ScrollArea(widget))
  591. }
  592. type GroupBox record { Widget Widget }
  593. function GroupBox { title String, layout Layout, margin-x Int(0), margin-y Int(0) } Hook[GroupBox] {
  594. @use widget = <CreateGroupBox>(title, layout, margin-x, margin-y),
  595. Hook(new GroupBox(widget))
  596. }
  597. type Splitter record { Widget Widget }
  598. function variadic Splitter { content List[Widget] } Hook[Splitter] {
  599. @use widget = <CreateSplitter>(content),
  600. Hook(new Splitter(widget))
  601. }
  602. type Window record { Widget Widget, <Exit> $[Null] }
  603. function Window { title $[String], layout Layout, menu-bar MenuBar(MenuBar()), tool-bar ToolBar(ToolBar()), exit Lambda[$[Null],$[Null]] ({ closes => closes }), margin-x Int(6), margin-y Int(6), width Int(-1), height Int(-1), icon Icon(Icon('window')) } Hook[Window] {
  604. @use widget = <CreateMainWindow>(menu-bar, tool-bar, layout, margin-x, margin-y, width, height, icon),
  605. @use Effect(<Bind>(<<WindowTitle>>, title, widget)),
  606. let close = <Listen>(<<Close>>, widget),
  607. Hook(new Window(widget, exit(close)))
  608. }
  609. type Dialog[T] record { Widget Widget, <Exit> $[T] }
  610. function Dialog[T] { title $[String], layout Layout, exit Lambda[$[Null],$[T]], margin-x Int(6), margin-y Int(6), width Int(-1), height Int(-1), icon Icon(Icon('window')) } Hook[Dialog[T]] {
  611. @use widget = <CreateDialog>(layout, margin-x, margin-y, width, height, icon),
  612. @use Effect(<Bind>(<<WindowTitle>>, title, widget)),
  613. let close = <Listen>(<<Close>>, widget),
  614. Hook(new Dialog(widget, exit(close)))
  615. }
  616. type Switchable record { Widget Widget }
  617. function Switchable { widgets $[Widget] } Hook[Switchable] {
  618. @use widget = <CreateDynamicWidget>(widgets),
  619. Hook(new Switchable(widget))
  620. }
  621. type Reloadable record { Widget Widget }
  622. function Reloadable { hooks $[Hook[Widget]] } Hook[Reloadable] {
  623. @use widget = <CreateDynamicWidget>((hooks run { w => $(w) })),
  624. Hook(new Reloadable(widget))
  625. }
  626. function LazyReloadable { hooks $[Hook[Widget]] } Hook[Reloadable] {
  627. @use bus = Subject[Hook[Widget]] {},
  628. @use r = Reloadable(bus.Values),
  629. @use Effect({
  630. @await { <Listen>(<<Show>>, r.Widget) | take(1) },
  631. (bus plug hooks)
  632. }),
  633. Hook(r)
  634. }
  635. type Label record { Widget Widget }
  636. function Label { text $[String], align Align(Left), selectable Bool(No) } Hook[Label] {
  637. @use widget = <CreateLabel>(align, selectable),
  638. @use Effect(<Bind>(<<Text>>, text, widget)),
  639. Hook(new Label(widget))
  640. }
  641. type ElidedLabel record { Widget Widget }
  642. function ElidedLabel { text $[String] } Hook[ElidedLabel] {
  643. @use widget = <CreateElidedLabel>(),
  644. @use Effect(<Bind>(<<Text>>, text, widget)),
  645. Hook(new ElidedLabel(widget))
  646. }
  647. type IconLabel record { Widget Widget }
  648. function IconLabel { icon Icon, size IconSize(Auto) } Hook[IconLabel] {
  649. @use widget = <CreateIconLabel>(icon, ([Int])size),
  650. Hook(new IconLabel(widget))
  651. }
  652. type IconSize enum { Auto, Small, Medium, Large }
  653. type TextView record { Widget Widget }
  654. function TextView { text $[String], format TextFormat(Plain) } Hook[TextView] {
  655. @use widget = <CreateTextView>(format),
  656. @use Effect(<Bind>(<<Text>>, text, widget)),
  657. Hook(new TextView(widget))
  658. }
  659. type CheckBox record { Widget Widget }
  660. function CheckBox { text String, checked Bool } Hook[CheckBox] {
  661. @use widget = <CreateCheckBox>(text, checked),
  662. Hook(new CheckBox(widget))
  663. }
  664. method CheckBox.Checked $[Bool] { <Connect>(<Read>(<<Checked>>, <<Toggled>>), this.Widget) }
  665. type ComboBox[T] record { Widget Widget, SelectedItem $[T] }
  666. function ComboBox[T] { items List[ComboBoxItem[T]] } Hook[ComboBox[T]] {
  667. @use widget = <CreateComboBox>(items),
  668. let selected = <ComboBoxSelectedItem>(widget, items),
  669. Hook(new ComboBox(widget, selected))
  670. }
  671. type ComboBoxItem[T] record { Icon Icon, Name String, Value T, Selected Bool }
  672. function ComboBoxItem[T] { icon Icon, name String, value T, selected Bool } ComboBoxItem[T] {
  673. new ComboBoxItem(icon, name, value, selected)
  674. }
  675. type Button record { Widget Widget }
  676. function Button { icon Icon, text String, tooltip String(''), enable $[Bool]($()) } Hook[Button] {
  677. @use widget = <CreatePushButton>(icon, text, tooltip),
  678. @use Effect(<Bind>(<<Enabled>>, enable, widget)),
  679. Hook(new Button(widget))
  680. }
  681. function PlainButton { text String, enable $[Bool]($()) } Hook[Button] {
  682. Button(Icon(), text, '', enable)
  683. }
  684. function IconButton { icon Icon, tooltip String, enable $[Bool]($()) } Hook[Button] {
  685. Button(icon, '', tooltip, enable)
  686. }
  687. method Button.Clicks $[Null] { <Connect>(<<Clicked>>, this.Widget) }
  688. type TextBox record { Widget Widget }
  689. function TextBox { text String('') } Hook[TextBox] {
  690. @use widget = <CreateLineEdit>(text),
  691. Hook(new TextBox(widget))
  692. }
  693. method TextBox.Text $[String] { <Connect>(<Read>(<<Text>>, <<TextChanged1>>), this.Widget) }
  694. method TextBox.Enters $[Null] { <Connect>(<<ReturnPressed>>, this.Widget) }
  695. method TextBox.TextOn Lambda[$[Null],$[String]] {{ triggers => <ClearTextLater>(this.Widget, (triggers map-to-latest-from this.Text)) }}
  696. method TextBox.TextOnEnters $[String] { this.TextOn(this.Enters) }
  697. operator bind-override { edit TextBox, text $[String] } $[Null] { <Bind>(<<Text>>, text, edit.Widget) }
  698. type TextArea record { Widget Widget }
  699. function TextArea { text String('') } Hook[TextArea] {
  700. @use widget = <CreatePlainTextEdit>(text),
  701. Hook(new TextArea(widget))
  702. }
  703. method TextArea.Text $[String] { <Connect>(<Read>(<<PlainText>>, <<TextChanged0>>), this.Widget) }
  704. type Slider record { Widget Widget }
  705. function Slider { value Int, min Int, max Int } Hook[Slider] {
  706. @use widget = <CreateSlider>(value, min, max),
  707. Hook(new Slider(widget))
  708. }
  709. method Slider.Value $[Int] { <Connect>(<Read>(<<Value>>, <<ValueChanged>>), this.Widget) }
  710. type ProgressBar record { Widget Widget }
  711. function ProgressBar { value $[Int], max Int, format String('') } Hook[ProgressBar] {
  712. @use widget = <CreateProgressBar>(max, format),
  713. @use Effect(<Bind>(<<Value>>, value, widget)),
  714. Hook(new ProgressBar(widget))
  715. }
  716. type ListView[T] record {
  717. Widget Widget,
  718. Extension $[Maybe[Widget]],
  719. Current $[Maybe[String]],
  720. Selection $[List[String]]
  721. }
  722. function ListView[T] {
  723. data $[List[T]],
  724. key Lambda[T, String],
  725. content Lambda[Pair[$[T],ItemInfo], Hook[ItemView]],
  726. headers List[HeaderView] (List()),
  727. stretch Int (-1),
  728. select ItemSelect (Single)
  729. } Hook[ListView[T]]
  730. native ('ListView')
  731. //
  732. type ItemView record {
  733. <Widgets> Widgets,
  734. <Extension> Maybe[Widget]
  735. }
  736. function ItemView { widgets Widgets, extension Maybe[Widget] (Null) } Hook[ItemView] {
  737. Hook(new ItemView(widgets,extension))
  738. }
  739. type ListEditView[T] record {
  740. Widget Widget,
  741. Output $[List[T]],
  742. Extension $[Maybe[Widget]],
  743. <EditOps> Subject[<ListEditOperation>[T]]
  744. }
  745. function ListEditView[T] {
  746. initial List[T],
  747. content Lambda[Pair[T,ItemInfo], Hook[ItemEditView[T]]],
  748. headers List[HeaderView] (List()),
  749. stretch Int (-1),
  750. select ItemSelect (Single)
  751. } Hook[ListEditView[T]]
  752. native ('ListEditView')
  753. //
  754. operator bind-update[T] {
  755. list ListEditView[T],
  756. prepend $[T] ($()),
  757. append $[T] ($()),
  758. delete $[Null] ($()),
  759. move-up $[Null] ($()),
  760. move-down $[Null] ($()),
  761. move-top $[Null] ($()),
  762. move-bottom $[Null] ($()),
  763. reorder $[Lambda[List[T],List[T]]] ($())
  764. } $[Null]
  765. {
  766. (list.<EditOps> plug Merge(
  767. (prepend map { value => new <Prepend>(value) }),
  768. (append map { value => new <Append>(value) }),
  769. (delete map { => new <Delete>() }),
  770. (move-up map { => new <MoveUp>() }),
  771. (move-down map { => new <MoveDown>() }),
  772. (move-top map { => new <MoveTop>() }),
  773. (move-bottom map { => new <MoveBottom>() }),
  774. (reorder map { reorder => new <Reorder>(reorder) })
  775. ))}
  776. //
  777. type ItemEditView[T] record {
  778. <Widgets> Widgets,
  779. <Extension> Maybe[Widget],
  780. <EditOps> Lambda[String,$[<ListEditOperation>[T]]]
  781. }
  782. function ItemEditView[T] {
  783. widgets Widgets,
  784. extension Maybe[Widget] (Null),
  785. update $[T] ($()),
  786. delete $[Null] ($()),
  787. move-up $[Null] ($()),
  788. move-down $[Null] ($()),
  789. move-top $[Null] ($()),
  790. move-bottom $[Null] ($()),
  791. insert-above $[T] ($()),
  792. insert-below $[T] ($())
  793. } Hook[ItemEditView[T]]
  794. {
  795. Hook(new ItemEditView {
  796. <Widgets>: widgets,
  797. <Extension>: extension,
  798. <EditOps>: { key => Merge(
  799. (update map { value => new <Update>(key,value) }),
  800. (delete map { => new <Delete>(key) }),
  801. (move-up map { => new <MoveUp>(key) }),
  802. (move-down map { => new <MoveDown>(key) }),
  803. (move-top map { => new <MoveTop>(key) }),
  804. (move-bottom map { => new <MoveBottom>(key) }),
  805. (insert-above map { value => new <InsertAbove>(key,value) }),
  806. (insert-below map { value => new <InsertBelow>(key,value) })
  807. )}
  808. })}
  809. //
  810. type <ListEditOperation>[T] union {
  811. <Prepend>[T], <Append>[T],
  812. <Update>[T], <Delete>,
  813. <MoveUp>, <MoveDown>,
  814. <MoveTop>, <MoveBottom>,
  815. <InsertAbove>[T], <InsertBelow>[T],
  816. <Reorder>[T]
  817. }
  818. type <Prepend>[T] record { Value T }
  819. type <Append>[T] record { Value T }
  820. type <Update>[T] record { Key String, Value T }
  821. type <Delete> record { Key Maybe[String](Null) }
  822. type <MoveUp> record { Key Maybe[String](Null) }
  823. type <MoveDown> record { Key Maybe[String](Null) }
  824. type <MoveTop> record { Key Maybe[String](Null) }
  825. type <MoveBottom> record { Key Maybe[String](Null) }
  826. type <InsertAbove>[T] record { PivotKey String, Value T }
  827. type <InsertBelow>[T] record { PivotKey String, Value T }
  828. type <Reorder>[T] record { Reorder Lambda[List[T],List[T]] }
  829. type HeaderView union { String, Widget }
  830. type ItemSelect enum { N/A, Single, Multiple, MaybeMultiple }
  831. type ItemInfo record { Key String, Pos $[ItemPos] }
  832. type ItemPos record { Index Int, Total Int }
  833. method ItemInfo.IsFirst $[Bool] { (this.Pos map { (i,_) => (i == 0) }) }
  834. method ItemInfo.IsLast $[Bool] { (this.Pos map { (i,n) => ((i + 1) == n) }) }
  835. type Editor[T] record {
  836. Widget Widget,
  837. <Output> Subject[T],
  838. <Override> Subject[T],
  839. <LastSave> Subject[T],
  840. <File> Subject[Maybe[File]],
  841. <Open> EditorOpenBehavior[T],
  842. <Save> EditorSaveBehavior[T]
  843. }
  844. function Editor[T] {
  845. initial EditorDocument[T],
  846. content Lambda[T,Hook[EditorView[T]]],
  847. open EditorOpenBehavior[T] ({ _ => $() }),
  848. save EditorSaveBehavior[T] ({ doc => $(doc.File?) })
  849. } Hook[Editor[T]]
  850. {
  851. let (file?,initial) = initial,
  852. @use last-save = Subject(1, initial),
  853. @use output = Subject(1, initial),
  854. @use override = Subject[T](),
  855. @use Effect((output plug override.$)),
  856. @use r = Reloadable({
  857. @map value = (override.$ start-with initial),
  858. @use (widget, new-values) = content(value),
  859. @use Effect((output plug SkipSync(new-values))),
  860. Hook(widget)
  861. }),
  862. @use file = Subject(1, file?),
  863. Hook(new Editor(r.Widget, output, override, last-save, file, open, save)) }
  864. //
  865. method Editor.Document $[EditorDocument[T]] {
  866. new:$ EditorDocument(this.File, this.Output)
  867. }
  868. method Editor.File $[Maybe[File]] {
  869. this.<File>.$
  870. }
  871. method Editor.Output $[T] {
  872. this.<Output>.$
  873. }
  874. method Editor.LastSave $[T] {
  875. this.<LastSave>.$
  876. }
  877. method Editor.Modified $[Bool] {
  878. <ObjectPairEqualities>((this.LastSave combine-latest this.Output))
  879. | map(Not)
  880. }
  881. function EditorDirty[T] { e Editor[T] } { T/== ==[T] } $[Bool] {
  882. (e.LastSave combine-latest e.Output)
  883. | map(T/==.Operator)
  884. | distinct-until-changed()
  885. | map(Not)
  886. }
  887. operator bind-override[T] { e Editor[T], values $[T] } $[Null] {
  888. (e.<Override> plug values)
  889. }
  890. operator bind-reset[T] { e Editor[T], triggers $[Null] } $[Null] {
  891. (e bind-override (triggers map-to-latest-from e.LastSave))
  892. }
  893. operator bind-open[T] { e Editor[T], triggers $[Null] } $[Null] {
  894. @concat-map (_, modified) = (triggers with-latest-from e.Modified),
  895. @await new-doc = { e.<Open>(modified) | log-error() },
  896. @await (e.<File> <- new-doc.File?),
  897. @await (e.<LastSave> <- new-doc.Data),
  898. @await (e.<Override> <- new-doc.Data),
  899. return (Null)
  900. }
  901. operator bind-save[T] { e Editor[T], triggers $[Null] } $[Null] {
  902. @concat-map (_, doc) = (triggers with-latest-from e.Document),
  903. @await new-file = { e.<Save>(doc) | log-error() },
  904. @await (e.<File> <- new-file),
  905. @await (e.<LastSave> <- doc.Data),
  906. return (Null)
  907. }
  908. operator bind-save-as[T] { e Editor[T], triggers $[Null] } $[Null] {
  909. let doc = (e.Document map { doc => doc.(File?).Assign(Null) }),
  910. @concat-map (_, doc) = (triggers with-latest-from doc),
  911. @await new-file = { e.<Save>(doc) | log-error() },
  912. @await (e.<File> <- new-file),
  913. @await (e.<LastSave> <- doc.Data),
  914. return (Null)
  915. }
  916. method Editor.Open $[Null] {
  917. this | bind-open($(Null))
  918. }
  919. method Editor.Save $[Null] {
  920. this | bind-save($(Null))
  921. }
  922. method Editor.SaveAs $[Null] {
  923. this | bind-save-as($(Null))
  924. }
  925. type EditorOpenBehavior[T] interface {
  926. Open Lambda[Bool,$[EditorDocument[T]]]
  927. }
  928. type EditorSaveBehavior[T] interface {
  929. Save Lambda[EditorDocument[T],$[Maybe[File]]]
  930. }
  931. type EditorDocument[T] record {
  932. File? Maybe[File],
  933. Data T
  934. }
  935. function EditorDocument[T] { file? Maybe[File], data T } EditorDocument[T] {
  936. new EditorDocument(file?, data)
  937. }
  938. type EditorView[T] record {
  939. Widget Widget,
  940. NewValues $[T]
  941. }
  942. function EditorView[T] { w Widget, new-values $[T] } Hook[EditorView[T]] {
  943. Hook(new EditorView(w, new-values))
  944. }
  945. type Hook[T] record { <Job> $[T] }
  946. function Hook[T] { value T } Hook[T] { new Hook($(value)) }
  947. operator use[A,B] { h Hook[A], f Lambda[A,Hook[B]] } Hook[B] {
  948. new Hook((h.<Job> await-noexcept { a => f(a).<Job> }))
  949. }
  950. operator run[T,X] { h Hook[T], f Lambda[T,$[X]] } $[X] {
  951. WithChildContext((h.<Job> await-noexcept f))
  952. }
  953. operator run[T,X] { o $[Hook[T]], f Lambda[T,$[X]] } $[X] {
  954. (o switch-map { h => (h.<Job> await-noexcept f) })
  955. }
  956. function Hooks[T] { l List[Hook[T]] } Hook[List[T]] {
  957. l | reverse() | fold(Hook(List()), { (r,i) => {
  958. @use head = i,
  959. @use tail = r,
  960. Hook(Cons(head, tail))
  961. }})
  962. }
  963. function Effect { effect $[Null] } Hook[Null] {
  964. new Hook(($(Null) with effect))
  965. }
  966. function State[T] { initial T } Hook[State[T]] {
  967. new Hook(CreateState(initial))
  968. }
  969. function Memo[T] { o $[T] } Hook[$[T]] {
  970. new Hook(MakeMemo(o))
  971. }
  972. function variadic Subject[T] { replay Int(0), items List[T] } Hook[Subject[T]] {
  973. new Hook(CreateSubject[T] { replay, items })
  974. }
  975. function Multicasting[T] { o $[T] } Hook[$[T]] {
  976. new Hook(Multicast(o))
  977. }
  978. function Style { w Widget, o $[String] } Hook[Null] {
  979. Effect(<BindInlineStyleSheet>(w, o))
  980. }
  981. function ShowWindow { h Hook[Window] } $[Null] {
  982. @run window = h,
  983. let watch-exit = window.<Exit>,
  984. let show = <ShowAndActivate>(window.Widget),
  985. { watch-exit | take(1) | and(show) }
  986. }
  987. function ShowDialog[T] { h Hook[Dialog[T]] } $[T] {
  988. @run dialog = h,
  989. let watch-exit = dialog.<Exit>,
  990. let show = <ShowAndActivate>(dialog.Widget),
  991. { watch-exit | take(1) | and(show) }
  992. }