create-foldkit-app 0.29.0 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/templates/base/AGENTS.md +5 -112
  2. package/dist/templates/base/FOLDKIT.md +144 -0
  3. package/dist/templates/examples/api-cache/src/main.ts +36 -40
  4. package/dist/templates/examples/auth/src/main.ts +16 -15
  5. package/dist/templates/examples/auth/src/page/loggedIn/update.ts +10 -11
  6. package/dist/templates/examples/auth/src/page/loggedOut/page/login.ts +44 -55
  7. package/dist/templates/examples/auth/src/page/loggedOut/update.ts +8 -12
  8. package/dist/templates/examples/auth/src/update.ts +67 -73
  9. package/dist/templates/examples/canvas-art/src/main.ts +32 -31
  10. package/dist/templates/examples/charting/src/init.test.ts +6 -3
  11. package/dist/templates/examples/charting/src/init.ts +4 -4
  12. package/dist/templates/examples/charting/src/update.ts +34 -38
  13. package/dist/templates/examples/counter/src/main.ts +13 -13
  14. package/dist/templates/examples/counters/src/counter.ts +9 -8
  15. package/dist/templates/examples/counters/src/main.ts +20 -26
  16. package/dist/templates/examples/crash-view/src/main.ts +5 -3
  17. package/dist/templates/examples/embedding/src/main.ts +11 -9
  18. package/dist/templates/examples/form/src/main.ts +79 -89
  19. package/dist/templates/examples/generative-art/src/main.ts +6 -4
  20. package/dist/templates/examples/generative-art/src/update.ts +26 -23
  21. package/dist/templates/examples/interrupting-commands/src/main.ts +68 -66
  22. package/dist/templates/examples/job-application/src/main.ts +3 -4
  23. package/dist/templates/examples/job-application/src/step/attachments.ts +16 -19
  24. package/dist/templates/examples/job-application/src/step/coverLetter.ts +5 -5
  25. package/dist/templates/examples/job-application/src/step/education/education.ts +12 -17
  26. package/dist/templates/examples/job-application/src/step/education/entry.ts +29 -42
  27. package/dist/templates/examples/job-application/src/step/personalInfo.ts +35 -44
  28. package/dist/templates/examples/job-application/src/step/skills/entry.ts +15 -21
  29. package/dist/templates/examples/job-application/src/step/skills/skills.ts +12 -17
  30. package/dist/templates/examples/job-application/src/step/workHistory/entry.ts +41 -58
  31. package/dist/templates/examples/job-application/src/step/workHistory/workHistory.ts +12 -17
  32. package/dist/templates/examples/job-application/src/update.ts +26 -29
  33. package/dist/templates/examples/kanban/src/main.ts +3 -4
  34. package/dist/templates/examples/kanban/src/update.ts +31 -31
  35. package/dist/templates/examples/managed-resource-layer/src/main.ts +30 -34
  36. package/dist/templates/examples/map/src/main.ts +48 -56
  37. package/dist/templates/examples/pixel-art/src/comparison.bench.test.ts +34 -13
  38. package/dist/templates/examples/pixel-art/src/main.bench.ts +3 -3
  39. package/dist/templates/examples/pixel-art/src/main.ts +3 -4
  40. package/dist/templates/examples/pixel-art/src/update.ts +109 -100
  41. package/dist/templates/examples/query-sync/src/main.ts +27 -25
  42. package/dist/templates/examples/route-transitions/src/main.ts +46 -43
  43. package/dist/templates/examples/route-transitions/src/story.test.ts +11 -11
  44. package/dist/templates/examples/routing/src/main.ts +16 -14
  45. package/dist/templates/examples/routing/src/page/people.ts +23 -28
  46. package/dist/templates/examples/shopping-cart/src/main.ts +41 -42
  47. package/dist/templates/examples/shopping-cart/src/page/products.ts +28 -35
  48. package/dist/templates/examples/slow-warnings/src/main.ts +23 -32
  49. package/dist/templates/examples/snake/src/main.ts +135 -143
  50. package/dist/templates/examples/ssg/src/main.ts +20 -17
  51. package/dist/templates/examples/ssr/src/main.ts +20 -24
  52. package/dist/templates/examples/state-machine/src/main.ts +24 -11
  53. package/dist/templates/examples/state-machine/src/story.test.ts +2 -2
  54. package/dist/templates/examples/stopwatch/src/main.ts +42 -50
  55. package/dist/templates/examples/todo/src/main.ts +152 -160
  56. package/dist/templates/examples/ui-showcase/src/main.ts +53 -54
  57. package/dist/templates/examples/ui-showcase/src/scene.test.ts +2 -2
  58. package/dist/templates/examples/ui-showcase/src/story.test.ts +2 -2
  59. package/dist/templates/examples/ui-showcase/src/ui/init.ts +6 -7
  60. package/dist/templates/examples/ui-showcase/src/ui/update.ts +265 -336
  61. package/dist/templates/examples/view-transitions/src/main.ts +18 -17
  62. package/dist/templates/examples/weather/src/main.ts +33 -40
  63. package/dist/templates/examples/web-components/src/main.ts +14 -17
  64. package/dist/templates/examples/websocket-chat/src/main.ts +44 -50
  65. package/dist/templates/release.json +8 -8
  66. package/dist/templates/rendering/ssg/src/main.ts +20 -17
  67. package/dist/templates/rendering/ssr/src/main.ts +20 -24
  68. package/package.json +1 -1
@@ -54,20 +54,17 @@ export const GenerateEntryId = Command.define('GenerateEntryId', {
54
54
 
55
55
  // UPDATE
56
56
 
57
- type UpdateReturn = readonly [Model, ReadonlyArray<Command.Command<Message>>]
58
-
59
57
  const foldEntryOutMessage: (
60
58
  entryId: string,
61
59
  ) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
62
60
  M.type<Entry.OutMessage>().pipe(
63
61
  M.withReturnType<Update.Step<Model, Message>>(),
64
62
  M.tagsExhaustive({
65
- Removed: () => model => [
66
- evo(model, {
63
+ Removed: () => model => ({
64
+ model: evo(model, {
67
65
  entries: Array.filter(entry => entry.id !== entryId),
68
66
  }),
69
- [],
70
- ],
67
+ }),
71
68
  }),
72
69
  )
73
70
 
@@ -85,24 +82,22 @@ const foldEntry = (entryId: string) =>
85
82
  })
86
83
 
87
84
  export const update = (model: Model, message: Message) =>
88
- Message.match<UpdateReturn>(message, {
89
- ClickedAddEntry: () => [model, [GenerateEntryId()]],
85
+ Message.match<Update.Return<Model, Message>>(message, {
86
+ ClickedAddEntry: () => ({ model, commands: [GenerateEntryId()] }),
90
87
 
91
- SucceededGenerateEntryId: ({ entryId }) => [
92
- evo(model, {
88
+ SucceededGenerateEntryId: ({ entryId }) => ({
89
+ model: evo(model, {
93
90
  entries: Array.append(Entry.init(entryId)),
94
91
  }),
95
- [],
96
- ],
92
+ }),
97
93
 
98
- FailedGenerateEntryId: () => [model, []],
94
+ FailedGenerateEntryId: () => ({ model }),
99
95
 
100
- RemovedEntry: ({ entryId }) => [
101
- evo(model, {
96
+ RemovedEntry: ({ entryId }) => ({
97
+ model: evo(model, {
102
98
  entries: Array.filter(entry => entry.id !== entryId),
103
99
  }),
104
- [],
105
- ],
100
+ }),
106
101
 
107
102
  GotEntryMessage: ({ entryId, message }) =>
108
103
  foldEntry(entryId)(model, message),
@@ -1,5 +1,5 @@
1
1
  import { Match as M, Option, Schema as S } from 'effect'
2
- import { Command, Update } from 'foldkit'
2
+ import { Update } from 'foldkit'
3
3
  import {
4
4
  Field,
5
5
  NotValidated,
@@ -87,21 +87,14 @@ export const init = (entryId: string): Model => ({
87
87
 
88
88
  // UPDATE
89
89
 
90
- type UpdateReturn = readonly [
91
- Model,
92
- ReadonlyArray<Command.Command<Message>>,
93
- Option.Option<OutMessage>,
94
- ]
95
-
96
90
  const foldGraduationYearListboxOutMessage = M.type<Listbox.OutMessage>().pipe(
97
91
  M.withReturnType<Update.Step<Model, Message>>(),
98
92
  M.tagsExhaustive({
99
93
  Selected:
100
94
  ({ value }) =>
101
- model => [
102
- evo(model, { maybeGraduationYear: () => Option.some(value) }),
103
- [],
104
- ],
95
+ model => ({
96
+ model: evo(model, { maybeGraduationYear: () => Option.some(value) }),
97
+ }),
105
98
  }),
106
99
  )
107
100
 
@@ -112,41 +105,35 @@ const foldGraduationYearListbox = Update.foldChild({
112
105
  evo(model, { graduationYearListbox: () => nextGraduationYearListbox }),
113
106
  toParentMessage: message =>
114
107
  Message.GotGraduationYearListboxMessage({ message }),
115
- toParentOutMessage: () => Option.none(),
116
108
  foldOutMessage: foldGraduationYearListboxOutMessage,
117
109
  })
118
110
 
119
111
  export const update = (model: Model, message: Message) =>
120
- Message.match<UpdateReturn>(message, {
121
- UpdatedSchool: ({ value }) => [
122
- evo(model, { school: () => validateSchool(value) }),
123
- [],
124
- Option.none(),
125
- ],
126
-
127
- UpdatedDegree: ({ value }) => [
128
- evo(model, { degree: () => validateDegree(value) }),
129
- [],
130
- Option.none(),
131
- ],
132
-
133
- UpdatedFieldOfStudy: ({ value }) => [
134
- evo(model, { fieldOfStudy: () => validateFieldOfStudy(value) }),
135
- [],
136
- Option.none(),
137
- ],
138
-
139
- GotGraduationYearListboxMessage: ({ message }) =>
140
- foldGraduationYearListbox(model, message),
141
-
142
- ToggledCurrentlyEnrolled: ({ isChecked }) => [
143
- evo(model, { isCurrentlyEnrolled: () => isChecked }),
144
- [],
145
- Option.none(),
146
- ],
147
-
148
- ClickedRemoveSelf: () => [model, [], Option.some(OutMessage.Removed())],
149
- })
112
+ Message.match<Update.ReturnWithOutMessage<Model, Message, OutMessage>>(
113
+ message,
114
+ {
115
+ UpdatedSchool: ({ value }) => ({
116
+ model: evo(model, { school: () => validateSchool(value) }),
117
+ }),
118
+
119
+ UpdatedDegree: ({ value }) => ({
120
+ model: evo(model, { degree: () => validateDegree(value) }),
121
+ }),
122
+
123
+ UpdatedFieldOfStudy: ({ value }) => ({
124
+ model: evo(model, { fieldOfStudy: () => validateFieldOfStudy(value) }),
125
+ }),
126
+
127
+ GotGraduationYearListboxMessage: ({ message }) =>
128
+ foldGraduationYearListbox(model, message),
129
+
130
+ ToggledCurrentlyEnrolled: ({ isChecked }) => ({
131
+ model: evo(model, { isCurrentlyEnrolled: () => isChecked }),
132
+ }),
133
+
134
+ ClickedRemoveSelf: () => ({ model, outMessage: OutMessage.Removed() }),
135
+ },
136
+ )
150
137
 
151
138
  // VALIDATION SUMMARY
152
139
 
@@ -162,17 +162,16 @@ export const ValidateEmailAsync = Command.define('ValidateEmailAsync', {
162
162
 
163
163
  // UPDATE
164
164
 
165
- type UpdateReturn = readonly [Model, ReadonlyArray<Command.Command<Message>>]
165
+ type UpdateReturn = Update.Return<Model, Message>
166
166
 
167
167
  const foldPronounsOutMessage = M.type<Listbox.OutMessage>().pipe(
168
168
  M.withReturnType<Update.Step<Model, Message>>(),
169
169
  M.tagsExhaustive({
170
170
  Selected:
171
171
  ({ value }) =>
172
- model => [
173
- evo(model, { maybeSelectedPronoun: () => Option.some(value) }),
174
- [],
175
- ],
172
+ model => ({
173
+ model: evo(model, { maybeSelectedPronoun: () => Option.some(value) }),
174
+ }),
176
175
  }),
177
176
  )
178
177
 
@@ -189,15 +188,13 @@ const foldAvailableDateOutMessage = M.type<DatePicker.OutMessage>().pipe(
189
188
  M.tagsExhaustive({
190
189
  SelectedDate:
191
190
  ({ date }) =>
192
- model => [
193
- evo(model, { maybeAvailableDate: () => Option.some(date) }),
194
- [],
195
- ],
196
- ClearedDate: () => model => [
197
- evo(model, { maybeAvailableDate: () => Option.none() }),
198
- [],
199
- ],
200
- ChangedViewMonth: () => model => [model, []],
191
+ model => ({
192
+ model: evo(model, { maybeAvailableDate: () => Option.some(date) }),
193
+ }),
194
+ ClearedDate: () => model => ({
195
+ model: evo(model, { maybeAvailableDate: () => Option.none() }),
196
+ }),
197
+ ChangedViewMonth: () => model => ({ model }),
201
198
  }),
202
199
  )
203
200
 
@@ -212,63 +209,57 @@ const foldAvailableDate = Update.foldChild({
212
209
 
213
210
  export const update = (model: Model, message: Message) =>
214
211
  Message.match<UpdateReturn>(message, {
215
- UpdatedFirstName: ({ value }) => [
216
- evo(model, { firstName: () => validateFirstName(value) }),
217
- [],
218
- ],
212
+ UpdatedFirstName: ({ value }) => ({
213
+ model: evo(model, { firstName: () => validateFirstName(value) }),
214
+ }),
219
215
 
220
- UpdatedLastName: ({ value }) => [
221
- evo(model, { lastName: () => validateLastName(value) }),
222
- [],
223
- ],
216
+ UpdatedLastName: ({ value }) => ({
217
+ model: evo(model, { lastName: () => validateLastName(value) }),
218
+ }),
224
219
 
225
220
  UpdatedEmail: ({ value }) => {
226
221
  const validationId = Number.increment(model.emailValidationId)
227
222
  return M.value(validateEmail(value)).pipe(
228
223
  M.withReturnType<UpdateReturn>(),
229
- M.tag('Valid', () => [
230
- evo(model, {
224
+ M.tag('Valid', () => ({
225
+ model: evo(model, {
231
226
  email: () => Validating({ value }),
232
227
  emailValidationId: () => validationId,
233
228
  }),
234
- [ValidateEmailAsync({ emailInput: value, validationId })],
235
- ]),
236
- M.orElse(syncResult => [
237
- evo(model, {
229
+ commands: [ValidateEmailAsync({ emailInput: value, validationId })],
230
+ })),
231
+ M.orElse(syncResult => ({
232
+ model: evo(model, {
238
233
  email: () => syncResult,
239
234
  emailValidationId: () => validationId,
240
235
  }),
241
- [],
242
- ]),
236
+ })),
243
237
  )
244
238
  },
245
239
 
246
240
  CompletedValidateEmailAsync: ({ validationId, field }) => {
247
241
  if (validationId === model.emailValidationId) {
248
- return [evo(model, { email: () => field }), []]
242
+ return { model: evo(model, { email: () => field }) }
249
243
  } else {
250
- return [model, []]
244
+ return { model }
251
245
  }
252
246
  },
253
247
 
254
- UpdatedPhone: ({ value }) => [
255
- evo(model, { phone: () => validatePhone(value) }),
256
- [],
257
- ],
248
+ UpdatedPhone: ({ value }) => ({
249
+ model: evo(model, { phone: () => validatePhone(value) }),
250
+ }),
258
251
 
259
252
  GotPronounsMessage: ({ message }) => foldPronouns(model, message),
260
253
 
261
- UpdatedCustomPronouns: ({ value }) => [
262
- evo(model, { customPronouns: () => value }),
263
- [],
264
- ],
254
+ UpdatedCustomPronouns: ({ value }) => ({
255
+ model: evo(model, { customPronouns: () => value }),
256
+ }),
265
257
 
266
- UpdatedPortfolioUrl: ({ value }) => [
267
- evo(model, {
258
+ UpdatedPortfolioUrl: ({ value }) => ({
259
+ model: evo(model, {
268
260
  portfolioUrl: () => validatePortfolioUrl(value),
269
261
  }),
270
- [],
271
- ],
262
+ }),
272
263
 
273
264
  GotAvailableDateMessage: ({ message }) => foldAvailableDate(model, message),
274
265
  })
@@ -1,5 +1,5 @@
1
1
  import { Match as M, Option, Schema as S } from 'effect'
2
- import { Command, Update } from 'foldkit'
2
+ import { Update } from 'foldkit'
3
3
  import {
4
4
  Field,
5
5
  NotValidated,
@@ -73,12 +73,6 @@ export const init = (entryId: string): Model => ({
73
73
 
74
74
  // UPDATE
75
75
 
76
- type UpdateReturn = readonly [
77
- Model,
78
- ReadonlyArray<Command.Command<Message>>,
79
- Option.Option<OutMessage>,
80
- ]
81
-
82
76
  const foldProficiencyRadioGroupOutMessage = M.type<
83
77
  RadioGroup.OutMessage<ProficiencyLevel.ProficiencyLevel>
84
78
  >().pipe(
@@ -86,7 +80,7 @@ const foldProficiencyRadioGroupOutMessage = M.type<
86
80
  M.tagsExhaustive({
87
81
  Selected:
88
82
  ({ value }) =>
89
- model => [evo(model, { proficiency: () => value }), []],
83
+ model => ({ model: evo(model, { proficiency: () => value }) }),
90
84
  }),
91
85
  )
92
86
 
@@ -98,22 +92,22 @@ const foldProficiencyRadioGroup = Update.foldChild({
98
92
  toParentMessage: message =>
99
93
  Message.GotProficiencyRadioGroupMessage({ message }),
100
94
  foldOutMessage: foldProficiencyRadioGroupOutMessage,
101
- toParentOutMessage: () => Option.none(),
102
95
  })
103
96
 
104
97
  export const update = (model: Model, message: Message) =>
105
- Message.match<UpdateReturn>(message, {
106
- UpdatedName: ({ value }) => [
107
- evo(model, { name: () => validateName(value) }),
108
- [],
109
- Option.none(),
110
- ],
111
-
112
- GotProficiencyRadioGroupMessage: ({ message }) =>
113
- foldProficiencyRadioGroup(model, message),
114
-
115
- ClickedRemoveSelf: () => [model, [], Option.some(OutMessage.Removed())],
116
- })
98
+ Message.match<Update.ReturnWithOutMessage<Model, Message, OutMessage>>(
99
+ message,
100
+ {
101
+ UpdatedName: ({ value }) => ({
102
+ model: evo(model, { name: () => validateName(value) }),
103
+ }),
104
+
105
+ GotProficiencyRadioGroupMessage: ({ message }) =>
106
+ foldProficiencyRadioGroup(model, message),
107
+
108
+ ClickedRemoveSelf: () => ({ model, outMessage: OutMessage.Removed() }),
109
+ },
110
+ )
117
111
 
118
112
  // VALIDATION SUMMARY
119
113
 
@@ -51,20 +51,17 @@ export const GenerateEntryId = Command.define('GenerateEntryId', {
51
51
 
52
52
  // UPDATE
53
53
 
54
- type UpdateReturn = readonly [Model, ReadonlyArray<Command.Command<Message>>]
55
-
56
54
  const foldEntryOutMessage: (
57
55
  entryId: string,
58
56
  ) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
59
57
  M.type<Entry.OutMessage>().pipe(
60
58
  M.withReturnType<Update.Step<Model, Message>>(),
61
59
  M.tagsExhaustive({
62
- Removed: () => model => [
63
- evo(model, {
60
+ Removed: () => model => ({
61
+ model: evo(model, {
64
62
  entries: Array.filter(entry => entry.id !== entryId),
65
63
  }),
66
- [],
67
- ],
64
+ }),
68
65
  }),
69
66
  )
70
67
 
@@ -82,24 +79,22 @@ const foldEntry = (entryId: string) =>
82
79
  })
83
80
 
84
81
  export const update = (model: Model, message: Message) =>
85
- Message.match<UpdateReturn>(message, {
86
- ClickedAddEntry: () => [model, [GenerateEntryId()]],
82
+ Message.match<Update.Return<Model, Message>>(message, {
83
+ ClickedAddEntry: () => ({ model, commands: [GenerateEntryId()] }),
87
84
 
88
- SucceededGenerateEntryId: ({ entryId }) => [
89
- evo(model, {
85
+ SucceededGenerateEntryId: ({ entryId }) => ({
86
+ model: evo(model, {
90
87
  entries: Array.append(Entry.init(entryId)),
91
88
  }),
92
- [],
93
- ],
89
+ }),
94
90
 
95
- FailedGenerateEntryId: () => [model, []],
91
+ FailedGenerateEntryId: () => ({ model }),
96
92
 
97
- RemovedEntry: ({ entryId }) => [
98
- evo(model, {
93
+ RemovedEntry: ({ entryId }) => ({
94
+ model: evo(model, {
99
95
  entries: Array.filter(entry => entry.id !== entryId),
100
96
  }),
101
- [],
102
- ],
97
+ }),
103
98
 
104
99
  GotEntryMessage: ({ entryId, message }) =>
105
100
  foldEntry(entryId)(model, message),
@@ -1,5 +1,5 @@
1
1
  import { Match as M, Option, Schema as S } from 'effect'
2
- import { Command, Update } from 'foldkit'
2
+ import { Update } from 'foldkit'
3
3
  import { CalendarDate } from 'foldkit/calendar'
4
4
  import {
5
5
  Field,
@@ -84,32 +84,24 @@ export const init = (entryId: string, today: CalendarDate): Model => ({
84
84
 
85
85
  // UPDATE
86
86
 
87
- type UpdateReturn = readonly [
88
- Model,
89
- ReadonlyArray<Command.Command<Message>>,
90
- Option.Option<OutMessage>,
91
- ]
92
-
93
87
  const foldStartDateOutMessage = M.type<DatePicker.OutMessage>().pipe(
94
88
  M.withReturnType<Update.Step<Model, Message>>(),
95
89
  M.tagsExhaustive({
96
- ChangedViewMonth: () => model => [model, []],
90
+ ChangedViewMonth: () => model => ({ model }),
97
91
  SelectedDate:
98
92
  ({ date }) =>
99
- model => [
100
- evo(model, {
93
+ model => ({
94
+ model: evo(model, {
101
95
  maybeStartDate: () => Option.some(date),
102
96
  endDate: DatePicker.reflectMinDate(Option.some(date)),
103
97
  }),
104
- [],
105
- ],
106
- ClearedDate: () => model => [
107
- evo(model, {
98
+ }),
99
+ ClearedDate: () => model => ({
100
+ model: evo(model, {
108
101
  maybeStartDate: () => Option.none(),
109
102
  endDate: DatePicker.reflectMinDate(Option.none()),
110
103
  }),
111
- [],
112
- ],
104
+ }),
113
105
  }),
114
106
  )
115
107
 
@@ -119,30 +111,27 @@ const foldStartDate = Update.foldChild({
119
111
  write: (model, nextStartDate) =>
120
112
  evo(model, { startDate: () => nextStartDate }),
121
113
  toParentMessage: message => Message.GotStartDateMessage({ message }),
122
- toParentOutMessage: () => Option.none(),
123
114
  foldOutMessage: foldStartDateOutMessage,
124
115
  })
125
116
 
126
117
  const foldEndDateOutMessage = M.type<DatePicker.OutMessage>().pipe(
127
118
  M.withReturnType<Update.Step<Model, Message>>(),
128
119
  M.tagsExhaustive({
129
- ChangedViewMonth: () => model => [model, []],
120
+ ChangedViewMonth: () => model => ({ model }),
130
121
  SelectedDate:
131
122
  ({ date }) =>
132
- model => [
133
- evo(model, {
123
+ model => ({
124
+ model: evo(model, {
134
125
  maybeEndDate: () => Option.some(date),
135
126
  startDate: DatePicker.reflectMaxDate(Option.some(date)),
136
127
  }),
137
- [],
138
- ],
139
- ClearedDate: () => model => [
140
- evo(model, {
128
+ }),
129
+ ClearedDate: () => model => ({
130
+ model: evo(model, {
141
131
  maybeEndDate: () => Option.none(),
142
132
  startDate: DatePicker.reflectMaxDate(Option.none()),
143
133
  }),
144
- [],
145
- ],
134
+ }),
146
135
  }),
147
136
  )
148
137
 
@@ -151,42 +140,36 @@ const foldEndDate = Update.foldChild({
151
140
  read: (model: Model) => Option.some(model.endDate),
152
141
  write: (model, nextEndDate) => evo(model, { endDate: () => nextEndDate }),
153
142
  toParentMessage: message => Message.GotEndDateMessage({ message }),
154
- toParentOutMessage: () => Option.none(),
155
143
  foldOutMessage: foldEndDateOutMessage,
156
144
  })
157
145
 
158
146
  export const update = (model: Model, message: Message) =>
159
- Message.match<UpdateReturn>(message, {
160
- UpdatedCompany: ({ value }) => [
161
- evo(model, { company: () => validateCompany(value) }),
162
- [],
163
- Option.none(),
164
- ],
165
-
166
- UpdatedTitle: ({ value }) => [
167
- evo(model, { title: () => validateTitle(value) }),
168
- [],
169
- Option.none(),
170
- ],
171
-
172
- GotStartDateMessage: ({ message }) => foldStartDate(model, message),
173
-
174
- GotEndDateMessage: ({ message }) => foldEndDate(model, message),
175
-
176
- ToggledCurrentlyEmployed: ({ isChecked }) => [
177
- evo(model, { isCurrentlyEmployed: () => isChecked }),
178
- [],
179
- Option.none(),
180
- ],
181
-
182
- UpdatedDescription: ({ value }) => [
183
- evo(model, { description: () => value }),
184
- [],
185
- Option.none(),
186
- ],
187
-
188
- ClickedRemoveSelf: () => [model, [], Option.some(OutMessage.Removed())],
189
- })
147
+ Message.match<Update.ReturnWithOutMessage<Model, Message, OutMessage>>(
148
+ message,
149
+ {
150
+ UpdatedCompany: ({ value }) => ({
151
+ model: evo(model, { company: () => validateCompany(value) }),
152
+ }),
153
+
154
+ UpdatedTitle: ({ value }) => ({
155
+ model: evo(model, { title: () => validateTitle(value) }),
156
+ }),
157
+
158
+ GotStartDateMessage: ({ message }) => foldStartDate(model, message),
159
+
160
+ GotEndDateMessage: ({ message }) => foldEndDate(model, message),
161
+
162
+ ToggledCurrentlyEmployed: ({ isChecked }) => ({
163
+ model: evo(model, { isCurrentlyEmployed: () => isChecked }),
164
+ }),
165
+
166
+ UpdatedDescription: ({ value }) => ({
167
+ model: evo(model, { description: () => value }),
168
+ }),
169
+
170
+ ClickedRemoveSelf: () => ({ model, outMessage: OutMessage.Removed() }),
171
+ },
172
+ )
190
173
 
191
174
  // VALIDATION SUMMARY
192
175
 
@@ -54,20 +54,17 @@ export const GenerateEntryId = Command.define('GenerateEntryId', {
54
54
 
55
55
  // UPDATE
56
56
 
57
- type UpdateReturn = readonly [Model, ReadonlyArray<Command.Command<Message>>]
58
-
59
57
  const foldEntryOutMessage: (
60
58
  entryId: string,
61
59
  ) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
62
60
  M.type<Entry.OutMessage>().pipe(
63
61
  M.withReturnType<Update.Step<Model, Message>>(),
64
62
  M.tagsExhaustive({
65
- Removed: () => model => [
66
- evo(model, {
63
+ Removed: () => model => ({
64
+ model: evo(model, {
67
65
  entries: Array.filter(entry => entry.id !== entryId),
68
66
  }),
69
- [],
70
- ],
67
+ }),
71
68
  }),
72
69
  )
73
70
 
@@ -85,24 +82,22 @@ const foldEntry = (entryId: string) =>
85
82
  })
86
83
 
87
84
  export const update = (model: Model, message: Message) =>
88
- Message.match<UpdateReturn>(message, {
89
- ClickedAddEntry: () => [model, [GenerateEntryId()]],
85
+ Message.match<Update.Return<Model, Message>>(message, {
86
+ ClickedAddEntry: () => ({ model, commands: [GenerateEntryId()] }),
90
87
 
91
- SucceededGenerateEntryId: ({ entryId }) => [
92
- evo(model, {
88
+ SucceededGenerateEntryId: ({ entryId }) => ({
89
+ model: evo(model, {
93
90
  entries: Array.append(Entry.init(entryId, model.today)),
94
91
  }),
95
- [],
96
- ],
92
+ }),
97
93
 
98
- FailedGenerateEntryId: () => [model, []],
94
+ FailedGenerateEntryId: () => ({ model }),
99
95
 
100
- RemovedEntry: ({ entryId }) => [
101
- evo(model, {
96
+ RemovedEntry: ({ entryId }) => ({
97
+ model: evo(model, {
102
98
  entries: Array.filter(entry => entry.id !== entryId),
103
99
  }),
104
- [],
105
- ],
100
+ }),
106
101
 
107
102
  GotEntryMessage: ({ entryId, message }) =>
108
103
  foldEntry(entryId)(model, message),