create-foldkit-app 0.30.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/templates/base/FOLDKIT.md +3 -1
  2. package/dist/templates/examples/auth/src/main.ts +3 -3
  3. package/dist/templates/examples/auth/src/page/loggedIn/model.ts +2 -2
  4. package/dist/templates/examples/auth/src/page/loggedOut/model.ts +2 -2
  5. package/dist/templates/examples/auth/src/route.ts +19 -29
  6. package/dist/templates/examples/auth/src/scene.test.ts +2 -2
  7. package/dist/templates/examples/auth/src/update.ts +3 -4
  8. package/dist/templates/examples/form/src/main.ts +12 -21
  9. package/dist/templates/examples/interrupting-commands/src/scene.test.ts +2 -2
  10. package/dist/templates/examples/interrupting-commands/src/story.test.ts +7 -7
  11. package/dist/templates/examples/job-application/src/main.ts +2 -2
  12. package/dist/templates/examples/job-application/src/model.ts +7 -12
  13. package/dist/templates/examples/job-application/src/scene.test.ts +5 -11
  14. package/dist/templates/examples/job-application/src/story.test.ts +4 -4
  15. package/dist/templates/examples/job-application/src/update.ts +8 -4
  16. package/dist/templates/examples/job-application/src/view/review.ts +92 -94
  17. package/dist/templates/examples/managed-resource-layer/src/main.ts +23 -27
  18. package/dist/templates/examples/managed-resource-layer/src/scene.test.ts +3 -4
  19. package/dist/templates/examples/managed-resource-layer/src/story.test.ts +11 -20
  20. package/dist/templates/examples/map/src/main.fixtures.ts +2 -2
  21. package/dist/templates/examples/map/src/main.ts +23 -21
  22. package/dist/templates/examples/map/src/scene.test.ts +4 -2
  23. package/dist/templates/examples/map/src/story.test.ts +9 -10
  24. package/dist/templates/examples/query-sync/src/main.ts +30 -29
  25. package/dist/templates/examples/query-sync/src/scene.test.ts +8 -15
  26. package/dist/templates/examples/query-sync/src/story.test.ts +21 -8
  27. package/dist/templates/examples/route-transitions/src/main.ts +15 -25
  28. package/dist/templates/examples/route-transitions/src/route.ts +21 -26
  29. package/dist/templates/examples/route-transitions/src/story.test.ts +20 -26
  30. package/dist/templates/examples/routing/src/fileTree.ts +3 -3
  31. package/dist/templates/examples/routing/src/main.ts +2 -12
  32. package/dist/templates/examples/routing/src/page/people.ts +18 -16
  33. package/dist/templates/examples/routing/src/route.ts +18 -32
  34. package/dist/templates/examples/routing/src/scene.test.ts +12 -20
  35. package/dist/templates/examples/routing/src/story.test.ts +9 -6
  36. package/dist/templates/examples/shopping-cart/src/route.ts +11 -19
  37. package/dist/templates/examples/shopping-cart/src/scene.test.ts +10 -8
  38. package/dist/templates/examples/shopping-cart/src/story.test.ts +2 -2
  39. package/dist/templates/examples/ssg/src/route.ts +9 -8
  40. package/dist/templates/examples/state-machine/src/main.ts +68 -63
  41. package/dist/templates/examples/state-machine/src/story.test.ts +8 -7
  42. package/dist/templates/examples/state-machine/src/view.ts +7 -13
  43. package/dist/templates/examples/todo/src/main.ts +11 -17
  44. package/dist/templates/examples/todo/src/scene.test.ts +2 -2
  45. package/dist/templates/examples/todo/src/story.test.ts +11 -12
  46. package/dist/templates/examples/ui-showcase/src/main.ts +64 -85
  47. package/dist/templates/examples/ui-showcase/src/scene.test.ts +14 -30
  48. package/dist/templates/examples/ui-showcase/src/story.test.ts +2 -2
  49. package/dist/templates/examples/ui-showcase/src/ui/message.ts +0 -70
  50. package/dist/templates/examples/view-transitions/src/main.ts +1 -1
  51. package/dist/templates/examples/view-transitions/src/route.ts +9 -12
  52. package/dist/templates/examples/view-transitions/src/scene.test.ts +5 -14
  53. package/dist/templates/examples/websocket-chat/src/main.ts +29 -37
  54. package/dist/templates/examples/websocket-chat/src/scene.test.ts +18 -10
  55. package/dist/templates/examples/websocket-chat/src/story.test.ts +19 -15
  56. package/dist/templates/release.json +13 -13
  57. package/dist/templates/rendering/ssg/src/route.ts +9 -8
  58. package/dist/templates/rendering/ssg/src/scene.test.ts +2 -2
  59. package/package.json +1 -1
@@ -31,7 +31,9 @@ Replace it whenever the project upgrades its Foldkit packages. If `./repos/foldk
31
31
  - Foldkit is tightly coupled to the Effect ecosystem. Do not suggest solutions outside of Effect-TS.
32
32
  - Model fields must be Schema types (the model is a schema). Plain TypeScript types are fine elsewhere (function return types, local variables, etc.).
33
33
  - Use full names like `Message` (not `Msg`), and `withReturnType` (not `as const` or type casting).
34
- - Use `defineMessageUnion()` for Message unions, `ts()` for tagged structs (Model states, field validation), and `r()` for route schemas.
34
+ - Declare every variant together: `defineMessageUnion()` for Messages, `defineTaggedUnion()` for other domain unions, and `defineRouteUnion()` for Routes.
35
+ - Keep constructors on their union: `Message.ClickedSubmit()`, `FetchState.Ok({ data })`, and `AppRoute.Home()`.
36
+ - Use `taggedStruct()` only when the variants cannot be declared together, such as a recursive union.
35
37
  - Push back on any direction that violates Elm Architecture principles: unidirectional data flow, messages as facts (not commands), model as single source of truth, side effects confined to commands. If a prompt suggests mutating state, imperative event handlers, or two-way bindings, flag the issue and propose the idiomatic Foldkit approach.
36
38
  - Never use `NoOp`. Every message must describe what happened. A command's result message is named from the command, not from the fact it reports, whether or not it carries a payload: `LockScroll` → `CompletedLockScroll`, `DetermineStartTime` → `CompletedDetermineStartTime` (never `DeterminedStartTime`).
37
39
 
@@ -9,7 +9,7 @@ import { SESSION_STORAGE_KEY } from './constant'
9
9
  import { Session, SessionJsonString } from './domain/session'
10
10
  import { Message } from './message'
11
11
  import { LoggedIn, LoggedOut, Model } from './model'
12
- import { DashboardRoute, LoginRoute, urlToAppRoute } from './route'
12
+ import { AppRoute, urlToAppRoute } from './route'
13
13
  import { RedirectToDashboard, RedirectToLogin } from './update'
14
14
 
15
15
  // FLAGS
@@ -56,7 +56,7 @@ export const init: Runtime.RoutingApplicationInit<Model, Message, Flags> = (
56
56
  model: LoggedOut.init(route),
57
57
  })),
58
58
  M.orElse(() => ({
59
- model: LoggedOut.init(LoginRoute()),
59
+ model: LoggedOut.init(AppRoute.Login()),
60
60
  commands: [RedirectToLogin()],
61
61
  })),
62
62
  ),
@@ -68,7 +68,7 @@ export const init: Runtime.RoutingApplicationInit<Model, Message, Flags> = (
68
68
  model: LoggedIn.init(route, session),
69
69
  })),
70
70
  M.orElse(() => ({
71
- model: LoggedIn.init(DashboardRoute(), session),
71
+ model: LoggedIn.init(AppRoute.Dashboard(), session),
72
72
  commands: [RedirectToDashboard()],
73
73
  })),
74
74
  ),
@@ -1,11 +1,11 @@
1
- import { ts } from 'foldkit/schema'
1
+ import { taggedStruct } from 'foldkit/schema'
2
2
 
3
3
  import { Session } from '../../domain/session'
4
4
  import { LoggedInRoute } from '../../route'
5
5
 
6
6
  // MODEL
7
7
 
8
- export const Model = ts('LoggedIn', {
8
+ export const Model = taggedStruct('LoggedIn', {
9
9
  route: LoggedInRoute,
10
10
  session: Session,
11
11
  })
@@ -1,11 +1,11 @@
1
- import { ts } from 'foldkit/schema'
1
+ import { taggedStruct } from 'foldkit/schema'
2
2
 
3
3
  import { LoggedOutRoute } from '../../route'
4
4
  import * as Login from './page/login'
5
5
 
6
6
  // MODEL
7
7
 
8
- export const Model = ts('LoggedOut', {
8
+ export const Model = taggedStruct('LoggedOut', {
9
9
  route: LoggedOutRoute,
10
10
  loginModel: Login.Model,
11
11
  })
@@ -1,46 +1,36 @@
1
1
  import { Schema as S, pipe } from 'effect'
2
2
  import { Route } from 'foldkit'
3
- import { literal, r } from 'foldkit/route'
3
+ import { defineRouteUnion, literal } from 'foldkit/route'
4
4
 
5
- export const HomeRoute = r('Home')
6
- export const LoginRoute = r('Login')
7
- export const DashboardRoute = r('Dashboard')
8
- export const SettingsRoute = r('Settings')
9
- export const NotFoundRoute = r('NotFound', { path: S.String })
5
+ export const AppRoute = defineRouteUnion({
6
+ Home: {},
7
+ Login: {},
8
+ Dashboard: {},
9
+ Settings: {},
10
+ NotFound: { path: S.String },
11
+ })
10
12
 
11
- export type HomeRoute = typeof HomeRoute.Type
12
- export type LoginRoute = typeof LoginRoute.Type
13
- export type DashboardRoute = typeof DashboardRoute.Type
14
- export type SettingsRoute = typeof SettingsRoute.Type
15
- export type NotFoundRoute = typeof NotFoundRoute.Type
13
+ export type AppRoute = typeof AppRoute.Type
16
14
 
17
- export const LoggedOutRoute = S.Union([HomeRoute, LoginRoute, NotFoundRoute])
18
- export const LoggedInRoute = S.Union([
19
- DashboardRoute,
20
- SettingsRoute,
21
- NotFoundRoute,
22
- ])
23
- export const AppRoute = S.Union([
24
- HomeRoute,
25
- LoginRoute,
26
- DashboardRoute,
27
- SettingsRoute,
28
- NotFoundRoute,
15
+ export const LoggedOutRoute = AppRoute.subset(['Home', 'Login', 'NotFound'])
16
+ export const LoggedInRoute = AppRoute.subset([
17
+ 'Dashboard',
18
+ 'Settings',
19
+ 'NotFound',
29
20
  ])
30
21
 
31
22
  export type LoggedOutRoute = typeof LoggedOutRoute.Type
32
23
  export type LoggedInRoute = typeof LoggedInRoute.Type
33
- export type AppRoute = typeof AppRoute.Type
34
24
 
35
- export const homeRouter = pipe(Route.root, Route.mapTo(HomeRoute))
36
- export const loginRouter = pipe(literal('login'), Route.mapTo(LoginRoute))
25
+ export const homeRouter = pipe(Route.root, Route.mapTo(AppRoute.Home))
26
+ export const loginRouter = pipe(literal('login'), Route.mapTo(AppRoute.Login))
37
27
  export const dashboardRouter = pipe(
38
28
  literal('dashboard'),
39
- Route.mapTo(DashboardRoute),
29
+ Route.mapTo(AppRoute.Dashboard),
40
30
  )
41
31
  export const settingsRouter = pipe(
42
32
  literal('settings'),
43
- Route.mapTo(SettingsRoute),
33
+ Route.mapTo(AppRoute.Settings),
44
34
  )
45
35
 
46
36
  const routeParser = Route.oneOf(
@@ -52,5 +42,5 @@ const routeParser = Route.oneOf(
52
42
 
53
43
  export const urlToAppRoute = Route.parseUrlWithFallback(
54
44
  routeParser,
55
- NotFoundRoute,
45
+ AppRoute.NotFound,
56
46
  )
@@ -20,12 +20,12 @@ import {
20
20
  SimulateAuthRequest,
21
21
  initModel as initLoginModel,
22
22
  } from './page/loggedOut/page/login'
23
- import { LoginRoute } from './route'
23
+ import { AppRoute } from './route'
24
24
  import { RedirectToDashboard, update } from './update'
25
25
  import { view } from './view'
26
26
 
27
27
  const validModel = LoggedOut.Model({
28
- route: LoginRoute(),
28
+ route: AppRoute.Login(),
29
29
  loginModel: LoginModel.make({
30
30
  ...initLoginModel(),
31
31
  email: Valid({ value: 'alice@example.com' }),
@@ -8,8 +8,7 @@ import { ClearSession, LogError, SaveSession } from './command'
8
8
  import { Message } from './message'
9
9
  import { LoggedIn, LoggedOut, Model } from './model'
10
10
  import {
11
- DashboardRoute,
12
- HomeRoute,
11
+ AppRoute,
13
12
  dashboardRouter,
14
13
  homeRouter,
15
14
  loginRouter,
@@ -62,7 +61,7 @@ const foldLoggedOutOutMessage: (
62
61
  SucceededLogin:
63
62
  ({ session }) =>
64
63
  () => ({
65
- model: LoggedIn.init(DashboardRoute(), session),
64
+ model: LoggedIn.init(AppRoute.Dashboard(), session),
66
65
  commands: [SaveSession({ session }), RedirectToDashboard()],
67
66
  }),
68
67
  }),
@@ -88,7 +87,7 @@ const foldLoggedInOutMessage: (
88
87
  M.withReturnType<Update.Step<Model, Message>>(),
89
88
  M.tagsExhaustive({
90
89
  RequestedLogout: () => () => ({
91
- model: LoggedOut.init(HomeRoute()),
90
+ model: LoggedOut.init(AppRoute.Home()),
92
91
  commands: [ClearSession(), RedirectToHome()],
93
92
  }),
94
93
  }),
@@ -21,7 +21,7 @@ import {
21
21
  } from 'foldkit/fieldValidation'
22
22
  import { type Attribute, Document, Html, HtmlBuilder } from 'foldkit/html'
23
23
  import { defineMessageUnion } from 'foldkit/message'
24
- import { ts } from 'foldkit/schema'
24
+ import { defineTaggedUnion } from 'foldkit/schema'
25
25
  import { evo } from 'foldkit/struct'
26
26
 
27
27
  import { Button, Input, Textarea } from '@foldkit/ui'
@@ -37,22 +37,13 @@ const emailRules = makeRules({
37
37
 
38
38
  // MODEL
39
39
 
40
- const NotSubmitted = ts('NotSubmitted')
41
- const Submitting = ts('Submitting')
42
- const SubmitSuccess = ts('SubmitSuccess', { confirmationText: S.String })
43
- const SubmitError = ts('SubmitError', { error: S.String })
44
-
45
- const Submission = S.Union([
46
- NotSubmitted,
47
- Submitting,
48
- SubmitSuccess,
49
- SubmitError,
50
- ])
51
-
52
- type NotSubmitted = typeof NotSubmitted.Type
53
- type Submitting = typeof Submitting.Type
54
- type SubmitSuccess = typeof SubmitSuccess.Type
55
- type SubmitError = typeof SubmitError.Type
40
+ const Submission = defineTaggedUnion({
41
+ NotSubmitted: {},
42
+ Submitting: {},
43
+ SubmitSuccess: { confirmationText: S.String },
44
+ SubmitError: { error: S.String },
45
+ })
46
+
56
47
  type Submission = typeof Submission.Type
57
48
 
58
49
  export const Model = S.Struct({
@@ -83,7 +74,7 @@ export const initialModel: Model = {
83
74
  name: NotValidated({ value: '' }),
84
75
  email: NotValidated({ value: '' }),
85
76
  messageText: NotValidated({ value: '' }),
86
- submission: NotSubmitted(),
77
+ submission: Submission.NotSubmitted(),
87
78
  }
88
79
 
89
80
  export const init: Runtime.ApplicationInit<Model, Message> = () => ({
@@ -191,7 +182,7 @@ export const update = (model: Model, message: Message) =>
191
182
 
192
183
  return {
193
184
  model: evo(model, {
194
- submission: () => Submitting(),
185
+ submission: () => Submission.Submitting(),
195
186
  }),
196
187
  commands: [
197
188
  SubmitForm({
@@ -206,7 +197,7 @@ export const update = (model: Model, message: Message) =>
206
197
  SucceededSubmitForm: ({ name }) => ({
207
198
  model: evo(model, {
208
199
  submission: () =>
209
- SubmitSuccess({
200
+ Submission.SubmitSuccess({
210
201
  confirmationText: `Welcome to the waitlist, ${name}! We'll be in touch soon.`,
211
202
  }),
212
203
  }),
@@ -215,7 +206,7 @@ export const update = (model: Model, message: Message) =>
215
206
  FailedSubmitForm: () => ({
216
207
  model: evo(model, {
217
208
  submission: () =>
218
- SubmitError({
209
+ Submission.SubmitError({
219
210
  error:
220
211
  'Sorry, there was an error adding you to the waitlist. Please try again.',
221
212
  }),
@@ -52,7 +52,7 @@ describe('view', () => {
52
52
  CancelUploadFile({ uploadId: 0 }),
53
53
  Message.CompletedCancelUploadFile({
54
54
  uploadId: 0,
55
- outcome: Interruptible.Interrupted(),
55
+ outcome: Interruptible.Outcome.Interrupted(),
56
56
  }),
57
57
  ),
58
58
  expect(text('Cancelled')).toExist(),
@@ -79,7 +79,7 @@ describe('view', () => {
79
79
  CancelUploadFile({ uploadId: 0 }),
80
80
  Message.CompletedCancelUploadFile({
81
81
  uploadId: 0,
82
- outcome: Interruptible.Interrupted(),
82
+ outcome: Interruptible.Outcome.Interrupted(),
83
83
  }),
84
84
  ),
85
85
  expect(role('button', { name: 'Cancel all' })).toBeAbsent(),
@@ -57,7 +57,7 @@ describe('update', () => {
57
57
  CancelUploadFile({ uploadId: 0 }),
58
58
  Message.CompletedCancelUploadFile({
59
59
  uploadId: 0,
60
- outcome: Interruptible.Interrupted(),
60
+ outcome: Interruptible.Outcome.Interrupted(),
61
61
  }),
62
62
  ),
63
63
  Command.expectNone(),
@@ -83,7 +83,7 @@ describe('update', () => {
83
83
  CancelUploadFile({ uploadId: 0 }),
84
84
  Message.CompletedCancelUploadFile({
85
85
  uploadId: 0,
86
- outcome: Interruptible.NotFound(),
86
+ outcome: Interruptible.Outcome.NotFound(),
87
87
  }),
88
88
  ),
89
89
  model(model => {
@@ -105,7 +105,7 @@ describe('update', () => {
105
105
  CancelUploadFile({ uploadId: 0 }),
106
106
  Message.CompletedCancelUploadFile({
107
107
  uploadId: 0,
108
- outcome: Interruptible.Interrupted(),
108
+ outcome: Interruptible.Outcome.Interrupted(),
109
109
  }),
110
110
  ),
111
111
  Command.expectExact(
@@ -135,7 +135,7 @@ describe('update', () => {
135
135
  CancelUploadFile({ uploadId: 0 }),
136
136
  Message.CompletedCancelUploadFile({
137
137
  uploadId: 0,
138
- outcome: Interruptible.Interrupted(),
138
+ outcome: Interruptible.Outcome.Interrupted(),
139
139
  }),
140
140
  ),
141
141
  Command.resolve(
@@ -161,7 +161,7 @@ describe('update', () => {
161
161
  CancelUploadFile({ uploadId: 0 }),
162
162
  Message.CompletedCancelUploadFile({
163
163
  uploadId: 0,
164
- outcome: Interruptible.Interrupted(),
164
+ outcome: Interruptible.Outcome.Interrupted(),
165
165
  }),
166
166
  ),
167
167
  message(Message.ClickedRestartUpload({ uploadId: 0 })),
@@ -201,14 +201,14 @@ describe('update', () => {
201
201
  CancelUploadFile({ uploadId: 0 }),
202
202
  Message.CompletedCancelUploadFile({
203
203
  uploadId: 0,
204
- outcome: Interruptible.Interrupted(),
204
+ outcome: Interruptible.Outcome.Interrupted(),
205
205
  }),
206
206
  ),
207
207
  Command.resolve(
208
208
  CancelUploadFile({ uploadId: 2 }),
209
209
  Message.CompletedCancelUploadFile({
210
210
  uploadId: 2,
211
- outcome: Interruptible.Interrupted(),
211
+ outcome: Interruptible.Outcome.Interrupted(),
212
212
  }),
213
213
  ),
214
214
  Command.expectNone(),
@@ -5,7 +5,7 @@ import { BrowserCrypto } from '@effect/platform-browser'
5
5
  import { Menu, Tabs } from '@foldkit/ui'
6
6
 
7
7
  import { Message } from './message'
8
- import { Model, NotSubmitted } from './model'
8
+ import { Model, Submission } from './model'
9
9
  import {
10
10
  Attachments,
11
11
  CoverLetter,
@@ -58,7 +58,7 @@ export const init: Runtime.ApplicationInit<Model, Message, Flags> = ({
58
58
  coverLetter: CoverLetter.init(),
59
59
  attachments: Attachments.init(),
60
60
  isPreviewVisible: false,
61
- submission: NotSubmitted(),
61
+ submission: Submission.NotSubmitted(),
62
62
  stepMenu: Menu.init({ id: 'step-menu' }),
63
63
  stepTabs: Tabs.init({ id: 'step-tabs' }),
64
64
  isSubmitAttempted: false,
@@ -1,5 +1,5 @@
1
1
  import { Schema as S } from 'effect'
2
- import { ts } from 'foldkit/schema'
2
+ import { defineTaggedUnion } from 'foldkit/schema'
3
3
 
4
4
  import { Menu, Tabs } from '@foldkit/ui'
5
5
 
@@ -15,17 +15,12 @@ import {
15
15
 
16
16
  // SUBMISSION
17
17
 
18
- export const NotSubmitted = ts('NotSubmitted')
19
- export const Submitting = ts('Submitting')
20
- export const SubmitSuccess = ts('SubmitSuccess')
21
- export const SubmitError = ts('SubmitError', { error: S.String })
22
-
23
- export const Submission = S.Union([
24
- NotSubmitted,
25
- Submitting,
26
- SubmitSuccess,
27
- SubmitError,
28
- ])
18
+ export const Submission = defineTaggedUnion({
19
+ NotSubmitted: {},
20
+ Submitting: {},
21
+ SubmitSuccess: {},
22
+ SubmitError: { error: S.String },
23
+ })
29
24
  export type Submission = typeof Submission.Type
30
25
 
31
26
  // MODEL
@@ -15,13 +15,7 @@ import { describe, test } from 'vitest'
15
15
  import { Menu, Tabs } from '@foldkit/ui'
16
16
  import { Message as TabsMessage } from '@foldkit/ui/tabs'
17
17
 
18
- import {
19
- type Model,
20
- NotSubmitted,
21
- SubmitError,
22
- SubmitSuccess,
23
- Submitting,
24
- } from './model'
18
+ import { type Model, Submission } from './model'
25
19
  import {
26
20
  Attachments,
27
21
  CoverLetter,
@@ -44,7 +38,7 @@ const initialModel: Model = {
44
38
  coverLetter: CoverLetter.init(),
45
39
  attachments: Attachments.init(),
46
40
  isPreviewVisible: false,
47
- submission: NotSubmitted(),
41
+ submission: Submission.NotSubmitted(),
48
42
  stepMenu: Menu.init({ id: 'step-menu' }),
49
43
  stepTabs: Tabs.init({ id: 'step-tabs' }),
50
44
  isSubmitAttempted: false,
@@ -236,7 +230,7 @@ describe('view', () => {
236
230
  given({
237
231
  ...initialModel,
238
232
  currentStep: 'Review',
239
- submission: Submitting(),
233
+ submission: Submission.Submitting(),
240
234
  }),
241
235
  expect(role('button', { name: 'Submitting...' })).toExist(),
242
236
  )
@@ -248,7 +242,7 @@ describe('view', () => {
248
242
  given({
249
243
  ...initialModel,
250
244
  currentStep: 'Review',
251
- submission: SubmitSuccess(),
245
+ submission: Submission.SubmitSuccess(),
252
246
  }),
253
247
  expect(text('Application Submitted', { exact: false })).toExist(),
254
248
  )
@@ -260,7 +254,7 @@ describe('view', () => {
260
254
  given({
261
255
  ...initialModel,
262
256
  currentStep: 'Review',
263
- submission: SubmitError({ error: 'Network down' }),
257
+ submission: Submission.SubmitError({ error: 'Network down' }),
264
258
  }),
265
259
  expect(text('Network down')).toExist(),
266
260
  expect(role('button', { name: 'Try Again' })).toExist(),
@@ -11,7 +11,7 @@ import { Message as TabsMessage } from '@foldkit/ui/tabs'
11
11
 
12
12
  import { SubmitApplication } from './command'
13
13
  import { Message } from './message'
14
- import { type Model, NotSubmitted, Submitting } from './model'
14
+ import { type Model, Submission } from './model'
15
15
  import {
16
16
  Attachments,
17
17
  CoverLetter,
@@ -39,7 +39,7 @@ const initialModel: Model = {
39
39
  coverLetter: CoverLetter.init(),
40
40
  attachments: Attachments.init(),
41
41
  isPreviewVisible: false,
42
- submission: NotSubmitted(),
42
+ submission: Submission.NotSubmitted(),
43
43
  stepMenu: Menu.init({ id: 'step-menu' }),
44
44
  stepTabs: Tabs.init({ id: 'step-tabs' }),
45
45
  isSubmitAttempted: false,
@@ -748,7 +748,7 @@ describe('update', () => {
748
748
  given({
749
749
  ...initialModel,
750
750
  currentStep: 'Review',
751
- submission: Submitting(),
751
+ submission: Submission.Submitting(),
752
752
  }),
753
753
  message(Message.SucceededSubmitApplication()),
754
754
  model(model => {
@@ -763,7 +763,7 @@ describe('update', () => {
763
763
  given({
764
764
  ...initialModel,
765
765
  currentStep: 'Review',
766
- submission: Submitting(),
766
+ submission: Submission.Submitting(),
767
767
  }),
768
768
  message(Message.FailedSubmitApplication({ error: 'Server down' })),
769
769
  model(model => {
@@ -7,7 +7,7 @@ import { Menu, Tabs } from '@foldkit/ui'
7
7
  import { SubmitApplication } from './command'
8
8
  import { Step } from './domain'
9
9
  import { Message } from './message'
10
- import { type Model, SubmitError, SubmitSuccess, Submitting } from './model'
10
+ import { type Model, Submission } from './model'
11
11
  import {
12
12
  Attachments,
13
13
  CoverLetter,
@@ -163,7 +163,9 @@ export const update = (model: Model, message: Message) =>
163
163
  })
164
164
  if (isApplicationComplete(revealedModel)) {
165
165
  return {
166
- model: evo(revealedModel, { submission: () => Submitting() }),
166
+ model: evo(revealedModel, {
167
+ submission: () => Submission.Submitting(),
168
+ }),
167
169
  commands: [SubmitApplication()],
168
170
  }
169
171
  }
@@ -171,10 +173,12 @@ export const update = (model: Model, message: Message) =>
171
173
  },
172
174
 
173
175
  SucceededSubmitApplication: () => ({
174
- model: evo(model, { submission: () => SubmitSuccess() }),
176
+ model: evo(model, { submission: () => Submission.SubmitSuccess() }),
175
177
  }),
176
178
 
177
179
  FailedSubmitApplication: ({ error }) => ({
178
- model: evo(model, { submission: () => SubmitError({ error }) }),
180
+ model: evo(model, {
181
+ submission: () => Submission.SubmitError({ error }),
182
+ }),
179
183
  }),
180
184
  })