[] = [];
- while (!mmkv.eof) {
- const key = mmkv.readString();
- const idMatch = key.match(/^sec_ekey#(\d+)-(.+)/);
- if (!idMatch) {
- mmkv.skipContainer();
- continue;
- }
-
- const [_, rid, quality] = idMatch;
- const ekey = mmkv.readVariantString();
- result.push({ rid, quality, ekey });
- }
- return result;
- }
-}
diff --git a/um-react/src/util/WorkerEventBus.ts b/um-react/src/util/WorkerEventBus.ts
deleted file mode 100644
index 54ad649..0000000
--- a/um-react/src/util/WorkerEventBus.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { nanoid } from 'nanoid';
-import { DecryptError } from '~/decrypt-worker/util/DecryptError';
-
-type WorkerServerHandler = (payload: P) => R | Promise;
-
-interface SerializedError {
- message: string;
- stack?: string;
- code?: string;
-}
-
-interface WorkerClientRequestPayload {
- id: string;
- action: string;
- payload: P;
-}
-
-interface WorkerServerResponsePayload {
- id: string;
- result: R;
- error: SerializedError;
-}
-
-export class WorkerClientBus {
- private idPromiseMap = new Map void, (error: Error) => void]>();
-
- constructor(private worker: Worker) {
- worker.addEventListener('message', this.eventHandler);
- }
-
- eventHandler = (e: MessageEvent) => {
- const { id, result, error } = e.data;
- const actionPromise = this.idPromiseMap.get(id);
- if (!actionPromise) {
- console.error('cound not fetch worker promise for action: %s', id);
- return;
- }
- this.idPromiseMap.delete(id);
-
- const [resolve, reject] = actionPromise;
- if (error) {
- const wrappedError = new Error(error.message, { cause: error });
- wrappedError.stack = error.stack;
- Object.assign(wrappedError, { code: error.code ?? null });
- reject(wrappedError);
- } else {
- resolve(result as never);
- }
- };
-
- async request(actionName: T, payload: P): Promise {
- return new Promise((resolve, reject) => {
- const id = `request://${actionName}/${nanoid()}`;
- this.idPromiseMap.set(id, [resolve, reject]);
- this.worker.postMessage({
- id,
- action: actionName,
- payload,
- });
- });
- }
-}
-
-export class WorkerServerBus {
- private handlers = new Map>();
-
- addEventHandler(actionName: string, handler: WorkerServerHandler) {
- this.handlers.set(actionName, handler as WorkerServerHandler);
- }
-
- onmessage = async (e: MessageEvent) => {
- const { id, action, payload } = e.data;
- const handler = this.handlers.get(action);
-
- let result = null;
- let error = null;
-
- if (!handler) {
- error = new Error('Handler missing for action ' + action);
- } else {
- try {
- result = await handler(payload);
- } catch (err: unknown) {
- if (err instanceof DecryptError) {
- error = err.toJSON();
- } else {
- error = err;
- }
- }
- }
-
- postMessage({ id, result, error });
- };
-}
diff --git a/um-react/src/util/__tests__/ConcurrentQueue.test.ts b/um-react/src/util/__tests__/ConcurrentQueue.test.ts
deleted file mode 100644
index 5074953..0000000
--- a/um-react/src/util/__tests__/ConcurrentQueue.test.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { ConcurrentQueue } from '../ConcurrentQueue';
-import { nextTickAsync } from '../nextTick';
-
-class SimpleQueue extends ConcurrentQueue {
- handler(_item: T): Promise {
- throw new Error('Method not overridden');
- }
-}
-
-test('should be able to process the queue within limit', async () => {
- const inputs: number[] = [];
- const queuedResolver: (() => void)[] = [];
- const queue = new SimpleQueue(3);
-
- try {
- vi.spyOn(queue, 'handler').mockImplementation((item) => {
- inputs.push(item);
- return new Promise((resolve, _reject) => {
- queuedResolver.push(resolve);
- });
- });
-
- const promises = [
- // Add some values
- queue.add(1),
- queue.add(2),
- queue.add(3),
- queue.add(4),
- queue.add(5),
- ];
-
- // Should queue 3 things at once
- expect(queue.handler).toHaveBeenCalledTimes(3);
- expect(inputs).toEqual([1, 2, 3]);
-
- // Let first 3 go
- for (let i = 0; i < 3; i++) {
- queuedResolver[i]();
- await promises[i];
- }
-
- // Wait till all fulfilled
- while (queuedResolver.length !== 5) {
- await nextTickAsync();
- }
-
- // Now it should've queued everything.
- expect(inputs).toEqual([1, 2, 3, 4, 5]);
- expect(queue.handler).toHaveBeenCalledTimes(5);
-
- // Resolve everything
- queuedResolver.forEach((resolve) => resolve());
- await Promise.all(promises);
- } finally {
- vi.spyOn(queue, 'handler').mockRejectedValue(new Error('handler ran too late'));
- queuedResolver.forEach((resolve) => resolve());
- }
-});
-
-test('it should move on to the next item in the queue once failed', async () => {
- const inputs: number[] = [];
- const queuedResolver: (() => void)[] = [];
- const queue = new SimpleQueue(3);
-
- try {
- vi.spyOn(queue, 'handler').mockImplementation((item) => {
- if (item === 3) {
- throw new Error('dummy error');
- }
-
- inputs.push(item);
- return new Promise((resolve, _reject) => {
- queuedResolver.push(() => resolve(item));
- });
- });
-
- const promises = [
- // Add some values
- queue.add(1),
- queue.add(2),
- ];
- const errorHandler = vi.fn();
- const badPromise = queue.add(3);
- badPromise.catch(errorHandler);
- promises.push(queue.add(4));
- promises.push(queue.add(5));
-
- // Let first 2 be fulfilled
- for (let i = 0; i < 2; i++) {
- queuedResolver[i]();
- await promises[i];
- }
-
- // Wait till all fulfilled
- while (queuedResolver.length !== 4) {
- await nextTickAsync();
- }
-
- // Should've moved on, as 3 will throw error
- expect(queue.handler).toHaveBeenCalledTimes(5);
- await expect(badPromise).rejects.toThrowError('dummy error');
-
- queuedResolver.forEach((resolve) => resolve());
- expect(Promise.all(promises)).resolves.toEqual([1, 2, 4, 5]);
- } finally {
- vi.spyOn(queue, 'handler').mockRejectedValue(new Error('handler ran too late'));
- queuedResolver.forEach((resolve) => resolve());
- }
-});
diff --git a/um-react/src/util/__tests__/DecryptionQueue.test.ts b/um-react/src/util/__tests__/DecryptionQueue.test.ts
deleted file mode 100644
index 4f2bf35..0000000
--- a/um-react/src/util/__tests__/DecryptionQueue.test.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { DECRYPTION_WORKER_ACTION_NAME } from '~/decrypt-worker/constants';
-import { WorkerClientBus } from '../WorkerEventBus';
-import { DecryptionQueue } from '../DecryptionQueue';
-
-vi.mock('../WorkerEventBus', () => {
- class MyWorkerClientBus {
- request() {
- throw new Error('request not mocked');
- }
- }
-
- return { WorkerClientBus: MyWorkerClientBus };
-});
-
-test('should be able to forward request to worker client bus', async () => {
- // This class is mocked
- const bus = new WorkerClientBus(null as never);
- vi.spyOn(bus, 'request').mockImplementation(
- async (actionName: DECRYPTION_WORKER_ACTION_NAME, payload: unknown): Promise => {
- return { actionName, payload };
- }
- );
-
- const queue = new DecryptionQueue(bus, 1);
- await expect(queue.add({ id: 'file://1', blobURI: 'blob://mock-file' })).resolves.toEqual({
- actionName: DECRYPTION_WORKER_ACTION_NAME.DECRYPT,
- payload: {
- blobURI: 'blob://mock-file',
- id: 'file://1',
- },
- });
-});
diff --git a/um-react/src/util/__tests__/MMKVParser.test.ts b/um-react/src/util/__tests__/MMKVParser.test.ts
deleted file mode 100644
index e4eebcb..0000000
--- a/um-react/src/util/__tests__/MMKVParser.test.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { MMKVParser } from '../MMKVParser';
-import { readFileSync } from 'node:fs';
-
-test('parse mmkv file as expected', () => {
- const buff = readFileSync(__dirname + '/__fixture__/test.mmkv');
- const view = new DataView(buff.buffer.slice(buff.byteOffset, buff.byteOffset + buff.byteLength));
- expect(MMKVParser.toStringMap(view)).toEqual(
- new Map([
- ['key', 'value'],
- [
- 'Lorem Ipsum',
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' +
- 'Vestibulum congue volutpat metus non molestie. Quisque id est sapien. ' +
- 'Fusce eget tristique sem. Donec tellus lacus, viverra sed lectus eget, elementum ultrices dolor. ' +
- 'Integer non urna justo.',
- ],
- ])
- );
-});
diff --git a/um-react/src/util/__tests__/__fixture__/test.mmkv b/um-react/src/util/__tests__/__fixture__/test.mmkv
deleted file mode 100644
index 04a8a01..0000000
Binary files a/um-react/src/util/__tests__/__fixture__/test.mmkv and /dev/null differ
diff --git a/um-react/src/util/__tests__/enumObject.test.ts b/um-react/src/util/__tests__/enumObject.test.ts
deleted file mode 100644
index 64ab335..0000000
--- a/um-react/src/util/__tests__/enumObject.test.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { enumObject } from '../objects';
-
-test('it should ignore and not crash with non-object', () => {
- expect(Array.from(enumObject('string' as never))).toEqual([]);
-});
-
-test('it should ignore and not crash with null', () => {
- expect(Array.from(enumObject(null))).toEqual([]);
-});
-
-test('it be able to iterate object', () => {
- expect(Array.from(enumObject({ a: '1', b: '2' }))).toMatchInlineSnapshot(`
- [
- [
- "a",
- "1",
- ],
- [
- "b",
- "2",
- ],
- ]
- `);
-});
diff --git a/um-react/src/util/__tests__/levenshtein.test.ts b/um-react/src/util/__tests__/levenshtein.test.ts
deleted file mode 100644
index e3c5b1e..0000000
--- a/um-react/src/util/__tests__/levenshtein.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { closestByLevenshtein, levenshtein } from '../levenshtein';
-
-test('levenshtein quick test', () => {
- expect(levenshtein('cat', '')).toStrictEqual(3);
- expect(levenshtein('', 'cat')).toStrictEqual(3);
- expect(levenshtein('cat', 'cat')).toStrictEqual(0);
- expect(levenshtein('cat', 'cut')).toStrictEqual(1);
- expect(levenshtein('kitten', 'sitting')).toStrictEqual(3);
- expect(levenshtein('tier', 'tor')).toStrictEqual(2);
- expect(levenshtein('mississippi', 'swiss miss')).toStrictEqual(8);
-});
-
-test('closestByLevenshtein quick test', () => {
- expect(closestByLevenshtein('cat', ['cut', 'dog', 'bat'])).toStrictEqual('cut');
- expect(closestByLevenshtein('dag', ['dog', 'pumpkin'])).toStrictEqual('dog');
- expect(closestByLevenshtein('hello', ['jello', 'yellow', 'bello'])).toStrictEqual('jello');
-});
diff --git a/um-react/src/util/__tests__/pathHelper.test.ts b/um-react/src/util/__tests__/pathHelper.test.ts
deleted file mode 100644
index b8ac642..0000000
--- a/um-react/src/util/__tests__/pathHelper.test.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { getFileName } from '../pathHelper';
-
-test('handle linux path', () => {
- expect(getFileName('/path/to/file.bin')).toEqual('file.bin');
-});
-
-test('handle win32 path', () => {
- expect(getFileName('C:\\system32\\file.bin')).toEqual('file.bin');
-});
-
-test('handle file name only as well', () => {
- expect(getFileName('file.bin')).toEqual('file.bin');
-});
diff --git a/um-react/src/util/__tests__/splitN.ts.test.ts b/um-react/src/util/__tests__/splitN.ts.test.ts
deleted file mode 100644
index 448322b..0000000
--- a/um-react/src/util/__tests__/splitN.ts.test.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { splitN } from '../splitN';
-
-test('some test cases', () => {
- expect(splitN('1,2,3', ',', 2)).toEqual(['1', '2,3']);
- expect(splitN('1,2,3', ',', 3)).toEqual(['1', '2', '3']);
- expect(splitN('1,2,3', ',', 4)).toEqual(['1', '2', '3']);
-
- expect(splitN('1,2,3', '.', 3)).toEqual(['1,2,3']);
- expect(splitN('1,2,3', '?', 0)).toEqual(['1,2,3']);
-});
diff --git a/um-react/src/util/fnWrapper.ts b/um-react/src/util/fnWrapper.ts
deleted file mode 100644
index 8c3bdf4..0000000
--- a/um-react/src/util/fnWrapper.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-function isPromise(p: unknown): p is Promise {
- return !!p && typeof p === 'object' && 'then' in p && 'catch' in p && 'finally' in p;
-}
-
-export function wrapFunctionCall(pre: () => void, post: () => void, fn: () => R): R {
- pre();
-
- try {
- const result = fn();
-
- if (isPromise(result)) {
- result.finally(post);
- }
-
- return result;
- } catch (e) {
- post();
- throw e;
- }
-}
diff --git a/um-react/src/util/formatHex.ts b/um-react/src/util/formatHex.ts
deleted file mode 100644
index 0d778c1..0000000
--- a/um-react/src/util/formatHex.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function formatHex(value: number, len = 8) {
- return '0x' + (value | 0).toString(16).padStart(len, '0');
-}
diff --git a/um-react/src/util/levenshtein.ts b/um-react/src/util/levenshtein.ts
deleted file mode 100644
index 340a057..0000000
--- a/um-react/src/util/levenshtein.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-// translation of pseudocode from Wikipedia:
-import { stringToUTF8Bytes } from '~/decrypt-worker/util/utf8Encoder';
-
-// https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows
-export function levenshtein(str1: string, str2: string) {
- if (str1 === str2) {
- return 0;
- }
-
- if (str1.length === 0) {
- return str2.length;
- } else if (str2.length === 0) {
- return str1.length;
- }
-
- // Convert them to Uint8Array to avoid expensive string APIs.
- const s = stringToUTF8Bytes(str1.normalize().toLowerCase());
- const t = stringToUTF8Bytes(str2.normalize().toLowerCase());
- const m = s.byteLength;
- const n = t.byteLength;
-
- // create two work vectors of integer distances
- let v0 = new Uint32Array(n + 1);
- let v1 = new Uint32Array(n + 1);
-
- // initialize v0 (the previous row of distances)
- // this row is A[0][i]: edit distance from an empty s to t;
- // that distance is the number of characters to append to s to make t.
- for (let i = 0; i <= n; i++) {
- v0[i] = i;
- }
-
- for (let i = 0; i < m; i++) {
- // calculate v1 (current row distances) from the previous row v0
-
- // first element of v1 is A[i + 1][0]
- // edit distance is delete (i + 1) chars from s to match empty t
- v1[0] = i + 1;
-
- // use formula to fill in the rest of the row
- for (let j = 0; j < n; j++) {
- // calculating costs for A[i + 1][j + 1]
- const deletionCost = v0[j + 1] + 1;
- const insertionCost = v1[j] + 1;
- const substitutionCost = v0[j] + (s[i] === t[j] ? 0 : 1);
- v1[j + 1] = Math.min(deletionCost, insertionCost, substitutionCost);
- }
-
- // copy v1 (current row) to v0 (previous row) for next iteration
- // since data in v1 is always invalidated, a swap without copy could be more efficient
- [v0, v1] = [v1, v0];
- }
-
- // after the last swap, the results of v1 are now in v0
- return v0[n];
-}
-
-export function closestByLevenshtein(str: string, candidates: string[]) {
- // Faster than pre-calculate all and pass scores to Math.min.
- const n = candidates.length;
- if (n === 0) {
- throw new Error('empty candidates');
- }
-
- let lowestIdx = 0;
- let lowestScore = levenshtein(str, candidates[0]);
-
- for (let i = 1; i < n; i++) {
- const score = levenshtein(str, candidates[i]);
- if (score < lowestScore) {
- lowestScore = score;
- lowestIdx = i;
- }
- }
-
- return candidates[lowestIdx];
-}
diff --git a/um-react/src/util/logUtils.ts b/um-react/src/util/logUtils.ts
deleted file mode 100644
index 29430b5..0000000
--- a/um-react/src/util/logUtils.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { wrapFunctionCall } from './fnWrapper';
-
-export function timedLogger(label: string, fn: () => R): R {
- if (import.meta.env.ENABLE_PERF_LOG !== '1') {
- return fn();
- } else {
- return wrapFunctionCall(
- () => console.time(label),
- () => console.timeEnd(label),
- fn
- );
- }
-}
-
-export function withGroupedLogs(label: string, fn: () => R): R {
- if (import.meta.env.ENABLE_PERF_LOG !== '1') {
- return fn();
- } else {
- return wrapFunctionCall(
- () => console.group(label),
- () => (console.groupEnd as (label: string) => void)(label),
- () => timedLogger(`${label}/total`, fn)
- );
- }
-}
-
-const noop = (..._args: unknown[]) => {
- // noop
-};
-
-const dummyLogger = {
- log: noop,
- info: noop,
- warn: noop,
- debug: noop,
- trace: noop,
-};
-
-export function getLogger() {
- if (import.meta.env.ENABLE_PERF_LOG === '1') {
- return window.console;
- } else {
- return dummyLogger;
- }
-}
diff --git a/um-react/src/util/nextTick.ts b/um-react/src/util/nextTick.ts
deleted file mode 100644
index 0b50258..0000000
--- a/um-react/src/util/nextTick.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-type NextTickFn = (callback: () => void) => void;
-
-/* c8 ignore start */
-const nextTickFn =
- typeof setImmediate !== 'undefined'
- ? (setImmediate as NextTickFn)
- : typeof requestAnimationFrame !== 'undefined'
- ? (requestAnimationFrame as NextTickFn)
- : (setTimeout as NextTickFn);
-/* c8 ignore stop */
-
-export async function nextTickAsync() {
- return new Promise((resolve) => nextTickFn(resolve));
-}
diff --git a/um-react/src/util/objects.ts b/um-react/src/util/objects.ts
deleted file mode 100644
index ee7fe14..0000000
--- a/um-react/src/util/objects.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-export function* enumObject(obj: Record | null | void): Generator<[string, T]> {
- if (obj && typeof obj === 'object') {
- for (const key in obj) {
- yield [key, obj[key]];
- }
- }
-}
-
-export const { hasOwn } = Object;
diff --git a/um-react/src/util/pathHelper.ts b/um-react/src/util/pathHelper.ts
deleted file mode 100644
index c50939b..0000000
--- a/um-react/src/util/pathHelper.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function getFileName(path: string) {
- return path.replace(/.*[\\/]/, '');
-}
diff --git a/um-react/src/util/splitN.ts b/um-react/src/util/splitN.ts
deleted file mode 100644
index 0b3d402..0000000
--- a/um-react/src/util/splitN.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export function splitN(str: string, sep: string, maxN: number) {
- if (maxN <= 1) {
- return [str];
- }
-
- const chunks: string[] = [];
- const lenSep = sep.length;
- let searchIdx = 0;
- for (; maxN > 1; maxN--) {
- const nextIdx = str.indexOf(sep, searchIdx);
- if (nextIdx === -1) {
- break;
- }
- chunks.push(str.slice(searchIdx, nextIdx));
- searchIdx = nextIdx + lenSep;
- }
-
- chunks.push(str.slice(searchIdx));
- return chunks;
-}
diff --git a/um-react/src/util/sqlite.ts b/um-react/src/util/sqlite.ts
deleted file mode 100644
index f1c652c..0000000
--- a/um-react/src/util/sqlite.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import * as initSqlite from 'sql.js';
-
-const urlWasm = new URL('@nm/sql.js/dist/sql-wasm.wasm', import.meta.url).toString();
-
-export type SQLStatic = Awaited>;
-export type SQLDatabase = SQLStatic['Database']['prototype'];
-
-let sqlLoaderPromise: Promise | void;
-
-export async function loadSQL() {
- if (!sqlLoaderPromise) {
- sqlLoaderPromise = initSqlite.default({ locateFile: () => urlWasm });
- }
- return await sqlLoaderPromise;
-}
diff --git a/um-react/src/vite-env.d.ts b/um-react/src/vite-env.d.ts
deleted file mode 100644
index 11f02fe..0000000
--- a/um-react/src/vite-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/um-react/tsconfig.json b/um-react/tsconfig.json
deleted file mode 100644
index 86d1a54..0000000
--- a/um-react/tsconfig.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "compilerOptions": {
- "target": "ESNext",
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
- "types": ["vitest/globals", "@testing-library/jest-dom"],
- "module": "ESNext",
- "skipLibCheck": true,
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx",
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true,
- "baseUrl": ".",
- "esModuleInterop": true,
- "paths": {
- "~/*": ["./src/*"],
- "@nm/*": ["./node_modules/*"]
- }
- },
- "include": ["src"],
- "references": [
- {
- "path": "./tsconfig.node.json"
- }
- ]
-}
diff --git a/um-react/tsconfig.node.json b/um-react/tsconfig.node.json
deleted file mode 100644
index b5a3431..0000000
--- a/um-react/tsconfig.node.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "compilerOptions": {
- "composite": true,
- "skipLibCheck": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowSyntheticDefaultImports": true
- },
- "include": [
- "vite.config.ts"
- ]
-}
diff --git a/um-react/tsconfig.prod.json b/um-react/tsconfig.prod.json
deleted file mode 100644
index a829226..0000000
--- a/um-react/tsconfig.prod.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "./tsconfig",
- "exclude": [
- "./src/**/__tests__/**",
- "./src/**/__mocks__/**",
- "./src/test-utils/**",
- "./src/**/*.test.{js,jsx,ts,tsx}"
- ]
-}
\ No newline at end of file
diff --git a/um-react/vite.config.ts b/um-react/vite.config.ts
deleted file mode 100644
index cec9341..0000000
--- a/um-react/vite.config.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import cp from 'node:child_process';
-import url from 'node:url';
-import path from 'node:path';
-import fs from 'node:fs';
-
-import { defineConfig } from 'vite';
-import react from '@vitejs/plugin-react';
-import wasm from 'vite-plugin-wasm';
-import replace from '@rollup/plugin-replace';
-import topLevelAwait from 'vite-plugin-top-level-await';
-import { VitePWA } from 'vite-plugin-pwa';
-
-const gitRoot = url.fileURLToPath(new URL('.', import.meta.url));
-const pkg = JSON.parse(fs.readFileSync(gitRoot + '/package.json', 'utf-8'));
-
-function command(cmd, dir = '') {
- return cp.execSync(cmd, { cwd: path.join(gitRoot, dir), encoding: 'utf-8' }).trim();
-}
-
-const COMMAND_GIT_VERSION = 'git describe --long --dirty --tags --always';
-const shortCommit = command(COMMAND_GIT_VERSION);
-const version = `${pkg.version}-${shortCommit}`;
-
-// https://vitejs.dev/config/
-export default defineConfig({
- worker: {
- format: 'es',
- },
- server: {
- fs: {
- // Note:
- // This is _insecure_, but is required to get pnpm link to work.
- // strict: false,
-
- allow: [
- 'src',
- 'node_modules',
-
- // Allow pnpm to link.
- process.env.LIB_PARAKEET_JS_DIR || '../libparakeet-js',
- ],
- },
- },
- base: './',
- optimizeDeps: {
- exclude: ['@jixun/libparakeet', 'sql.js'],
- },
- plugins: [
- replace({
- preventAssignment: true,
- values: {
- __APP_VERSION_SHORT__: pkg.version,
- __APP_VERSION__: version,
- },
- }),
- react(),
- wasm(),
- topLevelAwait(),
- VitePWA({
- registerType: 'prompt',
- workbox: {
- // Cache everything from dist
- globPatterns: ['**/*.{js,css,html,ico,png,svg,wasm}'],
- },
- manifest: {
- display: 'standalone',
- name: '音乐解锁 (Unlock Music)',
- short_name: '音乐解锁',
- lang: 'zh-cmn-Hans-CN',
- description: '在现代浏览器解锁已购的加密音乐!',
- theme_color: '#ffffff',
- icons: [
- {
- src: 'pwa-192x192.png',
- sizes: '192x192',
- type: 'image/png',
- purpose: 'maskable',
- },
- {
- src: 'pwa-512x512.png',
- sizes: '512x512',
- type: 'image/png',
- },
- ],
- },
- }),
- ],
- resolve: {
- alias: {
- '~': path.resolve(__dirname, 'src'),
- '@nm': path.resolve(__dirname, 'node_modules'),
- module: path.resolve(__dirname, 'src', 'dummy.mjs'),
- },
- },
- build: {
- outDir: '../src/renderer',
- rollupOptions: {
- output: {
- manualChunks: {
- reacts: ['react', 'react-dom', 'react-dropzone', 'react-promise-suspense', 'react-redux', '@reduxjs/toolkit'],
- chakra: ['@chakra-ui/react', '@emotion/react', '@emotion/styled', 'framer-motion'],
- icons: ['react-icons', '@chakra-ui/icons'],
- utility: ['radash', 'nanoid', 'immer', 'react-syntax-highlighter'],
- },
- },
- },
- },
-});
diff --git a/um-react/vitest.config.ts b/um-react/vitest.config.ts
deleted file mode 100644
index e7e0842..0000000
--- a/um-react/vitest.config.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import { defineConfig } from 'vitest/config';
-
-export default defineConfig({
- test: {
- globals: true,
- mockReset: true,
- environment: 'jsdom',
- setupFiles: ['src/test-utils/setup-jest.ts'],
- alias: [
- {
- find: /^~\/(.*)/,
- replacement: 'src/$1',
- },
- ],
- // workaround: sql.js is not ESModule friendly, yet...
- deps: {
- inline: ['sql.js'],
- },
- api: {
- port: 5174, // vite port + 1
- },
- coverage: {
- exclude: [
- // default rules
- 'coverage/**',
- 'dist/**',
- 'packages/*/test{,s}/**',
- '**/*.d.ts',
- 'cypress/**',
- 'test{,s}/**',
- 'test{,-*}.{js,cjs,mjs,ts,tsx,jsx}',
- '**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx}',
- '**/*{.,-}spec.{js,cjs,mjs,ts,tsx,jsx}',
- '**/__tests__/**',
- '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
- '**/.{eslint,mocha,prettier}rc.{js,cjs,yml}',
-
- // custom ones
- 'src/test-utils/**',
- ],
- },
- },
-});