create-foldkit-app 0.32.0 → 0.32.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 (149) hide show
  1. package/dist/commands/create.js +9 -7
  2. package/dist/templates/base/FOLDKIT.md +22 -6
  3. package/dist/templates/examples/api-cache/src/data.ts +14 -14
  4. package/dist/templates/examples/api-cache/src/main.ts +42 -39
  5. package/dist/templates/examples/auth/src/command.ts +3 -3
  6. package/dist/templates/examples/auth/src/domain/session.ts +8 -6
  7. package/dist/templates/examples/auth/src/main.ts +11 -11
  8. package/dist/templates/examples/auth/src/message.ts +3 -3
  9. package/dist/templates/examples/auth/src/model.ts +2 -2
  10. package/dist/templates/examples/auth/src/page/loggedIn/index.ts +1 -1
  11. package/dist/templates/examples/auth/src/page/loggedIn/view.ts +3 -3
  12. package/dist/templates/examples/auth/src/page/loggedOut/index.ts +1 -1
  13. package/dist/templates/examples/auth/src/page/loggedOut/page/login.ts +9 -17
  14. package/dist/templates/examples/auth/src/page/loggedOut/update.ts +4 -6
  15. package/dist/templates/examples/auth/src/page/loggedOut/view.ts +3 -3
  16. package/dist/templates/examples/auth/src/route.ts +2 -2
  17. package/dist/templates/examples/auth/src/update.ts +37 -40
  18. package/dist/templates/examples/auth/src/view.ts +6 -6
  19. package/dist/templates/examples/canvas-art/src/main.ts +22 -30
  20. package/dist/templates/examples/charting/src/command.ts +3 -3
  21. package/dist/templates/examples/charting/src/domain.ts +53 -48
  22. package/dist/templates/examples/charting/src/echarts.ts +6 -6
  23. package/dist/templates/examples/charting/src/githubApi.ts +33 -34
  24. package/dist/templates/examples/charting/src/http.ts +7 -7
  25. package/dist/templates/examples/charting/src/message.ts +6 -6
  26. package/dist/templates/examples/charting/src/model.ts +6 -6
  27. package/dist/templates/examples/charting/src/npmApi.ts +19 -15
  28. package/dist/templates/examples/charting/src/subscription.ts +5 -5
  29. package/dist/templates/examples/charting/src/telemetry.test.ts +18 -12
  30. package/dist/templates/examples/charting/src/telemetry.ts +11 -18
  31. package/dist/templates/examples/charting/src/update.ts +17 -23
  32. package/dist/templates/examples/charting/src/view/chart.ts +2 -2
  33. package/dist/templates/examples/counter/src/main.ts +2 -2
  34. package/dist/templates/examples/counters/src/counter.ts +2 -2
  35. package/dist/templates/examples/counters/src/main.ts +8 -8
  36. package/dist/templates/examples/embedding/src/main.ts +10 -7
  37. package/dist/templates/examples/form/src/main.ts +18 -14
  38. package/dist/templates/examples/generative-art/src/command.ts +7 -2
  39. package/dist/templates/examples/generative-art/src/message.ts +14 -14
  40. package/dist/templates/examples/generative-art/src/model.ts +21 -21
  41. package/dist/templates/examples/generative-art/src/update.ts +15 -17
  42. package/dist/templates/examples/interrupting-commands/src/main.ts +30 -27
  43. package/dist/templates/examples/job-application/src/domain/proficiencyLevel.ts +2 -2
  44. package/dist/templates/examples/job-application/src/domain/pronounOption.ts +2 -2
  45. package/dist/templates/examples/job-application/src/domain/step.ts +11 -11
  46. package/dist/templates/examples/job-application/src/main.ts +5 -5
  47. package/dist/templates/examples/job-application/src/message.ts +2 -2
  48. package/dist/templates/examples/job-application/src/model.ts +5 -5
  49. package/dist/templates/examples/job-application/src/step/attachments.ts +32 -34
  50. package/dist/templates/examples/job-application/src/step/coverLetter.ts +4 -4
  51. package/dist/templates/examples/job-application/src/step/education/education.ts +11 -14
  52. package/dist/templates/examples/job-application/src/step/education/entry.ts +21 -22
  53. package/dist/templates/examples/job-application/src/step/personalInfo.ts +44 -54
  54. package/dist/templates/examples/job-application/src/step/skills/entry.ts +12 -14
  55. package/dist/templates/examples/job-application/src/step/skills/skills.ts +11 -14
  56. package/dist/templates/examples/job-application/src/step/workHistory/entry.ts +43 -45
  57. package/dist/templates/examples/job-application/src/step/workHistory/workHistory.ts +11 -14
  58. package/dist/templates/examples/job-application/src/update.ts +17 -17
  59. package/dist/templates/examples/job-application/src/view/attachments.ts +5 -5
  60. package/dist/templates/examples/job-application/src/view/datePicker.ts +3 -3
  61. package/dist/templates/examples/job-application/src/view/field.ts +5 -5
  62. package/dist/templates/examples/job-application/src/view/index.ts +28 -22
  63. package/dist/templates/examples/kanban/src/command.ts +4 -4
  64. package/dist/templates/examples/kanban/src/domain/card.ts +6 -6
  65. package/dist/templates/examples/kanban/src/domain/column.ts +9 -9
  66. package/dist/templates/examples/kanban/src/main.ts +4 -4
  67. package/dist/templates/examples/kanban/src/message.ts +6 -6
  68. package/dist/templates/examples/kanban/src/model.ts +11 -9
  69. package/dist/templates/examples/kanban/src/update.ts +5 -5
  70. package/dist/templates/examples/managed-resource-layer/src/main.ts +20 -20
  71. package/dist/templates/examples/map/src/locations.ts +7 -7
  72. package/dist/templates/examples/map/src/main.ts +83 -44
  73. package/dist/templates/examples/map/src/mount.test.ts +127 -0
  74. package/dist/templates/examples/pixel-art/src/command.ts +12 -5
  75. package/dist/templates/examples/pixel-art/src/main.ts +4 -4
  76. package/dist/templates/examples/pixel-art/src/message.ts +7 -7
  77. package/dist/templates/examples/pixel-art/src/model.ts +34 -29
  78. package/dist/templates/examples/pixel-art/src/subscription.ts +2 -2
  79. package/dist/templates/examples/pixel-art/src/update.ts +79 -86
  80. package/dist/templates/examples/query-sync/src/main.ts +106 -102
  81. package/dist/templates/examples/route-transitions/src/data.ts +6 -6
  82. package/dist/templates/examples/route-transitions/src/main.ts +23 -29
  83. package/dist/templates/examples/route-transitions/src/route.ts +3 -3
  84. package/dist/templates/examples/routing/src/fileTree.ts +10 -8
  85. package/dist/templates/examples/routing/src/main.ts +23 -21
  86. package/dist/templates/examples/routing/src/page/people.ts +14 -22
  87. package/dist/templates/examples/routing/src/route.ts +7 -7
  88. package/dist/templates/examples/shopping-cart/src/main.ts +30 -31
  89. package/dist/templates/examples/shopping-cart/src/page/products.ts +10 -10
  90. package/dist/templates/examples/shopping-cart/src/route.ts +6 -4
  91. package/dist/templates/examples/slow-warnings/src/main.ts +35 -43
  92. package/dist/templates/examples/snake/src/domain/snake.ts +2 -2
  93. package/dist/templates/examples/snake/src/main.ts +39 -47
  94. package/dist/templates/examples/ssg/src/main.ts +5 -5
  95. package/dist/templates/examples/ssg/src/route.ts +2 -2
  96. package/dist/templates/examples/ssr/src/cookie.ts +3 -3
  97. package/dist/templates/examples/ssr/src/main.ts +10 -10
  98. package/dist/templates/examples/state-machine/src/main.ts +55 -53
  99. package/dist/templates/examples/state-machine/src/view.ts +7 -7
  100. package/dist/templates/examples/stopwatch/src/main.ts +10 -10
  101. package/dist/templates/examples/todo/src/main.ts +41 -34
  102. package/dist/templates/examples/ui-showcase/src/main.ts +54 -42
  103. package/dist/templates/examples/ui-showcase/src/scene.test.ts +1 -1
  104. package/dist/templates/examples/ui-showcase/src/ui/init.ts +1 -2
  105. package/dist/templates/examples/ui-showcase/src/ui/message.ts +17 -18
  106. package/dist/templates/examples/ui-showcase/src/ui/model.ts +47 -44
  107. package/dist/templates/examples/ui-showcase/src/ui/subscriptions.ts +1 -1
  108. package/dist/templates/examples/ui-showcase/src/ui/toast.ts +4 -4
  109. package/dist/templates/examples/ui-showcase/src/ui/update.ts +287 -298
  110. package/dist/templates/examples/ui-showcase/src/ui/view/animation.ts +2 -2
  111. package/dist/templates/examples/ui-showcase/src/ui/view/button.ts +1 -1
  112. package/dist/templates/examples/ui-showcase/src/ui/view/calendar.ts +4 -4
  113. package/dist/templates/examples/ui-showcase/src/ui/view/checkbox.ts +1 -1
  114. package/dist/templates/examples/ui-showcase/src/ui/view/combobox.ts +1 -1
  115. package/dist/templates/examples/ui-showcase/src/ui/view/datePicker.ts +4 -4
  116. package/dist/templates/examples/ui-showcase/src/ui/view/dialog.ts +1 -1
  117. package/dist/templates/examples/ui-showcase/src/ui/view/disclosure.ts +1 -1
  118. package/dist/templates/examples/ui-showcase/src/ui/view/dragAndDrop.ts +1 -1
  119. package/dist/templates/examples/ui-showcase/src/ui/view/fieldset.ts +1 -1
  120. package/dist/templates/examples/ui-showcase/src/ui/view/fileDrop.ts +6 -6
  121. package/dist/templates/examples/ui-showcase/src/ui/view/hoverIntent.ts +9 -20
  122. package/dist/templates/examples/ui-showcase/src/ui/view/input.ts +1 -1
  123. package/dist/templates/examples/ui-showcase/src/ui/view/listbox.ts +1 -1
  124. package/dist/templates/examples/ui-showcase/src/ui/view/menu.ts +15 -15
  125. package/dist/templates/examples/ui-showcase/src/ui/view/popover.ts +1 -1
  126. package/dist/templates/examples/ui-showcase/src/ui/view/radioGroup.ts +1 -1
  127. package/dist/templates/examples/ui-showcase/src/ui/view/select.ts +1 -1
  128. package/dist/templates/examples/ui-showcase/src/ui/view/slider.ts +1 -1
  129. package/dist/templates/examples/ui-showcase/src/ui/view/switch.ts +1 -1
  130. package/dist/templates/examples/ui-showcase/src/ui/view/tabs.ts +7 -7
  131. package/dist/templates/examples/ui-showcase/src/ui/view/textarea.ts +1 -1
  132. package/dist/templates/examples/ui-showcase/src/ui/view/toast.ts +8 -8
  133. package/dist/templates/examples/ui-showcase/src/ui/view/tooltip.ts +1 -1
  134. package/dist/templates/examples/ui-showcase/src/ui/view/virtualList.ts +7 -7
  135. package/dist/templates/examples/view-transitions/src/artwork.ts +7 -7
  136. package/dist/templates/examples/view-transitions/src/main.ts +6 -6
  137. package/dist/templates/examples/view-transitions/src/route.ts +3 -3
  138. package/dist/templates/examples/weather/src/main.ts +42 -42
  139. package/dist/templates/examples/weather/src/story.test.ts +5 -5
  140. package/dist/templates/examples/web-components/src/main.ts +16 -16
  141. package/dist/templates/examples/websocket-chat/src/main.ts +30 -30
  142. package/dist/templates/release.json +13 -13
  143. package/dist/templates/rendering/ssg/src/main.ts +5 -5
  144. package/dist/templates/rendering/ssg/src/route.ts +2 -2
  145. package/dist/templates/rendering/ssr/server/main.ts +15 -15
  146. package/dist/templates/rendering/ssr/src/cookie.ts +3 -3
  147. package/dist/templates/rendering/ssr/src/main.ts +10 -10
  148. package/dist/utils/packages.js +17 -0
  149. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { Array, Effect, Match as M, Option, Schema as S, String } from 'effect'
1
+ import { Array, Effect, Match, Option, Schema, String } from 'effect'
2
2
  import { HttpClient, HttpClientRequest } from 'effect/unstable/http'
3
3
  import { AsyncData, Command, Http, Runtime, type Update } from 'foldkit'
4
4
  import { Document, Html, HtmlBuilder } from 'foldkit/html'
@@ -9,21 +9,21 @@ import { Button, Input } from '@foldkit/ui'
9
9
 
10
10
  // MODEL
11
11
 
12
- export const WeatherData = S.Struct({
13
- zipCode: S.String,
14
- temperature: S.Number,
15
- description: S.String,
16
- humidity: S.Number,
17
- windSpeed: S.Number,
18
- locationName: S.String,
19
- region: S.String,
12
+ export const WeatherData = Schema.Struct({
13
+ zipCode: Schema.String,
14
+ temperature: Schema.Number,
15
+ description: Schema.String,
16
+ humidity: Schema.Number,
17
+ windSpeed: Schema.Number,
18
+ locationName: Schema.String,
19
+ region: Schema.String,
20
20
  })
21
21
  export type WeatherData = typeof WeatherData.Type
22
22
 
23
- export const WeatherAsyncData = AsyncData.Schema(WeatherData, S.String)
23
+ export const WeatherAsyncData = AsyncData.Schema(WeatherData, Schema.String)
24
24
 
25
- export const Model = S.Struct({
26
- zipCodeInput: S.String,
25
+ export const Model = Schema.Struct({
26
+ zipCodeInput: Schema.String,
27
27
  weather: WeatherAsyncData.schema,
28
28
  })
29
29
  export type Model = typeof Model.Type
@@ -31,10 +31,10 @@ export type Model = typeof Model.Type
31
31
  // MESSAGE
32
32
 
33
33
  export const Message = defineMessageUnion({
34
- UpdatedZipCodeInput: { value: S.String },
34
+ UpdatedZipCodeInput: { value: Schema.String },
35
35
  SubmittedWeatherForm: {},
36
36
  SucceededFetchWeather: { weather: WeatherData },
37
- FailedFetchWeather: { error: S.String },
37
+ FailedFetchWeather: { error: Schema.String },
38
38
  })
39
39
 
40
40
  export type Message = typeof Message.Type
@@ -86,39 +86,39 @@ export const init: Runtime.ApplicationInit<Model, Message> = () => ({
86
86
  const GEOCODING_API = 'https://geocoding-api.open-meteo.com/v1/search'
87
87
  const WEATHER_API = 'https://api.open-meteo.com/v1/forecast'
88
88
 
89
- const GeocodingResult = S.Struct({
90
- name: S.String,
91
- latitude: S.Number,
92
- longitude: S.Number,
93
- admin1: S.OptionFromOptional(S.String),
89
+ const GeocodingResult = Schema.Struct({
90
+ name: Schema.String,
91
+ latitude: Schema.Number,
92
+ longitude: Schema.Number,
93
+ admin1: Schema.OptionFromOptional(Schema.String),
94
94
  })
95
95
 
96
- const GeocodingResponse = S.Struct({
97
- results: S.OptionFromOptional(S.Array(GeocodingResult)),
96
+ const GeocodingResponse = Schema.Struct({
97
+ results: Schema.OptionFromOptional(Schema.Array(GeocodingResult)),
98
98
  })
99
99
 
100
- const WeatherResponse = S.Struct({
101
- current: S.Struct({
102
- temperature_2m: S.Number,
103
- relative_humidity_2m: S.Number,
104
- wind_speed_10m: S.Number,
105
- weather_code: S.Number,
100
+ const WeatherResponse = Schema.Struct({
101
+ current: Schema.Struct({
102
+ temperature_2m: Schema.Number,
103
+ relative_humidity_2m: Schema.Number,
104
+ wind_speed_10m: Schema.Number,
105
+ weather_code: Schema.Number,
106
106
  }),
107
107
  })
108
108
 
109
109
  const weatherCodeToDescription = (code: number): string =>
110
- M.value(code).pipe(
111
- M.when(0, () => 'Clear sky'),
112
- M.whenOr(1, 2, 3, () => 'Partly cloudy'),
113
- M.whenOr(45, 48, () => 'Foggy'),
114
- M.whenOr(51, 53, 55, () => 'Drizzle'),
115
- M.whenOr(61, 63, 65, () => 'Rain'),
116
- M.whenOr(66, 67, () => 'Freezing rain'),
117
- M.whenOr(71, 73, 75, 77, () => 'Snow'),
118
- M.whenOr(80, 81, 82, () => 'Rain showers'),
119
- M.whenOr(85, 86, () => 'Snow showers'),
120
- M.whenOr(95, 96, 99, () => 'Thunderstorm'),
121
- M.orElse(() => 'Unknown'),
110
+ Match.value(code).pipe(
111
+ Match.when(0, () => 'Clear sky'),
112
+ Match.whenOr(1, 2, 3, () => 'Partly cloudy'),
113
+ Match.whenOr(45, 48, () => 'Foggy'),
114
+ Match.whenOr(51, 53, 55, () => 'Drizzle'),
115
+ Match.whenOr(61, 63, 65, () => 'Rain'),
116
+ Match.whenOr(66, 67, () => 'Freezing rain'),
117
+ Match.whenOr(71, 73, 75, 77, () => 'Snow'),
118
+ Match.whenOr(80, 81, 82, () => 'Rain showers'),
119
+ Match.whenOr(85, 86, () => 'Snow showers'),
120
+ Match.whenOr(95, 96, 99, () => 'Thunderstorm'),
121
+ Match.orElse(() => 'Unknown'),
122
122
  )
123
123
 
124
124
  export const fetchWeatherEffect = (zipCode: string) =>
@@ -147,7 +147,7 @@ export const fetchWeatherEffect = (zipCode: string) =>
147
147
  )
148
148
  }
149
149
 
150
- const geocodeData = yield* S.decodeUnknownEffect(GeocodingResponse)(
150
+ const geocodeData = yield* Schema.decodeUnknownEffect(GeocodingResponse)(
151
151
  yield* geocodeResponse.json,
152
152
  )
153
153
 
@@ -180,7 +180,7 @@ export const fetchWeatherEffect = (zipCode: string) =>
180
180
  )
181
181
  }
182
182
 
183
- const weatherData = yield* S.decodeUnknownEffect(WeatherResponse)(
183
+ const weatherData = yield* Schema.decodeUnknownEffect(WeatherResponse)(
184
184
  yield* weatherResponse.json,
185
185
  )
186
186
 
@@ -205,7 +205,7 @@ export const fetchWeatherEffect = (zipCode: string) =>
205
205
  )
206
206
 
207
207
  export const FetchWeather = Command.define('FetchWeather', {
208
- args: { zipCode: S.String },
208
+ args: { zipCode: Schema.String },
209
209
  messages: [Message.SucceededFetchWeather, Message.FailedFetchWeather],
210
210
  execute: ({ zipCode }) =>
211
211
  Effect.provide(fetchWeatherEffect(zipCode), Http.layer),
@@ -1,4 +1,4 @@
1
- import { Effect, Layer, Match as M, String } from 'effect'
1
+ import { Effect, Layer, Match, String } from 'effect'
2
2
  import { HttpClient, HttpClientResponse } from 'effect/unstable/http'
3
3
  import { Command, given, message, model, story } from 'foldkit/story'
4
4
  import { expect, test } from 'vitest'
@@ -54,10 +54,10 @@ test('failed fetch shows failure state', () => {
54
54
  test('fetchWeather returns SucceededFetchWeather with data on success', async () => {
55
55
  const mockClient = HttpClient.make(request =>
56
56
  Effect.sync(() => {
57
- const responseData = M.value(request.url).pipe(
58
- M.when(String.includes('geocoding'), () => mockGeocodingResponse),
59
- M.when(String.includes('forecast'), () => mockWeatherResponse),
60
- M.orElse(url => {
57
+ const responseData = Match.value(request.url).pipe(
58
+ Match.when(String.includes('geocoding'), () => mockGeocodingResponse),
59
+ Match.when(String.includes('forecast'), () => mockWeatherResponse),
60
+ Match.orElse(url => {
61
61
  throw new Error(`Unexpected request URL: ${url}`)
62
62
  }),
63
63
  )
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx'
2
- import { Schema as S } from 'effect'
2
+ import { Schema } from 'effect'
3
3
  import { CustomElement, Runtime, type Update } from 'foldkit'
4
4
  import { Document, Html, HtmlBuilder } from 'foldkit/html'
5
5
  import { defineMessageUnion } from 'foldkit/message'
@@ -11,19 +11,19 @@ import '@shoelace-style/shoelace/dist/components/qr-code/qr-code.js'
11
11
 
12
12
  // MODEL
13
13
 
14
- export const Model = S.Struct({
15
- content: S.String,
16
- fillColor: S.String,
17
- backgroundColor: S.String,
14
+ export const Model = Schema.Struct({
15
+ content: Schema.String,
16
+ fillColor: Schema.String,
17
+ backgroundColor: Schema.String,
18
18
  })
19
19
  export type Model = typeof Model.Type
20
20
 
21
21
  // MESSAGE
22
22
 
23
23
  export const Message = defineMessageUnion({
24
- UpdatedContent: { value: S.String },
25
- ChangedFillColor: { value: S.String },
26
- ChangedBackgroundColor: { value: S.String },
24
+ UpdatedContent: { value: Schema.String },
25
+ ChangedFillColor: { value: Schema.String },
26
+ ChangedBackgroundColor: { value: Schema.String },
27
27
  })
28
28
 
29
29
  export type Message = typeof Message.Type
@@ -62,22 +62,22 @@ export const update = (model: Model, message: Message) =>
62
62
  export const hexColorPicker = CustomElement.define({
63
63
  tag: 'hex-color-picker',
64
64
  properties: {
65
- color: S.String,
65
+ color: Schema.String,
66
66
  },
67
67
  events: {
68
- 'color-changed': S.Struct({ value: S.String }),
68
+ 'color-changed': Schema.Struct({ value: Schema.String }),
69
69
  },
70
70
  })
71
71
 
72
72
  const qrCode = CustomElement.define({
73
73
  tag: 'sl-qr-code',
74
74
  properties: {
75
- value: S.String,
76
- label: S.String,
77
- size: S.Number,
78
- fill: S.String,
79
- background: S.String,
80
- radius: S.Number,
75
+ value: Schema.String,
76
+ label: Schema.String,
77
+ size: Schema.Number,
78
+ fill: Schema.String,
79
+ background: Schema.String,
80
+ radius: Schema.Number,
81
81
  },
82
82
  events: {},
83
83
  })
@@ -3,10 +3,10 @@ import {
3
3
  DateTime,
4
4
  Duration,
5
5
  Effect,
6
- Match as M,
6
+ Match,
7
7
  Option,
8
8
  Queue,
9
- Schema as S,
9
+ Schema,
10
10
  Stream,
11
11
  String,
12
12
  } from 'effect'
@@ -33,10 +33,10 @@ const getZonedTime = DateTime.now.pipe(
33
33
 
34
34
  // MODEL
35
35
 
36
- const ChatMessage = S.Struct({
37
- text: S.String,
38
- zoned: S.DateTimeZoned,
39
- isSent: S.Boolean,
36
+ const ChatMessage = Schema.Struct({
37
+ text: Schema.String,
38
+ zoned: Schema.DateTimeZoned,
39
+ isSent: Schema.Boolean,
40
40
  })
41
41
 
42
42
  type ChatMessage = typeof ChatMessage.Type
@@ -48,14 +48,14 @@ export const ConnectionState = defineTaggedUnion({
48
48
  Disconnected: {},
49
49
  Connecting: {},
50
50
  Connected: {},
51
- Error: { error: S.String },
51
+ Error: { error: Schema.String },
52
52
  })
53
53
  export type ConnectionState = typeof ConnectionState.Type
54
54
 
55
- export const Model = S.Struct({
55
+ export const Model = Schema.Struct({
56
56
  connection: ConnectionState,
57
- messages: S.Array(ChatMessage),
58
- messageInput: S.String,
57
+ messages: Schema.Array(ChatMessage),
58
+ messageInput: Schema.String,
59
59
  })
60
60
 
61
61
  export type Model = typeof Model.Type
@@ -66,15 +66,15 @@ export const Message = defineMessageUnion({
66
66
  ClickedConnect: {},
67
67
  Connected: {},
68
68
  Disconnected: {},
69
- FailedConnect: { error: S.String },
70
- UpdatedMessageInput: { value: S.String },
69
+ FailedConnect: { error: Schema.String },
70
+ UpdatedMessageInput: { value: Schema.String },
71
71
  SubmittedMessage: {},
72
- SucceededSendMessage: { text: S.String },
73
- ReceivedMessage: { text: S.String },
72
+ SucceededSendMessage: { text: Schema.String },
73
+ ReceivedMessage: { text: Schema.String },
74
74
  TimestampedMessage: {
75
- text: S.String,
76
- zoned: S.DateTimeZoned,
77
- isSent: S.Boolean,
75
+ text: Schema.String,
76
+ zoned: Schema.DateTimeZoned,
77
+ isSent: Schema.Boolean,
78
78
  },
79
79
  })
80
80
 
@@ -124,15 +124,15 @@ export const update = (model: Model, message: Message) =>
124
124
  return { model }
125
125
  }
126
126
 
127
- return M.value(model.connection).pipe(
128
- M.withReturnType<UpdateReturn>(),
129
- M.tag('Connected', () => ({
127
+ return Match.value(model.connection).pipe(
128
+ Match.withReturnType<UpdateReturn>(),
129
+ Match.tag('Connected', () => ({
130
130
  model: evo(model, {
131
131
  messageInput: () => '',
132
132
  }),
133
133
  commands: [SendMessage({ text: trimmedMessage })],
134
134
  })),
135
- M.orElse(() => ({ model })),
135
+ Match.orElse(() => ({ model })),
136
136
  )
137
137
  },
138
138
 
@@ -170,7 +170,7 @@ export const init: Runtime.ApplicationInit<Model, Message> = () => ({
170
170
  // COMMAND
171
171
 
172
172
  export const TimestampSentMessage = Command.define('TimestampSentMessage', {
173
- args: { text: S.String },
173
+ args: { text: Schema.String },
174
174
  messages: [Message.TimestampedMessage],
175
175
  execute: ({ text }) =>
176
176
  getZonedTime.pipe(
@@ -183,7 +183,7 @@ export const TimestampSentMessage = Command.define('TimestampSentMessage', {
183
183
  export const TimestampReceivedMessage = Command.define(
184
184
  'TimestampReceivedMessage',
185
185
  {
186
- args: { text: S.String },
186
+ args: { text: Schema.String },
187
187
  messages: [Message.TimestampedMessage],
188
188
  execute: ({ text }) =>
189
189
  getZonedTime.pipe(
@@ -195,7 +195,7 @@ export const TimestampReceivedMessage = Command.define(
195
195
  )
196
196
 
197
197
  export const SendMessage = Command.define('SendMessage', {
198
- args: { text: S.String },
198
+ args: { text: Schema.String },
199
199
  messages: [Message.SucceededSendMessage, Message.FailedConnect],
200
200
  execute: ({ text }) =>
201
201
  ChatSocket.get.pipe(
@@ -215,13 +215,13 @@ export const SendMessage = Command.define('SendMessage', {
215
215
 
216
216
  export const managedResources = ManagedResource.make<Model, Message>()(
217
217
  entry => ({
218
- chatSocket: entry(S.Option(S.Null), {
218
+ chatSocket: entry(Schema.Option(Schema.Null), {
219
219
  resource: ChatSocket,
220
220
  modelToMaybeRequirements: model =>
221
- M.value(model.connection).pipe(
222
- M.tag('Connecting', () => Option.some(null)),
223
- M.tag('Connected', () => Option.some(null)),
224
- M.orElse(() => Option.none()),
221
+ Match.value(model.connection).pipe(
222
+ Match.tag('Connecting', () => Option.some(null)),
223
+ Match.tag('Connected', () => Option.some(null)),
224
+ Match.orElse(() => Option.none()),
225
225
  ),
226
226
  acquire: () =>
227
227
  Effect.callback<WebSocket, Error>(resume => {
@@ -313,7 +313,7 @@ export const subscriptions = Subscription.make<
313
313
  ChatSocketService
314
314
  >()(entry => ({
315
315
  isConnected: entry(
316
- { isConnected: S.Boolean },
316
+ { isConnected: Schema.Boolean },
317
317
  {
318
318
  modelToDependencies: model => ({
319
319
  isConnected: model.connection._tag === 'Connected',
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "channel": "stable",
4
- "sourceCommit": "00c836c7927fd2e89e969c4b25974a371e299451",
4
+ "sourceCommit": "2f739758a2786fb72c0983e125a6f3d2f8eae56a",
5
5
  "packages": {
6
- "create-foldkit-app": "0.32.0",
7
- "@foldkit/devtools": "0.155.0",
8
- "@foldkit/devtools-mcp": "0.19.2",
9
- "foldkit": "0.155.0",
10
- "@foldkit/markdown": "0.8.1",
11
- "@foldkit/oxlint-plugin": "0.11.0",
12
- "@foldkit/ui": "0.155.0",
13
- "@foldkit/vite-plugin": "0.20.0"
6
+ "create-foldkit-app": "0.32.1",
7
+ "@foldkit/devtools": "0.157.0",
8
+ "@foldkit/devtools-mcp": "0.19.3",
9
+ "foldkit": "0.157.0",
10
+ "@foldkit/markdown": "0.9.0",
11
+ "@foldkit/oxlint-plugin": "0.12.0",
12
+ "@foldkit/ui": "0.157.0",
13
+ "@foldkit/vite-plugin": "0.20.1"
14
14
  },
15
15
  "dependencies": {
16
- "@foldkit/devtools": "0.155.0",
17
- "@foldkit/vite-plugin": "0.20.0",
18
- "@foldkit/devtools-mcp": "0.19.2",
19
- "@foldkit/oxlint-plugin": "0.11.0",
16
+ "@foldkit/devtools": "0.157.0",
17
+ "@foldkit/vite-plugin": "0.20.1",
18
+ "@foldkit/devtools-mcp": "0.19.3",
19
+ "@foldkit/oxlint-plugin": "0.12.0",
20
20
  "@trivago/prettier-plugin-sort-imports": "^6.0.2",
21
21
  "@types/node": "^26.4.0",
22
22
  "happy-dom": "^20.11.13",
@@ -1,4 +1,4 @@
1
- import { Effect, Schema as S, pipe } from 'effect'
1
+ import { Effect, Schema, pipe } from 'effect'
2
2
  import { Command, Runtime, type Update } from 'foldkit'
3
3
  import { type Document, type Html, type HtmlBuilder } from 'foldkit/html'
4
4
  import { defineMessageUnion } from 'foldkit/message'
@@ -10,9 +10,9 @@ import { AppRoute, aboutRouter, homeRouter, urlToAppRoute } from './route'
10
10
 
11
11
  // MODEL
12
12
 
13
- export const Model = S.Struct({
13
+ export const Model = Schema.Struct({
14
14
  route: AppRoute,
15
- count: S.Number,
15
+ count: Schema.Number,
16
16
  })
17
17
  export type Model = typeof Model.Type
18
18
 
@@ -37,14 +37,14 @@ export const init: Runtime.RoutingApplicationInit<Model, Message> = url => ({
37
37
  // COMMAND
38
38
 
39
39
  const NavigateInternal = Command.define('NavigateInternal', {
40
- args: { url: S.String },
40
+ args: { url: Schema.String },
41
41
  messages: [Message.CompletedNavigateInternal],
42
42
  execute: ({ url }) =>
43
43
  pushUrl(url).pipe(Effect.as(Message.CompletedNavigateInternal())),
44
44
  })
45
45
 
46
46
  const LoadExternal = Command.define('LoadExternal', {
47
- args: { href: S.String },
47
+ args: { href: Schema.String },
48
48
  messages: [Message.CompletedLoadExternal],
49
49
  execute: ({ href }) =>
50
50
  load(href).pipe(Effect.as(Message.CompletedLoadExternal())),
@@ -1,11 +1,11 @@
1
- import { Schema as S, pipe } from 'effect'
1
+ import { Schema, pipe } from 'effect'
2
2
  import { Route } from 'foldkit'
3
3
  import { defineRouteUnion, literal } from 'foldkit/route'
4
4
 
5
5
  export const AppRoute = defineRouteUnion({
6
6
  Home: {},
7
7
  About: {},
8
- NotFound: { path: S.String },
8
+ NotFound: { path: Schema.String },
9
9
  })
10
10
 
11
11
  export type AppRoute = typeof AppRoute.Type
@@ -1,4 +1,4 @@
1
- import { Config, Effect, FileSystem, Layer, Match as M, Option } from 'effect'
1
+ import { Config, Effect, FileSystem, Layer, Match, Option } from 'effect'
2
2
  import {
3
3
  Headers as HttpHeaders,
4
4
  HttpServer,
@@ -88,12 +88,12 @@ const requestKind = ({
88
88
  method,
89
89
  url,
90
90
  }: HttpServerRequest.HttpServerRequest): RequestKind =>
91
- M.value(method).pipe(
92
- M.withReturnType<RequestKind>(),
93
- M.whenOr('GET', 'HEAD', () =>
91
+ Match.value(method).pipe(
92
+ Match.withReturnType<RequestKind>(),
93
+ Match.whenOr('GET', 'HEAD', () =>
94
94
  Server.resolvesToIndexHtml(url) ? 'Render' : 'StaticOrRender',
95
95
  ),
96
- M.orElse(() =>
96
+ Match.orElse(() =>
97
97
  Server.isHostSettledMethod(method) ? 'HostSettled' : 'Render',
98
98
  ),
99
99
  )
@@ -138,21 +138,21 @@ const makeHandler = Effect.gen(function* () {
138
138
  ) =>
139
139
  staticFiles.pipe(
140
140
  Effect.catchIf(isRouteNotFound, () =>
141
- M.value(
141
+ Match.value(
142
142
  Server.classifyRequest(
143
143
  request.url,
144
144
  request.headers['sec-fetch-dest'],
145
145
  ),
146
146
  ).pipe(
147
- M.when('PathAsset', () =>
147
+ Match.when('PathAsset', () =>
148
148
  Effect.succeed(HttpServerResponse.empty({ status: 404 })),
149
149
  ),
150
- M.when('DestinationAsset', () =>
150
+ Match.when('DestinationAsset', () =>
151
151
  Effect.succeed(
152
152
  withNegotiatedVary(HttpServerResponse.empty({ status: 404 })),
153
153
  ),
154
154
  ),
155
- M.when('Page', () =>
155
+ Match.when('Page', () =>
156
156
  Server.acceptsHtml(request.headers['accept'])
157
157
  ? renderRequest(request, template, requestUrl).pipe(
158
158
  Effect.map(withNegotiatedVary),
@@ -161,7 +161,7 @@ const makeHandler = Effect.gen(function* () {
161
161
  withNegotiatedVary(HttpServerResponse.empty({ status: 404 })),
162
162
  ),
163
163
  ),
164
- M.exhaustive,
164
+ Match.exhaustive,
165
165
  ),
166
166
  ),
167
167
  )
@@ -175,15 +175,15 @@ const makeHandler = Effect.gen(function* () {
175
175
  const normalizedRequest = request.modify({
176
176
  url: `${resolved.pathname}${resolved.search}`,
177
177
  })
178
- const response = M.value(requestKind(normalizedRequest)).pipe(
179
- M.when('Render', () =>
178
+ const response = Match.value(requestKind(normalizedRequest)).pipe(
179
+ Match.when('Render', () =>
180
180
  renderRequest(normalizedRequest, template, requestUrl),
181
181
  ),
182
- M.when('StaticOrRender', () =>
182
+ Match.when('StaticOrRender', () =>
183
183
  serveStaticOrRender(normalizedRequest, requestUrl),
184
184
  ),
185
- M.when('HostSettled', () => Effect.succeed(hostSettledResponse())),
186
- M.exhaustive,
185
+ Match.when('HostSettled', () => Effect.succeed(hostSettledResponse())),
186
+ Match.exhaustive,
187
187
  )
188
188
  return Effect.provideService(
189
189
  response,
@@ -1,4 +1,4 @@
1
- import { Number as Number_, Option, Record, pipe } from 'effect'
1
+ import { Number, Option, Record, pipe } from 'effect'
2
2
  import { Cookies } from 'effect/unstable/http'
3
3
 
4
4
  export const COUNT_COOKIE = 'count'
@@ -7,7 +7,7 @@ export const readCountCookie = (cookieHeader: string): number =>
7
7
  pipe(
8
8
  Cookies.parseHeader(cookieHeader),
9
9
  Record.get(COUNT_COOKIE),
10
- Option.flatMap(Number_.parse),
11
- Option.filter(Number.isSafeInteger),
10
+ Option.flatMap(Number.parse),
11
+ Option.filter(globalThis.Number.isSafeInteger),
12
12
  Option.getOrElse(() => 0),
13
13
  )
@@ -1,4 +1,4 @@
1
- import { Effect, Schema as S } from 'effect'
1
+ import { Effect, Schema } from 'effect'
2
2
  import { Command, Runtime, type Update } from 'foldkit'
3
3
  import { type Document, type HtmlBuilder } from 'foldkit/html'
4
4
  import { defineMessageUnion } from 'foldkit/message'
@@ -10,19 +10,19 @@ import { COUNT_COOKIE } from './cookie'
10
10
 
11
11
  // MODEL
12
12
 
13
- export const Model = S.Struct({
14
- count: S.Number,
15
- renderedAt: S.String,
16
- renderedOn: S.Literals(['Server', 'Client']),
13
+ export const Model = Schema.Struct({
14
+ count: Schema.Number,
15
+ renderedAt: Schema.String,
16
+ renderedOn: Schema.Literals(['Server', 'Client']),
17
17
  })
18
18
  export type Model = typeof Model.Type
19
19
 
20
20
  // FLAGS
21
21
 
22
- export const Flags = S.Struct({
23
- initialCount: S.Number,
24
- renderedAt: S.String,
25
- renderedOn: S.Literals(['Server', 'Client']),
22
+ export const Flags = Schema.Struct({
23
+ initialCount: Schema.Number,
24
+ renderedAt: Schema.String,
25
+ renderedOn: Schema.Literals(['Server', 'Client']),
26
26
  })
27
27
  export type Flags = typeof Flags.Type
28
28
 
@@ -62,7 +62,7 @@ export const update = (model: Model, message: Message) =>
62
62
  const COUNT_COOKIE_MAX_AGE_SECONDS = 31536000
63
63
 
64
64
  export const PersistCount = Command.define('PersistCount', {
65
- args: { count: S.Number },
65
+ args: { count: Schema.Number },
66
66
  messages: [Message.CompletedPersistCount],
67
67
  execute: ({ count }) =>
68
68
  Effect.try(() => {
@@ -115,6 +115,23 @@ const readReleaseManifest = Effect.gen(function* () {
115
115
  const content = yield* fs.readFileString(path.join(templateRoot, 'release.json'));
116
116
  return yield* Schema.decodeUnknownEffect(ReleaseManifest)(JSON.parse(content));
117
117
  });
118
+ /**
119
+ * The git ref in the Foldkit repository that matches a CLI release manifest.
120
+ * A stable release is tagged `foldkit@<version>` at promotion, so the ref is
121
+ * that tag for the manifest's `foldkit` package. A canary release is
122
+ * commit-addressed and never tagged, so the ref is its source commit.
123
+ */
124
+ export const foldkitSubtreeRef = (manifest) => Match.value(manifest.channel).pipe(Match.when('stable', () => Option.match(Record.get(manifest.packages, 'foldkit'), {
125
+ onNone: () => manifest.sourceCommit,
126
+ onSome: version => `foldkit@${version}`,
127
+ })), Match.when('canary', () => manifest.sourceCommit), Match.exhaustive);
128
+ /**
129
+ * The subtree ref for the release manifest bundled with this CLI. The create
130
+ * command resolves it before scaffolding, so a broken manifest fails before
131
+ * any files are created, then prints it in the success message so the user
132
+ * vendors the Foldkit repository at the release the scaffold installs.
133
+ */
134
+ export const readFoldkitSubtreeRef = Effect.map(readReleaseManifest, foldkitSubtreeRef);
118
135
  const releaseVersions = (manifest) => Record.union(manifest.dependencies, manifest.packages, (_, version) => version);
119
136
  const resolveReleaseVersion = (versions, name) => Option.match(Record.get(versions, name), {
120
137
  onNone: () => Effect.fail(`The CLI release does not declare ${name}.`),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-foldkit-app",
3
- "version": "0.32.0",
3
+ "version": "0.32.1",
4
4
  "description": "Create Foldkit applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",