@evolu/relay 1.1.2-preview.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.
package/Dockerfile ADDED
@@ -0,0 +1,66 @@
1
+ FROM node:22-alpine AS base
2
+ ENV PNPM_HOME="/pnpm"
3
+ ENV PATH="$PNPM_HOME:$PATH"
4
+
5
+ FROM base AS builder
6
+ RUN apk update && apk add --no-cache libc6-compat
7
+ WORKDIR /app
8
+ RUN corepack enable pnpm
9
+ RUN pnpm install -g turbo
10
+ COPY . .
11
+
12
+ # Generate a partial monorepo with a pruned lockfile for the relay workspace
13
+ RUN turbo prune @evolu/relay --docker
14
+
15
+ # ------------------------------------------------------------
16
+ # Installer stage - build the pruned workspace
17
+ FROM base AS installer
18
+ RUN apk update && apk add --no-cache libc6-compat
19
+ WORKDIR /app
20
+
21
+ # Install pnpm and turbo
22
+ RUN corepack enable pnpm
23
+ RUN pnpm install -g turbo
24
+
25
+ # Install dependencies from pruned lockfile
26
+ COPY --from=builder /app/out/json/ .
27
+ RUN pnpm install --frozen-lockfile
28
+
29
+ # Copy source and build
30
+ COPY --from=builder /app/out/full/ .
31
+ # Ensure README.md is available at the root for the build process
32
+ COPY --from=builder /app/README.md ./README.md
33
+ RUN turbo run build
34
+
35
+ # ------------------------------------------------------------
36
+ # Runner stage - minimal runtime image
37
+ FROM base AS runner
38
+ WORKDIR /app
39
+
40
+ # Create non-root user
41
+ RUN addgroup --system --gid 1001 nodejs && \
42
+ adduser --system --uid 1001 evolu --ingroup nodejs
43
+ RUN chown evolu:nodejs /app
44
+ USER evolu
45
+
46
+ # Copy built application
47
+ COPY --from=installer --chown=evolu:nodejs /app/apps/relay/dist ./dist
48
+
49
+ # Copy the complete node_modules with all dependencies
50
+ COPY --from=installer --chown=evolu:nodejs /app/node_modules ./node_modules
51
+
52
+ # Copy the built workspace packages that the relay needs at runtime
53
+ COPY --from=installer --chown=evolu:nodejs /app/packages/common/dist ./node_modules/@evolu/common/dist
54
+ COPY --from=installer --chown=evolu:nodejs /app/packages/common/package.json ./node_modules/@evolu/common/package.json
55
+ COPY --from=installer --chown=evolu:nodejs /app/packages/nodejs/dist ./node_modules/@evolu/nodejs/dist
56
+ COPY --from=installer --chown=evolu:nodejs /app/packages/nodejs/package.json ./node_modules/@evolu/nodejs/package.json
57
+
58
+ # Expose port
59
+ EXPOSE 4000
60
+
61
+ # Health check
62
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
63
+ CMD wget --no-verbose --tries=1 --spider http://localhost:4000 || exit 1
64
+
65
+ # Start the application
66
+ CMD ["node", "dist/index.js"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Evolu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,154 @@
1
+ # Evolu Relay - Docker Setup
2
+
3
+ Docker configuration for the Evolu Relay.
4
+
5
+ ## 🚀 Quick Start for Developers
6
+
7
+ **Just one command to get started:**
8
+
9
+ ```bash
10
+ cd apps/relay
11
+ pnpm docker:up
12
+ ```
13
+
14
+ That's it! This will:
15
+
16
+ - ✅ Automatically build the Docker image
17
+ - ✅ Start the Evolu Relay service
18
+ - ✅ Show real-time logs
19
+ - ✅ Make the service available at `http://localhost:4000`
20
+
21
+ Press `Ctrl+C` to stop the service.
22
+
23
+ ### Background Mode (Optional)
24
+
25
+ ```bash
26
+ cd apps/relay
27
+
28
+ # Start in background
29
+ pnpm docker:up:detached
30
+
31
+ # View logs when needed
32
+ pnpm docker:logs
33
+
34
+ # Stop when done
35
+ pnpm docker:down
36
+ ```
37
+
38
+ ## 🔧 Advanced Usage
39
+
40
+ ### All Available Commands
41
+
42
+ | Command | Description | Auto-builds? | Persistence |
43
+ | ------------------------- | ---------------------------------------------- | ------------ | ------------ |
44
+ | `pnpm docker:up` | **Recommended**: Start in foreground with logs | ✅ Yes | Named volume |
45
+ | `pnpm docker:up:detached` | Start in background | ✅ Yes | Named volume |
46
+ | `pnpm docker:down` | Stop services | N/A | N/A |
47
+ | `pnpm docker:restart` | Restart with rebuild | ✅ Yes | Named volume |
48
+ | `pnpm docker:logs` | View logs (live) | N/A | N/A |
49
+ | `pnpm docker:shell` | Access running container shell | N/A | N/A |
50
+ | `pnpm docker:stats` | View container resource usage | N/A | N/A |
51
+ | `pnpm docker:inspect` | View container details | N/A | N/A |
52
+ | `pnpm docker:build` | Build image only | N/A | N/A |
53
+ | `pnpm docker:clean` | Clean up containers and images | N/A | N/A |
54
+ | `pnpm docker:clean:all` | **Full cleanup**: Remove everything | N/A | N/A |
55
+
56
+ ### Manual Docker Commands (Alternative)
57
+
58
+ ```bash
59
+ # Build manually
60
+ docker-compose build
61
+
62
+ # Run with Docker Compose
63
+ docker-compose up --build
64
+
65
+ # Run directly with Docker
66
+ docker run -p 4000:4000 evolu/relay:latest
67
+ ```
68
+
69
+ ## ❓ FAQ
70
+
71
+ **Q: Do I need to build the image first?**
72
+ A: No! `pnpm docker:up` automatically builds and starts everything.
73
+
74
+ **Q: How do I update after code changes?**
75
+ A: Just run `pnpm docker:restart` or stop and start again.
76
+
77
+ **Q: How do I know if it's working?**
78
+ A: Check `http://localhost:4000` - you should get a "426 Upgrade Required" response (this is correct for WebSocket servers).
79
+
80
+ **Q: How do I see what's happening?**
81
+ A: Use `pnpm docker:logs` to view live logs.
82
+
83
+ **Q: How do I access the container?**
84
+ A: Use `pnpm docker:shell` to get shell access inside the running container.
85
+
86
+ **Q: How do I clean up everything?**
87
+ A: Run `pnpm docker:clean:all` to remove all containers, images, and networks.
88
+
89
+ ## 📁 Docker Files
90
+
91
+ - `Dockerfile` - Multi-stage Docker build configuration
92
+ - `docker-compose.yml` - Docker Compose configuration with health checks
93
+ - `.dockerignore` - Files to exclude from Docker build context
94
+
95
+ ## ⚙️ Configuration
96
+
97
+ - **Port**: 4000 (modify in `docker-compose.yml` if needed)
98
+ - **Environment**: `NODE_ENV=production` in Docker
99
+ - **Health Check**: Built-in health monitoring via Docker Compose
100
+ - **Data Persistence**: SQLite database automatically persists via Docker volumes
101
+
102
+ ### Container Details
103
+
104
+ | Component | Value | Description |
105
+ | ------------------ | --------------------- | ---------------------------------- |
106
+ | **Container Name** | `evolu-relay-server` | Easy identification |
107
+ | **Image Name** | `evolu/relay:latest` | Tagged for production deployment |
108
+ | **Network** | `evolu-relay-network` | Isolated Docker network |
109
+ | **Volume** | `evolu-relay-data` | Persistent SQLite database storage |
110
+ | **User** | `evolu:nodejs` (1001) | Non-root user for security |
111
+ | **Memory Limit** | 1GB | Resource constraint |
112
+ | **CPU Limit** | 1.0 | CPU resource constraint |
113
+
114
+ ## 🚨 Troubleshooting
115
+
116
+ | Issue | Solution |
117
+ | ------------------------ | ---------------------------------------------------------- |
118
+ | Build fails | Run `pnpm docker:clean:all` and try again |
119
+ | Port already in use | Change port in `docker-compose.yml` or stop other services |
120
+ | Container won't start | Check logs with `pnpm docker:logs` |
121
+ | Need container access | Use `pnpm docker:shell` for interactive shell |
122
+ | Performance issues | Check resources with `pnpm docker:stats` |
123
+ | Need to reset everything | Run `pnpm docker:clean:all` |
124
+
125
+ ## 🔍 Monitoring & Debugging
126
+
127
+ ### Real-time Monitoring
128
+
129
+ ```bash
130
+ # View live logs
131
+ pnpm docker:logs
132
+
133
+ # Monitor resource usage
134
+ pnpm docker:stats
135
+
136
+ # Container details
137
+ pnpm docker:inspect
138
+
139
+ # Access container shell
140
+ pnpm docker:shell
141
+ ```
142
+
143
+ ### Inside Container Commands
144
+
145
+ ```bash
146
+ # Access container
147
+ pnpm docker:shell
148
+
149
+ # Then inside container:
150
+ ls -la /app/apps/relay/data/ # View database files
151
+ ps aux # Check running processes
152
+ top # Monitor resource usage
153
+ netstat -tlnp # Check port bindings
154
+ ```
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # Evolu Relay
2
+
3
+ A WebSocket relay server for the Evolu database system that enables real-time synchronization between clients.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ### Docker Development (Recommended)
8
+
9
+ ```bash
10
+ cd apps/relay
11
+ pnpm docker:up
12
+ ```
13
+
14
+ ### Production Deployment
15
+
16
+ ```bash
17
+ # Complete server setup + deployment
18
+ pnpm deploy:full
19
+ ```
20
+
21
+ The relay will be available at `http://localhost:4000` (Docker) or your server's IP:4000 (production)
22
+
23
+ ## 📖 Documentation
24
+
25
+ - **[Docker Setup](./README.docker.md)** - Complete Docker containerization guide
26
+
27
+ ## 🔧 Development
28
+
29
+ ### Local Development (Node.js)
30
+
31
+ ```bash
32
+ pnpm dev # Start with file watching
33
+ pnpm build # Build TypeScript
34
+ pnpm start # Start built application
35
+ ```
36
+
37
+ ### Docker Development
38
+
39
+ ```bash
40
+ pnpm docker:up # Start with logs
41
+ pnpm docker:up:detached # Start in background
42
+ pnpm docker:down # Stop containers
43
+ pnpm docker:logs # View logs
44
+ pnpm docker:shell # Access container shell
45
+ pnpm docker:clean # Clean up everything
46
+ ```
47
+
48
+ ## 🛠️ Available Commands
49
+
50
+ ### Development
51
+
52
+ | Command | Description |
53
+ | ------------ | ------------------------------------------- |
54
+ | `pnpm dev` | Start development server with file watching |
55
+ | `pnpm build` | Build TypeScript to JavaScript |
56
+ | `pnpm start` | Start the built application |
57
+ | `pnpm clean` | Clean build artifacts |
58
+
59
+ ### Docker
60
+
61
+ | Command | Description |
62
+ | ------------------------- | ------------------------------------ |
63
+ | `pnpm docker:up` | Build and start containers with logs |
64
+ | `pnpm docker:up:detached` | Start containers in background |
65
+ | `pnpm docker:down` | Stop all containers |
66
+ | `pnpm docker:restart` | Restart containers with rebuild |
67
+ | `pnpm docker:logs` | View container logs |
68
+ | `pnpm docker:shell` | Access running container shell |
69
+ | `pnpm docker:stats` | View container resource usage |
70
+ | `pnpm docker:clean` | Remove containers and cleanup |
71
+
72
+ ## 📋 Requirements
73
+
74
+ - **Node.js** ≥22.0.0
75
+ - **Docker** (for containerized development/deployment)
76
+ - **pnpm** (workspace package manager)
77
+
78
+ ## 🔗 Integration
79
+
80
+ After deployment, your Evolu applications can connect to the relay:
81
+
82
+ **Development**: `ws://localhost:4000`
83
+ **Production**: `ws://your-server-ip:4000`
84
+
85
+ The relay handles WebSocket connections and data synchronization across all connected Evolu applications.
86
+
87
+ ---
88
+
89
+ 📚 **Quick Links**:
90
+
91
+ - [Docker Setup Guide](./README.docker.md) - Local development and testing
package/data/.gitkeep ADDED
@@ -0,0 +1,2 @@
1
+ # This directory is used for persistent SQLite database storage in production deployments
2
+ # The .gitkeep file ensures this directory exists in git while ignoring its contents
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@evolu/relay",
3
+ "version": "1.1.2-preview.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "@evolu/relay": "dist/src/cli.js"
7
+ },
8
+ "scripts": {
9
+ "dev": "tsx --watch src/cli.ts -- start",
10
+ "build": "shx rm -rf dist && tsc",
11
+ "start": "node dist/src/cli.js",
12
+ "clean": "shx rm -rf .turbo node_modules dist db.sqlite",
13
+ "docker:build": "docker-compose build --no-cache",
14
+ "docker:up": "docker-compose up --build",
15
+ "docker:up:detached": "docker-compose up -d --build",
16
+ "docker:down": "docker-compose down",
17
+ "docker:restart": "docker-compose down && docker-compose up --build",
18
+ "docker:logs": "docker-compose logs -f evolu-relay",
19
+ "docker:shell": "docker exec -it evolu-relay-server sh",
20
+ "docker:inspect": "docker inspect evolu-relay-server",
21
+ "docker:stats": "docker stats evolu-relay-server",
22
+ "docker:clean": "docker-compose down -v && docker system prune -f",
23
+ "docker:clean:all": "docker-compose down -v && docker system prune -af && docker volume prune -f"
24
+ },
25
+ "dependencies": {
26
+ "@evolu/common": "workspace:*",
27
+ "@evolu/nodejs": "workspace:*",
28
+ "commander": "^14.0.1"
29
+ },
30
+ "devDependencies": {
31
+ "@evolu/tsconfig": "workspace:*",
32
+ "@types/node": "^22.17.1",
33
+ "typescript": "^5.9.2"
34
+ },
35
+ "engines": {
36
+ "node": ">=22.0.0"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { Command, Option } from "commander";
2
+ import packageJson from "../package.json" with { type: "json" };
3
+ import { logger } from "./logger.js";
4
+ import { startNodeJsRelay } from "./nodejs.js";
5
+ import { cliParams } from "./params.js";
6
+ function main() {
7
+ const program = new Command()
8
+ .name("@evolu/relay")
9
+ .description("Evolu Relay server")
10
+ .version(packageJson.version || "1.0.0", "-v, --version", "display the version number");
11
+ program
12
+ .command("start")
13
+ .description("start the relay server")
14
+ .addOption(new Option("-n, --name <name>", "database name").default("evolu-relay"))
15
+ .addOption(new Option("-l, --enable-logging", "enable logging").default(false))
16
+ .addOption(new Option("-p, --port <number>", "port to listen on")
17
+ .default(4000)
18
+ .argParser(Number))
19
+ .addOption(new Option("-m, --in-memory", "enable in-memory mode").default(false))
20
+ // .addOption(
21
+ // new Option("--platform <platform>", "platform")
22
+ // .choices(["nodejs", "bun"])
23
+ // .default("nodejs"),
24
+ // )
25
+ .action(async (options) => {
26
+ logger.enabled = true;
27
+ const params = cliParams.fromUnknown(options);
28
+ if (!params.ok) {
29
+ logger.error(params.error.reason);
30
+ process.exit(1);
31
+ }
32
+ try {
33
+ await startNodeJsRelay(params.value);
34
+ }
35
+ catch (error) {
36
+ logger.error(error);
37
+ process.exit(1);
38
+ }
39
+ });
40
+ program.parse();
41
+ }
42
+ main();
@@ -0,0 +1,2 @@
1
+ export declare const logger: import("@evolu/common").Console;
2
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,iCAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { createConsole } from "@evolu/common";
2
+ // TODO: use createConsoleWithTime after release
3
+ // export const logger = createConsoleWithTime({ timestampType: "absolute" });
4
+ export const logger = createConsole();
@@ -0,0 +1,3 @@
1
+ import { CliParams } from "./params.js";
2
+ export declare function startNodeJsRelay(options: CliParams): Promise<void>;
3
+ //# sourceMappingURL=nodejs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodejs.d.ts","sourceRoot":"","sources":["../../src/nodejs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBxE"}
@@ -0,0 +1,24 @@
1
+ import { createNodeJsRelay } from "@evolu/nodejs";
2
+ import { mkdirSync } from "fs";
3
+ import { once } from "node:events";
4
+ import { logger } from "./logger.js";
5
+ export async function startNodeJsRelay(options) {
6
+ // Ensure the database is created in a predictable location for Docker.
7
+ mkdirSync("data", { recursive: true });
8
+ process.chdir("data");
9
+ if (options.enableLogging) {
10
+ logger.enabled = true;
11
+ }
12
+ const relay = await createNodeJsRelay({ console: logger })({
13
+ port: options.port,
14
+ enableLogging: options.enableLogging,
15
+ name: options.name,
16
+ });
17
+ await Promise.race([
18
+ once(process, "SIGINT"), // Ctrl-C
19
+ once(process, "SIGTERM"), // OS/k8s/etc requested termination
20
+ ]);
21
+ logger.enabled = true;
22
+ logger.log("Shutting down relay server");
23
+ relay[Symbol.dispose]();
24
+ }
@@ -0,0 +1,7 @@
1
+ export declare const cliParams: import("@evolu/common").ObjectType<{
2
+ name: import("@evolu/common").BrandType<import("@evolu/common").Type<"String", string, string, import("@evolu/common").StringError, string, import("@evolu/common").StringError>, "SimpleName", import("@evolu/common").RegexError<"SimpleName">, import("@evolu/common").StringError>;
3
+ enableLogging: import("@evolu/common").Type<"Boolean", boolean, boolean, import("@evolu/common").BooleanError, boolean, import("@evolu/common").BooleanError>;
4
+ port: import("@evolu/common").Type<"Number", number, number, import("@evolu/common").NumberError, number, import("@evolu/common").NumberError>;
5
+ }>;
6
+ export type CliParams = typeof cliParams.Type;
7
+ //# sourceMappingURL=params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../src/params.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;EAIpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Boolean, Number, object, SimpleName } from "@evolu/common";
2
+ export const cliParams = object({
3
+ name: SimpleName,
4
+ enableLogging: Boolean,
5
+ port: Number,
6
+ });
@@ -0,0 +1,56 @@
1
+ services:
2
+ evolu-relay:
3
+ container_name: evolu-relay-server
4
+ image: evolu/relay:latest
5
+ build:
6
+ context: ../../
7
+ dockerfile: apps/relay/Dockerfile
8
+ tags:
9
+ - evolu/relay:latest
10
+ - evolu/relay:dev
11
+ ports:
12
+ - "4000:4000"
13
+ volumes:
14
+ # Use named volume by default, can be overridden with bind mount if needed
15
+ - evolu-relay-data:/app/apps/relay/data
16
+ environment:
17
+ - NODE_ENV=${NODE_ENV:-production}
18
+ - LOG_LEVEL=${LOG_LEVEL:-info}
19
+ restart: unless-stopped
20
+ deploy:
21
+ resources:
22
+ limits:
23
+ memory: ${MEMORY_LIMIT:-1G}
24
+ cpus: ${CPU_LIMIT:-1.0}
25
+ reservations:
26
+ memory: ${MEMORY_RESERVED:-512M}
27
+ cpus: ${CPU_RESERVED:-0.5}
28
+ healthcheck:
29
+ test:
30
+ [
31
+ "CMD",
32
+ "sh",
33
+ "-c",
34
+ "wget --no-verbose --tries=1 --spider http://localhost:4000 2>&1 | grep -q '426 Upgrade Required' || exit 1",
35
+ ]
36
+ interval: 30s
37
+ timeout: 5s
38
+ retries: 3
39
+ start_period: 30s
40
+ logging:
41
+ driver: "json-file"
42
+ options:
43
+ max-size: ${LOG_MAX_SIZE:-50m}
44
+ max-file: ${LOG_MAX_FILES:-5}
45
+ networks:
46
+ - evolu-network
47
+
48
+ volumes:
49
+ evolu-relay-data:
50
+ driver: local
51
+ name: evolu-relay-data
52
+
53
+ networks:
54
+ evolu-network:
55
+ name: evolu-relay-network
56
+ driver: bridge
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@evolu/relay",
3
+ "version": "1.1.2-preview.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "@evolu/relay": "dist/src/cli.js"
7
+ },
8
+ "dependencies": {
9
+ "commander": "^14.0.1",
10
+ "@evolu/common": "6.0.1-preview.19",
11
+ "@evolu/nodejs": "1.0.1-preview.7"
12
+ },
13
+ "devDependencies": {
14
+ "@types/node": "^22.17.1",
15
+ "typescript": "^5.9.2",
16
+ "@evolu/tsconfig": "0.0.2"
17
+ },
18
+ "engines": {
19
+ "node": ">=22.0.0"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "scripts": {
25
+ "dev": "tsx --watch src/cli.ts -- start",
26
+ "build": "shx rm -rf dist && tsc",
27
+ "start": "node dist/src/cli.js",
28
+ "clean": "shx rm -rf .turbo node_modules dist db.sqlite",
29
+ "docker:build": "docker-compose build --no-cache",
30
+ "docker:up": "docker-compose up --build",
31
+ "docker:up:detached": "docker-compose up -d --build",
32
+ "docker:down": "docker-compose down",
33
+ "docker:restart": "docker-compose down && docker-compose up --build",
34
+ "docker:logs": "docker-compose logs -f evolu-relay",
35
+ "docker:shell": "docker exec -it evolu-relay-server sh",
36
+ "docker:inspect": "docker inspect evolu-relay-server",
37
+ "docker:stats": "docker stats evolu-relay-server",
38
+ "docker:clean": "docker-compose down -v && docker system prune -f",
39
+ "docker:clean:all": "docker-compose down -v && docker system prune -af && docker volume prune -f"
40
+ }
41
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,59 @@
1
+ import { Command, Option } from "commander";
2
+ import packageJson from "../package.json" with { type: "json" };
3
+ import { logger } from "./logger.js";
4
+ import { startNodeJsRelay } from "./nodejs.js";
5
+ import { cliParams } from "./params.js";
6
+
7
+ function main() {
8
+ const program = new Command()
9
+ .name("@evolu/relay")
10
+ .description("Evolu Relay server")
11
+ .version(
12
+ packageJson.version || "1.0.0",
13
+ "-v, --version",
14
+ "display the version number",
15
+ );
16
+
17
+ program
18
+ .command("start")
19
+ .description("start the relay server")
20
+ .addOption(
21
+ new Option("-n, --name <name>", "database name").default("evolu-relay"),
22
+ )
23
+ .addOption(
24
+ new Option("-l, --enable-logging", "enable logging").default(false),
25
+ )
26
+ .addOption(
27
+ new Option("-p, --port <number>", "port to listen on")
28
+ .default(4000)
29
+ .argParser(Number),
30
+ )
31
+ .addOption(
32
+ new Option("-m, --in-memory", "enable in-memory mode").default(false),
33
+ )
34
+ // .addOption(
35
+ // new Option("--platform <platform>", "platform")
36
+ // .choices(["nodejs", "bun"])
37
+ // .default("nodejs"),
38
+ // )
39
+ .action(async (options: unknown) => {
40
+ logger.enabled = true;
41
+ const params = cliParams.fromUnknown(options);
42
+
43
+ if (!params.ok) {
44
+ logger.error(params.error.reason);
45
+ process.exit(1);
46
+ }
47
+
48
+ try {
49
+ await startNodeJsRelay(params.value);
50
+ } catch (error: unknown) {
51
+ logger.error(error);
52
+ process.exit(1);
53
+ }
54
+ });
55
+
56
+ program.parse();
57
+ }
58
+
59
+ main();
package/src/logger.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { createConsole } from "@evolu/common";
2
+
3
+ // TODO: use createConsoleWithTime after release
4
+ // export const logger = createConsoleWithTime({ timestampType: "absolute" });
5
+ export const logger = createConsole();