ezmedicationinput 0.1.30 → 0.1.31

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/maps.js CHANGED
@@ -700,6 +700,7 @@ exports.EVENT_TIMING_TOKENS = {
700
700
  night: types_1.EventTiming.Night,
701
701
  hs: types_1.EventTiming["Before Sleep"],
702
702
  bedtime: types_1.EventTiming["Before Sleep"],
703
+ bed: types_1.EventTiming["Before Sleep"],
703
704
  wake: types_1.EventTiming.Wake,
704
705
  waking: types_1.EventTiming.Wake,
705
706
  stat: types_1.EventTiming.Immediate
package/dist/parser.js CHANGED
@@ -190,6 +190,9 @@ const COMBO_EVENT_TIMINGS = {
190
190
  "early evening": types_1.EventTiming["Early Evening"],
191
191
  "late evening": types_1.EventTiming["Late Evening"],
192
192
  "after sleep": types_1.EventTiming["After Sleep"],
193
+ "before bed": types_1.EventTiming["Before Sleep"],
194
+ "before bedtime": types_1.EventTiming["Before Sleep"],
195
+ "before sleep": types_1.EventTiming["Before Sleep"],
193
196
  "upon waking": types_1.EventTiming.Wake
194
197
  };
195
198
  const MEAL_CONTEXT_CONNECTORS = new Set(["and", "or", "&", "+", "plus"]);
@@ -781,39 +784,17 @@ function tryParseTimeBasedSchedule(internal, tokens, index) {
781
784
  const token = tokens[index];
782
785
  if (internal.consumed.has(token.index))
783
786
  return false;
784
- // Handle connectors like "and at" or just "and" before a time.
785
- // This prevents rogue "and" from leaking into Additional Instructions
786
- // when it serves as a connector between schedule parts.
787
- let isAndPrefix = false;
788
787
  let isAtPrefix = token.lower === "@" || token.lower === "at";
789
- if (token.lower === "and" && !isAtPrefix) {
790
- const next = tokens[index + 1];
791
- if (next && !internal.consumed.has(next.index)) {
792
- const nextLower = next.lower;
793
- // If "and" is followed by "at", "@", or a number, it's a connector for this time block
794
- if (nextLower === "@" || nextLower === "at" || /^\d/.test(nextLower)) {
795
- isAndPrefix = true;
796
- if (nextLower === "@" || nextLower === "at") {
797
- isAtPrefix = true;
798
- }
799
- }
800
- }
801
- }
802
- if (!isAtPrefix && !isAndPrefix && !/^\d/.test(token.lower))
788
+ if (!isAtPrefix && !/^\d/.test(token.lower))
803
789
  return false;
804
790
  let nextIndex = index;
805
- if (isAndPrefix)
806
- nextIndex++;
807
791
  if (isAtPrefix)
808
792
  nextIndex++;
809
793
  const times = [];
810
794
  const consumedIndices = [];
811
795
  const timeTokens = [];
812
- if (isAndPrefix)
813
- consumedIndices.push(index);
814
796
  if (isAtPrefix) {
815
- // If we have "and at", at is the second token (index + 1)
816
- consumedIndices.push(isAndPrefix ? index + 1 : index);
797
+ consumedIndices.push(index);
817
798
  }
818
799
  while (nextIndex < tokens.length) {
819
800
  const nextToken = tokens[nextIndex];
@@ -1518,6 +1499,20 @@ function applyWhenToken(internal, token, code) {
1518
1499
  addWhen(internal.when, code);
1519
1500
  mark(internal.consumed, token);
1520
1501
  }
1502
+ function isTimingAnchorOrPrefix(tokens, index) {
1503
+ const token = tokens[index];
1504
+ if (!token)
1505
+ return false;
1506
+ const lower = token.lower;
1507
+ const nextToken = tokens[index + 1];
1508
+ const comboKey = nextToken ? `${lower} ${nextToken.lower}` : undefined;
1509
+ return Boolean(maps_1.EVENT_TIMING_TOKENS[lower] ||
1510
+ maps_1.TIMING_ABBREVIATIONS[lower] ||
1511
+ (comboKey && COMBO_EVENT_TIMINGS[comboKey]) ||
1512
+ (lower === "pc" || lower === "ac" || lower === "after" || lower === "before") ||
1513
+ (lower === "at" || lower === "@" || lower === "on" || lower === "with") ||
1514
+ /^\d/.test(lower));
1515
+ }
1521
1516
  function parseAnchorSequence(internal, tokens, index, prefixCode) {
1522
1517
  var _a;
1523
1518
  const token = tokens[index];
@@ -1936,7 +1931,25 @@ function parseInternal(input, options) {
1936
1931
  if (tryParseCompactQ(internal, tokens, i)) {
1937
1932
  continue;
1938
1933
  }
1934
+ // Skip connectors if they are followed by recognized timing tokens or prefixes
1935
+ if (MEAL_CONTEXT_CONNECTORS.has(token.lower) || token.lower === ",") {
1936
+ if (isTimingAnchorOrPrefix(tokens, i + 1)) {
1937
+ mark(internal.consumed, token);
1938
+ continue;
1939
+ }
1940
+ }
1939
1941
  // Event timing tokens
1942
+ const nextToken = tokens[i + 1];
1943
+ if (nextToken && !internal.consumed.has(nextToken.index)) {
1944
+ const lowerNext = nextToken.lower;
1945
+ const combo = `${token.lower} ${lowerNext}`;
1946
+ const comboWhen = (_f = COMBO_EVENT_TIMINGS[combo]) !== null && _f !== void 0 ? _f : maps_1.EVENT_TIMING_TOKENS[combo];
1947
+ if (comboWhen) {
1948
+ applyWhenToken(internal, token, comboWhen);
1949
+ mark(internal.consumed, nextToken);
1950
+ continue;
1951
+ }
1952
+ }
1940
1953
  if (token.lower === "pc" || token.lower === "ac" || token.lower === "after" || token.lower === "before") {
1941
1954
  parseAnchorSequence(internal, tokens, i, (token.lower === "pc" || token.lower === "after")
1942
1955
  ? types_1.EventTiming["After Meal"]
@@ -1957,17 +1970,6 @@ function parseInternal(input, options) {
1957
1970
  continue;
1958
1971
  }
1959
1972
  }
1960
- const nextToken = tokens[i + 1];
1961
- if (nextToken && !internal.consumed.has(nextToken.index)) {
1962
- const lowerNext = nextToken.lower;
1963
- const combo = `${token.lower} ${lowerNext}`;
1964
- const comboWhen = (_f = COMBO_EVENT_TIMINGS[combo]) !== null && _f !== void 0 ? _f : maps_1.EVENT_TIMING_TOKENS[combo];
1965
- if (comboWhen) {
1966
- applyWhenToken(internal, token, comboWhen);
1967
- mark(internal.consumed, nextToken);
1968
- continue;
1969
- }
1970
- }
1971
1973
  const customWhen = (_g = options === null || options === void 0 ? void 0 : options.whenMap) === null || _g === void 0 ? void 0 : _g[token.lower];
1972
1974
  if (customWhen) {
1973
1975
  applyWhenToken(internal, token, customWhen);
@@ -3183,7 +3185,7 @@ function collectAdditionalInstructions(internal, tokens) {
3183
3185
  : undefined
3184
3186
  });
3185
3187
  }
3186
- else {
3188
+ else if (!MEAL_CONTEXT_CONNECTORS.has(phrase.toLowerCase())) {
3187
3189
  instructions.push({ text: phrase });
3188
3190
  }
3189
3191
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ezmedicationinput",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "Parse concise medication sigs into FHIR R5 Dosage JSON",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",