@evolu/react-native 1.0.8 → 2.0.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.
@@ -1,6 +1,6 @@
1
- import { AppState, Bip39, FlushSync, Platform, SyncLock } from "@evolu/common";
1
+ import { AppState, Bip39, FlushSync, PlatformName, SyncLock } from "@evolu/common";
2
2
  import { Layer } from "effect";
3
- export declare const PlatformLive: Layer.Layer<never, never, Platform>;
3
+ export declare const PlatformNameLive: Layer.Layer<never, never, PlatformName>;
4
4
  export declare const FlushSyncLive: Layer.Layer<never, never, FlushSync>;
5
5
  export declare const SyncLockLive: Layer.Layer<never, never, SyncLock>;
6
6
  export declare const AppStateLive: Layer.Layer<never, never, AppState>;
@@ -1 +1 @@
1
- {"version":3,"file":"PlatformLive.d.ts","sourceRoot":"","sources":["../src/PlatformLive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EAGT,QAAQ,EACR,QAAQ,EACT,MAAM,eAAe,CAAC;AAQvB,OAAO,EAAoB,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIjD,eAAO,MAAM,YAAY,qCAEvB,CAAC;AAEH,eAAO,MAAM,aAAa,sCAA+C,CAAC;AAE1E,eAAO,MAAM,YAAY,qCAiBxB,CAAC;AAEF,eAAO,MAAM,YAAY,qCAgCxB,CAAC;AAEF,eAAO,MAAM,SAAS,kCAYrB,CAAC"}
1
+ {"version":3,"file":"PlatformLive.d.ts","sourceRoot":"","sources":["../src/PlatformLive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,KAAK,EACL,SAAS,EAGT,YAAY,EACZ,QAAQ,EACT,MAAM,eAAe,CAAC;AAQvB,OAAO,EAAoB,KAAK,EAAE,MAAM,QAAQ,CAAC;AAIjD,eAAO,MAAM,gBAAgB,yCAA8C,CAAC;AAE5E,eAAO,MAAM,aAAa,sCAA+C,CAAC;AAE1E,eAAO,MAAM,YAAY,qCAexB,CAAC;AAEF,eAAO,MAAM,YAAY,qCA8BxB,CAAC;AAEF,eAAO,MAAM,SAAS,kCAYrB,CAAC"}
@@ -1,53 +1,50 @@
1
- import { AppState, Bip39, FlushSync, Platform, SyncLock, } from "@evolu/common";
1
+ import { AppState, Bip39, FlushSync, PlatformName, SyncLock, } from "@evolu/common";
2
2
  import NetInfo from "@react-native-community/netinfo";
3
3
  import { generateMnemonic, mnemonicToSeed, validateMnemonic, } from "@scure/bip39";
4
4
  import { wordlist } from "@scure/bip39/wordlists/english";
5
5
  import { Effect, Function, Layer } from "effect";
6
6
  import { reloadAsync } from "expo-updates";
7
7
  import { DevSettings, AppState as ReactNativeAppState } from "react-native";
8
- export const PlatformLive = Layer.succeed(Platform, {
9
- name: "react-native",
10
- });
8
+ export const PlatformNameLive = Layer.succeed(PlatformName, "react-native");
11
9
  export const FlushSyncLive = Layer.succeed(FlushSync, Function.constVoid);
12
10
  export const SyncLockLive = Layer.effect(SyncLock, Effect.sync(() => {
13
- let hasLock = false;
14
- const acquire = Effect.sync(() => {
15
- if (hasLock)
16
- return false;
17
- hasLock = true;
18
- return true;
11
+ let hasSyncLock = false;
12
+ return SyncLock.of({
13
+ acquire: Effect.sync(() => {
14
+ if (hasSyncLock)
15
+ return false;
16
+ hasSyncLock = true;
17
+ return true;
18
+ }),
19
+ release: Effect.sync(() => {
20
+ hasSyncLock = false;
21
+ }),
19
22
  });
20
- const release = Effect.sync(() => {
21
- hasLock = false;
22
- });
23
- return { acquire, release };
24
23
  }));
25
- export const AppStateLive = Layer.effect(AppState, Effect.sync(() => {
26
- const onFocus = (callback) => {
27
- let state = ReactNativeAppState.currentState;
28
- ReactNativeAppState.addEventListener("change", (nextState) => {
29
- if (state.match(/inactive|background/) && nextState === "active")
30
- callback();
31
- state = nextState;
24
+ export const AppStateLive = Layer.succeed(AppState, AppState.of({
25
+ init: ({ onFocus, onReconnect }) => {
26
+ let appStateStatus = ReactNativeAppState.currentState;
27
+ ReactNativeAppState.addEventListener("change", (current) => {
28
+ if (appStateStatus.match(/inactive|background/) && current === "active")
29
+ onFocus();
30
+ appStateStatus = current;
32
31
  });
33
- };
34
- const onReconnect = (callback) => {
35
- let state = null;
36
- NetInfo.addEventListener((nextState) => {
37
- if (state?.isInternetReachable === false &&
38
- nextState.isConnected &&
39
- nextState.isInternetReachable)
40
- callback();
41
- state = nextState;
32
+ let netInfoState = null;
33
+ NetInfo.addEventListener((current) => {
34
+ if (netInfoState?.isInternetReachable === false &&
35
+ current.isConnected &&
36
+ current.isInternetReachable)
37
+ onReconnect();
38
+ netInfoState = current;
42
39
  });
43
- };
44
- const reset = Effect.sync(() => {
40
+ onReconnect();
41
+ },
42
+ reset: Effect.sync(() => {
45
43
  if (process.env.NODE_ENV === "development")
46
44
  DevSettings.reload();
47
45
  else
48
- void reloadAsync();
49
- });
50
- return AppState.of({ onFocus, onReconnect, reset });
46
+ reloadAsync();
47
+ }),
51
48
  }));
52
49
  export const Bip39Live = Layer.succeed(Bip39, Bip39.of({
53
50
  make: Effect.sync(() => generateMnemonic(wordlist, 128)),
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteLive.d.ts","sourceRoot":"","sources":["../src/SqliteLive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA0C,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AA2BvC,eAAO,MAAM,UAAU,mCAAkC,CAAC"}
1
+ {"version":3,"file":"SqliteLive.d.ts","sourceRoot":"","sources":["../src/SqliteLive.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EAIP,MAAM,eAAe,CAAC;AACvB,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AA2BvC,eAAO,MAAM,UAAU,mCAAkC,CAAC"}
@@ -1,12 +1,12 @@
1
- import { Sqlite, parseJsonResults, valuesToSqliteValues } from "@evolu/common";
1
+ import { Sqlite, ensureSqliteQuery, maybeParseJson, valuesToSqliteValues, } from "@evolu/common";
2
2
  import { Effect, Layer } from "effect";
3
3
  import * as SQLite from "expo-sqlite";
4
4
  const db = SQLite.openDatabase("evolu1.db");
5
5
  const exec = (arg) => Effect.gen(function* (_) {
6
- const isSqlString = typeof arg === "string";
6
+ const sqliteQuery = ensureSqliteQuery(arg);
7
7
  const query = {
8
- sql: isSqlString ? arg : arg.sql,
9
- args: isSqlString ? [] : valuesToSqliteValues(arg.parameters),
8
+ sql: sqliteQuery.sql,
9
+ args: valuesToSqliteValues(sqliteQuery.parameters),
10
10
  };
11
11
  const { rows, rowsAffected } = yield* _(Effect.promise(() => db
12
12
  .execAsync([query], false)
@@ -16,7 +16,7 @@ const exec = (arg) => Effect.gen(function* (_) {
16
16
  throw result.error;
17
17
  return result;
18
18
  })));
19
- parseJsonResults(rows);
19
+ maybeParseJson(rows);
20
20
  return { rows, changes: rowsAffected };
21
21
  });
22
22
  export const SqliteLive = Layer.succeed(Sqlite, { exec });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,35 @@
1
- export { Id, NonEmptyString1000, Owner, PositiveInt, SqliteBoolean, SqliteDate, String, String1000, canUseDom, cast, id, jsonArrayFrom, jsonObjectFrom, } from "@evolu/common";
2
- export type { EvoluError, Mnemonic, OwnerId, SyncState } from "@evolu/common";
3
- export declare const create: <From, To extends import("@evolu/common").Schema>(schema: import("@effect/schema/Schema").Schema<From, To>, config?: Partial<import("@evolu/common").Config> | undefined) => import("@evolu/common-react").ReactHooks<To>;
1
+ import { Config, InvalidMnemonicError, Mnemonic, Schema } from "@evolu/common";
2
+ import { Effect } from "effect";
3
+ export { Id, NonEmptyString1000, PositiveInt, SqliteBoolean, SqliteDate, String, String1000, canUseDom, cast, id, } from "@evolu/common";
4
+ export type { EvoluError, InvalidMnemonicError, Mnemonic, Owner, OwnerId, SyncState, Timestamp, TimestampError, UnexpectedError, } from "@evolu/common";
5
+ export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
6
+ /**
7
+ * Create Evolu for React Native.
8
+ *
9
+ * ### Example
10
+ *
11
+ * ```ts
12
+ * import * as S from "@effect/schema/Schema";
13
+ * import * as Evolu from "@evolu/react-native";
14
+ *
15
+ * const TodoId = Evolu.id("Todo");
16
+ * type TodoId = S.Schema.To<typeof TodoId>;
17
+ *
18
+ * const TodoTable = S.struct({
19
+ * id: TodoId,
20
+ * title: Evolu.NonEmptyString1000,
21
+ * });
22
+ * type TodoTable = S.Schema.To<typeof TodoTable>;
23
+ *
24
+ * const Database = S.struct({
25
+ * todo: TodoTable,
26
+ * });
27
+ *
28
+ * const { useEvolu, useEvoluError, useQuery, useOwner } =
29
+ * Evolu.create(Database);
30
+ * ```
31
+ */
32
+ export declare const create: <From, To extends Schema>(schema: import("@effect/schema/Schema").Schema<From, To>, config?: Partial<Config> | undefined) => import("@evolu/common-react").EvoluReact<To>;
33
+ /** Parse a string to {@link Mnemonic}. */
34
+ export declare const parseMnemonic: (mnemonic: string) => Effect.Effect<never, InvalidMnemonicError, Mnemonic>;
4
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,EAAE,EACF,kBAAkB,EAClB,KAAK,EACL,WAAW,EACX,aAAa,EACb,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,EACT,IAAI,EACJ,EAAE,EACF,aAAa,EACb,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9E,eAAO,MAAM,MAAM,2NAkBlB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EAKN,oBAAoB,EACpB,QAAQ,EAER,MAAM,EAGP,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,MAAM,EAAS,MAAM,QAAQ,CAAC;AAYvC,OAAO,EACL,EAAE,EACF,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,EACT,IAAI,EACJ,EAAE,GACH,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,UAAU,EACV,oBAAoB,EACpB,QAAQ,EACR,KAAK,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAatE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,MAAM,2KAGlB,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,aAAa,EAAE,CAC1B,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,oBAAoB,EAAE,QAAQ,CAGjD,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,41 @@
1
- import { DbWorkerLive, FetchLive, NanoIdLive, SecretBoxLive, SyncWorkerLive, } from "@evolu/common";
2
- import { makeReactHooksForPlatform } from "@evolu/common-react";
3
- import { Layer } from "effect";
4
- import { AppStateLive, Bip39Live, FlushSyncLive, PlatformLive, SyncLockLive, } from "./PlatformLive.js";
1
+ import { Bip39, DbWorkerLive, EvoluCommonLive, FetchLive, NanoIdLive, SecretBoxLive, SyncWorkerLive, } from "@evolu/common";
2
+ import { EvoluReactLive, makeCreateEvoluReact } from "@evolu/common-react";
3
+ import { Effect, Layer } from "effect";
4
+ import { AppStateLive, Bip39Live, FlushSyncLive, SyncLockLive, } from "./PlatformLive.js";
5
5
  import { SqliteLive } from "./SqliteLive.js";
6
- // Public API. It must be copy-pasted to all Evolu UI libs because re-exporting
7
- // from @evolu/common/Public is not working for some reason.
8
- export { Id, NonEmptyString1000, Owner, PositiveInt, SqliteBoolean, SqliteDate, String, String1000, canUseDom, cast, id, jsonArrayFrom, jsonObjectFrom, } from "@evolu/common";
9
- export const create = makeReactHooksForPlatform(Layer.use(DbWorkerLive, Layer.mergeAll(SqliteLive, Bip39Live, NanoIdLive, Layer.use(SyncWorkerLive, Layer.mergeAll(SyncLockLive, FetchLive, SecretBoxLive)))), Layer.use(AppStateLive, PlatformLive), PlatformLive, Bip39Live, NanoIdLive, FlushSyncLive);
6
+ // export * from "@evolu/common/public" isn't working in RN for some reason,
7
+ // so we have to export manually.
8
+ // TODO: Recheck after RN 0.73 release.
9
+ export { Id, NonEmptyString1000, PositiveInt, SqliteBoolean, SqliteDate, String, String1000, canUseDom, cast, id, } from "@evolu/common";
10
+ export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
11
+ /** Evolu for native platform. */
12
+ const EvoluNativeLive = EvoluCommonLive.pipe(Layer.use(Layer.mergeAll(FlushSyncLive, AppStateLive, DbWorkerLive)), Layer.use(Layer.mergeAll(Bip39Live, NanoIdLive, SqliteLive, SyncWorkerLive)), Layer.use(Layer.mergeAll(SecretBoxLive, SyncLockLive, FetchLive)));
13
+ /**
14
+ * Create Evolu for React Native.
15
+ *
16
+ * ### Example
17
+ *
18
+ * ```ts
19
+ * import * as S from "@effect/schema/Schema";
20
+ * import * as Evolu from "@evolu/react-native";
21
+ *
22
+ * const TodoId = Evolu.id("Todo");
23
+ * type TodoId = S.Schema.To<typeof TodoId>;
24
+ *
25
+ * const TodoTable = S.struct({
26
+ * id: TodoId,
27
+ * title: Evolu.NonEmptyString1000,
28
+ * });
29
+ * type TodoTable = S.Schema.To<typeof TodoTable>;
30
+ *
31
+ * const Database = S.struct({
32
+ * todo: TodoTable,
33
+ * });
34
+ *
35
+ * const { useEvolu, useEvoluError, useQuery, useOwner } =
36
+ * Evolu.create(Database);
37
+ * ```
38
+ */
39
+ export const create = EvoluReactLive.pipe(Layer.use(EvoluNativeLive), makeCreateEvoluReact);
40
+ /** Parse a string to {@link Mnemonic}. */
41
+ export const parseMnemonic = Bip39.pipe(Effect.provide(Bip39Live), Effect.runSync).parse;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evolu/react-native",
3
- "version": "1.0.8",
3
+ "version": "2.0.0",
4
4
  "description": "Evolu for React Native",
5
5
  "keywords": [
6
6
  "evolu",
@@ -31,24 +31,24 @@
31
31
  "README.md"
32
32
  ],
33
33
  "dependencies": {
34
- "expo-updates": "^0.18.16"
34
+ "expo-updates": "^0.18.17"
35
35
  },
36
36
  "devDependencies": {
37
- "eslint": "^8.52.0",
38
- "expo": "^49.0.16",
39
- "expo-sqlite": "~11.6.0",
37
+ "eslint": "^8.54.0",
38
+ "expo": "^49.0.21",
39
+ "expo-sqlite": "~11.3.3",
40
40
  "react-native": "^0.72.6",
41
- "typescript": "^5.2.2",
41
+ "typescript": "^5.3.2",
42
42
  "vitest": "^0.34.6",
43
- "@evolu/common": "1.0.13",
44
- "@evolu/common-react": "1.0.7",
43
+ "@evolu/common": "2.0.0",
44
+ "@evolu/common-react": "2.0.0",
45
45
  "@evolu/tsconfig": "0.0.2",
46
- "eslint-config-evolu": "0.0.2"
46
+ "eslint-config-evolu": "1.0.0"
47
47
  },
48
48
  "peerDependencies": {
49
- "@evolu/common-react": "^1.0.7",
50
- "expo": "^49.0.11",
51
- "expo-sqlite": "~11.6.0",
49
+ "@evolu/common-react": "^2.0.0",
50
+ "expo": "^49.0.20",
51
+ "expo-sqlite": "~11.3.3",
52
52
  "react-native": "^0.72.4"
53
53
  },
54
54
  "publishConfig": {
@@ -57,12 +57,12 @@
57
57
  "engines": {
58
58
  "node": ">=18.16"
59
59
  },
60
- "sideEffects": false,
60
+ "sideEffects": [],
61
61
  "scripts": {
62
62
  "dev": "tsc --watch",
63
63
  "build": "rm -rf dist && tsc",
64
- "lint": "TIMING=1 eslint src --ext .ts,.tsx",
65
- "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
64
+ "lint": "eslint src --ext .ts,.tsx",
65
+ "clean": "rm -rf .turbo node_modules dist",
66
66
  "format": "prettier --write \"src/*.{ts,tsx,md}\""
67
67
  }
68
68
  }
@@ -4,7 +4,7 @@ import {
4
4
  FlushSync,
5
5
  InvalidMnemonicError,
6
6
  Mnemonic,
7
- Platform,
7
+ PlatformName,
8
8
  SyncLock,
9
9
  } from "@evolu/common";
10
10
  import NetInfo, { NetInfoState } from "@react-native-community/netinfo";
@@ -18,62 +18,56 @@ import { Effect, Function, Layer } from "effect";
18
18
  import { reloadAsync } from "expo-updates";
19
19
  import { DevSettings, AppState as ReactNativeAppState } from "react-native";
20
20
 
21
- export const PlatformLive = Layer.succeed(Platform, {
22
- name: "react-native",
23
- });
21
+ export const PlatformNameLive = Layer.succeed(PlatformName, "react-native");
24
22
 
25
23
  export const FlushSyncLive = Layer.succeed(FlushSync, Function.constVoid);
26
24
 
27
25
  export const SyncLockLive = Layer.effect(
28
26
  SyncLock,
29
27
  Effect.sync(() => {
30
- let hasLock = false;
31
-
32
- const acquire: SyncLock["acquire"] = Effect.sync(() => {
33
- if (hasLock) return false;
34
- hasLock = true;
35
- return true;
36
- });
37
-
38
- const release: SyncLock["release"] = Effect.sync(() => {
39
- hasLock = false;
28
+ let hasSyncLock = false;
29
+ return SyncLock.of({
30
+ acquire: Effect.sync(() => {
31
+ if (hasSyncLock) return false;
32
+ hasSyncLock = true;
33
+ return true;
34
+ }),
35
+ release: Effect.sync(() => {
36
+ hasSyncLock = false;
37
+ }),
40
38
  });
41
-
42
- return { acquire, release };
43
39
  }),
44
40
  );
45
41
 
46
- export const AppStateLive = Layer.effect(
42
+ export const AppStateLive = Layer.succeed(
47
43
  AppState,
48
- Effect.sync(() => {
49
- const onFocus: AppState["onFocus"] = (callback) => {
50
- let state = ReactNativeAppState.currentState;
51
- ReactNativeAppState.addEventListener("change", (nextState): void => {
52
- if (state.match(/inactive|background/) && nextState === "active")
53
- callback();
54
- state = nextState;
44
+ AppState.of({
45
+ init: ({ onFocus, onReconnect }) => {
46
+ let appStateStatus = ReactNativeAppState.currentState;
47
+ ReactNativeAppState.addEventListener("change", (current): void => {
48
+ if (appStateStatus.match(/inactive|background/) && current === "active")
49
+ onFocus();
50
+ appStateStatus = current;
55
51
  });
56
- };
57
52
 
58
- const onReconnect: AppState["onReconnect"] = (callback) => {
59
- let state: NetInfoState | null = null;
60
- NetInfo.addEventListener((nextState) => {
53
+ let netInfoState: NetInfoState | null = null;
54
+ NetInfo.addEventListener((current) => {
61
55
  if (
62
- state?.isInternetReachable === false &&
63
- nextState.isConnected &&
64
- nextState.isInternetReachable
56
+ netInfoState?.isInternetReachable === false &&
57
+ current.isConnected &&
58
+ current.isInternetReachable
65
59
  )
66
- callback();
67
- state = nextState;
60
+ onReconnect();
61
+ netInfoState = current;
68
62
  });
69
- };
70
63
 
71
- const reset: AppState["reset"] = Effect.sync(() => {
72
- if (process.env.NODE_ENV === "development") DevSettings.reload();
73
- else void reloadAsync();
74
- });
64
+ onReconnect();
65
+ },
75
66
 
76
- return AppState.of({ onFocus, onReconnect, reset });
67
+ reset: Effect.sync(() => {
68
+ if (process.env.NODE_ENV === "development") DevSettings.reload();
69
+ else reloadAsync();
70
+ }),
77
71
  }),
78
72
  );
79
73
 
package/src/SqliteLive.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { Sqlite, parseJsonResults, valuesToSqliteValues } from "@evolu/common";
1
+ import {
2
+ Sqlite,
3
+ ensureSqliteQuery,
4
+ maybeParseJson,
5
+ valuesToSqliteValues,
6
+ } from "@evolu/common";
2
7
  import { Effect, Layer } from "effect";
3
8
  import * as SQLite from "expo-sqlite";
4
9
 
@@ -6,10 +11,10 @@ const db = SQLite.openDatabase("evolu1.db");
6
11
 
7
12
  const exec: Sqlite["exec"] = (arg) =>
8
13
  Effect.gen(function* (_) {
9
- const isSqlString = typeof arg === "string";
10
- const query: SQLite.Query = {
11
- sql: isSqlString ? arg : arg.sql,
12
- args: isSqlString ? [] : valuesToSqliteValues(arg.parameters),
14
+ const sqliteQuery = ensureSqliteQuery(arg);
15
+ const query = {
16
+ sql: sqliteQuery.sql,
17
+ args: valuesToSqliteValues(sqliteQuery.parameters),
13
18
  };
14
19
  const { rows, rowsAffected } = yield* _(
15
20
  Effect.promise(() =>
@@ -22,7 +27,7 @@ const exec: Sqlite["exec"] = (arg) =>
22
27
  }),
23
28
  ),
24
29
  );
25
- parseJsonResults(rows);
30
+ maybeParseJson(rows);
26
31
  return { rows, changes: rowsAffected };
27
32
  });
28
33
 
package/src/index.ts CHANGED
@@ -1,27 +1,33 @@
1
1
  import {
2
+ Bip39,
3
+ Config,
2
4
  DbWorkerLive,
5
+ Evolu,
6
+ EvoluCommonLive,
3
7
  FetchLive,
8
+ InvalidMnemonicError,
9
+ Mnemonic,
4
10
  NanoIdLive,
11
+ Schema,
5
12
  SecretBoxLive,
6
13
  SyncWorkerLive,
7
14
  } from "@evolu/common";
8
- import { makeReactHooksForPlatform } from "@evolu/common-react";
9
- import { Layer } from "effect";
15
+ import { EvoluReactLive, makeCreateEvoluReact } from "@evolu/common-react";
16
+ import { Effect, Layer } from "effect";
10
17
  import {
11
18
  AppStateLive,
12
19
  Bip39Live,
13
20
  FlushSyncLive,
14
- PlatformLive,
15
21
  SyncLockLive,
16
22
  } from "./PlatformLive.js";
17
23
  import { SqliteLive } from "./SqliteLive.js";
18
24
 
19
- // Public API. It must be copy-pasted to all Evolu UI libs because re-exporting
20
- // from @evolu/common/Public is not working for some reason.
25
+ // export * from "@evolu/common/public" isn't working in RN for some reason,
26
+ // so we have to export manually.
27
+ // TODO: Recheck after RN 0.73 release.
21
28
  export {
22
29
  Id,
23
30
  NonEmptyString1000,
24
- Owner,
25
31
  PositiveInt,
26
32
  SqliteBoolean,
27
33
  SqliteDate,
@@ -30,28 +36,66 @@ export {
30
36
  canUseDom,
31
37
  cast,
32
38
  id,
33
- jsonArrayFrom,
34
- jsonObjectFrom,
35
39
  } from "@evolu/common";
36
- // Re-exporting a type when 'isolatedModules' is enabled requires using 'export type'.
37
- export type { EvoluError, Mnemonic, OwnerId, SyncState } from "@evolu/common";
40
+ export type {
41
+ EvoluError,
42
+ InvalidMnemonicError,
43
+ Mnemonic,
44
+ Owner,
45
+ OwnerId,
46
+ SyncState,
47
+ Timestamp,
48
+ TimestampError,
49
+ UnexpectedError,
50
+ } from "@evolu/common";
51
+ export { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite";
38
52
 
39
- export const create = makeReactHooksForPlatform(
40
- Layer.use(
41
- DbWorkerLive,
42
- Layer.mergeAll(
43
- SqliteLive,
44
- Bip39Live,
45
- NanoIdLive,
46
- Layer.use(
47
- SyncWorkerLive,
48
- Layer.mergeAll(SyncLockLive, FetchLive, SecretBoxLive),
49
- ),
50
- ),
51
- ),
52
- Layer.use(AppStateLive, PlatformLive),
53
- PlatformLive,
54
- Bip39Live,
55
- NanoIdLive,
56
- FlushSyncLive,
53
+ /** Evolu for native platform. */
54
+ const EvoluNativeLive: Layer.Layer<
55
+ Config,
56
+ never,
57
+ Evolu<Schema>
58
+ > = EvoluCommonLive.pipe(
59
+ Layer.use(Layer.mergeAll(FlushSyncLive, AppStateLive, DbWorkerLive)),
60
+ Layer.use(Layer.mergeAll(Bip39Live, NanoIdLive, SqliteLive, SyncWorkerLive)),
61
+ Layer.use(Layer.mergeAll(SecretBoxLive, SyncLockLive, FetchLive)),
62
+ );
63
+
64
+ /**
65
+ * Create Evolu for React Native.
66
+ *
67
+ * ### Example
68
+ *
69
+ * ```ts
70
+ * import * as S from "@effect/schema/Schema";
71
+ * import * as Evolu from "@evolu/react-native";
72
+ *
73
+ * const TodoId = Evolu.id("Todo");
74
+ * type TodoId = S.Schema.To<typeof TodoId>;
75
+ *
76
+ * const TodoTable = S.struct({
77
+ * id: TodoId,
78
+ * title: Evolu.NonEmptyString1000,
79
+ * });
80
+ * type TodoTable = S.Schema.To<typeof TodoTable>;
81
+ *
82
+ * const Database = S.struct({
83
+ * todo: TodoTable,
84
+ * });
85
+ *
86
+ * const { useEvolu, useEvoluError, useQuery, useOwner } =
87
+ * Evolu.create(Database);
88
+ * ```
89
+ */
90
+ export const create = EvoluReactLive.pipe(
91
+ Layer.use(EvoluNativeLive),
92
+ makeCreateEvoluReact,
57
93
  );
94
+
95
+ /** Parse a string to {@link Mnemonic}. */
96
+ export const parseMnemonic: (
97
+ mnemonic: string,
98
+ ) => Effect.Effect<never, InvalidMnemonicError, Mnemonic> = Bip39.pipe(
99
+ Effect.provide(Bip39Live),
100
+ Effect.runSync,
101
+ ).parse;