Skip to content
Open
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
10 changes: 5 additions & 5 deletions .cursor/rules/actor-core-rules.mdc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: ActorCore rules
globs:
globs:
alwaysApply: false
---
# ActorCore Development Guide
Expand Down Expand Up @@ -59,11 +59,11 @@ When importing from workspace packages, always check the package's `package.json
- **Formatting:** Uses Biome for consistent formatting
- **Imports:** Organized imports enforced, unused imports warned
- **TypeScript:** Strict mode enabled, target ESNext
- **Naming:**
- **Naming:**
- camelCase for variables, functions
- PascalCase for classes, interfaces, types
- UPPER_CASE for constants
- **Error Handling:**
- **Error Handling:**
- Use `UserError` for client-safe errors
- Use `InternalError` for internal errors

Expand Down Expand Up @@ -105,7 +105,7 @@ When importing from workspace packages, always check the package's `package.json

- `createState()`: Function that returns initial actor state
- `onStart(c)`: Called any time actor is started (after restart/upgrade)
- `onStateChange(c, newState)`: Called when actor state changes
- `onStateChange(c,prevState, newState)`: Called when actor state changes
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The onStateChange function signature has been updated to include prevState, but there's a spacing inconsistency in the documentation. For consistency with other function signatures in this file, a space should be added after the first comma:

- `onStateChange(c,prevState, newState)`: Called when actor state changes
+ `onStateChange(c, prevState, newState)`: Called when actor state changes
Suggested change
- `onStateChange(c,prevState, newState)`: Called when actor state changes
- `onStateChange(c, prevState, newState)`: Called when actor state changes

Spotted by Diamond

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

- `onBeforeConnect(c)`: Called when new client connects
- `onConnect(c)`: Executed after client connection succeeds
- `onDisconnect(c)`: Called when client disconnects
Expand Down Expand Up @@ -144,4 +144,4 @@ When importing from workspace packages, always check the package's `package.json
- Use `assertUnreachable(x: never)` for exhaustive type checking
- Add proper JSDoc comments for public APIs
- Run `yarn check-types` regularly during development
- Use `tsx` CLI to execute TypeScript scripts directly
- Use `tsx` CLI to execute TypeScript scripts directly
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ out

# Nuxt.js build / generate output
.nuxt
dist

# Build output - ignore dist folders except in packages/actor
dist/
packages/*/dist/
examples/*/dist/
!packages/actor/dist/

# Gatsby files
.cache/
Expand Down
23 changes: 23 additions & 0 deletions examples/svelte/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
node_modules

# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/build

# OS
.DS_Store
Thumbs.db

# Env
.env
.env.*
!.env.example
!.env.test

# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
1 change: 1 addition & 0 deletions examples/svelte/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
engine-strict=true
38 changes: 38 additions & 0 deletions examples/svelte/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# sv

Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).

## Creating a project

If you're seeing this, you've probably already done this step. Congrats!

```sh
# create a new project in the current directory
npx sv create

# create a new project in my-app
npx sv create my-app
```

## Developing

Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:

```sh
npm run dev

# or start the server and open the app in a new browser tab
npm run dev -- --open
```

## Building

To create a production version of your app:

```sh
npm run build
```

You can preview the production build with `npm run preview`.

> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
9 changes: 9 additions & 0 deletions examples/svelte/backend/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { registry } from "./registry";

export type Registry = typeof registry;

registry.runServer({
cors: {
origin: "http://localhost:5173",
},
});
25 changes: 25 additions & 0 deletions examples/svelte/backend/registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { actor, setup } from "@rivetkit/actor";

export const counter = actor({
onAuth: () => {
// Configure auth here
},
state: { count: 0 },
actions: {
increment: (c, x: number) => {
console.log("incrementing by", x);
c.state.count += x;
c.broadcast("newCount", c.state.count);
return c.state.count;
},
reset: (c) => {
c.state.count = 0;
c.broadcast("newCount", c.state.count);
return c.state.count;
},
},
});

export const registry = setup({
use: { counter },
});
30 changes: 30 additions & 0 deletions examples/svelte/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "svelte-rivetkit-example",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "run-p dev:web dev:api",
"dev:web": "vite dev",
"dev:api": "tsx --watch backend/index.ts",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
"@rivetkit/actor": "workspace:*",
"@rivetkit/svelte": "workspace:*",
"@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@types/node": "^22.13.9",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.0.0",
"vite": "^7.0.4",
"npm-run-all": "^4.1.5",
"tsx": "^3.12.7"
}
}
13 changes: 13 additions & 0 deletions examples/svelte/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}

export {};
11 changes: 11 additions & 0 deletions examples/svelte/src/app.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
5 changes: 5 additions & 0 deletions examples/svelte/src/lib/actor-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createClient, createRivetKit } from "@rivetkit/svelte";
import type { Registry } from "../../backend";

const client = createClient<Registry>(`http://localhost:8080`);
export const { useActor } = createRivetKit(client);
1 change: 1 addition & 0 deletions examples/svelte/src/lib/assets/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/svelte/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// place files you want to import through the `$lib` alias in this folder.
1 change: 1 addition & 0 deletions examples/svelte/src/routes/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ssr = false;
11 changes: 11 additions & 0 deletions examples/svelte/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script lang="ts">
import favicon from '$lib/assets/favicon.svg';
let { children } = $props();
</script>

<svelte:head>
<link rel="icon" href={favicon} />
</svelte:head>

{@render children?.()}
40 changes: 40 additions & 0 deletions examples/svelte/src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script lang="ts">
import { useActor } from "../lib/actor-client";

let eventSub: any;
let count = $state(0);
const counter = useActor({ name: 'counter', key: ['test-counter'] });

$effect(()=>{
console.log('status', counter?.isConnected);
eventSub=counter?.useEvent('newCount', (x: number) => {
console.log('new count event', x);
count=x;
});
return () => {
eventSub?.unsubscribe();
};
//also works
// counter.connection?.on('newCount', (x: number) => {
// console.log('new count event', x);
// count=x;
// })
})
const increment = () => {
counter?.connection?.increment(1);

};
const reset = () => {
counter?.connection?.reset();

};

// $inspect is for debugging, but ensure it's used correctly
$inspect('useActor is connected', counter?.isConnected);
</script>

<div>
<h1>Counter: {count}</h1>
<button onclick={increment}>Increment</button>
<button onclick={reset}>Reset</button>
</div>
3 changes: 3 additions & 0 deletions examples/svelte/static/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# allow crawling everything by default
User-agent: *
Disallow:
24 changes: 24 additions & 0 deletions examples/svelte/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import adapter from "@sveltejs/adapter-auto";
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://svelte.dev/docs/kit/integrations
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter(),
alias: {
$: "./src",
"$/*": "./src/*",
$backend: "./backend",
"$backend/*": "./backend/*",
},
},
};

export default config;
24 changes: 24 additions & 0 deletions examples/svelte/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler",
"baseUrl": "./",
"paths": {
"$/": ["./src/"],
"$backend/": ["./backend/"]
}
}
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}
4 changes: 4 additions & 0 deletions examples/svelte/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"]
}
6 changes: 6 additions & 0 deletions examples/svelte/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [sveltekit()],
});
2 changes: 1 addition & 1 deletion examples/sync/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src", "tests"],
"include": ["src", "backend"],
"exclude": ["node_modules", "dist"]
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,10 @@
"@hono/node-ws": "^1.1.7",
"esbuild": "^0.25.1"
},
"packageManager": "[email protected]+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808"
"packageManager": "[email protected]+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808",
"pnpm": {
"onlyBuiltDependencies": [
"esbuild"
]
}
}
3 changes: 3 additions & 0 deletions packages/actor/dist/client.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); }// src/client.ts
var _client = require('@rivetkit/core/client'); _createStarExport(_client);
//# sourceMappingURL=client.cjs.map
1 change: 1 addition & 0 deletions packages/actor/dist/client.cjs.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions packages/actor/dist/client.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from '@rivetkit/core/client';
import '@rivetkit/core/errors';
import '@rivetkit/core/log';
import '@rivetkit/core';
import '@rivetkit/core/test';
5 changes: 5 additions & 0 deletions packages/actor/dist/client.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "@rivetkit/core/client";
import "@rivetkit/core/errors";
import "@rivetkit/core/log";
import "@rivetkit/core";
import "@rivetkit/core/test";
3 changes: 3 additions & 0 deletions packages/actor/dist/client.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/actor/dist/client.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions packages/actor/dist/errors.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _createStarExport(obj) { Object.keys(obj) .filter((key) => key !== "default" && key !== "__esModule") .forEach((key) => { if (exports.hasOwnProperty(key)) { return; } Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]}); }); }// src/errors.ts
var _errors = require('@rivetkit/core/errors'); _createStarExport(_errors);
//# sourceMappingURL=errors.cjs.map
1 change: 1 addition & 0 deletions packages/actor/dist/errors.cjs.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/actor/dist/errors.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@rivetkit/core/errors';
Loading