Skip to content

Commit 1376a63

Browse files
committed
Refactor example dependency toggling and docs
1 parent 1764fcb commit 1376a63

10 files changed

Lines changed: 79 additions & 52 deletions

File tree

examples/README.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Examples
22

3-
## Dependency Management
3+
## Testing examples
44

5-
During the preview phase, examples use monorepo dependencies (`workspace:*`) for local development and testing. After the official release, dependencies will point to published packages on npm.
5+
To test an example, move its directory out of Evolu monorepo. Otherwise, package managers will not work correctly. Examples are meant to work in isolation.
6+
7+
If you are using Yarn, you must install peer dependencies manually.
68

7-
To switch between development and production modes, use:
9+
## Toggle dependencies
810

911
```bash
1012
pnpm examples:toggle-deps
@@ -13,10 +15,4 @@ pnpm examples:toggle-deps
1315
This script toggles all example dependencies between:
1416

1517
- **Development**: `workspace:*` (uses local monorepo packages)
16-
- **Production**: `npm:@evolu/package@latest` (uses published packages)
17-
18-
## Testing Examples
19-
20-
To test an example, move its directory out of Evolu monorepo. Otherwise, package managers will not work correctly. Examples are meant to work in isolation.
21-
22-
If you are using Yarn, you must install peer dependencies manually.
18+
- **Production**: `latest` (uses published packages)

examples/angular-vite-pwa/src/app/app.config.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import { Schema } from "./schema";
1111
const evolu = createEvolu(evoluWebDeps)(Schema, {
1212
name: getOrThrow(SimpleName.from("angular-vite-pwa-minimal")),
1313

14-
...(typeof window !== "undefined" &&
15-
window.location.hostname === "localhost" && {
16-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
17-
}),
14+
// ...(typeof window !== "undefined" &&
15+
// window.location.hostname === "localhost" && {
16+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
17+
// }),
1818
});
1919

2020
// This injection token allows us to use Angular's dependency injection to get

examples/react-electron/components/EvoluMinimalExample.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@ const Schema = {
2626
const evolu = Evolu.createEvolu(evoluReactWebDeps)(Schema, {
2727
name: Evolu.SimpleName.orThrow("minimal-example"),
2828

29-
reloadUrl: "/playgrounds/minimal",
30-
31-
...(process.env.NODE_ENV === "development" && {
32-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
33-
}),
29+
// ...(process.env.NODE_ENV === "development" && {
30+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
31+
// }),
3432
});
3533

3634
// Creates a typed React Hook returning an instance of Evolu.

examples/react-expo/app/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ export default function Index(): React.ReactNode {
5454
),
5555
encryptionKey: authResult?.owner?.encryptionKey,
5656
externalAppOwner: authResult?.owner,
57-
...(process.env.NODE_ENV === "development" && {
58-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
59-
}),
57+
// ...(process.env.NODE_ENV === "development" && {
58+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
59+
// }),
6060
});
6161

6262
setEvolu(evolu as EvoluType<typeof Schema>);

examples/react-nextjs/components/EvoluMinimalExample.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@ const Schema = {
2828
const evolu = Evolu.createEvolu(evoluReactWebDeps)(Schema, {
2929
name: Evolu.SimpleName.orThrow("minimal-example"),
3030

31-
reloadUrl: "/playgrounds/minimal",
32-
33-
...(process.env.NODE_ENV === "development" && {
34-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
35-
}),
31+
// ...(process.env.NODE_ENV === "development" && {
32+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
33+
// }),
3634
});
3735

3836
// Creates a typed React Hook returning an instance of Evolu.

examples/react-vite-pwa/src/components/EvoluMinimalExample.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@ const evolu = Evolu.createEvolu(evoluReactWebDeps)(Schema, {
3535
name: Evolu.SimpleName.orThrow(
3636
`${service}-${authResult?.owner?.id ?? "guest"}`,
3737
),
38-
reloadUrl: "/",
3938
encryptionKey: authResult?.owner?.encryptionKey,
4039
externalAppOwner: authResult?.owner,
41-
...(process.env.NODE_ENV === "development" && {
42-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
43-
}),
40+
// ...(process.env.NODE_ENV === "development" && {
41+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
42+
// }),
4443
});
4544

4645
// Creates a typed React Hook returning an instance of Evolu.

examples/svelte-vite-pwa/src/App.svelte

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@
2323
const evolu = Evolu.createEvolu(evoluSvelteDeps)(Schema, {
2424
name: Evolu.SimpleName.orThrow("minimal-example"),
2525
26-
reloadUrl: "/",
27-
28-
...(process.env.NODE_ENV === "development" && {
29-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
30-
}),
26+
// ...(process.env.NODE_ENV === "development" && {
27+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
28+
// }),
3129
});
3230
3331
/**

examples/vue-vite-pwa/src/App.vue

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,10 @@ const DatabaseSchema = {
5555
type DatabaseSchema = typeof DatabaseSchema;
5656
5757
const evolu = createEvolu(evoluWebDeps)(DatabaseSchema, {
58-
reloadUrl: "/",
5958
name: SimpleName.orThrow("minimal-example"),
60-
...(isDev && {
61-
transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
62-
}),
63-
indexes: (create) => [
64-
create("todoCreatedAt").on("todo").column("createdAt"),
65-
create("todoCategoryCreatedAt").on("todoCategory").column("createdAt"),
66-
],
59+
// ...(isDev && {
60+
// transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
61+
// }),
6762
});
6863
6964
provideEvolu(evolu);

pnpm-workspace.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ packages:
33
- packages/*
44
- examples/*
55

6+
# Catalogs enforce consistent versions across the monorepo, especially important
7+
# for react-expo which requires exact React versions
68
catalogs:
79
react19:
810
"@types/react": ~19.1.13

scripts/toggle-examples-deps.ts

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,64 @@ import path from "node:path";
55

66
const examplesDir = path.resolve(__dirname, "../examples");
77

8-
type Mode = "Development" | "Production";
8+
type Mode = "development" | "production";
9+
10+
// Hardcoded catalogs matching pnpm-workspace.yaml
11+
const CATALOGS = {
12+
react19: {
13+
"@types/react": "~19.1.13",
14+
"@types/react-dom": "~19.1.9",
15+
react: "19.1.0",
16+
"react-dom": "19.1.0",
17+
},
18+
} as const;
919

1020
// Function to toggle the mode for a single example
1121
const toggleMode = (examplePath: string, mode: Mode): void => {
1222
const packageJsonPath = path.join(examplePath, "package.json");
1323
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
1424

25+
// Toggle @evolu/* dependencies
1526
for (const dep in packageJson.dependencies) {
16-
if (!dep.startsWith("@evolu/")) {
17-
continue;
27+
if (dep.startsWith("@evolu/")) {
28+
if (mode === "production") {
29+
packageJson.dependencies[dep] = `latest`;
30+
} else if (mode === "development") {
31+
packageJson.dependencies[dep] = `workspace:*`;
32+
}
1833
}
34+
}
1935

20-
if (mode === "Production") {
21-
packageJson.dependencies[dep] = `npm:${dep}@latest`;
22-
} else if (mode === "Development") {
23-
packageJson.dependencies[dep] = `workspace:*`;
36+
// Toggle catalog references in both dependencies and devDependencies
37+
const toggleCatalogRefs = (deps: Record<string, string>): void => {
38+
for (const dep in deps) {
39+
const value = deps[dep];
40+
if (mode === "production" && value.startsWith("catalog:")) {
41+
const catalogName = value.replace("catalog:", "");
42+
const catalog = CATALOGS[catalogName as keyof typeof CATALOGS];
43+
if (catalog && dep in catalog) {
44+
deps[dep] = catalog[dep as keyof typeof catalog];
45+
}
46+
} else if (mode === "development") {
47+
// Find which catalog this dep belongs to
48+
for (const [catalogName, catalogDeps] of Object.entries(CATALOGS)) {
49+
if (
50+
dep in catalogDeps &&
51+
catalogDeps[dep as keyof typeof catalogDeps] === value
52+
) {
53+
deps[dep] = `catalog:${catalogName}`;
54+
break;
55+
}
56+
}
57+
}
2458
}
59+
};
60+
61+
if (packageJson.dependencies) {
62+
toggleCatalogRefs(packageJson.dependencies);
63+
}
64+
if (packageJson.devDependencies) {
65+
toggleCatalogRefs(packageJson.devDependencies);
2566
}
2667

2768
fs.writeFileSync(
@@ -53,7 +94,7 @@ const askForMode = async (): Promise<Mode> => {
5394
type: "list",
5495
name: "mode",
5596
message: "Which mode do you want to switch to?",
56-
choices: ["Development", "Production"],
97+
choices: ["development", "production"],
5798
},
5899
]);
59100

0 commit comments

Comments
 (0)