mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-21 15:36:50 -05:00
[AI] Add browser-compatible build for @actual-app/api
The API package was previously Node.js-only due to its dependency on better-sqlite3 and Node.js fs/path modules. This adds a browser build that uses loot-core's existing browser platform implementations (sql.js/WASM, IndexedDB, absurd-sql) instead. Changes: - Add index.web.ts: browser entry point (no Node.js version check or node-fetch polyfill) - Add vite.browser.config.ts: browser-targeted Vite build that resolves to browser platform files (index.ts) instead of Node.js ones (index.api.ts -> index.electron.ts) - Update package.json: conditional exports (browser vs default/node), module field, build:browser script - Update tsconfig.json: exclude new config file from type checking The browser build outputs dist/browser.js (ESM) alongside the existing dist/index.js (CJS/Node). Bundlers that support the "browser" condition in package.json exports will automatically use the browser build. https://claude.ai/code/session_01MnxRXLNjqXrVb5CdsC85Fb
This commit is contained in:
26
packages/api/index.web.ts
Normal file
26
packages/api/index.web.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { init as initLootCore } from '@actual-app/core/server/main';
|
||||||
|
import type { InitConfig, lib } from '@actual-app/core/server/main';
|
||||||
|
|
||||||
|
export * from './methods';
|
||||||
|
export * as utils from './utils';
|
||||||
|
|
||||||
|
/** @deprecated Please use return value of `init` instead */
|
||||||
|
export let internal: typeof lib | null = null;
|
||||||
|
|
||||||
|
export async function init(config: InitConfig = {}) {
|
||||||
|
internal = await initLootCore(config);
|
||||||
|
return internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function shutdown() {
|
||||||
|
if (internal) {
|
||||||
|
try {
|
||||||
|
await internal.send('sync');
|
||||||
|
} catch {
|
||||||
|
// most likely that no budget is loaded, so the sync failed
|
||||||
|
}
|
||||||
|
|
||||||
|
await internal.send('close-budget');
|
||||||
|
internal = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,23 +8,39 @@
|
|||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
"module": "dist/browser.js",
|
||||||
"types": "@types/index.d.ts",
|
"types": "@types/index.d.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"development": "./index.ts",
|
"development": "./index.ts",
|
||||||
"default": "./dist/index.js"
|
"browser": {
|
||||||
}
|
"types": "./@types/index.d.ts",
|
||||||
|
"default": "./dist/browser.js"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"default": {
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./@types/index.d.ts",
|
"types": "./@types/index.d.ts",
|
||||||
"default": "./dist/index.js"
|
"default": "./dist/index.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"browser": {
|
||||||
|
"types": "./@types/index.d.ts",
|
||||||
|
"default": "./dist/browser.js"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"types": "./@types/index.d.ts",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "vite build",
|
"build": "vite build && vite build --config vite.browser.config.ts",
|
||||||
|
"build:node": "vite build",
|
||||||
|
"build:browser": "vite build --config vite.browser.config.ts",
|
||||||
"test": "vitest --run",
|
"test": "vitest --run",
|
||||||
"typecheck": "tsgo -b && tsc-strict"
|
"typecheck": "tsgo -b && tsc-strict"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,5 +18,12 @@
|
|||||||
},
|
},
|
||||||
"references": [{ "path": "../crdt" }, { "path": "../loot-core" }],
|
"references": [{ "path": "../crdt" }, { "path": "../loot-core" }],
|
||||||
"include": ["."],
|
"include": ["."],
|
||||||
"exclude": ["**/node_modules/*", "dist", "@types", "*.test.ts", "*.config.ts"]
|
"exclude": [
|
||||||
|
"**/node_modules/*",
|
||||||
|
"dist",
|
||||||
|
"@types",
|
||||||
|
"*.test.ts",
|
||||||
|
"*.config.ts",
|
||||||
|
"*.browser.config.ts"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
32
packages/api/vite.browser.config.ts
Normal file
32
packages/api/vite.browser.config.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import peggyLoader from 'vite-plugin-peggy-loader';
|
||||||
|
|
||||||
|
const distDir = path.resolve(__dirname, 'dist');
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
target: 'esnext',
|
||||||
|
outDir: distDir,
|
||||||
|
emptyOutDir: false,
|
||||||
|
sourcemap: true,
|
||||||
|
lib: {
|
||||||
|
entry: path.resolve(__dirname, 'index.web.ts'),
|
||||||
|
formats: ['es'],
|
||||||
|
fileName: () => 'browser.js',
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: [
|
||||||
|
// These are browser APIs provided by the environment
|
||||||
|
/^node:/,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [peggyLoader()],
|
||||||
|
resolve: {
|
||||||
|
// Default extensions — picks up browser implementations (index.ts)
|
||||||
|
// instead of .api.ts (which resolves to Node.js/Electron code)
|
||||||
|
extensions: ['.js', '.ts', '.tsx', '.json'],
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user