ballerina-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/main.ts +149 -0
  2. package/package.json +20 -0
  3. package/src/apiResultStatus/state.ts +7 -0
  4. package/src/async/domains/mirroring/domains/collection/coroutines/synchronizers.ts +334 -0
  5. package/src/async/domains/mirroring/domains/collection/state.ts +137 -0
  6. package/src/async/domains/mirroring/domains/entity/domains/loaded-collection/state.ts +24 -0
  7. package/src/async/domains/mirroring/domains/entity/domains/loaded-collection-entity/state.ts +27 -0
  8. package/src/async/domains/mirroring/domains/entity/domains/loaded-entities/state.ts +12 -0
  9. package/src/async/domains/mirroring/domains/entity/domains/loaded-entity/state.ts +29 -0
  10. package/src/async/domains/mirroring/domains/entity/state.ts +22 -0
  11. package/src/async/domains/mirroring/domains/singleton/coroutines/synchronizers.ts +216 -0
  12. package/src/async/domains/mirroring/domains/singleton/state.ts +57 -0
  13. package/src/async/domains/mirroring/domains/synchronization-result/state.ts +2 -0
  14. package/src/async/domains/mirroring/domains/synchronized-entities/state.ts +23 -0
  15. package/src/async/domains/promise/state.ts +13 -0
  16. package/src/async/domains/synchronized/coroutines/synchronize.ts +62 -0
  17. package/src/async/domains/synchronized/state.ts +20 -0
  18. package/src/async/state.ts +144 -0
  19. package/src/baseEntity/domains/identifiable/state.ts +29 -0
  20. package/src/collections/domains/array/state.ts +16 -0
  21. package/src/collections/domains/immutable/domains/list/state.ts +20 -0
  22. package/src/collections/domains/immutable/domains/map/state.ts +33 -0
  23. package/src/collections/domains/immutable/domains/orderedMap/state.ts +117 -0
  24. package/src/collections/domains/immutable/domains/ordereredSet/state.ts +19 -0
  25. package/src/collections/domains/immutable/domains/set/state.ts +15 -0
  26. package/src/collections/domains/maybe/state.ts +20 -0
  27. package/src/collections/domains/product/state.ts +47 -0
  28. package/src/collections/domains/sum/state.ts +82 -0
  29. package/src/coroutines/builder.tsx +66 -0
  30. package/src/coroutines/state.ts +574 -0
  31. package/src/coroutines/template.tsx +119 -0
  32. package/src/debounced/coroutines/debounce.ts +118 -0
  33. package/src/debounced/state.ts +61 -0
  34. package/src/diagnostics/domains/message-box/state.ts +4 -0
  35. package/src/foreignMutations/state.ts +4 -0
  36. package/src/forms/domains/attachments/views/attachments-view.tsx +22 -0
  37. package/src/forms/domains/collection/domains/reference/state.ts +18 -0
  38. package/src/forms/domains/collection/domains/selection/state.ts +5 -0
  39. package/src/forms/domains/launcher/domains/create/coroutines/runner.ts +60 -0
  40. package/src/forms/domains/launcher/domains/create/state.ts +71 -0
  41. package/src/forms/domains/launcher/domains/create/template.tsx +66 -0
  42. package/src/forms/domains/launcher/domains/edit/coroutines/runner.ts +47 -0
  43. package/src/forms/domains/launcher/domains/edit/state.ts +55 -0
  44. package/src/forms/domains/launcher/domains/edit/template.tsx +39 -0
  45. package/src/forms/domains/parser/domains/validator/state.ts +423 -0
  46. package/src/forms/domains/parser/state.tsx +311 -0
  47. package/src/forms/domains/primitives/domains/boolean/state.ts +13 -0
  48. package/src/forms/domains/primitives/domains/boolean/template.tsx +24 -0
  49. package/src/forms/domains/primitives/domains/date/state.ts +23 -0
  50. package/src/forms/domains/primitives/domains/date/template.tsx +31 -0
  51. package/src/forms/domains/primitives/domains/enum/state.ts +27 -0
  52. package/src/forms/domains/primitives/domains/enum/template.tsx +52 -0
  53. package/src/forms/domains/primitives/domains/enum-multiselect/state.ts +18 -0
  54. package/src/forms/domains/primitives/domains/enum-multiselect/template.tsx +56 -0
  55. package/src/forms/domains/primitives/domains/number/state.ts +8 -0
  56. package/src/forms/domains/primitives/domains/number/template.tsx +26 -0
  57. package/src/forms/domains/primitives/domains/searchable-infinite-stream/state.ts +55 -0
  58. package/src/forms/domains/primitives/domains/searchable-infinite-stream/template.tsx +114 -0
  59. package/src/forms/domains/primitives/domains/searchable-infinite-stream-multiselect/state.ts +27 -0
  60. package/src/forms/domains/primitives/domains/searchable-infinite-stream-multiselect/template.tsx +119 -0
  61. package/src/forms/domains/primitives/domains/string/state.ts +12 -0
  62. package/src/forms/domains/primitives/domains/string/template.tsx +24 -0
  63. package/src/forms/domains/singleton/domains/descriptors/entity/state.ts +9 -0
  64. package/src/forms/domains/singleton/domains/descriptors/field/domains/base/state.ts +5 -0
  65. package/src/forms/domains/singleton/domains/descriptors/field/domains/boolean/state.ts +6 -0
  66. package/src/forms/domains/singleton/domains/descriptors/field/domains/custom/state.ts +21 -0
  67. package/src/forms/domains/singleton/domains/descriptors/field/domains/date/state.ts +6 -0
  68. package/src/forms/domains/singleton/domains/descriptors/field/domains/enum/state.ts +7 -0
  69. package/src/forms/domains/singleton/domains/descriptors/field/domains/infinite-enum/state.ts +8 -0
  70. package/src/forms/domains/singleton/domains/descriptors/field/domains/number/state.ts +7 -0
  71. package/src/forms/domains/singleton/domains/descriptors/field/domains/string/state.ts +7 -0
  72. package/src/forms/domains/singleton/domains/descriptors/field/state.ts +16 -0
  73. package/src/forms/domains/singleton/domains/descriptors/form/state.ts +13 -0
  74. package/src/forms/domains/singleton/domains/form-label/state.ts +2 -0
  75. package/src/forms/domains/singleton/state.ts +87 -0
  76. package/src/forms/domains/singleton/template.tsx +92 -0
  77. package/src/forms/domains/singleton/views/field-views.ts +23 -0
  78. package/src/forms/domains/singleton/views/simple-inputs/base.ts +5 -0
  79. package/src/forms/domains/singleton/views/simple-inputs/boolean.tsx +4 -0
  80. package/src/forms/domains/singleton/views/simple-inputs/date.tsx +4 -0
  81. package/src/forms/domains/singleton/views/simple-inputs/number.tsx +4 -0
  82. package/src/forms/domains/singleton/views/simple-inputs/string.tsx +4 -0
  83. package/src/fun/domains/curry/state.ts +6 -0
  84. package/src/fun/domains/id/state.ts +2 -0
  85. package/src/fun/domains/predicate/domains/bool-expr.ts +98 -0
  86. package/src/fun/domains/predicate/state.ts +29 -0
  87. package/src/fun/domains/simpleCallback/state.ts +3 -0
  88. package/src/fun/domains/uncurry/state.ts +5 -0
  89. package/src/fun/domains/unit/state.ts +3 -0
  90. package/src/fun/domains/updater/domains/caseUpdater/state.ts +44 -0
  91. package/src/fun/domains/updater/domains/mapUpdater/state.ts +36 -0
  92. package/src/fun/domains/updater/domains/maybeUpdater/state.ts +45 -0
  93. package/src/fun/domains/updater/domains/orderedMapUpdater/state.ts +26 -0
  94. package/src/fun/domains/updater/domains/orderedSetUpdater/state.ts +23 -0
  95. package/src/fun/domains/updater/domains/replaceWith/state.ts +3 -0
  96. package/src/fun/domains/updater/domains/simpleUpdater/domains/baseSimpleUpdater/state.ts +18 -0
  97. package/src/fun/domains/updater/domains/simpleUpdater/state.ts +72 -0
  98. package/src/fun/domains/updater/state.ts +86 -0
  99. package/src/fun/state.ts +33 -0
  100. package/src/infinite-data-stream/coroutines/builder.ts +8 -0
  101. package/src/infinite-data-stream/coroutines/infiniteLoader.ts +51 -0
  102. package/src/infinite-data-stream/coroutines/runner.ts +12 -0
  103. package/src/infinite-data-stream/state.ts +175 -0
  104. package/src/infinite-data-stream/template.tsx +16 -0
  105. package/src/math/domains/DOMRect/state.ts +12 -0
  106. package/src/math/domains/number/state.ts +9 -0
  107. package/src/math/domains/rect/state.ts +22 -0
  108. package/src/math/domains/rgba/state.ts +87 -0
  109. package/src/math/domains/size2/state.ts +14 -0
  110. package/src/math/domains/vector2/state.ts +16 -0
  111. package/src/queue/state.ts +42 -0
  112. package/src/state/domains/repository/state.ts +14 -0
  113. package/src/template/state.tsx +198 -0
  114. package/src/validation/state.ts +2 -0
  115. package/src/value/domains/mutable-value/state.ts +13 -0
  116. package/src/value/state.ts +12 -0
  117. package/src/visibility/state.ts +3 -0
  118. package/tsconfig.json +22 -0
@@ -0,0 +1,55 @@
1
+ import { simpleUpdater, BasicUpdater, Updater, SimpleCallback } from "../../../../../../main";
2
+ import { Debounced } from "../../../../../debounced/state";
3
+ import { BasicFun } from "../../../../../fun/state";
4
+ import { InfiniteStreamState } from "../../../../../infinite-data-stream/state";
5
+ import { View } from "../../../../../template/state";
6
+ import { Value } from "../../../../../value/state";
7
+ import { CollectionReference } from "../../../collection/domains/reference/state";
8
+ import { CollectionSelection } from "../../../collection/domains/selection/state";
9
+ import { FormLabel } from "../../../singleton/domains/form-label/state";
10
+ import { OnChange, SharedFormState } from "../../../singleton/state";
11
+
12
+
13
+ export type SearchableInfiniteStreamState<Element extends CollectionReference> =
14
+ SharedFormState &
15
+ { searchText: Debounced<Value<string>>; status: "open" | "closed"; stream: InfiniteStreamState<Element>; getChunk: BasicFun<string, InfiniteStreamState<Element>["getChunk"]>; };
16
+ export const SearchableInfiniteStreamState = <Element extends CollectionReference>() => ({
17
+ Default: (searchText: string, getChunk: BasicFun<string, InfiniteStreamState<Element>["getChunk"]>): SearchableInfiniteStreamState<Element> => ({
18
+ ...SharedFormState.Default(),
19
+ searchText: Debounced.Default(Value.Default(searchText)),
20
+ status: "closed",
21
+ getChunk,
22
+ stream: InfiniteStreamState<Element>().Default(10, getChunk(searchText))
23
+ }),
24
+ Updaters: {
25
+ Core: {
26
+ ...simpleUpdater<SearchableInfiniteStreamState<Element>>()("status"),
27
+ ...simpleUpdater<SearchableInfiniteStreamState<Element>>()("stream"),
28
+ ...simpleUpdater<SearchableInfiniteStreamState<Element>>()("searchText"),
29
+ },
30
+ Template: {
31
+ searchText: (_: BasicUpdater<string>): Updater<SearchableInfiniteStreamState<Element>> => SearchableInfiniteStreamState<Element>().Updaters.Core.searchText(
32
+ Debounced.Updaters.Template.value(
33
+ Value.Updaters.value(
34
+ _
35
+ )
36
+ )
37
+ )
38
+ }
39
+ }
40
+ });
41
+ export type SearchableInfiniteStreamView<Element extends CollectionReference, Context extends FormLabel, ForeignMutationsExpected> =
42
+ View<
43
+ Context & Value<CollectionSelection<Element>> & SearchableInfiniteStreamState<Element> & {
44
+ hasMoreValues:boolean
45
+ },
46
+ SearchableInfiniteStreamState<Element>,
47
+ ForeignMutationsExpected & {
48
+ onChange: OnChange<CollectionSelection<Element>>;
49
+ toggleOpen:SimpleCallback<void>
50
+ clearSelection:SimpleCallback<void>
51
+ setSearchText:SimpleCallback<string>
52
+ select:SimpleCallback<Element>
53
+ loadMore:SimpleCallback<void>
54
+ reload:SimpleCallback<void>
55
+ }>;
@@ -0,0 +1,114 @@
1
+ import { List } from "immutable";
2
+ import { SimpleCallback, Debounce, InfiniteStreamLoader, id, replaceWith, BasicFun, Synchronize, Unit, ValidateRunner } from "../../../../../../main";
3
+ import { CoTypedFactory } from "../../../../../coroutines/builder";
4
+ import { Debounced } from "../../../../../debounced/state";
5
+ import { InfiniteStreamState } from "../../../../../infinite-data-stream/state";
6
+ import { Template } from "../../../../../template/state";
7
+ import { Value } from "../../../../../value/state";
8
+ import { CollectionReference } from "../../../collection/domains/reference/state";
9
+ import { CollectionSelection } from "../../../collection/domains/selection/state";
10
+ import { FormLabel } from "../../../singleton/domains/form-label/state";
11
+ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, OnChange, ValidationError } from "../../../singleton/state";
12
+ import { SearchableInfiniteStreamState, SearchableInfiniteStreamView } from "./state";
13
+
14
+
15
+ export const SearchableInfiniteStreamForm = <Element extends CollectionReference, Context extends FormLabel, ForeignMutationsExpected>(
16
+ validation:BasicFun<CollectionSelection<Element>, Promise<FieldValidation>>
17
+ ) => {
18
+ const Co = CoTypedFactory<Context & Value<CollectionSelection<Element>>, SearchableInfiniteStreamState<Element>>();
19
+ const DebouncerCo = CoTypedFactory<Context & { onDebounce: SimpleCallback<void>; } & Value<CollectionSelection<Element>>, SearchableInfiniteStreamState<Element>>();
20
+ const DebouncedCo = CoTypedFactory<{ onDebounce: SimpleCallback<void>; }, Value<string>>();
21
+ const debouncer = DebouncerCo.Repeat(
22
+ DebouncerCo.Seq([
23
+ Debounce<Value<string>, { onDebounce: SimpleCallback<void>; }>(
24
+ DebouncedCo.GetState().then(current => DebouncedCo.Do(() => current.onDebounce()))
25
+ //.SetState(SearchNow.Updaters.reloadsRequested(_ => _ + 1))
26
+ .then(_ => DebouncedCo.Return("success")),
27
+ 250
28
+ ).embed(_ => ({ ..._, ..._.searchText }), SearchableInfiniteStreamState<Element>().Updaters.Core.searchText),
29
+ DebouncerCo.Wait(0)
30
+ ])
31
+ );
32
+ const debouncerRunner = DebouncerCo.Template<ForeignMutationsExpected & { onChange: OnChange<CollectionSelection<Element>>; }>(
33
+ debouncer,
34
+ {
35
+ interval: 15,
36
+ runFilter: props => Debounced.Operations.shouldCoroutineRun(props.context.searchText)
37
+ }
38
+ );
39
+ const loaderRunner = Co.Template<ForeignMutationsExpected & { onChange: OnChange<CollectionSelection<Element>>; }>(
40
+ InfiniteStreamLoader<Element>().embed(_ => _.stream, SearchableInfiniteStreamState<Element>().Updaters.Core.stream),
41
+ {
42
+ interval: 15,
43
+ runFilter: props => InfiniteStreamState().Operations.shouldCoroutineRun(props.context.stream)
44
+ }
45
+ );
46
+
47
+ return Template.Default<Context & Value<CollectionSelection<Element>>, SearchableInfiniteStreamState<Element>, ForeignMutationsExpected & { onChange: OnChange<CollectionSelection<Element>>; },
48
+ SearchableInfiniteStreamView<Element, Context, ForeignMutationsExpected>>(props => <>
49
+ <props.view {...props}
50
+ context={{
51
+ ...props.context,
52
+ hasMoreValues: !(props.context.stream.loadedElements.last()?.hasMoreValues == false),
53
+ }}
54
+ foreignMutations={{
55
+ ...props.foreignMutations,
56
+ toggleOpen: () => props.setState(
57
+ SearchableInfiniteStreamState<Element>().Updaters.Core.status(
58
+ replaceWith(
59
+ props.context.status == "closed" ? "open" : "closed")
60
+ ).then(
61
+ props.context.stream.loadedElements.count() == 0 ?
62
+ SearchableInfiniteStreamState<Element>().Updaters.Core.stream(
63
+ InfiniteStreamState<Element>().Updaters.Template.loadMore()
64
+ )
65
+ : id
66
+ )
67
+ ),
68
+ clearSelection: () => {
69
+ props.foreignMutations.onChange(
70
+ replaceWith(
71
+ CollectionSelection<Element>().Default.right("no selection")
72
+ ), List()
73
+ )
74
+ },
75
+ setSearchText: _ =>
76
+ props.setState(
77
+ SearchableInfiniteStreamState<Element>().Updaters.Template.searchText(
78
+ replaceWith(_)
79
+ )
80
+ ),
81
+ loadMore: () =>
82
+ props.setState(
83
+ SearchableInfiniteStreamState<Element>().Updaters.Core.stream(
84
+ InfiniteStreamState<Element>().Updaters.Template.loadMore()
85
+ )
86
+ ),
87
+ reload: () =>
88
+ props.setState(
89
+ SearchableInfiniteStreamState<Element>().Updaters.Template.searchText(
90
+ replaceWith("")
91
+ )
92
+ ),
93
+ select: _ =>
94
+ props.foreignMutations.onChange(replaceWith<CollectionSelection<Element>>(CollectionSelection<Element>().Default.left(_)), List()),
95
+ }}
96
+ />
97
+ </>
98
+ ).any([
99
+ loaderRunner,
100
+ debouncerRunner.mapContextFromProps(props => ({
101
+ ...props.context,
102
+ onDebounce: () => props.setState(
103
+ SearchableInfiniteStreamState<Element>().Updaters.Core.stream(
104
+ InfiniteStreamState<Element>().Updaters.Template.reload(
105
+ props.context.getChunk(props.context.searchText.value)
106
+ )
107
+ )
108
+ )
109
+ })),
110
+ ValidateRunner<Context, SearchableInfiniteStreamState<Element>, ForeignMutationsExpected, CollectionSelection<Element>>(
111
+ _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
112
+ ),
113
+ ]);
114
+ };
@@ -0,0 +1,27 @@
1
+ import { OrderedMap } from "immutable";
2
+ import { Guid, SimpleCallback } from "../../../../../../main";
3
+ import { View } from "../../../../../template/state";
4
+ import { Value } from "../../../../../value/state";
5
+ import { CollectionReference } from "../../../collection/domains/reference/state";
6
+ import { FormLabel } from "../../../singleton/domains/form-label/state";
7
+ import { OnChange } from "../../../singleton/state";
8
+ import { SearchableInfiniteStreamState } from "../searchable-infinite-stream/state";
9
+
10
+
11
+ export type InfiniteStreamMultiselectView<Element extends CollectionReference, Context extends FormLabel, ForeignMutationsExpected> =
12
+ View<
13
+ Context & Value<OrderedMap<Guid, Element>> & SearchableInfiniteStreamState<Element> & {
14
+ hasMoreValues:boolean,
15
+ isLoading:boolean,
16
+ availableOptions:Array<Element>
17
+ },
18
+ SearchableInfiniteStreamState<Element>,
19
+ ForeignMutationsExpected & {
20
+ onChange: OnChange<OrderedMap<Guid, Element>>;
21
+ toggleOpen:SimpleCallback<void>
22
+ clearSelection:SimpleCallback<void>
23
+ setSearchText:SimpleCallback<string>
24
+ toggleSelection:SimpleCallback<Element>
25
+ loadMore:SimpleCallback<void>
26
+ reload:SimpleCallback<void>
27
+ }>;
@@ -0,0 +1,119 @@
1
+ import { List, OrderedMap } from "immutable";
2
+ import { Guid, SimpleCallback, Debounce, InfiniteStreamLoader, CollectionSelection, id, replaceWith, OrderedMapRepo, AsyncState, BasicFun, Synchronize, Unit, ValidateRunner } from "../../../../../../main";
3
+ import { CoTypedFactory } from "../../../../../coroutines/builder";
4
+ import { Debounced } from "../../../../../debounced/state";
5
+ import { InfiniteStreamState } from "../../../../../infinite-data-stream/state";
6
+ import { Template } from "../../../../../template/state";
7
+ import { Value } from "../../../../../value/state";
8
+ import { CollectionReference } from "../../../collection/domains/reference/state";
9
+ import { FormLabel } from "../../../singleton/domains/form-label/state";
10
+ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, OnChange, ValidationError } from "../../../singleton/state";
11
+ import { SearchableInfiniteStreamState } from "../searchable-infinite-stream/state";
12
+ import { InfiniteStreamMultiselectView } from "./state";
13
+
14
+
15
+ export const InfiniteMultiselectDropdownForm = <Element extends CollectionReference, Context extends FormLabel, ForeignMutationsExpected>(
16
+ validation:BasicFun<OrderedMap<Guid, Element>, Promise<FieldValidation>>
17
+ ) => {
18
+ const Co = CoTypedFactory<Context & Value<OrderedMap<Guid, Element>>, SearchableInfiniteStreamState<Element>>();
19
+ const DebouncerCo = CoTypedFactory<Context & { onDebounce: SimpleCallback<void>; } & Value<OrderedMap<Guid, Element>>, SearchableInfiniteStreamState<Element>>();
20
+ const DebouncedCo = CoTypedFactory<{ onDebounce: SimpleCallback<void>; }, Value<string>>();
21
+ const debouncer = DebouncerCo.Repeat(
22
+ DebouncerCo.Seq([
23
+ Debounce<Value<string>, { onDebounce: SimpleCallback<void>; }>(
24
+ DebouncedCo.GetState().then(current => DebouncedCo.Do(() => current.onDebounce()))
25
+ //.SetState(SearchNow.Updaters.reloadsRequested(_ => _ + 1))
26
+ .then(_ => DebouncedCo.Return("success")),
27
+ 250
28
+ ).embed(_ => ({ ..._, ..._.searchText }), SearchableInfiniteStreamState<Element>().Updaters.Core.searchText),
29
+ DebouncerCo.Wait(0)
30
+ ])
31
+ );
32
+ const debouncerRunner = DebouncerCo.Template<ForeignMutationsExpected & { onChange: OnChange<OrderedMap<Guid, Element>>; }>(
33
+ debouncer,
34
+ {
35
+ interval: 15,
36
+ runFilter: props => Debounced.Operations.shouldCoroutineRun(props.context.searchText)
37
+ }
38
+ );
39
+ const loaderRunner = Co.Template<ForeignMutationsExpected & { onChange: OnChange<OrderedMap<Guid, Element>>; }>(
40
+ InfiniteStreamLoader<Element>().embed(_ => _.stream, SearchableInfiniteStreamState<Element>().Updaters.Core.stream),
41
+ {
42
+ interval: 15,
43
+ runFilter: props => InfiniteStreamState().Operations.shouldCoroutineRun(props.context.stream)
44
+ }
45
+ );
46
+
47
+ return Template.Default<Context & Value<OrderedMap<Guid, Element>>, SearchableInfiniteStreamState<Element>, ForeignMutationsExpected & { onChange: OnChange<OrderedMap<Guid, Element>>; }, InfiniteStreamMultiselectView<Element, Context, ForeignMutationsExpected>>(props => <>
48
+ <props.view {...props}
49
+ context={{
50
+ ...props.context,
51
+ hasMoreValues: !(props.context.stream.loadedElements.last()?.hasMoreValues == false),
52
+ isLoading: AsyncState.Operations.isLoading(props.context.stream.loadingMore),
53
+ availableOptions: props.context.stream.loadedElements.valueSeq().flatMap(chunk =>
54
+ chunk.data.valueSeq()
55
+ ).toArray()
56
+ }}
57
+ foreignMutations={{
58
+ ...props.foreignMutations,
59
+ toggleOpen: () => props.setState(
60
+ SearchableInfiniteStreamState<Element>().Updaters.Core.status(
61
+ replaceWith(
62
+ props.context.status == "closed" ? "open" : "closed")
63
+ ).then(
64
+ props.context.stream.loadedElements.count() == 0 ?
65
+ SearchableInfiniteStreamState<Element>().Updaters.Core.stream(
66
+ InfiniteStreamState<Element>().Updaters.Template.loadMore()
67
+ )
68
+ : id
69
+ )
70
+ ),
71
+ clearSelection: () => {
72
+ props.foreignMutations.onChange(
73
+ OrderedMapRepo.Updaters.clear(), List()
74
+ )
75
+ },
76
+ setSearchText: _ =>
77
+ props.setState(
78
+ SearchableInfiniteStreamState<Element>().Updaters.Template.searchText(
79
+ replaceWith(_)
80
+ )
81
+ ),
82
+ loadMore: () =>
83
+ props.setState(
84
+ SearchableInfiniteStreamState<Element>().Updaters.Core.stream(
85
+ InfiniteStreamState<Element>().Updaters.Template.loadMore()
86
+ )
87
+ ),
88
+ reload: () =>
89
+ props.setState(
90
+ SearchableInfiniteStreamState<Element>().Updaters.Template.searchText(
91
+ replaceWith("")
92
+ )
93
+ ),
94
+ toggleSelection: element =>
95
+ props.foreignMutations.onChange(
96
+ props.context.value.has(element.id) ?
97
+ OrderedMapRepo.Updaters.remove(element.id) :
98
+ OrderedMapRepo.Updaters.set(element.id, element),
99
+ List()),
100
+ }}
101
+ />
102
+ </>
103
+ ).any([
104
+ loaderRunner,
105
+ debouncerRunner.mapContextFromProps(props => ({
106
+ ...props.context,
107
+ onDebounce: () => props.setState(
108
+ SearchableInfiniteStreamState<Element>().Updaters.Core.stream(
109
+ InfiniteStreamState<Element>().Updaters.Template.reload(
110
+ props.context.getChunk(props.context.searchText.value)
111
+ )
112
+ )
113
+ )
114
+ })),
115
+ ValidateRunner<Context, SearchableInfiniteStreamState<Element>, ForeignMutationsExpected, OrderedMap<Guid, Element>>(
116
+ _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
117
+ ),
118
+ ]);
119
+ };
@@ -0,0 +1,12 @@
1
+ import { SimpleCallback, Unit } from "../../../../../../main";
2
+ import { View } from "../../../../../template/state";
3
+ import { Value } from "../../../../../value/state";
4
+ import { FormLabel } from "../../../singleton/domains/form-label/state";
5
+ import { OnChange, SharedFormState } from "../../../singleton/state";
6
+
7
+ export type StringView<Context extends FormLabel, ForeignMutationsExpected> =
8
+ View<
9
+ Context & Value<string> & SharedFormState,
10
+ SharedFormState,
11
+ ForeignMutationsExpected & { onChange: OnChange<string>; setNewValue: SimpleCallback<string> }
12
+ >;
@@ -0,0 +1,24 @@
1
+ import { List } from "immutable";
2
+ import { BasicFun, CoTypedFactory, Debounce, Debounced, replaceWith, Synchronize, Unit, ValidateRunner } from "../../../../../../main";
3
+ import { Template } from "../../../../../template/state";
4
+ import { Value } from "../../../../../value/state";
5
+ import { FormLabel } from "../../../singleton/domains/form-label/state";
6
+ import { FieldValidation, FieldValidationWithPath, FormValidatorSynchronized, OnChange, SharedFormState, ValidationError } from "../../../singleton/state";
7
+ import { StringView } from "./state";
8
+
9
+
10
+ export const StringForm = <Context extends FormLabel, ForeignMutationsExpected>(
11
+ validation:BasicFun<string, Promise<FieldValidation>>) => {
12
+ return Template.Default<Context & Value<string>, SharedFormState, ForeignMutationsExpected & { onChange: OnChange<string>; }, StringView<Context, ForeignMutationsExpected>>(props => <>
13
+ <props.view {...props}
14
+ foreignMutations={{
15
+ ...props.foreignMutations,
16
+ setNewValue: (_) => props.foreignMutations.onChange(replaceWith(_), List())
17
+ }} />
18
+ </>
19
+ ).any([
20
+ ValidateRunner<Context, SharedFormState, ForeignMutationsExpected, string>(
21
+ _ => validation(_).then(FieldValidationWithPath.Default.fromFieldValidation)
22
+ ),
23
+ ])
24
+ }
@@ -0,0 +1,9 @@
1
+ import { FieldDescriptor } from "../field/state";
2
+
3
+
4
+ export type EntityDescriptor<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context> = {
5
+ [k in keyof E]: FieldDescriptor<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k, Context>;
6
+ };
7
+ export const EntityDescriptor = {
8
+ Default: <E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context>(_: EntityDescriptor<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context>): EntityDescriptor<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context> => _
9
+ };
@@ -0,0 +1,5 @@
1
+
2
+ export type BaseConfig = { visible: boolean; disabled: boolean; };
3
+ export const BaseConfig = {
4
+ Default: (visible?: boolean, disabled?: boolean): BaseConfig => ({ visible: visible ?? true, disabled: disabled ?? false })
5
+ };
@@ -0,0 +1,6 @@
1
+ import { BaseConfig } from "../base/state";
2
+
3
+ export type BooleanConfig = { kind: "boolean"; } & BaseConfig;
4
+ export const BooleanConfig = {
5
+ Default: (visible?: boolean, disabled?: boolean): BooleanConfig => ({ kind: "boolean", ...(BaseConfig.Default(visible, disabled)) })
6
+ };
@@ -0,0 +1,21 @@
1
+ import { SimpleCallback, BasicUpdater } from "../../../../../../../../../main";
2
+ import { SingletonFormWritableState } from "../../../../../state";
3
+ import { BaseConfig } from "../base/state";
4
+
5
+
6
+ export type CustomTypeConfig<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k extends (keyof E) & (keyof CustomTypeFields), Context> =
7
+ {
8
+ kind: "custom"; k: k;
9
+ render: (props: {
10
+ context:Context,
11
+ state:CustomTypeFields[k],
12
+ entityValue: E;
13
+ fieldValue: E[k];
14
+ onChange: SimpleCallback<E[k]>;
15
+ setState: SimpleCallback<BasicUpdater<SingletonFormWritableState<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields>>>;
16
+ }) => JSX.Element;
17
+ } & BaseConfig;
18
+ export const CustomTypeConfig = {
19
+ Default: <E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k extends (keyof E) & (keyof CustomTypeFields), Context>(
20
+ k: k, render: CustomTypeConfig<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k, Context>["render"], visible?: boolean, disabled?: boolean): CustomTypeConfig<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k, Context> => ({ kind: "custom", k, render, visible: visible ?? true, disabled: disabled ?? false })
21
+ };
@@ -0,0 +1,6 @@
1
+ import { BaseConfig } from "../base/state";
2
+
3
+ export type DateConfig = { kind: "date"; } & BaseConfig;
4
+ export const DateConfig = {
5
+ Default: (visible?: boolean, disabled?: boolean): DateConfig => ({ kind: "date", ...(BaseConfig.Default(visible, disabled)) })
6
+ };
@@ -0,0 +1,7 @@
1
+ import { SmallIdentifiable } from "../../../../../../../../../main";
2
+ import { BaseConfig } from "../base/state";
3
+
4
+ export type EnumConfig<V> = { kind: "enum"; choices: Array<SmallIdentifiable & { displayName: string; value: V; }>; } & BaseConfig;
5
+ export const EnumConfig = {
6
+ Default: <V>(choices: EnumConfig<V>["choices"], visible?: boolean, disabled?: boolean): EnumConfig<V> => ({ kind: "enum", choices, ...(BaseConfig.Default(visible, disabled)) })
7
+ };
@@ -0,0 +1,8 @@
1
+ import { SmallIdentifiable } from "../../../../../../../../../main";
2
+ import { InfiniteStreamState } from "../../../../../../../../infinite-data-stream/state";
3
+ import { BaseConfig } from "../base/state";
4
+
5
+ export type InfiniteEnumConfig<V extends SmallIdentifiable> = { kind: "infinite-enum"; getChunk: InfiniteStreamState<V>["getChunk"]; } & BaseConfig;
6
+ export const InfiniteEnumConfig = {
7
+ Default: <V extends SmallIdentifiable>(getChunk: InfiniteStreamState<V>["getChunk"], visible?: boolean, disabled?: boolean): InfiniteEnumConfig<V> => ({ kind: "infinite-enum", getChunk, ...(BaseConfig.Default(visible, disabled)) })
8
+ };
@@ -0,0 +1,7 @@
1
+ import { BaseConfig } from "../base/state";
2
+
3
+ export type NumberConfig = { kind: "number"; } & BaseConfig;
4
+ export const NumberConfig = {
5
+ Default: (visible?: boolean, disabled?: boolean): NumberConfig => ({ kind: "number", ...(BaseConfig.Default(visible, disabled)) })
6
+ };
7
+
@@ -0,0 +1,7 @@
1
+ import { BaseConfig } from "../base/state";
2
+
3
+
4
+ export type StringConfig = { kind: "string"; } & BaseConfig;
5
+ export const StringConfig = {
6
+ Default: (visible?: boolean, disabled?: boolean): StringConfig => ({ kind: "string", ...(BaseConfig.Default(visible, disabled)) })
7
+ };
@@ -0,0 +1,16 @@
1
+ import { SmallIdentifiable } from "../../../../../../../main";
2
+ import { NumberConfig } from "./domains/number/state";
3
+ import { StringConfig } from "./domains/string/state";
4
+ import { BooleanConfig } from "./domains/boolean/state";
5
+ import { DateConfig } from "./domains/date/state";
6
+ import { EnumConfig } from "./domains/enum/state";
7
+ import { InfiniteEnumConfig } from "./domains/infinite-enum/state";
8
+ import { CustomTypeConfig } from "./domains/custom/state";
9
+
10
+
11
+ export type FieldDescriptor<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k extends keyof E, Context> =
12
+ k extends keyof CustomTypeFields ?
13
+ CustomTypeConfig<E, EnumKeys, InfiniteEnumKeys, CustomTypeFields, k, Context> :
14
+ k extends EnumKeys ? EnumConfig<E[k]> :
15
+ k extends InfiniteEnumKeys ? E[k] extends SmallIdentifiable ? InfiniteEnumConfig<E[k]> :
16
+ { kind: "error - infinite enum requires 'extends Identifiable'"; } : E[k] extends number ? NumberConfig : E[k] extends string ? StringConfig : E[k] extends string ? StringConfig : E[k] extends boolean ? BooleanConfig : E[k] extends Date ? DateConfig : { kind: "error - type not supported "; };
@@ -0,0 +1,13 @@
1
+ import { Template } from "../../../../../../template/state";
2
+ import { SingletonFormReadonlyContext, SingletonFormWritableState, SingletonFormForeignMutationsExpected } from "../../../state";
3
+ import { FieldViews } from "../../../views/field-views";
4
+ import { EntityDescriptor } from "../entity/state";
5
+
6
+ export type FormDefinition<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context> = {
7
+ entityDescriptor: EntityDescriptor<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context>;
8
+ fieldOrder: Array<keyof Entity>;
9
+ };
10
+ export type FormTemplateAndDefinition<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context> = {
11
+ template: Template<
12
+ SingletonFormReadonlyContext<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context> & SingletonFormWritableState<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields>, SingletonFormWritableState<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields>, SingletonFormForeignMutationsExpected<Entity, EnumKeys, InfiniteEnumKeys>, FieldViews>;
13
+ } & FormDefinition<Entity, EnumKeys, InfiniteEnumKeys, CustomTypeFields, Context>;
@@ -0,0 +1,2 @@
1
+
2
+ export type FormLabel = { label: string; };
@@ -0,0 +1,87 @@
1
+ import { List, OrderedMap, OrderedSet } from "immutable"
2
+ import { BasicUpdater, id, BasicPredicate, SimpleCallback, Unit, Debounced, Synchronized, unit, replaceWith, CoTypedFactory, Debounce, Synchronize, BasicFun } from "../../../../main"
3
+ import { Template, View } from "../../../template/state"
4
+ import { Value } from "../../../value/state"
5
+
6
+ export type ToPathUnions<a> = a[keyof a]
7
+ export type Paths<Entity, NestedPaths = Unit> = {
8
+ [f in keyof Entity]:
9
+ f extends keyof NestedPaths ?
10
+ [f, ToPathUnions<NestedPaths[f]>]
11
+ : [f]
12
+ }
13
+
14
+ // type OtherNestedThing = { x:boolean, y:string }
15
+ // type Address = { city:string, street:string, number:number, other:OtherNestedThing }
16
+ // type Person = { name:string, surname:string, birthday:Date, address:Address, other:OtherNestedThing }
17
+ // type OtherNestedThingPaths = Paths<OtherNestedThing, Unit>
18
+ // type AddressPaths = Paths<Address, { other:OtherNestedThingPaths }>
19
+ // type PersonPaths = ToPathUnions<Paths<Person, { address:AddressPaths, other:OtherNestedThingPaths }>>
20
+ // const f = (_:PersonPaths) => {
21
+ // if (_[0] == "name") return
22
+ // if (_[0] == "surname") return
23
+ // if (_[0] == "birthday") return
24
+ // if (_[0] == "address") {
25
+ // _[1][0] == "city"
26
+ // if (_[1][0] == "other") {
27
+ // _[1][1][0] == "x"
28
+ // }
29
+ // return
30
+ // }
31
+ // _[1][0] == "x"
32
+ // }
33
+
34
+ export type ValidationError = string
35
+ export type FieldValidation = Array<ValidationError>
36
+ export type Path = Array<string>
37
+ export type ValidationErrorWithPath = [Path, ValidationError]
38
+ export type FieldValidationWithPath = Array<ValidationErrorWithPath>
39
+ export const FieldValidationWithPath = {
40
+ Default:{
41
+ fromFieldValidation:(_:FieldValidation) : FieldValidationWithPath =>
42
+ _.map(_ => ([[], _])),
43
+ }
44
+ }
45
+ export type FormValidatorSynchronized = Synchronized<Unit, FieldValidationWithPath>
46
+ export type SharedFormState = { modifiedByUser: boolean, validation: Debounced<FormValidatorSynchronized> }
47
+ export const SharedFormState = {
48
+ Default: (): SharedFormState => ({
49
+ modifiedByUser: false,
50
+ // start the validation so that it immediately runs and registers the first errors such as missing values and such
51
+ validation: Debounced.Updaters.Template.value<FormValidatorSynchronized>(Synchronized.Updaters.value(replaceWith(unit)))(Debounced.Default(Synchronized.Default(unit)))
52
+ })
53
+ }
54
+ export type EntityFormState<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> =
55
+ { [f in Fields]: FieldStates[f] & SharedFormState } & SharedFormState
56
+ export type EntityFormContext<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> =
57
+ Context & EntityFormState<Entity, Fields, FieldStates, Context, ForeignMutationsExpected> & { visibleFields: OrderedMap<Fields, BasicPredicate<Context>> } & Value<Entity>
58
+ export type OnChange<Entity> = (updater: BasicUpdater<Entity>, path: List<string>) => void
59
+ export type EntityFormForeignMutationsExpected<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> =
60
+ ForeignMutationsExpected & { onChange: OnChange<Entity> }
61
+
62
+ export type FieldTemplates<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> = {
63
+ [f in Fields]: EmbeddedFieldTemplate<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>
64
+ }
65
+
66
+ export type EntityFormView<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> =
67
+ View<EntityFormContext<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>, EntityFormState<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>, EntityFormForeignMutationsExpected<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>, {
68
+ EmbeddedFields: FieldTemplates<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>,
69
+ VisibleFieldKeys: OrderedSet<Fields>
70
+ }>
71
+ export type EntityFormTemplate<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> =
72
+ Template<
73
+ EntityFormContext<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>,
74
+ EntityFormState<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>,
75
+ EntityFormForeignMutationsExpected<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>,
76
+ EntityFormView<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>
77
+ >
78
+ export type EmbeddedFieldTemplate<Entity, Fields extends (keyof Entity) & (keyof FieldStates), FieldStates, Context, ForeignMutationsExpected> =
79
+ Template<
80
+ EntityFormContext<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>,
81
+ EntityFormState<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>,
82
+ EntityFormForeignMutationsExpected<Entity, Fields, FieldStates, Context, ForeignMutationsExpected>
83
+ >
84
+
85
+ export type FormStateFromEntity<E, S> = {
86
+ [f in keyof E]: f extends keyof S ? S[f] & SharedFormState : SharedFormState
87
+ } & SharedFormState