ee-core 5.0.0-beta.8 → 5.0.1

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.
package/README.md CHANGED
@@ -4,7 +4,7 @@ Enterprise-grade Electron application framework core — TypeScript edition with
4
4
 
5
5
  ## Overview
6
6
 
7
- `ee-core` provides the runtime foundation for [electron-egg](https://github.com/wallace5303/electron-egg) applications. It handles the complete lifecycle from boot to shutdown: configuration loading, controller registration, IPC communication, window management, logging, storage, background jobs, and cross-process coordination.
7
+ `ee-core` is the runtime foundation for [electron-egg](https://github.com/wallace5303/electron-egg) applications. It handles the complete lifecycle from boot to shutdown: configuration loading, controller registration, IPC communication, window management, logging, storage, background jobs, and cross-process coordination.
8
8
 
9
9
  The package outputs dual module formats (CJS + ESM) via conditional exports in `package.json`, making it compatible with both `require()` and `import` environments.
10
10
 
@@ -19,13 +19,13 @@ npm install ee-core
19
19
  ee-core exposes fine-grained subpath modules. Each can be imported individually:
20
20
 
21
21
  ```ts
22
- // Main entry (boot, app, config, etc.)
22
+ // Main entry (boot, app, config, events, etc.)
23
23
  import { ElectronEgg } from 'ee-core';
24
24
 
25
25
  // Specific submodules
26
26
  import { ControllerLoader } from 'ee-core/controller';
27
27
  import { Cross, cross } from 'ee-core/cross';
28
- import { extend } from 'ee-core/utils';
28
+ import { extend, is } from 'ee-core/utils';
29
29
  import { SqliteStorage } from 'ee-core/storage';
30
30
  import { ChildJob, ChildPoolJob, LoadBalancer } from 'ee-core/jobs';
31
31
  import type { Config, DevConfig } from 'ee-core/types';
@@ -35,51 +35,88 @@ Available subpaths:
35
35
 
36
36
  | Subpath | Description |
37
37
  |---|---|
38
- | `ee-core` | Main entry — boot, application, config, events |
39
- | `ee-core/app` | Application lifecycle and event bus |
38
+ | `ee-core` | Main entry — boot, application, config, events, all modules |
39
+ | `ee-core/app` | Application lifecycle, event bus, directory init |
40
40
  | `ee-core/config` | Configuration loading and merging |
41
+ | `ee-core/const` | IPC channel and event constants |
41
42
  | `ee-core/controller` | Controller loader and registry |
42
- | `ee-core/core` | FileLoader and core utilities |
43
- | `ee-core/cross` | IPC communication (socket.io, HTTP, Electron IPC) |
43
+ | `ee-core/core` | FileLoader, Timing, core utilities |
44
+ | `ee-core/cross` | External process management (Go/Python backends) |
44
45
  | `ee-core/electron` | Electron app/window management |
45
- | `ee-core/exception` | Exception handling |
46
- | `ee-core/html` | HTML static resource path utility |
46
+ | `ee-core/exception` | Global exception handling (uncaught/unhandled) |
47
+ | `ee-core/html` | Static HTML page path utility (failure pages) |
47
48
  | `ee-core/jobs` | Background jobs (ChildJob, ChildPoolJob, LoadBalancer) |
48
49
  | `ee-core/loader` | File/module loading utilities |
49
- | `ee-core/log` | Pino-based logging (pino-roll + pino-pretty) |
50
- | `ee-core/message` | IPC message routing |
51
- | `ee-core/ps` | Process/environment utilities (paths, env detection) |
52
- | `ee-core/socket` | Socket.IO, HTTP, IPC servers |
50
+ | `ee-core/log` | Pino logging (pino-roll + pino-pretty) |
51
+ | `ee-core/message` | Child process IPC message routing |
52
+ | `ee-core/ps` | Process state, environment detection, path utilities |
53
+ | `ee-core/socket` | Socket.IO, HTTP (Koa), IPC servers |
53
54
  | `ee-core/storage` | SQLite storage (better-sqlite3) |
54
55
  | `ee-core/types` | TypeScript type definitions |
55
- | `ee-core/utils` | extend, is, json, helper, pargv, port |
56
+ | `ee-core/utils` | extend, is, json, wrap, helper, pargv, port, ip |
56
57
 
57
58
  ## Architecture
58
59
 
59
60
  ### Lifecycle
60
61
 
61
- Boot loadConfig loadLog loadDir → loadController → loadSocket → loadElectron
62
+ The `ElectronEgg` startup sequence is strictly ordered:
63
+
64
+ ```
65
+ init() → loadException → loadConfig → loadDir → loadLog
66
+ run() → loadController → loadSocket → emitLifecycle(Ready) → loadElectron
67
+ ```
68
+
69
+ Exception handling must register first to catch subsequent errors; config is the foundation for all modules; directories must exist before writing logs; controllers precede communication services; Ready fires after core modules are loaded; Electron starts last.
70
+
71
+ ### Lifecycle Events
72
+
73
+ Five framework milestones managed by `EventBus`:
74
+
75
+ | Event | When |
76
+ |---|---|
77
+ | `Ready` | Core modules loaded, before Electron |
78
+ | `ElectronAppReady` | `app.whenReady()` completed |
79
+ | `WindowReady` | BrowserWindow created |
80
+ | `BeforeClose` | Window close triggered |
81
+ | `Preload` | Preload scripts executing |
82
+
83
+ Register handlers via `app.register(eventName, handler)` or custom events via `eventBus.on()/emit()`.
62
84
 
63
85
  ### Controller Loading Pipeline
64
86
 
65
- - **Build time** (ee-bin): `controllerRegistryPlugin` scans `electron/controller/`, generates `ee-core:controller-registry` virtual module with lazy getters.
66
- - **Runtime** (ee-core): If `globalThis.__EE_CONTROLLER_REGISTRY__` exists (bundle mode), loads from registry. Otherwise falls back to filesystem scanning via globby.
87
+ - **Build time** (ee-bin): `bundleRegistryPlugin` scans `electron/controller/`, computes property paths (`defaultCamelize` with `caseStyle: 'lower'`), generates `app:controller-registry` virtual module setting `global.__EE_CONTROLLER_REGISTRY__` with lazy getters (`get module() { return require(...) }`).
88
+ - **Bundle entry** (`app:bundle-entry`): loads config registry controller registry real `main.js`.
89
+ - **Runtime** (ee-core): If `globalThis.__EE_CONTROLLER_REGISTRY__` exists (bundle mode), `FileLoader.parseFromRegistry()` reads from it. Otherwise, falls back to filesystem scanning via `scanDirSync()`.
90
+
91
+ ### Configuration Loading Pipeline
92
+
93
+ Same dual-mode pattern as controllers:
94
+
95
+ - **Build time** (ee-bin): `bundleRegistryPlugin` scans `electron/config/`, generates `app:config-registry` virtual module.
96
+ - **Runtime** (ee-core): If `globalThis.__EE_CONFIG_REGISTRY__` exists, `ConfigLoader._loadConfig()` loads by filename. Otherwise, reads from filesystem using `loadFile()`.
67
97
 
68
- ### IPC Communication
98
+ Config layering (dev mode only): `config.default.js` → `config.local.js` / `config.prod.js`, merged by `ConfigLoader`.
69
99
 
70
- Main renderer via `ee-core/cross`, supporting three transport modes:
71
- - Socket.IO (bidirectional real-time)
72
- - HTTP server (RESTful)
73
- - Electron IPC (native)
100
+ ### Communication Services
74
101
 
75
- Channels follow pattern `controller/{name}/{method}`.
102
+ Three channels created in order during `loadSocket()`:
103
+
104
+ | Server | Use Case | Implementation |
105
+ |---|---|---|
106
+ | `SocketServer` | Third-party process communication (Go/Python) | Socket.IO |
107
+ | `HttpServer` | RESTful API for external HTTP clients | Koa + middleware |
108
+ | `IpcServer` | Main ↔ renderer process | `ipcMain.handle/on` + `ipcRenderer.invoke/send` |
109
+
110
+ All share `resolveControllerFn()` routing — channel pattern: `controller/{name}/{method}`.
76
111
 
77
112
  ### Window Loading Strategy
78
113
 
79
- - Remote mode Load remote URL
80
- - Dev mode → Wait for frontend dev server, show loading page first
81
- - Prod + cross takeover Wait for cross-process service
82
- - Prod (default) Load local HTML file
114
+ `loadServer()` selects strategy based on config and environment:
115
+
116
+ 1. **Remote mode** (`remote.enable=true`)Load remote URL
117
+ 2. **Dev mode** → Poll frontend dev server (`waitForUrl`), show loading page first
118
+ 3. **Prod + cross takeover** → Wait for cross-process service to be ready
119
+ 4. **Prod (default)** → Load local HTML file
83
120
 
84
121
  ## Key APIs
85
122
 
@@ -89,7 +126,10 @@ Channels follow pattern `controller/{name}/{method}`.
89
126
  import { ElectronEgg } from 'ee-core';
90
127
 
91
128
  // Start the framework
92
- const app = new ElectronEgg();
129
+ const boot = new ElectronEgg();
130
+
131
+ // Async startup (ESM)
132
+ await boot.runAsync();
93
133
  ```
94
134
 
95
135
  ### Configuration
@@ -98,32 +138,83 @@ const app = new ElectronEgg();
98
138
  import { getConfig, setConfig } from 'ee-core/config';
99
139
 
100
140
  const config = getConfig();
141
+
142
+ // Child processes can receive config without filesystem access
143
+ setConfig(config);
101
144
  ```
102
145
 
103
146
  ### Controller
104
147
 
105
148
  ```ts
106
- import { getController } from 'ee-core/controller';
149
+ import { getController, getControllers } from 'ee-core/controller';
107
150
 
151
+ // Get specific controller
108
152
  const userController = getController('user');
153
+
154
+ // Get all loaded controllers
155
+ const all = getControllers();
109
156
  ```
110
157
 
111
158
  ### Cross-Process Communication
112
159
 
113
160
  ```ts
114
161
  import { cross } from 'ee-core/cross';
162
+ import type { CrossTargetConfig } from 'ee-core';
163
+
164
+ // Run Go backend with custom config
165
+ const opt: CrossTargetConfig = {
166
+ name: 'goapp',
167
+ cmd: path.join(getExtraResourcesDir(), 'goapp'),
168
+ directory: getExtraResourcesDir(),
169
+ args: ['--port=7073'],
170
+ appExit: true,
171
+ };
172
+ const entity = await cross.run('go', opt);
173
+
174
+ // Get service URL
175
+ const url = cross.getUrl('goapp');
176
+
177
+ // Kill by name
178
+ cross.killByName('goapp');
179
+ ```
180
+
181
+ ### Communication Servers
115
182
 
116
- // Send IPC message to renderer
117
- cross.sendToRenderer('controller/user/info', data);
183
+ ```ts
184
+ import { getSocketServer, getHttpServer, getIpcServer } from 'ee-core/socket';
185
+
186
+ // All getters return non-null instances after Ready event
187
+ const socket = getSocketServer();
188
+ const http = getHttpServer();
189
+ const ipc = getIpcServer();
190
+ ```
191
+
192
+ ### Main Window
193
+
194
+ ```ts
195
+ import { getMainWindow } from 'ee-core/electron';
196
+
197
+ // Returns BrowserWindow (non-null) after WindowReady event
198
+ const win = getMainWindow();
199
+ win.setMenuBarVisibility(false);
118
200
  ```
119
201
 
120
202
  ### Jobs
121
203
 
122
204
  ```ts
123
- import { ChildJob, ChildPoolJob, LoadBalancer } from 'ee-core/jobs';
205
+ import { ChildJob, ChildPoolJob, LoadBalancer, AlgorithmType } from 'ee-core/jobs';
124
206
 
207
+ // Single task execution
125
208
  const job = new ChildJob();
126
- const result = await job.exec({ name: 'task', script: './jobs/demo.js' });
209
+ const result = await job.exec('./jobs/demo.js', { taskName: 'cleanup' });
210
+
211
+ // Process pool with load balancing
212
+ const pool = new ChildPoolJob();
213
+ pool.create(3); // Create 3 workers
214
+ const result = await pool.run('./jobs/demo.js', { taskName: 'batch' });
215
+
216
+ // 8 algorithms: polling, weights, random, specify, weightsPolling,
217
+ // weightsRandom, minimumConnection, weightsMinimumConnection
127
218
  ```
128
219
 
129
220
  ### Storage
@@ -131,28 +222,99 @@ const result = await job.exec({ name: 'task', script: './jobs/demo.js' });
131
222
  ```ts
132
223
  import { SqliteStorage } from 'ee-core/storage';
133
224
 
134
- const db = new SqliteStorage('./data/app.db');
135
- db.prepare('CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT)').run();
225
+ // Four modes: memory, onlyName, relative, absolute
226
+ const db = new SqliteStorage({ mode: 'onlyName', name: 'app' });
136
227
  ```
137
228
 
138
229
  ### Logging
139
230
 
140
231
  ```ts
141
- import { coreLogger, getLoggers } from 'ee-core/log';
232
+ import { logger, coreLogger } from 'ee-core/log';
233
+
234
+ // Supports three call styles: pino standard, pino printf, concatenation
235
+ logger.info('Application started');
236
+ logger.info('User %s logged in', 'admin');
237
+ logger.info('data:', { id: 1, name: 'test' });
142
238
 
143
- coreLogger.info('Application started');
239
+ // Log files: ee.log, ee-core.log, ee-error.log
240
+ // Rotation: daily/hourly via pino-roll
241
+ // Dev mode: pino-pretty for terminal output
144
242
  ```
145
243
 
146
244
  ### Process/Environment
147
245
 
148
246
  ```ts
149
- import { isDev, getBaseDir, env } from 'ee-core/ps';
247
+ import { isDev, isProd, getBaseDir, getDataDir, getLogDir } from 'ee-core/ps';
248
+ import { is } from 'ee-core/utils';
150
249
 
151
250
  if (isDev()) {
152
251
  // Development-specific logic
153
252
  }
253
+
254
+ // Platform detection
255
+ if (is.macOS()) { /* macOS */ }
256
+ if (is.windows()) { /* Windows */ }
257
+ if (is.linux()) { /* Linux */ }
258
+ if (is.openharmony()) { /* OpenHarmony */ }
259
+
260
+ // Path utilities
261
+ const baseDir = getBaseDir();
262
+ const dataDir = getDataDir();
263
+ const logDir = getLogDir();
264
+ const extraRes = getExtraResourcesDir();
265
+ ```
266
+
267
+ ### Event Bus
268
+
269
+ ```ts
270
+ import { eventBus, BeforeClose } from 'ee-core/app';
271
+
272
+ // Register lifecycle hook
273
+ app.register(BeforeClose, async () => {
274
+ // Cleanup before app closes
275
+ });
276
+
277
+ // Custom events
278
+ eventBus.on('myEvent', (data) => { /* handle */ });
279
+ eventBus.emit('myEvent', { key: 'value' });
280
+ ```
281
+
282
+ ### Exception Handling
283
+
284
+ ```ts
285
+ // Auto-registered during boot. Controls exit behavior:
286
+ // exception.mainExit / childExit / rendererExit
287
+ // Errors logged via coreLogger, dev mode sends to terminal
288
+ ```
289
+
290
+ ### Utility Functions
291
+
292
+ ```ts
293
+ import { extend, strictParse, getPort, parseArgv, sleep } from 'ee-core/utils';
294
+
295
+ // Deep merge with prototype pollution guard
296
+ const merged = extend(true, {}, defaults, userConfig);
297
+
298
+ // Port allocation with two-level locking
299
+ const port = await getPort({ port: 7070 });
300
+
301
+ // CLI argument parser
302
+ const args = parseArgv(process.argv);
303
+
304
+ // Sync sleep (Atomics.wait-based, no subprocess)
305
+ sleep(1000);
154
306
  ```
155
307
 
308
+ ## TypeScript Types
309
+
310
+ All types are exported from `ee-core/types`:
311
+
312
+ ```ts
313
+ import type { Config, CrossTargetConfig, DevConfig, AppInfo } from 'ee-core/types';
314
+ ```
315
+
316
+ Key type interfaces: `ElectronEggOptions`, `Config`, `AppInfo`, `CrossTargetConfig`, `CrossRunOptions`, `LoggerConfig`, `ExceptionConfig`, `FileLoaderOptions`, `LoadBalancerOptions`, `JobProcessOptions`, `MessageData`.
317
+
156
318
  ## Build
157
319
 
158
320
  ```bash
@@ -161,10 +323,21 @@ npm run build:cjs # Build CommonJS only
161
323
  npm run build:esm # Build ESM only
162
324
  npm run typecheck # TypeScript type checking
163
325
  npm run test # Run vitest
326
+ npm run test:watch # Run vitest in watch mode
164
327
  ```
165
328
 
166
329
  The `exports` map in `package.json` is auto-generated by `scripts/gen-exports.js`. Do not edit manually — run `npm run gen-exports` after adding new subpath modules.
167
330
 
331
+ ## Debug Logging
332
+
333
+ ee-core uses the `debug` library for verbose namespace-scoped logging. Enable to see runtime internals (config merging, controller loading, module resolution):
334
+
335
+ ```bash
336
+ DEBUG=ee-* node your-app # All ee-* namespaces
337
+ DEBUG=ee-core:config:* node your-app # Config subsystem only
338
+ DEBUG=ee-core:controller:* node your-app # Controller loading only
339
+ ```
340
+
168
341
  ## Requirements
169
342
 
170
343
  - Node.js >= 20.19.0
@@ -174,5 +347,6 @@ The `exports` map in `package.json` is auto-generated by `scripts/gen-exports.js
174
347
  ## Notes
175
348
 
176
349
  - ESM imports in ee-core source must include `.js` extensions (required by `module: NodeNext`)
177
- - ee-core is NOT bundled into the Electron main process bundle — it's an esbuild external loaded from `node_modules` at runtime
178
- - The framework uses the `debug` library for verbose logging. Enable with `DEBUG=ee-*` environment variable
350
+ - ee-core is NOT bundled into the Electron main process bundle — it's an esbuild external loaded from `node_modules` at runtime. This allows `child_process.fork()` to find `app.js` as a real disk file
351
+ - `getMainWindow()`, `getSocketServer()`, `getHttpServer()`, `getIpcServer()` return non-null instances. If called before the corresponding lifecycle event, they throw an Error indicating a lifecycle ordering bug
352
+ - The `exports` map is auto-generated — run `npm run gen-exports` after adding new modules
@@ -55,7 +55,7 @@ class JobProcess {
55
55
  processOptions: {
56
56
  cwd,
57
57
  env: (0, index_js_2.allEnv)(),
58
- stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
58
+ stdio: ['ignore', 'pipe', 'pipe', 'ipc']
59
59
  },
60
60
  };
61
61
  const options = (0, extend_js_1.extend)(true, defaultOptions, opt);
@@ -1,2 +1,17 @@
1
+ /**
2
+ * @module storage
3
+ * @description Data storage module entry point. Provides SqliteStorage for SQLite database operations.
4
+ *
5
+ * SqliteStorage class is exported statically — loading this module only imports built-in
6
+ * Node.js modules (assert, fs, path), NOT better-sqlite3. The native better-sqlite3 binding
7
+ * is only loaded when `SqliteStorage.init()` is called, via dynamic import().
8
+ *
9
+ * Usage:
10
+ * ```ts
11
+ * import { SqliteStorage } from 'ee-core/storage';
12
+ * const db = new SqliteStorage('myapp.db');
13
+ * await db.init(); // ← here better-sqlite3 is actually loaded
14
+ * ```
15
+ */
1
16
  export { SqliteStorage } from './sqliteStorage.js';
2
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,6 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqliteStorage = void 0;
4
+ /**
5
+ * @module storage
6
+ * @description Data storage module entry point. Provides SqliteStorage for SQLite database operations.
7
+ *
8
+ * SqliteStorage class is exported statically — loading this module only imports built-in
9
+ * Node.js modules (assert, fs, path), NOT better-sqlite3. The native better-sqlite3 binding
10
+ * is only loaded when `SqliteStorage.init()` is called, via dynamic import().
11
+ *
12
+ * Usage:
13
+ * ```ts
14
+ * import { SqliteStorage } from 'ee-core/storage';
15
+ * const db = new SqliteStorage('myapp.db');
16
+ * await db.init(); // ← here better-sqlite3 is actually loaded
17
+ * ```
18
+ */
4
19
  var sqliteStorage_js_1 = require("./sqliteStorage.js");
5
20
  Object.defineProperty(exports, "SqliteStorage", { enumerable: true, get: function () { return sqliteStorage_js_1.SqliteStorage; } });
6
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA,uDAAmD;AAA1C,iHAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;GAcG;AACH,uDAAmD;AAA1C,iHAAA,aAAa,OAAA"}
@@ -1,4 +1,4 @@
1
- import Database from 'better-sqlite3';
1
+ import type Database from 'better-sqlite3';
2
2
  /**
3
3
  * SqliteStorage - SQLite database storage class
4
4
  *
@@ -15,6 +15,12 @@ import Database from 'better-sqlite3';
15
15
  * Security:
16
16
  * The constructor validates the database name for path traversal, disallowing ".." in the name
17
17
  * to prevent malicious input from accessing files outside the intended directory.
18
+ *
19
+ * Lazy loading:
20
+ * better-sqlite3 is a native module that requires electron-rebuild for Electron.
21
+ * The constructor only computes paths (synchronous). The `init()` method lazily imports
22
+ * better-sqlite3 and opens the database connection. Projects that don't use SQLite
23
+ * never load the native binding.
18
24
  */
19
25
  export declare class SqliteStorage {
20
26
  /** Database name (original input value) */
@@ -25,42 +31,36 @@ export declare class SqliteStorage {
25
31
  dbDir: string;
26
32
  /** Database filename (only the filename part, excluding directory) */
27
33
  fileName: string;
28
- /** better-sqlite3 database instance */
34
+ /** better-sqlite3 database instance (set after init()) */
29
35
  db: Database.Database;
30
36
  /**
31
- * Create a SqliteStorage instance
37
+ * Create a SqliteStorage instance (path computation only, DB not yet opened)
32
38
  *
33
- * Initialization flow:
34
- * 1. Validate that the name is non-empty and does not contain path traversal characters ".."
35
- * 2. Infer storage mode from the name (getMode)
36
- * 3. Create the database file directory (_createDatabaseDir)
37
- * 4. Extract the filename part (_formatFileName)
38
- * 5. Open the database connection (_initDB)
39
+ * The constructor only validates the name, infers the storage mode, computes paths,
40
+ * and creates the database directory. It does NOT open the database connection
41
+ * call `init()` to lazily load better-sqlite3 and open the DB.
39
42
  *
40
43
  * @param name - Database name or path. Supports the following formats:
41
44
  * - ":memory:" - In-memory database
42
45
  * - "app.db" - Filename only, stored under {dataDir}/db/
43
46
  * - "sub/app.db" - Relative path, relative to {dataDir}/db/
44
47
  * - "/tmp/app.db" - Absolute path
45
- * @param opt - better-sqlite3 database options, defaults merged with timeout: 5000
46
48
  * @throws Asserts error if name is empty or contains ".." path traversal characters
47
49
  */
48
- constructor(name: string, opt?: Record<string, unknown>);
50
+ constructor(name: string);
49
51
  /**
50
52
  * Initialize the database connection
51
53
  *
52
- * Determines the database path based on storage mode:
53
- * - memory mode: Uses ":memory:" as the path, better-sqlite3 creates the database in memory
54
- * - file mode: Uses getFilePath() to get the full database file path
54
+ * Lazily imports better-sqlite3 via dynamic import() and opens the database.
55
+ * This is the only point where the native .node binding is loaded.
55
56
  *
56
- * In file mode, additionally validates that the database file was created successfully.
57
- * If the file does not exist, throws an assertion error (possibly due to insufficient directory permissions, etc.).
57
+ * Must be called after construction before using `this.db`.
58
58
  *
59
59
  * @param opt - better-sqlite3 database options, defaults merged with { timeout: 5000 }
60
- * @returns better-sqlite3 Database instance
60
+ * @returns this SqliteStorage instance (for chaining: `const db = await new SqliteStorage('app.db').init()`)
61
61
  * @throws Asserts error if the database file was not created successfully in file mode
62
62
  */
63
- _initDB(opt?: Record<string, unknown>): Database.Database;
63
+ init(opt?: Record<string, unknown>): Promise<this>;
64
64
  /**
65
65
  * Extract the database filename
66
66
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sqliteStorage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"AA6BA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IAEb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IAEb,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IAEjB,uCAAuC;IACvC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAEtB;;;;;;;;;;;;;;;;;OAiBG;gBACS,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAY3D;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,QAAQ,CAAC,QAAQ;IAmB7D;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOrC;;;;;;;;;;;OAWG;IACH,kBAAkB,IAAI,MAAM;IAc5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe7B;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;;OAOG;IACH,WAAW,IAAI,MAAM;CAGtB"}
1
+ {"version":3,"file":"sqliteStorage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAa;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IAEb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IAEb,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IAEjB,0DAA0D;IAC1D,EAAE,EAAG,QAAQ,CAAC,QAAQ,CAAC;IAEvB;;;;;;;;;;;;;OAaG;gBACS,IAAI,EAAE,MAAM;IAWxB;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB5D;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOrC;;;;;;;;;;;OAWG;IACH,kBAAkB,IAAI,MAAM;IAc5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe7B;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;;OAOG;IACH,WAAW,IAAI,MAAM;CAGtB"}
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -15,25 +48,32 @@ exports.SqliteStorage = void 0;
15
48
  * - Prevent path traversal attacks (validates that ".." is not present in the name during construction)
16
49
  * - Provide a unified interface for obtaining database file paths
17
50
  *
51
+ * better-sqlite3 is lazily imported — only loaded when `init()` is called to open the database.
52
+ * This avoids loading the native .node binding at module import time, which would happen unconditionally
53
+ * even if the consumer never uses SQLite.
54
+ *
18
55
  * Usage examples:
19
56
  * ```ts
20
57
  * // Name-only mode: file stored at {dataDir}/db/{name}.db
21
58
  * const db1 = new SqliteStorage('myapp.db');
59
+ * await db1.init();
22
60
  *
23
61
  * // Relative path mode: file stored at {dataDir}/db/sub/myapp.db
24
62
  * const db2 = new SqliteStorage('sub/myapp.db');
63
+ * await db2.init();
25
64
  *
26
65
  * // Absolute path mode: file stored at the specified path
27
66
  * const db3 = new SqliteStorage('/tmp/data/myapp.db');
67
+ * await db3.init();
28
68
  *
29
69
  * // In-memory mode: not persisted, data is lost when the process exits
30
70
  * const db4 = new SqliteStorage(':memory:');
71
+ * await db4.init();
31
72
  * ```
32
73
  */
33
74
  const assert_1 = __importDefault(require("assert"));
34
75
  const fs_1 = __importDefault(require("fs"));
35
76
  const path_1 = __importDefault(require("path"));
36
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
37
77
  const helper_js_1 = require("../utils/helper.js");
38
78
  const index_js_1 = require("../ps/index.js");
39
79
  /**
@@ -52,27 +92,29 @@ const index_js_1 = require("../ps/index.js");
52
92
  * Security:
53
93
  * The constructor validates the database name for path traversal, disallowing ".." in the name
54
94
  * to prevent malicious input from accessing files outside the intended directory.
95
+ *
96
+ * Lazy loading:
97
+ * better-sqlite3 is a native module that requires electron-rebuild for Electron.
98
+ * The constructor only computes paths (synchronous). The `init()` method lazily imports
99
+ * better-sqlite3 and opens the database connection. Projects that don't use SQLite
100
+ * never load the native binding.
55
101
  */
56
102
  class SqliteStorage {
57
103
  /**
58
- * Create a SqliteStorage instance
104
+ * Create a SqliteStorage instance (path computation only, DB not yet opened)
59
105
  *
60
- * Initialization flow:
61
- * 1. Validate that the name is non-empty and does not contain path traversal characters ".."
62
- * 2. Infer storage mode from the name (getMode)
63
- * 3. Create the database file directory (_createDatabaseDir)
64
- * 4. Extract the filename part (_formatFileName)
65
- * 5. Open the database connection (_initDB)
106
+ * The constructor only validates the name, infers the storage mode, computes paths,
107
+ * and creates the database directory. It does NOT open the database connection
108
+ * call `init()` to lazily load better-sqlite3 and open the DB.
66
109
  *
67
110
  * @param name - Database name or path. Supports the following formats:
68
111
  * - ":memory:" - In-memory database
69
112
  * - "app.db" - Filename only, stored under {dataDir}/db/
70
113
  * - "sub/app.db" - Relative path, relative to {dataDir}/db/
71
114
  * - "/tmp/app.db" - Absolute path
72
- * @param opt - better-sqlite3 database options, defaults merged with timeout: 5000
73
115
  * @throws Asserts error if name is empty or contains ".." path traversal characters
74
116
  */
75
- constructor(name, opt = {}) {
117
+ constructor(name) {
76
118
  (0, assert_1.default)(name, `db name ${name} Cannot be empty`);
77
119
  // Prevent path traversal attacks: disallow ".." in the name to avoid directory backtracking
78
120
  (0, assert_1.default)(!name.includes('..'), `db name ${name} contains path traversal`);
@@ -80,35 +122,36 @@ class SqliteStorage {
80
122
  this.mode = this.getMode(name);
81
123
  this.dbDir = this._createDatabaseDir();
82
124
  this.fileName = this._formatFileName(name);
83
- this.db = this._initDB(opt);
84
125
  }
85
126
  /**
86
127
  * Initialize the database connection
87
128
  *
88
- * Determines the database path based on storage mode:
89
- * - memory mode: Uses ":memory:" as the path, better-sqlite3 creates the database in memory
90
- * - file mode: Uses getFilePath() to get the full database file path
129
+ * Lazily imports better-sqlite3 via dynamic import() and opens the database.
130
+ * This is the only point where the native .node binding is loaded.
91
131
  *
92
- * In file mode, additionally validates that the database file was created successfully.
93
- * If the file does not exist, throws an assertion error (possibly due to insufficient directory permissions, etc.).
132
+ * Must be called after construction before using `this.db`.
94
133
  *
95
134
  * @param opt - better-sqlite3 database options, defaults merged with { timeout: 5000 }
96
- * @returns better-sqlite3 Database instance
135
+ * @returns this SqliteStorage instance (for chaining: `const db = await new SqliteStorage('app.db').init()`)
97
136
  * @throws Asserts error if the database file was not created successfully in file mode
98
137
  */
99
- _initDB(opt = {}) {
138
+ async init(opt = {}) {
139
+ // Lazy import: better-sqlite3 is only loaded when actually needed.
140
+ // This avoids loading the native .node binding at module import time.
141
+ // better-sqlite3 is a CJS package; dynamic import() resolves it correctly.
142
+ const { default: Database } = await Promise.resolve().then(() => __importStar(require('better-sqlite3')));
100
143
  const options = Object.assign({ timeout: 5000 }, opt);
101
144
  // Storage type: db file, in-memory (:memory:)
102
145
  let dbPath = this.name;
103
146
  if (this.mode !== 'memory') {
104
147
  dbPath = this.getFilePath();
105
148
  }
106
- const db = new better_sqlite3_1.default(dbPath, options);
149
+ this.db = new Database(dbPath, options);
107
150
  // For file mode, check if the file was created successfully
108
151
  if (this.mode !== 'memory') {
109
152
  (0, assert_1.default)(fs_1.default.existsSync(dbPath), `error: db ${dbPath} not exists`);
110
153
  }
111
- return db;
154
+ return this;
112
155
  }
113
156
  /**
114
157
  * Extract the database filename
@@ -1 +1 @@
1
- {"version":3,"file":"sqliteStorage.js","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqliteStorage.js","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"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"}
@@ -55,7 +55,7 @@ class JobProcess {
55
55
  processOptions: {
56
56
  cwd,
57
57
  env: (0, index_js_2.allEnv)(),
58
- stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
58
+ stdio: ['ignore', 'pipe', 'pipe', 'ipc']
59
59
  },
60
60
  };
61
61
  const options = (0, extend_js_1.extend)(true, defaultOptions, opt);
@@ -1,2 +1,17 @@
1
+ /**
2
+ * @module storage
3
+ * @description Data storage module entry point. Provides SqliteStorage for SQLite database operations.
4
+ *
5
+ * SqliteStorage class is exported statically — loading this module only imports built-in
6
+ * Node.js modules (assert, fs, path), NOT better-sqlite3. The native better-sqlite3 binding
7
+ * is only loaded when `SqliteStorage.init()` is called, via dynamic import().
8
+ *
9
+ * Usage:
10
+ * ```ts
11
+ * import { SqliteStorage } from 'ee-core/storage';
12
+ * const db = new SqliteStorage('myapp.db');
13
+ * await db.init(); // ← here better-sqlite3 is actually loaded
14
+ * ```
15
+ */
1
16
  export { SqliteStorage } from './sqliteStorage.js';
2
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,6 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqliteStorage = void 0;
4
+ /**
5
+ * @module storage
6
+ * @description Data storage module entry point. Provides SqliteStorage for SQLite database operations.
7
+ *
8
+ * SqliteStorage class is exported statically — loading this module only imports built-in
9
+ * Node.js modules (assert, fs, path), NOT better-sqlite3. The native better-sqlite3 binding
10
+ * is only loaded when `SqliteStorage.init()` is called, via dynamic import().
11
+ *
12
+ * Usage:
13
+ * ```ts
14
+ * import { SqliteStorage } from 'ee-core/storage';
15
+ * const db = new SqliteStorage('myapp.db');
16
+ * await db.init(); // ← here better-sqlite3 is actually loaded
17
+ * ```
18
+ */
4
19
  var sqliteStorage_js_1 = require("./sqliteStorage.js");
5
20
  Object.defineProperty(exports, "SqliteStorage", { enumerable: true, get: function () { return sqliteStorage_js_1.SqliteStorage; } });
6
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA,uDAAmD;AAA1C,iHAAA,aAAa,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;GAcG;AACH,uDAAmD;AAA1C,iHAAA,aAAa,OAAA"}
@@ -1,4 +1,4 @@
1
- import Database from 'better-sqlite3';
1
+ import type Database from 'better-sqlite3';
2
2
  /**
3
3
  * SqliteStorage - SQLite database storage class
4
4
  *
@@ -15,6 +15,12 @@ import Database from 'better-sqlite3';
15
15
  * Security:
16
16
  * The constructor validates the database name for path traversal, disallowing ".." in the name
17
17
  * to prevent malicious input from accessing files outside the intended directory.
18
+ *
19
+ * Lazy loading:
20
+ * better-sqlite3 is a native module that requires electron-rebuild for Electron.
21
+ * The constructor only computes paths (synchronous). The `init()` method lazily imports
22
+ * better-sqlite3 and opens the database connection. Projects that don't use SQLite
23
+ * never load the native binding.
18
24
  */
19
25
  export declare class SqliteStorage {
20
26
  /** Database name (original input value) */
@@ -25,42 +31,36 @@ export declare class SqliteStorage {
25
31
  dbDir: string;
26
32
  /** Database filename (only the filename part, excluding directory) */
27
33
  fileName: string;
28
- /** better-sqlite3 database instance */
34
+ /** better-sqlite3 database instance (set after init()) */
29
35
  db: Database.Database;
30
36
  /**
31
- * Create a SqliteStorage instance
37
+ * Create a SqliteStorage instance (path computation only, DB not yet opened)
32
38
  *
33
- * Initialization flow:
34
- * 1. Validate that the name is non-empty and does not contain path traversal characters ".."
35
- * 2. Infer storage mode from the name (getMode)
36
- * 3. Create the database file directory (_createDatabaseDir)
37
- * 4. Extract the filename part (_formatFileName)
38
- * 5. Open the database connection (_initDB)
39
+ * The constructor only validates the name, infers the storage mode, computes paths,
40
+ * and creates the database directory. It does NOT open the database connection
41
+ * call `init()` to lazily load better-sqlite3 and open the DB.
39
42
  *
40
43
  * @param name - Database name or path. Supports the following formats:
41
44
  * - ":memory:" - In-memory database
42
45
  * - "app.db" - Filename only, stored under {dataDir}/db/
43
46
  * - "sub/app.db" - Relative path, relative to {dataDir}/db/
44
47
  * - "/tmp/app.db" - Absolute path
45
- * @param opt - better-sqlite3 database options, defaults merged with timeout: 5000
46
48
  * @throws Asserts error if name is empty or contains ".." path traversal characters
47
49
  */
48
- constructor(name: string, opt?: Record<string, unknown>);
50
+ constructor(name: string);
49
51
  /**
50
52
  * Initialize the database connection
51
53
  *
52
- * Determines the database path based on storage mode:
53
- * - memory mode: Uses ":memory:" as the path, better-sqlite3 creates the database in memory
54
- * - file mode: Uses getFilePath() to get the full database file path
54
+ * Lazily imports better-sqlite3 via dynamic import() and opens the database.
55
+ * This is the only point where the native .node binding is loaded.
55
56
  *
56
- * In file mode, additionally validates that the database file was created successfully.
57
- * If the file does not exist, throws an assertion error (possibly due to insufficient directory permissions, etc.).
57
+ * Must be called after construction before using `this.db`.
58
58
  *
59
59
  * @param opt - better-sqlite3 database options, defaults merged with { timeout: 5000 }
60
- * @returns better-sqlite3 Database instance
60
+ * @returns this SqliteStorage instance (for chaining: `const db = await new SqliteStorage('app.db').init()`)
61
61
  * @throws Asserts error if the database file was not created successfully in file mode
62
62
  */
63
- _initDB(opt?: Record<string, unknown>): Database.Database;
63
+ init(opt?: Record<string, unknown>): Promise<this>;
64
64
  /**
65
65
  * Extract the database filename
66
66
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sqliteStorage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"AA6BA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IAEb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IAEb,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IAEjB,uCAAuC;IACvC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IAEtB;;;;;;;;;;;;;;;;;OAiBG;gBACS,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAY3D;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,QAAQ,CAAC,QAAQ;IAmB7D;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOrC;;;;;;;;;;;OAWG;IACH,kBAAkB,IAAI,MAAM;IAc5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe7B;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;;OAOG;IACH,WAAW,IAAI,MAAM;CAGtB"}
1
+ {"version":3,"file":"sqliteStorage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAa;IACxB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IAEb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IAEb,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;IAEjB,0DAA0D;IAC1D,EAAE,EAAG,QAAQ,CAAC,QAAQ,CAAC;IAEvB;;;;;;;;;;;;;OAaG;gBACS,IAAI,EAAE,MAAM;IAWxB;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB5D;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOrC;;;;;;;;;;;OAWG;IACH,kBAAkB,IAAI,MAAM;IAc5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe7B;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;;;OAOG;IACH,WAAW,IAAI,MAAM;CAGtB"}
@@ -15,25 +15,32 @@ exports.SqliteStorage = void 0;
15
15
  * - Prevent path traversal attacks (validates that ".." is not present in the name during construction)
16
16
  * - Provide a unified interface for obtaining database file paths
17
17
  *
18
+ * better-sqlite3 is lazily imported — only loaded when `init()` is called to open the database.
19
+ * This avoids loading the native .node binding at module import time, which would happen unconditionally
20
+ * even if the consumer never uses SQLite.
21
+ *
18
22
  * Usage examples:
19
23
  * ```ts
20
24
  * // Name-only mode: file stored at {dataDir}/db/{name}.db
21
25
  * const db1 = new SqliteStorage('myapp.db');
26
+ * await db1.init();
22
27
  *
23
28
  * // Relative path mode: file stored at {dataDir}/db/sub/myapp.db
24
29
  * const db2 = new SqliteStorage('sub/myapp.db');
30
+ * await db2.init();
25
31
  *
26
32
  * // Absolute path mode: file stored at the specified path
27
33
  * const db3 = new SqliteStorage('/tmp/data/myapp.db');
34
+ * await db3.init();
28
35
  *
29
36
  * // In-memory mode: not persisted, data is lost when the process exits
30
37
  * const db4 = new SqliteStorage(':memory:');
38
+ * await db4.init();
31
39
  * ```
32
40
  */
33
41
  const assert_1 = __importDefault(require("assert"));
34
42
  const fs_1 = __importDefault(require("fs"));
35
43
  const path_1 = __importDefault(require("path"));
36
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
37
44
  const helper_js_1 = require("../utils/helper.js");
38
45
  const index_js_1 = require("../ps/index.js");
39
46
  /**
@@ -52,27 +59,29 @@ const index_js_1 = require("../ps/index.js");
52
59
  * Security:
53
60
  * The constructor validates the database name for path traversal, disallowing ".." in the name
54
61
  * to prevent malicious input from accessing files outside the intended directory.
62
+ *
63
+ * Lazy loading:
64
+ * better-sqlite3 is a native module that requires electron-rebuild for Electron.
65
+ * The constructor only computes paths (synchronous). The `init()` method lazily imports
66
+ * better-sqlite3 and opens the database connection. Projects that don't use SQLite
67
+ * never load the native binding.
55
68
  */
56
69
  class SqliteStorage {
57
70
  /**
58
- * Create a SqliteStorage instance
71
+ * Create a SqliteStorage instance (path computation only, DB not yet opened)
59
72
  *
60
- * Initialization flow:
61
- * 1. Validate that the name is non-empty and does not contain path traversal characters ".."
62
- * 2. Infer storage mode from the name (getMode)
63
- * 3. Create the database file directory (_createDatabaseDir)
64
- * 4. Extract the filename part (_formatFileName)
65
- * 5. Open the database connection (_initDB)
73
+ * The constructor only validates the name, infers the storage mode, computes paths,
74
+ * and creates the database directory. It does NOT open the database connection
75
+ * call `init()` to lazily load better-sqlite3 and open the DB.
66
76
  *
67
77
  * @param name - Database name or path. Supports the following formats:
68
78
  * - ":memory:" - In-memory database
69
79
  * - "app.db" - Filename only, stored under {dataDir}/db/
70
80
  * - "sub/app.db" - Relative path, relative to {dataDir}/db/
71
81
  * - "/tmp/app.db" - Absolute path
72
- * @param opt - better-sqlite3 database options, defaults merged with timeout: 5000
73
82
  * @throws Asserts error if name is empty or contains ".." path traversal characters
74
83
  */
75
- constructor(name, opt = {}) {
84
+ constructor(name) {
76
85
  (0, assert_1.default)(name, `db name ${name} Cannot be empty`);
77
86
  // Prevent path traversal attacks: disallow ".." in the name to avoid directory backtracking
78
87
  (0, assert_1.default)(!name.includes('..'), `db name ${name} contains path traversal`);
@@ -80,35 +89,36 @@ class SqliteStorage {
80
89
  this.mode = this.getMode(name);
81
90
  this.dbDir = this._createDatabaseDir();
82
91
  this.fileName = this._formatFileName(name);
83
- this.db = this._initDB(opt);
84
92
  }
85
93
  /**
86
94
  * Initialize the database connection
87
95
  *
88
- * Determines the database path based on storage mode:
89
- * - memory mode: Uses ":memory:" as the path, better-sqlite3 creates the database in memory
90
- * - file mode: Uses getFilePath() to get the full database file path
96
+ * Lazily imports better-sqlite3 via dynamic import() and opens the database.
97
+ * This is the only point where the native .node binding is loaded.
91
98
  *
92
- * In file mode, additionally validates that the database file was created successfully.
93
- * If the file does not exist, throws an assertion error (possibly due to insufficient directory permissions, etc.).
99
+ * Must be called after construction before using `this.db`.
94
100
  *
95
101
  * @param opt - better-sqlite3 database options, defaults merged with { timeout: 5000 }
96
- * @returns better-sqlite3 Database instance
102
+ * @returns this SqliteStorage instance (for chaining: `const db = await new SqliteStorage('app.db').init()`)
97
103
  * @throws Asserts error if the database file was not created successfully in file mode
98
104
  */
99
- _initDB(opt = {}) {
105
+ async init(opt = {}) {
106
+ // Lazy import: better-sqlite3 is only loaded when actually needed.
107
+ // This avoids loading the native .node binding at module import time.
108
+ // better-sqlite3 is a CJS package; dynamic import() resolves it correctly.
109
+ const { default: Database } = await import('better-sqlite3');
100
110
  const options = Object.assign({ timeout: 5000 }, opt);
101
111
  // Storage type: db file, in-memory (:memory:)
102
112
  let dbPath = this.name;
103
113
  if (this.mode !== 'memory') {
104
114
  dbPath = this.getFilePath();
105
115
  }
106
- const db = new better_sqlite3_1.default(dbPath, options);
116
+ this.db = new Database(dbPath, options);
107
117
  // For file mode, check if the file was created successfully
108
118
  if (this.mode !== 'memory') {
109
119
  (0, assert_1.default)(fs_1.default.existsSync(dbPath), `error: db ${dbPath} not exists`);
110
120
  }
111
- return db;
121
+ return this;
112
122
  }
113
123
  /**
114
124
  * Extract the database filename
@@ -1 +1 @@
1
- {"version":3,"file":"sqliteStorage.js","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqliteStorage.js","sourceRoot":"","sources":["../../../src/storage/sqliteStorage.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ee-core",
3
- "version": "5.0.0-beta.8",
3
+ "version": "5.0.1",
4
4
  "description": "ee core - TypeScript edition with dual module support",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",