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.
- package/main.ts +149 -0
- package/package.json +20 -0
- package/src/apiResultStatus/state.ts +7 -0
- package/src/async/domains/mirroring/domains/collection/coroutines/synchronizers.ts +334 -0
- package/src/async/domains/mirroring/domains/collection/state.ts +137 -0
- package/src/async/domains/mirroring/domains/entity/domains/loaded-collection/state.ts +24 -0
- package/src/async/domains/mirroring/domains/entity/domains/loaded-collection-entity/state.ts +27 -0
- package/src/async/domains/mirroring/domains/entity/domains/loaded-entities/state.ts +12 -0
- package/src/async/domains/mirroring/domains/entity/domains/loaded-entity/state.ts +29 -0
- package/src/async/domains/mirroring/domains/entity/state.ts +22 -0
- package/src/async/domains/mirroring/domains/singleton/coroutines/synchronizers.ts +216 -0
- package/src/async/domains/mirroring/domains/singleton/state.ts +57 -0
- package/src/async/domains/mirroring/domains/synchronization-result/state.ts +2 -0
- package/src/async/domains/mirroring/domains/synchronized-entities/state.ts +23 -0
- package/src/async/domains/promise/state.ts +13 -0
- package/src/async/domains/synchronized/coroutines/synchronize.ts +62 -0
- package/src/async/domains/synchronized/state.ts +20 -0
- package/src/async/state.ts +144 -0
- package/src/baseEntity/domains/identifiable/state.ts +29 -0
- package/src/collections/domains/array/state.ts +16 -0
- package/src/collections/domains/immutable/domains/list/state.ts +20 -0
- package/src/collections/domains/immutable/domains/map/state.ts +33 -0
- package/src/collections/domains/immutable/domains/orderedMap/state.ts +117 -0
- package/src/collections/domains/immutable/domains/ordereredSet/state.ts +19 -0
- package/src/collections/domains/immutable/domains/set/state.ts +15 -0
- package/src/collections/domains/maybe/state.ts +20 -0
- package/src/collections/domains/product/state.ts +47 -0
- package/src/collections/domains/sum/state.ts +82 -0
- package/src/coroutines/builder.tsx +66 -0
- package/src/coroutines/state.ts +574 -0
- package/src/coroutines/template.tsx +119 -0
- package/src/debounced/coroutines/debounce.ts +118 -0
- package/src/debounced/state.ts +61 -0
- package/src/diagnostics/domains/message-box/state.ts +4 -0
- package/src/foreignMutations/state.ts +4 -0
- package/src/forms/domains/attachments/views/attachments-view.tsx +22 -0
- package/src/forms/domains/collection/domains/reference/state.ts +18 -0
- package/src/forms/domains/collection/domains/selection/state.ts +5 -0
- package/src/forms/domains/launcher/domains/create/coroutines/runner.ts +60 -0
- package/src/forms/domains/launcher/domains/create/state.ts +71 -0
- package/src/forms/domains/launcher/domains/create/template.tsx +66 -0
- package/src/forms/domains/launcher/domains/edit/coroutines/runner.ts +47 -0
- package/src/forms/domains/launcher/domains/edit/state.ts +55 -0
- package/src/forms/domains/launcher/domains/edit/template.tsx +39 -0
- package/src/forms/domains/parser/domains/validator/state.ts +423 -0
- package/src/forms/domains/parser/state.tsx +311 -0
- package/src/forms/domains/primitives/domains/boolean/state.ts +13 -0
- package/src/forms/domains/primitives/domains/boolean/template.tsx +24 -0
- package/src/forms/domains/primitives/domains/date/state.ts +23 -0
- package/src/forms/domains/primitives/domains/date/template.tsx +31 -0
- package/src/forms/domains/primitives/domains/enum/state.ts +27 -0
- package/src/forms/domains/primitives/domains/enum/template.tsx +52 -0
- package/src/forms/domains/primitives/domains/enum-multiselect/state.ts +18 -0
- package/src/forms/domains/primitives/domains/enum-multiselect/template.tsx +56 -0
- package/src/forms/domains/primitives/domains/number/state.ts +8 -0
- package/src/forms/domains/primitives/domains/number/template.tsx +26 -0
- package/src/forms/domains/primitives/domains/searchable-infinite-stream/state.ts +55 -0
- package/src/forms/domains/primitives/domains/searchable-infinite-stream/template.tsx +114 -0
- package/src/forms/domains/primitives/domains/searchable-infinite-stream-multiselect/state.ts +27 -0
- package/src/forms/domains/primitives/domains/searchable-infinite-stream-multiselect/template.tsx +119 -0
- package/src/forms/domains/primitives/domains/string/state.ts +12 -0
- package/src/forms/domains/primitives/domains/string/template.tsx +24 -0
- package/src/forms/domains/singleton/domains/descriptors/entity/state.ts +9 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/base/state.ts +5 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/boolean/state.ts +6 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/custom/state.ts +21 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/date/state.ts +6 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/enum/state.ts +7 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/infinite-enum/state.ts +8 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/number/state.ts +7 -0
- package/src/forms/domains/singleton/domains/descriptors/field/domains/string/state.ts +7 -0
- package/src/forms/domains/singleton/domains/descriptors/field/state.ts +16 -0
- package/src/forms/domains/singleton/domains/descriptors/form/state.ts +13 -0
- package/src/forms/domains/singleton/domains/form-label/state.ts +2 -0
- package/src/forms/domains/singleton/state.ts +87 -0
- package/src/forms/domains/singleton/template.tsx +92 -0
- package/src/forms/domains/singleton/views/field-views.ts +23 -0
- package/src/forms/domains/singleton/views/simple-inputs/base.ts +5 -0
- package/src/forms/domains/singleton/views/simple-inputs/boolean.tsx +4 -0
- package/src/forms/domains/singleton/views/simple-inputs/date.tsx +4 -0
- package/src/forms/domains/singleton/views/simple-inputs/number.tsx +4 -0
- package/src/forms/domains/singleton/views/simple-inputs/string.tsx +4 -0
- package/src/fun/domains/curry/state.ts +6 -0
- package/src/fun/domains/id/state.ts +2 -0
- package/src/fun/domains/predicate/domains/bool-expr.ts +98 -0
- package/src/fun/domains/predicate/state.ts +29 -0
- package/src/fun/domains/simpleCallback/state.ts +3 -0
- package/src/fun/domains/uncurry/state.ts +5 -0
- package/src/fun/domains/unit/state.ts +3 -0
- package/src/fun/domains/updater/domains/caseUpdater/state.ts +44 -0
- package/src/fun/domains/updater/domains/mapUpdater/state.ts +36 -0
- package/src/fun/domains/updater/domains/maybeUpdater/state.ts +45 -0
- package/src/fun/domains/updater/domains/orderedMapUpdater/state.ts +26 -0
- package/src/fun/domains/updater/domains/orderedSetUpdater/state.ts +23 -0
- package/src/fun/domains/updater/domains/replaceWith/state.ts +3 -0
- package/src/fun/domains/updater/domains/simpleUpdater/domains/baseSimpleUpdater/state.ts +18 -0
- package/src/fun/domains/updater/domains/simpleUpdater/state.ts +72 -0
- package/src/fun/domains/updater/state.ts +86 -0
- package/src/fun/state.ts +33 -0
- package/src/infinite-data-stream/coroutines/builder.ts +8 -0
- package/src/infinite-data-stream/coroutines/infiniteLoader.ts +51 -0
- package/src/infinite-data-stream/coroutines/runner.ts +12 -0
- package/src/infinite-data-stream/state.ts +175 -0
- package/src/infinite-data-stream/template.tsx +16 -0
- package/src/math/domains/DOMRect/state.ts +12 -0
- package/src/math/domains/number/state.ts +9 -0
- package/src/math/domains/rect/state.ts +22 -0
- package/src/math/domains/rgba/state.ts +87 -0
- package/src/math/domains/size2/state.ts +14 -0
- package/src/math/domains/vector2/state.ts +16 -0
- package/src/queue/state.ts +42 -0
- package/src/state/domains/repository/state.ts +14 -0
- package/src/template/state.tsx +198 -0
- package/src/validation/state.ts +2 -0
- package/src/value/domains/mutable-value/state.ts +13 -0
- package/src/value/state.ts +12 -0
- package/src/visibility/state.ts +3 -0
- package/tsconfig.json +22 -0
package/main.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export * from "./src/apiResultStatus/state"
|
|
2
|
+
export * from "./src/async/state"
|
|
3
|
+
export * from "./src/async/domains/promise/state"
|
|
4
|
+
export * from "./src/async/domains/synchronized/state"
|
|
5
|
+
export * from "./src/async/domains/synchronized/coroutines/synchronize"
|
|
6
|
+
export * from "./src/async/domains/mirroring/domains/synchronization-result/state"
|
|
7
|
+
export * from "./src/async/domains/mirroring/domains/entity/state"
|
|
8
|
+
export * from "./src/async/domains/mirroring/domains/entity/domains/loaded-entity/state"
|
|
9
|
+
export * from "./src/async/domains/mirroring/domains/entity/domains/loaded-collection-entity/state"
|
|
10
|
+
export * from "./src/async/domains/mirroring/domains/entity/domains/loaded-collection/state"
|
|
11
|
+
export * from "./src/async/domains/mirroring/domains/entity/domains/loaded-entities/state"
|
|
12
|
+
export * from "./src/async/domains/mirroring/domains/singleton/state"
|
|
13
|
+
export * from "./src/async/domains/mirroring/domains/singleton/coroutines/synchronizers"
|
|
14
|
+
export * from "./src/async/domains/mirroring/domains/collection/state"
|
|
15
|
+
export * from "./src/async/domains/mirroring/domains/collection/coroutines/synchronizers"
|
|
16
|
+
export * from "./src/async/domains/mirroring/domains/synchronized-entities/state"
|
|
17
|
+
export * from "./src/baseEntity/domains/identifiable/state"
|
|
18
|
+
export * from "./src/collections/domains/immutable/domains/map/state"
|
|
19
|
+
export * from "./src/collections/domains/immutable/domains/list/state"
|
|
20
|
+
export * from "./src/collections/domains/immutable/domains/orderedMap/state"
|
|
21
|
+
export * from "./src/collections/domains/immutable/domains/ordereredSet/state"
|
|
22
|
+
export * from "./src/collections/domains/array/state"
|
|
23
|
+
export * from "./src/coroutines/state"
|
|
24
|
+
export * from "./src/coroutines/template"
|
|
25
|
+
export * from "./src/coroutines/builder"
|
|
26
|
+
export * from "./src/debounced/state"
|
|
27
|
+
export * from "./src/debounced/coroutines/debounce"
|
|
28
|
+
export * from "./src/diagnostics/domains/message-box/state"
|
|
29
|
+
export * from "./src/foreignMutations/state"
|
|
30
|
+
export * from "./src/fun/state"
|
|
31
|
+
export * from "./src/fun/domains/curry/state"
|
|
32
|
+
export * from "./src/fun/domains/id/state"
|
|
33
|
+
export * from "./src/fun/domains/simpleCallback/state"
|
|
34
|
+
export * from "./src/fun/domains/uncurry/state"
|
|
35
|
+
export * from "./src/fun/domains/unit/state"
|
|
36
|
+
export * from "./src/fun/domains/predicate/state"
|
|
37
|
+
export * from "./src/fun/domains/predicate/domains/bool-expr"
|
|
38
|
+
export * from "./src/fun/domains/updater/state"
|
|
39
|
+
export * from "./src/fun/domains/updater/domains/simpleUpdater/state"
|
|
40
|
+
export * from "./src/fun/domains/updater/domains/simpleUpdater/domains/baseSimpleUpdater/state"
|
|
41
|
+
export * from "./src/fun/domains/updater/domains/maybeUpdater/state"
|
|
42
|
+
export * from "./src/fun/domains/updater/domains/mapUpdater/state"
|
|
43
|
+
export * from "./src/fun/domains/updater/domains/orderedMapUpdater/state"
|
|
44
|
+
export * from "./src/fun/domains/updater/domains/orderedSetUpdater/state"
|
|
45
|
+
export * from "./src/fun/domains/updater/domains/caseUpdater/state"
|
|
46
|
+
export * from "./src/fun/domains/updater/domains/replaceWith/state"
|
|
47
|
+
export * from "./src/infinite-data-stream/state"
|
|
48
|
+
export * from "./src/infinite-data-stream/template"
|
|
49
|
+
export * from "./src/infinite-data-stream/coroutines/runner"
|
|
50
|
+
export * from "./src/infinite-data-stream/coroutines/infiniteLoader"
|
|
51
|
+
export * from "./src/infinite-data-stream/coroutines/builder"
|
|
52
|
+
export * from "./src/math/domains/DOMRect/state"
|
|
53
|
+
export * from "./src/math/domains/number/state"
|
|
54
|
+
export * from "./src/math/domains/rgba/state"
|
|
55
|
+
export * from "./src/math/domains/size2/state"
|
|
56
|
+
export * from "./src/math/domains/vector2/state"
|
|
57
|
+
export * from "./src/math/domains/rect/state"
|
|
58
|
+
export * from "./src/state/domains/repository/state"
|
|
59
|
+
export * from "./src/template/state"
|
|
60
|
+
export * from "./src/validation/state"
|
|
61
|
+
export * from "./src/visibility/state"
|
|
62
|
+
export * from "./src/value/state"
|
|
63
|
+
export * from "./src/collections/domains/maybe/state"
|
|
64
|
+
export * from "./src/value/domains/mutable-value/state"
|
|
65
|
+
export * from "./src/collections/domains/sum/state"
|
|
66
|
+
export * from "./src/collections/domains/product/state"
|
|
67
|
+
export * from "./src/queue/state"
|
|
68
|
+
export * from "./src/forms/domains/attachments/views/attachments-view"
|
|
69
|
+
export * from "./src/forms/domains/singleton/state"
|
|
70
|
+
export * from "./src/forms/domains/singleton/template"
|
|
71
|
+
export * from "./src/forms/domains/singleton/domains/form-label/state"
|
|
72
|
+
export * from "./src/forms/domains/collection/domains/reference/state"
|
|
73
|
+
export * from "./src/forms/domains/collection/domains/selection/state"
|
|
74
|
+
export * from "./src/forms/domains/primitives/domains/string/state"
|
|
75
|
+
export * from "./src/forms/domains/primitives/domains/string/template"
|
|
76
|
+
export * from "./src/forms/domains/primitives/domains/boolean/state"
|
|
77
|
+
export * from "./src/forms/domains/primitives/domains/boolean/template"
|
|
78
|
+
export * from "./src/forms/domains/primitives/domains/number/state"
|
|
79
|
+
export * from "./src/forms/domains/primitives/domains/number/template"
|
|
80
|
+
export * from "./src/forms/domains/primitives/domains/date/state"
|
|
81
|
+
export * from "./src/forms/domains/primitives/domains/date/template"
|
|
82
|
+
export * from "./src/forms/domains/primitives/domains/enum/state"
|
|
83
|
+
export * from "./src/forms/domains/primitives/domains/enum/template"
|
|
84
|
+
export * from "./src/forms/domains/primitives/domains/enum-multiselect/state"
|
|
85
|
+
export * from "./src/forms/domains/primitives/domains/enum-multiselect/template"
|
|
86
|
+
export * from "./src/forms/domains/primitives/domains/searchable-infinite-stream/state"
|
|
87
|
+
export * from "./src/forms/domains/primitives/domains/searchable-infinite-stream/template"
|
|
88
|
+
export * from "./src/forms/domains/primitives/domains/searchable-infinite-stream-multiselect/state"
|
|
89
|
+
export * from "./src/forms/domains/primitives/domains/searchable-infinite-stream-multiselect/template"
|
|
90
|
+
export * from "./src/forms/domains/parser/state"
|
|
91
|
+
export * from "./src/forms/domains/parser/domains/validator/state"
|
|
92
|
+
export * from "./src/forms/domains/launcher/domains/edit/state"
|
|
93
|
+
export * from "./src/forms/domains/launcher/domains/edit/template"
|
|
94
|
+
export * from "./src/forms/domains/launcher/domains/edit/coroutines/runner"
|
|
95
|
+
export * from "./src/forms/domains/launcher/domains/create/state"
|
|
96
|
+
export * from "./src/forms/domains/launcher/domains/create/template"
|
|
97
|
+
export * from "./src/forms/domains/launcher/domains/create/coroutines/runner"
|
|
98
|
+
|
|
99
|
+
// import { simpleUpdater, simpleUpdaterWithChildren } from "./src/fun/domains/updater/domains/simpleUpdater/state"
|
|
100
|
+
// import { Updater } from "./src/fun/domains/updater/state"
|
|
101
|
+
|
|
102
|
+
// // little testing playground and microsample: please do not remove
|
|
103
|
+
// type City = { name: string, population: number }
|
|
104
|
+
// const City = {
|
|
105
|
+
// Default: (): City => ({
|
|
106
|
+
// name: "Mirano", population: 25000
|
|
107
|
+
// }),
|
|
108
|
+
// Updaters: {
|
|
109
|
+
// Core: {
|
|
110
|
+
// ...simpleUpdater<City>()("name"),
|
|
111
|
+
// ...simpleUpdater<City>()("population"),
|
|
112
|
+
// }
|
|
113
|
+
// }
|
|
114
|
+
// }
|
|
115
|
+
// type Address = { street: string, number: number, city: City }
|
|
116
|
+
// const Address = {
|
|
117
|
+
// Default: (): Address => ({
|
|
118
|
+
// street: "Don Minzoni", number: 20, city: City.Default()
|
|
119
|
+
// }),
|
|
120
|
+
// Updaters: {
|
|
121
|
+
// Core: {
|
|
122
|
+
// ...simpleUpdater<Address>()("street"),
|
|
123
|
+
// ...simpleUpdater<Address>()("number"),
|
|
124
|
+
// ...simpleUpdaterWithChildren<Address>()(City.Updaters)("city"),
|
|
125
|
+
// },
|
|
126
|
+
// }
|
|
127
|
+
// }
|
|
128
|
+
// type Person = { name: string, surname: string, address: Address }
|
|
129
|
+
// const Person = {
|
|
130
|
+
// Default: (): Person => ({
|
|
131
|
+
// name: "John", surname: "Doe", address: Address.Default()
|
|
132
|
+
// }),
|
|
133
|
+
// Updaters: {
|
|
134
|
+
// Core: {
|
|
135
|
+
// ...simpleUpdater<Person>()("name"),
|
|
136
|
+
// ...simpleUpdater<Person>()("surname"),
|
|
137
|
+
// ...simpleUpdaterWithChildren<Person>()(Address.Updaters)("address"),
|
|
138
|
+
// }
|
|
139
|
+
// }
|
|
140
|
+
// }
|
|
141
|
+
|
|
142
|
+
// const personUpdater:Updater<Person> =
|
|
143
|
+
// Person.Updaters.Core.address.children.Core.city.children.Core.name(_ =>"The Great " + _)
|
|
144
|
+
// .then(Person.Updaters.Core.address(Address.Updaters.Core.street(_ => _ + " str.")))
|
|
145
|
+
// .then(Person.Updaters.Core.address.children.Core.number(_ => _ + 1))
|
|
146
|
+
// console.log(personUpdater(Person.Default()))
|
|
147
|
+
|
|
148
|
+
// const addressUpdater:Updater<Address> = Address.Updaters.Core.city.children.name(_ =>"The Great " + _)
|
|
149
|
+
// console.log(addressUpdater(Address.Default()))
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ballerina-core",
|
|
3
|
+
"author": "Dr. Giuseppe Maggiore",
|
|
4
|
+
"private": false,
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"main": "main.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"immutable": "^5.0.0-beta.5",
|
|
9
|
+
"react": "^18.2.0",
|
|
10
|
+
"react-dom": "^18.2.0",
|
|
11
|
+
"uuid": "^9.0.1"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/node": "^20.12.12",
|
|
15
|
+
"@types/react": "^18.2.48",
|
|
16
|
+
"@types/react-dom": "^18.2.18",
|
|
17
|
+
"@types/uuid": "^9.0.8",
|
|
18
|
+
"typescript": "^5.4.5"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
|
|
2
|
+
export const errorPermanenceStatus = ["permanent failure", "transient failure"] as const
|
|
3
|
+
export type ErrorPermanenceStatus = (typeof errorPermanenceStatus)[number]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export const apiResultStatuses = ["success", ...errorPermanenceStatus] as const
|
|
7
|
+
export type ApiResultStatus = (typeof apiResultStatuses)[number]
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { OrderedMap } from "immutable";
|
|
2
|
+
import { Value, Guid, BasicUpdater, Updater, Unit, CoTypedFactory, AsyncState, replaceWith, DirtyStatus, Entity, Debounced, Synchronize, Sum, unit } from "../../../../../../../main";
|
|
3
|
+
import { Coroutine } from "../../../../../../coroutines/state";
|
|
4
|
+
import { Fun, BasicFun } from "../../../../../../fun/state";
|
|
5
|
+
import { Synchronized } from "../../../../synchronized/state";
|
|
6
|
+
import { insideEntitySynchronizedAndDebounced } from "../../singleton/coroutines/synchronizers";
|
|
7
|
+
import { SynchronizationResult } from "../../synchronization-result/state";
|
|
8
|
+
import { Collection, CollectionEntity } from "../state";
|
|
9
|
+
|
|
10
|
+
export type CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations> = {
|
|
11
|
+
[k in (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)]: {
|
|
12
|
+
add: (entity: CollectionEntity<Collections[k]>, position?: InsertionPosition) =>
|
|
13
|
+
Coroutine<Context & CollectionEntity<Collections[k]>, CollectionEntity<Collections[k]>, SynchronizationResult>,
|
|
14
|
+
remove: (entityId: Guid) =>
|
|
15
|
+
Coroutine<Context & CollectionEntity<Collections[k]>, CollectionEntity<Collections[k]>, SynchronizationResult>,
|
|
16
|
+
// reload: () =>
|
|
17
|
+
// Coroutine<Context & Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Unit>,
|
|
18
|
+
wholeMutations:
|
|
19
|
+
{
|
|
20
|
+
[_ in keyof (WholeCollectionMutations[k])]: BasicFun<WholeCollectionMutations[k][_], Coroutine<Context & Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Unit>>
|
|
21
|
+
}
|
|
22
|
+
} &
|
|
23
|
+
{
|
|
24
|
+
[_ in keyof (CollectionMutations[k])]: BasicFun<CollectionMutations[k][_], Coroutine<Context & CollectionEntity<Collections[k]>, CollectionEntity<Collections[k]>, SynchronizationResult>>
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type CollectionLoaders<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {
|
|
29
|
+
[k in (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)]: {
|
|
30
|
+
<mutation extends (keyof CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations>[k]) & (keyof CollectionMutations[k])>(mutation: mutation, mutationArg: CollectionMutations[k][mutation], entityId: Guid):
|
|
31
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>,
|
|
32
|
+
add: (entityId: Guid, entity: CollectionEntity<Collections[k]>, position?: InsertionPosition) =>
|
|
33
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>,
|
|
34
|
+
remove: (entityId: Guid) =>
|
|
35
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>,
|
|
36
|
+
// reload: () =>
|
|
37
|
+
// Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>,
|
|
38
|
+
wholeMutations: <mutation extends (keyof CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations>[k]) & (keyof WholeCollectionMutations[k]) >(mutation: mutation, mutationArg: WholeCollectionMutations[k][mutation]) =>
|
|
39
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>,
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const collectionEntityLoader = <Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>(
|
|
44
|
+
synchronizers: CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations>) =>
|
|
45
|
+
<k extends (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)>(k: k,
|
|
46
|
+
id: BasicFun<Collections[k], Guid>,
|
|
47
|
+
narrowing_k: BasicFun<SynchronizedEntities, Collection<Collections[k]>>,
|
|
48
|
+
widening_k: BasicFun<BasicUpdater<Collection<Collections[k]>>, Updater<SynchronizedEntities>>,
|
|
49
|
+
dependees: Array<Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>>):
|
|
50
|
+
CollectionLoaders<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>[k] =>
|
|
51
|
+
Object.assign(
|
|
52
|
+
<mutation extends (keyof CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations>[k]) & (keyof CollectionMutations[k])>(mutation: mutation, mutationArg: CollectionMutations[k][mutation], entityId: Guid):
|
|
53
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult> => {
|
|
54
|
+
const Co = CoTypedFactory<Context, SynchronizedEntities>();
|
|
55
|
+
return Co.GetState().then(current => {
|
|
56
|
+
const entities = narrowing_k(current).entities
|
|
57
|
+
if (!AsyncState.Operations.hasValue(entities.sync) || !entities.sync.value.get(entityId))
|
|
58
|
+
return Co.Return("completed" as const)
|
|
59
|
+
return (synchronizers[k][mutation](mutationArg as any) as Coroutine<Context & CollectionEntity<Collections[k]>, CollectionEntity<Collections[k]>, SynchronizationResult>)
|
|
60
|
+
.embed<Context & SynchronizedEntities, SynchronizedEntities>(
|
|
61
|
+
_ => {
|
|
62
|
+
const entities = narrowing_k(_).entities
|
|
63
|
+
if (AsyncState.Operations.hasValue(entities.sync)) {
|
|
64
|
+
const entity = entities.sync.value.get(entityId)
|
|
65
|
+
if (entity != undefined)
|
|
66
|
+
return ({ ..._, ...entity })
|
|
67
|
+
}
|
|
68
|
+
return undefined
|
|
69
|
+
},
|
|
70
|
+
Fun(Collection<Collections[k]>().Updaters.Core.entity.set(entityId)).then(widening_k)
|
|
71
|
+
).then(syncResult =>
|
|
72
|
+
Co.All<SynchronizationResult>(dependees).then(syncResults =>
|
|
73
|
+
Co.Return([syncResult, ...syncResults].some(_ => _ == "should be enqueued again") ? "should be enqueued again" : "completed")
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
})
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
add: (entityId: Guid, entity: CollectionEntity<Collections[k]>, position?: InsertionPosition):
|
|
80
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult> => {
|
|
81
|
+
const Co = CoTypedFactory<Context, SynchronizedEntities>();
|
|
82
|
+
const CoColl = CoTypedFactory<Context, Collection<Collections[k]>>();
|
|
83
|
+
return CoColl.SetState(
|
|
84
|
+
_ => {
|
|
85
|
+
// alert("state set?!?")
|
|
86
|
+
// return Collection<Collections[k]>().Updaters.Core.entity.add([entityId, entity, position ?? { kind: "at the end" }])(_)
|
|
87
|
+
return _
|
|
88
|
+
}
|
|
89
|
+
).embed<Context & SynchronizedEntities, SynchronizedEntities>(_ => ({ ..._, ...(narrowing_k(_)) }), widening_k)
|
|
90
|
+
.then(() =>
|
|
91
|
+
synchronizers[k].add(entity).embed<Context & SynchronizedEntities, SynchronizedEntities>(
|
|
92
|
+
_ => {
|
|
93
|
+
const entities = narrowing_k(_).entities
|
|
94
|
+
if (AsyncState.Operations.hasValue(entities.sync)) {
|
|
95
|
+
const entity = entities.sync.value.get(entityId)
|
|
96
|
+
if (entity != undefined)
|
|
97
|
+
return ({ ..._, ...(entity) })
|
|
98
|
+
}
|
|
99
|
+
return undefined
|
|
100
|
+
},
|
|
101
|
+
Fun(Collection<Collections[k]>().Updaters.Core.entity.set(entityId)).then(
|
|
102
|
+
widening_k
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
// )
|
|
106
|
+
// .then(_ =>
|
|
107
|
+
// CoColl.GetState().then(current => {
|
|
108
|
+
// if (!AsyncState.Operations.hasValue(current.entities.sync)) return CoColl.Return(unit)
|
|
109
|
+
// const syncedEntity = current.entities.sync.value.get(entityId)
|
|
110
|
+
// if (!syncedEntity || !AsyncState.Operations.hasValue(syncedEntity.value.value.sync)) return CoColl.Return(unit)
|
|
111
|
+
// if (id(syncedEntity.value.value.sync.value) == entityId) return CoColl.Return(unit)
|
|
112
|
+
// // otherwise, the id has changed (probably overridden by the API), let's save the new id
|
|
113
|
+
// return CoColl.SetState(
|
|
114
|
+
// Collection<Collections[k]>().Updaters.Core.entity.add([id(syncedEntity.value.value.sync.value), syncedEntity, position ?? { kind:"at the end" }]).then(
|
|
115
|
+
// Collection<Collections[k]>().Updaters.Core.entity.remove(entityId)
|
|
116
|
+
// )
|
|
117
|
+
// )
|
|
118
|
+
// }
|
|
119
|
+
// )
|
|
120
|
+
// .embed<Context & SynchronizedEntities, SynchronizedEntities>(_ => ({ ..._, ...(narrowing_k(_)) }), widening_k)
|
|
121
|
+
.then((syncResult) =>
|
|
122
|
+
Co.All<SynchronizationResult>(dependees).then((syncResults) =>
|
|
123
|
+
Co.Return(
|
|
124
|
+
[syncResult, ...syncResults].some(
|
|
125
|
+
(_) => _ == "should be enqueued again"
|
|
126
|
+
)
|
|
127
|
+
? "should be enqueued again"
|
|
128
|
+
: "completed"
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
},
|
|
134
|
+
remove: (entityId: Guid):
|
|
135
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult> => {
|
|
136
|
+
const Co = CoTypedFactory<Context, SynchronizedEntities>();
|
|
137
|
+
const CoColl = CoTypedFactory<Context, Collection<Collections[k]>>();
|
|
138
|
+
return CoColl.SetState(
|
|
139
|
+
// Collection<Collections[k]>().Updaters.Core.entity.remove(entityId)
|
|
140
|
+
Collection<Collections[k]>().Updaters.Core.removed(entityId, replaceWith(true))
|
|
141
|
+
).embed<Context & SynchronizedEntities, SynchronizedEntities>(_ => ({ ..._, ...(narrowing_k(_)) }), widening_k)
|
|
142
|
+
.then(() =>
|
|
143
|
+
synchronizers[k].remove(entityId).embed<Context & SynchronizedEntities, SynchronizedEntities>(
|
|
144
|
+
_ => {
|
|
145
|
+
const entities = narrowing_k(_).entities
|
|
146
|
+
if (AsyncState.Operations.hasValue(entities.sync)) {
|
|
147
|
+
const entity = entities.sync.value.get(entityId)
|
|
148
|
+
if (entity != undefined)
|
|
149
|
+
return ({ ..._, ...(entity) })
|
|
150
|
+
}
|
|
151
|
+
return undefined
|
|
152
|
+
},
|
|
153
|
+
Fun(Collection<Collections[k]>().Updaters.Core.entity.set(entityId)).then(
|
|
154
|
+
widening_k
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
).then((_) =>
|
|
158
|
+
Co.GetState().then(current => {
|
|
159
|
+
const entities = narrowing_k(current).entities
|
|
160
|
+
if (!AsyncState.Operations.hasValue(entities.sync)) return Co.Return<SynchronizationResult>("completed")
|
|
161
|
+
const entity = entities.sync.value.get(entityId)
|
|
162
|
+
if (!entity || entity.value.sync.kind == "error") return Co.Return<SynchronizationResult>("completed")
|
|
163
|
+
return Co.All<SynchronizationResult>(dependees).then((syncResults) =>
|
|
164
|
+
Co.Return(
|
|
165
|
+
syncResults.some(
|
|
166
|
+
(_) => _ == "should be enqueued again"
|
|
167
|
+
)
|
|
168
|
+
? "should be enqueued again"
|
|
169
|
+
: "completed"
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
})
|
|
173
|
+
)
|
|
174
|
+
},
|
|
175
|
+
wholeMutations: <mutation extends (keyof CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations>[k]) & (keyof WholeCollectionMutations[k])>(mutation: mutation, mutationArg: WholeCollectionMutations[k][mutation]):
|
|
176
|
+
Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult> => {
|
|
177
|
+
const Co = CoTypedFactory<Context, SynchronizedEntities>();
|
|
178
|
+
const CoColl = CoTypedFactory<Context, Collection<Collections[k]>>();
|
|
179
|
+
return CoColl.Seq([
|
|
180
|
+
synchronizers[k]["wholeMutations"][mutation](mutationArg).embed(
|
|
181
|
+
_ => ({ ..._, ..._.entities }),
|
|
182
|
+
Collection<Collections[k]>().Updaters.Core.entities,
|
|
183
|
+
)
|
|
184
|
+
])
|
|
185
|
+
.embed<Context & SynchronizedEntities, SynchronizedEntities>(_ => ({ ..._, ...(narrowing_k(_)) }), widening_k)
|
|
186
|
+
.then((syncResult) =>
|
|
187
|
+
Co.All<SynchronizationResult>(dependees).then((syncResults) =>
|
|
188
|
+
Co.Return(
|
|
189
|
+
[syncResult, ...syncResults].some(
|
|
190
|
+
(_) => _ == "should be enqueued again"
|
|
191
|
+
)
|
|
192
|
+
? "should be enqueued again"
|
|
193
|
+
: "completed"
|
|
194
|
+
)
|
|
195
|
+
)
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
export type CollectionDirtySetters<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {
|
|
202
|
+
[k in (keyof Collections) & (keyof CollectionMutations)]:
|
|
203
|
+
(entityId: Guid, dirtyStatus: DirtyStatus) => Coroutine<Context & SynchronizedEntities, SynchronizedEntities, Unit>
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export const collectionDirtySetter = <Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>() =>
|
|
207
|
+
<k extends (keyof Collections) & (keyof CollectionMutations)>(k: k,
|
|
208
|
+
narrowing_k: BasicFun<SynchronizedEntities, Collection<Collections[k]>>,
|
|
209
|
+
widening_k: BasicFun<BasicUpdater<Collection<Collections[k]>>, Updater<SynchronizedEntities>>):
|
|
210
|
+
CollectionDirtySetters<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>[k] =>
|
|
211
|
+
(entityId: Guid, dirtyStatus: DirtyStatus) => {
|
|
212
|
+
const CoEntity = CoTypedFactory<Context, CollectionEntity<Collections[k]>>();
|
|
213
|
+
const Co = CoTypedFactory<Context, SynchronizedEntities>();
|
|
214
|
+
return (CoEntity.SetState(
|
|
215
|
+
CollectionEntity<Collections[k]>().Updaters.Core.entity(
|
|
216
|
+
Entity<Collections[k]>().Updaters.Core.value(
|
|
217
|
+
Debounced.Updaters.Core.dirty(replaceWith<DirtyStatus>(dirtyStatus))
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
).embed<Context & SynchronizedEntities, SynchronizedEntities>(
|
|
222
|
+
_ => {
|
|
223
|
+
const _narrowed = narrowing_k(_)
|
|
224
|
+
const entities = _narrowed.entities
|
|
225
|
+
if (AsyncState.Operations.hasValue(entities.sync)) {
|
|
226
|
+
const entity = entities.sync.value.get(entityId)
|
|
227
|
+
if (entity != undefined)
|
|
228
|
+
return ({ ..._, ...entity })
|
|
229
|
+
}
|
|
230
|
+
return undefined
|
|
231
|
+
},
|
|
232
|
+
Fun(Collection<Collections[k]>().Updaters.Core.entity.set(entityId)).then(widening_k)
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export type CollectionDirtyCheckers<Collections, CollectionMutations, WholeCollectionMutations> = {
|
|
237
|
+
[k in (keyof Collections) & (keyof CollectionMutations)]: Fun<[Guid, Collection<Collections[k]>], boolean>;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export const collectionCheckNotDirty = <Collections, CollectionMutations, WholeCollectionMutations>() => <k extends (keyof Collections) & (keyof CollectionMutations)>([id, e]: [Guid, Collection<Collections[k]>]): boolean => {
|
|
241
|
+
return AsyncState.Operations.hasValue(e.entities.sync) && e.entities.sync.value.get(id)?.value.dirty != "not dirty";
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export type CollectionUpdaters<Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {
|
|
245
|
+
[k in (keyof Collections) & (keyof CollectionMutations)]: Fun<[Guid, BasicUpdater<Collections[k]>], Updater<SynchronizedEntities>>;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export const collectionEntityUpdater = <Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>() => <k extends (keyof Collections) & (keyof CollectionMutations)>(widening_k: BasicFun<BasicUpdater<Collection<Collections[k]>>, Updater<SynchronizedEntities>>): Fun<[Guid, BasicUpdater<Collections[k]>], Updater<SynchronizedEntities>> => Fun(([id, u]) => widening_k(
|
|
249
|
+
Collection<Collections[k]>().Updaters.Template.entityValue(id, u)
|
|
250
|
+
));
|
|
251
|
+
|
|
252
|
+
export type InsertionPosition = { kind: "after", id: Guid } | { kind: "before", id: Guid } | { kind: "at the end" } | { kind: "at the beginning" }
|
|
253
|
+
|
|
254
|
+
export type SynchronizableCollectionEntity<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities, k extends (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)> = {
|
|
255
|
+
entityName: k,
|
|
256
|
+
// default: BasicFun<void, CollectionEntity<Collections[k]>>,
|
|
257
|
+
id: BasicFun<Collections[k], Guid>,
|
|
258
|
+
narrowing: BasicFun<SynchronizedEntities, Collection<Collections[k]>>,
|
|
259
|
+
widening: BasicFun<BasicUpdater<Collection<Collections[k]>>, Updater<SynchronizedEntities>>,
|
|
260
|
+
dependees: Array<Coroutine<Context & SynchronizedEntities, SynchronizedEntities, SynchronizationResult>>,
|
|
261
|
+
add: (entity: CollectionEntity<Collections[k]>, position?: InsertionPosition) =>
|
|
262
|
+
Coroutine<Context & Synchronized<Value<Synchronized<Unit, Collections[k]>>, Unit>, Synchronized<Value<Synchronized<Unit, Collections[k]>>, Unit>, Unit>,
|
|
263
|
+
remove: (entityId: Guid) =>
|
|
264
|
+
Coroutine<Context & Synchronized<Value<Synchronized<Unit, Collections[k]>>, Unit>, Synchronized<Value<Synchronized<Unit, Collections[k]>>, Unit>, Unit>,
|
|
265
|
+
// reload: () =>
|
|
266
|
+
// Coroutine<Context & Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Unit>,
|
|
267
|
+
} & {
|
|
268
|
+
[_ in keyof (CollectionMutations[k])]: BasicFun<CollectionMutations[k][_], Coroutine<Context & Synchronized<Value<Synchronized<Unit, Collections[k]>>, Unit>, Synchronized<Value<Synchronized<Unit, Collections[k]>>, Unit>, Unit>>
|
|
269
|
+
} & {
|
|
270
|
+
wholeMutations:{
|
|
271
|
+
[_ in keyof (WholeCollectionMutations[k])]: BasicFun<WholeCollectionMutations[k][_], Coroutine<Context & Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Synchronized<Unit, OrderedMap<Guid, CollectionEntity<Collections[k]>>>, Unit>>
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export type SynchronizableEntityDescriptor<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {
|
|
276
|
+
[k in (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)]: SynchronizableCollectionEntity<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities, k>
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
export const collectionSynchronizationContext = <Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>(
|
|
281
|
+
entityDescriptors: SynchronizableEntityDescriptor<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>):
|
|
282
|
+
[
|
|
283
|
+
CollectionLoaders<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>,
|
|
284
|
+
CollectionDirtyCheckers<Collections, CollectionMutations, WholeCollectionMutations>,
|
|
285
|
+
CollectionDirtySetters<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>,
|
|
286
|
+
CollectionUpdaters<Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>,
|
|
287
|
+
SynchronizableEntityDescriptor<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>
|
|
288
|
+
] => {
|
|
289
|
+
let synchronizers: CollectionSynchronizers<Context, Collections, CollectionMutations, WholeCollectionMutations> = {} as any
|
|
290
|
+
Object.keys(entityDescriptors).forEach(k_s => {
|
|
291
|
+
const k = k_s as (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)
|
|
292
|
+
synchronizers[k] = {} as any
|
|
293
|
+
Object.keys(entityDescriptors[k]).forEach(field => {
|
|
294
|
+
// only update the mutation fields of the entity descriptor
|
|
295
|
+
if (field != "entityName" && field != "narrowing" && field != "widening" && field != "dependees" && field != "add" && field != "remove" && field != "default" && field != "reload" && field != "reloadElement")
|
|
296
|
+
(synchronizers[k] as any)[field] = (mutationArg: any) => {
|
|
297
|
+
return insideEntitySynchronizedAndDebounced((entityDescriptors[k] as any)[field](mutationArg)) as any
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
(synchronizers[k] as any)["add"] = (entity: CollectionEntity<any>, position?: InsertionPosition) =>
|
|
302
|
+
insideEntitySynchronizedAndDebounced((entityDescriptors[k] as any)["add"](entity, position)) as any
|
|
303
|
+
(synchronizers[k] as any)["remove"] = (entityId: Guid) =>
|
|
304
|
+
insideEntitySynchronizedAndDebounced((entityDescriptors[k] as any)["remove"](entityId)) as any
|
|
305
|
+
(synchronizers[k] as any)["wholeMutations"] = {} as any
|
|
306
|
+
Object.keys(entityDescriptors[k]["wholeMutations"]).forEach(field => {
|
|
307
|
+
(synchronizers[k] as any)["wholeMutations"][field] = (mutationArg:any) => (entityDescriptors[k]["wholeMutations"] as any)[field](mutationArg)
|
|
308
|
+
})
|
|
309
|
+
})
|
|
310
|
+
let loaders: CollectionLoaders<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {} as any
|
|
311
|
+
Object.keys(entityDescriptors).forEach(k_s => {
|
|
312
|
+
const k = k_s as (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)
|
|
313
|
+
loaders[k] = collectionEntityLoader<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>(synchronizers)(k, entityDescriptors[k].id, entityDescriptors[k].narrowing, entityDescriptors[k].widening, entityDescriptors[k].dependees)
|
|
314
|
+
})
|
|
315
|
+
let dirtyCheckers: CollectionDirtyCheckers<Collections, CollectionMutations, WholeCollectionMutations> = {} as any
|
|
316
|
+
Object.keys(entityDescriptors).forEach(k_s => {
|
|
317
|
+
const k = k_s as (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)
|
|
318
|
+
dirtyCheckers[k] = Fun(collectionCheckNotDirty<Collections, CollectionMutations, WholeCollectionMutations>())
|
|
319
|
+
})
|
|
320
|
+
let dirtySetters: CollectionDirtySetters<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {} as any
|
|
321
|
+
Object.keys(entityDescriptors).forEach(k_s => {
|
|
322
|
+
const k = k_s as (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)
|
|
323
|
+
dirtySetters[k] =
|
|
324
|
+
collectionDirtySetter<Context, Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>()
|
|
325
|
+
(k, entityDescriptors[k].narrowing, entityDescriptors[k].widening)
|
|
326
|
+
})
|
|
327
|
+
let updaters: CollectionUpdaters<Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities> = {} as any
|
|
328
|
+
Object.keys(entityDescriptors).forEach(k_s => {
|
|
329
|
+
const k = k_s as (keyof Collections) & (keyof CollectionMutations) & (keyof WholeCollectionMutations)
|
|
330
|
+
updaters[k] = collectionEntityUpdater<Collections, CollectionMutations, WholeCollectionMutations, SynchronizedEntities>()(entityDescriptors[k].widening)
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
return [loaders, dirtyCheckers, dirtySetters, updaters, entityDescriptors]
|
|
334
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Value, AsyncState, BasicUpdater, Debounced, Guid, Synchronized, Updater, mapUpdater, Unit, unit, simpleUpdater, simpleUpdaterWithChildren, OrderedMapRepo, InsertionPosition } from "ballerina-core";
|
|
2
|
+
import { OrderedMap } from "immutable";
|
|
3
|
+
import { Entity } from "../entity/state";
|
|
4
|
+
|
|
5
|
+
export type CollectionEntity<E> = Entity<E> & {
|
|
6
|
+
removed: boolean
|
|
7
|
+
}
|
|
8
|
+
export const CollectionEntity = <E>() => ({
|
|
9
|
+
Default: (value: E): CollectionEntity<E> =>
|
|
10
|
+
Object.assign(Entity<E>().Default(value), { removed: false }),
|
|
11
|
+
Updaters: {
|
|
12
|
+
Core: {
|
|
13
|
+
entity: (_: BasicUpdater<Entity<E>>): Updater<CollectionEntity<E>> =>
|
|
14
|
+
Updater(e => ({
|
|
15
|
+
...(_(e)),
|
|
16
|
+
removed: e.removed
|
|
17
|
+
})),
|
|
18
|
+
removed: (_: BasicUpdater<boolean>): Updater<CollectionEntity<E>> =>
|
|
19
|
+
Updater(e => ({
|
|
20
|
+
...e,
|
|
21
|
+
removed: _(e.removed)
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export type Collection<E> = {
|
|
29
|
+
entities: Synchronized<Unit, OrderedMap<Guid, CollectionEntity<E>>>;
|
|
30
|
+
};
|
|
31
|
+
export const Collection = <E>() => {
|
|
32
|
+
return ({
|
|
33
|
+
Default: (entities: OrderedMap<Guid, CollectionEntity<E>>): Collection<E> => ({
|
|
34
|
+
entities: Synchronized.Default(unit, AsyncState.Default.loaded(entities.map(_ => ({ ..._, removed: false })))),
|
|
35
|
+
}),
|
|
36
|
+
Updaters: {
|
|
37
|
+
Core: {
|
|
38
|
+
...simpleUpdater<Collection<E>>()("entities"),
|
|
39
|
+
// reloader: (u: BasicUpdater<OrderedMap<Guid, CollectionEntity<E>>>): Updater<Collection<E>> =>
|
|
40
|
+
// Collection<E>().Updaters.Core.entities(
|
|
41
|
+
// Synchronized.Updaters.sync(
|
|
42
|
+
// AsyncState.Operations.map(
|
|
43
|
+
// u
|
|
44
|
+
// )
|
|
45
|
+
// )
|
|
46
|
+
// ),
|
|
47
|
+
entity: {
|
|
48
|
+
add: ([id, value, position]: [
|
|
49
|
+
Guid,
|
|
50
|
+
CollectionEntity<E>,
|
|
51
|
+
InsertionPosition
|
|
52
|
+
]): Updater<Collection<E>> =>
|
|
53
|
+
position.kind == "at the end" ?
|
|
54
|
+
Collection<E>().Updaters.Core.entities(
|
|
55
|
+
Synchronized.Updaters.sync(
|
|
56
|
+
AsyncState.Operations.map(
|
|
57
|
+
OrderedMapRepo.Updaters.insertAtEnd(id, value)
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
) :
|
|
61
|
+
position.kind =="at the beginning" ?
|
|
62
|
+
Collection<E>().Updaters.Core.entities(
|
|
63
|
+
Synchronized.Updaters.sync(
|
|
64
|
+
AsyncState.Operations.map(
|
|
65
|
+
OrderedMapRepo.Updaters.insertAtBeginning(id, value)
|
|
66
|
+
)
|
|
67
|
+
)
|
|
68
|
+
) :
|
|
69
|
+
Collection<E>().Updaters.Core.entities(
|
|
70
|
+
Synchronized.Updaters.sync(
|
|
71
|
+
AsyncState.Operations.map(
|
|
72
|
+
OrderedMapRepo.Updaters.insertAt([id, value], position.id, position.kind)
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
),
|
|
76
|
+
remove: (id: Guid): Updater<Collection<E>> =>
|
|
77
|
+
Collection<E>().Updaters.Core.entities(
|
|
78
|
+
Synchronized.Updaters.sync(
|
|
79
|
+
AsyncState.Operations.map(
|
|
80
|
+
OrderedMapRepo.Updaters.remove(id)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
),
|
|
84
|
+
set: (id: Guid) => (u: BasicUpdater<CollectionEntity<E>>): Updater<Collection<E>> =>
|
|
85
|
+
Collection<E>().Updaters.Core.entities(
|
|
86
|
+
Synchronized.Updaters.sync(
|
|
87
|
+
AsyncState.Operations.map(
|
|
88
|
+
OrderedMapRepo.Updaters.update(id, u)
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
),
|
|
92
|
+
// set: Fun<key, Fun<BasicUpdater<value>, Updater<Entity>>>;
|
|
93
|
+
},
|
|
94
|
+
removed: (id: Guid, u: BasicUpdater<boolean>): Updater<Collection<E>> =>
|
|
95
|
+
Collection<E>().Updaters.Core.entity.set(id)(
|
|
96
|
+
CollectionEntity<E>().Updaters.Core.removed(
|
|
97
|
+
u
|
|
98
|
+
)
|
|
99
|
+
),
|
|
100
|
+
entityValue: (id: Guid, u: BasicUpdater<E>): Updater<Collection<E>> =>
|
|
101
|
+
Collection<E>().Updaters.Core.entity.set(id)(
|
|
102
|
+
CollectionEntity<E>().Updaters.Core.entity(
|
|
103
|
+
Entity<E>().Updaters.Core.value(
|
|
104
|
+
Debounced.Updaters.Core.value(
|
|
105
|
+
Synchronized.Updaters.value(
|
|
106
|
+
Value.Updaters.value(
|
|
107
|
+
Synchronized.Updaters.sync(
|
|
108
|
+
AsyncState.Operations.map(u)
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
),
|
|
116
|
+
},
|
|
117
|
+
Template: {
|
|
118
|
+
entityValue: (id: Guid, u: BasicUpdater<E>): Updater<Collection<E>> =>
|
|
119
|
+
Collection<E>().Updaters.Core.entity.set(id)(
|
|
120
|
+
CollectionEntity<E>().Updaters.Core.entity(
|
|
121
|
+
Entity<E>().Updaters.Core.value(
|
|
122
|
+
Debounced.Updaters.Template.value(
|
|
123
|
+
Synchronized.Updaters.value(
|
|
124
|
+
Value.Updaters.value(
|
|
125
|
+
Synchronized.Updaters.sync(
|
|
126
|
+
AsyncState.Operations.map(u)
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
),
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
};
|