@nsshunt/stsfhirpg 1.1.7 → 1.2.2
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/dist/stsfhirpg.cjs +226 -536
- package/dist/stsfhirpg.cjs.map +1 -1
- package/dist/stsfhirpg.mjs +228 -538
- package/dist/stsfhirpg.mjs.map +1 -1
- package/package.json +2 -3
- package/types/fhir-database/dbsearchindex.d.ts +1 -7
- package/types/fhir-database/dbsearchindex.d.ts.map +1 -1
- package/types/fhir-utils/resourceHelper.d.ts +8 -1
- package/types/fhir-utils/resourceHelper.d.ts.map +1 -1
- package/types/index.d.ts +0 -2
- package/types/index.d.ts.map +1 -1
- package/types/redisDistributedLock.d.ts +0 -36
- package/types/redisDistributedLock.d.ts.map +0 -1
- package/types/searchParameterManager.d.ts +0 -13
- package/types/searchParameterManager.d.ts.map +0 -1
package/dist/stsfhirpg.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import { defaultLogger
|
|
2
|
+
import { defaultLogger } from "@nsshunt/stsutils";
|
|
3
3
|
import { isAbsoluteUrl } from "@nsshunt/stsfhirclient";
|
|
4
4
|
import { goptions } from "@nsshunt/stsconfig";
|
|
5
5
|
import cluster from "cluster";
|
|
6
|
-
import require$$0
|
|
6
|
+
import require$$0 from "crypto";
|
|
7
7
|
import require$$0$3 from "events";
|
|
8
8
|
import require$$1$1 from "util";
|
|
9
9
|
import require$$0$2 from "dns";
|
|
@@ -13,7 +13,6 @@ import require$$1$2 from "tls";
|
|
|
13
13
|
import require$$0$7 from "path";
|
|
14
14
|
import require$$0$6 from "stream";
|
|
15
15
|
import require$$0$5 from "buffer";
|
|
16
|
-
import { createClient } from "redis";
|
|
17
16
|
class LuxonError extends Error {
|
|
18
17
|
}
|
|
19
18
|
class InvalidDateTimeError extends LuxonError {
|
|
@@ -7024,7 +7023,8 @@ class ResourceHelper {
|
|
|
7024
7023
|
this.#definitions = {
|
|
7025
7024
|
resources: {},
|
|
7026
7025
|
types: {},
|
|
7027
|
-
|
|
7026
|
+
searchParametersByUrl: {},
|
|
7027
|
+
searchParametersByResourceType: {}
|
|
7028
7028
|
};
|
|
7029
7029
|
}
|
|
7030
7030
|
__resources.entry.forEach((entry) => {
|
|
@@ -7041,25 +7041,22 @@ class ResourceHelper {
|
|
|
7041
7041
|
}
|
|
7042
7042
|
});
|
|
7043
7043
|
__searchParams.entry.forEach((entry) => {
|
|
7044
|
-
this.#definitions.
|
|
7044
|
+
this.#definitions.searchParametersByUrl[entry.fullUrl] = entry.resource;
|
|
7045
7045
|
});
|
|
7046
|
+
this._LoadSearchParameters();
|
|
7046
7047
|
return this.#definitions;
|
|
7047
7048
|
};
|
|
7048
|
-
|
|
7049
|
+
get definitions() {
|
|
7049
7050
|
if (!this.#definitions) {
|
|
7050
7051
|
this.#LoadDefinitions();
|
|
7051
7052
|
}
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
return [];
|
|
7053
|
+
return this.#definitions;
|
|
7054
|
+
}
|
|
7055
|
+
GetType = (typeName) => {
|
|
7056
|
+
return this.definitions.types[typeName];
|
|
7057
7057
|
};
|
|
7058
7058
|
GetResource = (resourceType) => {
|
|
7059
|
-
|
|
7060
|
-
this.#LoadDefinitions();
|
|
7061
|
-
}
|
|
7062
|
-
return this.#definitions.resources[resourceType];
|
|
7059
|
+
return this.definitions.resources[resourceType];
|
|
7063
7060
|
};
|
|
7064
7061
|
GetResourceField = (resourceType, fieldPath) => {
|
|
7065
7062
|
const resource = this.GetResource(resourceType);
|
|
@@ -7072,22 +7069,215 @@ class ResourceHelper {
|
|
|
7072
7069
|
}
|
|
7073
7070
|
};
|
|
7074
7071
|
GetSearchParam = (url) => {
|
|
7075
|
-
|
|
7076
|
-
this.#LoadDefinitions();
|
|
7077
|
-
}
|
|
7078
|
-
return this.#definitions.searchParameters[url];
|
|
7072
|
+
return this.definitions.searchParametersByUrl[url];
|
|
7079
7073
|
};
|
|
7080
7074
|
GetSearchParams = () => {
|
|
7081
|
-
|
|
7082
|
-
this.#LoadDefinitions();
|
|
7083
|
-
}
|
|
7084
|
-
return this.#definitions.searchParameters;
|
|
7075
|
+
return this.definitions.searchParametersByUrl;
|
|
7085
7076
|
};
|
|
7086
7077
|
GetSearchParamsByResource = (resource) => {
|
|
7087
|
-
|
|
7088
|
-
|
|
7078
|
+
return Object.values(this.definitions.searchParametersByUrl).filter((sp) => sp.base.includes(resource)).map((sp) => sp);
|
|
7079
|
+
};
|
|
7080
|
+
// ------------------------------------------------------------------------------------------------------------------
|
|
7081
|
+
// Remove ( ) when either are present
|
|
7082
|
+
#RemoveOuterParentheses = (input) => {
|
|
7083
|
+
return input.replace(/^\(|\)$/g, "");
|
|
7084
|
+
};
|
|
7085
|
+
// Remove ( ) only when both are present
|
|
7086
|
+
#RemoveSurroundingParentheses = (input) => {
|
|
7087
|
+
return input.replace(/^\((.*)\)$/, "$1").trim();
|
|
7088
|
+
};
|
|
7089
|
+
/*
|
|
7090
|
+
|
|
7091
|
+
NamingSystem derived-from reference NamingSystem.relatedArtifact.where(type='derived-from').resource
|
|
7092
|
+
|
|
7093
|
+
NamingSystem predecessor reference NamingSystem.relatedArtifact.where(type='predecessor').resource
|
|
7094
|
+
|
|
7095
|
+
ClinicalUseDefinition product reference ClinicalUseDefinition.subject.where(resolve() is MedicinalProductDefinition)
|
|
7096
|
+
|
|
7097
|
+
OrganizationAffiliation email token OrganizationAffiliation.contact.telecom.where(system='email')
|
|
7098
|
+
OrganizationAffiliation phone token OrganizationAffiliation.contact.telecom.where(system='phone')
|
|
7099
|
+
|
|
7100
|
+
PackagedProductDefinition biological reference PackagedProductDefinition.packaging.containedItem.item.reference
|
|
7101
|
+
PackagedProductDefinition contained-item reference PackagedProductDefinition.packaging.containedItem.item.reference
|
|
7102
|
+
|
|
7103
|
+
Patient deceased token Patient.deceased.exists() and Patient.deceased != false
|
|
7104
|
+
Practitioner deceased token Practitioner.deceased.exists() and Practitioner.deceased != false
|
|
7105
|
+
|
|
7106
|
+
Location contains special Location.extension('http://hl7.org/fhir/StructureDefinition/location-boundary-geojson').value
|
|
7107
|
+
|
|
7108
|
+
QuestionnaireResponse item-subject reference QuestionnaireResponse.item.where(extension('http://hl7.org/fhir/StructureDefinition/questionnaireresponse-isSubject').exists()).answer.valueReference
|
|
7109
|
+
*/
|
|
7110
|
+
ProcessExpressions = (resourceName, SP_EXPRESSION) => {
|
|
7111
|
+
let expressions = [];
|
|
7112
|
+
expressions = SP_EXPRESSION.split("|").map((e) => e.trim());
|
|
7113
|
+
expressions = expressions.map((e) => this.#RemoveSurroundingParentheses(e).trim());
|
|
7114
|
+
if (resourceName !== "") {
|
|
7115
|
+
expressions = expressions.filter((e) => e.split(".")[0].trim().localeCompare(resourceName) === 0);
|
|
7089
7116
|
}
|
|
7090
|
-
|
|
7117
|
+
let original_expressions = [...expressions];
|
|
7118
|
+
expressions = expressions.map((e) => {
|
|
7119
|
+
let capturedTypeOf = void 0;
|
|
7120
|
+
return {
|
|
7121
|
+
path: e.replace(
|
|
7122
|
+
/\.ofType\(([^)]+)\)/g,
|
|
7123
|
+
(_, typeName) => {
|
|
7124
|
+
capturedTypeOf = true;
|
|
7125
|
+
return typeName.charAt(0).toUpperCase() + typeName.slice(1);
|
|
7126
|
+
}
|
|
7127
|
+
),
|
|
7128
|
+
typeOf: capturedTypeOf
|
|
7129
|
+
};
|
|
7130
|
+
});
|
|
7131
|
+
expressions.forEach((expression) => {
|
|
7132
|
+
try {
|
|
7133
|
+
const sp = expression;
|
|
7134
|
+
if (sp.path.indexOf("exists()") >= 0) {
|
|
7135
|
+
const parts = sp.path.split(" ");
|
|
7136
|
+
const i = parts[0].indexOf("exists()");
|
|
7137
|
+
if (i >= 0) {
|
|
7138
|
+
let fieldExistsEx = parts[0].substring(0, i - 1);
|
|
7139
|
+
let op = parts[1];
|
|
7140
|
+
let fieldTestEx = parts[2];
|
|
7141
|
+
let comparator = parts[3];
|
|
7142
|
+
let value = parts[4];
|
|
7143
|
+
const fieldExistsParts = fieldExistsEx.split(".");
|
|
7144
|
+
let fieldExists = fieldExistsParts.slice(1).join(".");
|
|
7145
|
+
const fieldTestParts = fieldTestEx.split(".");
|
|
7146
|
+
let fieldTest = fieldTestParts.slice(1).join(".");
|
|
7147
|
+
sp.exists = {
|
|
7148
|
+
fieldExists: [`${fieldExists}Boolean`, `${fieldExists}DataTime`],
|
|
7149
|
+
// [x]Boolean or [x]DateTime
|
|
7150
|
+
op,
|
|
7151
|
+
fieldTest: [`${fieldTest}Boolean`, `${fieldTest}DataTime`],
|
|
7152
|
+
comparator,
|
|
7153
|
+
value: [value, void 0]
|
|
7154
|
+
};
|
|
7155
|
+
}
|
|
7156
|
+
}
|
|
7157
|
+
} catch (error) {
|
|
7158
|
+
}
|
|
7159
|
+
});
|
|
7160
|
+
let capturedType;
|
|
7161
|
+
expressions = expressions.map((obj) => {
|
|
7162
|
+
capturedType = void 0;
|
|
7163
|
+
const { path, typeOf, exists } = obj;
|
|
7164
|
+
return {
|
|
7165
|
+
path: path.replace(
|
|
7166
|
+
/\.where\(resolve\(\)\s+is\s+([^)]+)\)/,
|
|
7167
|
+
(_, typeName) => {
|
|
7168
|
+
capturedType = typeName;
|
|
7169
|
+
return "";
|
|
7170
|
+
}
|
|
7171
|
+
),
|
|
7172
|
+
typeOf,
|
|
7173
|
+
reference: capturedType,
|
|
7174
|
+
exists
|
|
7175
|
+
};
|
|
7176
|
+
});
|
|
7177
|
+
let capturedWhere = void 0;
|
|
7178
|
+
expressions = expressions.map((obj) => {
|
|
7179
|
+
capturedWhere = void 0;
|
|
7180
|
+
const { path, reference, typeOf, exists } = obj;
|
|
7181
|
+
const retVal = {
|
|
7182
|
+
path: path.replace(/([^.]+)\.where\(([^=]+)='([^']+)'\)/g, (_, field, subfield, value) => {
|
|
7183
|
+
capturedWhere = { field, subfield, value };
|
|
7184
|
+
return field;
|
|
7185
|
+
}),
|
|
7186
|
+
typeOf,
|
|
7187
|
+
reference,
|
|
7188
|
+
exists
|
|
7189
|
+
};
|
|
7190
|
+
if (capturedWhere) {
|
|
7191
|
+
capturedWhere.full = `${capturedWhere.field}[*].${capturedWhere.subfield}=${capturedWhere.value}`;
|
|
7192
|
+
retVal.where = capturedWhere;
|
|
7193
|
+
}
|
|
7194
|
+
return retVal;
|
|
7195
|
+
});
|
|
7196
|
+
return {
|
|
7197
|
+
expressions,
|
|
7198
|
+
original_expressions
|
|
7199
|
+
};
|
|
7200
|
+
};
|
|
7201
|
+
_LoadSearchParameters = () => {
|
|
7202
|
+
for (const [key, val] of Object.entries(this.GetSearchParams())) {
|
|
7203
|
+
const { id, url, code, base, type, expression, component, target } = val;
|
|
7204
|
+
for (let i = 0; i < base.length; i++) {
|
|
7205
|
+
const resourceName = base[i];
|
|
7206
|
+
if (!this.#definitions?.searchParametersByResourceType[resourceName]) {
|
|
7207
|
+
this.#definitions.searchParametersByResourceType[resourceName] = {
|
|
7208
|
+
resourceName,
|
|
7209
|
+
params: []
|
|
7210
|
+
};
|
|
7211
|
+
}
|
|
7212
|
+
const SP_ID = id;
|
|
7213
|
+
const SP_NAME = code;
|
|
7214
|
+
const SP_TYPE = type;
|
|
7215
|
+
const SP_URL = url;
|
|
7216
|
+
const SP_TARGET = target;
|
|
7217
|
+
let SP_EXPRESSION = expression;
|
|
7218
|
+
let expressions = [];
|
|
7219
|
+
let original_expressions = [];
|
|
7220
|
+
if (SP_EXPRESSION) {
|
|
7221
|
+
const retVal = this.ProcessExpressions(resourceName, SP_EXPRESSION);
|
|
7222
|
+
expressions = retVal.expressions;
|
|
7223
|
+
original_expressions = retVal.original_expressions;
|
|
7224
|
+
}
|
|
7225
|
+
const record = {
|
|
7226
|
+
SP_ID,
|
|
7227
|
+
SP_NAME,
|
|
7228
|
+
SP_TYPE,
|
|
7229
|
+
SP_URL,
|
|
7230
|
+
SP_TARGET,
|
|
7231
|
+
expressions,
|
|
7232
|
+
original_expressions,
|
|
7233
|
+
SP_DEFINITION: this.GetSearchParam(SP_URL)
|
|
7234
|
+
};
|
|
7235
|
+
for (let i2 = 0; i2 < record.expressions.length; i2++) {
|
|
7236
|
+
const rf = this.GetResourceField(resourceName, record.expressions[i2].path);
|
|
7237
|
+
if (rf) {
|
|
7238
|
+
expressions[i2].RES_FIELD = rf;
|
|
7239
|
+
}
|
|
7240
|
+
}
|
|
7241
|
+
if (component) {
|
|
7242
|
+
record.component = [...component];
|
|
7243
|
+
record.component.forEach((c) => {
|
|
7244
|
+
const retVal = this.ProcessExpressions("", c.expression);
|
|
7245
|
+
c.expressions = retVal.expressions;
|
|
7246
|
+
c.original_expressions = retVal.original_expressions;
|
|
7247
|
+
const def = this.GetSearchParam(c.definition);
|
|
7248
|
+
if (def && def.type) {
|
|
7249
|
+
c.type = def.type;
|
|
7250
|
+
}
|
|
7251
|
+
});
|
|
7252
|
+
}
|
|
7253
|
+
this.#definitions.searchParametersByResourceType[resourceName].params.push(record);
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
7256
|
+
};
|
|
7257
|
+
GetSearchParamFromResourceTypeUrl = (resourceType, url) => {
|
|
7258
|
+
const filterByNameAndUrl = this.definitions.searchParametersByResourceType[resourceType].params.filter((rt) => rt.SP_URL.localeCompare(url) === 0);
|
|
7259
|
+
if (filterByNameAndUrl.length > 0) {
|
|
7260
|
+
return filterByNameAndUrl[0];
|
|
7261
|
+
}
|
|
7262
|
+
};
|
|
7263
|
+
/*
|
|
7264
|
+
GetSearchParamFromResourceType = (resourceType: string, name: string): ISearchParamRecord | undefined => {
|
|
7265
|
+
const filterByName = this.definitions.searchParametersByResourceType[resourceType].params.filter(rt => rt.SP_NAME.localeCompare(name) === 0);
|
|
7266
|
+
if (filterByName.length > 0) {
|
|
7267
|
+
return filterByName[0];
|
|
7268
|
+
}
|
|
7269
|
+
}
|
|
7270
|
+
|
|
7271
|
+
GetPathsFromResourceType = (resourceType: string, name: string): string[] => {
|
|
7272
|
+
const filterByName = this.definitions.searchParametersByResourceType[resourceType].params.filter(rt => rt.SP_NAME.localeCompare(name) === 0);
|
|
7273
|
+
if (filterByName.length > 0) {
|
|
7274
|
+
return filterByName[0].expressions.map(e => e.path)
|
|
7275
|
+
}
|
|
7276
|
+
return [ ];
|
|
7277
|
+
}
|
|
7278
|
+
*/
|
|
7279
|
+
GetSearchParamsFromResourceType = (resourceType) => {
|
|
7280
|
+
return this.definitions.searchParametersByResourceType[resourceType].params;
|
|
7091
7281
|
};
|
|
7092
7282
|
}
|
|
7093
7283
|
var ansiStyles = { exports: {} };
|
|
@@ -10565,7 +10755,7 @@ class DBSearchIndexComposite extends DBSearchIndexBase {
|
|
|
10565
10755
|
searchFieldRecord.component.forEach((searchParamComponentRecord) => {
|
|
10566
10756
|
components.push([]);
|
|
10567
10757
|
const url = searchParamComponentRecord.definition;
|
|
10568
|
-
const sp = searchIndex.GetSearchParamFromResourceTypeUrl(resource.resourceType, url);
|
|
10758
|
+
const sp = searchIndex.resourceHelper.GetSearchParamFromResourceTypeUrl(resource.resourceType, url);
|
|
10569
10759
|
if (this.IsDefined(sp)) {
|
|
10570
10760
|
const tir2 = {
|
|
10571
10761
|
PID: v4(),
|
|
@@ -11220,27 +11410,13 @@ class DBSearchIndex {
|
|
|
11220
11410
|
return [];
|
|
11221
11411
|
}
|
|
11222
11412
|
};
|
|
11223
|
-
ResolveFhirChoiceType = (path) => {
|
|
11224
|
-
const match2 = path.match(/^(.+?)\.ofType\((.+?)\)$/);
|
|
11225
|
-
if (!match2) {
|
|
11226
|
-
return path;
|
|
11227
|
-
}
|
|
11228
|
-
const base = match2[1];
|
|
11229
|
-
const fhirType = match2[2];
|
|
11230
|
-
const capitalizedType = fhirType.charAt(0).toUpperCase() + fhirType.slice(1);
|
|
11231
|
-
return `${base}${capitalizedType}`;
|
|
11232
|
-
};
|
|
11233
11413
|
GetSearchIndexData = (resource) => {
|
|
11234
11414
|
try {
|
|
11235
|
-
const
|
|
11236
|
-
if (!this.#searchParams) {
|
|
11237
|
-
this.LoadSearchParameters();
|
|
11238
|
-
}
|
|
11415
|
+
const searchParamRecords = this.resourceHelper.GetSearchParamsFromResourceType(resource.resourceType);
|
|
11239
11416
|
const searchIndexData = [];
|
|
11240
|
-
for (let i = 0; i <
|
|
11241
|
-
const searchRecord =
|
|
11417
|
+
for (let i = 0; i < searchParamRecords.length; i++) {
|
|
11418
|
+
const searchRecord = searchParamRecords[i];
|
|
11242
11419
|
try {
|
|
11243
|
-
const st2 = performance.now();
|
|
11244
11420
|
const retVal = this.UpdateIndex(resource, searchRecord);
|
|
11245
11421
|
if (retVal && retVal.length > 0) {
|
|
11246
11422
|
searchIndexData.push(...retVal);
|
|
@@ -11255,286 +11431,19 @@ class DBSearchIndex {
|
|
|
11255
11431
|
return [];
|
|
11256
11432
|
}
|
|
11257
11433
|
};
|
|
11258
|
-
GetSearchParamFromResourceTypeUrl = (resourceType, url) => {
|
|
11259
|
-
if (!this.#searchParams) {
|
|
11260
|
-
this.LoadSearchParameters();
|
|
11261
|
-
}
|
|
11262
|
-
const filterByNameAndUrl = this.#searchParams[resourceType].params.filter((rt) => rt.SP_URL.localeCompare(url) === 0);
|
|
11263
|
-
if (filterByNameAndUrl.length > 0) {
|
|
11264
|
-
return filterByNameAndUrl[0];
|
|
11265
|
-
}
|
|
11266
|
-
};
|
|
11267
|
-
GetSearchParamFromResourceType = (resourceType, name) => {
|
|
11268
|
-
if (!this.#searchParams) {
|
|
11269
|
-
this.LoadSearchParameters();
|
|
11270
|
-
}
|
|
11271
|
-
const filterByName = this.#searchParams[resourceType].params.filter((rt) => rt.SP_NAME.localeCompare(name) === 0);
|
|
11272
|
-
if (filterByName.length > 0) {
|
|
11273
|
-
return filterByName[0];
|
|
11274
|
-
}
|
|
11275
|
-
};
|
|
11276
|
-
GetPathsFromResourceType = (resourceType, name) => {
|
|
11277
|
-
if (!this.#searchParams) {
|
|
11278
|
-
this.LoadSearchParameters();
|
|
11279
|
-
}
|
|
11280
|
-
const filterByName = this.#searchParams[resourceType].params.filter((rt) => rt.SP_NAME.localeCompare(name) === 0);
|
|
11281
|
-
if (filterByName.length > 0) {
|
|
11282
|
-
return filterByName[0].expressions.map((e) => e.path);
|
|
11283
|
-
}
|
|
11284
|
-
return [];
|
|
11285
|
-
};
|
|
11286
|
-
// Remove ( ) when either are present
|
|
11287
|
-
#RemoveOuterParentheses = (input) => {
|
|
11288
|
-
return input.replace(/^\(|\)$/g, "");
|
|
11289
|
-
};
|
|
11290
|
-
// Remove ( ) only when both are present
|
|
11291
|
-
#RemoveSurroundingParentheses = (input) => {
|
|
11292
|
-
return input.replace(/^\((.*)\)$/, "$1").trim();
|
|
11293
|
-
};
|
|
11294
11434
|
/*
|
|
11295
|
-
|
|
11296
|
-
|
|
11297
|
-
|
|
11298
|
-
NamingSystem predecessor reference NamingSystem.relatedArtifact.where(type='predecessor').resource
|
|
11299
|
-
|
|
11300
|
-
ClinicalUseDefinition product reference ClinicalUseDefinition.subject.where(resolve() is MedicinalProductDefinition)
|
|
11301
|
-
|
|
11302
|
-
OrganizationAffiliation email token OrganizationAffiliation.contact.telecom.where(system='email')
|
|
11303
|
-
OrganizationAffiliation phone token OrganizationAffiliation.contact.telecom.where(system='phone')
|
|
11304
|
-
|
|
11305
|
-
PackagedProductDefinition biological reference PackagedProductDefinition.packaging.containedItem.item.reference
|
|
11306
|
-
PackagedProductDefinition contained-item reference PackagedProductDefinition.packaging.containedItem.item.reference
|
|
11307
|
-
|
|
11308
|
-
Patient deceased token Patient.deceased.exists() and Patient.deceased != false
|
|
11309
|
-
Practitioner deceased token Practitioner.deceased.exists() and Practitioner.deceased != false
|
|
11310
|
-
|
|
11311
|
-
Location contains special Location.extension('http://hl7.org/fhir/StructureDefinition/location-boundary-geojson').value
|
|
11312
|
-
|
|
11313
|
-
QuestionnaireResponse item-subject reference QuestionnaireResponse.item.where(extension('http://hl7.org/fhir/StructureDefinition/questionnaireresponse-isSubject').exists()).answer.valueReference
|
|
11314
|
-
*/
|
|
11315
|
-
ProcessExpressions = (resourceName, SP_EXPRESSION) => {
|
|
11316
|
-
let expressions = [];
|
|
11317
|
-
expressions = SP_EXPRESSION.split("|").map((e) => e.trim());
|
|
11318
|
-
expressions = expressions.map((e) => this.#RemoveSurroundingParentheses(e).trim());
|
|
11319
|
-
if (resourceName !== "") {
|
|
11320
|
-
expressions = expressions.filter((e) => e.split(".")[0].trim().localeCompare(resourceName) === 0);
|
|
11321
|
-
}
|
|
11322
|
-
let original_expressions = [...expressions];
|
|
11323
|
-
expressions = expressions.map((e) => {
|
|
11324
|
-
let capturedTypeOf = void 0;
|
|
11325
|
-
return {
|
|
11326
|
-
path: e.replace(
|
|
11327
|
-
/\.ofType\(([^)]+)\)/g,
|
|
11328
|
-
(_, typeName) => {
|
|
11329
|
-
capturedTypeOf = true;
|
|
11330
|
-
return typeName.charAt(0).toUpperCase() + typeName.slice(1);
|
|
11331
|
-
}
|
|
11332
|
-
),
|
|
11333
|
-
typeOf: capturedTypeOf
|
|
11334
|
-
};
|
|
11335
|
-
});
|
|
11336
|
-
expressions.forEach((expression) => {
|
|
11337
|
-
try {
|
|
11338
|
-
const sp = expression;
|
|
11339
|
-
if (sp.path.indexOf("exists()") >= 0) {
|
|
11340
|
-
const parts = sp.path.split(" ");
|
|
11341
|
-
const i = parts[0].indexOf("exists()");
|
|
11342
|
-
if (i >= 0) {
|
|
11343
|
-
let fieldExistsEx = parts[0].substring(0, i - 1);
|
|
11344
|
-
let op = parts[1];
|
|
11345
|
-
let fieldTestEx = parts[2];
|
|
11346
|
-
let comparator = parts[3];
|
|
11347
|
-
let value = parts[4];
|
|
11348
|
-
const fieldExistsParts = fieldExistsEx.split(".");
|
|
11349
|
-
let fieldExists = fieldExistsParts.slice(1).join(".");
|
|
11350
|
-
const fieldTestParts = fieldTestEx.split(".");
|
|
11351
|
-
let fieldTest = fieldTestParts.slice(1).join(".");
|
|
11352
|
-
sp.exists = {
|
|
11353
|
-
fieldExists: [`${fieldExists}Boolean`, `${fieldExists}DataTime`],
|
|
11354
|
-
// [x]Boolean or [x]DateTime
|
|
11355
|
-
op,
|
|
11356
|
-
fieldTest: [`${fieldTest}Boolean`, `${fieldTest}DataTime`],
|
|
11357
|
-
comparator,
|
|
11358
|
-
value: [value, void 0]
|
|
11359
|
-
};
|
|
11360
|
-
}
|
|
11361
|
-
}
|
|
11362
|
-
} catch (error) {
|
|
11435
|
+
GetSearchParamFromResourceTypeUrl = (resourceType: string, url: string): ISearchParamRecord | undefined => {
|
|
11436
|
+
return this.resourceHelper.GetSearchParamFromResourceTypeUrl(resourceType, url);
|
|
11363
11437
|
}
|
|
11364
|
-
});
|
|
11365
|
-
let capturedType;
|
|
11366
|
-
expressions = expressions.map((obj) => {
|
|
11367
|
-
capturedType = void 0;
|
|
11368
|
-
const { path, typeOf, exists } = obj;
|
|
11369
|
-
return {
|
|
11370
|
-
path: path.replace(
|
|
11371
|
-
/\.where\(resolve\(\)\s+is\s+([^)]+)\)/,
|
|
11372
|
-
(_, typeName) => {
|
|
11373
|
-
capturedType = typeName;
|
|
11374
|
-
return "";
|
|
11375
|
-
}
|
|
11376
|
-
),
|
|
11377
|
-
typeOf,
|
|
11378
|
-
reference: capturedType,
|
|
11379
|
-
exists
|
|
11380
|
-
};
|
|
11381
|
-
});
|
|
11382
|
-
let capturedWhere = void 0;
|
|
11383
|
-
expressions = expressions.map((obj) => {
|
|
11384
|
-
capturedWhere = void 0;
|
|
11385
|
-
const { path, reference, typeOf, exists } = obj;
|
|
11386
|
-
const retVal = {
|
|
11387
|
-
path: path.replace(/([^.]+)\.where\(([^=]+)='([^']+)'\)/g, (_, field, subfield, value) => {
|
|
11388
|
-
capturedWhere = { field, subfield, value };
|
|
11389
|
-
return field;
|
|
11390
|
-
}),
|
|
11391
|
-
typeOf,
|
|
11392
|
-
reference,
|
|
11393
|
-
exists
|
|
11394
|
-
};
|
|
11395
|
-
if (capturedWhere) {
|
|
11396
|
-
capturedWhere.full = `${capturedWhere.field}[*].${capturedWhere.subfield}=${capturedWhere.value}`;
|
|
11397
|
-
retVal.where = capturedWhere;
|
|
11398
|
-
}
|
|
11399
|
-
return retVal;
|
|
11400
|
-
});
|
|
11401
|
-
return {
|
|
11402
|
-
expressions,
|
|
11403
|
-
original_expressions
|
|
11404
|
-
};
|
|
11405
|
-
};
|
|
11406
|
-
LoadSearchParameters = () => {
|
|
11407
|
-
const searchParamData = {};
|
|
11408
|
-
for (const [key, val] of Object.entries(this.resourceHelper.GetSearchParams())) {
|
|
11409
|
-
const { id, url, code, base, type, expression, component, target } = val;
|
|
11410
|
-
for (let i = 0; i < base.length; i++) {
|
|
11411
|
-
const resourceName = base[i];
|
|
11412
|
-
if (!searchParamData[resourceName]) {
|
|
11413
|
-
searchParamData[resourceName] = {
|
|
11414
|
-
resourceName,
|
|
11415
|
-
params: []
|
|
11416
|
-
};
|
|
11417
|
-
}
|
|
11418
|
-
const SP_ID = id;
|
|
11419
|
-
const SP_NAME = code;
|
|
11420
|
-
const SP_TYPE = type;
|
|
11421
|
-
const SP_URL = url;
|
|
11422
|
-
const SP_TARGET = target;
|
|
11423
|
-
let SP_EXPRESSION = expression;
|
|
11424
|
-
let expressions = [];
|
|
11425
|
-
let original_expressions = [];
|
|
11426
|
-
if (SP_EXPRESSION) {
|
|
11427
|
-
const retVal = this.ProcessExpressions(resourceName, SP_EXPRESSION);
|
|
11428
|
-
expressions = retVal.expressions;
|
|
11429
|
-
original_expressions = retVal.original_expressions;
|
|
11430
|
-
}
|
|
11431
|
-
const record = {
|
|
11432
|
-
SP_ID,
|
|
11433
|
-
SP_NAME,
|
|
11434
|
-
SP_TYPE,
|
|
11435
|
-
SP_URL,
|
|
11436
|
-
SP_TARGET,
|
|
11437
|
-
expressions,
|
|
11438
|
-
original_expressions,
|
|
11439
|
-
SP_DEFINITION: this.resourceHelper.GetSearchParam(SP_URL)
|
|
11440
|
-
};
|
|
11441
|
-
for (let i2 = 0; i2 < record.expressions.length; i2++) {
|
|
11442
|
-
const rf = this.resourceHelper.GetResourceField(resourceName, record.expressions[i2].path);
|
|
11443
|
-
if (rf) {
|
|
11444
|
-
expressions[i2].RES_FIELD = rf;
|
|
11445
|
-
}
|
|
11446
|
-
}
|
|
11447
|
-
if (component) {
|
|
11448
|
-
record.component = [...component];
|
|
11449
|
-
record.component.forEach((c) => {
|
|
11450
|
-
const retVal = this.ProcessExpressions("", c.expression);
|
|
11451
|
-
c.expressions = retVal.expressions;
|
|
11452
|
-
c.original_expressions = retVal.original_expressions;
|
|
11453
|
-
const def = this.resourceHelper.GetSearchParam(c.definition);
|
|
11454
|
-
if (def && def.type) {
|
|
11455
|
-
c.type = def.type;
|
|
11456
|
-
}
|
|
11457
|
-
});
|
|
11458
|
-
}
|
|
11459
|
-
searchParamData[resourceName].params.push(record);
|
|
11460
|
-
}
|
|
11461
|
-
}
|
|
11462
|
-
this.#searchParams = searchParamData;
|
|
11463
|
-
return searchParamData;
|
|
11464
|
-
};
|
|
11465
|
-
/*
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
for (const [resourceName,val] of Object.entries(searchParams)) {
|
|
11469
|
-
|
|
11470
|
-
const patientSearchList: Record<string, any> = (val as any).resourceSpecific;
|
|
11471
|
-
|
|
11472
|
-
for (const [key2,val2] of Object.entries(patientSearchList)) {
|
|
11473
|
-
|
|
11474
|
-
const SP_ID = val2.id;
|
|
11475
|
-
const SP_NAME = key2;
|
|
11476
|
-
const SP_TYPE = val2.type;
|
|
11477
|
-
const SP_URL = val2.url;
|
|
11478
|
-
let SP_EXPRESSION: string = val2.expression;
|
|
11479
|
-
let expressions: any[] = [];
|
|
11480
|
-
let original_expressions: any[] = [];
|
|
11481
|
-
if (SP_EXPRESSION) {
|
|
11482
|
-
const retVal = this.ProcessExpressions(resourceName, SP_EXPRESSION);
|
|
11483
|
-
expressions = retVal.expressions;
|
|
11484
|
-
original_expressions = retVal.original_expressions;
|
|
11485
|
-
}
|
|
11486
11438
|
|
|
11487
|
-
|
|
11488
|
-
|
|
11489
|
-
|
|
11490
|
-
params: [ ]
|
|
11491
|
-
}
|
|
11492
|
-
}
|
|
11493
|
-
|
|
11494
|
-
// GetResourceField
|
|
11495
|
-
|
|
11496
|
-
const record: ISearchParamRecord = {
|
|
11497
|
-
SP_ID,
|
|
11498
|
-
SP_NAME,
|
|
11499
|
-
SP_TYPE,
|
|
11500
|
-
SP_URL,
|
|
11501
|
-
expressions,
|
|
11502
|
-
original_expressions,
|
|
11503
|
-
SP_DEFINITION: this.resourceHelper.GetSearchParam(SP_URL)
|
|
11504
|
-
};
|
|
11505
|
-
|
|
11506
|
-
for (let i=0; i < record.expressions.length; i++) {
|
|
11507
|
-
//console.log(record.expressions[i]);
|
|
11508
|
-
const rf = this.resourceHelper.GetResourceField(resourceName, record.expressions[i].path);
|
|
11509
|
-
if (rf) {
|
|
11510
|
-
expressions[i].RES_FIELD = rf;
|
|
11511
|
-
}
|
|
11512
|
-
}
|
|
11513
|
-
|
|
11514
|
-
if (val2.component) {
|
|
11515
|
-
record.component = [ ...val2.component ];
|
|
11516
|
-
(record.component as any[]).forEach(c => {
|
|
11517
|
-
//c.SP_RAW_PATHS = (c.expression.split('|') as any[]).map(rp => rp.trim());
|
|
11518
|
-
//c.SP_PATHS = (c.SP_RAW_PATHS as any[]).map(rawPath => this.ResolveFhirChoiceType(rawPath));
|
|
11519
|
-
const retVal = this.ProcessExpressions('', c.expression);
|
|
11520
|
-
c.expressions = retVal.expressions;
|
|
11521
|
-
c.original_expressions = retVal.original_expressions;
|
|
11522
|
-
const def = this.resourceHelper.GetSearchParam(c.definition);
|
|
11523
|
-
if (def && def.type) {
|
|
11524
|
-
c.type = def.type
|
|
11525
|
-
}
|
|
11526
|
-
})
|
|
11527
|
-
}
|
|
11528
|
-
|
|
11529
|
-
searchParamData[resourceName].params.push(record);
|
|
11530
|
-
}
|
|
11531
|
-
}
|
|
11532
|
-
|
|
11533
|
-
this.#searchParams = searchParamData;
|
|
11439
|
+
GetSearchParamFromResourceType = (resourceType: string, name: string): ISearchParamRecord | undefined => {
|
|
11440
|
+
return this.resourceHelper.GetSearchParamFromResourceType(resourceType, name);
|
|
11441
|
+
}
|
|
11534
11442
|
|
|
11535
|
-
|
|
11443
|
+
GetPathsFromResourceType = (resourceType: string, name: string): string[] => {
|
|
11444
|
+
return this.resourceHelper.GetPathsFromResourceType(resourceType, name);
|
|
11536
11445
|
}
|
|
11537
|
-
|
|
11446
|
+
*/
|
|
11538
11447
|
}
|
|
11539
11448
|
var lib$1 = { exports: {} };
|
|
11540
11449
|
var defaults = { exports: {} };
|
|
@@ -18943,230 +18852,11 @@ class PGFhirAccessLayer extends tinyEmitterExports.TinyEmitter {
|
|
|
18943
18852
|
}
|
|
18944
18853
|
};
|
|
18945
18854
|
}
|
|
18946
|
-
const RELEASE_SCRIPT = `
|
|
18947
|
-
if redis.call("get", KEYS[1]) == ARGV[1] then
|
|
18948
|
-
return redis.call("del", KEYS[1])
|
|
18949
|
-
else
|
|
18950
|
-
return 0
|
|
18951
|
-
end
|
|
18952
|
-
`;
|
|
18953
|
-
const RENEW_SCRIPT = `
|
|
18954
|
-
if redis.call("get", KEYS[1]) == ARGV[1] then
|
|
18955
|
-
return redis.call("pexpire", KEYS[1], ARGV[2])
|
|
18956
|
-
else
|
|
18957
|
-
return 0
|
|
18958
|
-
end
|
|
18959
|
-
`;
|
|
18960
|
-
class RedisDistributedLock {
|
|
18961
|
-
client;
|
|
18962
|
-
ttlMs;
|
|
18963
|
-
heartbeatMs;
|
|
18964
|
-
keyPrefix;
|
|
18965
|
-
constructor(client2, options) {
|
|
18966
|
-
this.client = client2;
|
|
18967
|
-
this.ttlMs = options?.ttlMs ?? 3e4;
|
|
18968
|
-
this.heartbeatMs = options?.heartbeatMs ?? Math.floor(this.ttlMs / 3);
|
|
18969
|
-
this.keyPrefix = options?.keyPrefix ?? "lock:";
|
|
18970
|
-
if (this.ttlMs <= 0) {
|
|
18971
|
-
throw new Error("ttlMs must be > 0");
|
|
18972
|
-
}
|
|
18973
|
-
if (this.heartbeatMs <= 0) {
|
|
18974
|
-
throw new Error("heartbeatMs must be > 0");
|
|
18975
|
-
}
|
|
18976
|
-
if (this.heartbeatMs >= this.ttlMs) {
|
|
18977
|
-
throw new Error("heartbeatMs should be less than ttlMs");
|
|
18978
|
-
}
|
|
18979
|
-
}
|
|
18980
|
-
buildKey(name) {
|
|
18981
|
-
return `${this.keyPrefix}${name}`;
|
|
18982
|
-
}
|
|
18983
|
-
async acquire(name, ttlMs) {
|
|
18984
|
-
const key = this.buildKey(name);
|
|
18985
|
-
const token = randomUUID$1();
|
|
18986
|
-
const effectiveTtlMs = ttlMs ?? this.ttlMs;
|
|
18987
|
-
const result2 = await this.client.set(key, token, {
|
|
18988
|
-
NX: true,
|
|
18989
|
-
PX: effectiveTtlMs
|
|
18990
|
-
});
|
|
18991
|
-
if (result2 !== "OK") {
|
|
18992
|
-
return null;
|
|
18993
|
-
}
|
|
18994
|
-
return {
|
|
18995
|
-
key,
|
|
18996
|
-
token,
|
|
18997
|
-
ttlMs: effectiveTtlMs
|
|
18998
|
-
};
|
|
18999
|
-
}
|
|
19000
|
-
async release(lock) {
|
|
19001
|
-
const result2 = await this.client.eval(RELEASE_SCRIPT, {
|
|
19002
|
-
keys: [lock.key],
|
|
19003
|
-
arguments: [lock.token]
|
|
19004
|
-
});
|
|
19005
|
-
return Number(result2) === 1;
|
|
19006
|
-
}
|
|
19007
|
-
async renew(lock, ttlMs) {
|
|
19008
|
-
const effectiveTtlMs = ttlMs ?? lock.ttlMs;
|
|
19009
|
-
const result2 = await this.client.eval(RENEW_SCRIPT, {
|
|
19010
|
-
keys: [lock.key],
|
|
19011
|
-
arguments: [lock.token, String(effectiveTtlMs)]
|
|
19012
|
-
});
|
|
19013
|
-
return Number(result2) === 1;
|
|
19014
|
-
}
|
|
19015
|
-
async isOwner(lock) {
|
|
19016
|
-
const currentValue = await this.client.get(lock.key);
|
|
19017
|
-
return currentValue === lock.token;
|
|
19018
|
-
}
|
|
19019
|
-
async runExclusive(name, task, options) {
|
|
19020
|
-
const lock = await this.acquire(name, options?.ttlMs);
|
|
19021
|
-
if (!lock) {
|
|
19022
|
-
if (options?.onLockNotAcquired) {
|
|
19023
|
-
await options.onLockNotAcquired();
|
|
19024
|
-
}
|
|
19025
|
-
return { acquired: false };
|
|
19026
|
-
}
|
|
19027
|
-
let timer = null;
|
|
19028
|
-
let stopped = false;
|
|
19029
|
-
let renewalError = null;
|
|
19030
|
-
const autoRenew = options?.autoRenew ?? false;
|
|
19031
|
-
const heartbeatMs = options?.heartbeatMs ?? this.heartbeatMs;
|
|
19032
|
-
const stopHeartbeat = () => {
|
|
19033
|
-
stopped = true;
|
|
19034
|
-
if (timer) {
|
|
19035
|
-
clearInterval(timer);
|
|
19036
|
-
timer = null;
|
|
19037
|
-
}
|
|
19038
|
-
};
|
|
19039
|
-
if (autoRenew) {
|
|
19040
|
-
timer = setInterval(async () => {
|
|
19041
|
-
if (stopped) {
|
|
19042
|
-
return;
|
|
19043
|
-
}
|
|
19044
|
-
try {
|
|
19045
|
-
const ok = await this.renew(lock, lock.ttlMs);
|
|
19046
|
-
if (!ok) {
|
|
19047
|
-
renewalError = new Error(
|
|
19048
|
-
`Lost lock ownership while renewing "${lock.key}"`
|
|
19049
|
-
);
|
|
19050
|
-
stopHeartbeat();
|
|
19051
|
-
}
|
|
19052
|
-
} catch (err) {
|
|
19053
|
-
renewalError = err instanceof Error ? err : new Error(String(err));
|
|
19054
|
-
stopHeartbeat();
|
|
19055
|
-
}
|
|
19056
|
-
}, heartbeatMs).unref();
|
|
19057
|
-
}
|
|
19058
|
-
try {
|
|
19059
|
-
const result2 = await task();
|
|
19060
|
-
if (renewalError) {
|
|
19061
|
-
throw renewalError;
|
|
19062
|
-
}
|
|
19063
|
-
return { acquired: true, result: result2 };
|
|
19064
|
-
} finally {
|
|
19065
|
-
stopHeartbeat();
|
|
19066
|
-
try {
|
|
19067
|
-
await this.release(lock);
|
|
19068
|
-
} catch {
|
|
19069
|
-
}
|
|
19070
|
-
}
|
|
19071
|
-
}
|
|
19072
|
-
}
|
|
19073
|
-
class SearchParameterManager {
|
|
19074
|
-
redis;
|
|
19075
|
-
EnsureSearchParameterDataLoaded = async (name, loadFn, options) => {
|
|
19076
|
-
if (!this.redis) {
|
|
19077
|
-
const redisUrl = goptions.imRedisMessageProcessorUrl;
|
|
19078
|
-
console.log(`SearchParameterManager(): redis trying to connect ...`);
|
|
19079
|
-
this.redis = createClient({
|
|
19080
|
-
url: redisUrl
|
|
19081
|
-
});
|
|
19082
|
-
await this.redis.connect();
|
|
19083
|
-
console.log(`SearchParameterManager(): redis connected`);
|
|
19084
|
-
}
|
|
19085
|
-
try {
|
|
19086
|
-
const pollIntervalMs = options?.pollIntervalMs ?? 250;
|
|
19087
|
-
const lockTtlMs = options?.lockTtlMs ?? 3e4;
|
|
19088
|
-
const autoRenew = options?.autoRenew ?? true;
|
|
19089
|
-
const heartbeatMs = options?.heartbeatMs ?? 1e4;
|
|
19090
|
-
const completeTtlSeconds = options?.completeTtlSeconds;
|
|
19091
|
-
const timeoutMs = options?.timeoutMs;
|
|
19092
|
-
const completeKey = `fhir:searchparam:${name}:complete`;
|
|
19093
|
-
const startedAt = Date.now();
|
|
19094
|
-
const lockManager = new RedisDistributedLock(this.redis, {
|
|
19095
|
-
ttlMs: 3e4,
|
|
19096
|
-
heartbeatMs: 1e4,
|
|
19097
|
-
keyPrefix: "lock:"
|
|
19098
|
-
});
|
|
19099
|
-
while (true) {
|
|
19100
|
-
if (typeof timeoutMs === "number" && timeoutMs > 0) {
|
|
19101
|
-
const elapsedMs = Date.now() - startedAt;
|
|
19102
|
-
if (elapsedMs >= timeoutMs) {
|
|
19103
|
-
throw new Error(
|
|
19104
|
-
`Timed out waiting for search param "${name}" to be loaded`
|
|
19105
|
-
);
|
|
19106
|
-
}
|
|
19107
|
-
}
|
|
19108
|
-
try {
|
|
19109
|
-
const alreadyComplete = await this.redis.get(completeKey);
|
|
19110
|
-
if (alreadyComplete) {
|
|
19111
|
-
console.log(`ensureSearchParamLoaded():alreadyComplete: PID: [${process.pid}] data loaded: [${alreadyComplete}]`);
|
|
19112
|
-
return;
|
|
19113
|
-
}
|
|
19114
|
-
} catch (error) {
|
|
19115
|
-
console.error(error);
|
|
19116
|
-
throw error;
|
|
19117
|
-
}
|
|
19118
|
-
const runResult = await lockManager.runExclusive(
|
|
19119
|
-
`fhir:searchparam:${name}`,
|
|
19120
|
-
async () => {
|
|
19121
|
-
console.log(`ensureSearchParamLoaded(): PID: [${process.pid}] lock acquired`);
|
|
19122
|
-
const completeAfterLock = await this.redis.get(completeKey);
|
|
19123
|
-
if (completeAfterLock) {
|
|
19124
|
-
console.log(`ensureSearchParamLoaded():completeAfterLock: PID: [${process.pid}] data loaded: [${completeAfterLock}]`);
|
|
19125
|
-
return;
|
|
19126
|
-
}
|
|
19127
|
-
await loadFn();
|
|
19128
|
-
const completeValue = JSON.stringify({
|
|
19129
|
-
loaded: true,
|
|
19130
|
-
loadedAt: (/* @__PURE__ */ new Date()).toLocaleString(),
|
|
19131
|
-
name,
|
|
19132
|
-
workerPid: process.pid
|
|
19133
|
-
});
|
|
19134
|
-
console.log(`ensureSearchParamLoaded(): PID: [${process.pid}] data loaded: [${completeValue}]`);
|
|
19135
|
-
if (typeof completeTtlSeconds === "number" && completeTtlSeconds > 0) {
|
|
19136
|
-
await this.redis.set(completeKey, completeValue, {
|
|
19137
|
-
EX: completeTtlSeconds
|
|
19138
|
-
});
|
|
19139
|
-
} else {
|
|
19140
|
-
await this.redis.set(completeKey, completeValue);
|
|
19141
|
-
}
|
|
19142
|
-
},
|
|
19143
|
-
{
|
|
19144
|
-
ttlMs: lockTtlMs,
|
|
19145
|
-
autoRenew,
|
|
19146
|
-
heartbeatMs
|
|
19147
|
-
}
|
|
19148
|
-
);
|
|
19149
|
-
if (runResult.acquired) {
|
|
19150
|
-
return;
|
|
19151
|
-
}
|
|
19152
|
-
console.log(`ensureSearchParamLoaded(): PID: [${process.pid}] Did not get lock`);
|
|
19153
|
-
await Sleep(pollIntervalMs);
|
|
19154
|
-
}
|
|
19155
|
-
} finally {
|
|
19156
|
-
if (this.redis) {
|
|
19157
|
-
this.redis.close();
|
|
19158
|
-
console.log(`SearchParameterManager(): redis closed`);
|
|
19159
|
-
}
|
|
19160
|
-
}
|
|
19161
|
-
};
|
|
19162
|
-
}
|
|
19163
18855
|
export {
|
|
19164
18856
|
DBSearchIndex,
|
|
19165
18857
|
FHIRDateUtils,
|
|
19166
18858
|
PGFhirAccessLayer,
|
|
19167
|
-
RedisDistributedLock,
|
|
19168
18859
|
ResourceHelper,
|
|
19169
|
-
SearchParameterManager,
|
|
19170
18860
|
hashReferenceParam,
|
|
19171
18861
|
hashStringParam,
|
|
19172
18862
|
hashTokenParam,
|