fhir-engine 0.1.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-03-15
9
+
10
+ ### Added
11
+
12
+ - **Core Bootstrap** — `createFhirEngine(config?)` assembles fhir-definition, fhir-runtime, and fhir-persistence into a running system from a single configuration object
13
+ - **Plugin System** — `FhirEnginePlugin` interface with lifecycle hooks (`init` / `start` / `ready` / `stop`), registration-order execution, reverse-order shutdown, and error isolation
14
+ - **Config File Support** — `defineConfig()` type helper, `loadFhirConfig()` auto-discovery (`fhir.config.ts` → `.js` → `.mjs` → `.json`), and environment variable overrides (`FHIR_DATABASE_TYPE`, `FHIR_DATABASE_URL`, `FHIR_PACKAGES_PATH`)
15
+ - **Zero-arg bootstrap** — `createFhirEngine()` with no arguments auto-loads config from cwd
16
+ - **Adapter Factory** — `createAdapter()` supporting `sqlite` (BetterSqlite3Adapter), `sqlite-wasm` (SQLiteAdapter), with clear error for unsupported `postgres`
17
+ - **Logger** — pluggable `Logger` interface with `createConsoleLogger()` default
18
+ - **EngineContext** — shared context object (`config`, `definitions`, `runtime`, `adapter`, `persistence`, `logger`) injected into all plugin hooks
19
+ - **Type exports** — `FhirEngine`, `FhirEngineConfig`, `FhirEnginePlugin`, `EngineContext`, `DatabaseConfig`, `Logger`, and re-exported upstream types
20
+ - **Dual build** — ESM (`.mjs`) + CJS (`.cjs`) with bundled `.d.ts` type declarations
21
+
22
+ ### Known Issues
23
+
24
+ - **PostgreSQL adapter** — `PostgresAdapter` is not exported from `fhir-persistence@0.1.0`; `database.type = 'postgres'` throws a descriptive error
25
+ - **fhir-runtime core JSON** — `fhir-runtime@0.8.x` npm package is missing bundled core definition JSON files; workaround: `preloadCore: false` (applied automatically)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jason fang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # fhir-engine
2
+
3
+ [![npm version](https://img.shields.io/npm/v/fhir-engine.svg)](https://www.npmjs.com/package/fhir-engine)
4
+ [![license](https://img.shields.io/npm/l/fhir-engine.svg)](./LICENSE)
5
+
6
+ **FHIR Runtime Kernel** — Bootstrap and orchestrate the embedded FHIR stack with a single function call.
7
+
8
+ `fhir-engine` assembles [fhir-definition](https://www.npmjs.com/package/fhir-definition), [fhir-runtime](https://www.npmjs.com/package/fhir-runtime), and [fhir-persistence](https://www.npmjs.com/package/fhir-persistence) into a running system from a single configuration object.
9
+
10
+ ## Features
11
+
12
+ - **One-call bootstrap** — `createFhirEngine(config)` initializes definitions, runtime, and persistence
13
+ - **Plugin system** — lifecycle hooks (`init` / `start` / `ready` / `stop`) for extensibility
14
+ - **Config file support** — `fhir.config.ts` / `.js` / `.json` with env variable overrides
15
+ - **Multi-adapter** — SQLite (native + WASM) out of the box, PostgreSQL planned
16
+ - **TypeScript-first** — full type safety, dual ESM/CJS builds
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install fhir-engine
22
+ ```
23
+
24
+ ### Peer dependencies
25
+
26
+ `fhir-engine` depends on the three upstream FHIR packages:
27
+
28
+ ```bash
29
+ npm install fhir-definition fhir-runtime fhir-persistence
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```ts
35
+ import { createFhirEngine } from "fhir-engine";
36
+
37
+ const engine = await createFhirEngine({
38
+ database: { type: "sqlite", path: ":memory:" },
39
+ packages: { path: "./fhir-packages" },
40
+ });
41
+
42
+ // Create a Patient
43
+ const patient = await engine.persistence.createResource("Patient", {
44
+ resourceType: "Patient",
45
+ name: [{ family: "Smith", given: ["John"] }],
46
+ gender: "male",
47
+ birthDate: "1990-01-15",
48
+ });
49
+
50
+ // Read it back
51
+ const read = await engine.persistence.readResource("Patient", patient.id!);
52
+
53
+ // Shut down
54
+ await engine.stop();
55
+ ```
56
+
57
+ ## Config File
58
+
59
+ Create a `fhir.config.ts` (or `.js` / `.json`) in your project root:
60
+
61
+ ```ts
62
+ // fhir.config.ts
63
+ import { defineConfig } from "fhir-engine";
64
+
65
+ export default defineConfig({
66
+ database: { type: "sqlite", path: "./data/fhir.db" },
67
+ packages: { path: "./fhir-packages" },
68
+ plugins: [],
69
+ });
70
+ ```
71
+
72
+ Then bootstrap with zero arguments:
73
+
74
+ ```ts
75
+ const engine = await createFhirEngine(); // auto-discovers fhir.config.ts
76
+ ```
77
+
78
+ ### Environment Variable Overrides
79
+
80
+ | Variable | Overrides | Example |
81
+ | -------------------- | --------------------------------- | ------------------------------- |
82
+ | `FHIR_DATABASE_TYPE` | `database.type` | `sqlite` / `postgres` |
83
+ | `FHIR_DATABASE_URL` | `database.path` or `database.url` | `:memory:` / `postgresql://...` |
84
+ | `FHIR_PACKAGES_PATH` | `packages.path` | `./fhir-packages` |
85
+
86
+ ## Plugin System
87
+
88
+ Plugins hook into the engine lifecycle:
89
+
90
+ ```ts
91
+ import { createFhirEngine, FhirEnginePlugin, EngineContext } from "fhir-engine";
92
+
93
+ const myPlugin: FhirEnginePlugin = {
94
+ name: "my-plugin",
95
+ async init(ctx: EngineContext) {
96
+ // Before persistence init — ctx.persistence is undefined
97
+ ctx.logger.info("Plugin initializing...");
98
+ },
99
+ async start(ctx: EngineContext) {
100
+ // After persistence init — ctx.persistence is available
101
+ await ctx.persistence!.createResource("Patient", {
102
+ resourceType: "Patient",
103
+ name: [{ family: "Seed" }],
104
+ });
105
+ },
106
+ async ready(ctx: EngineContext) {
107
+ ctx.logger.info("System fully operational");
108
+ },
109
+ async stop(ctx: EngineContext) {
110
+ ctx.logger.info("Cleaning up...");
111
+ },
112
+ };
113
+
114
+ const engine = await createFhirEngine({
115
+ database: { type: "sqlite", path: ":memory:" },
116
+ packages: { path: "./fhir-packages" },
117
+ plugins: [myPlugin],
118
+ });
119
+ ```
120
+
121
+ ### Lifecycle
122
+
123
+ ```
124
+ init → plugins.init(ctx) — before FhirSystem.initialize()
125
+ start → FhirSystem.initialize() — schema + migration
126
+ plugins.start(ctx) — ctx.persistence now available
127
+ ready → plugins.ready(ctx) — system fully operational
128
+ stop → plugins.stop(ctx) — reverse registration order
129
+ adapter.close()
130
+ ```
131
+
132
+ - **init/start/ready** errors abort startup with clear message
133
+ - **stop** errors are logged but don't block other plugins
134
+
135
+ ## API Reference
136
+
137
+ ### `createFhirEngine(config?)`
138
+
139
+ Creates and bootstraps a fully initialized FHIR engine.
140
+
141
+ **Parameters:**
142
+
143
+ - `config` (optional) — `FhirEngineConfig`. If omitted, auto-loads from `fhir.config.*` in cwd.
144
+
145
+ **Returns:** `Promise<FhirEngine>`
146
+
147
+ ### `FhirEngine`
148
+
149
+ | Property | Type | Description |
150
+ | --------------- | ----------------------------- | ---------------------------------------------- |
151
+ | `definitions` | `DefinitionRegistry` | FHIR definitions from fhir-definition |
152
+ | `runtime` | `FhirRuntimeInstance` | FHIRPath, validation from fhir-runtime |
153
+ | `persistence` | `FhirPersistence` | CRUD + search + indexing from fhir-persistence |
154
+ | `adapter` | `StorageAdapter` | Underlying database adapter |
155
+ | `sdRegistry` | `StructureDefinitionRegistry` | Loaded StructureDefinitions |
156
+ | `spRegistry` | `SearchParameterRegistry` | Loaded SearchParameters |
157
+ | `resourceTypes` | `string[]` | Resource types with database tables |
158
+ | `context` | `EngineContext` | Shared context (same object plugins receive) |
159
+ | `logger` | `Logger` | Logger instance |
160
+ | `stop()` | `() => Promise<void>` | Gracefully shut down the engine |
161
+
162
+ ### `FhirEngineConfig`
163
+
164
+ ```ts
165
+ interface FhirEngineConfig {
166
+ database: DatabaseConfig; // sqlite | sqlite-wasm | postgres
167
+ packages: PackagesConfig; // { path: string }
168
+ packageName?: string; // IG migration label
169
+ packageVersion?: string; // IG migration version
170
+ logger?: Logger; // custom logger (default: console)
171
+ plugins?: FhirEnginePlugin[]; // plugins array
172
+ }
173
+ ```
174
+
175
+ ### `defineConfig(config)`
176
+
177
+ Type-safe identity helper for config files. Returns the config unchanged.
178
+
179
+ ### `loadFhirConfig(path?)`
180
+
181
+ Loads config from a file. Auto-discovers `fhir.config.ts` → `.js` → `.mjs` → `.json` from cwd if no path given.
182
+
183
+ ## Database Adapters
184
+
185
+ | `database.type` | Adapter | Use Case |
186
+ | --------------- | ---------------------- | --------------------------- |
187
+ | `sqlite` | `BetterSqlite3Adapter` | Node.js / Electron / CLI |
188
+ | `sqlite-wasm` | `SQLiteAdapter` | Browser / WASM |
189
+ | `postgres` | — | Not yet available (planned) |
190
+
191
+ ## Requirements
192
+
193
+ - Node.js >= 18.0.0
194
+ - npm >= 9.0.0
195
+
196
+ ## License
197
+
198
+ [MIT](./LICENSE)
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ createAdapter: () => createAdapter,
24
+ createConsoleLogger: () => createConsoleLogger,
25
+ createFhirEngine: () => createFhirEngine,
26
+ defineConfig: () => defineConfig,
27
+ loadFhirConfig: () => loadFhirConfig
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/engine.ts
32
+ var import_fhir_definition = require("fhir-definition");
33
+ var import_fhir_runtime = require("fhir-runtime");
34
+ var import_fhir_persistence2 = require("fhir-persistence");
35
+
36
+ // src/adapter-factory.ts
37
+ var import_fhir_persistence = require("fhir-persistence");
38
+ function createAdapter(config, logger) {
39
+ switch (config.type) {
40
+ case "sqlite": {
41
+ logger.info(`Creating BetterSqlite3Adapter (path: ${config.path})`);
42
+ return new import_fhir_persistence.BetterSqlite3Adapter({
43
+ path: config.path,
44
+ wal: config.wal ?? true,
45
+ busyTimeout: config.busyTimeout ?? 5e3
46
+ });
47
+ }
48
+ case "sqlite-wasm": {
49
+ logger.info(`Creating SQLiteAdapter (WASM, path: ${config.path})`);
50
+ return new import_fhir_persistence.SQLiteAdapter(config.path);
51
+ }
52
+ case "postgres": {
53
+ throw new Error(
54
+ 'fhir-engine: PostgreSQL adapter is not yet available. PostgresAdapter is not exported from fhir-persistence v0.1.0. Use database.type = "sqlite" for now.'
55
+ );
56
+ }
57
+ default: {
58
+ const _exhaustive = config;
59
+ throw new Error(`fhir-engine: unknown database type: ${_exhaustive.type}`);
60
+ }
61
+ }
62
+ }
63
+
64
+ // src/config.ts
65
+ var import_node_fs = require("node:fs");
66
+ var import_node_path = require("node:path");
67
+ var import_node_url = require("node:url");
68
+ function defineConfig(config) {
69
+ return config;
70
+ }
71
+ var CONFIG_FILENAMES = [
72
+ "fhir.config.ts",
73
+ "fhir.config.js",
74
+ "fhir.config.mjs",
75
+ "fhir.config.json"
76
+ ];
77
+ async function loadFhirConfig(configPath) {
78
+ let resolvedPath;
79
+ if (configPath) {
80
+ resolvedPath = (0, import_node_path.resolve)(configPath);
81
+ if (!(0, import_node_fs.existsSync)(resolvedPath)) {
82
+ throw new Error(`fhir-engine: config file not found: ${resolvedPath}`);
83
+ }
84
+ } else {
85
+ const cwd = process.cwd();
86
+ const found = CONFIG_FILENAMES.map((name) => (0, import_node_path.resolve)(cwd, name)).find((p) => (0, import_node_fs.existsSync)(p));
87
+ if (!found) {
88
+ throw new Error(
89
+ `fhir-engine: no config file found in ${cwd}. Expected one of: ${CONFIG_FILENAMES.join(", ")}`
90
+ );
91
+ }
92
+ resolvedPath = found;
93
+ }
94
+ const config = await loadConfigFile(resolvedPath);
95
+ return applyEnvOverrides(config);
96
+ }
97
+ async function loadConfigFile(filePath) {
98
+ const ext = (0, import_node_path.extname)(filePath);
99
+ if (ext === ".json") {
100
+ return loadJsonConfig(filePath);
101
+ }
102
+ if (ext === ".ts" || ext === ".js" || ext === ".mjs") {
103
+ return loadModuleConfig(filePath);
104
+ }
105
+ throw new Error(`fhir-engine: unsupported config file extension: ${ext}`);
106
+ }
107
+ function loadJsonConfig(filePath) {
108
+ try {
109
+ const raw = (0, import_node_fs.readFileSync)(filePath, "utf-8");
110
+ return JSON.parse(raw);
111
+ } catch (err) {
112
+ throw new Error(
113
+ `fhir-engine: failed to parse config file ${filePath}: ${err instanceof Error ? err.message : String(err)}`,
114
+ { cause: err }
115
+ );
116
+ }
117
+ }
118
+ async function loadModuleConfig(filePath) {
119
+ try {
120
+ const fileUrl = (0, import_node_url.pathToFileURL)(filePath).href;
121
+ const mod = await import(fileUrl);
122
+ const config = mod.default ?? mod;
123
+ if (!config || typeof config !== "object") {
124
+ throw new Error("config file must export a FhirEngineConfig object as default export");
125
+ }
126
+ return config;
127
+ } catch (err) {
128
+ if (err instanceof Error && err.message.includes("must export")) {
129
+ throw err;
130
+ }
131
+ throw new Error(
132
+ `fhir-engine: failed to load config file ${filePath}: ${err instanceof Error ? err.message : String(err)}`,
133
+ { cause: err }
134
+ );
135
+ }
136
+ }
137
+ var VALID_DB_TYPES = ["sqlite", "sqlite-wasm", "postgres"];
138
+ function applyEnvOverrides(config) {
139
+ const result = structuredClone(config);
140
+ const dbType = process.env.FHIR_DATABASE_TYPE;
141
+ const dbUrl = process.env.FHIR_DATABASE_URL;
142
+ const pkgPath = process.env.FHIR_PACKAGES_PATH;
143
+ if (dbType) {
144
+ if (!VALID_DB_TYPES.includes(dbType)) {
145
+ throw new Error(
146
+ `fhir-engine: FHIR_DATABASE_TYPE must be one of: ${VALID_DB_TYPES.join(", ")}. Got: "${dbType}"`
147
+ );
148
+ }
149
+ const validType = dbType;
150
+ if (validType === "postgres") {
151
+ result.database = { type: "postgres", url: result.database.url ?? "" };
152
+ } else if (validType === "sqlite-wasm") {
153
+ result.database = { type: "sqlite-wasm", path: result.database.path ?? "" };
154
+ } else {
155
+ result.database = { type: "sqlite", path: result.database.path ?? "" };
156
+ }
157
+ }
158
+ if (dbUrl) {
159
+ const type = result.database?.type;
160
+ if (type === "postgres") {
161
+ result.database = { ...result.database, type: "postgres", url: dbUrl };
162
+ } else if (type === "sqlite-wasm") {
163
+ result.database = { ...result.database, type: "sqlite-wasm", path: dbUrl };
164
+ } else {
165
+ result.database = { ...result.database, type: "sqlite", path: dbUrl };
166
+ }
167
+ }
168
+ if (pkgPath) {
169
+ result.packages = { ...result.packages, path: pkgPath };
170
+ }
171
+ return result;
172
+ }
173
+
174
+ // src/logger.ts
175
+ function createConsoleLogger() {
176
+ return {
177
+ debug: (message, ...args) => console.debug(`[fhir-engine] ${message}`, ...args),
178
+ info: (message, ...args) => console.info(`[fhir-engine] ${message}`, ...args),
179
+ warn: (message, ...args) => console.warn(`[fhir-engine] ${message}`, ...args),
180
+ error: (message, ...args) => console.error(`[fhir-engine] ${message}`, ...args)
181
+ };
182
+ }
183
+
184
+ // src/engine.ts
185
+ function resolveDialect(type) {
186
+ switch (type) {
187
+ case "sqlite":
188
+ case "sqlite-wasm":
189
+ return "sqlite";
190
+ case "postgres":
191
+ return "postgres";
192
+ }
193
+ }
194
+ function validateConfig(config) {
195
+ if (!config.database) {
196
+ throw new Error("fhir-engine: config.database is required");
197
+ }
198
+ if (!config.database.type) {
199
+ throw new Error("fhir-engine: config.database.type is required (sqlite | sqlite-wasm | postgres)");
200
+ }
201
+ if (!config.packages) {
202
+ throw new Error("fhir-engine: config.packages is required");
203
+ }
204
+ if (!config.packages.path) {
205
+ throw new Error("fhir-engine: config.packages.path is required");
206
+ }
207
+ }
208
+ async function runPluginHook(plugins, hook, ctx) {
209
+ for (const plugin of plugins) {
210
+ const fn = plugin[hook];
211
+ if (fn) {
212
+ try {
213
+ await fn.call(plugin, ctx);
214
+ } catch (err) {
215
+ throw new Error(
216
+ `fhir-engine: plugin "${plugin.name}" failed during ${hook}: ${err instanceof Error ? err.message : String(err)}`,
217
+ { cause: err }
218
+ );
219
+ }
220
+ }
221
+ }
222
+ }
223
+ async function createFhirEngine(config) {
224
+ if (!config) {
225
+ config = await loadFhirConfig();
226
+ }
227
+ validateConfig(config);
228
+ const logger = config.logger ?? createConsoleLogger();
229
+ const plugins = config.plugins ?? [];
230
+ logger.info("Initializing fhir-engine...");
231
+ logger.info(`Loading FHIR packages from: ${config.packages.path}`);
232
+ const { registry, result } = (0, import_fhir_definition.loadDefinitionPackages)(config.packages.path);
233
+ logger.info(
234
+ `Loaded ${result.packages.length} package(s): ${result.packages.map((p) => `${p.name}@${p.version}`).join(", ")}`
235
+ );
236
+ logger.info("Creating fhir-runtime instance...");
237
+ const runtime = await (0, import_fhir_runtime.createRuntime)({ definitions: registry, preloadCore: false });
238
+ const definitionBridge = new import_fhir_persistence2.FhirDefinitionBridge(registry);
239
+ const runtimeProvider = new import_fhir_persistence2.FhirRuntimeProvider({
240
+ extractSearchValues: import_fhir_runtime.extractSearchValues,
241
+ extractAllSearchValues: import_fhir_runtime.extractAllSearchValues,
242
+ extractReferences: import_fhir_runtime.extractReferences
243
+ });
244
+ const adapter = createAdapter(config.database, logger);
245
+ const ctx = {
246
+ config,
247
+ definitions: registry,
248
+ runtime,
249
+ adapter,
250
+ persistence: void 0,
251
+ logger
252
+ };
253
+ if (plugins.length > 0) {
254
+ logger.info(`Running init for ${plugins.length} plugin(s): ${plugins.map((p) => p.name).join(", ")}`);
255
+ await runPluginHook(plugins, "init", ctx);
256
+ }
257
+ const dialect = resolveDialect(config.database.type);
258
+ const system = new import_fhir_persistence2.FhirSystem(adapter, {
259
+ dialect,
260
+ runtimeProvider,
261
+ packageName: config.packageName ?? "fhir-engine.default",
262
+ packageVersion: config.packageVersion ?? "1.0.0"
263
+ });
264
+ logger.info("Initializing persistence system (schema + migration)...");
265
+ const { persistence, sdRegistry, spRegistry, igResult, resourceTypes } = await system.initialize(definitionBridge);
266
+ logger.info(`Persistence ready \u2014 IG action: ${igResult.action}, ${resourceTypes.length} resource type(s)`);
267
+ ctx.persistence = persistence;
268
+ if (plugins.length > 0) {
269
+ logger.info(`Running start for ${plugins.length} plugin(s)...`);
270
+ await runPluginHook(plugins, "start", ctx);
271
+ }
272
+ if (plugins.length > 0) {
273
+ logger.info(`Running ready for ${plugins.length} plugin(s)...`);
274
+ await runPluginHook(plugins, "ready", ctx);
275
+ }
276
+ let stopped = false;
277
+ const engine = {
278
+ definitions: registry,
279
+ runtime,
280
+ adapter,
281
+ persistence,
282
+ sdRegistry,
283
+ spRegistry,
284
+ igResult,
285
+ resourceTypes,
286
+ logger,
287
+ context: ctx,
288
+ async stop() {
289
+ if (stopped) return;
290
+ stopped = true;
291
+ logger.info("Stopping fhir-engine...");
292
+ for (let i = plugins.length - 1; i >= 0; i--) {
293
+ const plugin = plugins[i];
294
+ if (plugin.stop) {
295
+ try {
296
+ await plugin.stop.call(plugin, ctx);
297
+ } catch (err) {
298
+ logger.error(
299
+ `Plugin "${plugin.name}" failed during stop: ${err instanceof Error ? err.message : String(err)}`
300
+ );
301
+ }
302
+ }
303
+ }
304
+ await adapter.close();
305
+ logger.info("fhir-engine stopped.");
306
+ }
307
+ };
308
+ logger.info("fhir-engine ready.");
309
+ return engine;
310
+ }
311
+ // Annotate the CommonJS export names for ESM import in node:
312
+ 0 && (module.exports = {
313
+ createAdapter,
314
+ createConsoleLogger,
315
+ createFhirEngine,
316
+ defineConfig,
317
+ loadFhirConfig
318
+ });
319
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/index.ts", "../../src/engine.ts", "../../src/adapter-factory.ts", "../../src/config.ts", "../../src/logger.ts"],
4
+ "sourcesContent": ["// fhir-engine \u2014 public API\n\nexport { createFhirEngine } from './engine.js';\nexport { defineConfig, loadFhirConfig } from './config.js';\nexport { createConsoleLogger } from './logger.js';\nexport { createAdapter } from './adapter-factory.js';\n\nexport type {\n FhirEngine,\n FhirEngineConfig,\n FhirEnginePlugin,\n EngineContext,\n DatabaseConfig,\n SqliteDatabaseConfig,\n SqliteWasmDatabaseConfig,\n PostgresDatabaseConfig,\n PackagesConfig,\n Logger,\n} from './types.js';\n\n// Re-export key upstream types for convenience\nexport type { DefinitionRegistry, DefinitionProvider } from 'fhir-definition';\nexport type { FhirRuntimeInstance } from 'fhir-runtime';\nexport type { FhirPersistence, StorageAdapter } from 'fhir-persistence';\n", "import { loadDefinitionPackages } from 'fhir-definition';\nimport { createRuntime, extractSearchValues, extractAllSearchValues, extractReferences } from 'fhir-runtime';\nimport { FhirDefinitionBridge, FhirRuntimeProvider, FhirSystem } from 'fhir-persistence';\n\nimport { createAdapter } from './adapter-factory.js';\nimport { loadFhirConfig } from './config.js';\nimport { createConsoleLogger } from './logger.js';\nimport type { EngineContext, FhirEngine, FhirEngineConfig, FhirEnginePlugin } from './types.js';\n\n/**\n * Resolve the SQL dialect from the database config type.\n */\nfunction resolveDialect(type: FhirEngineConfig['database']['type']): 'sqlite' | 'postgres' {\n switch (type) {\n case 'sqlite':\n case 'sqlite-wasm':\n return 'sqlite';\n case 'postgres':\n return 'postgres';\n }\n}\n\n/**\n * Validate the engine configuration, throwing on missing required fields.\n */\nfunction validateConfig(config: FhirEngineConfig): void {\n if (!config.database) {\n throw new Error('fhir-engine: config.database is required');\n }\n if (!config.database.type) {\n throw new Error('fhir-engine: config.database.type is required (sqlite | sqlite-wasm | postgres)');\n }\n if (!config.packages) {\n throw new Error('fhir-engine: config.packages is required');\n }\n if (!config.packages.path) {\n throw new Error('fhir-engine: config.packages.path is required');\n }\n}\n\n/**\n * Run a lifecycle hook on all plugins in order.\n * Wraps errors with the plugin name for clear diagnostics.\n */\nasync function runPluginHook(\n plugins: FhirEnginePlugin[],\n hook: 'init' | 'start' | 'ready',\n ctx: EngineContext,\n): Promise<void> {\n for (const plugin of plugins) {\n const fn = plugin[hook];\n if (fn) {\n try {\n await fn.call(plugin, ctx);\n } catch (err) {\n throw new Error(\n `fhir-engine: plugin \"${plugin.name}\" failed during ${hook}: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n }\n }\n}\n\n/**\n * Create and bootstrap a fully initialized FHIR engine.\n *\n * This is the single entry point for all FHIR applications.\n * It assembles fhir-definition, fhir-runtime, and fhir-persistence\n * into a running system from a single configuration object.\n *\n * @example\n * ```ts\n * const engine = await createFhirEngine({\n * database: { type: 'sqlite', path: ':memory:' },\n * packages: { path: './fhir-packages' },\n * });\n *\n * const patient = await engine.persistence.createResource('Patient', {\n * resourceType: 'Patient',\n * name: [{ family: 'Smith', given: ['John'] }],\n * });\n *\n * await engine.stop();\n * ```\n */\nexport async function createFhirEngine(config?: FhirEngineConfig): Promise<FhirEngine> {\n // \u2500\u2500 0. Resolve config \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (!config) {\n config = await loadFhirConfig();\n }\n validateConfig(config);\n\n const logger = config.logger ?? createConsoleLogger();\n const plugins = config.plugins ?? [];\n logger.info('Initializing fhir-engine...');\n\n // \u2500\u2500 1. Load FHIR definitions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n logger.info(`Loading FHIR packages from: ${config.packages.path}`);\n const { registry, result } = loadDefinitionPackages(config.packages.path);\n logger.info(\n `Loaded ${result.packages.length} package(s): ${result.packages.map((p) => `${p.name}@${p.version}`).join(', ')}`,\n );\n\n // \u2500\u2500 2. Create fhir-runtime \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n logger.info('Creating fhir-runtime instance...');\n const runtime = await createRuntime({ definitions: registry, preloadCore: false });\n\n // \u2500\u2500 3. Build provider bridges \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const definitionBridge = new FhirDefinitionBridge(registry);\n const runtimeProvider = new FhirRuntimeProvider({\n extractSearchValues,\n extractAllSearchValues,\n extractReferences,\n });\n\n // \u2500\u2500 4. Create storage adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const adapter = createAdapter(config.database, logger);\n\n // \u2500\u2500 5. Build EngineContext \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const ctx: { -readonly [K in keyof EngineContext]: EngineContext[K] } = {\n config,\n definitions: registry,\n runtime,\n adapter,\n persistence: undefined,\n logger,\n };\n\n // \u2500\u2500 6. INIT phase \u2014 plugins run before persistence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (plugins.length > 0) {\n logger.info(`Running init for ${plugins.length} plugin(s): ${plugins.map((p) => p.name).join(', ')}`);\n await runPluginHook(plugins, 'init', ctx);\n }\n\n // \u2500\u2500 7. Initialize FhirSystem \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const dialect = resolveDialect(config.database.type);\n const system = new FhirSystem(adapter, {\n dialect,\n runtimeProvider,\n packageName: config.packageName ?? 'fhir-engine.default',\n packageVersion: config.packageVersion ?? '1.0.0',\n });\n\n logger.info('Initializing persistence system (schema + migration)...');\n const { persistence, sdRegistry, spRegistry, igResult, resourceTypes } =\n await system.initialize(definitionBridge);\n\n logger.info(`Persistence ready \u2014 IG action: ${igResult.action}, ${resourceTypes.length} resource type(s)`);\n\n // ctx.persistence now available\n ctx.persistence = persistence;\n\n // \u2500\u2500 8. START phase \u2014 plugins can access persistence \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (plugins.length > 0) {\n logger.info(`Running start for ${plugins.length} plugin(s)...`);\n await runPluginHook(plugins, 'start', ctx);\n }\n\n // \u2500\u2500 9. READY phase \u2014 system fully operational \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n if (plugins.length > 0) {\n logger.info(`Running ready for ${plugins.length} plugin(s)...`);\n await runPluginHook(plugins, 'ready', ctx);\n }\n\n // \u2500\u2500 10. Return FhirEngine \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n let stopped = false;\n\n const engine: FhirEngine = {\n definitions: registry,\n runtime,\n adapter,\n persistence,\n sdRegistry,\n spRegistry,\n igResult,\n resourceTypes,\n logger,\n context: ctx as EngineContext,\n\n async stop() {\n if (stopped) return;\n stopped = true;\n logger.info('Stopping fhir-engine...');\n\n // Stop plugins in reverse registration order\n for (let i = plugins.length - 1; i >= 0; i--) {\n const plugin = plugins[i];\n if (plugin.stop) {\n try {\n await plugin.stop.call(plugin, ctx as EngineContext);\n } catch (err) {\n logger.error(\n `Plugin \"${plugin.name}\" failed during stop: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n await adapter.close();\n logger.info('fhir-engine stopped.');\n },\n };\n\n logger.info('fhir-engine ready.');\n return engine;\n}\n", "import { BetterSqlite3Adapter, SQLiteAdapter } from 'fhir-persistence';\nimport type { StorageAdapter } from 'fhir-persistence';\nimport type { DatabaseConfig, Logger } from './types.js';\n\n/**\n * Create a StorageAdapter from the database configuration.\n *\n * Supported adapters:\n * - `sqlite` \u2192 BetterSqlite3Adapter (native, Node.js / Electron)\n * - `sqlite-wasm` \u2192 SQLiteAdapter (sql.js WASM, browser / cross-platform)\n * - `postgres` \u2192 not yet available (PostgresAdapter not exported from fhir-persistence)\n */\nexport function createAdapter(config: DatabaseConfig, logger: Logger): StorageAdapter {\n switch (config.type) {\n case 'sqlite': {\n logger.info(`Creating BetterSqlite3Adapter (path: ${config.path})`);\n return new BetterSqlite3Adapter({\n path: config.path,\n wal: config.wal ?? true,\n busyTimeout: config.busyTimeout ?? 5000,\n });\n }\n\n case 'sqlite-wasm': {\n logger.info(`Creating SQLiteAdapter (WASM, path: ${config.path})`);\n return new SQLiteAdapter(config.path);\n }\n\n case 'postgres': {\n throw new Error(\n 'fhir-engine: PostgreSQL adapter is not yet available. ' +\n 'PostgresAdapter is not exported from fhir-persistence v0.1.0. ' +\n 'Use database.type = \"sqlite\" for now.',\n );\n }\n\n default: {\n const _exhaustive: never = config;\n throw new Error(`fhir-engine: unknown database type: ${(_exhaustive as DatabaseConfig).type}`);\n }\n }\n}\n", "import { existsSync, readFileSync } from 'node:fs';\nimport { resolve, extname } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { FhirEngineConfig, DatabaseConfig } from './types.js';\n\n// ---------------------------------------------------------------------------\n// defineConfig \u2014 typed identity helper for fhir.config.ts / .js\n// ---------------------------------------------------------------------------\n\n/**\n * Type-safe config helper for `fhir.config.ts` / `fhir.config.js`.\n *\n * @example\n * ```ts\n * // fhir.config.ts\n * import { defineConfig } from 'fhir-engine';\n *\n * export default defineConfig({\n * database: { type: 'sqlite', path: './fhir.db' },\n * packages: { path: './fhir-packages' },\n * });\n * ```\n */\nexport function defineConfig(config: FhirEngineConfig): FhirEngineConfig {\n return config;\n}\n\n// ---------------------------------------------------------------------------\n// Config file discovery order\n// ---------------------------------------------------------------------------\n\nconst CONFIG_FILENAMES = [\n 'fhir.config.ts',\n 'fhir.config.js',\n 'fhir.config.mjs',\n 'fhir.config.json',\n] as const;\n\n// ---------------------------------------------------------------------------\n// loadFhirConfig \u2014 auto-discover and load config\n// ---------------------------------------------------------------------------\n\n/**\n * Load engine configuration from a file.\n *\n * If `configPath` is provided, loads that exact file.\n * Otherwise, searches the current working directory for config files\n * in this order: `fhir.config.ts` \u2192 `fhir.config.js` \u2192 `fhir.config.mjs` \u2192 `fhir.config.json`.\n *\n * Environment variable overrides are applied on top of the loaded config.\n *\n * @param configPath - Explicit path to a config file (optional).\n * @returns The resolved `FhirEngineConfig`.\n */\nexport async function loadFhirConfig(configPath?: string): Promise<FhirEngineConfig> {\n let resolvedPath: string;\n\n if (configPath) {\n resolvedPath = resolve(configPath);\n if (!existsSync(resolvedPath)) {\n throw new Error(`fhir-engine: config file not found: ${resolvedPath}`);\n }\n } else {\n const cwd = process.cwd();\n const found = CONFIG_FILENAMES\n .map((name) => resolve(cwd, name))\n .find((p) => existsSync(p));\n if (!found) {\n throw new Error(\n `fhir-engine: no config file found in ${cwd}. ` +\n `Expected one of: ${CONFIG_FILENAMES.join(', ')}`,\n );\n }\n resolvedPath = found;\n }\n\n const config = await loadConfigFile(resolvedPath);\n return applyEnvOverrides(config);\n}\n\n// ---------------------------------------------------------------------------\n// File loaders\n// ---------------------------------------------------------------------------\n\nasync function loadConfigFile(filePath: string): Promise<FhirEngineConfig> {\n const ext = extname(filePath);\n\n if (ext === '.json') {\n return loadJsonConfig(filePath);\n }\n\n if (ext === '.ts' || ext === '.js' || ext === '.mjs') {\n return loadModuleConfig(filePath);\n }\n\n throw new Error(`fhir-engine: unsupported config file extension: ${ext}`);\n}\n\nfunction loadJsonConfig(filePath: string): FhirEngineConfig {\n try {\n const raw = readFileSync(filePath, 'utf-8');\n return JSON.parse(raw) as FhirEngineConfig;\n } catch (err) {\n throw new Error(\n `fhir-engine: failed to parse config file ${filePath}: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n}\n\nasync function loadModuleConfig(filePath: string): Promise<FhirEngineConfig> {\n try {\n const fileUrl = pathToFileURL(filePath).href;\n const mod = await import(fileUrl);\n const config = mod.default ?? mod;\n\n if (!config || typeof config !== 'object') {\n throw new Error('config file must export a FhirEngineConfig object as default export');\n }\n\n return config as FhirEngineConfig;\n } catch (err) {\n if (err instanceof Error && err.message.includes('must export')) {\n throw err;\n }\n throw new Error(\n `fhir-engine: failed to load config file ${filePath}: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Environment variable overrides\n// ---------------------------------------------------------------------------\n\nconst VALID_DB_TYPES = ['sqlite', 'sqlite-wasm', 'postgres'] as const;\n\n/**\n * Apply environment variable overrides on top of a loaded config.\n *\n * | Env Variable | Overrides |\n * |---------------------|----------------------------------|\n * | FHIR_DATABASE_TYPE | config.database.type |\n * | FHIR_DATABASE_URL | config.database.path / .url |\n * | FHIR_PACKAGES_PATH | config.packages.path |\n * | FHIR_LOG_LEVEL | (stored for logger filtering) |\n */\nexport function applyEnvOverrides(config: FhirEngineConfig): FhirEngineConfig {\n const result = structuredClone(config);\n\n const dbType = process.env.FHIR_DATABASE_TYPE;\n const dbUrl = process.env.FHIR_DATABASE_URL;\n const pkgPath = process.env.FHIR_PACKAGES_PATH;\n\n if (dbType) {\n if (!VALID_DB_TYPES.includes(dbType as typeof VALID_DB_TYPES[number])) {\n throw new Error(\n `fhir-engine: FHIR_DATABASE_TYPE must be one of: ${VALID_DB_TYPES.join(', ')}. Got: \"${dbType}\"`,\n );\n }\n // Rebuild database config with overridden type\n const validType = dbType as DatabaseConfig['type'];\n if (validType === 'postgres') {\n result.database = { type: 'postgres', url: (result.database as { url?: string }).url ?? '' };\n } else if (validType === 'sqlite-wasm') {\n result.database = { type: 'sqlite-wasm', path: (result.database as { path?: string }).path ?? '' };\n } else {\n result.database = { type: 'sqlite', path: (result.database as { path?: string }).path ?? '' };\n }\n }\n\n if (dbUrl) {\n const type = result.database?.type;\n if (type === 'postgres') {\n result.database = { ...result.database, type: 'postgres', url: dbUrl };\n } else if (type === 'sqlite-wasm') {\n result.database = { ...result.database, type: 'sqlite-wasm', path: dbUrl };\n } else {\n result.database = { ...result.database, type: 'sqlite', path: dbUrl };\n }\n }\n\n if (pkgPath) {\n result.packages = { ...result.packages, path: pkgPath };\n }\n\n return result;\n}\n", "import type { Logger } from './types.js';\n\n/**\n * Default console-based logger.\n */\nexport function createConsoleLogger(): Logger {\n return {\n debug: (message: string, ...args: unknown[]) => console.debug(`[fhir-engine] ${message}`, ...args),\n info: (message: string, ...args: unknown[]) => console.info(`[fhir-engine] ${message}`, ...args),\n warn: (message: string, ...args: unknown[]) => console.warn(`[fhir-engine] ${message}`, ...args),\n error: (message: string, ...args: unknown[]) => console.error(`[fhir-engine] ${message}`, ...args),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_fhir_persistence"]
7
+ }