PROforma is a clinical decision support system (CDSS) language (see Sutton and Fox 2003). PROformajs is a lightweight javascript PROforma engine, written in Javascript.
Getting started
PROformajs is a library intended to be embedded in other applications. The easiest way to get started is by trying the online demonstrator. However, if you are a developer then the REPL can be used to get your hands on the API. With Nodejs (v6+) and Git installed you can first clone the repository, install the dependencies and start it up:
you@yourmachine:~$ git clone https://gitlab.com/openclinical/proformajs.git
you@yourmachine:~$ cd proformajs
you@yourmachine:~$ npm install
you@yourmachine:~$ npm run build
you@yourmachine:~$ npm run repl
> @openclinical/proformajs@0.4.3 repl /home/you/Software/proformajs
> node src/repl.js
PROformajs Copyright (C) 2017 Openclinical CIC
This program comes with ABSOLUTELY NO WARRANTY;
This is free software, and you are welcome to
redistribute it under certain conditions;
This is a Javascript REPL with pre-loaded modules:
* Protocol
* Enactment
* Moment
PROforma>
Protocols and Enactments
Protocols
are the design-time representation of guidelines that consist of a tree of tasks
and data definitions. Runtime enactments of a protocol are created with the
Enactment module which uses the Moment library
to handle date and time calculations. The REPL has pre-loaded Protocol
, Enactment
and Moment
modules.
To create a very simple protocol you can create a single demo task. Type
protocol = new Protocol.Task({name: 'demo'})
at the cursor. You should see:
PROforma> protocol = new Protocol.Task({name:'demo'})
Task {
preCondition: undefined,
waitCondition: undefined,
abortCondition: undefined,
eventTrigger: undefined,
cycleUntil: undefined,
name: 'demo',
caption: undefined,
description: undefined,
_parent: undefined,
meta: undefined,
optional: false,
autonomous: false,
cyclic: false,
dataDefinitions: []
}
and use that protocol to create a runtime enactment:
PROforma> enactment = new Enactment({start:true, protocol: protocol})
Enactment {
protocol: Task {
preCondition: undefined,
waitCondition: undefined,
abortCondition: undefined,
eventTrigger: undefined,
cycleUntil: undefined,
name: 'demo',
caption: undefined,
description: undefined,
_parent: undefined,
meta: undefined,
optional: false,
autonomous: false,
cyclic: false,
dataDefinitions: []
},
options: undefined,
listeners: {},
_state: {
demo: TaskState {
state: 'in_progress',
completeable: true,
cancellable: true,
index: undefined,
cycleable: true,
path: 'demo',
_enactment: [Circular],
design: 'demo'
}
},
_data: {},
_audit: [
{
action: 'start',
timestamp: 2019-08-19T15:51:43.872Z,
deltas: [Array]
}
],
_triggers: {},
tickInterval: undefined,
stackLimit: 1000
}
The getStatus
method shows options available. Ours is a simple protocol and
there's only two things that can be done, completing or cancelling the 'demo' task.
PROforma> enactment.getStatus()
{ started: true,
finished: false,
completeable: [ 'demo' ],
cancellable: [ 'demo' ],
warnings: [],
requested: {},
confirmable: {},
triggers: []
}
Enactment has a chainable interface so completing the task returns the updated
enactment which is now finished, as is seen when we chain the getStatus
method.
PROforma> enactment.complete('demo').getStatus()
{ started: true, finished: true }
Serialisation
Both protocols and enactments can be serialised to JSON with JSON.stringify and deserialised with a static inflate method, e.g.
PROforma> json = JSON.stringify(protocol)
'{"class":"Task","name":"demo"}'
PROforma> Protocol.inflate(json)
Task {
preCondition: undefined,
waitCondition: undefined,
abortCondition: undefined,
eventTrigger: undefined,
cycleUntil: undefined,
name: 'demo',
caption: undefined,
description: undefined,
_parent: undefined,
meta: undefined,
optional: false,
autonomous: false,
cyclic: false,
dataDefinitions: [] }