Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/platformer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"typecheck": "tsc --noEmit",
"build": "pnpm typecheck && vite build",
"preview": "vite preview",
"check": "pnpm build"
},
Expand Down
37 changes: 24 additions & 13 deletions examples/platformer/src/machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ const initialCharacter = () =>
export const CharacterMachine = Machine.make({
id: "PlatformerCharacter",
states: CharacterStates.states,
events: Object.values(Event.cases),
internalEvents: Object.values(InternalEvent.cases),
events: [Event],
internalEvents: [InternalEvent],
initial: initialCharacter
}).handle({
Character: {
Expand All @@ -151,18 +151,29 @@ export const CharacterMachine = Machine.make({
Grounded: {
on: {
JumpPressed: ({ event, target }) =>
target.branch.Character.locomotion.Airborne(
State.cases.Airborne.make({ originY: event.y }),
(airborne) =>
airborne
.motion(State.cases.Motion.make({}), (motion) =>
motion.Jumping(
State.cases.Jumping.make({ startedAt: event.at, push: 0, kind: "Ground" })
)
)
.airJump(State.cases.AirJump.make({}), (airJump) =>
airJump.AirJumpGroundLock(State.cases.AirJumpGroundLock.make({}))
target.full.Character(State.cases.Character.make({}), (character) =>
character
.locomotion(State.cases.Locomotion.make({}), (locomotion) =>
locomotion.Airborne(State.cases.Airborne.make({ originY: event.y }), (airborne) =>
airborne
.motion(State.cases.Motion.make({}), (motion) =>
motion.Jumping(
State.cases.Jumping.make({ startedAt: event.at, push: 0, kind: "Ground" })
)
)
.airJump(State.cases.AirJump.make({}), (airJump) =>
airJump.AirJumpGroundLock(State.cases.AirJumpGroundLock.make({}))
)
)
)
.facing(State.cases.Facing.make({}), (facing) => facing.Right(State.cases.Right.make({})))
.contact(State.cases.WallContact.make({}), (contact) =>
event.wall === -1
? contact.LeftWall(State.cases.LeftWall.make({}))
: event.wall === 1
? contact.RightWall(State.cases.RightWall.make({}))
: contact.NoWall(State.cases.NoWall.make({}))
)
)
},
states: {
Expand Down
3 changes: 3 additions & 0 deletions examples/playground/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
node_modules

45 changes: 45 additions & 0 deletions examples/playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Effect Machine examples playground

A React and Vite workspace with TanStack Router routes for implementing small
`@typeonce/effect-machine` examples.

## Run it

From this directory:

```sh
pnpm install
pnpm dev
```

Build and type-check with:

```sh
pnpm check
```

## Starters

Each starter keeps its machine definition next to its route component:

- `src/examples/turnstile`
- `src/examples/traffic-light`
- `src/examples/microwave`
- `src/examples/media-player`
- `src/examples/worker-tabs`

The first four route components are intentionally light: their domain schemas,
events, and state topology are ready, while the React-to-machine adapter is left
for the exercise.

The workers route additionally contains:

- `machine.worker.ts`: Vite's module-worker entry point and the place to start
the machine runtime.
- `worker-client.ts`: typed worker construction, send, subscribe, and cleanup.
- `tab-channel.ts`: a typed `BroadcastChannel` wrapper for cross-tab messages.
- `protocol.ts`: worker and tab message boundaries.

Vite discovers the worker because `worker-client.ts` constructs it with
`new Worker(new URL("./machine.worker.ts", import.meta.url), { type: "module" })`.
No extra Vite worker plugin is required.
14 changes: 14 additions & 0 deletions examples/playground/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#10131a" />
<title>Effect Machine examples</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

34 changes: 34 additions & 0 deletions examples/playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@typeonce/effect-machine-example-playground",
"version": "0.0.0",
"private": true,
"description": "React playground for building @typeonce/effect-machine examples",
"type": "module",
"scripts": {
"dev": "vite",
"typecheck": "tsc --noEmit",
"build": "pnpm typecheck && vite build",
"preview": "vite preview",
"check": "pnpm build"
},
"dependencies": {
"@effect/atom-react": "4.0.0-beta.102",
"@tanstack/react-router": "1.170.18",
"@typeonce/effect-machine": "file:../..",
"effect": "4.0.0-beta.102",
"react": "19.2.7",
"react-dom": "19.2.7",
"scheduler": "0.27.0"
},
"devDependencies": {
"@types/react": "19.2.17",
"@types/react-dom": "19.2.2",
"@vitejs/plugin-react": "6.0.4",
"typescript": "6.0.3",
"vite": "8.1.5"
},
"packageManager": "pnpm@10.17.1",
"engines": {
"node": "^20.19.0 || >=22.12.0"
}
}
Loading