fhir-persistence 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 +77 -0
- package/LICENSE +21 -0
- package/README.md +225 -0
- package/dist/cjs/index.cjs +8869 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/index.d.ts +3114 -0
- package/dist/cjs/package.json +5 -0
- package/dist/esm/index.d.ts +3114 -0
- package/dist/esm/index.mjs +8745 -0
- package/dist/esm/index.mjs.map +7 -0
- package/dist/esm/package.json +5 -0
- package/dist/index.d.ts +3114 -0
- package/dist/lib/cache/resource-cache.d.ts +137 -0
- package/dist/lib/cache/resource-cache.d.ts.map +1 -0
- package/dist/lib/cli/reindex.d.ts +55 -0
- package/dist/lib/cli/reindex.d.ts.map +1 -0
- package/dist/lib/db/adapter.d.ts +79 -0
- package/dist/lib/db/adapter.d.ts.map +1 -0
- package/dist/lib/db/better-sqlite3-adapter.d.ts +65 -0
- package/dist/lib/db/better-sqlite3-adapter.d.ts.map +1 -0
- package/dist/lib/db/dialect.d.ts +87 -0
- package/dist/lib/db/dialect.d.ts.map +1 -0
- package/dist/lib/db/index.d.ts +18 -0
- package/dist/lib/db/index.d.ts.map +1 -0
- package/dist/lib/db/postgres-adapter.d.ts +84 -0
- package/dist/lib/db/postgres-adapter.d.ts.map +1 -0
- package/dist/lib/db/postgres-dialect.d.ts +36 -0
- package/dist/lib/db/postgres-dialect.d.ts.map +1 -0
- package/dist/lib/db/sqlite-adapter.d.ts +41 -0
- package/dist/lib/db/sqlite-adapter.d.ts.map +1 -0
- package/dist/lib/db/sqlite-dialect.d.ts +34 -0
- package/dist/lib/db/sqlite-dialect.d.ts.map +1 -0
- package/dist/lib/index.d.ts +65 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/migration/ig-persistence-manager.d.ts +56 -0
- package/dist/lib/migration/ig-persistence-manager.d.ts.map +1 -0
- package/dist/lib/migration/migration-generator.d.ts +38 -0
- package/dist/lib/migration/migration-generator.d.ts.map +1 -0
- package/dist/lib/migration/reindex-scheduler.d.ts +82 -0
- package/dist/lib/migration/reindex-scheduler.d.ts.map +1 -0
- package/dist/lib/migration/schema-diff.d.ts +44 -0
- package/dist/lib/migration/schema-diff.d.ts.map +1 -0
- package/dist/lib/migrations/index.d.ts +8 -0
- package/dist/lib/migrations/index.d.ts.map +1 -0
- package/dist/lib/migrations/migration-runner.d.ts +102 -0
- package/dist/lib/migrations/migration-runner.d.ts.map +1 -0
- package/dist/lib/observability/search-logger.d.ts +74 -0
- package/dist/lib/observability/search-logger.d.ts.map +1 -0
- package/dist/lib/platform/platform-ig-definitions.d.ts +51 -0
- package/dist/lib/platform/platform-ig-definitions.d.ts.map +1 -0
- package/dist/lib/platform/platform-ig-loader.d.ts +30 -0
- package/dist/lib/platform/platform-ig-loader.d.ts.map +1 -0
- package/dist/lib/providers/definition-provider.d.ts +124 -0
- package/dist/lib/providers/definition-provider.d.ts.map +1 -0
- package/dist/lib/providers/fhir-definition-provider.d.ts +58 -0
- package/dist/lib/providers/fhir-definition-provider.d.ts.map +1 -0
- package/dist/lib/providers/fhir-runtime-provider.d.ts +75 -0
- package/dist/lib/providers/fhir-runtime-provider.d.ts.map +1 -0
- package/dist/lib/providers/in-memory-definition-provider.d.ts +72 -0
- package/dist/lib/providers/in-memory-definition-provider.d.ts.map +1 -0
- package/dist/lib/providers/index.d.ts +13 -0
- package/dist/lib/providers/index.d.ts.map +1 -0
- package/dist/lib/providers/property-path-runtime-provider.d.ts +34 -0
- package/dist/lib/providers/property-path-runtime-provider.d.ts.map +1 -0
- package/dist/lib/providers/runtime-provider.d.ts +84 -0
- package/dist/lib/providers/runtime-provider.d.ts.map +1 -0
- package/dist/lib/registry/element-cardinality.d.ts +15 -0
- package/dist/lib/registry/element-cardinality.d.ts.map +1 -0
- package/dist/lib/registry/index.d.ts +10 -0
- package/dist/lib/registry/index.d.ts.map +1 -0
- package/dist/lib/registry/package-registry-repo.d.ts +106 -0
- package/dist/lib/registry/package-registry-repo.d.ts.map +1 -0
- package/dist/lib/registry/search-parameter-registry.d.ts +175 -0
- package/dist/lib/registry/search-parameter-registry.d.ts.map +1 -0
- package/dist/lib/registry/structure-definition-registry.d.ts +93 -0
- package/dist/lib/registry/structure-definition-registry.d.ts.map +1 -0
- package/dist/lib/repo/errors.d.ts +61 -0
- package/dist/lib/repo/errors.d.ts.map +1 -0
- package/dist/lib/repo/history-bundle.d.ts +78 -0
- package/dist/lib/repo/history-bundle.d.ts.map +1 -0
- package/dist/lib/repo/index.d.ts +17 -0
- package/dist/lib/repo/index.d.ts.map +1 -0
- package/dist/lib/repo/indexing-pipeline.d.ts +108 -0
- package/dist/lib/repo/indexing-pipeline.d.ts.map +1 -0
- package/dist/lib/repo/lookup-table-writer.d.ts +46 -0
- package/dist/lib/repo/lookup-table-writer.d.ts.map +1 -0
- package/dist/lib/repo/reference-indexer.d.ts +56 -0
- package/dist/lib/repo/reference-indexer.d.ts.map +1 -0
- package/dist/lib/repo/row-builder.d.ts +78 -0
- package/dist/lib/repo/row-builder.d.ts.map +1 -0
- package/dist/lib/repo/row-indexer.d.ts +111 -0
- package/dist/lib/repo/row-indexer.d.ts.map +1 -0
- package/dist/lib/repo/sql-builder.d.ts +166 -0
- package/dist/lib/repo/sql-builder.d.ts.map +1 -0
- package/dist/lib/repo/types.d.ts +321 -0
- package/dist/lib/repo/types.d.ts.map +1 -0
- package/dist/lib/schema/ddl-generator.d.ts +81 -0
- package/dist/lib/schema/ddl-generator.d.ts.map +1 -0
- package/dist/lib/schema/index.d.ts +8 -0
- package/dist/lib/schema/index.d.ts.map +1 -0
- package/dist/lib/schema/table-schema-builder.d.ts +66 -0
- package/dist/lib/schema/table-schema-builder.d.ts.map +1 -0
- package/dist/lib/schema/table-schema.d.ts +236 -0
- package/dist/lib/schema/table-schema.d.ts.map +1 -0
- package/dist/lib/search/index.d.ts +22 -0
- package/dist/lib/search/index.d.ts.map +1 -0
- package/dist/lib/search/pagination.d.ts +53 -0
- package/dist/lib/search/pagination.d.ts.map +1 -0
- package/dist/lib/search/param-parser.d.ts +85 -0
- package/dist/lib/search/param-parser.d.ts.map +1 -0
- package/dist/lib/search/search-bundle.d.ts +61 -0
- package/dist/lib/search/search-bundle.d.ts.map +1 -0
- package/dist/lib/search/search-executor.d.ts +58 -0
- package/dist/lib/search/search-executor.d.ts.map +1 -0
- package/dist/lib/search/search-planner.d.ts +57 -0
- package/dist/lib/search/search-planner.d.ts.map +1 -0
- package/dist/lib/search/search-sql-builder.d.ts +86 -0
- package/dist/lib/search/search-sql-builder.d.ts.map +1 -0
- package/dist/lib/search/types.d.ts +219 -0
- package/dist/lib/search/types.d.ts.map +1 -0
- package/dist/lib/search/where-builder.d.ts +64 -0
- package/dist/lib/search/where-builder.d.ts.map +1 -0
- package/dist/lib/startup/fhir-system.d.ts +82 -0
- package/dist/lib/startup/fhir-system.d.ts.map +1 -0
- package/dist/lib/store/conditional-service.d.ts +76 -0
- package/dist/lib/store/conditional-service.d.ts.map +1 -0
- package/dist/lib/store/fhir-persistence.d.ts +81 -0
- package/dist/lib/store/fhir-persistence.d.ts.map +1 -0
- package/dist/lib/store/fhir-store.d.ts +44 -0
- package/dist/lib/store/fhir-store.d.ts.map +1 -0
- package/dist/lib/terminology/terminology-code-repo.d.ts +61 -0
- package/dist/lib/terminology/terminology-code-repo.d.ts.map +1 -0
- package/dist/lib/terminology/valueset-repo.d.ts +76 -0
- package/dist/lib/terminology/valueset-repo.d.ts.map +1 -0
- package/dist/lib/transaction/bundle-processor.d.ts +84 -0
- package/dist/lib/transaction/bundle-processor.d.ts.map +1 -0
- package/dist/lib/transaction/urn-resolver.d.ts +62 -0
- package/dist/lib/transaction/urn-resolver.d.ts.map +1 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/package.json +87 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
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] - 2025-03-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
#### Storage Layer
|
|
13
|
+
- `StorageAdapter` interface — unified async database abstraction
|
|
14
|
+
- `SQLiteAdapter` — sql.js (WASM) implementation for cross-platform use
|
|
15
|
+
- `BetterSqlite3Adapter` — native better-sqlite3 implementation for production Node.js
|
|
16
|
+
- `SQLiteDialect` / PostgreSQL dialect support for DDL generation
|
|
17
|
+
|
|
18
|
+
#### CRUD & Persistence
|
|
19
|
+
- `FhirStore` — basic CRUD with soft delete and version tracking
|
|
20
|
+
- `FhirPersistence` — end-to-end facade with automatic search indexing
|
|
21
|
+
- `ConditionalService` — conditionalCreate / conditionalUpdate / conditionalDelete
|
|
22
|
+
- `BundleProcessorV2` — FHIR transaction and batch bundle processing
|
|
23
|
+
- Resource versioning with `versionId` auto-increment
|
|
24
|
+
- History tracking via dedicated `_History` tables
|
|
25
|
+
|
|
26
|
+
#### Search
|
|
27
|
+
- `SearchParameterRegistry` — index FHIR SearchParameter bundles
|
|
28
|
+
- `parseSearchRequest` — parse FHIR search URL query parameters
|
|
29
|
+
- `buildSearchSQLv2` — generate SQL with `?` placeholders (SQLite + PG compatible)
|
|
30
|
+
- `buildWhereClauseV2` — chain search support (`subject:Patient.birthdate=...`)
|
|
31
|
+
- `SearchPlanner` — filter reordering, chain depth validation, two-phase recommendation
|
|
32
|
+
- `buildTwoPhaseSearchSQLv2` — id-first query for large table performance
|
|
33
|
+
- `SearchExecutor` — `_include`, `_revinclude`, recursive `_include:iterate` (max depth 3)
|
|
34
|
+
- `SearchBundleBuilder` — FHIR Bundle response construction with pagination
|
|
35
|
+
|
|
36
|
+
#### Indexing
|
|
37
|
+
- `IndexingPipeline` — automatic search column population on CRUD
|
|
38
|
+
- `RuntimeProvider` bridge — FHIRPath-driven extraction via `fhir-runtime`
|
|
39
|
+
- `buildSearchColumns` — fallback property-path extraction
|
|
40
|
+
- `extractReferencesV2` — reference extraction and indexing
|
|
41
|
+
- `LookupTableWriter` — HumanName, Address, ContactPoint, Identifier lookup tables
|
|
42
|
+
- Column strategy, token-column strategy, lookup-table strategy
|
|
43
|
+
|
|
44
|
+
#### Schema & Migration
|
|
45
|
+
- `StructureDefinitionRegistry` — register and resolve FHIR StructureDefinitions
|
|
46
|
+
- `buildResourceTableSet` — StructureDefinition + SearchParameter → table schema
|
|
47
|
+
- DDL generators for Main, History, References tables + indexes
|
|
48
|
+
- `compareSchemas` — schema diff between old and new table sets
|
|
49
|
+
- `generateMigration` — diff → DDL migration statements
|
|
50
|
+
- `MigrationRunnerV2` — execute migrations with `StorageAdapter`
|
|
51
|
+
- `IGPersistenceManager` — three-way branch (new / upgrade / consistent)
|
|
52
|
+
- `PackageRegistryRepo` — multi-version package tracking with checksum
|
|
53
|
+
- `ReindexScheduler` — schedule reindex jobs for SP expression changes
|
|
54
|
+
|
|
55
|
+
#### Terminology
|
|
56
|
+
- `TerminologyCodeRepo` — code system concept storage
|
|
57
|
+
- `ValueSetRepo` — value set expansion storage
|
|
58
|
+
|
|
59
|
+
#### Platform IG
|
|
60
|
+
- Built-in platform resource types: User, Bot, Project, Agent, ClientApplication
|
|
61
|
+
- `initializePlatformIG` — auto-register platform search parameters
|
|
62
|
+
|
|
63
|
+
#### Provider Bridges (for fhir-engine)
|
|
64
|
+
- `FhirDefinitionBridge` — wraps `fhir-definition` `DefinitionRegistry` → `DefinitionProvider`
|
|
65
|
+
- `FhirRuntimeProvider` — wraps `fhir-runtime` `FhirRuntimeInstance` → `RuntimeProvider`
|
|
66
|
+
- `FhirSystem` — end-to-end startup orchestrator
|
|
67
|
+
|
|
68
|
+
#### Production
|
|
69
|
+
- `ResourceCacheV2` — in-memory resource cache with TTL
|
|
70
|
+
- `SearchLogger` — search query logging and diagnostics
|
|
71
|
+
- `reindexResourceTypeV2` / `reindexAllV2` — CLI reindex utilities
|
|
72
|
+
|
|
73
|
+
### Dependencies
|
|
74
|
+
- `fhir-definition` ^0.5.0
|
|
75
|
+
- `fhir-runtime` ^0.8.1
|
|
76
|
+
- `better-sqlite3` ^12.6.2
|
|
77
|
+
- `sql.js` ^1.14.1
|
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,225 @@
|
|
|
1
|
+
# fhir-persistence
|
|
2
|
+
|
|
3
|
+
Embedded FHIR R4 persistence layer — CRUD, search, indexing, and schema migration over SQLite and PostgreSQL.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/fhir-persistence)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **StorageAdapter abstraction** — unified async interface for SQLite and PostgreSQL
|
|
11
|
+
- **Two SQLite adapters** — `BetterSqlite3Adapter` (native, production) + `SQLiteAdapter` (sql.js WASM, cross-platform)
|
|
12
|
+
- **3-table-per-resource pattern** — Main + History + References tables per FHIR resource type
|
|
13
|
+
- **Automatic search indexing** — column, token-column, and lookup-table strategies
|
|
14
|
+
- **FHIRPath-driven extraction** — optional `RuntimeProvider` bridge for `fhir-runtime` powered indexing
|
|
15
|
+
- **Chain search** — `subject:Patient.birthdate=1990-01-15`
|
|
16
|
+
- **\_include / \_revinclude** — with recursive `_include:iterate` support (max depth 3)
|
|
17
|
+
- **Search planner** — filter reordering, chain depth validation, two-phase SQL recommendation
|
|
18
|
+
- **Two-phase SQL** — id-first query for large table performance
|
|
19
|
+
- **IG-driven schema** — StructureDefinition + SearchParameter → DDL (SQLite + PostgreSQL dialects)
|
|
20
|
+
- **Migration engine** — SchemaDiff → MigrationGenerator → MigrationRunnerV2
|
|
21
|
+
- **Conditional operations** — conditionalCreate / conditionalUpdate / conditionalDelete
|
|
22
|
+
- **Bundle processing** — transaction and batch bundle support
|
|
23
|
+
- **Terminology** — TerminologyCodeRepo + ValueSetRepo
|
|
24
|
+
- **FhirSystem orchestrator** — end-to-end startup flow for `fhir-engine` integration
|
|
25
|
+
- **Provider bridges** — `FhirDefinitionBridge` + `FhirRuntimeProvider` for `fhir-definition` / `fhir-runtime`
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install fhir-persistence
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Peer dependencies:**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install fhir-definition fhir-runtime
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
### Standalone (low-level)
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import {
|
|
45
|
+
SQLiteAdapter,
|
|
46
|
+
FhirPersistence,
|
|
47
|
+
SearchParameterRegistry,
|
|
48
|
+
} from "fhir-persistence";
|
|
49
|
+
|
|
50
|
+
// 1. Create storage adapter
|
|
51
|
+
const adapter = new SQLiteAdapter(":memory:");
|
|
52
|
+
|
|
53
|
+
// 2. Create search parameter registry
|
|
54
|
+
const spRegistry = new SearchParameterRegistry();
|
|
55
|
+
spRegistry.indexBundle(searchParameterBundle);
|
|
56
|
+
|
|
57
|
+
// 3. Create persistence facade
|
|
58
|
+
const persistence = new FhirPersistence({
|
|
59
|
+
adapter,
|
|
60
|
+
searchParameterRegistry: spRegistry,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// 4. CRUD with automatic indexing
|
|
64
|
+
const patient = await persistence.createResource("Patient", {
|
|
65
|
+
resourceType: "Patient",
|
|
66
|
+
name: [{ family: "Smith", given: ["John"] }],
|
|
67
|
+
birthDate: "1990-01-15",
|
|
68
|
+
active: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const result = await persistence.searchResources({
|
|
72
|
+
resourceType: "Patient",
|
|
73
|
+
queryParams: {
|
|
74
|
+
birthdate: "ge1990-01-01",
|
|
75
|
+
active: "true",
|
|
76
|
+
_sort: "-birthdate",
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### With FhirSystem (recommended for fhir-engine)
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { BetterSqlite3Adapter, FhirSystem, FhirDefinitionBridge } from 'fhir-persistence';
|
|
85
|
+
import { loadDefinitionPackages } from 'fhir-definition';
|
|
86
|
+
import { createRuntime } from 'fhir-runtime';
|
|
87
|
+
|
|
88
|
+
// 1. Load FHIR definitions
|
|
89
|
+
const { registry } = loadDefinitionPackages('./fhir-packages');
|
|
90
|
+
|
|
91
|
+
// 2. Create runtime with definitions
|
|
92
|
+
const runtime = await createRuntime({ definitions: registry });
|
|
93
|
+
|
|
94
|
+
// 3. Create adapter + bridges
|
|
95
|
+
const adapter = new BetterSqlite3Adapter({ path: './fhir.db' });
|
|
96
|
+
const definitionBridge = new FhirDefinitionBridge(registry);
|
|
97
|
+
|
|
98
|
+
// 4. Bootstrap via FhirSystem
|
|
99
|
+
const system = new FhirSystem(adapter, { dialect: 'sqlite' });
|
|
100
|
+
const { persistence, sdRegistry, spRegistry, igResult } =
|
|
101
|
+
await system.initialize(definitionBridge);
|
|
102
|
+
|
|
103
|
+
// 5. Use persistence
|
|
104
|
+
const patient = await persistence.createResource('Patient', { resourceType: 'Patient', ... });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Architecture
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
StorageAdapter (SQLite / better-sqlite3 / PostgreSQL)
|
|
111
|
+
└── FhirPersistence (end-to-end facade)
|
|
112
|
+
├── FhirStore (basic CRUD + soft delete + versioning)
|
|
113
|
+
├── IndexingPipeline
|
|
114
|
+
│ ├── RuntimeProvider (FHIRPath extraction, optional)
|
|
115
|
+
│ ├── buildSearchColumns (fallback row indexer)
|
|
116
|
+
│ ├── extractReferencesV2 (reference indexer)
|
|
117
|
+
│ └── LookupTableWriter (HumanName/Address/ContactPoint/Identifier)
|
|
118
|
+
├── ConditionalService (conditional CRUD)
|
|
119
|
+
├── BundleProcessorV2 (transaction / batch)
|
|
120
|
+
├── SearchParameterRegistry
|
|
121
|
+
└── Search Engine
|
|
122
|
+
├── WhereBuilder v2 (chain search, ? placeholders)
|
|
123
|
+
├── SearchPlanner (filter reorder, two-phase recommendation)
|
|
124
|
+
├── SearchSQLBuilder v2 (single-phase + two-phase)
|
|
125
|
+
├── SearchExecutor (_include / _revinclude / _include:iterate)
|
|
126
|
+
└── SearchBundleBuilder
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Storage Adapters
|
|
130
|
+
|
|
131
|
+
| Adapter | Backend | Use Case |
|
|
132
|
+
| ---------------------- | ----------------------- | --------------------------------- |
|
|
133
|
+
| `BetterSqlite3Adapter` | better-sqlite3 (native) | Production Node.js, CLI, Electron |
|
|
134
|
+
| `SQLiteAdapter` | sql.js (WASM) | Browser, cross-platform, testing |
|
|
135
|
+
| `PostgresAdapter` | pg | Production server |
|
|
136
|
+
|
|
137
|
+
## Search
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import {
|
|
141
|
+
parseSearchRequest,
|
|
142
|
+
buildSearchSQLv2,
|
|
143
|
+
planSearch,
|
|
144
|
+
} from "fhir-persistence";
|
|
145
|
+
|
|
146
|
+
// Parse search URL
|
|
147
|
+
const request = parseSearchRequest(
|
|
148
|
+
"Patient",
|
|
149
|
+
{
|
|
150
|
+
birthdate: "ge1990-01-01",
|
|
151
|
+
active: "true",
|
|
152
|
+
_sort: "-birthdate",
|
|
153
|
+
_count: "50",
|
|
154
|
+
},
|
|
155
|
+
registry,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// Single-phase SQL
|
|
159
|
+
const sql = buildSearchSQLv2(request, registry);
|
|
160
|
+
|
|
161
|
+
// Two-phase SQL for large tables
|
|
162
|
+
const plan = planSearch(request, registry, { estimatedRowCount: 100_000 });
|
|
163
|
+
if (plan.useTwoPhase) {
|
|
164
|
+
const { phase1, phase2Template } = buildTwoPhaseSearchSQLv2(
|
|
165
|
+
plan.request,
|
|
166
|
+
registry,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Chain search
|
|
171
|
+
const chainRequest = parseSearchRequest(
|
|
172
|
+
"Observation",
|
|
173
|
+
{
|
|
174
|
+
"subject:Patient.birthdate": "ge1990-01-01",
|
|
175
|
+
},
|
|
176
|
+
registry,
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Schema Migration
|
|
181
|
+
|
|
182
|
+
The IG persistence manager automatically handles schema evolution:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
import { IGPersistenceManager } from "fhir-persistence";
|
|
186
|
+
|
|
187
|
+
const igManager = new IGPersistenceManager(adapter, "sqlite");
|
|
188
|
+
const result = await igManager.initialize({
|
|
189
|
+
name: "hl7.fhir.r4.core",
|
|
190
|
+
version: "4.0.1",
|
|
191
|
+
checksum: contentChecksum,
|
|
192
|
+
tableSets: generatedTableSets,
|
|
193
|
+
});
|
|
194
|
+
// result.action: 'new' | 'upgrade' | 'consistent'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Integration with fhir-engine
|
|
198
|
+
|
|
199
|
+
`fhir-persistence` is designed to be bootstrapped by `fhir-engine`:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { createFhirEngine } from "fhir-engine";
|
|
203
|
+
|
|
204
|
+
const engine = await createFhirEngine({
|
|
205
|
+
database: { type: "sqlite", url: "./fhir.db" },
|
|
206
|
+
packages: { path: "./fhir-packages" },
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// engine.persistence — FhirPersistence instance
|
|
210
|
+
// engine.definitions — DefinitionRegistry
|
|
211
|
+
// engine.runtime — FhirRuntimeInstance
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Dependencies
|
|
215
|
+
|
|
216
|
+
| Package | Role |
|
|
217
|
+
| ----------------- | ---------------------------------------------------------------------- |
|
|
218
|
+
| `fhir-definition` | StructureDefinition, SearchParameter, ValueSet, CodeSystem definitions |
|
|
219
|
+
| `fhir-runtime` | FHIRPath evaluation, validation, search value extraction |
|
|
220
|
+
| `better-sqlite3` | Native SQLite bindings (production) |
|
|
221
|
+
| `sql.js` | WebAssembly SQLite (cross-platform) |
|
|
222
|
+
|
|
223
|
+
## License
|
|
224
|
+
|
|
225
|
+
[MIT](./LICENSE)
|