Skip to content

Commit

Permalink
Merge pull request #199 from evoluhq/RN
Browse files Browse the repository at this point in the history
React Fast Refresh
  • Loading branch information
steida authored Aug 22, 2023
2 parents 43b7e46 + a47544b commit 0791c49
Show file tree
Hide file tree
Showing 25 changed files with 859 additions and 823 deletions.
7 changes: 7 additions & 0 deletions .changeset/green-carrots-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"evolu": minor
---

React Fast Refresh support

It also ensures only one instance of Evolu is used.
6 changes: 2 additions & 4 deletions apps/native/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { pipe } from "@effect/data/Function";
import SelectDropdown from "react-native-select-dropdown";
import * as Schema from "@effect/schema/Schema";
import * as Evolu from "evolu";
import { StatusBar } from "expo-status-bar";
Expand All @@ -12,15 +10,15 @@ import {
useState,
} from "react";
import { Button, StyleSheet, Text, View } from "react-native";
import SelectDropdown from "react-native-select-dropdown";

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

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

const NonEmptyString50 = pipe(
Schema.string,
const NonEmptyString50 = Schema.string.pipe(
Schema.minLength(1),
Schema.maxLength(50),
Schema.brand("NonEmptyString50"),
Expand Down
4 changes: 2 additions & 2 deletions apps/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
"clean": "rm -rf .turbo && rm -rf .expo && rm -rf node_modules"
},
"dependencies": {
"@effect/schema": "^0.33.1",
"@effect/schema": "^0.33.2",
"@types/react": "^18.2.20",
"effect": "2.0.0-next.27",
"evolu": "workspace:*",
"expo": "^49.0.7",
"expo": "^49.0.8",
"expo-sqlite": "~11.3.2",
"expo-status-bar": "^1.6.0",
"react": "18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"devDependencies": {
"@evolu/tsconfig": "workspace:*",
"@types/node": "^20.5.1",
"@types/node": "^20.5.2",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
},
Expand Down
4 changes: 2 additions & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"clean": "rm -rf .turbo && rm -rf .next && rm -rf node_modules"
},
"dependencies": {
"@effect/schema": "~0.33.1",
"@effect/schema": "~0.33.2",
"clsx": "^2.0.0",
"effect": "2.0.0-next.27",
"evolu": "workspace:*",
Expand All @@ -22,7 +22,7 @@
},
"devDependencies": {
"@evolu/tsconfig": "workspace:*",
"@types/node": "^20.5.1",
"@types/node": "^20.5.2",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"autoprefixer": "^10.4.15",
Expand Down
6 changes: 3 additions & 3 deletions packages/eslint-config-evolu/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
"clean": "rm -rf node_modules"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.4.0",
"@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.4.1",
"eslint-config-next": "^13.4.19",
"eslint-config-prettier": "^9.0.0",
"eslint-config-turbo": "^1.10.12",
"eslint-plugin-jsdoc": "^46.4.6",
"eslint-plugin-jsdoc": "^46.5.0",
"eslint-plugin-node": "^11.1.0",
"next": "^13.4.19",
"react": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/evolu-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@types/body-parser": "^1.19.2",
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
"@types/node": "^20.5.1",
"@types/node": "^20.5.2",
"eslint": "^8.47.0",
"eslint-config-evolu": "workspace:*",
"typescript": "^5.1.6",
Expand Down
4 changes: 2 additions & 2 deletions packages/evolu/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"nanoid": "^4.0.2"
},
"devDependencies": {
"@effect/schema": "^0.33.1",
"@effect/schema": "^0.33.2",
"@evolu/tsconfig": "workspace:*",
"@protobuf-ts/plugin": "^2.9.1",
"@protobuf-ts/protoc": "^2.9.1",
Expand All @@ -78,7 +78,7 @@
"effect": "2.0.0-next.27",
"eslint": "^8.47.0",
"eslint-config-evolu": "workspace:*",
"expo": "^49.0.7",
"expo": "^49.0.8",
"expo-sqlite": "^11.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
14 changes: 9 additions & 5 deletions packages/evolu/src/Db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { makeInitialTimestamp, timestampToString } from "./Timestamp.js";

export type Schema = ReadonlyRecord.ReadonlyRecord<{ id: Id } & Row>;

export type CreateQuery<S extends Schema = Schema> = (
export type CreateQuery<S extends Schema> = (
queryCallback: QueryCallback<S, Row>,
) => Query;

Expand Down Expand Up @@ -64,6 +64,8 @@ export interface Table {
readonly columns: ReadonlyArray<string>;
}

export type Tables = ReadonlyArray<Table>;

const commonColumns = ["createdAt", "updatedAt", "isDeleted"];

const kysely: Kysely.Kysely<SchemaForQuery<Schema>> = new Kysely.Kysely({
Expand All @@ -77,8 +79,10 @@ const kysely: Kysely.Kysely<SchemaForQuery<Schema>> = new Kysely.Kysely({
},
});

export const createQuery: CreateQuery = (queryCallback) =>
queryObjectToQuery(queryCallback(kysely).compile() as QueryObject);
export const makeCreateQuery =
<T extends Schema>(): CreateQuery<T> =>
(queryCallback) =>
queryObjectToQuery(queryCallback(kysely as never).compile() as QueryObject);

// https://github.com/Effect-TS/schema/releases/tag/v0.18.0
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -99,7 +103,7 @@ const getPropertySignatures = <I extends { [K in keyof A]: any }, A>(
export const schemaToTables = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
schema: S.Schema<any, any>,
): ReadonlyArray<Table> =>
): Tables =>
pipe(
getPropertySignatures(schema),
ReadonlyRecord.toEntries,
Expand Down Expand Up @@ -288,7 +292,7 @@ const createTable = ({
);

export const ensureSchema = (
tables: ReadonlyArray<Table>,
tables: Tables,
): Effect.Effect<Sqlite, never, void> =>
Effect.flatMap(getTables, (existingTables) =>
Effect.forEach(
Expand Down
30 changes: 24 additions & 6 deletions packages/evolu/src/DbWorker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Brand,
Cause,
Context,
Effect,
Expand All @@ -17,6 +18,7 @@ import { Bip39, Mnemonic, NanoId, Slip21 } from "./Crypto.js";
import {
Owner,
Table,
Tables,
ensureSchema,
lazyInit,
someDefectToNoSuchTableOrColumnError,
Expand All @@ -33,8 +35,6 @@ import {
unsafeMerkleTreeFromString,
} from "./MerkleTree.js";
import { CastableForMutate, Id, SqliteDate, cast } from "./Model.js";
import { OnCompleteId } from "./OnCompletes.js";
import { RowsCacheRef, RowsCacheRefLive } from "./RowsCache.js";
import {
insertIntoMessagesIfNew,
insertValueIntoTableRowColumn,
Expand All @@ -44,7 +44,7 @@ import {
selectOwnerTimestampAndMerkleTree,
updateOwnerTimestampAndMerkleTree,
} from "./Sql.js";
import { Query, Sqlite, Value, queryObjectFromQuery } from "./Sqlite.js";
import { Query, Row, Sqlite, Value, queryObjectFromQuery } from "./Sqlite.js";
import {
Message,
NewMessage,
Expand Down Expand Up @@ -81,12 +81,13 @@ export type DbWorkerInput =
| DbWorkerInputMutate
| DbWorkerInputSync
| DbWorkerInputReset
| DbWorkerInputEnsureSchema
| SyncWorkerOutputSyncResponse;

interface DbWorkerInputInit {
readonly _tag: "init";
readonly config: Config;
readonly tables: ReadonlyArray<Table>;
readonly tables: Tables;
}

interface DbWorkerInputQuery {
Expand All @@ -110,6 +111,11 @@ interface DbWorkerInputReset {
readonly mnemonic?: Mnemonic;
}

interface DbWorkerInputEnsureSchema {
readonly _tag: "ensureSchema";
readonly tables: Tables;
}

type DbWorkerOnMessage = DbWorker["onMessage"];

const DbWorkerOnMessage = Context.Tag<DbWorkerOnMessage>(
Expand Down Expand Up @@ -140,6 +146,10 @@ export interface DbWorkerOutputOnQuery {
readonly onCompleteIds: ReadonlyArray<OnCompleteId>;
}

export type OnCompleteId = string &
Brand.Brand<"Id"> &
Brand.Brand<"OnComplete">;

interface DbWorkerOutputOnReceive {
readonly _tag: "onReceive";
}
Expand Down Expand Up @@ -177,6 +187,12 @@ const init = (
);
});

export type RowsCacheMap = ReadonlyMap<Query, ReadonlyArray<Row>>;

type RowsCacheRef = Ref.Ref<RowsCacheMap>;
const RowsCacheRef = Context.Tag<RowsCacheRef>("evolu/RowsCacheRef");
const RowsCacheRefLive = Layer.effect(RowsCacheRef, Ref.make(new Map()));

const query = ({
queries,
onCompleteIds = ReadonlyArray.empty(),
Expand All @@ -186,14 +202,16 @@ const query = ({
}): Effect.Effect<Sqlite | RowsCacheRef | DbWorkerOnMessage, never, void> =>
Effect.gen(function* (_) {
const sqlite = yield* _(Sqlite);
const rowsCache = yield* _(RowsCacheRef);
const dbWorkerOnMessage = yield* _(DbWorkerOnMessage);

const queriesRows = yield* _(
Effect.forEach(queries, (query) =>
sqlite
.exec(queryObjectFromQuery(query))
.pipe(Effect.map((rows) => [query, rows] as const)),
),
);
const rowsCache = yield* _(RowsCacheRef);
const previous = yield* _(Ref.get(rowsCache));
yield* _(Ref.set(rowsCache, new Map([...previous, ...queriesRows])));
const queriesPatches = queriesRows.map(
Expand All @@ -202,7 +220,6 @@ const query = ({
patches: makePatches(previous.get(query), rows),
}),
);
const dbWorkerOnMessage = yield* _(DbWorkerOnMessage);
dbWorkerOnMessage({ _tag: "onQuery", queriesPatches, onCompleteIds });
});

Expand Down Expand Up @@ -607,6 +624,7 @@ export const DbWorkerLive = Layer.effect(
skipAllBecauseOfReset = true;
return reset(input);
},
ensureSchema: (input) => ensureSchema(input.tables),
SyncWorkerOutputSyncResponse: handleSyncResponse,
}),
Effect.provideSomeLayer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import {
NanoIdLive,
Sha512Live,
} from "./CryptoLive.web.js";
import { DbWorkerLive } from "./DbWorker.js";
import { DbWorker, DbWorkerLive } from "./DbWorker.js";
import { SqliteLive } from "./SqliteLive.web.js";
import { SyncWorker, SyncWorkerOutput } from "./SyncWorker.js";

// It's a separate file because it's imported dynamically and by Web Worker.

const SyncWorkerLive = Layer.effect(
SyncWorker,
Effect.sync(() => {
Expand All @@ -30,11 +32,16 @@ const SyncWorkerLive = Layer.effect(
}),
);

// It's a separate file because it's imported dynamically or by WebWorker.
export const dbWorkerLive = Layer.mergeAll(
SqliteLive,
Bip39Live,
Layer.merge(HmacLive, Sha512Live).pipe(Layer.provide(Slip21Live)),
NanoIdLive,
SyncWorkerLive,
).pipe(Layer.provide(DbWorkerLive));
export const dbWorker = Effect.provideLayer(
DbWorker,
Layer.use(
DbWorkerLive,
Layer.mergeAll(
SqliteLive,
Bip39Live,
Layer.use(Slip21Live, Layer.merge(HmacLive, Sha512Live)),
NanoIdLive,
SyncWorkerLive,
),
),
).pipe(Effect.runSync);
10 changes: 2 additions & 8 deletions packages/evolu/src/DbWorker.worker.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { Effect } from "effect";
import { DbWorker, DbWorkerInput } from "./DbWorker.js";
import { dbWorkerLive } from "./DbWorkerLive.web.js";

const dbWorker = DbWorker.pipe(
Effect.provideLayer(dbWorkerLive),
Effect.runSync,
);
import { DbWorkerInput } from "./DbWorker.js";
import { dbWorker } from "./DbWorker.web.js";

dbWorker.onMessage = (output): void => {
postMessage(output);
Expand Down
Loading

1 comment on commit 0791c49

@vercel
Copy link

@vercel vercel bot commented on 0791c49 Aug 22, 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.dev
evolu-evolu.vercel.app
www.evolu.dev
evolu-git-main-evolu.vercel.app
evolu.vercel.app

Please sign in to comment.