mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 12:12:54 +01:00
web: migrate to rsbuild
This commit is contained in:
@@ -55,6 +55,8 @@ async function onChange(first) {
|
||||
if (first) {
|
||||
await fs.rm("./build/", { force: true, recursive: true });
|
||||
|
||||
await exec("npm rebuild electron --foreground-scripts --verbose");
|
||||
|
||||
await exec("bun electron-builder install-app-deps");
|
||||
}
|
||||
|
||||
@@ -68,9 +70,9 @@ async function onChange(first) {
|
||||
|
||||
if (first) {
|
||||
await spawnAndWaitUntil(
|
||||
["bun", "run", "start:desktop"],
|
||||
["yarn", "run", "start:desktop"],
|
||||
path.join(__dirname, "..", "..", "web"),
|
||||
(data) => data.includes("Network: use --host to expose")
|
||||
(data) => data.includes("built in")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -80,7 +82,7 @@ async function onChange(first) {
|
||||
}
|
||||
|
||||
execAsync(
|
||||
"yarn",
|
||||
"bun",
|
||||
["electron", path.join("build", "electron.js")],
|
||||
true,
|
||||
cleanup
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,9 @@
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@emotion/react": "11.11.1",
|
||||
"@hazae41/foras": "^2.1.4",
|
||||
"@henrygd/queue": "^1.0.6",
|
||||
"@lingui/core": "5.1.2",
|
||||
"@lingui/react": "5.1.2",
|
||||
"@henrygd/queue": "^1.1.1",
|
||||
"@lingui/core": "5.5.1",
|
||||
"@lingui/react": "5.5.1",
|
||||
"@mdi/js": "7.4.47",
|
||||
"@mdi/react": "1.6.1",
|
||||
"@notesnook-importer/core": "^2.2.2",
|
||||
@@ -46,10 +46,10 @@
|
||||
"@zip.js/zip.js": "^2.7.62",
|
||||
"async-mutex": "0.5.0",
|
||||
"axios": "^1.7.9",
|
||||
"clipboard-polyfill": "4.1.0",
|
||||
"clipboard-polyfill": "4.1.1",
|
||||
"comlink": "^4.3.1",
|
||||
"cronosjs": "^1.7.1",
|
||||
"dayjs": "1.11.13",
|
||||
"dayjs": "1.11.18",
|
||||
"diffblazer": "^1.0.1",
|
||||
"electron-trpc": "0.7.1",
|
||||
"event-source-polyfill": "1.0.31",
|
||||
@@ -58,7 +58,7 @@
|
||||
"hash-wasm": "4.12.0",
|
||||
"hotkeys-js": "^3.8.3",
|
||||
"katex": "0.16.11",
|
||||
"mac-scrollbar": "0.13.6",
|
||||
"mac-scrollbar": "0.13.8",
|
||||
"mutative": "^1.1.0",
|
||||
"pdfjs-dist": "3.6.172",
|
||||
"phone": "^3.1.14",
|
||||
@@ -84,16 +84,17 @@
|
||||
"zustand-mutative": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.22.5",
|
||||
"@rsbuild/plugin-react": "^1.4.1",
|
||||
"@rsbuild/plugin-svgr": "^1.2.2",
|
||||
"@aaroon/workbox-rspack-plugin": "^0.3.2",
|
||||
"@cloudflare/workers-types": "^4.20250224.0",
|
||||
"@playwright/test": "1.48.2",
|
||||
"@swc/plugin-react-remove-properties": "^6.0.2",
|
||||
"@playwright/test": "1.56.0",
|
||||
"@rsbuild/core": "^1.5.17",
|
||||
"@rsdoctor/rspack-plugin": "^1.3.2",
|
||||
"@swc/plugin-react-remove-properties": "^9.1.0",
|
||||
"@trpc/server": "10.45.2",
|
||||
"@types/babel__core": "^7.20.1",
|
||||
"@types/event-source-polyfill": "1.0.5",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/marked": "^6.0.0",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"@types/platform": "^1.3.6",
|
||||
"@types/react": "18.3.5",
|
||||
"@types/react-avatar-editor": "^13.0.3",
|
||||
@@ -101,24 +102,11 @@
|
||||
"@types/react-modal": "3.16.3",
|
||||
"@types/react-scroll-sync": "^0.9.0",
|
||||
"@types/wicg-file-system-access": "^2023.10.5",
|
||||
"@vitejs/plugin-react-swc": "^3.7.2",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"better-sqlite3-multiple-ciphers": "11.5.0",
|
||||
"buffer": "^6.0.3",
|
||||
"chalk": "^4.1.0",
|
||||
"dotenv": "16.4.7",
|
||||
"esbuild": "0.21.5",
|
||||
"file-loader": "^6.2.0",
|
||||
"find-process": "^1.4.4",
|
||||
"happy-dom": "16.0.1",
|
||||
"ip": "^2.0.1",
|
||||
"lorem-ipsum": "^2.0.4",
|
||||
"otplib": "^12.0.1",
|
||||
"rollup-plugin-visualizer": "^5.13.1",
|
||||
"vite": "5.4.11",
|
||||
"vite-plugin-env-compatible": "^2.0.1",
|
||||
"vite-plugin-pwa": "^0.21.1",
|
||||
"vite-plugin-svgr": "^4.3.0",
|
||||
"vitest": "2.1.8",
|
||||
"workbox-core": "^7.3.0",
|
||||
"workbox-expiration": "^7.3.0",
|
||||
@@ -127,14 +115,14 @@
|
||||
"workbox-strategies": "^7.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "PLATFORM=web vite",
|
||||
"start:desktop": "PLATFORM=desktop vite",
|
||||
"start": "PLATFORM=web rsbuild dev",
|
||||
"start:desktop": "PLATFORM=desktop rsbuild dev",
|
||||
"start:test": "serve -s build/ -p 3000",
|
||||
"build": "PLATFORM=web vite build",
|
||||
"build:test": "PLATFORM=web TEST=true vite build",
|
||||
"build:beta": "PLATFORM=web BETA=true vite build",
|
||||
"build:desktop": "PLATFORM=desktop vite build",
|
||||
"analyze": "ANALYZING=true PLATFORM=web vite build",
|
||||
"build": "PLATFORM=web rsbuild build",
|
||||
"build:test": "PLATFORM=web TEST=true rsbuild build",
|
||||
"build:beta": "PLATFORM=web BETA=true rsbuild build",
|
||||
"build:desktop": "PLATFORM=desktop rsbuild build",
|
||||
"analyze": "RSDOCTOR=true rsbuild build",
|
||||
"test": "playwright test -u"
|
||||
},
|
||||
"browserslist": {
|
||||
|
||||
246
apps/web/rsbuild.config.ts
Normal file
246
apps/web/rsbuild.config.ts
Normal file
@@ -0,0 +1,246 @@
|
||||
import { defineConfig, loadEnv, RsbuildPluginAPI } from "@rsbuild/core";
|
||||
import { pluginReact } from "@rsbuild/plugin-react";
|
||||
import { pluginSvgr } from "@rsbuild/plugin-svgr";
|
||||
import { InjectManifest } from "@aaroon/workbox-rspack-plugin";
|
||||
import { execSync } from "child_process";
|
||||
import { version } from "./package.json";
|
||||
import path from "path";
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
const gitHash = (() => {
|
||||
try {
|
||||
return execSync("git rev-parse --short HEAD").toString().trim();
|
||||
} catch (e) {
|
||||
return process.env.GIT_HASH || "gitless";
|
||||
}
|
||||
})();
|
||||
// const appVersion = version.replaceAll(".", "").replace("-beta", "");
|
||||
const isBeta = version.includes("-beta");
|
||||
const isTesting =
|
||||
process.env.TEST === "true" || process.env.NODE_ENV === "development";
|
||||
const isDesktop = process.env.PLATFORM === "desktop";
|
||||
const isThemeBuilder = process.env.THEME_BUILDER === "true";
|
||||
const { publicVars } = loadEnv({ prefixes: ["NN_"] });
|
||||
|
||||
export default defineConfig({
|
||||
html: {
|
||||
template: "./src/index.html"
|
||||
},
|
||||
output: {
|
||||
sourceMap: !isDesktop,
|
||||
cleanDistPath: true,
|
||||
distPath: {
|
||||
root: "./build",
|
||||
assets: "assets",
|
||||
js: "assets",
|
||||
css: "assets",
|
||||
cssAsync: "assets",
|
||||
font: "assets",
|
||||
image: "assets",
|
||||
jsAsync: "assets",
|
||||
svg: "assets",
|
||||
wasm: "assets",
|
||||
media: "assets"
|
||||
}
|
||||
},
|
||||
source: {
|
||||
entry: {
|
||||
index: "./src/index.ts"
|
||||
},
|
||||
define: {
|
||||
...publicVars,
|
||||
APP_TITLE: `"${
|
||||
isThemeBuilder ? "Notesnook Theme Builder" : "Notesnook"
|
||||
}"`,
|
||||
GIT_HASH: `"${gitHash}"`,
|
||||
APP_VERSION: `"${version}"`,
|
||||
PUBLIC_URL: `"${process.env.PUBLIC_URL || ""}"`,
|
||||
IS_DESKTOP_APP: isDesktop,
|
||||
PLATFORM: `"${process.env.PLATFORM}"`,
|
||||
IS_TESTING: process.env.TEST === "true",
|
||||
IS_BETA: isBeta,
|
||||
IS_THEME_BUILDER: isThemeBuilder
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
dedupe: [
|
||||
"react",
|
||||
"react-dom",
|
||||
"@mdi/js",
|
||||
"@mdi/react",
|
||||
"@emotion/react",
|
||||
"katex",
|
||||
"react-modal",
|
||||
"dayjs",
|
||||
"@streetwriters/kysely"
|
||||
]
|
||||
},
|
||||
tools: {
|
||||
rspack: {
|
||||
externalsPresets: isDesktop
|
||||
? { electronRenderer: true, electron: true }
|
||||
: undefined,
|
||||
plugins: [
|
||||
...(isThemeBuilder || isDesktop || process.env.NODE_ENV !== "production"
|
||||
? []
|
||||
: [
|
||||
new InjectManifest({
|
||||
swSrc: "./src/service-worker.ts",
|
||||
swDest: "service-worker.js",
|
||||
mode: "production",
|
||||
include: ["**/*.{js,css,html,wasm}", "**/Inter-*.woff2"],
|
||||
exclude: [
|
||||
"**/node_modules/**/*",
|
||||
"**/code-lang-*.js",
|
||||
"pdf.worker.min.js"
|
||||
]
|
||||
})
|
||||
])
|
||||
],
|
||||
externals: isDesktop
|
||||
? {
|
||||
"node:crypto": "commonjs crypto",
|
||||
stream: "commonjs stream",
|
||||
"better-sqlite3-multiple-ciphers":
|
||||
"commonjs better-sqlite3-multiple-ciphers",
|
||||
path: "commonjs path",
|
||||
fs: "commonjs fs",
|
||||
url: "commonjs url",
|
||||
util: "commonjs util",
|
||||
"fs/promises": "commonjs fs/promises",
|
||||
crypto: "commonjs crypto"
|
||||
}
|
||||
: { "node:crypto": "commonjs crypto" },
|
||||
resolve: {
|
||||
fallback: isDesktop
|
||||
? {}
|
||||
: {
|
||||
fs: false,
|
||||
path: false,
|
||||
crypto: false,
|
||||
util: false,
|
||||
url: false
|
||||
}
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
codeLang: {
|
||||
test: (module) => {
|
||||
const resource =
|
||||
module.nameForCondition && module.nameForCondition();
|
||||
if (!resource) return false;
|
||||
return (
|
||||
(resource.includes("/editor/languages/") ||
|
||||
resource.includes("/html/languages/") ||
|
||||
resource.includes("/refractor/lang/")) &&
|
||||
path.basename(resource) !== "index.js"
|
||||
);
|
||||
},
|
||||
name(module) {
|
||||
const resource =
|
||||
module.nameForCondition && module.nameForCondition();
|
||||
if (!resource) return;
|
||||
const base = path.basename(resource, ".js");
|
||||
return `code-lang-${base}`;
|
||||
},
|
||||
chunks: "all",
|
||||
enforce: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
swc: {
|
||||
jsc: {
|
||||
experimental: {
|
||||
plugins: isTesting
|
||||
? []
|
||||
: [
|
||||
[
|
||||
"@swc/plugin-react-remove-properties",
|
||||
{
|
||||
properties: ["^data-test-id$"]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
pluginReact(),
|
||||
pluginSvgr({
|
||||
svgrOptions: {
|
||||
icon: true,
|
||||
namedExport: "ReactComponent"
|
||||
}
|
||||
}),
|
||||
regexpAliasPlugin([
|
||||
{
|
||||
find: /desktop-bridge\/index.ts/gm,
|
||||
replacement: isDesktop
|
||||
? path.resolve(
|
||||
__dirname,
|
||||
"src/common/desktop-bridge/index.desktop.ts"
|
||||
)
|
||||
: path.resolve(__dirname, "src/common/desktop-bridge/index.ts")
|
||||
},
|
||||
{
|
||||
find: /sqlite\/index.ts/gm,
|
||||
replacement: isDesktop
|
||||
? path.resolve(__dirname, "src/common/sqlite/index.desktop.ts")
|
||||
: path.resolve(__dirname, "src/common/sqlite/index.ts")
|
||||
}
|
||||
]),
|
||||
{
|
||||
name: "bypass-webpack-require-plugin",
|
||||
setup(api: RsbuildPluginAPI) {
|
||||
api.transform(
|
||||
{
|
||||
test: /sqlite-kysely\.js$/
|
||||
},
|
||||
({ code }) => {
|
||||
return code.replaceAll(/require/gm, "__non_webpack_require__");
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "emit-editor-styles",
|
||||
setup(api: RsbuildPluginAPI) {
|
||||
api.transform(
|
||||
{
|
||||
test: (filename) => filename.endsWith("css")
|
||||
},
|
||||
(context) => {
|
||||
if (
|
||||
context.code.includes("KaTeX_Fraktur-Bold-") ||
|
||||
context.code.includes("Hack typeface")
|
||||
) {
|
||||
context.emitFile("assets/editor-styles.css", context.code);
|
||||
return "";
|
||||
}
|
||||
return context.code;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function regexpAliasPlugin(rules: { find: RegExp; replacement: string }[]) {
|
||||
return {
|
||||
name: "generic-alias-plugin",
|
||||
setup(api: RsbuildPluginAPI) {
|
||||
for (const { find, replacement } of rules) {
|
||||
api.transform(
|
||||
{
|
||||
test: find
|
||||
},
|
||||
() => readFileSync(replacement, "utf-8")
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -20,14 +20,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import { createTRPCProxyClient } from "@trpc/client";
|
||||
import { ipcLink } from "electron-trpc/renderer";
|
||||
import type { AppRouter } from "@notesnook/desktop";
|
||||
import { PATHS } from "@notesnook/desktop";
|
||||
import { AppEventManager, AppEvents } from "../app-events";
|
||||
import { TaskScheduler } from "../../utils/task-scheduler";
|
||||
import { checkForUpdate } from "../../utils/updater";
|
||||
import { showToast } from "../../utils/toast";
|
||||
|
||||
console.log("DESKTOP!");
|
||||
export const desktop = createTRPCProxyClient<AppRouter>({
|
||||
links: [ipcLink()]
|
||||
});
|
||||
export { PATHS };
|
||||
|
||||
attachListeners();
|
||||
function attachListeners() {
|
||||
|
||||
@@ -19,8 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { createWriteStream } from "../../utils/stream-saver";
|
||||
import { type desktop as bridge } from "./index.desktop";
|
||||
console.log("NOT DESKTOP!");
|
||||
|
||||
export const desktop: typeof bridge | undefined = undefined;
|
||||
export function createWritableStream(filename: string) {
|
||||
return createWriteStream(filename);
|
||||
}
|
||||
export const PATHS: Record<string, string> | undefined = undefined;
|
||||
|
||||
@@ -37,10 +37,9 @@ import {
|
||||
import { showToast } from "../utils/toast";
|
||||
import { readFile, showFilePicker } from "../utils/file-picker";
|
||||
import { logger } from "../utils/logger";
|
||||
import { PATHS } from "@notesnook/desktop";
|
||||
import { TaskManager } from "./task-manager";
|
||||
import { EVENTS } from "@notesnook/core";
|
||||
import { createWritableStream } from "./desktop-bridge";
|
||||
import { createWritableStream, PATHS } from "./desktop-bridge";
|
||||
import { FeatureDialog, FeatureKeys } from "../dialogs/feature-dialog";
|
||||
import { User } from "@notesnook/core";
|
||||
import { LegacyBackupFile } from "@notesnook/core";
|
||||
@@ -126,7 +125,10 @@ export async function createBackup(
|
||||
})}-${new Date().getSeconds()}${mode === "full" ? "-full" : ""}`,
|
||||
{ replacement: "-" }
|
||||
);
|
||||
const directory = Config.get("backupStorageLocation", PATHS.backupsDirectory);
|
||||
const directory = Config.get(
|
||||
"backupStorageLocation",
|
||||
PATHS?.backupsDirectory
|
||||
);
|
||||
const ext = "nnbackupz";
|
||||
const filePath = IS_DESKTOP_APP
|
||||
? `${directory}/${filename}.${ext}`
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
Driver
|
||||
} from "@streetwriters/kysely";
|
||||
import { desktop } from "../desktop-bridge";
|
||||
import Worker from "./sqlite.worker.desktop.ts?worker";
|
||||
// import Worker from "./sqlite.worker.desktop.ts?worker";
|
||||
import type { SQLiteWorker } from "./sqlite.worker.desktop";
|
||||
import { wrap, Remote } from "comlink";
|
||||
import { Mutex } from "async-mutex";
|
||||
@@ -37,7 +37,9 @@ import { DialectOptions } from ".";
|
||||
class SqliteDriver implements Driver {
|
||||
connection?: DatabaseConnection;
|
||||
private connectionMutex = new Mutex();
|
||||
worker: Remote<SQLiteWorker> = wrap<SQLiteWorker>(new Worker());
|
||||
worker: Remote<SQLiteWorker> = wrap<SQLiteWorker>(
|
||||
new Worker(new URL("./sqlite.worker.desktop.ts", import.meta.url))
|
||||
);
|
||||
constructor(private readonly config: { name: string }) {}
|
||||
|
||||
async init(): Promise<void> {
|
||||
|
||||
@@ -17,11 +17,11 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import SharedWorker from "./shared-service.worker.ts?sharedworker";
|
||||
// import SharedWorker from "./shared-service.worker.ts?sharedworker";
|
||||
import { Mutex } from "async-mutex";
|
||||
|
||||
const sharedWorker = globalThis.SharedWorker
|
||||
? new SharedWorker({
|
||||
? new SharedWorker(new URL("./shared-service.worker.ts", import.meta.url), {
|
||||
name: "SharedService"
|
||||
})
|
||||
: null;
|
||||
|
||||
@@ -23,14 +23,17 @@ import type {
|
||||
QueryResult
|
||||
} from "@streetwriters/kysely";
|
||||
import { CompiledQuery } from "@streetwriters/kysely";
|
||||
import Worker from "./sqlite.worker.ts?worker";
|
||||
// import Worker from "./sqlite.worker.ts?worker";
|
||||
import type { SQLiteWorker } from "./sqlite.worker";
|
||||
import SQLiteSyncURI from "./wa-sqlite.wasm?url";
|
||||
import SQLiteAsyncURI from "./wa-sqlite-async.wasm?url";
|
||||
// import SQLiteSyncURI from "./wa-sqlite.wasm?url";
|
||||
// import SQLiteAsyncURI from "./wa-sqlite-async.wasm?url";
|
||||
import { Mutex } from "async-mutex";
|
||||
import { SharedService } from "./shared-service";
|
||||
import { Remote, wrap } from "comlink";
|
||||
|
||||
const SQLiteSyncURI = new URL("./wa-sqlite.wasm", import.meta.url).href;
|
||||
const SQLiteAsyncURI = new URL("./wa-sqlite-async.wasm", import.meta.url).href;
|
||||
|
||||
type Config = {
|
||||
dbName: string;
|
||||
async: boolean;
|
||||
@@ -90,7 +93,9 @@ export class WaSqliteWorkerMultipleTabDriver implements Driver {
|
||||
console.log("initializing worker");
|
||||
this.needsInitialization = true;
|
||||
|
||||
const worker = new Worker();
|
||||
const worker = new Worker(
|
||||
new URL("./sqlite.worker.ts", import.meta.url)
|
||||
);
|
||||
worker.addEventListener(
|
||||
"message",
|
||||
(event) =>
|
||||
@@ -235,8 +240,10 @@ export class WaSqliteWorkerSingleTabDriver implements Driver {
|
||||
constructor(private readonly config: Config) {
|
||||
console.log("single tab driver", config.dbName);
|
||||
this.worker = wrap<SQLiteWorker>(
|
||||
new Worker({ name: config.dbName })
|
||||
)
|
||||
new Worker(new URL("./sqlite.worker.ts", import.meta.url), {
|
||||
name: config.dbName
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async init(): Promise<void> {
|
||||
|
||||
@@ -25,11 +25,12 @@ import { strings } from "@notesnook/intl";
|
||||
import { useStore as useSettingStore } from "../../stores/setting-store";
|
||||
import { useStore as useAppStore } from "../../stores/app-store";
|
||||
import { useStore as useUserStore } from "../../stores/user-store";
|
||||
import { desktop } from "../../common/desktop-bridge";
|
||||
import { PATHS } from "@notesnook/desktop";
|
||||
import { desktop, PATHS } from "../../common/desktop-bridge";
|
||||
|
||||
const getDesktopBackupsDirectoryPath = () =>
|
||||
useSettingStore.getState().backupStorageLocation || PATHS.backupsDirectory;
|
||||
useSettingStore.getState().backupStorageLocation ||
|
||||
PATHS?.backupsDirectory ||
|
||||
"";
|
||||
|
||||
export const BackupExportSettings: SettingsGroup[] = [
|
||||
{
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script type="module" src="./index.ts"></script>
|
||||
<style>
|
||||
html {
|
||||
overscroll-behavior: none;
|
||||
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { IFileStorage, File } from "@notesnook/streamable-fs";
|
||||
import { IndexedDBKVStore } from "./key-value";
|
||||
import OriginPrivateFileStoreWorker from "./opfs.worker?worker";
|
||||
// import OriginPrivateFileStoreWorker from "./opfs.worker?worker";
|
||||
import { OriginPrivateFileStoreWorkerType } from "./opfs.worker";
|
||||
import { transfer, wrap } from "comlink";
|
||||
|
||||
@@ -151,7 +151,7 @@ export class CacheStorageFileStore implements IFileStorage {
|
||||
|
||||
export class OriginPrivateFileSystem implements IFileStorage {
|
||||
private readonly worker = wrap<OriginPrivateFileStoreWorkerType>(
|
||||
new OriginPrivateFileStoreWorker()
|
||||
new Worker(new URL("./opfs.worker.ts", import.meta.url))
|
||||
);
|
||||
private created = false;
|
||||
constructor(private readonly name: string) {
|
||||
|
||||
@@ -18,10 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { INNCrypto } from "@notesnook/crypto";
|
||||
import CryptoWorker from "./nncrypto.worker?worker";
|
||||
// import CryptoWorker from "./nncrypto.worker?worker";
|
||||
import { wrap } from "comlink";
|
||||
|
||||
export const NNCrypto = wrap<INNCrypto>(new CryptoWorker()) as INNCrypto;
|
||||
export const NNCrypto = wrap<INNCrypto>(
|
||||
new Worker(new URL("./nncrypto.worker.ts", import.meta.url))
|
||||
) as INNCrypto;
|
||||
// TODO: disable until we fix the `pull failed` errors for good.
|
||||
// IS_DESKTOP_APP && window.NativeNNCrypto
|
||||
// ? new window.NativeNNCrypto()
|
||||
|
||||
@@ -17,9 +17,9 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { DesktopIntegration, PATHS } from "@notesnook/desktop";
|
||||
import type { DesktopIntegration } from "@notesnook/desktop";
|
||||
import { db } from "../common/db";
|
||||
import { desktop } from "../common/desktop-bridge";
|
||||
import { desktop, PATHS } from "../common/desktop-bridge";
|
||||
import createStore from "../common/store";
|
||||
import Config from "../utils/config";
|
||||
import BaseStore from "./index";
|
||||
@@ -53,7 +53,7 @@ class SettingStore extends BaseStore<SettingStore> {
|
||||
fullBackupReminderOffset = Config.get("fullBackupReminderOffset", 0);
|
||||
backupStorageLocation = Config.get(
|
||||
"backupStorageLocation",
|
||||
PATHS.backupsDirectory
|
||||
PATHS?.backupsDirectory
|
||||
);
|
||||
doubleSpacedParagraphs = Config.get("doubleSpacedLines", true);
|
||||
markdownShortcuts = Config.get("markdownShortcuts", false);
|
||||
|
||||
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import NetworkCheckWorker from "./network-check.worker.ts?worker";
|
||||
// import NetworkCheckWorker from "./network-check.worker.ts?worker";
|
||||
import type { NetworkCheck as NetworkWorker } from "./network-check.worker";
|
||||
import { wrap, Remote } from "comlink";
|
||||
|
||||
@@ -26,7 +26,9 @@ export class NetworkCheck {
|
||||
private network!: Remote<NetworkWorker>;
|
||||
|
||||
constructor() {
|
||||
this.worker = new NetworkCheckWorker();
|
||||
this.worker = new Worker(
|
||||
new URL("./network-check.worker.ts", import.meta.url)
|
||||
);
|
||||
this.network = wrap<NetworkWorker>(this.worker);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import TaskSchedulerWorker from "./task-scheduler.worker.ts?worker";
|
||||
// import TaskSchedulerWorker from "./task-scheduler.worker.ts?worker";
|
||||
import type {
|
||||
TaskScheduler as TaskSchedulerType,
|
||||
TaskSchedulerEvent
|
||||
@@ -83,6 +83,6 @@ export class TaskScheduler {
|
||||
function init() {
|
||||
if (worker) return;
|
||||
|
||||
worker = new TaskSchedulerWorker();
|
||||
worker = new Worker(new URL("./task-scheduler.worker.ts", import.meta.url));
|
||||
if (worker) scheduler = wrap<TaskSchedulerType>(worker);
|
||||
}
|
||||
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Plugin, PluginOption, ResolvedConfig, defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react-swc";
|
||||
import svgrPlugin from "vite-plugin-svgr";
|
||||
import envCompatible from "vite-plugin-env-compatible";
|
||||
import { VitePWA } from "vite-plugin-pwa";
|
||||
import autoprefixer from "autoprefixer";
|
||||
import { WEB_MANIFEST } from "./web-manifest";
|
||||
import { execSync } from "child_process";
|
||||
import { version } from "./package.json";
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
import { OutputPlugin } from "rollup";
|
||||
import path from "path";
|
||||
|
||||
const gitHash = (() => {
|
||||
try {
|
||||
return execSync("git rev-parse --short HEAD").toString().trim();
|
||||
} catch (e) {
|
||||
return process.env.GIT_HASH || "gitless";
|
||||
}
|
||||
})();
|
||||
// const appVersion = version.replaceAll(".", "").replace("-beta", "");
|
||||
const isBeta = version.includes("-beta");
|
||||
const isTesting =
|
||||
process.env.TEST === "true" || process.env.NODE_ENV === "development";
|
||||
const isDesktop = process.env.PLATFORM === "desktop";
|
||||
const isThemeBuilder = process.env.THEME_BUILDER === "true";
|
||||
const isAnalyzing = process.env.ANALYZING === "true";
|
||||
|
||||
export default defineConfig({
|
||||
envPrefix: "NN_",
|
||||
root: "src/",
|
||||
publicDir: isThemeBuilder ? path.join(__dirname, "public") : "../public",
|
||||
build: {
|
||||
target: isDesktop ? "esnext" : "modules",
|
||||
outDir: "../build",
|
||||
minify: "esbuild",
|
||||
cssMinify: true,
|
||||
emptyOutDir: true,
|
||||
sourcemap: !isDesktop,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
plugins: [emitEditorStyles()],
|
||||
assetFileNames: "assets/[name]-[hash:12][extname]",
|
||||
chunkFileNames: "assets/[name]-[hash:12].js",
|
||||
manualChunks: (id: string) => {
|
||||
if (
|
||||
(id.includes("/editor/languages/") ||
|
||||
id.includes("/html/languages/") ||
|
||||
id.includes("/refractor/lang/")) &&
|
||||
path.basename(id) !== "index.js"
|
||||
)
|
||||
return `code-lang-${path.basename(id, "js")}`;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
define: {
|
||||
APP_TITLE: `"${isThemeBuilder ? "Notesnook Theme Builder" : "Notesnook"}"`,
|
||||
GIT_HASH: `"${gitHash}"`,
|
||||
APP_VERSION: `"${version}"`,
|
||||
PUBLIC_URL: `"${process.env.PUBLIC_URL || ""}"`,
|
||||
IS_DESKTOP_APP: isDesktop,
|
||||
PLATFORM: `"${process.env.PLATFORM}"`,
|
||||
IS_TESTING: process.env.TEST === "true",
|
||||
IS_BETA: isBeta,
|
||||
IS_THEME_BUILDER: isThemeBuilder
|
||||
},
|
||||
logLevel: process.env.NODE_ENV === "production" ? "warn" : "info",
|
||||
resolve: {
|
||||
dedupe: [
|
||||
"react",
|
||||
"react-dom",
|
||||
"@mdi/js",
|
||||
"@mdi/react",
|
||||
"@emotion/react",
|
||||
"katex",
|
||||
"react-modal",
|
||||
"dayjs",
|
||||
"@streetwriters/kysely"
|
||||
],
|
||||
|
||||
alias: [
|
||||
{
|
||||
find: /\/desktop-bridge$/gm,
|
||||
replacement: isDesktop
|
||||
? "/desktop-bridge/index.desktop"
|
||||
: "/desktop-bridge/index"
|
||||
},
|
||||
{
|
||||
find: /\/sqlite$/gm,
|
||||
replacement: isDesktop ? "/sqlite/index.desktop" : "/sqlite/index"
|
||||
}
|
||||
]
|
||||
},
|
||||
server: {
|
||||
port: 3000
|
||||
},
|
||||
worker: {
|
||||
format: "es",
|
||||
rollupOptions: {
|
||||
output: {
|
||||
assetFileNames: "assets/[name]-[hash:12][extname]",
|
||||
chunkFileNames: "assets/[name]-[hash:12].js",
|
||||
inlineDynamicImports: true
|
||||
}
|
||||
}
|
||||
},
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [autoprefixer()]
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
...(isAnalyzing
|
||||
? [
|
||||
visualizer({
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
open: true
|
||||
}) as PluginOption
|
||||
]
|
||||
: []),
|
||||
...((isThemeBuilder || isDesktop) && process.env.NODE_ENV === "production"
|
||||
? []
|
||||
: [
|
||||
VitePWA({
|
||||
strategies: "injectManifest",
|
||||
minify: true,
|
||||
manifest: WEB_MANIFEST,
|
||||
injectRegister: null,
|
||||
srcDir: "",
|
||||
filename: "service-worker.ts",
|
||||
mode: "production",
|
||||
workbox: { mode: "production" },
|
||||
injectManifest: {
|
||||
globPatterns: ["**/*.{js,css,html,wasm}", "**/Inter-*.woff2"],
|
||||
globIgnores: [
|
||||
"**/node_modules/**/*",
|
||||
"**/code-lang-*.js",
|
||||
"pdf.worker.min.js"
|
||||
]
|
||||
}
|
||||
})
|
||||
]),
|
||||
react({
|
||||
plugins: isTesting
|
||||
? undefined
|
||||
: [
|
||||
[
|
||||
"@swc/plugin-react-remove-properties",
|
||||
{
|
||||
properties: ["^data-test-id$"]
|
||||
}
|
||||
]
|
||||
]
|
||||
}),
|
||||
envCompatible({
|
||||
prefix: "NN_",
|
||||
mountedPath: "process.env"
|
||||
}),
|
||||
svgrPlugin({
|
||||
svgrOptions: {
|
||||
icon: true,
|
||||
namedExport: "ReactComponent"
|
||||
// ...svgr options (https://react-svgr.com/docs/options/)
|
||||
}
|
||||
}),
|
||||
...(isDesktop
|
||||
? []
|
||||
: [
|
||||
prefetchPlugin({
|
||||
excludeFn: (assetName) =>
|
||||
assetName.includes("wa-sqlite-async") ||
|
||||
!assetName.includes("wa-sqlite")
|
||||
})
|
||||
])
|
||||
]
|
||||
});
|
||||
|
||||
function emitEditorStyles(): OutputPlugin {
|
||||
return {
|
||||
name: "rollup-plugin-emit-editor-styles",
|
||||
generateBundle(options, bundle) {
|
||||
for (const file in bundle) {
|
||||
const chunk = bundle[file];
|
||||
if (
|
||||
chunk.type === "asset" &&
|
||||
chunk.fileName.endsWith(".css") &&
|
||||
typeof chunk.source === "string" &&
|
||||
(chunk.source.includes("KaTeX_Fraktur-Bold-") ||
|
||||
chunk.source.includes("Hack typeface"))
|
||||
) {
|
||||
this.emitFile({
|
||||
type: "asset",
|
||||
fileName: "assets/editor-styles.css",
|
||||
name: "editor-styles.css",
|
||||
source: chunk.source
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function prefetchPlugin(options?: {
|
||||
excludeFn?: (assetName: string) => boolean;
|
||||
}): Plugin {
|
||||
let config: ResolvedConfig;
|
||||
return {
|
||||
name: "vite-plugin-bundle-prefetch",
|
||||
apply: "build",
|
||||
configResolved(resolvedConfig: ResolvedConfig) {
|
||||
// store the resolved config
|
||||
config = resolvedConfig;
|
||||
},
|
||||
transformIndexHtml(
|
||||
html: string,
|
||||
ctx: {
|
||||
path: string;
|
||||
filename: string;
|
||||
bundle?: import("rollup").OutputBundle;
|
||||
chunk?: import("rollup").OutputChunk;
|
||||
}
|
||||
) {
|
||||
const bundles = Object.keys(ctx.bundle ?? {});
|
||||
const isLegacy = bundles.some((bundle) => bundle.includes("legacy"));
|
||||
if (isLegacy) {
|
||||
//legacy build won't add prefetch
|
||||
return html;
|
||||
}
|
||||
// remove map files
|
||||
let modernBundles = bundles.filter(
|
||||
(bundle) => bundle.endsWith(".map") === false
|
||||
);
|
||||
const excludeFn = options?.excludeFn;
|
||||
if (excludeFn) {
|
||||
modernBundles = modernBundles.filter((bundle) => !excludeFn(bundle));
|
||||
}
|
||||
// Remove existing files and concatenate them into link tags
|
||||
const prefechBundlesString = modernBundles
|
||||
.filter((bundle) => html.includes(bundle) === false)
|
||||
.map((bundle) => `<link rel="prefetch" href="${config.base}${bundle}">`)
|
||||
.join("\n");
|
||||
|
||||
// Use regular expression to get the content within <head> </head>
|
||||
const headContent = html.match(/<head>([\s\S]*)<\/head>/)?.[1] ?? "";
|
||||
// Insert the content of prefetch into the head
|
||||
const newHeadContent = `${headContent}${prefechBundlesString}`;
|
||||
// Replace the original head
|
||||
html = html.replace(
|
||||
/<head>([\s\S]*)<\/head>/,
|
||||
`<head>${newHeadContent}</head>`
|
||||
);
|
||||
|
||||
return html;
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user