create-foldkit-app 0.35.1 → 0.35.2

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 (134) hide show
  1. package/dist/templates/base/FOLDKIT.md +2 -2
  2. package/dist/templates/examples/api-cache/package.json +2 -2
  3. package/dist/templates/examples/api-cache/src/main.fixture.ts +4 -4
  4. package/dist/templates/examples/api-cache/src/main.ts +12 -12
  5. package/dist/templates/examples/api-cache/src/story.test.ts +6 -6
  6. package/dist/templates/examples/auth/package.json +2 -2
  7. package/dist/templates/examples/auth/src/page/loggedOut/page/login.scene.test.ts +2 -2
  8. package/dist/templates/examples/auth/src/page/loggedOut/page/login.story.test.ts +2 -2
  9. package/dist/templates/examples/auth/src/page/loggedOut/page/login.ts +5 -5
  10. package/dist/templates/examples/auth/src/page/loggedOut/update.ts +2 -2
  11. package/dist/templates/examples/auth/src/scene.test.ts +2 -2
  12. package/dist/templates/examples/auth/src/update.ts +3 -3
  13. package/dist/templates/examples/canvas-art/package.json +2 -2
  14. package/dist/templates/examples/canvas-art/src/main.ts +6 -6
  15. package/dist/templates/examples/canvas-art/src/scene.test.ts +3 -3
  16. package/dist/templates/examples/canvas-art/src/story.test.ts +3 -3
  17. package/dist/templates/examples/charting/package.json +2 -2
  18. package/dist/templates/examples/charting/src/main.fixture.ts +2 -2
  19. package/dist/templates/examples/charting/src/scene.test.ts +3 -3
  20. package/dist/templates/examples/charting/src/story.test.ts +2 -2
  21. package/dist/templates/examples/charting/src/update.ts +18 -16
  22. package/dist/templates/examples/counter/package.json +2 -2
  23. package/dist/templates/examples/counter/src/main.ts +4 -4
  24. package/dist/templates/examples/counters/package.json +2 -2
  25. package/dist/templates/examples/counters/src/counter.ts +3 -3
  26. package/dist/templates/examples/counters/src/main.ts +7 -5
  27. package/dist/templates/examples/crash-view/package.json +2 -2
  28. package/dist/templates/examples/embedding/package.json +2 -2
  29. package/dist/templates/examples/embedding/src/main.ts +5 -3
  30. package/dist/templates/examples/embedding/src/scene.test.ts +2 -2
  31. package/dist/templates/examples/embedding/src/story.test.ts +2 -2
  32. package/dist/templates/examples/form/package.json +2 -2
  33. package/dist/templates/examples/form/src/main.ts +9 -9
  34. package/dist/templates/examples/form/src/scene.test.ts +5 -5
  35. package/dist/templates/examples/form/src/story.test.ts +4 -4
  36. package/dist/templates/examples/generative-art/package.json +2 -2
  37. package/dist/templates/examples/generative-art/src/scene.test.ts +2 -2
  38. package/dist/templates/examples/generative-art/src/story.test.ts +3 -3
  39. package/dist/templates/examples/generative-art/src/update.ts +11 -11
  40. package/dist/templates/examples/interrupting-commands/package.json +2 -2
  41. package/dist/templates/examples/interrupting-commands/src/main.ts +8 -6
  42. package/dist/templates/examples/job-application/package.json +2 -2
  43. package/dist/templates/examples/job-application/src/main.fixture.ts +9 -9
  44. package/dist/templates/examples/job-application/src/scene.test.ts +13 -13
  45. package/dist/templates/examples/job-application/src/step/attachments/attachments.ts +7 -7
  46. package/dist/templates/examples/job-application/src/step/coverLetter/coverLetter.ts +2 -2
  47. package/dist/templates/examples/job-application/src/step/education/education.ts +6 -6
  48. package/dist/templates/examples/job-application/src/step/education/entry/entry.ts +14 -8
  49. package/dist/templates/examples/job-application/src/step/personalInfo/personalInfo.ts +20 -15
  50. package/dist/templates/examples/job-application/src/step/personalInfo/story.test.ts +2 -2
  51. package/dist/templates/examples/job-application/src/step/skills/entry/entry.ts +7 -5
  52. package/dist/templates/examples/job-application/src/step/skills/skills.ts +6 -6
  53. package/dist/templates/examples/job-application/src/step/workHistory/entry/entry.ts +13 -12
  54. package/dist/templates/examples/job-application/src/step/workHistory/workHistory.ts +6 -6
  55. package/dist/templates/examples/job-application/src/story.test.ts +10 -10
  56. package/dist/templates/examples/job-application/src/update.ts +25 -18
  57. package/dist/templates/examples/kanban/package.json +2 -2
  58. package/dist/templates/examples/kanban/src/domain/column.ts +9 -6
  59. package/dist/templates/examples/kanban/src/update.ts +8 -8
  60. package/dist/templates/examples/managed-resource-layer/package.json +2 -2
  61. package/dist/templates/examples/managed-resource-layer/src/main.ts +11 -7
  62. package/dist/templates/examples/managed-resource-layer/src/story.test.ts +3 -3
  63. package/dist/templates/examples/map/package.json +2 -2
  64. package/dist/templates/examples/map/src/main.fixture.ts +2 -2
  65. package/dist/templates/examples/map/src/main.ts +11 -11
  66. package/dist/templates/examples/map/src/scene.test.ts +4 -4
  67. package/dist/templates/examples/map/src/story.test.ts +4 -4
  68. package/dist/templates/examples/pixel-art/package.json +2 -2
  69. package/dist/templates/examples/pixel-art/src/comparison.bench.test.ts +2 -2
  70. package/dist/templates/examples/pixel-art/src/main.bench.ts +7 -3
  71. package/dist/templates/examples/pixel-art/src/scene.test.ts +5 -5
  72. package/dist/templates/examples/pixel-art/src/story.test.ts +4 -4
  73. package/dist/templates/examples/pixel-art/src/subscription.ts +2 -2
  74. package/dist/templates/examples/pixel-art/src/update.ts +49 -33
  75. package/dist/templates/examples/query-sync/package.json +2 -2
  76. package/dist/templates/examples/query-sync/src/main.ts +4 -4
  77. package/dist/templates/examples/query-sync/src/scene.test.ts +4 -4
  78. package/dist/templates/examples/query-sync/src/story.test.ts +2 -2
  79. package/dist/templates/examples/route-transitions/package.json +2 -2
  80. package/dist/templates/examples/route-transitions/src/main.ts +10 -10
  81. package/dist/templates/examples/route-transitions/src/story.test.ts +10 -6
  82. package/dist/templates/examples/routing/package.json +2 -2
  83. package/dist/templates/examples/routing/src/main.ts +13 -17
  84. package/dist/templates/examples/routing/src/page/people.ts +4 -4
  85. package/dist/templates/examples/shopping-cart/package.json +2 -2
  86. package/dist/templates/examples/shopping-cart/src/domain/cart.ts +4 -4
  87. package/dist/templates/examples/shopping-cart/src/main.ts +12 -12
  88. package/dist/templates/examples/shopping-cart/src/page/products.ts +2 -2
  89. package/dist/templates/examples/shopping-cart/src/scene.test.ts +10 -8
  90. package/dist/templates/examples/shopping-cart/src/story.test.ts +7 -7
  91. package/dist/templates/examples/slow-warnings/package.json +2 -2
  92. package/dist/templates/examples/slow-warnings/src/handleSlow.test.ts +2 -2
  93. package/dist/templates/examples/slow-warnings/src/main.ts +8 -8
  94. package/dist/templates/examples/slow-warnings/src/scene.test.ts +2 -2
  95. package/dist/templates/examples/slow-warnings/src/story.test.ts +2 -2
  96. package/dist/templates/examples/snake/package.json +2 -2
  97. package/dist/templates/examples/snake/src/main.ts +10 -10
  98. package/dist/templates/examples/snake/src/scene.test.ts +10 -5
  99. package/dist/templates/examples/snake/src/story.test.ts +6 -6
  100. package/dist/templates/examples/ssg/package.json +2 -2
  101. package/dist/templates/examples/ssg/src/main.ts +3 -3
  102. package/dist/templates/examples/ssr/package.json +4 -4
  103. package/dist/templates/examples/ssr/src/main.ts +3 -3
  104. package/dist/templates/examples/state-machine/package.json +2 -2
  105. package/dist/templates/examples/state-machine/src/main.ts +14 -10
  106. package/dist/templates/examples/stopwatch/package.json +2 -2
  107. package/dist/templates/examples/stopwatch/src/main.ts +5 -5
  108. package/dist/templates/examples/stopwatch/src/story.test.ts +2 -2
  109. package/dist/templates/examples/todo/package.json +2 -2
  110. package/dist/templates/examples/todo/src/main.ts +17 -17
  111. package/dist/templates/examples/todo/src/scene.test.ts +4 -4
  112. package/dist/templates/examples/todo/src/story.test.ts +22 -16
  113. package/dist/templates/examples/ui-showcase/package.json +2 -2
  114. package/dist/templates/examples/ui-showcase/src/main.ts +8 -5
  115. package/dist/templates/examples/ui-showcase/src/story.test.ts +3 -3
  116. package/dist/templates/examples/ui-showcase/src/ui/init.ts +4 -1
  117. package/dist/templates/examples/ui-showcase/src/ui/subscriptions.ts +10 -0
  118. package/dist/templates/examples/ui-showcase/src/ui/update.ts +119 -91
  119. package/dist/templates/examples/ui-showcase/src/ui/view/toast.ts +20 -3
  120. package/dist/templates/examples/view-transitions/package.json +2 -2
  121. package/dist/templates/examples/view-transitions/src/main.ts +3 -3
  122. package/dist/templates/examples/weather/package.json +2 -2
  123. package/dist/templates/examples/weather/src/main.ts +5 -5
  124. package/dist/templates/examples/web-components/package.json +2 -2
  125. package/dist/templates/examples/web-components/src/main.ts +4 -4
  126. package/dist/templates/examples/websocket-chat/package.json +2 -2
  127. package/dist/templates/examples/websocket-chat/src/main.ts +8 -8
  128. package/dist/templates/examples/websocket-chat/src/scene.test.ts +18 -6
  129. package/dist/templates/examples/websocket-chat/src/story.test.ts +15 -9
  130. package/dist/templates/release.json +13 -13
  131. package/dist/templates/rendering/ssg/src/main.ts +3 -3
  132. package/dist/templates/rendering/ssr/scripts/serve.ts +2 -2
  133. package/dist/templates/rendering/ssr/src/main.ts +3 -3
  134. package/package.json +5 -5
@@ -12,7 +12,7 @@ import {
12
12
  import { Command, Runtime, type Update } from 'foldkit'
13
13
  import { Document, Html, HtmlBuilder } from 'foldkit/html'
14
14
  import { defineMessageUnion } from 'foldkit/message'
15
- import { evo } from 'foldkit/struct'
15
+ import { modifyFields } from 'foldkit/struct'
16
16
 
17
17
  // MODEL
18
18
 
@@ -115,7 +115,9 @@ export const CancelUploadFile = ({ uploadId }: UploadKey) =>
115
115
 
116
116
  const setStatusForId = (uploadId: number, status: UploadStatus) =>
117
117
  Array.map((upload: Upload) =>
118
- upload.id === uploadId ? evo(upload, { status: () => status }) : upload,
118
+ upload.id === uploadId
119
+ ? modifyFields(upload, { status: () => status })
120
+ : upload,
119
121
  )
120
122
 
121
123
  type UpdateReturn = Update.Return<Model, Message>
@@ -131,7 +133,7 @@ export const update = (model: Model, message: Message) =>
131
133
  status: 'Uploading',
132
134
  })
133
135
  return {
134
- model: evo(model, {
136
+ model: modifyFields(model, {
135
137
  uploadId: Number.increment,
136
138
  uploads: Array.append(startedUpload),
137
139
  }),
@@ -169,7 +171,7 @@ export const update = (model: Model, message: Message) =>
169
171
  Option.match({
170
172
  onNone: () => ({ model }),
171
173
  onSome: upload => ({
172
- model: evo(model, {
174
+ model: modifyFields(model, {
173
175
  uploads: setStatusForId(uploadId, 'Uploading'),
174
176
  }),
175
177
  commands: [
@@ -180,13 +182,13 @@ export const update = (model: Model, message: Message) =>
180
182
  ),
181
183
 
182
184
  SucceededUploadFile: ({ uploadId }) => ({
183
- model: evo(model, { uploads: setStatusForId(uploadId, 'Done') }),
185
+ model: modifyFields(model, { uploads: setStatusForId(uploadId, 'Done') }),
184
186
  }),
185
187
 
186
188
  CompletedCancelUploadFile: ({ uploadId, outcome }) =>
187
189
  Command.Interruptible.Outcome.match<UpdateReturn>(outcome, {
188
190
  Interrupted: () => ({
189
- model: evo(model, {
191
+ model: modifyFields(model, {
190
192
  uploads: setStatusForId(uploadId, 'Cancelled'),
191
193
  }),
192
194
  }),
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.115",
12
+ "@effect/platform-browser": "4.0.0-rc.116",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.115",
15
+ "effect": "4.0.0-rc.116",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -1,7 +1,7 @@
1
1
  import { Array } from 'effect'
2
2
  import { Calendar } from 'foldkit'
3
3
  import { Valid } from 'foldkit/fieldValidation'
4
- import { evo } from 'foldkit/struct'
4
+ import { modifyFields } from 'foldkit/struct'
5
5
 
6
6
  import { Menu, Tabs } from '@foldkit/ui'
7
7
 
@@ -32,26 +32,26 @@ export const initialModel: Model = {
32
32
  isSubmitAttempted: false,
33
33
  }
34
34
 
35
- export const completeModel: Model = evo(initialModel, {
35
+ export const completeModel: Model = modifyFields(initialModel, {
36
36
  personalInfo: personalInfo =>
37
- evo(personalInfo, {
37
+ modifyFields(personalInfo, {
38
38
  firstName: () => Valid({ value: 'Jane' }),
39
39
  lastName: () => Valid({ value: 'Doe' }),
40
40
  email: () => Valid({ value: 'jane@example.com' }),
41
41
  }),
42
42
  workHistory: workHistory =>
43
- evo(workHistory, {
43
+ modifyFields(workHistory, {
44
44
  entries: Array.map(entry =>
45
- evo(entry, {
45
+ modifyFields(entry, {
46
46
  company: () => Valid({ value: 'Foldkit' }),
47
47
  title: () => Valid({ value: 'Engineer' }),
48
48
  }),
49
49
  ),
50
50
  }),
51
51
  education: education =>
52
- evo(education, {
52
+ modifyFields(education, {
53
53
  entries: Array.map(entry =>
54
- evo(entry, {
54
+ modifyFields(entry, {
55
55
  school: () => Valid({ value: 'MIT' }),
56
56
  degree: () => Valid({ value: 'BS' }),
57
57
  fieldOfStudy: () => Valid({ value: 'CS' }),
@@ -59,9 +59,9 @@ export const completeModel: Model = evo(initialModel, {
59
59
  ),
60
60
  }),
61
61
  skills: skills =>
62
- evo(skills, {
62
+ modifyFields(skills, {
63
63
  entries: Array.map(entry =>
64
- evo(entry, {
64
+ modifyFields(entry, {
65
65
  name: () => Valid({ value: 'TypeScript' }),
66
66
  }),
67
67
  ),
@@ -9,7 +9,7 @@ import {
9
9
  scene,
10
10
  text,
11
11
  } from 'foldkit/scene'
12
- import { evo } from 'foldkit/struct'
12
+ import { modifyFields } from 'foldkit/struct'
13
13
  import { describe, test } from 'vitest'
14
14
 
15
15
  import { Tabs } from '@foldkit/ui'
@@ -78,7 +78,7 @@ describe('view', () => {
78
78
  test('Previous on a later step returns to the prior step', () => {
79
79
  scene(
80
80
  { update, view },
81
- given(evo(initialModel, { currentStep: () => 'Education' })),
81
+ given(modifyFields(initialModel, { currentStep: () => 'Education' })),
82
82
  expect(role('heading', { name: 'Education' })).toExist(),
83
83
  click(role('button', { name: '← Previous' })),
84
84
  expect(role('heading', { name: 'Work History' })).toExist(),
@@ -96,7 +96,7 @@ describe('view', () => {
96
96
  test('the Review step exposes a Submit button and hides Next', () => {
97
97
  scene(
98
98
  { update, view },
99
- given(evo(initialModel, { currentStep: () => 'Review' })),
99
+ given(modifyFields(initialModel, { currentStep: () => 'Review' })),
100
100
  expect(role('button', { name: 'Submit Application' })).toExist(),
101
101
  expect(role('button', { name: 'Next →' })).toBeAbsent(),
102
102
  )
@@ -105,7 +105,7 @@ describe('view', () => {
105
105
  test('clicking Submit on an incomplete application shows a blocking notice', () => {
106
106
  scene(
107
107
  { update, view },
108
- given(evo(initialModel, { currentStep: () => 'Review' })),
108
+ given(modifyFields(initialModel, { currentStep: () => 'Review' })),
109
109
  expect(role('button', { name: 'Submit Application' })).toBeEnabled(),
110
110
  expect(
111
111
  text(
@@ -125,9 +125,9 @@ describe('view', () => {
125
125
  scene(
126
126
  { update, view },
127
127
  given(
128
- evo(completeModel, {
128
+ modifyFields(completeModel, {
129
129
  currentStep: () => 'Review',
130
- personalInfo: evo({
130
+ personalInfo: modifyFields({
131
131
  email: () => Validating({ value: 'jane@example.com' }),
132
132
  }),
133
133
  }),
@@ -142,15 +142,15 @@ describe('view', () => {
142
142
  scene(
143
143
  { update, view },
144
144
  given(
145
- evo(completeModel, {
145
+ modifyFields(completeModel, {
146
146
  currentStep: () => 'Review',
147
- workHistory: evo({
147
+ workHistory: modifyFields({
148
148
  entries: () => [],
149
149
  }),
150
- education: evo({
150
+ education: modifyFields({
151
151
  entries: () => [],
152
152
  }),
153
- skills: evo({
153
+ skills: modifyFields({
154
154
  entries: () => [],
155
155
  }),
156
156
  }),
@@ -167,7 +167,7 @@ describe('view', () => {
167
167
  scene(
168
168
  { update, view },
169
169
  given(
170
- evo(initialModel, {
170
+ modifyFields(initialModel, {
171
171
  currentStep: () => 'Review',
172
172
  submission: () => Submission.Submitting(),
173
173
  }),
@@ -180,7 +180,7 @@ describe('view', () => {
180
180
  scene(
181
181
  { update, view },
182
182
  given(
183
- evo(initialModel, {
183
+ modifyFields(initialModel, {
184
184
  currentStep: () => 'Review',
185
185
  submission: () => Submission.SubmitSuccess(),
186
186
  }),
@@ -193,7 +193,7 @@ describe('view', () => {
193
193
  scene(
194
194
  { update, view },
195
195
  given(
196
- evo(initialModel, {
196
+ modifyFields(initialModel, {
197
197
  currentStep: () => 'Review',
198
198
  submission: () => Submission.SubmitError({ error: 'Network down' }),
199
199
  }),
@@ -1,7 +1,7 @@
1
1
  import { Array, Option, Schema, pipe } from 'effect'
2
2
  import { File, Update } from 'foldkit'
3
3
  import { defineMessageUnion } from 'foldkit/message'
4
- import { evo } from 'foldkit/struct'
4
+ import { modifyFields } from 'foldkit/struct'
5
5
 
6
6
  import { FileDrop } from '@foldkit/ui'
7
7
 
@@ -43,7 +43,7 @@ const foldResumeDropOutMessage = FileDrop.OutMessage.match<
43
43
  ReceivedFiles:
44
44
  ({ files }) =>
45
45
  model => ({
46
- model: evo(model, {
46
+ model: modifyFields(model, {
47
47
  maybeResume: () =>
48
48
  pipe(
49
49
  files,
@@ -59,7 +59,7 @@ const foldResumeDrop = Update.foldChild({
59
59
  update: FileDrop.update,
60
60
  read: (model: Model) => Option.some(model.resumeDrop),
61
61
  write: (model, nextResumeDrop) =>
62
- evo(model, { resumeDrop: () => nextResumeDrop }),
62
+ modifyFields(model, { resumeDrop: () => nextResumeDrop }),
63
63
  toParentMessage: message => Message.GotResumeDropMessage({ message }),
64
64
  foldOutMessage: foldResumeDropOutMessage,
65
65
  })
@@ -70,7 +70,7 @@ const foldAdditionalFilesDropOutMessage = FileDrop.OutMessage.match<
70
70
  ReceivedFiles:
71
71
  ({ files }) =>
72
72
  model => ({
73
- model: evo(model, {
73
+ model: modifyFields(model, {
74
74
  additionalFiles: Array.appendAll(files),
75
75
  }),
76
76
  }),
@@ -81,7 +81,7 @@ const foldAdditionalFilesDrop = Update.foldChild({
81
81
  update: FileDrop.update,
82
82
  read: (model: Model) => Option.some(model.additionalFilesDrop),
83
83
  write: (model, nextAdditionalFilesDrop) =>
84
- evo(model, { additionalFilesDrop: () => nextAdditionalFilesDrop }),
84
+ modifyFields(model, { additionalFilesDrop: () => nextAdditionalFilesDrop }),
85
85
  toParentMessage: message =>
86
86
  Message.GotAdditionalFilesDropMessage({ message }),
87
87
  foldOutMessage: foldAdditionalFilesDropOutMessage,
@@ -95,11 +95,11 @@ export const update = (model: Model, message: Message) =>
95
95
  foldAdditionalFilesDrop(model, message),
96
96
 
97
97
  RemovedResume: () => ({
98
- model: evo(model, { maybeResume: () => Option.none() }),
98
+ model: modifyFields(model, { maybeResume: () => Option.none() }),
99
99
  }),
100
100
 
101
101
  RemovedAdditionalFile: ({ fileIndex }) => ({
102
- model: evo(model, {
102
+ model: modifyFields(model, {
103
103
  additionalFiles: Array.remove(fileIndex),
104
104
  }),
105
105
  }),
@@ -3,7 +3,7 @@ import { Schema } from 'effect'
3
3
  import { Submodel, type Update } from 'foldkit'
4
4
  import type { Html } from 'foldkit/html'
5
5
  import { defineMessageUnion } from 'foldkit/message'
6
- import { evo } from 'foldkit/struct'
6
+ import { modifyFields } from 'foldkit/struct'
7
7
 
8
8
  import { Textarea } from '@foldkit/ui'
9
9
 
@@ -33,7 +33,7 @@ export const init = (): Model => ({
33
33
  export const update = (model: Model, message: Message) =>
34
34
  Message.match<Update.Return<Model, Message>>(message, {
35
35
  UpdatedContent: ({ value }) => ({
36
- model: evo(model, { content: () => value }),
36
+ model: modifyFields(model, { content: () => value }),
37
37
  }),
38
38
  })
39
39
 
@@ -2,7 +2,7 @@ import { Array, Crypto, Effect, Schema } from 'effect'
2
2
  import { Calendar, Command, Update } from 'foldkit'
3
3
  import { type CalendarDate } from 'foldkit/calendar'
4
4
  import { defineMessageUnion } from 'foldkit/message'
5
- import { evo } from 'foldkit/struct'
5
+ import { modifyFields } from 'foldkit/struct'
6
6
 
7
7
  import { BrowserCrypto } from '@effect/platform-browser'
8
8
 
@@ -59,7 +59,7 @@ const foldEntryOutMessage: (
59
59
  ) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
60
60
  Entry.OutMessage.match<Update.Step<Model, Message>>({
61
61
  Removed: () => model => ({
62
- model: evo(model, {
62
+ model: modifyFields(model, {
63
63
  entries: Array.filter(entry => entry.id !== entryId),
64
64
  }),
65
65
  }),
@@ -71,7 +71,7 @@ const foldEntry = (entryId: string) =>
71
71
  read: (model: Model) =>
72
72
  Array.findFirst(model.entries, entry => entry.id === entryId),
73
73
  write: (model, nextEntry) =>
74
- evo(model, {
74
+ modifyFields(model, {
75
75
  entries: Array.map(entry => (entry.id === entryId ? nextEntry : entry)),
76
76
  }),
77
77
  toParentMessage: message => Message.GotEntryMessage({ entryId, message }),
@@ -83,7 +83,7 @@ export const update = (model: Model, message: Message) =>
83
83
  ClickedAddEntry: () => ({ model, commands: [GenerateEntryId()] }),
84
84
 
85
85
  SucceededGenerateEntryId: ({ entryId }) => ({
86
- model: evo(model, {
86
+ model: modifyFields(model, {
87
87
  entries: Array.append(Entry.init(entryId)),
88
88
  }),
89
89
  }),
@@ -91,7 +91,7 @@ export const update = (model: Model, message: Message) =>
91
91
  FailedGenerateEntryId: () => ({ model }),
92
92
 
93
93
  RemovedEntry: ({ entryId }) => ({
94
- model: evo(model, {
94
+ model: modifyFields(model, {
95
95
  entries: Array.filter(entry => entry.id !== entryId),
96
96
  }),
97
97
  }),
@@ -110,4 +110,4 @@ export const isComplete = (model: Model): boolean =>
110
110
  Array.every(model.entries, Entry.isComplete)
111
111
 
112
112
  export const revealErrors = (model: Model): Model =>
113
- evo(model, { entries: Array.map(Entry.revealErrors) })
113
+ modifyFields(model, { entries: Array.map(Entry.revealErrors) })
@@ -9,7 +9,7 @@ import {
9
9
  validate,
10
10
  } from 'foldkit/fieldValidation'
11
11
  import { defineMessageUnion } from 'foldkit/message'
12
- import { evo } from 'foldkit/struct'
12
+ import { modifyFields } from 'foldkit/struct'
13
13
 
14
14
  import { Listbox } from '@foldkit/ui'
15
15
 
@@ -93,7 +93,9 @@ const foldGraduationYearListboxOutMessage = Listbox.OutMessage.match<
93
93
  Selected:
94
94
  ({ value }) =>
95
95
  model => ({
96
- model: evo(model, { maybeGraduationYear: () => Option.some(value) }),
96
+ model: modifyFields(model, {
97
+ maybeGraduationYear: () => Option.some(value),
98
+ }),
97
99
  }),
98
100
  })
99
101
 
@@ -101,7 +103,9 @@ const foldGraduationYearListbox = Update.foldChild({
101
103
  update: GraduationYearListbox.update,
102
104
  read: (model: Model) => Option.some(model.graduationYearListbox),
103
105
  write: (model, nextGraduationYearListbox) =>
104
- evo(model, { graduationYearListbox: () => nextGraduationYearListbox }),
106
+ modifyFields(model, {
107
+ graduationYearListbox: () => nextGraduationYearListbox,
108
+ }),
105
109
  toParentMessage: message =>
106
110
  Message.GotGraduationYearListboxMessage({ message }),
107
111
  foldOutMessage: foldGraduationYearListboxOutMessage,
@@ -112,22 +116,24 @@ export const update = (model: Model, message: Message) =>
112
116
  message,
113
117
  {
114
118
  UpdatedSchool: ({ value }) => ({
115
- model: evo(model, { school: () => validateSchool(value) }),
119
+ model: modifyFields(model, { school: () => validateSchool(value) }),
116
120
  }),
117
121
 
118
122
  UpdatedDegree: ({ value }) => ({
119
- model: evo(model, { degree: () => validateDegree(value) }),
123
+ model: modifyFields(model, { degree: () => validateDegree(value) }),
120
124
  }),
121
125
 
122
126
  UpdatedFieldOfStudy: ({ value }) => ({
123
- model: evo(model, { fieldOfStudy: () => validateFieldOfStudy(value) }),
127
+ model: modifyFields(model, {
128
+ fieldOfStudy: () => validateFieldOfStudy(value),
129
+ }),
124
130
  }),
125
131
 
126
132
  GotGraduationYearListboxMessage: ({ message }) =>
127
133
  foldGraduationYearListbox(model, message),
128
134
 
129
135
  ToggledCurrentlyEnrolled: ({ isChecked }) => ({
130
- model: evo(model, { isCurrentlyEnrolled: () => isChecked }),
136
+ model: modifyFields(model, { isCurrentlyEnrolled: () => isChecked }),
131
137
  }),
132
138
 
133
139
  ClickedRemoveSelf: () => ({ model, outMessage: OutMessage.Removed() }),
@@ -147,7 +153,7 @@ export const isComplete = (entry: Model): boolean =>
147
153
  ])
148
154
 
149
155
  export const revealErrors = (entry: Model): Model =>
150
- evo(entry, {
156
+ modifyFields(entry, {
151
157
  school: revealFieldErrors(schoolRules),
152
158
  degree: revealFieldErrors(degreeRules),
153
159
  fieldOfStudy: revealFieldErrors(fieldOfStudyRules),
@@ -14,7 +14,7 @@ import {
14
14
  validate,
15
15
  } from 'foldkit/fieldValidation'
16
16
  import { defineMessageUnion } from 'foldkit/message'
17
- import { evo } from 'foldkit/struct'
17
+ import { modifyFields } from 'foldkit/struct'
18
18
 
19
19
  import { DatePicker, Listbox } from '@foldkit/ui'
20
20
 
@@ -162,14 +162,17 @@ const foldPronounsOutMessage = Listbox.OutMessage.match<
162
162
  Selected:
163
163
  ({ value }) =>
164
164
  model => ({
165
- model: evo(model, { maybeSelectedPronoun: () => Option.some(value) }),
165
+ model: modifyFields(model, {
166
+ maybeSelectedPronoun: () => Option.some(value),
167
+ }),
166
168
  }),
167
169
  })
168
170
 
169
171
  const foldPronouns = Update.foldChild({
170
172
  update: PronounsListbox.update,
171
173
  read: (model: Model) => Option.some(model.pronouns),
172
- write: (model, nextPronouns) => evo(model, { pronouns: () => nextPronouns }),
174
+ write: (model, nextPronouns) =>
175
+ modifyFields(model, { pronouns: () => nextPronouns }),
173
176
  toParentMessage: message => Message.GotPronounsMessage({ message }),
174
177
  foldOutMessage: foldPronounsOutMessage,
175
178
  })
@@ -180,10 +183,12 @@ const foldAvailableDateOutMessage = DatePicker.OutMessage.match<
180
183
  SelectedDate:
181
184
  ({ date }) =>
182
185
  model => ({
183
- model: evo(model, { maybeAvailableDate: () => Option.some(date) }),
186
+ model: modifyFields(model, {
187
+ maybeAvailableDate: () => Option.some(date),
188
+ }),
184
189
  }),
185
190
  ClearedDate: () => model => ({
186
- model: evo(model, { maybeAvailableDate: () => Option.none() }),
191
+ model: modifyFields(model, { maybeAvailableDate: () => Option.none() }),
187
192
  }),
188
193
  ChangedViewMonth: () => model => ({ model }),
189
194
  })
@@ -192,7 +197,7 @@ const foldAvailableDate = Update.foldChild({
192
197
  update: DatePicker.update,
193
198
  read: (model: Model) => Option.some(model.availableDate),
194
199
  write: (model, nextAvailableDate) =>
195
- evo(model, { availableDate: () => nextAvailableDate }),
200
+ modifyFields(model, { availableDate: () => nextAvailableDate }),
196
201
  toParentMessage: message => Message.GotAvailableDateMessage({ message }),
197
202
  foldOutMessage: foldAvailableDateOutMessage,
198
203
  })
@@ -200,11 +205,11 @@ const foldAvailableDate = Update.foldChild({
200
205
  export const update = (model: Model, message: Message) =>
201
206
  Message.match<UpdateReturn>(message, {
202
207
  UpdatedFirstName: ({ value }) => ({
203
- model: evo(model, { firstName: () => validateFirstName(value) }),
208
+ model: modifyFields(model, { firstName: () => validateFirstName(value) }),
204
209
  }),
205
210
 
206
211
  UpdatedLastName: ({ value }) => ({
207
- model: evo(model, { lastName: () => validateLastName(value) }),
212
+ model: modifyFields(model, { lastName: () => validateLastName(value) }),
208
213
  }),
209
214
 
210
215
  UpdatedEmail: ({ value }) => {
@@ -212,14 +217,14 @@ export const update = (model: Model, message: Message) =>
212
217
  return Match.value(validateEmail(value)).pipe(
213
218
  Match.withReturnType<UpdateReturn>(),
214
219
  Match.tag('Valid', () => ({
215
- model: evo(model, {
220
+ model: modifyFields(model, {
216
221
  email: () => Validating({ value }),
217
222
  emailValidationId: () => validationId,
218
223
  }),
219
224
  commands: [ValidateEmailAsync({ emailInput: value, validationId })],
220
225
  })),
221
226
  Match.orElse(syncResult => ({
222
- model: evo(model, {
227
+ model: modifyFields(model, {
223
228
  email: () => syncResult,
224
229
  emailValidationId: () => validationId,
225
230
  }),
@@ -229,24 +234,24 @@ export const update = (model: Model, message: Message) =>
229
234
 
230
235
  CompletedValidateEmailAsync: ({ validationId, field }) => {
231
236
  if (validationId === model.emailValidationId) {
232
- return { model: evo(model, { email: () => field }) }
237
+ return { model: modifyFields(model, { email: () => field }) }
233
238
  } else {
234
239
  return { model }
235
240
  }
236
241
  },
237
242
 
238
243
  UpdatedPhone: ({ value }) => ({
239
- model: evo(model, { phone: () => validatePhone(value) }),
244
+ model: modifyFields(model, { phone: () => validatePhone(value) }),
240
245
  }),
241
246
 
242
247
  GotPronounsMessage: ({ message }) => foldPronouns(model, message),
243
248
 
244
249
  UpdatedCustomPronouns: ({ value }) => ({
245
- model: evo(model, { customPronouns: () => value }),
250
+ model: modifyFields(model, { customPronouns: () => value }),
246
251
  }),
247
252
 
248
253
  UpdatedPortfolioUrl: ({ value }) => ({
249
- model: evo(model, {
254
+ model: modifyFields(model, {
250
255
  portfolioUrl: () => validatePortfolioUrl(value),
251
256
  }),
252
257
  }),
@@ -277,7 +282,7 @@ export const isComplete = (model: Model): boolean =>
277
282
  ])
278
283
 
279
284
  export const revealErrors = (model: Model): Model =>
280
- evo(model, {
285
+ modifyFields(model, {
281
286
  firstName: revealFieldErrors(firstNameRules),
282
287
  lastName: revealFieldErrors(lastNameRules),
283
288
  email: revealFieldErrors(emailRules),
@@ -1,7 +1,7 @@
1
1
  import { Calendar } from 'foldkit'
2
2
  import { Valid, Validating } from 'foldkit/fieldValidation'
3
3
  import { Command, given, message, model, story } from 'foldkit/story'
4
- import { evo } from 'foldkit/struct'
4
+ import { modifyFields } from 'foldkit/struct'
5
5
  import { describe, expect, test } from 'vitest'
6
6
 
7
7
  import { Message, ValidateEmailAsync, init, update } from './personalInfo'
@@ -68,7 +68,7 @@ describe('personalInfo', () => {
68
68
  story(
69
69
  update,
70
70
  given(
71
- evo(init(today), {
71
+ modifyFields(init(today), {
72
72
  email: () => Validating({ value: 'jane@example.com' }),
73
73
  emailValidationId: () => 5,
74
74
  }),
@@ -9,7 +9,7 @@ import {
9
9
  validate,
10
10
  } from 'foldkit/fieldValidation'
11
11
  import { defineMessageUnion } from 'foldkit/message'
12
- import { evo } from 'foldkit/struct'
12
+ import { modifyFields } from 'foldkit/struct'
13
13
 
14
14
  import { RadioGroup } from '@foldkit/ui'
15
15
 
@@ -79,14 +79,16 @@ const foldProficiencyRadioGroupOutMessage = RadioGroup.OutMessage.match<
79
79
  >({
80
80
  Selected:
81
81
  ({ value }) =>
82
- model => ({ model: evo(model, { proficiency: () => value }) }),
82
+ model => ({ model: modifyFields(model, { proficiency: () => value }) }),
83
83
  })
84
84
 
85
85
  const foldProficiencyRadioGroup = Update.foldChild({
86
86
  update: ProficiencyRadioGroup.update,
87
87
  read: (model: Model) => Option.some(model.proficiencyRadioGroup),
88
88
  write: (model, nextProficiencyRadioGroup) =>
89
- evo(model, { proficiencyRadioGroup: () => nextProficiencyRadioGroup }),
89
+ modifyFields(model, {
90
+ proficiencyRadioGroup: () => nextProficiencyRadioGroup,
91
+ }),
90
92
  toParentMessage: message =>
91
93
  Message.GotProficiencyRadioGroupMessage({ message }),
92
94
  foldOutMessage: foldProficiencyRadioGroupOutMessage,
@@ -97,7 +99,7 @@ export const update = (model: Model, message: Message) =>
97
99
  message,
98
100
  {
99
101
  UpdatedName: ({ value }) => ({
100
- model: evo(model, { name: () => validateName(value) }),
102
+ model: modifyFields(model, { name: () => validateName(value) }),
101
103
  }),
102
104
 
103
105
  GotProficiencyRadioGroupMessage: ({ message }) =>
@@ -115,4 +117,4 @@ export const isComplete = (entry: Model): boolean =>
115
117
  allValid([[entry.name, nameRules]])
116
118
 
117
119
  export const revealErrors = (entry: Model): Model =>
118
- evo(entry, { name: revealFieldErrors(nameRules) })
120
+ modifyFields(entry, { name: revealFieldErrors(nameRules) })
@@ -1,7 +1,7 @@
1
1
  import { Array, Crypto, Effect, Schema } from 'effect'
2
2
  import { Command, Update } from 'foldkit'
3
3
  import { defineMessageUnion } from 'foldkit/message'
4
- import { evo } from 'foldkit/struct'
4
+ import { modifyFields } from 'foldkit/struct'
5
5
 
6
6
  import { BrowserCrypto } from '@effect/platform-browser'
7
7
 
@@ -56,7 +56,7 @@ const foldEntryOutMessage: (
56
56
  ) => (outMessage: Entry.OutMessage) => Update.Step<Model, Message> = entryId =>
57
57
  Entry.OutMessage.match<Update.Step<Model, Message>>({
58
58
  Removed: () => model => ({
59
- model: evo(model, {
59
+ model: modifyFields(model, {
60
60
  entries: Array.filter(entry => entry.id !== entryId),
61
61
  }),
62
62
  }),
@@ -68,7 +68,7 @@ const foldEntry = (entryId: string) =>
68
68
  read: (model: Model) =>
69
69
  Array.findFirst(model.entries, entry => entry.id === entryId),
70
70
  write: (model, nextEntry) =>
71
- evo(model, {
71
+ modifyFields(model, {
72
72
  entries: Array.map(entry => (entry.id === entryId ? nextEntry : entry)),
73
73
  }),
74
74
  toParentMessage: message => Message.GotEntryMessage({ entryId, message }),
@@ -80,7 +80,7 @@ export const update = (model: Model, message: Message) =>
80
80
  ClickedAddEntry: () => ({ model, commands: [GenerateEntryId()] }),
81
81
 
82
82
  SucceededGenerateEntryId: ({ entryId }) => ({
83
- model: evo(model, {
83
+ model: modifyFields(model, {
84
84
  entries: Array.append(Entry.init(entryId)),
85
85
  }),
86
86
  }),
@@ -88,7 +88,7 @@ export const update = (model: Model, message: Message) =>
88
88
  FailedGenerateEntryId: () => ({ model }),
89
89
 
90
90
  RemovedEntry: ({ entryId }) => ({
91
- model: evo(model, {
91
+ model: modifyFields(model, {
92
92
  entries: Array.filter(entry => entry.id !== entryId),
93
93
  }),
94
94
  }),
@@ -107,4 +107,4 @@ export const isComplete = (model: Model): boolean =>
107
107
  Array.every(model.entries, Entry.isComplete)
108
108
 
109
109
  export const revealErrors = (model: Model): Model =>
110
- evo(model, { entries: Array.map(Entry.revealErrors) })
110
+ modifyFields(model, { entries: Array.map(Entry.revealErrors) })