Skip to content

Commit

Permalink
Update Electron example
Browse files Browse the repository at this point in the history
  • Loading branch information
steida committed Dec 4, 2023
1 parent 9ece454 commit 610938c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 35 deletions.
2 changes: 1 addition & 1 deletion examples/electron-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"typescript": "5.3.2"
},
"dependencies": {
"@evolu/react": "2.0.7",
"@evolu/react": "3.0.0",
"@types/react-dom": "^18.2.17",
"electron-squirrel-startup": "1.0.0",
"react": "18.2.0",
Expand Down
81 changes: 47 additions & 34 deletions examples/electron-app/src/Example.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
import { TreeFormatter } from "@effect/schema";
import * as S from "@effect/schema/Schema";
import * as Evolu from "@evolu/react";
import {
canUseDom,
cast,
createEvolu,
EvoluProvider,
id,
jsonArrayFrom,
NonEmptyString1000,
parseMnemonic,
SqliteBoolean,
String,
useEvolu,
useEvoluError,
useOwner,
useQuery,
} from "@evolu/react";
import { Effect, Exit } from "effect";
import {
ChangeEvent,
FC,
Suspense,
memo,
startTransition,
Suspense,
useEffect,
useState,
} from "react";

const TodoId = Evolu.id("Todo");
const TodoId = id("Todo");
type TodoId = S.Schema.To<typeof TodoId>;

const TodoCategoryId = Evolu.id("TodoCategory");
const TodoCategoryId = id("TodoCategory");
type TodoCategoryId = S.Schema.To<typeof TodoCategoryId>;

const NonEmptyString50 = Evolu.String.pipe(
const NonEmptyString50 = String.pipe(
S.minLength(1),
S.maxLength(50),
S.brand("NonEmptyString50"),
S.brand("NonEmptyString50")
);
type NonEmptyString50 = S.Schema.To<typeof NonEmptyString50>;

const TodoTable = S.struct({
id: TodoId,
title: Evolu.NonEmptyString1000,
isCompleted: S.nullable(Evolu.SqliteBoolean),
title: NonEmptyString1000,
isCompleted: S.nullable(SqliteBoolean),
categoryId: S.nullable(TodoCategoryId),
});
type TodoTable = S.Schema.To<typeof TodoTable>;
Expand All @@ -47,18 +62,16 @@ const Database = S.struct({
todo: TodoTable,
todoCategory: TodoCategoryTable,
});
type Database = S.Schema.To<typeof Database>;

const evolu = Evolu.create(Database);

// React Hooks
const { useEvolu, useEvoluError, useQuery, useOwner } = evolu;
const evolu = createEvolu(Database);

const createFixtures = (): Promise<void> =>
Promise.all(
evolu.loadQueries([
evolu.createQuery((db) => db.selectFrom("todo").selectAll()),
evolu.createQuery((db) => db.selectFrom("todoCategory").selectAll()),
]),
])
).then(([todos, categories]) => {
if (todos.row || categories.row) return;

Expand All @@ -67,16 +80,16 @@ const createFixtures = (): Promise<void> =>
});

evolu.create("todo", {
title: S.parseSync(Evolu.NonEmptyString1000)("Try React Suspense"),
title: S.parseSync(NonEmptyString1000)("Try React Suspense"),
categoryId: notUrgentCategoryId,
});
});

const isRestoringOwner = (isRestoringOwner?: boolean): boolean => {
if (!Evolu.canUseDom) return false;
if (!canUseDom) return false;
const key = 'evolu:isRestoringOwner"';
if (isRestoringOwner != null)
localStorage.setItem(key, String(isRestoringOwner));
localStorage.setItem(key, isRestoringOwner.toString());
return localStorage.getItem(key) === "true";
};

Expand All @@ -93,7 +106,7 @@ export const Example = memo(function Example() {
});

return (
<>
<EvoluProvider value={evolu}>
<NotificationBar />
<h2 className="mt-6 text-xl font-semibold">
{currentTab === "todos" ? "Todos" : "Categories"}
Expand All @@ -114,7 +127,7 @@ export const Example = memo(function Example() {
</p>
<OwnerActions />
</Suspense>
</>
</EvoluProvider>
);
});

Expand Down Expand Up @@ -142,29 +155,29 @@ const todosWithCategories = evolu.createQuery((db) =>
db
.selectFrom("todo")
.select(["id", "title", "isCompleted", "categoryId"])
.where("isDeleted", "is not", Evolu.cast(true))
.where("isDeleted", "is not", cast(true))
// Filter null value and ensure non-null type. Evolu will provide a helper.
.where("title", "is not", null)
.$narrowType<{ title: Evolu.NonEmptyString1000 }>()
.$narrowType<{ title: NonEmptyString1000 }>()
.orderBy("createdAt")
// https://kysely.dev/docs/recipes/relations
.select((eb) => [
Evolu.jsonArrayFrom(
jsonArrayFrom(
eb
.selectFrom("todoCategory")
.select(["todoCategory.id", "todoCategory.name"])
.where("isDeleted", "is not", Evolu.cast(true))
.orderBy("createdAt"),
.where("isDeleted", "is not", cast(true))
.orderBy("createdAt")
).as("categories"),
]),
])
);

const Todos: FC = () => {
const { create } = useEvolu();
const { rows } = useQuery(todosWithCategories);

const handleAddTodoClick = (): void => {
prompt(Evolu.NonEmptyString1000, "What needs to be done?", (title) => {
prompt(NonEmptyString1000, "What needs to be done?", (title) => {
create("todo", { title });
});
};
Expand All @@ -188,14 +201,14 @@ const TodoItem = memo<{
}>(function TodoItem({
row: { id, title, isCompleted, categoryId, categories },
}) {
const { update } = useEvolu();
const { update } = useEvolu<Database>();

const handleToggleCompletedClick = (): void => {
update("todo", { id, isCompleted: !isCompleted });
};

const handleRenameClick = (): void => {
prompt(Evolu.NonEmptyString1000, "New Name", (title) => {
prompt(NonEmptyString1000, "New Name", (title) => {
update("todo", { id, title });
});
};
Expand Down Expand Up @@ -268,11 +281,11 @@ const todoCategories = evolu.createQuery((db) =>
db
.selectFrom("todoCategory")
.select(["id", "name", "json"])
.where("isDeleted", "is not", Evolu.cast(true))
.where("isDeleted", "is not", cast(true))
// Filter null value and ensure non-null type. Evolu will provide a helper.
.where("name", "is not", null)
.$narrowType<{ name: NonEmptyString50 }>()
.orderBy("createdAt"),
.orderBy("createdAt")
);

const TodoCategories: FC = () => {
Expand Down Expand Up @@ -306,7 +319,7 @@ const TodoCategories: FC = () => {
const TodoCategoryItem = memo<{
row: Pick<TodoCategoryTable, "id" | "name">;
}>(function TodoItem({ row: { id, name } }) {
const { update } = useEvolu();
const { update } = useEvolu<Database>();

const handleRenameClick = (): void => {
prompt(NonEmptyString50, "Category Name", (name) => {
Expand Down Expand Up @@ -335,8 +348,8 @@ const OwnerActions: FC = () => {
const [showMnemonic, setShowMnemonic] = useState(false);

const handleRestoreOwnerClick = (): void => {
prompt(Evolu.NonEmptyString1000, "Your Mnemonic", (mnemonic) => {
Evolu.parseMnemonic(mnemonic)
prompt(NonEmptyString1000, "Your Mnemonic", (mnemonic) => {
parseMnemonic(mnemonic)
.pipe(Effect.runPromiseExit)
.then(
Exit.match({
Expand All @@ -347,7 +360,7 @@ const OwnerActions: FC = () => {
isRestoringOwner(true);
evolu.restoreOwner(mnemonic);
},
}),
})
);
});
};
Expand Down Expand Up @@ -402,7 +415,7 @@ const Button: FC<{
const prompt = <From extends string, To>(
schema: S.Schema<From, To>,
message: string,
onSuccess: (value: To) => void,
onSuccess: (value: To) => void
): void => {
const value = window.prompt(message);
if (value == null) return; // on cancel
Expand Down

1 comment on commit 610938c

@vercel
Copy link

@vercel vercel bot commented on 610938c Dec 4, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

evolu – ./

evolu-git-main-evolu.vercel.app
evolu.vercel.app
www.evolu.dev
evolu-evolu.vercel.app
evolu.dev

Please sign in to comment.