@bitcobblers/wod-wiki-wql 0.6.31 → 0.6.36

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/index.cjs CHANGED
@@ -55,7 +55,7 @@ var WQL_CALC_TARGETS = [
55
55
  "calc.sends"
56
56
  ];
57
57
  var WQL_INTENSITY_TIERS = ["low", "moderate", "high"];
58
- var WQL_GRAINS = ["segment", "summary", "rollup"];
58
+ var WQL_GRAINS = ["summary", "event"];
59
59
  var WQL_FIND_TARGETS = ["note", "block", "effort"];
60
60
  var WQL_SCOPES = ["journal", "collections", "feeds", "all"];
61
61
  var WQL_CONTENT_FILTER_KEYS = ["type", "text", "has", "source", "catalog", ...WQL_TAG_KEYS];
@@ -316,9 +316,20 @@ function parseRowsQuery(raw) {
316
316
  return result;
317
317
  }
318
318
  result.filters = extractFilters(tree.topNode, synthetic);
319
+ const grainError = retiredGrainRollup(result.filters);
320
+ if (grainError) {
321
+ result.error = grainError;
322
+ return result;
323
+ }
319
324
  }
320
325
  return result;
321
326
  }
327
+ function retiredGrainRollup(filters) {
328
+ if (filters.some((f) => f.key === "grain" && f.values.some((v) => v.value === "rollup"))) {
329
+ return "grain:rollup is retired \u2014 rollup grains are never stored; compute them with the .rollup suffix";
330
+ }
331
+ return void 0;
332
+ }
322
333
  function extractFilters(query, text) {
323
334
  const out = [];
324
335
  const filters = query.getChild(Filters);
@@ -387,6 +398,11 @@ function parseAnalyticsQuery(raw) {
387
398
  base.agg = aggText;
388
399
  base.metric = text.slice(metricNode.from, metricNode.to);
389
400
  base.filters = extractFilters(query, text);
401
+ const grainError = retiredGrainRollup(base.filters);
402
+ if (grainError) {
403
+ base.error = grainError;
404
+ return base;
405
+ }
390
406
  if (whereText) {
391
407
  const join = parseJoinClause(whereText);
392
408
  if (join.error) {
@@ -438,6 +454,11 @@ function parseFindQuery(raw) {
438
454
  }
439
455
  result.target = text.slice(metricNode.from, metricNode.to);
440
456
  result.filters = extractFilters(query, text);
457
+ const findGrainError = retiredGrainRollup(result.filters);
458
+ if (findGrainError) {
459
+ result.error = findGrainError;
460
+ return result;
461
+ }
441
462
  if (whereText) {
442
463
  const join = parseJoinClause(whereText);
443
464
  if (join.error) {
@@ -723,9 +744,8 @@ function readGroupTags(metadata) {
723
744
  const entries = Object.entries(tags).filter((pair) => typeof pair[1] === "string" && pair[1].length > 0).sort(([a], [b]) => a < b ? -1 : 1);
724
745
  return entries.length > 0 ? Object.fromEntries(entries) : void 0;
725
746
  }
726
- function normalizeSummaryFacts(logs, identity) {
727
- const now = Date.now();
728
- const rowsByKey = /* @__PURE__ */ new Map();
747
+ function foldSummaryOutputs(logs) {
748
+ const folded = /* @__PURE__ */ new Map();
729
749
  for (const output of logs) {
730
750
  if (output.outputType !== "analytics") continue;
731
751
  const label = output.metrics.find((m) => m.type === wodWikiCore.MetricType.Label);
@@ -740,32 +760,171 @@ function normalizeSummaryFacts(logs, identity) {
740
760
  const grade = metadataString(value.metadata, "grade");
741
761
  const groupTags = readGroupTags(value.metadata) ?? (effortSlug ? { effort: effortSlug } : void 0);
742
762
  const rowKey = groupTags ? `${metricKey}:${Object.entries(groupTags).map(([k, v]) => `${k}=${v}`).join(":")}` : metricKey;
743
- rowsByKey.set(rowKey, {
744
- id: `${identity.resultId}-${rowKey}-${now}`,
745
- noteId: identity.noteId,
746
- blockContentId: identity.blockContentId,
747
- origin: identity.origin,
748
- pageId: identity.pageId,
749
- grain: "summary",
750
- segmentId: identity.segmentId ?? "",
751
- segmentVersion: identity.segmentVersion ?? 0,
752
- resultId: identity.resultId,
753
- type: metricKey,
763
+ folded.set(rowKey, {
764
+ projectionName,
765
+ metricKey,
754
766
  value: value.value,
755
767
  unit: value.unit,
756
- label: projectionName,
757
- metricKey,
758
- metricLabel: projectionName,
759
- metricUnit: value.unit,
760
- ...effortSlug ? { effortSlug } : {},
761
- ...discipline ? { discipline } : {},
762
- ...intensityTier ? { intensityTier } : {},
763
- ...grade ? { grade } : {},
764
- timestamp: identity.workoutTimestamp ?? output.timeSpan?.started ?? now,
765
- createdAt: now
768
+ effortSlug,
769
+ discipline,
770
+ intensityTier,
771
+ grade,
772
+ groupTags,
773
+ rowKey,
774
+ started: output.timeSpan?.started
766
775
  });
767
776
  }
768
- return Array.from(rowsByKey.values());
777
+ return folded;
778
+ }
779
+ function normalizeSummaryFacts(logs, identity) {
780
+ const now = Date.now();
781
+ return Array.from(foldSummaryOutputs(logs).values(), (f) => ({
782
+ id: `${identity.resultId}-${f.rowKey}-${now}`,
783
+ noteId: identity.noteId,
784
+ blockContentId: identity.blockContentId,
785
+ origin: identity.origin,
786
+ pageId: identity.pageId,
787
+ grain: "summary",
788
+ segmentId: identity.segmentId ?? "",
789
+ segmentVersion: identity.segmentVersion ?? 0,
790
+ resultId: identity.resultId,
791
+ type: f.metricKey,
792
+ value: f.value,
793
+ unit: f.unit,
794
+ label: f.projectionName,
795
+ metricKey: f.metricKey,
796
+ metricLabel: f.projectionName,
797
+ metricUnit: f.unit,
798
+ ...f.effortSlug ? { effortSlug: f.effortSlug } : {},
799
+ ...f.discipline ? { discipline: f.discipline } : {},
800
+ ...f.intensityTier ? { intensityTier: f.intensityTier } : {},
801
+ ...f.grade ? { grade: f.grade } : {},
802
+ timestamp: identity.workoutTimestamp ?? f.started ?? now,
803
+ createdAt: now
804
+ }));
805
+ }
806
+ function firstEffortSlug(metrics) {
807
+ const loose = metrics;
808
+ for (const m of loose) {
809
+ const slug = metadataString(m.metadata, "effortSlug");
810
+ if (slug) return slug;
811
+ }
812
+ return void 0;
813
+ }
814
+ function toEventRows(logs, identity) {
815
+ return logs.map((output, seq) => ({
816
+ id: `${identity.resultId}:${seq}`,
817
+ resultId: identity.resultId,
818
+ noteId: identity.noteId,
819
+ blockContentId: identity.blockContentId,
820
+ pageId: identity.pageId,
821
+ origin: identity.origin,
822
+ timestamp: identity.workoutTimestamp ?? output.timeSpan?.started ?? Date.now(),
823
+ grain: "event",
824
+ outputType: output.outputType ?? "segment",
825
+ effortSlug: firstEffortSlug(output.metrics),
826
+ metrics: output.metrics,
827
+ timeSpan: output.timeSpan?.started !== void 0 ? { started: output.timeSpan.started, ended: output.timeSpan.ended } : void 0,
828
+ sourceBlockKey: output.sourceBlockKey,
829
+ stackLevel: output.stackLevel,
830
+ completionReason: output.completionReason,
831
+ segmentId: identity.segmentId,
832
+ segmentVersion: identity.segmentVersion
833
+ }));
834
+ }
835
+ function toSummaryEventRows(logs, identity) {
836
+ const now = Date.now();
837
+ return Array.from(foldSummaryOutputs(logs).values(), (f) => ({
838
+ id: `${identity.resultId}:summary:${f.rowKey}`,
839
+ resultId: identity.resultId,
840
+ noteId: identity.noteId,
841
+ blockContentId: identity.blockContentId,
842
+ pageId: identity.pageId,
843
+ origin: identity.origin,
844
+ timestamp: identity.workoutTimestamp ?? f.started ?? now,
845
+ grain: "summary",
846
+ outputType: "analytics",
847
+ effortSlug: f.effortSlug,
848
+ metrics: [{
849
+ type: f.metricKey,
850
+ value: f.value,
851
+ ...f.unit ? { unit: f.unit } : {},
852
+ metadata: {
853
+ canonicalKey: f.metricKey,
854
+ ...f.effortSlug ? { effortSlug: f.effortSlug } : {},
855
+ ...f.discipline ? { effortDiscipline: f.discipline } : {},
856
+ ...f.intensityTier ? { effortIntensityTier: f.intensityTier } : {},
857
+ ...f.groupTags ? { groupTags: f.groupTags } : {},
858
+ ...f.grade ? { grade: f.grade } : {}
859
+ }
860
+ }],
861
+ segmentId: identity.segmentId,
862
+ segmentVersion: identity.segmentVersion
863
+ }));
864
+ }
865
+ function projectEventToFacts(record) {
866
+ const metrics = record.metrics;
867
+ if (record.grain === "summary") {
868
+ const m = metrics[0];
869
+ if (!m || typeof m.value !== "number") return [];
870
+ const metricKey = metadataString(m.metadata, "canonicalKey") ?? (m.type ?? "");
871
+ return [{
872
+ id: `${record.id}:0`,
873
+ noteId: record.noteId,
874
+ blockContentId: record.blockContentId,
875
+ origin: record.origin,
876
+ pageId: record.pageId,
877
+ grain: "summary",
878
+ segmentId: record.segmentId ?? "",
879
+ segmentVersion: record.segmentVersion ?? 0,
880
+ resultId: record.resultId,
881
+ type: metricKey,
882
+ value: m.value,
883
+ unit: m.unit,
884
+ label: metricKey,
885
+ metricKey,
886
+ metricLabel: metricKey,
887
+ metricUnit: m.unit,
888
+ effortSlug: metadataString(m.metadata, "effortSlug") ?? record.effortSlug,
889
+ discipline: metadataString(m.metadata, "effortDiscipline"),
890
+ intensityTier: metadataString(m.metadata, "effortIntensityTier"),
891
+ grade: metadataString(m.metadata, "grade"),
892
+ timestamp: record.timestamp,
893
+ createdAt: record.timestamp
894
+ }];
895
+ }
896
+ const label = metrics.find((m) => m.type === wodWikiCore.MetricType.Label);
897
+ const labelName = label ? String(label.value ?? label.image ?? "") : "";
898
+ const facts = [];
899
+ metrics.forEach((m) => {
900
+ if (m.type === wodWikiCore.MetricType.Label || typeof m.value !== "number") return;
901
+ const metricKey = metadataString(m.metadata, "canonicalKey") ?? (labelName ? resolveCanonicalMetricKey(labelName) : m.type ?? "metric");
902
+ const ordinal = facts.length;
903
+ facts.push({
904
+ id: `${record.id}:${ordinal}`,
905
+ noteId: record.noteId,
906
+ blockContentId: record.blockContentId,
907
+ origin: record.origin,
908
+ pageId: record.pageId,
909
+ grain: "event",
910
+ segmentId: record.segmentId ?? "",
911
+ segmentVersion: record.segmentVersion ?? 0,
912
+ resultId: record.resultId,
913
+ type: metricKey,
914
+ value: m.value,
915
+ unit: m.unit,
916
+ label: labelName || metricKey,
917
+ metricKey,
918
+ metricLabel: labelName || metricKey,
919
+ metricUnit: m.unit,
920
+ effortSlug: metadataString(m.metadata, "effortSlug") ?? record.effortSlug,
921
+ intensityTier: metadataString(m.metadata, "effortIntensityTier"),
922
+ grade: metadataString(m.metadata, "grade"),
923
+ timestamp: record.timestamp,
924
+ createdAt: record.timestamp
925
+ });
926
+ });
927
+ return facts;
769
928
  }
770
929
 
771
930
  // src/dashboard/frontmatter.ts
@@ -957,23 +1116,27 @@ function windowAnchor(selected, parsed, options2) {
957
1116
  if (options2.anchor === "latest-activity" && parsed.last) return latestActivity(selected);
958
1117
  return void 0;
959
1118
  }
960
- var defaultFactStore = {
961
- getFactsByMetric: async () => [],
962
- getFactsByTimeRange: async () => [],
963
- getNoteTagLabels: async () => []
1119
+ var defaultEventStore = {
1120
+ getEventsByTimeRange: async () => [],
1121
+ getEventsByResult: async () => [],
1122
+ getEventsForNote: async () => [],
1123
+ getEventsByContent: async () => [],
1124
+ scanAll: async () => [],
1125
+ appendEvents: async () => {
1126
+ },
1127
+ finalizeSummaries: async () => {
1128
+ },
1129
+ deleteEvents: async () => {
1130
+ }
964
1131
  };
965
1132
  var defaultNoteStore = {
966
1133
  getAllNotes: async () => [],
967
- getNoteIdsForTag: async () => /* @__PURE__ */ new Set()
1134
+ getNoteIdsForTag: async () => /* @__PURE__ */ new Set(),
1135
+ getNoteTagLabels: async () => []
968
1136
  };
969
1137
  var defaultBlockStore = {
970
1138
  getAllBlocks: async () => []
971
1139
  };
972
- var defaultResultStore = {
973
- getResultsByContentId: async () => [],
974
- getResultById: async () => void 0,
975
- getResultsForNote: async () => []
976
- };
977
1140
  var defaultEffortStore = {
978
1141
  getAllEfforts: async () => []
979
1142
  };
@@ -1085,32 +1248,31 @@ var QueryService = class {
1085
1248
  store;
1086
1249
  noteStore;
1087
1250
  blockStore;
1088
- resultStore;
1089
1251
  effortStore;
1090
1252
  staticNoteStore;
1091
1253
  staticBlockStore;
1092
- constructor(storesOrFactStore, noteStore, blockStore, resultStore, effortStore, staticNoteStore, staticBlockStore) {
1093
- if (storesOrFactStore && typeof storesOrFactStore === "object" && ("factStore" in storesOrFactStore || "noteStore" in storesOrFactStore || "blockStore" in storesOrFactStore || "resultStore" in storesOrFactStore || "effortStore" in storesOrFactStore || "staticNoteStore" in storesOrFactStore || "staticBlockStore" in storesOrFactStore)) {
1094
- const stores = storesOrFactStore;
1095
- this.store = stores.factStore ?? defaultFactStore;
1254
+ constructor(storesOrEventStore, noteStore, blockStore, effortStore, staticNoteStore, staticBlockStore) {
1255
+ if (storesOrEventStore && typeof storesOrEventStore === "object" && ("eventStore" in storesOrEventStore || "noteStore" in storesOrEventStore || "blockStore" in storesOrEventStore || "effortStore" in storesOrEventStore || "staticNoteStore" in storesOrEventStore || "staticBlockStore" in storesOrEventStore)) {
1256
+ const stores = storesOrEventStore;
1257
+ this.store = stores.eventStore ?? defaultEventStore;
1096
1258
  this.noteStore = stores.noteStore ?? defaultNoteStore;
1097
1259
  this.blockStore = stores.blockStore ?? defaultBlockStore;
1098
- this.resultStore = stores.resultStore ?? defaultResultStore;
1099
1260
  this.effortStore = stores.effortStore ?? defaultEffortStore;
1100
1261
  this.staticNoteStore = stores.staticNoteStore;
1101
1262
  this.staticBlockStore = stores.staticBlockStore;
1102
1263
  } else {
1103
- this.store = storesOrFactStore ?? defaultFactStore;
1264
+ this.store = storesOrEventStore ?? defaultEventStore;
1104
1265
  this.noteStore = noteStore ?? defaultNoteStore;
1105
1266
  this.blockStore = blockStore ?? defaultBlockStore;
1106
- this.resultStore = resultStore ?? defaultResultStore;
1107
1267
  this.effortStore = effortStore ?? defaultEffortStore;
1108
1268
  this.staticNoteStore = staticNoteStore;
1109
1269
  this.staticBlockStore = staticBlockStore;
1110
1270
  }
1111
1271
  }
1272
+ /** Windowed flat-fact fetch — the projected view over the event store. */
1112
1273
  async getFactsByTimeRange(start, end) {
1113
- return this.store.getFactsByTimeRange(start, end);
1274
+ const rows = await this.store.getEventsByTimeRange(start, end);
1275
+ return rows.flatMap(projectEventToFacts);
1114
1276
  }
1115
1277
  async runQuery(raw, options2 = {}) {
1116
1278
  const parsed = parseQuery(raw);
@@ -1134,8 +1296,8 @@ var QueryService = class {
1134
1296
  }
1135
1297
  /**
1136
1298
  * Execute a rows query (rows:{…}, #949) — the session results table plane.
1137
- * Re-derives output statements from raw WorkoutResult logs through the
1138
- * ResultLogStore seam ("logs win" — facts are never read for this path).
1299
+ * Reads event rows directly over the unified store (ticket 003): no
1300
+ * WorkoutResult blob parsing; outputType narrowing hits the promoted column.
1139
1301
  */
1140
1302
  async runRows(parsed, options2 = {}) {
1141
1303
  const empty = { parsed, runs: [] };
@@ -1157,28 +1319,30 @@ var QueryService = class {
1157
1319
  if (resultIds.length + blockIds.length + noteIds.length === 0) {
1158
1320
  return { ...empty, error: "Rows query needs a scope: result:, block:, or note:." };
1159
1321
  }
1160
- const byId = /* @__PURE__ */ new Map();
1161
- for (const id of resultIds) {
1162
- const r = await this.resultStore.getResultById(id);
1163
- if (r) byId.set(r.id, r);
1164
- }
1165
- for (const blockContentId of blockIds) {
1166
- for (const r of await this.resultStore.getResultsByContentId(blockContentId)) byId.set(r.id, r);
1167
- }
1168
- for (const noteId of noteIds) {
1169
- for (const r of await this.resultStore.getResultsForNote(noteId)) byId.set(r.id, r);
1170
- }
1171
- let results = [...byId.values()].filter((r) => r.data?.logs?.length);
1322
+ const byResult = /* @__PURE__ */ new Map();
1323
+ const collect = (rows) => {
1324
+ for (const row of rows) {
1325
+ const bucket = byResult.get(row.resultId);
1326
+ if (bucket) bucket.push(row);
1327
+ else byResult.set(row.resultId, [row]);
1328
+ }
1329
+ };
1330
+ for (const id of resultIds) collect(await this.store.getEventsByResult(id));
1331
+ for (const blockContentId of blockIds) collect(await this.store.getEventsByContent(blockContentId));
1332
+ for (const noteId of noteIds) collect(await this.store.getEventsForNote(noteId));
1333
+ let groups = [...byResult.entries()].filter(([, rows]) => rows.length > 0);
1172
1334
  if (parsed.last) {
1173
- results = results.filter(
1174
- (r) => effectiveTimeWindow(r.data.endTime ?? r.createdAt ?? 0, parsed.last, void 0, options2.anchorNow)
1335
+ groups = groups.filter(
1336
+ ([, rows]) => effectiveTimeWindow(rows[0].timestamp, parsed.last, void 0, options2.anchorNow)
1175
1337
  );
1176
1338
  }
1177
- results.sort((a, b) => (b.data.endTime ?? b.createdAt) - (a.data.endTime ?? a.createdAt));
1178
- const runs = results.map((result) => ({
1179
- result,
1180
- logs: parsed.outputType ? result.data.logs.filter((l) => l.outputType === parsed.outputType) : result.data.logs
1181
- })).filter((run) => run.logs.length > 0);
1339
+ groups.sort((a, b) => b[1][0].timestamp - a[1][0].timestamp);
1340
+ const runs = groups.map(([resultId, rows]) => ({
1341
+ resultId,
1342
+ noteId: rows[0].noteId,
1343
+ timestamp: rows[0].timestamp,
1344
+ events: parsed.outputType ? rows.filter((row) => row.outputType === parsed.outputType) : rows
1345
+ })).filter((run) => run.events.length > 0);
1182
1346
  return { parsed, runs };
1183
1347
  }
1184
1348
  /**
@@ -1367,14 +1531,11 @@ var QueryService = class {
1367
1531
  };
1368
1532
  if (parsed.error) return empty;
1369
1533
  if (parsed.join) return this.runJoined(parsed, options2);
1370
- const byMetric = await this.store.getFactsByMetric(parsed.metric);
1371
- let candidates = byMetric;
1372
- if (options2.rangeStart !== void 0 || options2.rangeEnd !== void 0) {
1373
- const start = options2.rangeStart ?? 0;
1374
- const end = options2.rangeEnd ?? Number.MAX_SAFE_INTEGER;
1375
- const inRange = new Set((await this.store.getFactsByTimeRange(start, end)).map((row) => row.id));
1376
- candidates = candidates.filter((row) => inRange.has(row.id));
1377
- }
1534
+ const windowed = options2.rangeStart !== void 0 || options2.rangeEnd !== void 0;
1535
+ const start = options2.rangeStart ?? 0;
1536
+ const end = options2.rangeEnd ?? Number.MAX_SAFE_INTEGER;
1537
+ const eventRows = windowed ? await this.store.getEventsByTimeRange(start, end) : await this.store.scanAll();
1538
+ const candidates = eventRows.flatMap(projectEventToFacts).filter((row) => row.metricKey === parsed.metric);
1378
1539
  const touchesTags = parsed.filters.some((f) => f.key === "tags") || parsed.groupBy.includes("tags");
1379
1540
  const noteTags = await this.loadNoteTags(candidates, touchesTags);
1380
1541
  const matched = this.applyEffortScope(
@@ -1518,29 +1679,14 @@ var QueryService = class {
1518
1679
  }
1519
1680
  return matched.some((r) => r.effortSlug === void 0) ? matched.filter((r) => r.effortSlug === void 0) : matched;
1520
1681
  }
1521
- /** Re-derive summary facts for one Canonical Metric Key from RAW WorkoutResult
1522
- * logs across the given content ids — the cross-store join source. One fact
1523
- * row per result (normalizeSummaryFacts dedupes within a result). */
1682
+ /** Summary facts for one Canonical Metric Key across the given content ids —
1683
+ * the cross-store join source. Reads finalize-written summary rows straight
1684
+ * off the content index (ticket 003: the store is authoritative; the old
1685
+ * freshness re-derivation is moot). One fact row per result × rowKey. */
1524
1686
  async deriveMetricFacts(contentIds, metricKey) {
1525
- const out = [];
1526
1687
  const ids = [...new Set(contentIds)];
1527
- await Promise.all(ids.map(async (blockContentId) => {
1528
- const results = await this.resultStore.getResultsByContentId(blockContentId);
1529
- for (const result of results) {
1530
- const facts = normalizeSummaryFacts(result.data.logs ?? [], {
1531
- noteId: result.noteId,
1532
- resultId: result.id,
1533
- segmentId: result.segmentId,
1534
- segmentVersion: result.segmentVersion,
1535
- blockContentId,
1536
- origin: result.origin,
1537
- pageId: result.pageId,
1538
- workoutTimestamp: result.createdAt
1539
- });
1540
- for (const f of facts) if (f.metricKey === metricKey) out.push(f);
1541
- }
1542
- }));
1543
- return out;
1688
+ const rows = await Promise.all(ids.map((blockContentId) => this.store.getEventsByContent(blockContentId)));
1689
+ return rows.flat().filter((row) => row.grain === "summary").flatMap(projectEventToFacts).filter((f) => f.metricKey === metricKey);
1544
1690
  }
1545
1691
  /** All content blocks across the journal + static corpus. */
1546
1692
  async allContentBlocks() {
@@ -1580,7 +1726,7 @@ var QueryService = class {
1580
1726
  const noteTags = /* @__PURE__ */ new Map();
1581
1727
  if (!touchesTags) return noteTags;
1582
1728
  const noteIds = [...new Set(rows.map((r) => r.noteId))];
1583
- await Promise.all(noteIds.map(async (id) => noteTags.set(id, await this.store.getNoteTagLabels(id))));
1729
+ await Promise.all(noteIds.map(async (id) => noteTags.set(id, await this.noteStore.getNoteTagLabels(id))));
1584
1730
  return noteTags;
1585
1731
  }
1586
1732
  };
@@ -1880,13 +2026,13 @@ sum:$metric{} rollup:1w
1880
2026
  }
1881
2027
 
1882
2028
  // src/version.ts
1883
- var VERSION = "0.6.31";
1884
- var GIT_SHA = "d53a937";
1885
- var BUILD_TIME = "2026-08-21T14:17:13.519Z";
2029
+ var VERSION = "0.6.36";
2030
+ var GIT_SHA = "c5ad2b0";
2031
+ var BUILD_TIME = "2026-08-24T20:14:33.951Z";
1886
2032
  var SEMVER = {
1887
- version: "0.6.31",
1888
- gitSha: "d53a937",
1889
- buildTime: "2026-08-21T14:17:13.519Z"
2033
+ version: "0.6.36",
2034
+ gitSha: "c5ad2b0",
2035
+ buildTime: "2026-08-24T20:14:33.951Z"
1890
2036
  };
1891
2037
 
1892
2038
  exports.BUILD_TIME = BUILD_TIME;
@@ -1945,6 +2091,7 @@ exports.parseFrontmatterProps = parseFrontmatterProps;
1945
2091
  exports.parseQuery = parseQuery;
1946
2092
  exports.parseQueryWidgetSuffix = parseQueryWidgetSuffix;
1947
2093
  exports.parseWqlSuffixes = parseWqlSuffixes;
2094
+ exports.projectEventToFacts = projectEventToFacts;
1948
2095
  exports.referencedTokens = referencedTokens;
1949
2096
  exports.resolveCanonicalMetricKey = resolveCanonicalMetricKey;
1950
2097
  exports.resolveDisplayUnit = resolveDisplayUnit;
@@ -1957,6 +2104,8 @@ exports.staticNotesFromBlocks = staticNotesFromBlocks;
1957
2104
  exports.staticTagIndexFromBlocks = staticTagIndexFromBlocks;
1958
2105
  exports.stripFrontmatter = stripFrontmatter;
1959
2106
  exports.substituteTokens = substituteTokens;
2107
+ exports.toEventRows = toEventRows;
2108
+ exports.toSummaryEventRows = toSummaryEventRows;
1960
2109
  exports.unknownTokensMessage = unknownTokensMessage;
1961
2110
  exports.unknownWidgetTypeMessage = unknownWidgetTypeMessage;
1962
2111
  exports.wql = wql;