Skip to content

Commit 3002a74

Browse files
Merge branch 'feature/LF-2985/async-functions' into 'master'
Added support for async functions See merge request lfor/fhirpath.js!17
2 parents 3cd1c87 + 07fffc5 commit 3002a74

20 files changed

+3688
-7627
lines changed

Diff for: .eslintrc.yml

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ parserOptions:
88
ecmaVersion: 2016
99
requireConfigFile: false
1010
sourceType: module
11+
globals:
12+
Headers: true
13+
fetch: true
1114
rules:
1215
indent:
1316
- error

Diff for: CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
This log documents significant changes for each release. This project follows
44
[Semantic Versioning](http://semver.org/).
55

6+
## [3.15.0] - 2024-08-05
7+
### Added
8+
- option `async`, which allows us to get the result of an expression evaluation
9+
asynchronously.
10+
- Support for asynchronous functions: if any function in an expression returns
11+
a Promise and option `async=true`, then the result of evaluating
12+
the expression is a Promise.
13+
- async function `memberOf`.
14+
615
## [3.14.1] - 2024-07-02
716
### Fixed
817
- impossibility to use attribute name that starts with a capital letter.

Diff for: README.md

+70-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
# fhirpath.js
22

3-
[![Build Status](https://travis-ci.org/HL7/fhirpath.js.svg?branch=master)](https://travis-ci.org/HL7/fhirpath.js)
4-
53
[FHIRPath](http://hl7.org/fhirpath/) implementation in JavaScript.
64

75
## Demo
86
Try it out on the [demo page](https://hl7.github.io/fhirpath.js/).
97

10-
8+
## Table of Contents:
9+
- [Installation](#installation-)
10+
* [Server-side (Node.js)](#server-side--nodejs-)
11+
* [Web-browser](#web-browser-)
12+
- [API Usage](#api-usage)
13+
* [Asynchronous functions](#asynchronous-functions)
14+
* [User-defined functions](#user-defined-functions)
15+
- [fhirpath CLI](#fhirpath-cli)
16+
- [Implementation Status](#implementation-status)
17+
- [Development Notes](#development-notes)
18+
* [Building the demo page](#building-the-demo-page)
19+
* [Updating the FHIR module on a FHIR release](#updating-the-fhir-module-on-a-fhir-release)
20+
- [Credits](#credits)
1121

1222
## Installation:
1323

@@ -47,6 +57,37 @@ Evaluating FHIRPath:
4757
```js
4858
evaluate(resourceObject, fhirPathExpression, environment, model, options);
4959
```
60+
where:
61+
* resourceObject - FHIR resource, part of a resource (in this case
62+
fhirPathExpression.base should be provided), bundle as js object or array
63+
of resources.
64+
* fhirPathExpression - string with FHIRPath expression, sample 'Patient.name.given',
65+
or object, if fhirData represents the part of the FHIR resource:
66+
* fhirPathExpression.base - base path in resource from which fhirData was extracted
67+
* fhirPathExpression.expression - FHIRPath expression relative to path.base
68+
* environment - a hash of variable name/value pairs.
69+
* model - the "model" data object specific to a domain, e.g. R4.
70+
For example, you could pass in the result of require("fhirpath/fhir-context/r4");
71+
* options - additional options:
72+
* options.resolveInternalTypes - whether values of internal
73+
types should be converted to standard JavaScript types (true by default).
74+
If false is passed, this conversion can be done later by calling
75+
fhirpath.resolveInternalTypes().
76+
* options.traceFn - An optional trace function to call when tracing.
77+
* options.userInvocationTable - a user invocation table used
78+
to replace any existing functions or define new ones.
79+
* options.async - defines how to support asynchronous functions:
80+
* false or similar to false, e.g. undefined, null, or 0 (default) - throw
81+
an exception,
82+
* true or similar to true - return Promise, only for asynchronous functions,
83+
* "always" - return Promise always.
84+
* options.terminologyUrl - a URL that points to a FHIR RESTful API that is
85+
used to create %terminologies that implements the Terminology Service API.
86+
* options.terminologyUrl - a URL that points to a terminology server. This
87+
URL is used to initialize %terminologies, as defined in the FHIR FHIRPath
88+
[Terminology Service API](https://www.hl7.org/fhir/fhirpath.html#txapi).
89+
See the [Implementation Status](#implementation-status) section for the
90+
currently supported %terminologies APIs.
5091

5192
Note: The resource will be modified by this function to add type information.
5293

@@ -153,6 +194,27 @@ let tracefunction = function (x, label) {
153194
const res = fhirpath.evaluate(contextNode, path, environment, fhirpath_r4_model, { traceFn: tracefunction });
154195
```
155196
197+
### Asynchronous functions
198+
199+
Some FHIRPath functions may be asynchronous. These functions throw exceptions by default.
200+
To enable these functions, we need to pass the `async` option to `evaluate` or `compile`.
201+
`async=true` enables return of a Promise only for expressions containing asynchronous functions.
202+
`async='always'` enables a Promise to be returned for any expression.
203+
204+
For example, using the `memberOf` function might look like this:
205+
```js
206+
fhirpath.evaluate(
207+
resource,
208+
"Observation.code.coding.where(memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult'))",
209+
{},
210+
model,
211+
{ async: true, terminologyUrl: 'https://lforms-fhir.nlm.nih.gov/baseR4' }
212+
)
213+
```
214+
215+
Please note that for the `memberOf` function to work you must pass in
216+
a terminologyUrl option.
217+
156218
### User-defined functions
157219
158220
You can also replace any existing functions or define new ones. To do this you
@@ -327,6 +389,11 @@ Completed sections:
327389
Supported additional functions from FHIR:
328390
- extension(url : string) : collection
329391
- hasValue() : Boolean
392+
- memberOf(valueset : string) : Boolean
393+
394+
Supported Terminology Service APIs (https://build.fhir.org/fhirpath.html#txapi):
395+
- only `%terminologies.validateVS(valueSet, coded, params) : Parameters` is
396+
partially supported. `valueSet` can only be a URL.
330397
331398
## Development Notes
332399

Diff for: bashrc.fhirpath

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# The following is the standard bashrc file for the
22
# development team for this repository.
33

4-
NODE=node-v16.15.0-linux-x64
4+
NODE=node-v18.14.2-linux-x64
55
#
66
# Set path
77
PATH=~/${NODE}/bin:/bin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/etc

Diff for: bin/fhirpath

+20-3
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,25 @@ else {
4545
throw new Error('FHIR model must be one of '+supportedVersions);
4646
model = require('../fhir-context/'+options.model);
4747
}
48-
let res = fp.evaluate(resource, base ? {base, expression} : expression, context, model);
49-
console.log('fhirpath(' + expression + ') =>');
50-
console.log(JSON.stringify(res, null, " "));
48+
let res = fp.evaluate(
49+
resource, base ? {base, expression} : expression, context, model,
50+
{ async: true }
51+
);
52+
53+
if (res instanceof Promise) {
54+
res.then((r) => printResult(expression, r))
55+
} else {
56+
printResult(expression, res);
57+
}
5158
}
5259
}
60+
61+
/**
62+
* Prints the result to the console.
63+
* @param {string} expression - input expression
64+
* @param {Array} result - result of evaluating the expression
65+
*/
66+
function printResult(expression, result) {
67+
console.log('fhirpath(' + expression + ') =>');
68+
console.log(JSON.stringify(result, null, " "));
69+
}

0 commit comments

Comments
 (0)