From 094e25a102438945a1c2126df5f80ecc2362c00a Mon Sep 17 00:00:00 2001 From: Daniel Steigerwald Date: Sun, 22 Oct 2023 15:02:35 +0200 Subject: [PATCH] Expose and leverage canUseDOM --- .changeset/kind-garlics-appear.md | 8 ++++++++ packages/evolu-common-web/src/PlatformLive.ts | 5 ++--- packages/evolu-common-web/src/SqliteLive.ts | 13 +++++++------ packages/evolu-common/src/Platform.ts | 10 ++++++++++ packages/evolu-react-native/src/index.ts | 1 + packages/evolu-react/src/index.ts | 1 + 6 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 .changeset/kind-garlics-appear.md diff --git a/.changeset/kind-garlics-appear.md b/.changeset/kind-garlics-appear.md new file mode 100644 index 000000000..db63fb918 --- /dev/null +++ b/.changeset/kind-garlics-appear.md @@ -0,0 +1,8 @@ +--- +"@evolu/react-native": patch +"@evolu/common-web": patch +"@evolu/common": patch +"@evolu/react": patch +--- + +Expose and leverage canUseDOM diff --git a/packages/evolu-common-web/src/PlatformLive.ts b/packages/evolu-common-web/src/PlatformLive.ts index bba50d13b..86ab73119 100644 --- a/packages/evolu-common-web/src/PlatformLive.ts +++ b/packages/evolu-common-web/src/PlatformLive.ts @@ -7,12 +7,11 @@ import { Mnemonic, Platform, SyncLock, + canUseDOM, } from "@evolu/common"; import { Effect, Function, Layer, Predicate, ReadonlyArray } from "effect"; import { flushSync } from "react-dom"; -const hasDoc = typeof document !== "undefined"; - const isChromeWithOpfs = (): boolean => navigator.userAgentData != null && navigator.userAgentData.brands.find( @@ -37,7 +36,7 @@ const isSafariWithOpfs = (): boolean => { return Number(matches[1]) >= 17; }; -const name = hasDoc +const name = canUseDOM ? isChromeWithOpfs() || isFirefoxWithOpfs() || isSafariWithOpfs() ? "web-with-opfs" : "web-without-opfs" diff --git a/packages/evolu-common-web/src/SqliteLive.ts b/packages/evolu-common-web/src/SqliteLive.ts index ea9f36911..7dec75411 100644 --- a/packages/evolu-common-web/src/SqliteLive.ts +++ b/packages/evolu-common-web/src/SqliteLive.ts @@ -1,6 +1,7 @@ import { Sqlite, SqliteRow, + canUseDOM, parseJsonResults, valuesToSqliteValues, } from "@evolu/common"; @@ -8,7 +9,7 @@ import { Effect, Function, Layer } from "effect"; import sqlite3InitModule from "@sqlite.org/sqlite-wasm"; -if (typeof document !== "undefined") +if (canUseDOM) // @ts-expect-error Missing types. self.sqlite3ApiConfig = { debug: Function.constVoid, @@ -17,11 +18,11 @@ if (typeof document !== "undefined") error: Function.constVoid, }; -const sqlitePromise = sqlite3InitModule().then((sqlite3) => { - return typeof document === "undefined" - ? new sqlite3.oo1.OpfsDb("/evolu/evolu1.db", "c") - : new sqlite3.oo1.JsStorageDb("local"); -}); +const sqlitePromise = sqlite3InitModule().then((sqlite3) => + canUseDOM + ? new sqlite3.oo1.JsStorageDb("local") + : new sqlite3.oo1.OpfsDb("/evolu/evolu1.db", "c"), +); const exec: Sqlite["exec"] = (arg) => Effect.gen(function* (_) { diff --git a/packages/evolu-common/src/Platform.ts b/packages/evolu-common/src/Platform.ts index 972410800..f6672c708 100644 --- a/packages/evolu-common/src/Platform.ts +++ b/packages/evolu-common/src/Platform.ts @@ -61,3 +61,13 @@ export interface AppState { } export const AppState = Context.Tag("evolu/AppState"); + +/** + * To detect whether DOM can be used. + * https://github.com/facebook/fbjs/blob/main/packages/fbjs/src/core/ExecutionEnvironment.js + */ +export const canUseDOM = !!( + typeof window !== "undefined" && + window.document && + window.document.createElement +); diff --git a/packages/evolu-react-native/src/index.ts b/packages/evolu-react-native/src/index.ts index 5ed0e3831..21a50bf16 100644 --- a/packages/evolu-react-native/src/index.ts +++ b/packages/evolu-react-native/src/index.ts @@ -27,6 +27,7 @@ export { SqliteDate, String, String1000, + canUseDOM, cast, id, jsonArrayFrom, diff --git a/packages/evolu-react/src/index.ts b/packages/evolu-react/src/index.ts index d6aba60e0..caa2c5d2b 100644 --- a/packages/evolu-react/src/index.ts +++ b/packages/evolu-react/src/index.ts @@ -20,6 +20,7 @@ export { SqliteDate, String, String1000, + canUseDOM, cast, id, jsonArrayFrom,