import { reactive, watch } from 'vue'; import vista from './vista.mjs'; import cookie from './cookie.mjs'; import { lab_parse, lab_reparse_results, measurement_parse } from './reportparser.mjs'; export const state = reactive(cookie.get('state') ? JSON.parse(cookie.get('state')) : {}); if((!state.secret) && (cookie.get('secret'))) state.resources = cookie.get('secret'); if((!state.cid) && (cookie.get('cid'))) state.resources = cookie.get('cid'); if((!state.host) && (cookie.get('host'))) state.resources = cookie.get('host'); if((!state.resources) && (cookie.get('vista.resources'))) state.resources = cookie.get('vista.resources'); if((!state.practitioner) && (cookie.get('vista.practitioner'))) state.practitioner = JSON.parse(cookie.get('vista.practitioner')); watch(state, value => cookie.set('state', JSON.stringify(value), 45), { immediate: true, deep: true }); function RPCError(type, ...args) { this.name = type; this.message = args; } RPCError.prototype = Object.create(Error.prototype); export function logged(fn, name) { return async function(...args) { var res = await fn(...args); console.log(name, ...args, res); return res; } } export function unwrapped(fn) { return async function(...args) { var res = await fn(...args); if(res.error) throw new RPCError(res.error.type, ...res.error.args); else return res.result; } } export function memoized(fn) { var cache = {}; return async function(...args) { var key = JSON.stringify(args); return cache.hasOwnProperty(key) ? cache[key] : (cache[key] = await fn(...args)); } } export function caretseparated(fn, columns=null) { return async function(...args) { if(columns) return (await fn(...args)).map(function(row) { row = row.split('^'); for(var i = columns.length - 1; i >= 0; --i) if(columns[i]) row[columns[i]] = row[i]; return row; }); else return (await fn(...args)).map(function(row) { return row.split('^'); }); } } export function caretseparated1(fn, columns=null) { return async function(...args) { var res = (await fn(...args)).split('^'); if(columns) for(var i = columns.length - 1; i >= 0; --i) if(columns[i]) res[columns[i]] = res[i]; return res; } } export function labreportparsed(fn) { return async function(...args) { return lab_parse(await fn(...args)); } } export function tabulated(fn, mapping) { return async function(...args) { var res = (await fn(...args)).map(function(row) { return row.slice(); }), nrow = res.length; for(var i = 0; i < nrow; ++i) { var row = res[i], ncol = row.length; for(var j = 0; j < ncol; ++j) if(mapping.hasOwnProperty(j)) row[mapping[j]] = row[j]; res.push() } return res; } } export function Client(cid, secret) { var heartbeat = null; this.secret = secret; this.cid = cid; this.close = function() { if(heartbeat) window.clearInterval(heartbeat); return vista.close(cid); }; this.call = (method, ...params) => vista.call(cid, method, ...params); this.callctx = (context, method, ...params) => vista.callctx(cid, context, method, ...params); this.heartbeat = async function(interval=null) { if(!interval) interval = 0.45*1000*(await this.XWB_GET_BROKER_INFO())[0]; if(heartbeat) window.clearInterval(heartbeat); this.XWB_IM_HERE(); return heartbeat = window.setInterval(this.XWB_IM_HERE, interval); } this.serverinfo = () => vista.serverinfo(cid); this.userinfo = () => vista.userinfo(cid); this.authenticate = (avcode=null) => vista.authenticate(cid, avcode); this.XWB_IM_HERE = unwrapped(logged(() => vista.call(cid, 'XWB_IM_HERE'), 'XWB_IM_HERE')); this.XUS_INTRO_MSG = memoized(unwrapped(logged(() => vista.callctx(cid, ['XUCOMMAND'], 'XUS_INTRO_MSG'), 'XUS_INTRO_MSG'))); this.XWB_GET_BROKER_INFO = memoized(unwrapped(logged(() => vista.callctx(cid, ['XUCOMMAND'], 'XWB_GET_BROKER_INFO'), 'XWB_GET_BROKER_INFO'))); this.XUS_GET_USER_INFO = memoized(unwrapped(logged(() => vista.call(cid, 'XUS_GET_USER_INFO'), 'XUS_GET_USER_INFO'))); this.SDEC_RESOURCE = memoized(unwrapped(logged(() => vista.callctx(cid, ['SDECRPC'], 'SDEC_RESOURCE'), 'SDEC_RESOURCE'))); this.SDEC_CLINLET = memoized(unwrapped(logged((...args) => vista.callctx(cid, ['SDECRPC'], 'SDEC_CLINLET', ...args), 'SDEC_CLINLET'))); this.ORWPT_FULLSSN = memoized(caretseparated(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORWPT_FULLSSN', ...args), 'ORWPT_FULLSSN')), ['dfn', 'name', 'date', 'pid'])); this.ORWPT_LAST5 = memoized(caretseparated(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORWPT_LAST5', ...args), 'ORWPT_LAST5')), ['dfn', 'name', 'date', 'pid'])); this.ORWPT_ID_INFO = memoized(caretseparated1(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORWPT_ID_INFO', ...args), 'ORWPT_ID_INFO')), ['pid', 'dob', 'sex', 'vet', 'sc_percentage', 'ward', 'room_bed', 'name'])); this.ORWPT16_LOOKUP = memoized(caretseparated(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORWPT16_LOOKUP', ...args), 'ORWPT16_LOOKUP')), ['dfn', 'name', 'pid'])); this.ORWPT16_ID_INFO = memoized(caretseparated1(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORWPT16_ID_INFO', ...args), 'ORWPT16_ID_INFO')), ['pid', 'dob', 'age', 'sex', 'sc_percentage', 'type', 'ward', 'room_bed', 'name'])); this.ORQQVI_VITALS = memoized(caretseparated(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORQQVI_VITALS', ...args), 'ORQQVI_VITALS')), ['measurement_ien', 'type', 'value', 'datetime', 'value_american', 'value_metric'])); this.ORQQVI_VITALS_FOR_DATE_RANGE = memoized(caretseparated(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORQQVI_VITALS_FOR_DATE_RANGE', ...args), 'ORQQVI_VITALS_FOR_DATE_RANGE')), ['measurement_ien', 'type', 'value', 'datetime'])); this.GMV_EXTRACT_REC = memoized(async (dfn, oredt, orsdt) => measurement_parse(await unwrapped(logged((...args0) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'GMV_EXTRACT_REC', args0.join('^')), 'GMV_EXTRACT_REC'))(dfn, oredt, '', orsdt))); this.ORWLRR_INTERIM = memoized(labreportparsed(unwrapped(logged((...args) => vista.callctx(cid, ['OR CPRS GUI CHART'], 'ORWLRR_INTERIM', ...args), 'ORWLRR_INTERIM')))); this.ORWLRR_INTERIM_RESULTS = memoized(async (...args) => lab_reparse_results(await this.ORWLRR_INTERIM(...args))); return this; } Client._registry = {}; Client.fromID = function(cid, secret) { if(Client._registry[cid]) return Client._registry[cid]; return Client._registry[cid] = new Client(cid, secret); }; Client.fromScratch = async function(secret, host='vista.northport.med.va.gov', port=19209) { var data = await vista.connect(secret, host, port); if(data.result) return Client.fromID(data.result, secret); }; Client.fromCookie = async function(secret, defaulthost='vista.northport.med.va.gov:19209') { if(!secret) secret = state.secret; if(secret) { var host = state.host; host = (host || defaulthost).split(':'); if(secret != state.secret) { console.log('Using new secret', secret); var client = await Client.fromScratch(secret, host[0], host[1]); if(client) { state.host = host.join(':'); state.secret = secret; state.cid = client.cid; console.log('Established connection', client.cid); return client; } else { delete state.secret; delete state.cid; console.log('Failed to connect'); return null; } } else if(!state.cid) { console.log('Using saved secret', secret); var client = await Client.fromScratch(secret, host[0], host[1]); if(client) { state.host = host.join(':'); state.secret = secret; state.cid = client.cid; console.log('Established connection', client.cid); return client; } else { delete state.secret; delete state.cid; console.log('Failed connection'); return null; } } else { console.log('Using saved secret and connection', secret); var cid = state.cid; var client = Client.fromID(cid, secret); if((await vista.call(cid, 'XWB_IM_HERE')).result == '1') { var server = await client.serverinfo(); if((host[0] == server.result.host) && (host[1] == server.result.port)) { state.host = host.join(':'); return client; } else console.log('Rejecting previous connection to different server', server); } delete state.cid; return await Client.fromCookie(secret, host.join(':')); } } }; export default window.vistax = { state, RPCError, Client, connect: Client.fromCookie };