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
@@ -61,7 +61,7 @@ Then replace this file whole. Foldkit's conventions change with its APIs, and a
61
61
  const update = (model: Model, message: Message) =>
62
62
  Message.match<Update.Return<Model, Message>>(message, {
63
63
  ClickedIncrement: () => ({
64
- model: evo(model, { count: count => count + 1 }),
64
+ model: modifyFields(model, { count: count => count + 1 }),
65
65
  }),
66
66
  })
67
67
  ```
@@ -86,7 +86,7 @@ Add `toParentOutMessage` only when at least one child OutMessage should continue
86
86
 
87
87
  When a `foldChildInits` entry can derive or forward an OutMessage, add `resolveOutMessage` to construct one parent OutMessage from the named OutMessages after every local fold completes. Combine their information when both results matter; choosing one discards the other. The callback also receives the final Model. If that Model alone contains everything needed, use local folds and attach a parent OutMessage afterward with `Update.withOutMessage`.
88
88
 
89
- Use `evo()` from `foldkit/struct` for immutable model updates. Never spread or `Object.assign`.
89
+ Use `modifyFields()` from `foldkit/struct` for immutable model updates. Never spread or `Object.assign`.
90
90
 
91
91
  ### View
92
92
 
@@ -9,9 +9,9 @@
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
- "effect": "4.0.0-rc.115",
14
+ "effect": "4.0.0-rc.116",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -1,5 +1,5 @@
1
1
  import { HashMap, Option } from 'effect'
2
- import { evo } from 'foldkit/struct'
2
+ import { modifyFields } from 'foldkit/struct'
3
3
 
4
4
  import { Tabs } from '@foldkit/ui'
5
5
 
@@ -44,14 +44,14 @@ export const loadingPostsModel: Model = {
44
44
  stats: StatsData.Idle(),
45
45
  }
46
46
 
47
- export const loadedPostsModel: Model = evo(loadingPostsModel, {
47
+ export const loadedPostsModel: Model = modifyFields(loadingPostsModel, {
48
48
  posts: () =>
49
49
  PostsData.Success({
50
50
  data: { posts: fixturePosts, fetchedAt: FETCHED_AT },
51
51
  }),
52
52
  })
53
53
 
54
- export const cachedFirstPostModel: Model = evo(loadedPostsModel, {
54
+ export const cachedFirstPostModel: Model = modifyFields(loadedPostsModel, {
55
55
  postDetailById: () =>
56
56
  HashMap.set(
57
57
  HashMap.empty(),
@@ -62,7 +62,7 @@ export const cachedFirstPostModel: Model = evo(loadedPostsModel, {
62
62
  ),
63
63
  })
64
64
 
65
- export const loadedStatsModel: Model = evo(loadedPostsModel, {
65
+ export const loadedStatsModel: Model = modifyFields(loadedPostsModel, {
66
66
  activeTab: () => 'Stats',
67
67
  stats: () =>
68
68
  StatsData.Success({
@@ -13,7 +13,7 @@ import {
13
13
  import { AsyncData, Command, Runtime, Subscription, Update } from 'foldkit'
14
14
  import { Document, Html, HtmlBuilder } from 'foldkit/html'
15
15
  import { defineMessageUnion } from 'foldkit/message'
16
- import { evo } from 'foldkit/struct'
16
+ import { modifyFields } from 'foldkit/struct'
17
17
 
18
18
  import { Button, Tabs } from '@foldkit/ui'
19
19
 
@@ -102,7 +102,7 @@ const applyPostsTransition = (
102
102
  Option.match(maybeNextPosts, {
103
103
  onNone: () => ({ model }),
104
104
  onSome: nextPosts => ({
105
- model: evo(model, { posts: () => nextPosts }),
105
+ model: modifyFields(model, { posts: () => nextPosts }),
106
106
  commands: [FetchPosts()],
107
107
  }),
108
108
  })
@@ -114,7 +114,7 @@ const applyStatsTransition = (
114
114
  Option.match(maybeNextStats, {
115
115
  onNone: () => ({ model }),
116
116
  onSome: nextStats => ({
117
- model: evo(model, { stats: () => nextStats }),
117
+ model: modifyFields(model, { stats: () => nextStats }),
118
118
  commands: [FetchStats()],
119
119
  }),
120
120
  })
@@ -123,7 +123,7 @@ const setPostDetail = (postId: string, postDetail: PostDetailData) =>
123
123
  HashMap.set(postId, postDetail)
124
124
 
125
125
  const activateTab = (model: Model, tab: Tab): UpdateReturn => {
126
- const modelWithActiveTab = evo(model, { activeTab: () => tab })
126
+ const modelWithActiveTab = modifyFields(model, { activeTab: () => tab })
127
127
 
128
128
  return Match.value(tab).pipe(
129
129
  Match.withReturnType<UpdateReturn>(),
@@ -156,7 +156,7 @@ const foldTabsOutMessage = Tabs.OutMessage.match<
156
156
  const foldTabs = Update.foldChild({
157
157
  update: AppTabs.update,
158
158
  read: (model: Model) => Option.some(model.tabs),
159
- write: (model, nextTabs) => evo(model, { tabs: () => nextTabs }),
159
+ write: (model, nextTabs) => modifyFields(model, { tabs: () => nextTabs }),
160
160
  toParentMessage: message => Message.GotTabsMessage({ message }),
161
161
  foldOutMessage: foldTabsOutMessage,
162
162
  })
@@ -166,13 +166,13 @@ export const update = (model: Model, message: Message) =>
166
166
  GotTabsMessage: ({ message }) => foldTabs(model, message),
167
167
 
168
168
  ClickedPost: ({ postId }) => {
169
- const selectedModel = evo(model, {
169
+ const selectedModel = modifyFields(model, {
170
170
  maybeSelectedPostId: () => Option.some(postId),
171
171
  })
172
172
 
173
173
  return Option.match(HashMap.get(model.postDetailById, postId), {
174
174
  onNone: () => ({
175
- model: evo(selectedModel, {
175
+ model: modifyFields(selectedModel, {
176
176
  postDetailById: setPostDetail(postId, PostDetailData.Loading()),
177
177
  }),
178
178
  commands: [FetchPostDetail({ postId })],
@@ -182,7 +182,7 @@ export const update = (model: Model, message: Message) =>
182
182
  },
183
183
 
184
184
  ClickedBackToPosts: () => ({
185
- model: evo(model, { maybeSelectedPostId: () => Option.none() }),
185
+ model: modifyFields(model, { maybeSelectedPostId: () => Option.none() }),
186
186
  }),
187
187
 
188
188
  ClickedInvalidatePosts: () =>
@@ -192,7 +192,7 @@ export const update = (model: Model, message: Message) =>
192
192
  applyPostsTransition(model, AsyncData.revalidateOrLoad(model.posts)),
193
193
 
194
194
  ClickedRetryPostDetail: ({ postId }) => ({
195
- model: evo(model, {
195
+ model: modifyFields(model, {
196
196
  postDetailById: setPostDetail(postId, PostDetailData.Loading()),
197
197
  }),
198
198
  commands: [FetchPostDetail({ postId })],
@@ -208,17 +208,17 @@ export const update = (model: Model, message: Message) =>
208
208
  applyStatsTransition(model, AsyncData.revalidate(model.stats)),
209
209
 
210
210
  SettledFetchPosts: ({ result }) => ({
211
- model: evo(model, { posts: AsyncData.settle(result) }),
211
+ model: modifyFields(model, { posts: AsyncData.settle(result) }),
212
212
  }),
213
213
 
214
214
  SettledFetchPostDetail: ({ postId, result }) => ({
215
- model: evo(model, {
215
+ model: modifyFields(model, {
216
216
  postDetailById: HashMap.modify(postId, AsyncData.settle(result)),
217
217
  }),
218
218
  }),
219
219
 
220
220
  SettledFetchStats: ({ result }) => ({
221
- model: evo(model, { stats: AsyncData.settle(result) }),
221
+ model: modifyFields(model, { stats: AsyncData.settle(result) }),
222
222
  }),
223
223
  })
224
224
 
@@ -1,6 +1,6 @@
1
1
  import { HashMap, Option, Result } from 'effect'
2
2
  import { Command, given, message, model, story } from 'foldkit/story'
3
- import { evo } from 'foldkit/struct'
3
+ import { modifyFields } from 'foldkit/struct'
4
4
  import { expect, test } from 'vitest'
5
5
 
6
6
  import { Tabs } from '@foldkit/ui'
@@ -97,7 +97,7 @@ test('a revalidation tick keeps stale stats on screen while refetching', () => {
97
97
  FetchStats,
98
98
  Message.SettledFetchStats({
99
99
  result: Result.succeed({
100
- stats: evo(fixtureStats, { activeUsers: () => 99 }),
100
+ stats: modifyFields(fixtureStats, { activeUsers: () => 99 }),
101
101
  fetchedAt: FETCHED_AT + 5000,
102
102
  }),
103
103
  }),
@@ -135,7 +135,7 @@ test('a failed refresh keeps the stale stats on screen with the error', () => {
135
135
  test('refresh clicks during an in-flight fetch are deduplicated', () => {
136
136
  story(
137
137
  update,
138
- given(evo(loadedStatsModel, { stats: () => StatsData.Loading() })),
138
+ given(modifyFields(loadedStatsModel, { stats: () => StatsData.Loading() })),
139
139
  message(Message.ClickedRefreshStats()),
140
140
  Command.expectNone(),
141
141
  )
@@ -145,7 +145,7 @@ test('a revalidation tick during a refresh is deduplicated', () => {
145
145
  story(
146
146
  update,
147
147
  given(
148
- evo(loadedStatsModel, {
148
+ modifyFields(loadedStatsModel, {
149
149
  stats: () =>
150
150
  StatsData.Refreshing({
151
151
  data: { stats: fixtureStats, fetchedAt: FETCHED_AT },
@@ -187,7 +187,7 @@ test('retrying failed posts shows the loading state and refetches', () => {
187
187
  story(
188
188
  update,
189
189
  given(
190
- evo(loadedPostsModel, {
190
+ modifyFields(loadedPostsModel, {
191
191
  posts: () => PostsData.Failure({ error: 'The server is down.' }),
192
192
  }),
193
193
  ),
@@ -274,7 +274,7 @@ test('revisiting a post with a cached failure shows it without refetching', () =
274
274
  story(
275
275
  update,
276
276
  given(
277
- evo(loadedPostsModel, {
277
+ modifyFields(loadedPostsModel, {
278
278
  postDetailById: () =>
279
279
  HashMap.set(
280
280
  HashMap.empty(),
@@ -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": {
@@ -11,12 +11,12 @@ import {
11
11
  type,
12
12
  within,
13
13
  } from 'foldkit/scene'
14
- import { evo } from 'foldkit/struct'
14
+ import { modifyFields } from 'foldkit/struct'
15
15
  import { describe, test } from 'vitest'
16
16
 
17
17
  import { Message, SimulateAuthRequest, initModel, update, view } from './login'
18
18
 
19
- const validModel = evo(initModel(), {
19
+ const validModel = modifyFields(initModel(), {
20
20
  email: () => Valid({ value: 'alice@example.com' }),
21
21
  password: () => Valid({ value: 'password' }),
22
22
  })
@@ -8,7 +8,7 @@ import {
8
8
  model,
9
9
  story,
10
10
  } from 'foldkit/story'
11
- import { evo } from 'foldkit/struct'
11
+ import { modifyFields } from 'foldkit/struct'
12
12
  import { describe, expect, test } from 'vitest'
13
13
 
14
14
  import {
@@ -19,7 +19,7 @@ import {
19
19
  update,
20
20
  } from './login'
21
21
 
22
- const validModel = evo(initModel(), {
22
+ const validModel = modifyFields(initModel(), {
23
23
  email: () => Valid({ value: 'alice@example.com' }),
24
24
  password: () => Valid({ value: 'password' }),
25
25
  })
@@ -12,7 +12,7 @@ import {
12
12
  } from 'foldkit/fieldValidation'
13
13
  import { 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
  import { Button, Input } from '@foldkit/ui'
18
18
 
@@ -111,11 +111,11 @@ export const update = (model: Model, message: Message) =>
111
111
  message,
112
112
  {
113
113
  ChangedEmail: ({ value }) => ({
114
- model: evo(model, { email: () => validateEmail(value) }),
114
+ model: modifyFields(model, { email: () => validateEmail(value) }),
115
115
  }),
116
116
 
117
117
  ChangedPassword: ({ value }) => ({
118
- model: evo(model, { password: () => validatePassword(value) }),
118
+ model: modifyFields(model, { password: () => validatePassword(value) }),
119
119
  }),
120
120
 
121
121
  SubmittedForm: () => {
@@ -128,7 +128,7 @@ export const update = (model: Model, message: Message) =>
128
128
  }
129
129
 
130
130
  return {
131
- model: evo(model, { isSubmitting: () => true }),
131
+ model: modifyFields(model, { isSubmitting: () => true }),
132
132
  commands: [
133
133
  SimulateAuthRequest({
134
134
  email: model.email.value,
@@ -144,7 +144,7 @@ export const update = (model: Model, message: Message) =>
144
144
  }),
145
145
 
146
146
  FailedSimulateAuthRequest: ({ error }) => ({
147
- model: evo(model, {
147
+ model: modifyFields(model, {
148
148
  password: () =>
149
149
  Invalid({
150
150
  value: model.password.value,
@@ -1,6 +1,6 @@
1
1
  import { Option } from 'effect'
2
2
  import { Update } from 'foldkit'
3
- import { evo } from 'foldkit/struct'
3
+ import { modifyFields } from 'foldkit/struct'
4
4
 
5
5
  import { Message, OutMessage } from './message'
6
6
  import { Model } from './model'
@@ -10,7 +10,7 @@ const foldLogin = Update.foldChild({
10
10
  update: Login.update,
11
11
  read: (model: Model) => Option.some(model.loginModel),
12
12
  write: (model, nextLoginModel) =>
13
- evo(model, { loginModel: () => nextLoginModel }),
13
+ modifyFields(model, { loginModel: () => nextLoginModel }),
14
14
  toParentMessage: message => Message.GotLoginMessage({ message }),
15
15
  toParentOutMessage: Login.OutMessage.match<OutMessage>({
16
16
  SucceededLogin: ({ session }) => OutMessage.SucceededLogin({ session }),
@@ -8,7 +8,7 @@ import {
8
8
  submit,
9
9
  text,
10
10
  } from 'foldkit/scene'
11
- import { evo } from 'foldkit/struct'
11
+ import { modifyFields } from 'foldkit/struct'
12
12
  import { describe, test } from 'vitest'
13
13
 
14
14
  import { SaveSession } from './command'
@@ -26,7 +26,7 @@ import { view } from './view'
26
26
 
27
27
  const validModel = LoggedOut.Model({
28
28
  route: AppRoute.Login(),
29
- loginModel: evo(initLoginModel(), {
29
+ loginModel: modifyFields(initLoginModel(), {
30
30
  email: () => Valid({ value: 'alice@example.com' }),
31
31
  password: () => Valid({ value: 'password' }),
32
32
  }),
@@ -1,7 +1,7 @@
1
1
  import { Effect, Match, Option, Schema } from 'effect'
2
2
  import { Command, Update } from 'foldkit'
3
3
  import { UrlRequest, load, pushUrl, replaceUrl } from 'foldkit/navigation'
4
- import { evo } from 'foldkit/struct'
4
+ import { modifyFields } from 'foldkit/struct'
5
5
  import { toString as urlToString } from 'foldkit/url'
6
6
 
7
7
  import { ClearSession, LogError, SaveSession } from './command'
@@ -125,7 +125,7 @@ export const update = (model: Model, message: Message) =>
125
125
  Match.value(route).pipe(
126
126
  withUpdateReturn,
127
127
  Match.tag('Home', 'Login', 'NotFound', route => ({
128
- model: evo(loggedOutModel, { route: () => route }),
128
+ model: modifyFields(loggedOutModel, { route: () => route }),
129
129
  })),
130
130
  Match.orElse(() => ({ model, commands: [RedirectToLogin()] })),
131
131
  ),
@@ -134,7 +134,7 @@ export const update = (model: Model, message: Message) =>
134
134
  Match.value(route).pipe(
135
135
  withUpdateReturn,
136
136
  Match.tag('Dashboard', 'Settings', 'NotFound', route => ({
137
- model: evo(loggedInModel, { route: () => route }),
137
+ model: modifyFields(loggedInModel, { route: () => route }),
138
138
  })),
139
139
  Match.orElse(() => ({
140
140
  model,
@@ -9,9 +9,9 @@
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
- "effect": "4.0.0-rc.115",
14
+ "effect": "4.0.0-rc.116",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -2,7 +2,7 @@ import { Array, Effect, Number, Option, Random, Schema, pipe } from 'effect'
2
2
  import { Canvas, Command, Runtime, Subscription, type Update } from 'foldkit'
3
3
  import { Document, Html, HtmlBuilder } from 'foldkit/html'
4
4
  import { defineMessageUnion } from 'foldkit/message'
5
- import { evo } from 'foldkit/struct'
5
+ import { modifyFields } from 'foldkit/struct'
6
6
 
7
7
  import { Button } from '@foldkit/ui'
8
8
 
@@ -113,7 +113,7 @@ const advanceBall =
113
113
  const maxY = CANVAS_HEIGHT - ball.radius
114
114
  const bouncedX = nextX < minX || nextX > maxX
115
115
  const bouncedY = nextY < minY || nextY > maxY
116
- return evo(ball, {
116
+ return modifyFields(ball, {
117
117
  x: () => Math.max(minX, Math.min(maxX, nextX)),
118
118
  y: () => Math.max(minY, Math.min(maxY, nextY)),
119
119
  vx: vx => (bouncedX ? -vx : vx),
@@ -124,7 +124,7 @@ const advanceBall =
124
124
  export const update = (model: Model, message: Message) =>
125
125
  Message.match<Update.Return<Model, Message>>(message, {
126
126
  TickedFrame: ({ deltaTime }) => ({
127
- model: evo(model, {
127
+ model: modifyFields(model, {
128
128
  balls: Array.map(advanceBall(deltaTime / MS_PER_SECOND)),
129
129
  }),
130
130
  }),
@@ -135,7 +135,7 @@ export const update = (model: Model, message: Message) =>
135
135
  }),
136
136
 
137
137
  CompletedGenerateBall: ({ x, y, vx, vy, radius, color }) => ({
138
- model: evo(model, {
138
+ model: modifyFields(model, {
139
139
  balls: Array.append({
140
140
  id: model.nextId,
141
141
  x,
@@ -149,10 +149,10 @@ export const update = (model: Model, message: Message) =>
149
149
  }),
150
150
  }),
151
151
 
152
- ClickedClear: () => ({ model: evo(model, { balls: () => [] }) }),
152
+ ClickedClear: () => ({ model: modifyFields(model, { balls: () => [] }) }),
153
153
 
154
154
  ClickedTogglePlay: () => ({
155
- model: evo(model, { isRunning: running => !running }),
155
+ model: modifyFields(model, { isRunning: running => !running }),
156
156
  }),
157
157
  })
158
158
 
@@ -1,5 +1,5 @@
1
1
  import { click, expect, given, role, scene, text } from 'foldkit/scene'
2
- import { evo } from 'foldkit/struct'
2
+ import { modifyFields } from 'foldkit/struct'
3
3
  import { describe, test } from 'vitest'
4
4
 
5
5
  import { type Model, update, view } from './main'
@@ -34,7 +34,7 @@ describe('view', () => {
34
34
  })
35
35
 
36
36
  test('the ball count reflects spawned balls in the Model', () => {
37
- const populatedModel: Model = evo(emptyModel, {
37
+ const populatedModel: Model = modifyFields(emptyModel, {
38
38
  balls: () => [
39
39
  { id: 0, x: 10, y: 20, vx: 1, vy: 1, radius: 8, color: '#ff2d55' },
40
40
  { id: 1, x: 30, y: 40, vx: -1, vy: 1, radius: 12, color: '#5ac8fa' },
@@ -51,7 +51,7 @@ describe('view', () => {
51
51
  })
52
52
 
53
53
  test('Clear empties the rendered ball count', () => {
54
- const populatedModel: Model = evo(emptyModel, {
54
+ const populatedModel: Model = modifyFields(emptyModel, {
55
55
  balls: () => [
56
56
  { id: 0, x: 10, y: 20, vx: 1, vy: 1, radius: 8, color: '#ff2d55' },
57
57
  ],
@@ -1,5 +1,5 @@
1
1
  import { Command, given, message, model, story } from 'foldkit/story'
2
- import { evo } from 'foldkit/struct'
2
+ import { modifyFields } from 'foldkit/struct'
3
3
  import { describe, expect, test } from 'vitest'
4
4
 
5
5
  import { GenerateBall, Message, type Model, update } from './main'
@@ -10,7 +10,7 @@ const emptyModel: Model = {
10
10
  isRunning: true,
11
11
  }
12
12
 
13
- const populatedModel: Model = evo(emptyModel, {
13
+ const populatedModel: Model = modifyFields(emptyModel, {
14
14
  balls: () => [
15
15
  { id: 0, x: 100, y: 100, vx: 50, vy: 50, radius: 10, color: '#ff2d55' },
16
16
  { id: 1, x: 200, y: 200, vx: -50, vy: -50, radius: 15, color: '#5ac8fa' },
@@ -97,7 +97,7 @@ describe('update', () => {
97
97
  })
98
98
 
99
99
  test('bounces a ball off the canvas edges, flipping its velocity', () => {
100
- const movingRightModel: Model = evo(emptyModel, {
100
+ const movingRightModel: Model = modifyFields(emptyModel, {
101
101
  balls: () => [
102
102
  {
103
103
  id: 0,
@@ -9,11 +9,11 @@
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
15
  "echarts": "^6.1.0",
16
- "effect": "4.0.0-rc.115",
16
+ "effect": "4.0.0-rc.116",
17
17
  "foldkit": "workspace:*"
18
18
  },
19
19
  "devDependencies": {
@@ -1,5 +1,5 @@
1
1
  import { Option } from 'effect'
2
- import { evo } from 'foldkit/struct'
2
+ import { modifyFields } from 'foldkit/struct'
3
3
 
4
4
  import { RadioGroup } from '@foldkit/ui'
5
5
 
@@ -120,7 +120,7 @@ export const loadingModel = Model.make({
120
120
  maybeSelectedDatumId: Option.none(),
121
121
  })
122
122
 
123
- export const readyModel = evo(loadingModel, {
123
+ export const readyModel = modifyFields(loadingModel, {
124
124
  telemetry: () => TelemetryAsyncData.Success({ data: sampleTelemetry }),
125
125
  maybeChartHostId: () => Option.some('test-chart-host'),
126
126
  })
@@ -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 { RadioGroup } from '@foldkit/ui'
@@ -79,7 +79,7 @@ describe('view', () => {
79
79
  scene(
80
80
  { update, view },
81
81
  given(
82
- evo(readyModel, {
82
+ modifyFields(readyModel, {
83
83
  telemetry: () =>
84
84
  TelemetryAsyncData.Refreshing({ data: sampleTelemetry }),
85
85
  }),
@@ -95,7 +95,7 @@ describe('view', () => {
95
95
  scene(
96
96
  { update, view },
97
97
  given(
98
- evo(loadingModel, {
98
+ modifyFields(loadingModel, {
99
99
  telemetry: () => TelemetryAsyncData.Failure({ error: 'offline' }),
100
100
  }),
101
101
  ),
@@ -1,5 +1,5 @@
1
1
  import { Command, given, message, model, story } from 'foldkit/story'
2
- import { evo } from 'foldkit/struct'
2
+ import { modifyFields } from 'foldkit/struct'
3
3
  import { expect, test } from 'vitest'
4
4
 
5
5
  import { RadioGroup } from '@foldkit/ui'
@@ -103,7 +103,7 @@ test('a failed refresh preserves stale data in the stale state', () => {
103
103
  story(
104
104
  update,
105
105
  given(
106
- evo(readyModel, {
106
+ modifyFields(readyModel, {
107
107
  telemetry: () =>
108
108
  TelemetryAsyncData.Refreshing({ data: sampleTelemetry }),
109
109
  }),