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.
- package/dist/commands/create.js +9 -7
- package/dist/templates/base/FOLDKIT.md +22 -6
- package/dist/templates/examples/api-cache/src/data.ts +14 -14
- package/dist/templates/examples/api-cache/src/main.ts +42 -39
- package/dist/templates/examples/auth/src/command.ts +3 -3
- package/dist/templates/examples/auth/src/domain/session.ts +8 -6
- package/dist/templates/examples/auth/src/main.ts +11 -11
- package/dist/templates/examples/auth/src/message.ts +3 -3
- package/dist/templates/examples/auth/src/model.ts +2 -2
- package/dist/templates/examples/auth/src/page/loggedIn/index.ts +1 -1
- package/dist/templates/examples/auth/src/page/loggedIn/view.ts +3 -3
- package/dist/templates/examples/auth/src/page/loggedOut/index.ts +1 -1
- package/dist/templates/examples/auth/src/page/loggedOut/page/login.ts +9 -17
- package/dist/templates/examples/auth/src/page/loggedOut/update.ts +4 -6
- package/dist/templates/examples/auth/src/page/loggedOut/view.ts +3 -3
- package/dist/templates/examples/auth/src/route.ts +2 -2
- package/dist/templates/examples/auth/src/update.ts +37 -40
- package/dist/templates/examples/auth/src/view.ts +6 -6
- package/dist/templates/examples/canvas-art/src/main.ts +22 -30
- package/dist/templates/examples/charting/src/command.ts +3 -3
- package/dist/templates/examples/charting/src/domain.ts +53 -48
- package/dist/templates/examples/charting/src/echarts.ts +6 -6
- package/dist/templates/examples/charting/src/githubApi.ts +33 -34
- package/dist/templates/examples/charting/src/http.ts +7 -7
- package/dist/templates/examples/charting/src/message.ts +6 -6
- package/dist/templates/examples/charting/src/model.ts +6 -6
- package/dist/templates/examples/charting/src/npmApi.ts +19 -15
- package/dist/templates/examples/charting/src/subscription.ts +5 -5
- package/dist/templates/examples/charting/src/telemetry.test.ts +18 -12
- package/dist/templates/examples/charting/src/telemetry.ts +11 -18
- package/dist/templates/examples/charting/src/update.ts +17 -23
- package/dist/templates/examples/charting/src/view/chart.ts +2 -2
- package/dist/templates/examples/counter/src/main.ts +2 -2
- package/dist/templates/examples/counters/src/counter.ts +2 -2
- package/dist/templates/examples/counters/src/main.ts +8 -8
- package/dist/templates/examples/embedding/src/main.ts +10 -7
- package/dist/templates/examples/form/src/main.ts +18 -14
- package/dist/templates/examples/generative-art/src/command.ts +7 -2
- package/dist/templates/examples/generative-art/src/message.ts +14 -14
- package/dist/templates/examples/generative-art/src/model.ts +21 -21
- package/dist/templates/examples/generative-art/src/update.ts +15 -17
- package/dist/templates/examples/interrupting-commands/src/main.ts +30 -27
- package/dist/templates/examples/job-application/src/domain/proficiencyLevel.ts +2 -2
- package/dist/templates/examples/job-application/src/domain/pronounOption.ts +2 -2
- package/dist/templates/examples/job-application/src/domain/step.ts +11 -11
- package/dist/templates/examples/job-application/src/main.ts +5 -5
- package/dist/templates/examples/job-application/src/message.ts +2 -2
- package/dist/templates/examples/job-application/src/model.ts +5 -5
- package/dist/templates/examples/job-application/src/step/attachments.ts +32 -34
- package/dist/templates/examples/job-application/src/step/coverLetter.ts +4 -4
- package/dist/templates/examples/job-application/src/step/education/education.ts +11 -14
- package/dist/templates/examples/job-application/src/step/education/entry.ts +21 -22
- package/dist/templates/examples/job-application/src/step/personalInfo.ts +44 -54
- package/dist/templates/examples/job-application/src/step/skills/entry.ts +12 -14
- package/dist/templates/examples/job-application/src/step/skills/skills.ts +11 -14
- package/dist/templates/examples/job-application/src/step/workHistory/entry.ts +43 -45
- package/dist/templates/examples/job-application/src/step/workHistory/workHistory.ts +11 -14
- package/dist/templates/examples/job-application/src/update.ts +17 -17
- package/dist/templates/examples/job-application/src/view/attachments.ts +5 -5
- package/dist/templates/examples/job-application/src/view/datePicker.ts +3 -3
- package/dist/templates/examples/job-application/src/view/field.ts +5 -5
- package/dist/templates/examples/job-application/src/view/index.ts +28 -22
- package/dist/templates/examples/kanban/src/command.ts +4 -4
- package/dist/templates/examples/kanban/src/domain/card.ts +6 -6
- package/dist/templates/examples/kanban/src/domain/column.ts +9 -9
- package/dist/templates/examples/kanban/src/main.ts +4 -4
- package/dist/templates/examples/kanban/src/message.ts +6 -6
- package/dist/templates/examples/kanban/src/model.ts +11 -9
- package/dist/templates/examples/kanban/src/update.ts +5 -5
- package/dist/templates/examples/managed-resource-layer/src/main.ts +20 -20
- package/dist/templates/examples/map/src/locations.ts +7 -7
- package/dist/templates/examples/map/src/main.ts +83 -44
- package/dist/templates/examples/map/src/mount.test.ts +127 -0
- package/dist/templates/examples/pixel-art/src/command.ts +12 -5
- package/dist/templates/examples/pixel-art/src/main.ts +4 -4
- package/dist/templates/examples/pixel-art/src/message.ts +7 -7
- package/dist/templates/examples/pixel-art/src/model.ts +34 -29
- package/dist/templates/examples/pixel-art/src/subscription.ts +2 -2
- package/dist/templates/examples/pixel-art/src/update.ts +79 -86
- package/dist/templates/examples/query-sync/src/main.ts +106 -102
- package/dist/templates/examples/route-transitions/src/data.ts +6 -6
- package/dist/templates/examples/route-transitions/src/main.ts +23 -29
- package/dist/templates/examples/route-transitions/src/route.ts +3 -3
- package/dist/templates/examples/routing/src/fileTree.ts +10 -8
- package/dist/templates/examples/routing/src/main.ts +23 -21
- package/dist/templates/examples/routing/src/page/people.ts +14 -22
- package/dist/templates/examples/routing/src/route.ts +7 -7
- package/dist/templates/examples/shopping-cart/src/main.ts +30 -31
- package/dist/templates/examples/shopping-cart/src/page/products.ts +10 -10
- package/dist/templates/examples/shopping-cart/src/route.ts +6 -4
- package/dist/templates/examples/slow-warnings/src/main.ts +35 -43
- package/dist/templates/examples/snake/src/domain/snake.ts +2 -2
- package/dist/templates/examples/snake/src/main.ts +39 -47
- package/dist/templates/examples/ssg/src/main.ts +5 -5
- package/dist/templates/examples/ssg/src/route.ts +2 -2
- package/dist/templates/examples/ssr/src/cookie.ts +3 -3
- package/dist/templates/examples/ssr/src/main.ts +10 -10
- package/dist/templates/examples/state-machine/src/main.ts +55 -53
- package/dist/templates/examples/state-machine/src/view.ts +7 -7
- package/dist/templates/examples/stopwatch/src/main.ts +10 -10
- package/dist/templates/examples/todo/src/main.ts +41 -34
- package/dist/templates/examples/ui-showcase/src/main.ts +54 -42
- package/dist/templates/examples/ui-showcase/src/scene.test.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/init.ts +1 -2
- package/dist/templates/examples/ui-showcase/src/ui/message.ts +17 -18
- package/dist/templates/examples/ui-showcase/src/ui/model.ts +47 -44
- package/dist/templates/examples/ui-showcase/src/ui/subscriptions.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/toast.ts +4 -4
- package/dist/templates/examples/ui-showcase/src/ui/update.ts +287 -298
- package/dist/templates/examples/ui-showcase/src/ui/view/animation.ts +2 -2
- package/dist/templates/examples/ui-showcase/src/ui/view/button.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/calendar.ts +4 -4
- package/dist/templates/examples/ui-showcase/src/ui/view/checkbox.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/combobox.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/datePicker.ts +4 -4
- package/dist/templates/examples/ui-showcase/src/ui/view/dialog.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/disclosure.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/dragAndDrop.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/fieldset.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/fileDrop.ts +6 -6
- package/dist/templates/examples/ui-showcase/src/ui/view/hoverIntent.ts +9 -20
- package/dist/templates/examples/ui-showcase/src/ui/view/input.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/listbox.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/menu.ts +15 -15
- package/dist/templates/examples/ui-showcase/src/ui/view/popover.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/radioGroup.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/select.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/slider.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/switch.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/tabs.ts +7 -7
- package/dist/templates/examples/ui-showcase/src/ui/view/textarea.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/toast.ts +8 -8
- package/dist/templates/examples/ui-showcase/src/ui/view/tooltip.ts +1 -1
- package/dist/templates/examples/ui-showcase/src/ui/view/virtualList.ts +7 -7
- package/dist/templates/examples/view-transitions/src/artwork.ts +7 -7
- package/dist/templates/examples/view-transitions/src/main.ts +6 -6
- package/dist/templates/examples/view-transitions/src/route.ts +3 -3
- package/dist/templates/examples/weather/src/main.ts +42 -42
- package/dist/templates/examples/weather/src/story.test.ts +5 -5
- package/dist/templates/examples/web-components/src/main.ts +16 -16
- package/dist/templates/examples/websocket-chat/src/main.ts +30 -30
- package/dist/templates/release.json +13 -13
- package/dist/templates/rendering/ssg/src/main.ts +5 -5
- package/dist/templates/rendering/ssg/src/route.ts +2 -2
- package/dist/templates/rendering/ssr/server/main.ts +15 -15
- package/dist/templates/rendering/ssr/src/cookie.ts +3 -3
- package/dist/templates/rendering/ssr/src/main.ts +10 -10
- package/dist/utils/packages.js +17 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Match
|
|
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
4
|
import { evo } from 'foldkit/struct'
|
|
@@ -16,14 +16,14 @@ import {
|
|
|
16
16
|
} from './route'
|
|
17
17
|
|
|
18
18
|
const NavigateInternal = Command.define('NavigateInternal', {
|
|
19
|
-
args: { url:
|
|
19
|
+
args: { url: Schema.String },
|
|
20
20
|
messages: [Message.CompletedNavigateInternal],
|
|
21
21
|
execute: ({ url }) =>
|
|
22
22
|
pushUrl(url).pipe(Effect.as(Message.CompletedNavigateInternal())),
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
const LoadExternal = Command.define('LoadExternal', {
|
|
26
|
-
args: { href:
|
|
26
|
+
args: { href: Schema.String },
|
|
27
27
|
messages: [Message.CompletedLoadExternal],
|
|
28
28
|
execute: ({ href }) =>
|
|
29
29
|
load(href).pipe(Effect.as(Message.CompletedLoadExternal())),
|
|
@@ -51,27 +51,24 @@ const RedirectToHome = Command.define('RedirectToHome', {
|
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
type UpdateReturn = Update.Return<Model, Message>
|
|
54
|
-
const withUpdateReturn =
|
|
55
|
-
|
|
56
|
-
const foldLoggedOutOutMessage
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
(
|
|
63
|
-
()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}),
|
|
67
|
-
}),
|
|
68
|
-
)
|
|
54
|
+
const withUpdateReturn = Match.withReturnType<UpdateReturn>()
|
|
55
|
+
|
|
56
|
+
const foldLoggedOutOutMessage = LoggedOut.OutMessage.match<
|
|
57
|
+
Update.Step<Model, Message>
|
|
58
|
+
>({
|
|
59
|
+
SucceededLogin:
|
|
60
|
+
({ session }) =>
|
|
61
|
+
() => ({
|
|
62
|
+
model: LoggedIn.init(AppRoute.Dashboard(), session),
|
|
63
|
+
commands: [SaveSession({ session }), RedirectToDashboard()],
|
|
64
|
+
}),
|
|
65
|
+
})
|
|
69
66
|
|
|
70
67
|
const foldLoggedOut = Update.foldChild({
|
|
71
68
|
update: LoggedOut.update,
|
|
72
69
|
read: (model: Model) =>
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
Match.value(model).pipe(
|
|
71
|
+
Match.tagsExhaustive({
|
|
75
72
|
LoggedOut: loggedOutModel => Option.some(loggedOutModel),
|
|
76
73
|
LoggedIn: () => Option.none(),
|
|
77
74
|
}),
|
|
@@ -81,23 +78,20 @@ const foldLoggedOut = Update.foldChild({
|
|
|
81
78
|
foldOutMessage: foldLoggedOutOutMessage,
|
|
82
79
|
})
|
|
83
80
|
|
|
84
|
-
const foldLoggedInOutMessage
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
model: LoggedOut.init(AppRoute.Home()),
|
|
91
|
-
commands: [ClearSession(), RedirectToHome()],
|
|
92
|
-
}),
|
|
81
|
+
const foldLoggedInOutMessage = LoggedIn.OutMessage.match<
|
|
82
|
+
Update.Step<Model, Message>
|
|
83
|
+
>({
|
|
84
|
+
RequestedLogout: () => () => ({
|
|
85
|
+
model: LoggedOut.init(AppRoute.Home()),
|
|
86
|
+
commands: [ClearSession(), RedirectToHome()],
|
|
93
87
|
}),
|
|
94
|
-
)
|
|
88
|
+
})
|
|
95
89
|
|
|
96
90
|
const foldLoggedIn = Update.foldChild({
|
|
97
91
|
update: LoggedIn.update,
|
|
98
92
|
read: (model: Model) =>
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
Match.value(model).pipe(
|
|
94
|
+
Match.tagsExhaustive({
|
|
101
95
|
LoggedOut: () => Option.none(),
|
|
102
96
|
LoggedIn: loggedInModel => Option.some(loggedInModel),
|
|
103
97
|
}),
|
|
@@ -124,25 +118,28 @@ export const update = (model: Model, message: Message) =>
|
|
|
124
118
|
ChangedUrl: ({ url }) => {
|
|
125
119
|
const route = urlToAppRoute(url)
|
|
126
120
|
|
|
127
|
-
return
|
|
121
|
+
return Match.value(model).pipe(
|
|
128
122
|
withUpdateReturn,
|
|
129
|
-
|
|
123
|
+
Match.tagsExhaustive({
|
|
130
124
|
LoggedOut: loggedOutModel =>
|
|
131
|
-
|
|
125
|
+
Match.value(route).pipe(
|
|
132
126
|
withUpdateReturn,
|
|
133
|
-
|
|
127
|
+
Match.tag('Home', 'Login', 'NotFound', route => ({
|
|
134
128
|
model: evo(loggedOutModel, { route: () => route }),
|
|
135
129
|
})),
|
|
136
|
-
|
|
130
|
+
Match.orElse(() => ({ model, commands: [RedirectToLogin()] })),
|
|
137
131
|
),
|
|
138
132
|
|
|
139
133
|
LoggedIn: loggedInModel =>
|
|
140
|
-
|
|
134
|
+
Match.value(route).pipe(
|
|
141
135
|
withUpdateReturn,
|
|
142
|
-
|
|
136
|
+
Match.tag('Dashboard', 'Settings', 'NotFound', route => ({
|
|
143
137
|
model: evo(loggedInModel, { route: () => route }),
|
|
144
138
|
})),
|
|
145
|
-
|
|
139
|
+
Match.orElse(() => ({
|
|
140
|
+
model,
|
|
141
|
+
commands: [RedirectToDashboard()],
|
|
142
|
+
})),
|
|
146
143
|
),
|
|
147
144
|
}),
|
|
148
145
|
)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Match
|
|
1
|
+
import { Match } from 'effect'
|
|
2
2
|
import { type Document, HtmlBuilder } from 'foldkit/html'
|
|
3
3
|
|
|
4
4
|
import { Message } from './message'
|
|
5
5
|
import { LoggedIn, LoggedOut, Model } from './model'
|
|
6
6
|
|
|
7
7
|
const title = (model: Model): string =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Match.value(model.route).pipe(
|
|
9
|
+
Match.tag('Home', () => 'Auth'),
|
|
10
|
+
Match.orElse(({ _tag }) => `${_tag} | Auth`),
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
export const view = (model: Model, h: HtmlBuilder<Message>): Document => ({
|
|
@@ -15,8 +15,8 @@ export const view = (model: Model, h: HtmlBuilder<Message>): Document => ({
|
|
|
15
15
|
body: h.div(
|
|
16
16
|
[h.Class('min-h-screen bg-gray-100')],
|
|
17
17
|
[
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
Match.value(model).pipe(
|
|
19
|
+
Match.tagsExhaustive({
|
|
20
20
|
LoggedOut: loggedOutModel =>
|
|
21
21
|
h.submodel({
|
|
22
22
|
slotId: 'logged-out',
|
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Array,
|
|
3
|
-
Effect,
|
|
4
|
-
Number,
|
|
5
|
-
Option,
|
|
6
|
-
Random,
|
|
7
|
-
Schema as S,
|
|
8
|
-
pipe,
|
|
9
|
-
} from 'effect'
|
|
1
|
+
import { Array, Effect, Number, Option, Random, Schema, pipe } from 'effect'
|
|
10
2
|
import { Canvas, Command, Runtime, Subscription, type Update } from 'foldkit'
|
|
11
3
|
import { Document, Html, HtmlBuilder } from 'foldkit/html'
|
|
12
4
|
import { defineMessageUnion } from 'foldkit/message'
|
|
@@ -36,36 +28,36 @@ const PALETTE: ReadonlyArray<string> = [
|
|
|
36
28
|
]
|
|
37
29
|
const FALLBACK_COLOR = '#ffffff'
|
|
38
30
|
|
|
39
|
-
const Ball =
|
|
40
|
-
id:
|
|
41
|
-
x:
|
|
42
|
-
y:
|
|
43
|
-
vx:
|
|
44
|
-
vy:
|
|
45
|
-
radius:
|
|
46
|
-
color:
|
|
31
|
+
const Ball = Schema.Struct({
|
|
32
|
+
id: Schema.Number,
|
|
33
|
+
x: Schema.Number,
|
|
34
|
+
y: Schema.Number,
|
|
35
|
+
vx: Schema.Number,
|
|
36
|
+
vy: Schema.Number,
|
|
37
|
+
radius: Schema.Number,
|
|
38
|
+
color: Schema.String,
|
|
47
39
|
})
|
|
48
40
|
type Ball = typeof Ball.Type
|
|
49
41
|
|
|
50
|
-
export const Model =
|
|
51
|
-
balls:
|
|
52
|
-
nextId:
|
|
53
|
-
isRunning:
|
|
42
|
+
export const Model = Schema.Struct({
|
|
43
|
+
balls: Schema.Array(Ball),
|
|
44
|
+
nextId: Schema.Number,
|
|
45
|
+
isRunning: Schema.Boolean,
|
|
54
46
|
})
|
|
55
47
|
export type Model = typeof Model.Type
|
|
56
48
|
|
|
57
49
|
// MESSAGE
|
|
58
50
|
|
|
59
51
|
export const Message = defineMessageUnion({
|
|
60
|
-
TickedFrame: { deltaTime:
|
|
61
|
-
ClickedCanvas: { x:
|
|
52
|
+
TickedFrame: { deltaTime: Schema.Number },
|
|
53
|
+
ClickedCanvas: { x: Schema.Number, y: Schema.Number },
|
|
62
54
|
CompletedGenerateBall: {
|
|
63
|
-
x:
|
|
64
|
-
y:
|
|
65
|
-
vx:
|
|
66
|
-
vy:
|
|
67
|
-
radius:
|
|
68
|
-
color:
|
|
55
|
+
x: Schema.Number,
|
|
56
|
+
y: Schema.Number,
|
|
57
|
+
vx: Schema.Number,
|
|
58
|
+
vy: Schema.Number,
|
|
59
|
+
radius: Schema.Number,
|
|
60
|
+
color: Schema.String,
|
|
69
61
|
},
|
|
70
62
|
ClickedClear: {},
|
|
71
63
|
ClickedTogglePlay: {},
|
|
@@ -82,7 +74,7 @@ export const init: Runtime.ApplicationInit<Model, Message> = () => ({
|
|
|
82
74
|
// COMMAND
|
|
83
75
|
|
|
84
76
|
export const GenerateBall = Command.define('GenerateBall', {
|
|
85
|
-
args: { x:
|
|
77
|
+
args: { x: Schema.Number, y: Schema.Number },
|
|
86
78
|
messages: [Message.CompletedGenerateBall],
|
|
87
79
|
execute: ({ x, y }) =>
|
|
88
80
|
Effect.gen(function* () {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Layer, Option, Schema
|
|
1
|
+
import { Effect, Layer, Option, Schema } from 'effect'
|
|
2
2
|
import { Command, Http } from 'foldkit'
|
|
3
3
|
|
|
4
4
|
import { getChart } from './chartHost'
|
|
@@ -31,12 +31,12 @@ export const FetchTelemetry = Command.define('FetchTelemetry', {
|
|
|
31
31
|
|
|
32
32
|
export const SyncChart = Command.define('SyncChart', {
|
|
33
33
|
args: {
|
|
34
|
-
hostId:
|
|
34
|
+
hostId: Schema.String,
|
|
35
35
|
telemetry: Telemetry,
|
|
36
36
|
chartMode: ChartMode,
|
|
37
37
|
selectedPackageId: PackageId,
|
|
38
38
|
period: Period,
|
|
39
|
-
maybeSelectedDatumId:
|
|
39
|
+
maybeSelectedDatumId: Schema.Option(Schema.String),
|
|
40
40
|
},
|
|
41
41
|
messages: [Message.SucceededSyncChart, Message.FailedSyncChart],
|
|
42
42
|
execute: args =>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Array, Option, Schema
|
|
1
|
+
import { Array, Option, Schema, pipe } from 'effect'
|
|
2
2
|
|
|
3
3
|
// MODEL
|
|
4
4
|
|
|
5
|
-
export const ChartMode =
|
|
5
|
+
export const ChartMode = Schema.Literals(['Adoption', 'Velocity', 'Ecosystem'])
|
|
6
6
|
export type ChartMode = typeof ChartMode.Type
|
|
7
7
|
export const chartModes: ReadonlyArray<ChartMode> = ChartMode.literals
|
|
8
8
|
|
|
9
|
-
export const Period =
|
|
9
|
+
export const Period = Schema.Literals([
|
|
10
10
|
'LastEightWeeks',
|
|
11
11
|
'LastSixteenWeeks',
|
|
12
12
|
'LastYear',
|
|
@@ -14,15 +14,20 @@ export const Period = S.Literals([
|
|
|
14
14
|
export type Period = typeof Period.Type
|
|
15
15
|
export const periods: ReadonlyArray<Period> = Period.literals
|
|
16
16
|
|
|
17
|
-
export const PackageId =
|
|
17
|
+
export const PackageId = Schema.Literals([
|
|
18
|
+
'Core',
|
|
19
|
+
'Ui',
|
|
20
|
+
'Devtools',
|
|
21
|
+
'VitePlugin',
|
|
22
|
+
])
|
|
18
23
|
export type PackageId = typeof PackageId.Type
|
|
19
24
|
export const packageIds: ReadonlyArray<PackageId> = PackageId.literals
|
|
20
25
|
|
|
21
|
-
export const PackageSpec =
|
|
26
|
+
export const PackageSpec = Schema.Struct({
|
|
22
27
|
id: PackageId,
|
|
23
|
-
npmName:
|
|
24
|
-
displayName:
|
|
25
|
-
role:
|
|
28
|
+
npmName: Schema.String,
|
|
29
|
+
displayName: Schema.String,
|
|
30
|
+
role: Schema.String,
|
|
26
31
|
})
|
|
27
32
|
export type PackageSpec = typeof PackageSpec.Type
|
|
28
33
|
|
|
@@ -53,68 +58,68 @@ export const packageSpecs: ReadonlyArray<PackageSpec> = [
|
|
|
53
58
|
},
|
|
54
59
|
]
|
|
55
60
|
|
|
56
|
-
export const WeeklyTelemetry =
|
|
57
|
-
weekStart:
|
|
58
|
-
cumulativeStars:
|
|
59
|
-
commits:
|
|
60
|
-
releases:
|
|
61
|
+
export const WeeklyTelemetry = Schema.Struct({
|
|
62
|
+
weekStart: Schema.String,
|
|
63
|
+
cumulativeStars: Schema.Number,
|
|
64
|
+
commits: Schema.Number,
|
|
65
|
+
releases: Schema.Number,
|
|
61
66
|
})
|
|
62
67
|
export type WeeklyTelemetry = typeof WeeklyTelemetry.Type
|
|
63
68
|
|
|
64
|
-
export const WeeklyDownloads =
|
|
65
|
-
weekStart:
|
|
66
|
-
downloads:
|
|
69
|
+
export const WeeklyDownloads = Schema.Struct({
|
|
70
|
+
weekStart: Schema.String,
|
|
71
|
+
downloads: Schema.Number,
|
|
67
72
|
})
|
|
68
73
|
export type WeeklyDownloads = typeof WeeklyDownloads.Type
|
|
69
74
|
|
|
70
|
-
export const PackageSnapshot =
|
|
75
|
+
export const PackageSnapshot = Schema.Struct({
|
|
71
76
|
id: PackageId,
|
|
72
|
-
npmName:
|
|
73
|
-
displayName:
|
|
74
|
-
role:
|
|
75
|
-
latestVersion:
|
|
76
|
-
publishedAt:
|
|
77
|
-
totalDownloads:
|
|
78
|
-
lastWeekDownloads:
|
|
79
|
-
dependencyCount:
|
|
80
|
-
downloadsByWeek:
|
|
77
|
+
npmName: Schema.String,
|
|
78
|
+
displayName: Schema.String,
|
|
79
|
+
role: Schema.String,
|
|
80
|
+
latestVersion: Schema.String,
|
|
81
|
+
publishedAt: Schema.String,
|
|
82
|
+
totalDownloads: Schema.Number,
|
|
83
|
+
lastWeekDownloads: Schema.Number,
|
|
84
|
+
dependencyCount: Schema.Number,
|
|
85
|
+
downloadsByWeek: Schema.Array(WeeklyDownloads),
|
|
81
86
|
})
|
|
82
87
|
export type PackageSnapshot = typeof PackageSnapshot.Type
|
|
83
88
|
|
|
84
|
-
export const DependencyEdge =
|
|
89
|
+
export const DependencyEdge = Schema.Struct({
|
|
85
90
|
source: PackageId,
|
|
86
91
|
target: PackageId,
|
|
87
|
-
kind:
|
|
92
|
+
kind: Schema.Literals(['Dependency', 'PeerDependency']),
|
|
88
93
|
})
|
|
89
94
|
export type DependencyEdge = typeof DependencyEdge.Type
|
|
90
95
|
|
|
91
|
-
export const ContributorSummary =
|
|
92
|
-
login:
|
|
93
|
-
contributions:
|
|
94
|
-
avatarUrl:
|
|
96
|
+
export const ContributorSummary = Schema.Struct({
|
|
97
|
+
login: Schema.String,
|
|
98
|
+
contributions: Schema.Number,
|
|
99
|
+
avatarUrl: Schema.Option(Schema.String),
|
|
95
100
|
})
|
|
96
101
|
export type ContributorSummary = typeof ContributorSummary.Type
|
|
97
102
|
|
|
98
|
-
export const RepositorySnapshot =
|
|
99
|
-
stars:
|
|
100
|
-
forks:
|
|
101
|
-
watchers:
|
|
102
|
-
openIssues:
|
|
103
|
-
openPullRequests:
|
|
104
|
-
visibleContributors:
|
|
105
|
-
pushedAt:
|
|
106
|
-
defaultBranch:
|
|
103
|
+
export const RepositorySnapshot = Schema.Struct({
|
|
104
|
+
stars: Schema.Number,
|
|
105
|
+
forks: Schema.Number,
|
|
106
|
+
watchers: Schema.Number,
|
|
107
|
+
openIssues: Schema.Number,
|
|
108
|
+
openPullRequests: Schema.Number,
|
|
109
|
+
visibleContributors: Schema.Number,
|
|
110
|
+
pushedAt: Schema.String,
|
|
111
|
+
defaultBranch: Schema.String,
|
|
107
112
|
})
|
|
108
113
|
export type RepositorySnapshot = typeof RepositorySnapshot.Type
|
|
109
114
|
|
|
110
|
-
export const Telemetry =
|
|
111
|
-
fetchedAt:
|
|
115
|
+
export const Telemetry = Schema.Struct({
|
|
116
|
+
fetchedAt: Schema.Number,
|
|
112
117
|
repository: RepositorySnapshot,
|
|
113
|
-
packages:
|
|
114
|
-
weeks:
|
|
115
|
-
dependencyEdges:
|
|
116
|
-
topContributors:
|
|
117
|
-
warnings:
|
|
118
|
+
packages: Schema.Array(PackageSnapshot),
|
|
119
|
+
weeks: Schema.Array(WeeklyTelemetry),
|
|
120
|
+
dependencyEdges: Schema.Array(DependencyEdge),
|
|
121
|
+
topContributors: Schema.Array(ContributorSummary),
|
|
122
|
+
warnings: Schema.Array(Schema.String),
|
|
118
123
|
})
|
|
119
124
|
export type Telemetry = typeof Telemetry.Type
|
|
120
125
|
|
|
@@ -13,7 +13,7 @@ import * as echarts from 'echarts/core'
|
|
|
13
13
|
import { LabelLayout, UniversalTransition } from 'echarts/features'
|
|
14
14
|
import { CanvasRenderer } from 'echarts/renderers'
|
|
15
15
|
import type { EChartsOption } from 'echarts/types/dist/shared'
|
|
16
|
-
import { Array, Match
|
|
16
|
+
import { Array, Match, Option, String, pipe } from 'effect'
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
19
|
type ChartMode,
|
|
@@ -382,11 +382,11 @@ const weekToDatumLabels =
|
|
|
382
382
|
]
|
|
383
383
|
|
|
384
384
|
export const makeChartOption = (args: ChartOptionArgs) =>
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
385
|
+
Match.value(args.chartMode).pipe(
|
|
386
|
+
Match.when('Adoption', () => adoptionOption(args)),
|
|
387
|
+
Match.when('Velocity', () => velocityOption(args)),
|
|
388
|
+
Match.when('Ecosystem', () => ecosystemOption(args)),
|
|
389
|
+
Match.exhaustive,
|
|
390
390
|
)
|
|
391
391
|
|
|
392
392
|
const findDatumLabelById =
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
Layer,
|
|
7
7
|
Number,
|
|
8
8
|
Option,
|
|
9
|
-
Schema as S,
|
|
10
9
|
Schedule,
|
|
10
|
+
Schema,
|
|
11
11
|
} from 'effect'
|
|
12
12
|
import { HttpClient, HttpClientRequest } from 'effect/unstable/http'
|
|
13
13
|
|
|
@@ -25,41 +25,41 @@ const RELEASE_PAGE_SIZE = 100
|
|
|
25
25
|
|
|
26
26
|
// SCHEMA
|
|
27
27
|
|
|
28
|
-
export const GitHubRepositoryResponse =
|
|
29
|
-
stargazers_count:
|
|
30
|
-
forks_count:
|
|
31
|
-
watchers_count:
|
|
32
|
-
open_issues_count:
|
|
33
|
-
pushed_at:
|
|
34
|
-
default_branch:
|
|
28
|
+
export const GitHubRepositoryResponse = Schema.Struct({
|
|
29
|
+
stargazers_count: Schema.Number,
|
|
30
|
+
forks_count: Schema.Number,
|
|
31
|
+
watchers_count: Schema.Number,
|
|
32
|
+
open_issues_count: Schema.Number,
|
|
33
|
+
pushed_at: Schema.String,
|
|
34
|
+
default_branch: Schema.String,
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
export const GitHubContributorResponse =
|
|
38
|
-
login:
|
|
39
|
-
contributions:
|
|
40
|
-
avatar_url:
|
|
37
|
+
export const GitHubContributorResponse = Schema.Struct({
|
|
38
|
+
login: Schema.String,
|
|
39
|
+
contributions: Schema.Number,
|
|
40
|
+
avatar_url: Schema.OptionFromOptional(Schema.String),
|
|
41
41
|
})
|
|
42
42
|
export type GitHubContributorResponse = typeof GitHubContributorResponse.Type
|
|
43
43
|
|
|
44
|
-
export const GitHubIssueResponse =
|
|
45
|
-
pull_request:
|
|
44
|
+
export const GitHubIssueResponse = Schema.Struct({
|
|
45
|
+
pull_request: Schema.OptionFromOptional(Schema.Unknown),
|
|
46
46
|
})
|
|
47
47
|
|
|
48
|
-
export const GitHubPullRequestResponse =
|
|
49
|
-
id:
|
|
48
|
+
export const GitHubPullRequestResponse = Schema.Struct({
|
|
49
|
+
id: Schema.Number,
|
|
50
50
|
})
|
|
51
51
|
|
|
52
|
-
export const GitHubReleaseResponse =
|
|
53
|
-
published_at:
|
|
52
|
+
export const GitHubReleaseResponse = Schema.Struct({
|
|
53
|
+
published_at: Schema.OptionFromOptional(Schema.String),
|
|
54
54
|
})
|
|
55
55
|
|
|
56
|
-
export const GitHubStargazerResponse =
|
|
57
|
-
starred_at:
|
|
56
|
+
export const GitHubStargazerResponse = Schema.Struct({
|
|
57
|
+
starred_at: Schema.String,
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
-
export const GitHubCommitActivityResponse =
|
|
61
|
-
week:
|
|
62
|
-
total:
|
|
60
|
+
export const GitHubCommitActivityResponse = Schema.Struct({
|
|
61
|
+
week: Schema.Number,
|
|
62
|
+
total: Schema.Number,
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
// SERVICE
|
|
@@ -104,7 +104,7 @@ class GitHubStatError extends Data.TaggedError('GitHubStatError') {}
|
|
|
104
104
|
|
|
105
105
|
const fetchOptionalGitHubStat =
|
|
106
106
|
(client: HttpClient.HttpClient) =>
|
|
107
|
-
<A, I>(schema:
|
|
107
|
+
<A, I>(schema: Schema.Codec<A, I>) =>
|
|
108
108
|
(path: string, label: string): Effect.Effect<GitHubStatResult<A>, never> => {
|
|
109
109
|
const url = `${GITHUB_REPOSITORY_API}${path}`
|
|
110
110
|
|
|
@@ -128,7 +128,7 @@ const fetchOptionalGitHubStat =
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
const data = yield* response.json.pipe(
|
|
131
|
-
Effect.flatMap(json =>
|
|
131
|
+
Effect.flatMap(json => Schema.decodeUnknownEffect(schema)(json)),
|
|
132
132
|
Effect.option,
|
|
133
133
|
)
|
|
134
134
|
|
|
@@ -178,19 +178,19 @@ export const GitHubApiLive: Layer.Layer<
|
|
|
178
178
|
const fetchStat_ = fetchOptionalGitHubStat(client)
|
|
179
179
|
return {
|
|
180
180
|
fetchRepository: fetch_(GitHubRepositoryResponse)(GITHUB_REPOSITORY_API),
|
|
181
|
-
fetchContributors: fetch_(
|
|
181
|
+
fetchContributors: fetch_(Schema.Array(GitHubContributorResponse))(
|
|
182
182
|
makeUrl(`${GITHUB_REPOSITORY_API}/contributors`, {
|
|
183
183
|
per_page: '100',
|
|
184
184
|
anon: 'false',
|
|
185
185
|
}),
|
|
186
186
|
),
|
|
187
|
-
fetchIssues: fetch_(
|
|
187
|
+
fetchIssues: fetch_(Schema.Array(GitHubIssueResponse))(
|
|
188
188
|
makeUrl(`${GITHUB_REPOSITORY_API}/issues`, {
|
|
189
189
|
state: 'open',
|
|
190
190
|
per_page: '100',
|
|
191
191
|
}),
|
|
192
192
|
),
|
|
193
|
-
fetchPullRequests: fetch_(
|
|
193
|
+
fetchPullRequests: fetch_(Schema.Array(GitHubPullRequestResponse))(
|
|
194
194
|
makeUrl(`${GITHUB_REPOSITORY_API}/pulls`, {
|
|
195
195
|
state: 'open',
|
|
196
196
|
per_page: '100',
|
|
@@ -198,7 +198,7 @@ export const GitHubApiLive: Layer.Layer<
|
|
|
198
198
|
),
|
|
199
199
|
fetchReleases: (yearCutoffMilliseconds: number) => {
|
|
200
200
|
const fetchPage = (page: number) =>
|
|
201
|
-
fetch_(
|
|
201
|
+
fetch_(Schema.Array(GitHubReleaseResponse))(
|
|
202
202
|
makeUrl(`${GITHUB_REPOSITORY_API}/releases`, {
|
|
203
203
|
per_page: `${RELEASE_PAGE_SIZE}`,
|
|
204
204
|
page: `${page}`,
|
|
@@ -252,7 +252,7 @@ export const GitHubApiLive: Layer.Layer<
|
|
|
252
252
|
return Effect.forEach(
|
|
253
253
|
Array.range(1, Math.max(1, pageCount)),
|
|
254
254
|
page =>
|
|
255
|
-
fetch_(
|
|
255
|
+
fetch_(Schema.Array(GitHubStargazerResponse))(
|
|
256
256
|
makeUrl(`${GITHUB_REPOSITORY_API}/stargazers`, {
|
|
257
257
|
per_page: `${STARGAZER_PAGE_SIZE}`,
|
|
258
258
|
page: `${page}`,
|
|
@@ -262,10 +262,9 @@ export const GitHubApiLive: Layer.Layer<
|
|
|
262
262
|
{ concurrency: 'unbounded' },
|
|
263
263
|
).pipe(Effect.map(Array.flatten))
|
|
264
264
|
},
|
|
265
|
-
fetchCommitActivity: fetchStat_(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
),
|
|
265
|
+
fetchCommitActivity: fetchStat_(
|
|
266
|
+
Schema.Array(GitHubCommitActivityResponse),
|
|
267
|
+
)('/stats/commit_activity', 'Commit activity'),
|
|
269
268
|
}
|
|
270
269
|
}),
|
|
271
270
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Record
|
|
1
|
+
import { Effect, Record, Schema } from 'effect'
|
|
2
2
|
import { HttpClient, HttpClientRequest } from 'effect/unstable/http'
|
|
3
3
|
|
|
4
4
|
// CONSTANT
|
|
@@ -16,7 +16,7 @@ export const errorMessage = (error: unknown): string =>
|
|
|
16
16
|
|
|
17
17
|
export const makeUrl = (
|
|
18
18
|
url: string,
|
|
19
|
-
params: Readonly<Record<string, string>>,
|
|
19
|
+
params: Readonly<globalThis.Record<string, string>>,
|
|
20
20
|
): string => {
|
|
21
21
|
const searchParams = new URLSearchParams(params)
|
|
22
22
|
return `${url}?${searchParams.toString()}`
|
|
@@ -27,10 +27,10 @@ export const encodePackageName = (packageName: string): string =>
|
|
|
27
27
|
|
|
28
28
|
export const fetchJson =
|
|
29
29
|
(client: HttpClient.HttpClient) =>
|
|
30
|
-
<A, I>(schema:
|
|
30
|
+
<A, I>(schema: Schema.Codec<A, I>) =>
|
|
31
31
|
(
|
|
32
32
|
url: string,
|
|
33
|
-
headers: Readonly<Record<string, string>> =
|
|
33
|
+
headers: Readonly<globalThis.Record<string, string>> = Record.empty(),
|
|
34
34
|
): Effect.Effect<A, Error> =>
|
|
35
35
|
Effect.gen(function* () {
|
|
36
36
|
const request = HttpClientRequest.get(url).pipe(
|
|
@@ -44,7 +44,7 @@ export const fetchJson =
|
|
|
44
44
|
)
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
return yield*
|
|
48
|
-
|
|
49
|
-
)
|
|
47
|
+
return yield* Schema.decodeUnknownEffect(schema)(
|
|
48
|
+
yield* response.json,
|
|
49
|
+
).pipe(Effect.mapError(error => new Error(errorMessage(error))))
|
|
50
50
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Schema
|
|
1
|
+
import { Schema } from 'effect'
|
|
2
2
|
import { defineMessageUnion } from 'foldkit/message'
|
|
3
3
|
|
|
4
4
|
import { RadioGroup } from '@foldkit/ui'
|
|
@@ -11,13 +11,13 @@ export const Message = defineMessageUnion({
|
|
|
11
11
|
GotPeriodRadioGroupMessage: { message: RadioGroup.Message },
|
|
12
12
|
ClickedRefresh: {},
|
|
13
13
|
ClickedRetry: {},
|
|
14
|
-
ClickedChartDatum: { datumId:
|
|
14
|
+
ClickedChartDatum: { datumId: Schema.String },
|
|
15
15
|
SucceededFetchTelemetry: { telemetry: Telemetry },
|
|
16
|
-
FailedFetchTelemetry: { error:
|
|
17
|
-
SucceededMountChart: { hostId:
|
|
18
|
-
FailedMountChart: { reason:
|
|
16
|
+
FailedFetchTelemetry: { error: Schema.String },
|
|
17
|
+
SucceededMountChart: { hostId: Schema.String },
|
|
18
|
+
FailedMountChart: { reason: Schema.String },
|
|
19
19
|
SucceededSyncChart: {},
|
|
20
|
-
FailedSyncChart: { reason:
|
|
20
|
+
FailedSyncChart: { reason: Schema.String },
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
export type Message = typeof Message.Type
|