create-foldkit-app 0.34.0 → 0.35.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 (40) hide show
  1. package/dist/commands/create.js +4 -4
  2. package/dist/index.js +7 -7
  3. package/dist/templates/examples/api-cache/package.json +3 -3
  4. package/dist/templates/examples/auth/package.json +3 -3
  5. package/dist/templates/examples/canvas-art/package.json +3 -3
  6. package/dist/templates/examples/charting/package.json +3 -3
  7. package/dist/templates/examples/counter/package.json +3 -3
  8. package/dist/templates/examples/counters/package.json +3 -3
  9. package/dist/templates/examples/crash-view/package.json +3 -3
  10. package/dist/templates/examples/embedding/package.json +3 -3
  11. package/dist/templates/examples/form/package.json +3 -3
  12. package/dist/templates/examples/generative-art/package.json +3 -3
  13. package/dist/templates/examples/interrupting-commands/package.json +3 -3
  14. package/dist/templates/examples/job-application/package.json +3 -3
  15. package/dist/templates/examples/kanban/package.json +3 -3
  16. package/dist/templates/examples/managed-resource-layer/package.json +3 -3
  17. package/dist/templates/examples/map/package.json +3 -3
  18. package/dist/templates/examples/pixel-art/package.json +3 -3
  19. package/dist/templates/examples/pixel-art/src/main.bench.ts +70 -54
  20. package/dist/templates/examples/pixel-art/src/subscription.ts +45 -35
  21. package/dist/templates/examples/query-sync/package.json +3 -3
  22. package/dist/templates/examples/route-transitions/package.json +3 -3
  23. package/dist/templates/examples/routing/package.json +3 -3
  24. package/dist/templates/examples/shopping-cart/package.json +3 -3
  25. package/dist/templates/examples/slow-warnings/package.json +3 -3
  26. package/dist/templates/examples/snake/package.json +3 -3
  27. package/dist/templates/examples/snake/src/main.ts +16 -8
  28. package/dist/templates/examples/ssg/package.json +2 -2
  29. package/dist/templates/examples/ssr/package.json +5 -5
  30. package/dist/templates/examples/state-machine/package.json +3 -3
  31. package/dist/templates/examples/stopwatch/package.json +3 -3
  32. package/dist/templates/examples/todo/package.json +3 -3
  33. package/dist/templates/examples/ui-showcase/package.json +3 -3
  34. package/dist/templates/examples/view-transitions/package.json +3 -3
  35. package/dist/templates/examples/weather/package.json +3 -3
  36. package/dist/templates/examples/web-components/package.json +3 -3
  37. package/dist/templates/examples/websocket-chat/package.json +3 -3
  38. package/dist/templates/release.json +14 -14
  39. package/dist/templates/rendering/ssr/scripts/serve.ts +2 -2
  40. package/package.json +6 -6
@@ -8,14 +8,14 @@ import { createProject } from '../utils/files.js';
8
8
  import { devCommand, installDependencies, readFoldkitSubtreeRef, } from '../utils/packages.js';
9
9
  import { validateProjectName } from '../validateName.js';
10
10
  const isWindows = process.platform === 'win32';
11
- const promptForName = Prompt.text({
11
+ const promptForName = Prompt.String({
12
12
  message: 'Give your project a name',
13
13
  validate: value => Option.match(validateProjectName(value), {
14
14
  onNone: () => Effect.succeed(value),
15
15
  onSome: message => Effect.fail(message),
16
16
  }),
17
17
  });
18
- const promptForRendering = Prompt.select({
18
+ const promptForRendering = Prompt.Select({
19
19
  message: 'Pick a rendering mode',
20
20
  choices: renderings.map(({ value, title, description }) => ({
21
21
  value,
@@ -23,7 +23,7 @@ const promptForRendering = Prompt.select({
23
23
  description,
24
24
  })),
25
25
  });
26
- const promptForExample = Prompt.autoComplete({
26
+ const promptForExample = Prompt.AutoComplete({
27
27
  message: 'Pick a starting example',
28
28
  choices: examples.map(({ value, title, description }) => ({
29
29
  value,
@@ -31,7 +31,7 @@ const promptForExample = Prompt.autoComplete({
31
31
  description,
32
32
  })),
33
33
  });
34
- const promptForPackageManager = Prompt.select({
34
+ const promptForPackageManager = Prompt.Select({
35
35
  message: 'Pick a package manager',
36
36
  choices: [
37
37
  { value: 'pnpm', title: 'pnpm' },
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { Effect, Layer, Option, Schema } from 'effect';
2
+ import { Effect, Option, Schema } from 'effect';
3
3
  import { Command, Flag } from 'effect/unstable/cli';
4
4
  import { createRequire } from 'node:module';
5
- import { NodeRuntime, NodeServices, NodeStdio } from '@effect/platform-node';
5
+ import { NodeRuntime, NodeServices } from '@effect/platform-node';
6
6
  import { create as create_ } from './commands/create.js';
7
7
  import { EXAMPLE_VALUES } from './examples.js';
8
8
  import { RENDERING_VALUES } from './rendering.js';
@@ -13,10 +13,10 @@ const nameSchema = Schema.String.pipe(Schema.check(Schema.makeFilter(value => Op
13
13
  onNone: () => true,
14
14
  onSome: message => message,
15
15
  }))));
16
- const name = Flag.string('name').pipe(Flag.withAlias('n'), Flag.withDescription('The name of the project to create'), Flag.withSchema(nameSchema), Flag.optional);
17
- const rendering = Flag.choice('rendering', RENDERING_VALUES).pipe(Flag.withAlias('r'), Flag.withDescription('How the application renders: spa renders entirely in the browser, ssg prerenders routes to static HTML at build time, ssr renders each request then hydrates'), Flag.optional);
18
- const example = Flag.choice('example', EXAMPLE_VALUES).pipe(Flag.withAlias('e'), Flag.withDescription("The example application to start from with spa rendering. Run with no flags for an interactive picker that shows each example's description."), Flag.optional);
19
- const packageManager = Flag.choice('package-manager', [
16
+ const name = Flag.String('name').pipe(Flag.withAlias('n'), Flag.withDescription('The name of the project to create'), Flag.withSchema(nameSchema), Flag.optional);
17
+ const rendering = Flag.Literals('rendering', RENDERING_VALUES).pipe(Flag.withAlias('r'), Flag.withDescription('How the application renders: spa renders entirely in the browser, ssg prerenders routes to static HTML at build time, ssr renders each request then hydrates'), Flag.optional);
18
+ const example = Flag.Literals('example', EXAMPLE_VALUES).pipe(Flag.withAlias('e'), Flag.withDescription("The example application to start from with spa rendering. Run with no flags for an interactive picker that shows each example's description."), Flag.optional);
19
+ const packageManager = Flag.Literals('package-manager', [
20
20
  'pnpm',
21
21
  'npm',
22
22
  'yarn',
@@ -32,4 +32,4 @@ const create = Command.make('create', {
32
32
  const cli = Command.run(create, {
33
33
  version: packageJson.version,
34
34
  });
35
- cli.pipe(Effect.provide([Layer.mergeAll(NodeServices.layer, NodeStdio.layer)]), NodeRuntime.runMain);
35
+ cli.pipe(Effect.provide(NodeServices.layer), NodeRuntime.runMain);
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,11 +9,11 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
15
  "echarts": "^6.1.0",
16
- "effect": "4.0.0-rc.112",
16
+ "effect": "4.0.0-rc.115",
17
17
  "foldkit": "workspace:*"
18
18
  },
19
19
  "devDependencies": {
@@ -24,6 +24,6 @@
24
24
  "tailwindcss": "^4.3.3",
25
25
  "typescript": "^7.0.2",
26
26
  "vite": "^8.2.2",
27
- "vitest": "^4.1.11"
27
+ "vitest": "^5.0.0"
28
28
  }
29
29
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "clsx": "^2.1.1",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*",
17
17
  "fractional-indexing": "^4.0.0"
18
18
  },
@@ -24,6 +24,6 @@
24
24
  "tailwindcss": "^4.3.3",
25
25
  "typescript": "^7.0.2",
26
26
  "vite": "^8.2.2",
27
- "vitest": "^4.1.11"
27
+ "vitest": "^5.0.0"
28
28
  }
29
29
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*",
17
17
  "maplibre-gl": "^6.6.0"
18
18
  },
@@ -24,6 +24,6 @@
24
24
  "tailwindcss": "^4.3.3",
25
25
  "typescript": "^7.0.2",
26
26
  "vite": "^8.2.2",
27
- "vitest": "^4.1.11"
27
+ "vitest": "^5.0.0"
28
28
  }
29
29
  }
@@ -10,10 +10,10 @@
10
10
  "bench": "vitest run --config vitest.bench.config.ts"
11
11
  },
12
12
  "dependencies": {
13
- "@effect/platform-browser": "4.0.0-rc.112",
13
+ "@effect/platform-browser": "4.0.0-rc.115",
14
14
  "@foldkit/ui": "workspace:*",
15
15
  "clsx": "^2.1.1",
16
- "effect": "4.0.0-rc.112",
16
+ "effect": "4.0.0-rc.115",
17
17
  "foldkit": "workspace:*"
18
18
  },
19
19
  "devDependencies": {
@@ -24,6 +24,6 @@
24
24
  "tailwindcss": "^4.3.3",
25
25
  "typescript": "^7.0.2",
26
26
  "vite": "^8.2.2",
27
- "vitest": "^4.1.11"
27
+ "vitest": "^5.0.0"
28
28
  }
29
29
  }
@@ -1,6 +1,6 @@
1
1
  import { Option } from 'effect'
2
2
  import { evo } from 'foldkit/struct'
3
- import { bench, describe } from 'vitest'
3
+ import { describe, test } from 'vitest'
4
4
 
5
5
  import { Dialog, Listbox, RadioGroup } from '@foldkit/ui'
6
6
 
@@ -56,29 +56,35 @@ const buildHistoryModel = (steps: number): Model => {
56
56
  }
57
57
 
58
58
  describe('update: single operations', () => {
59
- bench('brush stroke (press + release)', () => {
60
- dispatch(
61
- initialModel,
62
- Message.PressedCell({ x: 5, y: 5 }),
63
- Message.ReleasedMouse(),
64
- )
59
+ test('brush stroke (press + release)', async ({ bench }) => {
60
+ await bench('brush stroke (press + release)', () => {
61
+ dispatch(
62
+ initialModel,
63
+ Message.PressedCell({ x: 5, y: 5 }),
64
+ Message.ReleasedMouse(),
65
+ )
66
+ }).run()
65
67
  })
66
68
 
67
- bench('brush drag (5 cells)', () => {
68
- dispatch(
69
- initialModel,
70
- Message.PressedCell({ x: 0, y: 0 }),
71
- Message.EnteredCell({ x: 1, y: 0 }),
72
- Message.EnteredCell({ x: 2, y: 0 }),
73
- Message.EnteredCell({ x: 3, y: 0 }),
74
- Message.EnteredCell({ x: 4, y: 0 }),
75
- Message.ReleasedMouse(),
76
- )
69
+ test('brush drag (5 cells)', async ({ bench }) => {
70
+ await bench('brush drag (5 cells)', () => {
71
+ dispatch(
72
+ initialModel,
73
+ Message.PressedCell({ x: 0, y: 0 }),
74
+ Message.EnteredCell({ x: 1, y: 0 }),
75
+ Message.EnteredCell({ x: 2, y: 0 }),
76
+ Message.EnteredCell({ x: 3, y: 0 }),
77
+ Message.EnteredCell({ x: 4, y: 0 }),
78
+ Message.ReleasedMouse(),
79
+ )
80
+ }).run()
77
81
  })
78
82
 
79
- bench('flood fill (empty grid)', () => {
80
- const fillModel: Model = evo(initialModel, { tool: () => 'Fill' })
81
- dispatch(fillModel, Message.PressedCell({ x: 0, y: 0 }))
83
+ test('flood fill (empty grid)', async ({ bench }) => {
84
+ await bench('flood fill (empty grid)', () => {
85
+ const fillModel: Model = evo(initialModel, { tool: () => 'Fill' })
86
+ dispatch(fillModel, Message.PressedCell({ x: 0, y: 0 }))
87
+ }).run()
82
88
  })
83
89
  })
84
90
 
@@ -86,49 +92,59 @@ describe('update: undo/redo with history', () => {
86
92
  const modelWith10Steps = buildHistoryModel(10)
87
93
  const modelWith30Steps = buildHistoryModel(30)
88
94
 
89
- bench('undo (10 history entries)', () => {
90
- dispatch(modelWith10Steps, Message.ClickedUndo())
95
+ test('undo (10 history entries)', async ({ bench }) => {
96
+ await bench('undo (10 history entries)', () => {
97
+ dispatch(modelWith10Steps, Message.ClickedUndo())
98
+ }).run()
91
99
  })
92
100
 
93
- bench('undo (30 history entries)', () => {
94
- dispatch(modelWith30Steps, Message.ClickedUndo())
101
+ test('undo (30 history entries)', async ({ bench }) => {
102
+ await bench('undo (30 history entries)', () => {
103
+ dispatch(modelWith30Steps, Message.ClickedUndo())
104
+ }).run()
95
105
  })
96
106
 
97
- bench('5x undo then 5x redo', () => {
98
- let model = modelWith10Steps
99
- for (let i = 0; i < 5; i++) {
100
- model = update(model, Message.ClickedUndo()).model
101
- }
102
- for (let i = 0; i < 5; i++) {
103
- model = update(model, Message.ClickedRedo()).model
104
- }
107
+ test('5x undo then 5x redo', async ({ bench }) => {
108
+ await bench('5x undo then 5x redo', () => {
109
+ let model = modelWith10Steps
110
+ for (let i = 0; i < 5; i++) {
111
+ model = update(model, Message.ClickedUndo()).model
112
+ }
113
+ for (let i = 0; i < 5; i++) {
114
+ model = update(model, Message.ClickedRedo()).model
115
+ }
116
+ }).run()
105
117
  })
106
118
  })
107
119
 
108
120
  describe('update: paint sequence (16x16 grid)', () => {
109
- bench('paint 50 random cells', () => {
110
- let model = initialModel
111
- for (let i = 0; i < 50; i++) {
112
- const x = (i * 7 + 3) % GRID_SIZE
113
- const y = (i * 11 + 5) % GRID_SIZE
114
- model = dispatch(
115
- model,
116
- Message.PressedCell({ x, y }),
117
- Message.ReleasedMouse(),
118
- )
119
- }
121
+ test('paint 50 random cells', async ({ bench }) => {
122
+ await bench('paint 50 random cells', () => {
123
+ let model = initialModel
124
+ for (let i = 0; i < 50; i++) {
125
+ const x = (i * 7 + 3) % GRID_SIZE
126
+ const y = (i * 11 + 5) % GRID_SIZE
127
+ model = dispatch(
128
+ model,
129
+ Message.PressedCell({ x, y }),
130
+ Message.ReleasedMouse(),
131
+ )
132
+ }
133
+ }).run()
120
134
  })
121
135
 
122
- bench('paint 50 cells with mirror mode', () => {
123
- let model: Model = evo(initialModel, { mirrorMode: () => 'Both' })
124
- for (let i = 0; i < 50; i++) {
125
- const x = (i * 7 + 3) % GRID_SIZE
126
- const y = (i * 11 + 5) % GRID_SIZE
127
- model = dispatch(
128
- model,
129
- Message.PressedCell({ x, y }),
130
- Message.ReleasedMouse(),
131
- )
132
- }
136
+ test('paint 50 cells with mirror mode', async ({ bench }) => {
137
+ await bench('paint 50 cells with mirror mode', () => {
138
+ let model: Model = evo(initialModel, { mirrorMode: () => 'Both' })
139
+ for (let i = 0; i < 50; i++) {
140
+ const x = (i * 7 + 3) % GRID_SIZE
141
+ const y = (i * 11 + 5) % GRID_SIZE
142
+ model = dispatch(
143
+ model,
144
+ Message.PressedCell({ x, y }),
145
+ Message.ReleasedMouse(),
146
+ )
147
+ }
148
+ }).run()
133
149
  })
134
150
  })
@@ -1,48 +1,58 @@
1
- import { Effect, Option, Schema, Stream } from 'effect'
1
+ import { Effect, Match, Option, Schema, Stream } from 'effect'
2
2
  import { Subscription } from 'foldkit'
3
3
 
4
4
  import { Message } from './message'
5
5
  import type { Model } from './model'
6
6
 
7
- export const handleKeyboardEvent = (
8
- event: KeyboardEvent,
9
- ): Effect.Effect<Option.Option<Message>> =>
10
- Effect.sync(() => {
11
- const isCtrlOrMeta = event.ctrlKey || event.metaKey
12
- const key = event.key.toLowerCase()
7
+ const toUndoRedoMessage = (event: KeyboardEvent): Option.Option<Message> => {
8
+ const isCtrlOrMeta = event.ctrlKey || event.metaKey
9
+ if (!isCtrlOrMeta) {
10
+ return Option.none()
11
+ }
13
12
 
14
- if (isCtrlOrMeta && key === 'z') {
15
- event.preventDefault()
16
- return Option.some(
13
+ return Match.value(event.key.toLowerCase()).pipe(
14
+ Match.withReturnType<Option.Option<Message>>(),
15
+ Match.when('z', () =>
16
+ Option.some(
17
17
  event.shiftKey ? Message.ClickedRedo() : Message.ClickedUndo(),
18
- )
19
- }
20
- if (isCtrlOrMeta && key === 'y') {
21
- event.preventDefault()
22
- return Option.some(Message.ClickedRedo())
23
- }
24
-
25
- if (!isCtrlOrMeta) {
26
- if (key === 'b') {
27
- return Option.some(Message.SelectedTool({ tool: 'Brush' }))
28
- }
29
- if (key === 'f') {
30
- return Option.some(Message.SelectedTool({ tool: 'Fill' }))
31
- }
32
- if (key === 'e') {
33
- return Option.some(Message.SelectedTool({ tool: 'Eraser' }))
34
- }
35
- }
18
+ ),
19
+ ),
20
+ Match.when('y', () => Option.some(Message.ClickedRedo())),
21
+ Match.orElse(() => Option.none()),
22
+ )
23
+ }
24
+
25
+ const toToolMessage = (event: KeyboardEvent): Option.Option<Message> => {
26
+ if (event.ctrlKey || event.metaKey) {
36
27
  return Option.none()
37
- })
28
+ }
38
29
 
39
- export const subscriptions = Subscription.make<Model, Message>()(entry => ({
40
- keyboard: Subscription.persistent(
41
- Stream.fromEventListener<KeyboardEvent>(document, 'keydown').pipe(
42
- Stream.mapEffect(handleKeyboardEvent),
43
- Stream.filter(Option.isSome),
44
- Stream.map(option => option.value),
30
+ return Match.value(event.key.toLowerCase()).pipe(
31
+ Match.withReturnType<Option.Option<Message>>(),
32
+ Match.when('b', () => Option.some(Message.SelectedTool({ tool: 'Brush' }))),
33
+ Match.when('f', () => Option.some(Message.SelectedTool({ tool: 'Fill' }))),
34
+ Match.when('e', () =>
35
+ Option.some(Message.SelectedTool({ tool: 'Eraser' })),
45
36
  ),
37
+ Match.orElse(() => Option.none()),
38
+ )
39
+ }
40
+
41
+ export const subscriptions = Subscription.make<Model, Message>()(entry => ({
42
+ undoRedoKeys: Subscription.persistent(
43
+ Subscription.fromEventFilterMapPreventDefault<KeyboardEvent, Message>({
44
+ target: document,
45
+ type: 'keydown',
46
+ toMessage: toUndoRedoMessage,
47
+ }),
48
+ ),
49
+
50
+ toolKeys: Subscription.persistent(
51
+ Subscription.fromEventFilterMap<KeyboardEvent, Message>({
52
+ target: document,
53
+ type: 'keydown',
54
+ toMessage: toToolMessage,
55
+ }),
46
56
  ),
47
57
 
48
58
  mouseRelease: entry(
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,8 +9,8 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
13
- "effect": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
+ "effect": "4.0.0-rc.115",
14
14
  "foldkit": "workspace:*"
15
15
  },
16
16
  "devDependencies": {
@@ -21,6 +21,6 @@
21
21
  "tailwindcss": "^4.3.3",
22
22
  "typescript": "^7.0.2",
23
23
  "vite": "^8.2.2",
24
- "vitest": "^4.1.11"
24
+ "vitest": "^5.0.0"
25
25
  }
26
26
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,8 +9,8 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
13
- "effect": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
+ "effect": "4.0.0-rc.115",
14
14
  "foldkit": "workspace:*"
15
15
  },
16
16
  "devDependencies": {
@@ -21,6 +21,6 @@
21
21
  "tailwindcss": "^4.3.3",
22
22
  "typescript": "^7.0.2",
23
23
  "vite": "^8.2.2",
24
- "vitest": "^4.1.11"
24
+ "vitest": "^5.0.0"
25
25
  }
26
26
  }
@@ -9,8 +9,8 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
13
- "effect": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
+ "effect": "4.0.0-rc.115",
14
14
  "foldkit": "workspace:*"
15
15
  },
16
16
  "devDependencies": {
@@ -21,6 +21,6 @@
21
21
  "tailwindcss": "^4.3.3",
22
22
  "typescript": "^7.0.2",
23
23
  "vite": "^8.2.2",
24
- "vitest": "^4.1.11"
24
+ "vitest": "^5.0.0"
25
25
  }
26
26
  }
@@ -1,4 +1,13 @@
1
- import { Array, Duration, Effect, Match, Schema, Stream, pipe } from 'effect'
1
+ import {
2
+ Array,
3
+ Duration,
4
+ Effect,
5
+ Match,
6
+ Option,
7
+ Schema,
8
+ Stream,
9
+ pipe,
10
+ } from 'effect'
2
11
  import { Command, Runtime, Subscription, type Update } from 'foldkit'
3
12
  import { Document, Html, HtmlBuilder } from 'foldkit/html'
4
13
  import { defineMessageUnion } from 'foldkit/message'
@@ -243,13 +252,12 @@ export const subscriptions = Subscription.make<Model, Message>()(entry => ({
243
252
  ),
244
253
 
245
254
  keyboard: Subscription.persistent(
246
- Stream.fromEventListener<KeyboardEvent>(document, 'keydown').pipe(
247
- Stream.mapEffect(keyboardEvent =>
248
- Effect.sync(() => keyboardEvent.preventDefault()).pipe(
249
- Effect.as(Message.PressedKey({ key: keyboardEvent.key })),
250
- ),
251
- ),
252
- ),
255
+ Subscription.fromEventFilterMapPreventDefault<KeyboardEvent, Message>({
256
+ target: document,
257
+ type: 'keydown',
258
+ toMessage: keyboardEvent =>
259
+ Option.some(Message.PressedKey({ key: keyboardEvent.key })),
260
+ }),
253
261
  ),
254
262
  }))
255
263
 
@@ -10,8 +10,8 @@
10
10
  "typecheck": "tsc --noEmit"
11
11
  },
12
12
  "dependencies": {
13
- "@effect/platform-browser": "4.0.0-rc.112",
14
- "effect": "4.0.0-rc.112",
13
+ "@effect/platform-browser": "4.0.0-rc.115",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -11,11 +11,11 @@
11
11
  "test": "vitest run"
12
12
  },
13
13
  "dependencies": {
14
- "@effect/platform-browser": "4.0.0-rc.112",
15
- "@effect/platform-node": "4.0.0-rc.112",
16
- "@effect/platform-node-shared": "4.0.0-rc.112",
14
+ "@effect/platform-browser": "4.0.0-rc.115",
15
+ "@effect/platform-node": "4.0.0-rc.115",
16
+ "@effect/platform-node-shared": "4.0.0-rc.115",
17
17
  "@foldkit/ui": "workspace:*",
18
- "effect": "4.0.0-rc.112",
18
+ "effect": "4.0.0-rc.115",
19
19
  "foldkit": "workspace:*"
20
20
  },
21
21
  "devDependencies": {
@@ -26,6 +26,6 @@
26
26
  "tailwindcss": "^4.3.3",
27
27
  "typescript": "^7.0.2",
28
28
  "vite": "^8.2.2",
29
- "vitest": "^4.1.11"
29
+ "vitest": "^5.0.0"
30
30
  }
31
31
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,10 +9,10 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "clsx": "^2.1.1",
15
- "effect": "4.0.0-rc.112",
15
+ "effect": "4.0.0-rc.115",
16
16
  "foldkit": "workspace:*"
17
17
  },
18
18
  "devDependencies": {
@@ -23,6 +23,6 @@
23
23
  "tailwindcss": "^4.3.3",
24
24
  "typescript": "^7.0.2",
25
25
  "vite": "^8.2.2",
26
- "vitest": "^4.1.11"
26
+ "vitest": "^5.0.0"
27
27
  }
28
28
  }
@@ -9,8 +9,8 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
13
- "effect": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
+ "effect": "4.0.0-rc.115",
14
14
  "foldkit": "workspace:*"
15
15
  },
16
16
  "devDependencies": {
@@ -21,6 +21,6 @@
21
21
  "tailwindcss": "^4.3.3",
22
22
  "typescript": "^7.0.2",
23
23
  "vite": "^8.2.2",
24
- "vitest": "^4.1.11"
24
+ "vitest": "^5.0.0"
25
25
  }
26
26
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -9,11 +9,11 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
14
  "@shoelace-style/shoelace": "^2.20.1",
15
15
  "clsx": "^2.1.1",
16
- "effect": "4.0.0-rc.112",
16
+ "effect": "4.0.0-rc.115",
17
17
  "foldkit": "workspace:*",
18
18
  "vanilla-colorful": "^0.7.2"
19
19
  },
@@ -25,6 +25,6 @@
25
25
  "tailwindcss": "^4.3.3",
26
26
  "typescript": "^7.0.2",
27
27
  "vite": "^8.2.2",
28
- "vitest": "^4.1.11"
28
+ "vitest": "^5.0.0"
29
29
  }
30
30
  }
@@ -9,9 +9,9 @@
9
9
  "test": "vitest run"
10
10
  },
11
11
  "dependencies": {
12
- "@effect/platform-browser": "4.0.0-rc.112",
12
+ "@effect/platform-browser": "4.0.0-rc.115",
13
13
  "@foldkit/ui": "workspace:*",
14
- "effect": "4.0.0-rc.112",
14
+ "effect": "4.0.0-rc.115",
15
15
  "foldkit": "workspace:*"
16
16
  },
17
17
  "devDependencies": {
@@ -22,6 +22,6 @@
22
22
  "tailwindcss": "^4.3.3",
23
23
  "typescript": "^7.0.2",
24
24
  "vite": "^8.2.2",
25
- "vitest": "^4.1.11"
25
+ "vitest": "^5.0.0"
26
26
  }
27
27
  }
@@ -1,26 +1,26 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "channel": "stable",
4
- "sourceCommit": "ba0d6f141325a66ba6608cdd5957c3667ed5ba37",
4
+ "sourceCommit": "a124b3451a885f2e58b4477adcd04b2ef9e4795a",
5
5
  "packages": {
6
- "create-foldkit-app": "0.34.0",
7
- "@foldkit/devtools": "0.159.0",
8
- "@foldkit/devtools-mcp": "0.19.5",
9
- "foldkit": "0.159.0",
10
- "@foldkit/markdown": "0.9.2",
11
- "@foldkit/oxlint-plugin": "0.12.1",
12
- "@foldkit/ui": "0.159.0",
13
- "@foldkit/vite-plugin": "0.21.0"
6
+ "create-foldkit-app": "0.35.0",
7
+ "@foldkit/devtools": "0.160.0",
8
+ "@foldkit/devtools-mcp": "0.20.0",
9
+ "foldkit": "0.160.0",
10
+ "@foldkit/markdown": "0.10.0",
11
+ "@foldkit/oxlint-plugin": "0.13.0",
12
+ "@foldkit/ui": "0.160.0",
13
+ "@foldkit/vite-plugin": "0.22.0"
14
14
  },
15
15
  "dependencies": {
16
- "@foldkit/devtools": "0.159.0",
17
- "@foldkit/vite-plugin": "0.21.0",
18
- "@foldkit/devtools-mcp": "0.19.5",
19
- "@foldkit/oxlint-plugin": "0.12.1",
16
+ "@foldkit/devtools": "0.160.0",
17
+ "@foldkit/vite-plugin": "0.22.0",
18
+ "@foldkit/devtools-mcp": "0.20.0",
19
+ "@foldkit/oxlint-plugin": "0.13.0",
20
20
  "@types/node": "^26.4.0",
21
21
  "happy-dom": "^20.11.13",
22
22
  "oxfmt": "^0.66.0",
23
23
  "oxlint": "^1.80.0",
24
- "vitest": "^4.1.11"
24
+ "vitest": "^5.0.0"
25
25
  }
26
26
  }
@@ -28,7 +28,7 @@ const FETCH_MODULE_URL = new URL('../dist/server/fetch.js', import.meta.url)
28
28
  .href
29
29
  const DEFAULT_PORT = 3000
30
30
 
31
- const PORT = Config.withDefault(Config.port('PORT'), DEFAULT_PORT)
31
+ const PORT = Config.withDefault(Config.Port('PORT'), DEFAULT_PORT)
32
32
 
33
33
  // NOTE: the origin this deployment serves. A client may send an absolute-form
34
34
  // target or a network-path reference such as `//elsewhere.example/page`.
@@ -36,7 +36,7 @@ const PORT = Config.withDefault(Config.port('PORT'), DEFAULT_PORT)
36
36
  // and cookie domains, so a target that resolves anywhere else is refused
37
37
  // before static files or fetch. Set ORIGIN when deploying behind a proxy or
38
38
  // TLS terminator.
39
- const ORIGIN = Config.option(Config.string('ORIGIN')).pipe(
39
+ const ORIGIN = Config.option(Config.String('ORIGIN')).pipe(
40
40
  Config.map(Option.filter(String.isNonEmpty)),
41
41
  )
42
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-foldkit-app",
3
- "version": "0.34.0",
3
+ "version": "0.35.0",
4
4
  "description": "Create Foldkit applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -11,17 +11,17 @@
11
11
  "dist"
12
12
  ],
13
13
  "dependencies": {
14
- "@effect/platform-node": "4.0.0-rc.112",
15
- "@effect/platform-node-shared": "4.0.0-rc.112",
14
+ "@effect/platform-node": "4.0.0-rc.115",
15
+ "@effect/platform-node-shared": "4.0.0-rc.115",
16
16
  "chalk": "^6.0.0",
17
- "effect": "4.0.0-rc.112",
17
+ "effect": "4.0.0-rc.115",
18
18
  "rimraf": "^6.1.3",
19
19
  "typescript": "^7.0.2"
20
20
  },
21
21
  "devDependencies": {
22
- "@effect/vitest": "4.0.0-rc.112",
22
+ "@effect/vitest": "4.0.0-rc.115",
23
23
  "@types/node": "^26.4.0",
24
- "vitest": "^4.1.11"
24
+ "vitest": "^5.0.0"
25
25
  },
26
26
  "keywords": [
27
27
  "create-foldkit-app",