@powerhousedao/analytics-engine-core 6.1.0-dev.9 → 6.1.0

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.d.ts CHANGED
@@ -26,7 +26,7 @@ declare class AnalyticsProfiler implements IAnalyticsProfiler {
26
26
  }
27
27
  declare class PassthroughAnalyticsProfiler implements IAnalyticsProfiler {
28
28
  get prefix(): string;
29
- push(system: string): void;
29
+ push(_system: string): void;
30
30
  pop(): void;
31
31
  popAndReturn(result: any): any;
32
32
  record<T>(metric: string, fn: () => Promise<T>): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/AnalyticsProfiler.ts","../src/AnalyticsDiscretizer.ts","../src/AnalyticsQueryEngine.ts","../src/AnalyticsSubscriptionManager.ts","../src/types.ts","../src/util.ts"],"mappings":";;;;UAAiB,kBAAA;EAAA,IACX,MAAA;EAEJ,IAAA,GAAO,MAAA;EACP,GAAA;EACA,YAAA,GAAe,MAAA;EAEf,MAAA,MAAY,MAAA,UAAgB,EAAA,QAAU,OAAA,CAAQ,CAAA,MAAO,OAAA,CAAQ,CAAA;EAC7D,UAAA,MAAgB,MAAA,UAAgB,EAAA,QAAU,CAAA,KAAM,CAAA;AAAA;AAAA,cAGrC,iBAAA,YAA6B,kBAAA;EAAA,iBAKrB,GAAA;EAAA,iBACA,OAAA;EAAA,iBALF,MAAA;EAAA,QACT,OAAA;cAGW,GAAA,UACA,OAAA,GAAU,UAAA,UAAoB,EAAA;EAAA,IAK7C,MAAA,CAAA;EAIJ,IAAA,CAAK,MAAA;EAML,GAAA,CAAA;EAMA,YAAA,CAAa,MAAA;EAMP,MAAA,GAAA,CAAU,MAAA,UAAgB,EAAA,QAAU,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAW/D,UAAA,GAAA,CAAc,MAAA,UAAgB,EAAA,QAAU,CAAA,GAAI,CAAA;EAW5C,YAAA,CAAA;AAAA;AAAA,cASW,4BAAA,YAAwC,kBAAA;EAAA,IAC/C,MAAA,CAAA;EAIJ,IAAA,CAAK,MAAA;EAIL,GAAA,CAAA;EAIA,YAAA,CAAa,MAAA;EAIP,MAAA,GAAA,CAAU,MAAA,UAAgB,EAAA,QAAU,OAAA,CAAQ,CAAA,IAAE,OAAA,CAAA,CAAA;EAIpD,UAAA,GAAA,CAAc,MAAA,UAAgB,EAAA,QAAU,CAAA,GAAC,CAAA;AAAA;;;KC9E/B,mBAAA;EACV,MAAA;EACA,KAAA,EAAO,QAAA;EACP,GAAA,EAAK,QAAA;EACL,IAAA,EAAM,KAAA;IACJ,UAAA,EAAY,MAAA,SAAe,kBAAA;IAC3B,MAAA;IACA,IAAA;IACA,KAAA;IDlB+C;;;ICuB/C,GAAA;EAAA;AAAA;AAAA,KAIQ,oBAAA,GAAuB,KAAA,CAAM,mBAAA;;;cCd5B,oBAAA;EAAA,iBAIQ,eAAA;EAAA,iBAHF,SAAA;cAGE,eAAA,EAAiB,eAAA,EAClC,QAAA,GAAW,kBAAA;EAKA,eAAA,CACX,KAAA,EAAO,sBAAA,GACN,OAAA,CAAQ,oBAAA;EA0DE,OAAA,CAAQ,KAAA,EAAO,cAAA,GAAiB,OAAA,CAAQ,oBAAA;EAsBxC,oBAAA,CACX,KAAA,EAAO,cAAA,EACP,GAAA,EAAK,uBAAA,GACJ,OAAA,CAAQ,oBAAA;EAAA,QAwCG,oBAAA;EAAA,QAgBA,oBAAA;EAAA,QAoDN,qBAAA;EAAA,QAiBM,mBAAA;EAAA,QAcN,UAAA;EAAA,QAUA,oBAAA;EAmBK,aAAA,CAAA,GAAiB,OAAA;AAAA;;;cCzRnB,iBAAA,SAA0B,KAAA;EAAA,SACrB,WAAA,EAAa,KAAA;cAEjB,MAAA,EAAQ,KAAA;AAAA;;;;cAWT,4BAAA;EAAA,QACH,cAAA;EHVkC;;;;;;;;;;;;;;EG0BnC,eAAA,CACL,IAAA,EAAM,aAAA,EACN,QAAA,EAAU,uBAAA;EH7BgB;;;;;EGyDrB,iBAAA,CAAkB,KAAA,EAAO,aAAA;EHxDU;;;EAAA,QG0HlC,aAAA;EH1HyC;AAGnD;;EAHmD,QGoIzC,0BAAA;EHhG0C;;;;;EAAA,QG+I1C,eAAA;AAAA;;;KC3LE,cAAA,IAAkB,KAAA,UAAe,KAAA;AAAA,KAEjC,gBAAA,IAAoB,KAAA,UAAe,OAAA;AAAA,UAE9B,YAAA;EACf,OAAA,CAAQ,MAAA,UAAgB,MAAA,eAAqB,OAAA;AAAA;;;cCHlC,kBAAA,GACV,GAAA,aAAc,cAAA;AAAA,cAKJ,oBAAA,GACV,GAAA,aAAc,gBAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/AnalyticsProfiler.ts","../src/AnalyticsDiscretizer.ts","../src/AnalyticsQueryEngine.ts","../src/AnalyticsSubscriptionManager.ts","../src/types.ts","../src/util.ts"],"mappings":";;;;UAAiB,kBAAA;EAAA,IACX,MAAA;EAEJ,IAAA,GAAO,MAAA;EACP,GAAA;EACA,YAAA,GAAe,MAAA;EAEf,MAAA,MAAY,MAAA,UAAgB,EAAA,QAAU,OAAA,CAAQ,CAAA,MAAO,OAAA,CAAQ,CAAA;EAC7D,UAAA,MAAgB,MAAA,UAAgB,EAAA,QAAU,CAAA,KAAM,CAAA;AAAA;AAAA,cAGrC,iBAAA,YAA6B,kBAAA;EAAA,iBAKrB,GAAA;EAAA,iBACA,OAAA;EAAA,iBALF,MAAA;EAAA,QACT,OAAA;cAGW,GAAA,UACA,OAAA,GAAU,UAAA,UAAoB,EAAA;EAAA,IAK7C,MAAA,CAAA;EAIJ,IAAA,CAAK,MAAA;EAML,GAAA,CAAA;EAMA,YAAA,CAAa,MAAA;EAMP,MAAA,GAAA,CAAU,MAAA,UAAgB,EAAA,QAAU,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAW/D,UAAA,GAAA,CAAc,MAAA,UAAgB,EAAA,QAAU,CAAA,GAAI,CAAA;EAW5C,YAAA,CAAA;AAAA;AAAA,cASW,4BAAA,YAAwC,kBAAA;EAAA,IAC/C,MAAA,CAAA;EAIJ,IAAA,CAAK,OAAA;EAIL,GAAA,CAAA;EAIA,YAAA,CAAa,MAAA;EAIP,MAAA,GAAA,CAAU,MAAA,UAAgB,EAAA,QAAU,OAAA,CAAQ,CAAA,IAAE,OAAA,CAAA,CAAA;EAIpD,UAAA,GAAA,CAAc,MAAA,UAAgB,EAAA,QAAU,CAAA,GAAC,CAAA;AAAA;;;KC9E/B,mBAAA;EACV,MAAA;EACA,KAAA,EAAO,QAAA;EACP,GAAA,EAAK,QAAA;EACL,IAAA,EAAM,KAAA;IACJ,UAAA,EAAY,MAAA,SAAe,kBAAA;IAC3B,MAAA;IACA,IAAA;IACA,KAAA;IDlB+C;;;ICuB/C,GAAA;EAAA;AAAA;AAAA,KAIQ,oBAAA,GAAuB,KAAA,CAAM,mBAAA;;;cCd5B,oBAAA;EAAA,iBAIQ,eAAA;EAAA,iBAHF,SAAA;cAGE,eAAA,EAAiB,eAAA,EAClC,QAAA,GAAW,kBAAA;EAKA,eAAA,CACX,KAAA,EAAO,sBAAA,GACN,OAAA,CAAQ,oBAAA;EA0DE,OAAA,CAAQ,KAAA,EAAO,cAAA,GAAiB,OAAA,CAAQ,oBAAA;EAsBxC,oBAAA,CACX,KAAA,EAAO,cAAA,EACP,GAAA,EAAK,uBAAA,GACJ,OAAA,CAAQ,oBAAA;EAAA,QAwCH,oBAAA;EAAA,QAgBA,oBAAA;EAAA,QAoDA,qBAAA;EAAA,QAiBM,mBAAA;EAAA,QAcN,UAAA;EAAA,QAUA,oBAAA;EAmBK,aAAA,CAAA,GAAiB,OAAA;AAAA;;;cCzRnB,iBAAA,SAA0B,KAAA;EAAA,SACrB,WAAA,EAAa,KAAA;cAEjB,MAAA,EAAQ,KAAA;AAAA;;;;cAWT,4BAAA;EAAA,QACH,cAAA;EHVkC;;;;;;;;;;;;;;EG0BnC,eAAA,CACL,IAAA,EAAM,aAAA,EACN,QAAA,EAAU,uBAAA;EH7BgB;;;;;EGyDrB,iBAAA,CAAkB,KAAA,EAAO,aAAA;EHxDU;;;EAAA,QG0HlC,aAAA;EH1HyC;AAGnD;;EAHmD,QGoIzC,0BAAA;EHhG0C;;;;;EAAA,QG+I1C,eAAA;AAAA;;;KC3LE,cAAA,IAAkB,KAAA,UAAe,KAAA;AAAA,KAEjC,gBAAA,IAAoB,KAAA,UAAe,OAAA;AAAA,UAE9B,YAAA;EACf,OAAA,CAAQ,MAAA,UAAgB,MAAA,eAAqB,OAAA;AAAA;;;cCHlC,kBAAA,GACV,GAAA,aAAc,cAAA;AAAA,cAKJ,oBAAA,GACV,GAAA,aAAc,gBAAA"}
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ var PassthroughAnalyticsProfiler = class {
50
50
  get prefix() {
51
51
  return "";
52
52
  }
53
- push(system) {}
53
+ push(_system) {}
54
54
  pop() {}
55
55
  popAndReturn(result) {
56
56
  return result;
@@ -291,7 +291,7 @@ var AnalyticsDiscretizer = class AnalyticsDiscretizer {
291
291
  const result = [];
292
292
  if (remainingDimensions.length > 0) {
293
293
  const subdimension = remainingDimensions[0];
294
- Object.keys(node).forEach((subdimensionValue, index, arr) => {
294
+ Object.keys(node).forEach((subdimensionValue, _index, _arr) => {
295
295
  const newDimensionValues = { ...dimensionValues };
296
296
  newDimensionValues[subdimension] = subdimensionValue;
297
297
  result.push(...this._discretizeNode(node[subdimensionValue], newDimensionValues, remainingDimensions.slice(1), periods));
@@ -474,11 +474,11 @@ var AnalyticsQueryEngine = class {
474
474
  }
475
475
  return result;
476
476
  }
477
- async _applyVectorOperator(inputsA, inputsB, operator, resultCurrency) {
477
+ _applyVectorOperator(inputsA, inputsB, operator, _resultCurrency) {
478
478
  if ([CompoundOperator.ScalarMultiply, CompoundOperator.ScalarDivide].includes(operator)) throw new Error("Invalid operator for vector operation");
479
- return inputsB;
479
+ return Promise.resolve(inputsB);
480
480
  }
481
- async _applyScalarOperator(inputs, operand, operator, useOperandSum, resultCurrency) {
481
+ _applyScalarOperator(inputs, operand, operator, useOperandSum, resultCurrency) {
482
482
  if ([CompoundOperator.VectorAdd, CompoundOperator.VectorSubtract].includes(operator)) throw new Error("Invalid operator for scalar operation");
483
483
  const result = [];
484
484
  const operandMap = {};
@@ -501,7 +501,7 @@ var AnalyticsQueryEngine = class {
501
501
  };
502
502
  result.push(outputPeriod);
503
503
  }
504
- return result;
504
+ return Promise.resolve(result);
505
505
  }
506
506
  _calculateOutputValue(input, operator, operand) {
507
507
  switch (operator) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/AnalyticsProfiler.ts","../src/AnalyticsTimeSlicer.ts","../src/AnalyticsDiscretizer.ts","../src/AnalyticsQueryEngine.ts","../src/AnalyticsSubscriptionManager.ts","../src/util.ts"],"sourcesContent":["export interface IAnalyticsProfiler {\n get prefix(): string;\n\n push: (system: string) => void;\n pop: () => void;\n popAndReturn: (result: any) => any;\n\n record: <T>(metric: string, fn: () => Promise<T>) => Promise<T>;\n recordSync: <T>(metric: string, fn: () => T) => T;\n}\n\nexport class AnalyticsProfiler implements IAnalyticsProfiler {\n private readonly _stack: string[] = [];\n private _prefix: string = \"\";\n\n constructor(\n private readonly _ns: string,\n private readonly _logger: (metricName: string, ms: number) => void,\n ) {\n this._prefix = _ns;\n }\n\n get prefix(): string {\n return this._prefix;\n }\n\n push(system: string): void {\n this._stack.push(system);\n\n this.updatePrefix();\n }\n\n pop(): void {\n if (this._stack.pop()) {\n this.updatePrefix();\n }\n }\n\n popAndReturn(result: any): any {\n this.pop();\n\n return result;\n }\n\n async record<T>(metric: string, fn: () => Promise<T>): Promise<T> {\n const start = performance.now();\n const fullMetric = `${this.prefix}.${metric}`;\n\n try {\n return await fn();\n } finally {\n this._logger(fullMetric, performance.now() - start);\n }\n }\n\n recordSync<T>(metric: string, fn: () => T): T {\n const start = performance.now();\n const fullMetric = `${this.prefix}.${metric}`;\n\n try {\n return fn();\n } finally {\n this._logger(fullMetric, performance.now() - start);\n }\n }\n\n updatePrefix(): void {\n if (this._stack.length > 0) {\n this._prefix = `${this._ns}.${this._stack.join(\".\")}`;\n } else {\n this._prefix = this._ns;\n }\n }\n}\n\nexport class PassthroughAnalyticsProfiler implements IAnalyticsProfiler {\n get prefix(): string {\n return \"\";\n }\n\n push(system: string) {\n //\n }\n\n pop() {\n //\n }\n\n popAndReturn(result: any) {\n return result;\n }\n\n async record<T>(metric: string, fn: () => Promise<T>) {\n return await fn();\n }\n\n recordSync<T>(metric: string, fn: () => T) {\n return fn();\n }\n}\n","import { DateTime } from \"luxon\";\nimport { AnalyticsGranularity } from \"./AnalyticsQuery.js\";\n\nexport type AnalyticsRange = {\n start: DateTime;\n end: DateTime;\n granularity: AnalyticsGranularity;\n};\n\nexport type AnalyticsPeriod = {\n period: string;\n start: DateTime;\n end: DateTime;\n};\n\ninterface AnalyticsPeriodSeries {\n start: DateTime;\n end: DateTime;\n granularity: AnalyticsGranularity;\n next(): AnalyticsPeriod | null;\n}\n\nexport const getPeriodSeriesArray = (\n range: AnalyticsRange,\n): AnalyticsPeriod[] => {\n const result: AnalyticsPeriod[] = [];\n const series = getPeriodSeries(range);\n\n let next = series.next();\n while (next) {\n result.push(next);\n next = series.next();\n }\n\n return result;\n};\n\nexport const getPeriodSeries = (\n range: AnalyticsRange,\n): AnalyticsPeriodSeries => {\n return {\n ...range,\n next: _createFactoryFn(range),\n };\n};\n\nconst _createFactoryFn = (range: AnalyticsRange) => {\n let current: DateTime | null = range.start;\n\n return () => {\n if (current == null) {\n return null;\n }\n\n let result: AnalyticsPeriod | null = null;\n switch (range.granularity) {\n case AnalyticsGranularity.Total:\n result = _nextTotalPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Annual:\n result = _nextAnnualPeriod(current, range.end);\n break;\n case AnalyticsGranularity.SemiAnnual:\n result = _nextSemiAnnualPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Quarterly:\n result = _nextQuarterlyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Monthly:\n result = _nextMonthlyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Weekly:\n result = _nextWeeklyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Daily:\n result = _nextDailyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Hourly:\n result = _nextHourlyPeriod(current, range.end);\n }\n\n // Update current to start of next period\n if (result === null) {\n current = null;\n } else {\n current = result.end.plus({ milliseconds: 1 });\n }\n\n return result;\n };\n};\n\nconst _nextTotalPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n return {\n period: \"total\",\n start: nextStart,\n end: seriesEnd,\n };\n};\n\nexport const _nextAnnualPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n const inputUtc = nextStart.toUTC();\n const oneYearLater = DateTime.utc(\n inputUtc.year,\n inputUtc.month,\n inputUtc.day,\n ).plus({ years: 1 });\n\n return {\n period: \"annual\",\n start: nextStart,\n end: oneYearLater,\n };\n};\n\nexport const _nextSemiAnnualPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n const midYear = DateTime.utc(nextStart.year, 7, 1);\n const endYear = DateTime.utc(nextStart.year, 12, 31, 23, 59, 59, 999);\n\n let endDate: DateTime;\n if (midYear > nextStart) {\n endDate = midYear;\n } else {\n endDate = endYear;\n }\n\n if (endDate > seriesEnd) {\n endDate = seriesEnd;\n }\n\n return {\n period: \"semiAnnual\",\n start: nextStart,\n end: endDate,\n };\n};\n\nexport const _nextQuarterlyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n let endDate: DateTime;\n const nextStartUtc = nextStart.toUTC();\n const startMonth = nextStartUtc.month;\n\n if (startMonth < 3) {\n endDate = DateTime.utc(nextStartUtc.year, 4, 1);\n } else if (startMonth < 6) {\n endDate = DateTime.utc(nextStartUtc.year, 7, 1);\n } else if (startMonth < 9) {\n endDate = DateTime.utc(nextStartUtc.year, 10, 1);\n } else {\n endDate = DateTime.utc(nextStartUtc.year, 12, 31, 23, 59, 59, 999);\n }\n\n if (endDate > seriesEnd) {\n endDate = seriesEnd;\n }\n\n return {\n period: \"quarterly\",\n start: nextStart,\n end: endDate,\n };\n};\nexport const _nextMonthlyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n // Get the first day of the next month\n const nextStartUtc = nextStart.toUTC();\n let endDate = DateTime.utc(\n nextStartUtc.year,\n nextStartUtc.month,\n nextStartUtc.day,\n )\n .plus({ months: 1 })\n .startOf(\"month\");\n\n // If the end date is after the series end, then use the series end as the end date\n if (endDate > seriesEnd) {\n if (!nextStart.hasSame(seriesEnd, \"month\")) {\n endDate = seriesEnd;\n }\n }\n\n // Otherwise, return the end date as the first day of the next month\n return {\n period: \"monthly\",\n start: nextStart,\n end: endDate,\n };\n};\n\nexport const _nextWeeklyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n // Calculate the start of the next week (Monday)\n const nextStartUtc = nextStart.toUTC();\n const nextWeekStartUTC = DateTime.utc(\n nextStartUtc.year,\n nextStartUtc.month,\n nextStartUtc.day,\n )\n .plus({ weeks: 1 })\n .startOf(\"week\");\n\n // If the calculated next week start is later or equal to the series end date, return the series end\n if (nextWeekStartUTC > seriesEnd)\n if (!nextWeekStartUTC.hasSame(seriesEnd, \"day\")) {\n return {\n period: \"weekly\",\n start: nextStart,\n end: seriesEnd,\n };\n }\n\n return {\n period: \"weekly\",\n start: nextStart,\n end: nextWeekStartUTC,\n };\n};\n\nexport const _nextDailyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n // Set the end date to the start of the next day\n const nextStartUtc = nextStart.toUTC();\n let endDate = nextStartUtc.plus({ days: 1 }).startOf(\"day\");\n if (endDate > seriesEnd || endDate.hasSame(seriesEnd, \"day\")) {\n endDate = seriesEnd;\n }\n\n return {\n period: \"daily\",\n start: nextStart,\n end: endDate,\n };\n};\n\nexport const _nextHourlyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n const startDate = nextStart.toUTC();\n let endDate = startDate.plus({ hours: 1 });\n\n if (endDate > seriesEnd) {\n if (nextStart.hour !== seriesEnd.hour) {\n endDate = seriesEnd.toUTC();\n }\n }\n\n return {\n period: \"hourly\",\n start: nextStart,\n end: endDate,\n };\n};\n","/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n/* eslint-disable no-case-declarations */\nimport { DateTime, Interval } from \"luxon\";\nimport type { AnalyticsGranularity } from \"./AnalyticsQuery.js\";\nimport {\n type AnalyticsDimension,\n type AnalyticsSeries,\n} from \"./AnalyticsQuery.js\";\nimport {\n type AnalyticsPeriod,\n type AnalyticsRange,\n getPeriodSeriesArray,\n} from \"./AnalyticsTimeSlicer.js\";\n\nexport const getQuarter = (date: DateTime) => {\n return Math.floor((date.month - 1) / 3) + 1;\n};\n\nexport type GroupedPeriodResult = {\n period: string;\n start: DateTime;\n end: DateTime;\n rows: Array<{\n dimensions: Record<string, AnalyticsDimension>;\n metric: string;\n unit: string | null;\n value: number;\n\n /**\n * The sum of all metric values over this period?\n */\n sum: number;\n }>;\n};\n\nexport type GroupedPeriodResults = Array<GroupedPeriodResult>;\n\nexport class AnalyticsDiscretizer {\n public static discretize(\n series: AnalyticsSeries<string>[],\n dimensions: string[],\n start: DateTime | null,\n end: DateTime | null,\n granularity: AnalyticsGranularity,\n ): GroupedPeriodResults {\n const index = this._buildIndex(series, dimensions);\n const periods = getPeriodSeriesArray(\n this._calculateRange(start, end, granularity, series),\n );\n const disretizedResults = this._discretizeNode(\n index,\n {},\n dimensions,\n periods,\n );\n const groupedResults = this._groupResultsByPeriod(\n periods,\n disretizedResults,\n );\n\n return groupedResults;\n }\n\n private static _calculateRange(\n start: DateTime | null,\n end: DateTime | null,\n granularity: AnalyticsGranularity,\n results: AnalyticsSeries<any>[],\n ) {\n let calculatedStart: DateTime | null = start || null;\n let calculatedEnd: DateTime | null = end || null;\n\n if (calculatedStart == null || calculatedEnd == null) {\n for (const r of results) {\n if (calculatedStart == null) {\n calculatedStart = r.start;\n }\n\n const endValue = r.end || r.start;\n if (calculatedEnd == null || calculatedEnd < endValue) {\n calculatedEnd = endValue;\n }\n }\n }\n\n if (calculatedStart == null || calculatedEnd == null) {\n throw new Error(\"Cannot determine query start and/or end.\");\n }\n\n return {\n start: calculatedStart,\n end: calculatedEnd,\n granularity,\n } as AnalyticsRange;\n }\n\n public static _groupResultsByPeriod(\n periods: AnalyticsPeriod[],\n dimensionedResults: DimensionedSeries[],\n ): GroupedPeriodResults {\n const result: Record<string, GroupedPeriodResult> = {};\n\n for (const p of periods) {\n const id = p.start.toISO() + \"-\" + p.period;\n const period = AnalyticsDiscretizer._getPeriodString(p);\n result[id] = {\n period: period,\n start: p.start,\n end: p.end,\n rows: [],\n };\n }\n\n for (const r of dimensionedResults) {\n for (const period of Object.keys(r.series)) {\n result[period].rows.push({\n dimensions: r.dimensions,\n metric: r.metric,\n unit: r.unit == \"__NULL__\" ? null : r.unit,\n value: r.series[period].inc,\n sum: r.series[period].sum,\n });\n }\n }\n\n return Object.values(result);\n }\n\n static _getPeriodString(p: AnalyticsPeriod) {\n switch (p.period) {\n case \"annual\":\n return p.start.year.toString();\n case \"semiAnnual\":\n return `${p.start.year}/${p.start.month < 7 ? \"H1\" : \"H2\"}`;\n case \"quarterly\":\n return `${p.start.year}/Q${getQuarter(p.start)}`;\n case \"monthly\":\n const month = p.start.toUTC().month;\n const formattedMonth = month < 10 ? `0${month}` : `${month}`;\n return `${p.start.year}/${formattedMonth}`;\n case \"weekly\":\n return `${p.start.weekYear}/W${p.start.weekNumber}`;\n case \"daily\":\n const monthD = p.start.month;\n const day = p.start.day;\n const formattedMonthD = monthD < 10 ? `0${monthD}` : `${monthD}`;\n const formattedDay = day < 10 ? `0${day}` : `${day}`;\n return `${p.start.year}/${formattedMonthD}/${formattedDay}`;\n case \"hourly\":\n const monthH = p.start.month;\n const dayH = p.start.day;\n const hourH = p.start.hour;\n const formattedMonthH = monthH < 10 ? `0${monthH}` : `${monthH}`;\n const formattedDayH = dayH < 10 ? `0${dayH}` : `${dayH}`;\n const formattedHourH = hourH < 10 ? `0${hourH}` : `${hourH}`;\n return `${p.start.year}/${formattedMonthH}/${formattedDayH}/${formattedHourH}`;\n default:\n return p.period;\n }\n }\n\n public static _discretizeNode(\n node: DiscretizerIndexNode,\n dimensionValues: Record<string, string>,\n remainingDimensions: string[],\n periods: AnalyticsPeriod[],\n ): DimensionedSeries[] {\n const result: DimensionedSeries[] = [];\n\n if (remainingDimensions.length > 0) {\n const subdimension = remainingDimensions[0] as string;\n Object.keys(node).forEach((subdimensionValue, index, arr) => {\n const newDimensionValues = { ...dimensionValues };\n newDimensionValues[subdimension] = subdimensionValue;\n result.push(\n ...this._discretizeNode(\n node[subdimensionValue] as DiscretizerIndexNode,\n newDimensionValues,\n remainingDimensions.slice(1),\n periods,\n ),\n );\n });\n } else {\n Object.keys(node).forEach((metric) => {\n result.push(\n ...this._discretizeLeaf(\n node[metric] as DiscretizerIndexLeaf,\n periods,\n metric,\n dimensionValues,\n ),\n );\n });\n }\n\n return result;\n }\n\n public static _discretizeLeaf(\n leaf: DiscretizerIndexLeaf,\n periods: AnalyticsPeriod[],\n metric: string,\n dimensionValues: Record<string, string>,\n ): DimensionedSeries[] {\n const result: DimensionedSeries[] = [];\n Object.keys(leaf).forEach((unit) => {\n const metaDimensions: any = {};\n Object.keys(dimensionValues).forEach((k) => {\n metaDimensions[k] = {\n path: leaf[unit][0].dimensions[k],\n icon: leaf[unit][0].dimensions.icon,\n label: leaf[unit][0].dimensions.label,\n description: leaf[unit][0].dimensions.description,\n };\n });\n result.push({\n unit,\n metric,\n dimensions: metaDimensions as any,\n series: this._discretizeSeries(leaf[unit], periods),\n });\n });\n\n return result;\n }\n\n public static _discretizeSeries(\n series: AnalyticsSeries<string>[],\n periods: AnalyticsPeriod[],\n ): Series {\n const result: Series = {};\n\n for (const s of series) {\n let oldSum = this._getValue(s, periods[0].start);\n for (const p of periods) {\n const newSum = this._getValue(s, p.end);\n const id = `${p.start.toISO()}-${p.period}`;\n\n // const id = p.period;\n if (result[id]) {\n result[id].inc += newSum - oldSum;\n result[id].sum += newSum;\n } else {\n result[id] = {\n inc: newSum - oldSum,\n sum: newSum,\n };\n }\n\n oldSum = newSum;\n }\n }\n\n return result;\n }\n\n public static _getValue(\n series: AnalyticsSeries<string>,\n when: DateTime,\n ): number {\n switch (series.fn) {\n case \"Single\":\n return this._getSingleValue(series, when);\n case \"DssVest\":\n return this._getVestValue(series, when);\n default:\n // todo: logging interface\n //console.error(`Unknown analytics series function: '${series.fn}'`);\n return 0.0;\n }\n }\n\n public static _getSingleValue(\n series: AnalyticsSeries<string>,\n when: DateTime,\n ): number {\n return when >= series.start ? series.value : 0.0;\n }\n\n public static _getVestValue(\n series: AnalyticsSeries<string>,\n when: DateTime,\n ): number {\n const now = when;\n const start = series.start;\n const end = series.end;\n\n const cliff = series.params?.cliff\n ? DateTime.fromISO(series.params.cliff! as string)\n : null;\n if (now < start || (cliff && now < cliff)) {\n return 0.0;\n } else if (end && now >= end) {\n return series.value;\n }\n\n const a = Interval.fromDateTimes(start, now);\n const b = Interval.fromDateTimes(start, end || now);\n\n return (a.length() / b.length()) * series.value;\n }\n\n public static _buildIndex(\n series: AnalyticsSeries<string>[],\n dimensions: string[],\n ): DiscretizerIndexNode {\n const result: DiscretizerIndexNode | any = {};\n const map: DiscretizerIndexLeaf = {};\n const dimName = dimensions[0] || \"\";\n\n for (const s of series) {\n const dimValue = s.dimensions[dimName];\n if (undefined === map[dimValue]) {\n map[dimValue] = [];\n }\n map[dimValue].push(s);\n }\n\n if (dimensions.length > 1) {\n const newDimensions = dimensions.slice(1);\n Object.keys(map).forEach((k) => {\n result[k] = this._buildIndex(map[k], newDimensions);\n });\n } else {\n Object.keys(map).forEach((k) => {\n result[k] = this._buildMetricsIndex(map[k]);\n });\n }\n\n return result;\n }\n\n public static _buildMetricsIndex(\n series: AnalyticsSeries<string>[],\n ): DiscretizerIndexNode {\n const result: DiscretizerIndexNode = {};\n\n const map: DiscretizerIndexLeaf = {};\n for (const s of series) {\n const metric = s.metric;\n if (undefined === map[metric]) {\n map[metric] = [];\n }\n\n map[metric].push(s);\n }\n\n Object.keys(map).forEach((k) => (result[k] = this._buildUnitIndex(map[k])));\n return result;\n }\n\n public static _buildUnitIndex(\n series: AnalyticsSeries<string>[],\n ): DiscretizerIndexLeaf {\n const result: DiscretizerIndexLeaf = {};\n\n for (const s of series) {\n const unit = s.unit || \"__NULL__\";\n if (undefined === result[unit]) {\n result[unit] = [];\n }\n\n result[unit].push(s);\n }\n\n return result;\n }\n}\n\ntype DiscretizerIndexLeaf = { [k: string]: AnalyticsSeries<string>[] };\ntype DiscretizerIndexNode = {\n [k: string]: DiscretizerIndexNode | DiscretizerIndexLeaf;\n};\ntype Series = Record<\n string,\n {\n /**\n * How much the metric increased from the beginning of the series to the end of the specified period.\n */\n inc: number;\n\n /**\n * The sum of all metric values from the beginning of the series to the end of the specified period.\n */\n sum: number;\n }\n>;\ntype DimensionedSeries = {\n unit: string;\n metric: string;\n dimensions: Record<string, AnalyticsDimension>;\n series: Series;\n};\n","/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\nimport {\n AnalyticsDiscretizer,\n type GroupedPeriodResults,\n type GroupedPeriodResult,\n} from \"./AnalyticsDiscretizer.js\";\nimport { AnalyticsPath } from \"./AnalyticsPath.js\";\nimport {\n type IAnalyticsProfiler,\n PassthroughAnalyticsProfiler,\n} from \"./AnalyticsProfiler.js\";\nimport {\n type AnalyticsQuery,\n type AnalyticsSeries,\n type AnalyticsSeriesQuery,\n type CompoundAnalyticsQuery,\n type MultiCurrencyConversion,\n CompoundOperator,\n} from \"./AnalyticsQuery.js\";\nimport { type IAnalyticsStore } from \"./IAnalyticsStore.js\";\n\nexport class AnalyticsQueryEngine {\n private readonly _profiler: IAnalyticsProfiler;\n\n public constructor(\n private readonly _analyticsStore: IAnalyticsStore,\n profiler?: IAnalyticsProfiler,\n ) {\n this._profiler = profiler ?? new PassthroughAnalyticsProfiler();\n }\n\n public async executeCompound(\n query: CompoundAnalyticsQuery,\n ): Promise<GroupedPeriodResults> {\n let result: GroupedPeriodResults;\n\n const inputsQuery: AnalyticsQuery = {\n start: query.start,\n end: query.end,\n granularity: query.granularity,\n lod: query.lod,\n select: query.select,\n metrics: query.expression.inputs.metrics,\n currency: query.expression.inputs.currency,\n };\n\n const operandQuery: AnalyticsQuery = {\n start: query.start,\n end: query.end,\n granularity: query.granularity,\n lod: { priceData: 1 },\n select: { priceData: [AnalyticsPath.fromString(\"atlas\")] },\n metrics: [query.expression.operand.metric],\n currency: query.expression.operand.currency,\n };\n\n const inputExecute = await this.execute(inputsQuery);\n const operandExecute = await this.execute(operandQuery);\n\n if (\n [CompoundOperator.VectorAdd, CompoundOperator.VectorSubtract].includes(\n query.expression.operator,\n )\n ) {\n result = await this._profiler.record(\n \"ApplyVectorOperator\",\n async () =>\n await this._applyVectorOperator(\n inputExecute,\n operandExecute,\n query.expression.operator,\n query.expression.resultCurrency,\n ),\n );\n } else {\n result = await this._profiler.record(\n \"ApplyScalarOperator\",\n async () =>\n await this._applyScalarOperator(\n inputExecute,\n operandExecute,\n query.expression.operator,\n query.expression.operand.useSum,\n query.expression.resultCurrency,\n ),\n );\n }\n\n return result;\n }\n\n public async execute(query: AnalyticsQuery): Promise<GroupedPeriodResults> {\n const seriesResults = await this._executeSeriesQuery(query);\n\n const normalizedSeriesResults = this._profiler.recordSync(\"ApplyLODs\", () =>\n this._applyLods(seriesResults, query.lod),\n );\n\n const dimensions = Object.keys(query.select);\n const discretizedResult = this._profiler.recordSync(\"Discretize\", () =>\n normalizedSeriesResults.length < 1\n ? []\n : AnalyticsDiscretizer.discretize(\n normalizedSeriesResults,\n dimensions,\n query.start,\n query.end,\n query.granularity,\n ),\n );\n return discretizedResult;\n }\n\n public async executeMultiCurrency(\n query: AnalyticsQuery,\n mcc: MultiCurrencyConversion,\n ): Promise<GroupedPeriodResults> {\n const baseQuery: AnalyticsQuery = {\n ...query,\n currency: mcc.targetCurrency ?? query.currency,\n };\n let result = await this.execute(baseQuery);\n\n for (const conversion of mcc.conversions) {\n const nextQuery: CompoundAnalyticsQuery = {\n start: query.start,\n end: query.end,\n granularity: query.granularity,\n lod: query.lod,\n select: query.select,\n expression: {\n inputs: {\n metrics: baseQuery.metrics,\n currency: conversion.currency,\n },\n operator: CompoundOperator.ScalarMultiply,\n operand: {\n metric: conversion.metric,\n currency: mcc.targetCurrency,\n useSum: true,\n },\n resultCurrency: mcc.targetCurrency,\n },\n };\n\n const executedCompound = await this.executeCompound(nextQuery);\n result = await this._applyVectorOperator(\n result,\n executedCompound,\n CompoundOperator.VectorAdd,\n mcc.targetCurrency,\n );\n }\n return result;\n }\n\n private async _applyVectorOperator(\n inputsA: GroupedPeriodResults,\n inputsB: GroupedPeriodResults,\n operator: CompoundOperator,\n resultCurrency?: AnalyticsPath,\n ) {\n if (\n [CompoundOperator.ScalarMultiply, CompoundOperator.ScalarDivide].includes(\n operator,\n )\n ) {\n throw new Error(\"Invalid operator for vector operation\");\n }\n return inputsB;\n }\n\n private async _applyScalarOperator(\n inputs: GroupedPeriodResults, // expected input is the budget & actuals in 2022 monthly granularity in MKR\n operand: GroupedPeriodResults, // expected input is the daily mkr price change in 2022 monthly granularity in DAI\n operator: CompoundOperator, // expected to me multiply and later addition\n useOperandSum: boolean,\n resultCurrency?: AnalyticsPath, // expected to be DAI\n ): Promise<GroupedPeriodResults> {\n if (\n [CompoundOperator.VectorAdd, CompoundOperator.VectorSubtract].includes(\n operator,\n )\n ) {\n throw new Error(\"Invalid operator for scalar operation\");\n }\n\n const result: GroupedPeriodResults = [];\n const operandMap: Record<string, number> = {};\n const key = useOperandSum ? \"sum\" : \"value\";\n\n for (const operandPeriod of operand) {\n if (operandPeriod.rows.length > 0) {\n operandMap[operandPeriod.period] = operandPeriod.rows[0][key];\n }\n }\n\n // let previousValue: number = 1;\n for (const inputPeriod of inputs) {\n const outputPeriod: GroupedPeriodResult = {\n period: inputPeriod.period,\n start: inputPeriod.start,\n end: inputPeriod.end,\n rows: inputPeriod.rows.map((row) => {\n const newRow = {\n dimensions: row.dimensions,\n metric: row.metric,\n unit: resultCurrency ? resultCurrency.toString() : row.unit,\n value: this._calculateOutputValue(\n row.value,\n operator,\n operandMap[inputPeriod.period],\n ),\n sum: -1,\n };\n return newRow;\n }),\n };\n result.push(outputPeriod);\n }\n\n return result;\n }\n\n private _calculateOutputValue(\n input: number,\n operator: CompoundOperator,\n operand: number,\n ): number {\n switch (operator) {\n case CompoundOperator.VectorAdd:\n return input + operand;\n case CompoundOperator.VectorSubtract:\n return input - operand;\n case CompoundOperator.ScalarMultiply:\n return input * operand;\n case CompoundOperator.ScalarDivide:\n return input / operand;\n }\n }\n\n private async _executeSeriesQuery(\n query: AnalyticsQuery,\n ): Promise<AnalyticsSeries[]> {\n const seriesQuery: AnalyticsSeriesQuery = {\n start: query.start,\n end: query.end,\n select: query.select,\n metrics: query.metrics,\n currency: query.currency,\n };\n\n return await this._analyticsStore.getMatchingSeries(seriesQuery);\n }\n\n private _applyLods(\n series: AnalyticsSeries[],\n lods: Record<string, number | null>,\n ): AnalyticsSeries<string>[] {\n return series.map((result) => ({\n ...result,\n dimensions: this._applyDimensionsLods(result.dimensions, lods),\n }));\n }\n\n private _applyDimensionsLods(\n dimensionMap: Record<string, AnalyticsPath> | any,\n lods: Record<string, number | null>,\n ) {\n const result: Record<string, string> | any = {};\n for (const [dimension, lod] of Object.entries(lods)) {\n if (lod !== null && dimensionMap[dimension]) {\n result[dimension] = dimensionMap[dimension][\"path\"]\n .applyLod(lod)\n .toString();\n result[\"icon\"] = dimensionMap[dimension][\"icon\"].toString();\n result[\"label\"] = dimensionMap[dimension][\"label\"].toString();\n result[\"description\"] =\n dimensionMap[dimension][\"description\"].toString();\n }\n }\n return result;\n }\n\n public async getDimensions(): Promise<any> {\n return await this._analyticsStore.getDimensions();\n }\n\n /*public async getMetrics(): Promise<string[]> {\n return await this._analyticsStore.getMetrics();\n }\n\n public async getCurrencies(): Promise<string[]> {\n return await this._analyticsStore.getCurrencies();\n }*/\n}\n","import type { AnalyticsPath } from \"./AnalyticsPath.js\";\nimport type { AnalyticsUpdateCallback } from \"./IAnalyticsStore.js\";\n\nexport class NotificationError extends Error {\n public readonly innerErrors: Error[];\n\n constructor(errors: Error[]) {\n super(errors.map((e) => e.message).join(\"\\n\"));\n\n this.name = \"NotificationError\";\n this.innerErrors = errors;\n }\n}\n\n/**\n * Manages subscriptions for analytics paths.\n */\nexport class AnalyticsSubscriptionManager {\n private _subscriptions: Map<string, Set<AnalyticsUpdateCallback>> = new Map();\n\n /**\n * Subscribe to updates for an analytics path. A subscribed function will be\n * called for:\n *\n * - exact path matches\n * - matching child paths (i.e. an update to /a/b/c will trigger a callback\n * for /a/b/c, /a/b, and /a)\n * - wildcard matches\n *\n * @param path The analytics path to subscribe to.\n * @param callback Function to be called when the path is updated.\n *\n * @returns A function that, when called, unsubscribes from the updates.\n */\n public subscribeToPath(\n path: AnalyticsPath,\n callback: AnalyticsUpdateCallback,\n ): () => void {\n const pathString = this.normalizePath(path.toString(\"/\"));\n\n if (!this._subscriptions.has(pathString)) {\n this._subscriptions.set(pathString, new Set());\n }\n\n this._subscriptions.get(pathString)!.add(callback);\n\n return () => {\n const callbacks = this._subscriptions.get(pathString);\n if (callbacks) {\n callbacks.delete(callback);\n\n // only remove the path entry if there are no more callbacks\n if (callbacks.size === 0) {\n this._subscriptions.delete(pathString);\n }\n }\n };\n }\n\n /**\n * Notifies subscribers about updates to paths.\n *\n * @param paths The paths that were updated.\n */\n public notifySubscribers(paths: AnalyticsPath[]): void {\n if (paths.length === 0 || this._subscriptions.size === 0) {\n return;\n }\n\n const errors: Error[] = [];\n for (const path of paths) {\n const pathString = this.normalizePath(path.toString(\"/\"));\n const pathPrefixes = this.getPathPrefixes(pathString);\n\n const matchingSubscriptions: Array<{\n prefix: string;\n callbacks: Set<AnalyticsUpdateCallback>;\n }> = [];\n\n // add the exact prefix matches\n pathPrefixes\n .filter((prefix) => this._subscriptions.has(prefix))\n .forEach((prefix) => {\n matchingSubscriptions.push({\n prefix,\n callbacks: this._subscriptions.get(prefix)!,\n });\n });\n\n // check all wildcard patterns\n for (const [\n subscriptionPath,\n callbacks,\n ] of this._subscriptions.entries()) {\n // skip if it's already in the exact matches\n if (pathPrefixes.includes(subscriptionPath)) {\n continue;\n }\n\n // hceck if this subscription path (which might have wildcards) matches the update path\n if (this.pathMatchesWildcardPattern(pathString, subscriptionPath)) {\n matchingSubscriptions.push({\n prefix: subscriptionPath,\n callbacks,\n });\n }\n }\n\n if (matchingSubscriptions.length === 0) continue;\n\n // guarantee delivery to all subscribers\n for (const { callbacks } of matchingSubscriptions) {\n for (const callback of callbacks) {\n try {\n callback(path);\n } catch (e) {\n errors.push(e as Error);\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new NotificationError(errors);\n }\n }\n\n /**\n * Normalizes a path string to ensure consistent comparison.\n */\n private normalizePath(path: string): string {\n // Handle potential double slashes by first splitting on slashes and rejoining\n const parts = path.split(\"/\").filter((p) => p.length > 0);\n const normalized = \"/\" + parts.join(\"/\");\n return normalized;\n }\n\n /**\n * Checks if a path matches a subscription pattern that may contain wildcards.\n */\n private pathMatchesWildcardPattern(\n updatePath: string,\n subscriptionPath: string,\n ): boolean {\n // Handle the wildcard segment case\n if (subscriptionPath.includes(\"*\")) {\n const updateSegments = updatePath.split(\"/\").filter((s) => s.length > 0);\n const subscriptionSegments = subscriptionPath\n .split(\"/\")\n .filter((s) => s.length > 0);\n\n // If subscription is longer than the update path, it can't match\n if (subscriptionSegments.length > updateSegments.length) {\n return false;\n }\n\n // Compare each segment\n for (let i = 0; i < subscriptionSegments.length; i++) {\n const subSegment = subscriptionSegments[i];\n const updateSegment = updateSegments[i];\n\n // If segment is * or starts with * (wildcard), it matches anything\n if (subSegment === \"*\" || subSegment.startsWith(\"*:\")) {\n continue;\n }\n\n // Otherwise, segments should match exactly\n if (subSegment !== updateSegment) {\n return false;\n }\n }\n\n return true;\n }\n\n // If no wildcards, check if subscription is a prefix of the update path\n return (\n updatePath === subscriptionPath ||\n updatePath.startsWith(subscriptionPath + \"/\")\n );\n }\n\n /**\n * Gets all path prefixes for a given path.\n *\n * For example, for '/a/b/c' it returns ['/a', '/a/b', '/a/b/c'].\n */\n private getPathPrefixes(path: string): string[] {\n const segments = path.split(\"/\").filter((s) => s.length > 0);\n const prefixes: string[] = [];\n\n let currentPath = \"\";\n for (const segment of segments) {\n currentPath = currentPath ? `${currentPath}/${segment}` : `/${segment}`;\n prefixes.push(currentPath);\n }\n\n if (prefixes.length === 0 && path === \"/\") {\n prefixes.push(\"/\");\n }\n\n return prefixes;\n }\n}\n","import type { SqlQueryLogger, SqlResultsLogger } from \"./types.js\";\n\nexport const defaultQueryLogger =\n (tag: string): SqlQueryLogger =>\n (index: number, query: string) => {\n console.log(`[${tag}][Q:${index}]: ${query}\\n`);\n };\n\nexport const defaultResultsLogger =\n (tag: string): SqlResultsLogger =>\n (index: number, results: any) => {\n if (Array.isArray(results)) {\n console.log(`[${tag}][R:${index}]: ${results.length} results\\n`);\n } else {\n console.log(`[${tag}][R:${index}]: Received ${typeof results}.\\n`);\n }\n };\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/AnalyticsProfiler.ts","../src/AnalyticsTimeSlicer.ts","../src/AnalyticsDiscretizer.ts","../src/AnalyticsQueryEngine.ts","../src/AnalyticsSubscriptionManager.ts","../src/util.ts"],"sourcesContent":["export interface IAnalyticsProfiler {\n get prefix(): string;\n\n push: (system: string) => void;\n pop: () => void;\n popAndReturn: (result: any) => any;\n\n record: <T>(metric: string, fn: () => Promise<T>) => Promise<T>;\n recordSync: <T>(metric: string, fn: () => T) => T;\n}\n\nexport class AnalyticsProfiler implements IAnalyticsProfiler {\n private readonly _stack: string[] = [];\n private _prefix: string = \"\";\n\n constructor(\n private readonly _ns: string,\n private readonly _logger: (metricName: string, ms: number) => void,\n ) {\n this._prefix = _ns;\n }\n\n get prefix(): string {\n return this._prefix;\n }\n\n push(system: string): void {\n this._stack.push(system);\n\n this.updatePrefix();\n }\n\n pop(): void {\n if (this._stack.pop()) {\n this.updatePrefix();\n }\n }\n\n popAndReturn(result: any): any {\n this.pop();\n\n return result;\n }\n\n async record<T>(metric: string, fn: () => Promise<T>): Promise<T> {\n const start = performance.now();\n const fullMetric = `${this.prefix}.${metric}`;\n\n try {\n return await fn();\n } finally {\n this._logger(fullMetric, performance.now() - start);\n }\n }\n\n recordSync<T>(metric: string, fn: () => T): T {\n const start = performance.now();\n const fullMetric = `${this.prefix}.${metric}`;\n\n try {\n return fn();\n } finally {\n this._logger(fullMetric, performance.now() - start);\n }\n }\n\n updatePrefix(): void {\n if (this._stack.length > 0) {\n this._prefix = `${this._ns}.${this._stack.join(\".\")}`;\n } else {\n this._prefix = this._ns;\n }\n }\n}\n\nexport class PassthroughAnalyticsProfiler implements IAnalyticsProfiler {\n get prefix(): string {\n return \"\";\n }\n\n push(_system: string) {\n //\n }\n\n pop() {\n //\n }\n\n popAndReturn(result: any) {\n return result;\n }\n\n async record<T>(metric: string, fn: () => Promise<T>) {\n return await fn();\n }\n\n recordSync<T>(metric: string, fn: () => T) {\n return fn();\n }\n}\n","import { DateTime } from \"luxon\";\nimport { AnalyticsGranularity } from \"./AnalyticsQuery.js\";\n\nexport type AnalyticsRange = {\n start: DateTime;\n end: DateTime;\n granularity: AnalyticsGranularity;\n};\n\nexport type AnalyticsPeriod = {\n period: string;\n start: DateTime;\n end: DateTime;\n};\n\ninterface AnalyticsPeriodSeries {\n start: DateTime;\n end: DateTime;\n granularity: AnalyticsGranularity;\n next(): AnalyticsPeriod | null;\n}\n\nexport const getPeriodSeriesArray = (\n range: AnalyticsRange,\n): AnalyticsPeriod[] => {\n const result: AnalyticsPeriod[] = [];\n const series = getPeriodSeries(range);\n\n let next = series.next();\n while (next) {\n result.push(next);\n next = series.next();\n }\n\n return result;\n};\n\nexport const getPeriodSeries = (\n range: AnalyticsRange,\n): AnalyticsPeriodSeries => {\n return {\n ...range,\n next: _createFactoryFn(range),\n };\n};\n\nconst _createFactoryFn = (range: AnalyticsRange) => {\n let current: DateTime | null = range.start;\n\n return () => {\n if (current == null) {\n return null;\n }\n\n let result: AnalyticsPeriod | null = null;\n switch (range.granularity) {\n case AnalyticsGranularity.Total:\n result = _nextTotalPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Annual:\n result = _nextAnnualPeriod(current, range.end);\n break;\n case AnalyticsGranularity.SemiAnnual:\n result = _nextSemiAnnualPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Quarterly:\n result = _nextQuarterlyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Monthly:\n result = _nextMonthlyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Weekly:\n result = _nextWeeklyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Daily:\n result = _nextDailyPeriod(current, range.end);\n break;\n case AnalyticsGranularity.Hourly:\n result = _nextHourlyPeriod(current, range.end);\n }\n\n // Update current to start of next period\n if (result === null) {\n current = null;\n } else {\n current = result.end.plus({ milliseconds: 1 });\n }\n\n return result;\n };\n};\n\nconst _nextTotalPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n return {\n period: \"total\",\n start: nextStart,\n end: seriesEnd,\n };\n};\n\nexport const _nextAnnualPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n const inputUtc = nextStart.toUTC();\n const oneYearLater = DateTime.utc(\n inputUtc.year,\n inputUtc.month,\n inputUtc.day,\n ).plus({ years: 1 });\n\n return {\n period: \"annual\",\n start: nextStart,\n end: oneYearLater,\n };\n};\n\nexport const _nextSemiAnnualPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n const midYear = DateTime.utc(nextStart.year, 7, 1);\n const endYear = DateTime.utc(nextStart.year, 12, 31, 23, 59, 59, 999);\n\n let endDate: DateTime;\n if (midYear > nextStart) {\n endDate = midYear;\n } else {\n endDate = endYear;\n }\n\n if (endDate > seriesEnd) {\n endDate = seriesEnd;\n }\n\n return {\n period: \"semiAnnual\",\n start: nextStart,\n end: endDate,\n };\n};\n\nexport const _nextQuarterlyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n let endDate: DateTime;\n const nextStartUtc = nextStart.toUTC();\n const startMonth = nextStartUtc.month;\n\n if (startMonth < 3) {\n endDate = DateTime.utc(nextStartUtc.year, 4, 1);\n } else if (startMonth < 6) {\n endDate = DateTime.utc(nextStartUtc.year, 7, 1);\n } else if (startMonth < 9) {\n endDate = DateTime.utc(nextStartUtc.year, 10, 1);\n } else {\n endDate = DateTime.utc(nextStartUtc.year, 12, 31, 23, 59, 59, 999);\n }\n\n if (endDate > seriesEnd) {\n endDate = seriesEnd;\n }\n\n return {\n period: \"quarterly\",\n start: nextStart,\n end: endDate,\n };\n};\nexport const _nextMonthlyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n // Get the first day of the next month\n const nextStartUtc = nextStart.toUTC();\n let endDate = DateTime.utc(\n nextStartUtc.year,\n nextStartUtc.month,\n nextStartUtc.day,\n )\n .plus({ months: 1 })\n .startOf(\"month\");\n\n // If the end date is after the series end, then use the series end as the end date\n if (endDate > seriesEnd) {\n if (!nextStart.hasSame(seriesEnd, \"month\")) {\n endDate = seriesEnd;\n }\n }\n\n // Otherwise, return the end date as the first day of the next month\n return {\n period: \"monthly\",\n start: nextStart,\n end: endDate,\n };\n};\n\nexport const _nextWeeklyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n // Calculate the start of the next week (Monday)\n const nextStartUtc = nextStart.toUTC();\n const nextWeekStartUTC = DateTime.utc(\n nextStartUtc.year,\n nextStartUtc.month,\n nextStartUtc.day,\n )\n .plus({ weeks: 1 })\n .startOf(\"week\");\n\n // If the calculated next week start is later or equal to the series end date, return the series end\n if (nextWeekStartUTC > seriesEnd)\n if (!nextWeekStartUTC.hasSame(seriesEnd, \"day\")) {\n return {\n period: \"weekly\",\n start: nextStart,\n end: seriesEnd,\n };\n }\n\n return {\n period: \"weekly\",\n start: nextStart,\n end: nextWeekStartUTC,\n };\n};\n\nexport const _nextDailyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n // Set the end date to the start of the next day\n const nextStartUtc = nextStart.toUTC();\n let endDate = nextStartUtc.plus({ days: 1 }).startOf(\"day\");\n if (endDate > seriesEnd || endDate.hasSame(seriesEnd, \"day\")) {\n endDate = seriesEnd;\n }\n\n return {\n period: \"daily\",\n start: nextStart,\n end: endDate,\n };\n};\n\nexport const _nextHourlyPeriod = (\n nextStart: DateTime,\n seriesEnd: DateTime,\n): AnalyticsPeriod | null => {\n if (seriesEnd <= nextStart) {\n return null;\n }\n\n const startDate = nextStart.toUTC();\n let endDate = startDate.plus({ hours: 1 });\n\n if (endDate > seriesEnd) {\n if (nextStart.hour !== seriesEnd.hour) {\n endDate = seriesEnd.toUTC();\n }\n }\n\n return {\n period: \"hourly\",\n start: nextStart,\n end: endDate,\n };\n};\n","/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n/* eslint-disable no-case-declarations */\nimport { DateTime, Interval } from \"luxon\";\nimport type { AnalyticsGranularity } from \"./AnalyticsQuery.js\";\nimport {\n type AnalyticsDimension,\n type AnalyticsSeries,\n} from \"./AnalyticsQuery.js\";\nimport {\n type AnalyticsPeriod,\n type AnalyticsRange,\n getPeriodSeriesArray,\n} from \"./AnalyticsTimeSlicer.js\";\n\nexport const getQuarter = (date: DateTime) => {\n return Math.floor((date.month - 1) / 3) + 1;\n};\n\nexport type GroupedPeriodResult = {\n period: string;\n start: DateTime;\n end: DateTime;\n rows: Array<{\n dimensions: Record<string, AnalyticsDimension>;\n metric: string;\n unit: string | null;\n value: number;\n\n /**\n * The sum of all metric values over this period?\n */\n sum: number;\n }>;\n};\n\nexport type GroupedPeriodResults = Array<GroupedPeriodResult>;\n\nexport class AnalyticsDiscretizer {\n public static discretize(\n series: AnalyticsSeries<string>[],\n dimensions: string[],\n start: DateTime | null,\n end: DateTime | null,\n granularity: AnalyticsGranularity,\n ): GroupedPeriodResults {\n const index = this._buildIndex(series, dimensions);\n const periods = getPeriodSeriesArray(\n this._calculateRange(start, end, granularity, series),\n );\n const disretizedResults = this._discretizeNode(\n index,\n {},\n dimensions,\n periods,\n );\n const groupedResults = this._groupResultsByPeriod(\n periods,\n disretizedResults,\n );\n\n return groupedResults;\n }\n\n private static _calculateRange(\n start: DateTime | null,\n end: DateTime | null,\n granularity: AnalyticsGranularity,\n results: AnalyticsSeries<any>[],\n ) {\n let calculatedStart: DateTime | null = start || null;\n let calculatedEnd: DateTime | null = end || null;\n\n if (calculatedStart == null || calculatedEnd == null) {\n for (const r of results) {\n if (calculatedStart == null) {\n calculatedStart = r.start;\n }\n\n const endValue = r.end || r.start;\n if (calculatedEnd == null || calculatedEnd < endValue) {\n calculatedEnd = endValue;\n }\n }\n }\n\n if (calculatedStart == null || calculatedEnd == null) {\n throw new Error(\"Cannot determine query start and/or end.\");\n }\n\n return {\n start: calculatedStart,\n end: calculatedEnd,\n granularity,\n } as AnalyticsRange;\n }\n\n public static _groupResultsByPeriod(\n periods: AnalyticsPeriod[],\n dimensionedResults: DimensionedSeries[],\n ): GroupedPeriodResults {\n const result: Record<string, GroupedPeriodResult> = {};\n\n for (const p of periods) {\n const id = p.start.toISO() + \"-\" + p.period;\n const period = AnalyticsDiscretizer._getPeriodString(p);\n result[id] = {\n period: period,\n start: p.start,\n end: p.end,\n rows: [],\n };\n }\n\n for (const r of dimensionedResults) {\n for (const period of Object.keys(r.series)) {\n result[period].rows.push({\n dimensions: r.dimensions,\n metric: r.metric,\n unit: r.unit == \"__NULL__\" ? null : r.unit,\n value: r.series[period].inc,\n sum: r.series[period].sum,\n });\n }\n }\n\n return Object.values(result);\n }\n\n static _getPeriodString(p: AnalyticsPeriod) {\n switch (p.period) {\n case \"annual\":\n return p.start.year.toString();\n case \"semiAnnual\":\n return `${p.start.year}/${p.start.month < 7 ? \"H1\" : \"H2\"}`;\n case \"quarterly\":\n return `${p.start.year}/Q${getQuarter(p.start)}`;\n case \"monthly\":\n const month = p.start.toUTC().month;\n const formattedMonth = month < 10 ? `0${month}` : `${month}`;\n return `${p.start.year}/${formattedMonth}`;\n case \"weekly\":\n return `${p.start.weekYear}/W${p.start.weekNumber}`;\n case \"daily\":\n const monthD = p.start.month;\n const day = p.start.day;\n const formattedMonthD = monthD < 10 ? `0${monthD}` : `${monthD}`;\n const formattedDay = day < 10 ? `0${day}` : `${day}`;\n return `${p.start.year}/${formattedMonthD}/${formattedDay}`;\n case \"hourly\":\n const monthH = p.start.month;\n const dayH = p.start.day;\n const hourH = p.start.hour;\n const formattedMonthH = monthH < 10 ? `0${monthH}` : `${monthH}`;\n const formattedDayH = dayH < 10 ? `0${dayH}` : `${dayH}`;\n const formattedHourH = hourH < 10 ? `0${hourH}` : `${hourH}`;\n return `${p.start.year}/${formattedMonthH}/${formattedDayH}/${formattedHourH}`;\n default:\n return p.period;\n }\n }\n\n public static _discretizeNode(\n node: DiscretizerIndexNode,\n dimensionValues: Record<string, string>,\n remainingDimensions: string[],\n periods: AnalyticsPeriod[],\n ): DimensionedSeries[] {\n const result: DimensionedSeries[] = [];\n\n if (remainingDimensions.length > 0) {\n const subdimension = remainingDimensions[0] as string;\n Object.keys(node).forEach((subdimensionValue, _index, _arr) => {\n const newDimensionValues = { ...dimensionValues };\n newDimensionValues[subdimension] = subdimensionValue;\n result.push(\n ...this._discretizeNode(\n node[subdimensionValue] as DiscretizerIndexNode,\n newDimensionValues,\n remainingDimensions.slice(1),\n periods,\n ),\n );\n });\n } else {\n Object.keys(node).forEach((metric) => {\n result.push(\n ...this._discretizeLeaf(\n node[metric] as DiscretizerIndexLeaf,\n periods,\n metric,\n dimensionValues,\n ),\n );\n });\n }\n\n return result;\n }\n\n public static _discretizeLeaf(\n leaf: DiscretizerIndexLeaf,\n periods: AnalyticsPeriod[],\n metric: string,\n dimensionValues: Record<string, string>,\n ): DimensionedSeries[] {\n const result: DimensionedSeries[] = [];\n Object.keys(leaf).forEach((unit) => {\n const metaDimensions: any = {};\n Object.keys(dimensionValues).forEach((k) => {\n metaDimensions[k] = {\n path: leaf[unit][0].dimensions[k],\n icon: leaf[unit][0].dimensions.icon,\n label: leaf[unit][0].dimensions.label,\n description: leaf[unit][0].dimensions.description,\n };\n });\n result.push({\n unit,\n metric,\n dimensions: metaDimensions as any,\n series: this._discretizeSeries(leaf[unit], periods),\n });\n });\n\n return result;\n }\n\n public static _discretizeSeries(\n series: AnalyticsSeries<string>[],\n periods: AnalyticsPeriod[],\n ): Series {\n const result: Series = {};\n\n for (const s of series) {\n let oldSum = this._getValue(s, periods[0].start);\n for (const p of periods) {\n const newSum = this._getValue(s, p.end);\n const id = `${p.start.toISO()}-${p.period}`;\n\n // const id = p.period;\n if (result[id]) {\n result[id].inc += newSum - oldSum;\n result[id].sum += newSum;\n } else {\n result[id] = {\n inc: newSum - oldSum,\n sum: newSum,\n };\n }\n\n oldSum = newSum;\n }\n }\n\n return result;\n }\n\n public static _getValue(\n series: AnalyticsSeries<string>,\n when: DateTime,\n ): number {\n switch (series.fn) {\n case \"Single\":\n return this._getSingleValue(series, when);\n case \"DssVest\":\n return this._getVestValue(series, when);\n default:\n // todo: logging interface\n //console.error(`Unknown analytics series function: '${series.fn}'`);\n return 0.0;\n }\n }\n\n public static _getSingleValue(\n series: AnalyticsSeries<string>,\n when: DateTime,\n ): number {\n return when >= series.start ? series.value : 0.0;\n }\n\n public static _getVestValue(\n series: AnalyticsSeries<string>,\n when: DateTime,\n ): number {\n const now = when;\n const start = series.start;\n const end = series.end;\n\n const cliff = series.params?.cliff\n ? DateTime.fromISO(series.params.cliff! as string)\n : null;\n if (now < start || (cliff && now < cliff)) {\n return 0.0;\n } else if (end && now >= end) {\n return series.value;\n }\n\n const a = Interval.fromDateTimes(start, now);\n const b = Interval.fromDateTimes(start, end || now);\n\n return (a.length() / b.length()) * series.value;\n }\n\n public static _buildIndex(\n series: AnalyticsSeries<string>[],\n dimensions: string[],\n ): DiscretizerIndexNode {\n const result: DiscretizerIndexNode | any = {};\n const map: DiscretizerIndexLeaf = {};\n const dimName = dimensions[0] || \"\";\n\n for (const s of series) {\n const dimValue = s.dimensions[dimName];\n if (undefined === map[dimValue]) {\n map[dimValue] = [];\n }\n map[dimValue].push(s);\n }\n\n if (dimensions.length > 1) {\n const newDimensions = dimensions.slice(1);\n Object.keys(map).forEach((k) => {\n result[k] = this._buildIndex(map[k], newDimensions);\n });\n } else {\n Object.keys(map).forEach((k) => {\n result[k] = this._buildMetricsIndex(map[k]);\n });\n }\n\n return result;\n }\n\n public static _buildMetricsIndex(\n series: AnalyticsSeries<string>[],\n ): DiscretizerIndexNode {\n const result: DiscretizerIndexNode = {};\n\n const map: DiscretizerIndexLeaf = {};\n for (const s of series) {\n const metric = s.metric;\n if (undefined === map[metric]) {\n map[metric] = [];\n }\n\n map[metric].push(s);\n }\n\n Object.keys(map).forEach((k) => (result[k] = this._buildUnitIndex(map[k])));\n return result;\n }\n\n public static _buildUnitIndex(\n series: AnalyticsSeries<string>[],\n ): DiscretizerIndexLeaf {\n const result: DiscretizerIndexLeaf = {};\n\n for (const s of series) {\n const unit = s.unit || \"__NULL__\";\n if (undefined === result[unit]) {\n result[unit] = [];\n }\n\n result[unit].push(s);\n }\n\n return result;\n }\n}\n\ntype DiscretizerIndexLeaf = { [k: string]: AnalyticsSeries<string>[] };\ntype DiscretizerIndexNode = {\n [k: string]: DiscretizerIndexNode | DiscretizerIndexLeaf;\n};\ntype Series = Record<\n string,\n {\n /**\n * How much the metric increased from the beginning of the series to the end of the specified period.\n */\n inc: number;\n\n /**\n * The sum of all metric values from the beginning of the series to the end of the specified period.\n */\n sum: number;\n }\n>;\ntype DimensionedSeries = {\n unit: string;\n metric: string;\n dimensions: Record<string, AnalyticsDimension>;\n series: Series;\n};\n","/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\nimport {\n AnalyticsDiscretizer,\n type GroupedPeriodResults,\n type GroupedPeriodResult,\n} from \"./AnalyticsDiscretizer.js\";\nimport { AnalyticsPath } from \"./AnalyticsPath.js\";\nimport {\n type IAnalyticsProfiler,\n PassthroughAnalyticsProfiler,\n} from \"./AnalyticsProfiler.js\";\nimport {\n type AnalyticsQuery,\n type AnalyticsSeries,\n type AnalyticsSeriesQuery,\n type CompoundAnalyticsQuery,\n type MultiCurrencyConversion,\n CompoundOperator,\n} from \"./AnalyticsQuery.js\";\nimport { type IAnalyticsStore } from \"./IAnalyticsStore.js\";\n\nexport class AnalyticsQueryEngine {\n private readonly _profiler: IAnalyticsProfiler;\n\n public constructor(\n private readonly _analyticsStore: IAnalyticsStore,\n profiler?: IAnalyticsProfiler,\n ) {\n this._profiler = profiler ?? new PassthroughAnalyticsProfiler();\n }\n\n public async executeCompound(\n query: CompoundAnalyticsQuery,\n ): Promise<GroupedPeriodResults> {\n let result: GroupedPeriodResults;\n\n const inputsQuery: AnalyticsQuery = {\n start: query.start,\n end: query.end,\n granularity: query.granularity,\n lod: query.lod,\n select: query.select,\n metrics: query.expression.inputs.metrics,\n currency: query.expression.inputs.currency,\n };\n\n const operandQuery: AnalyticsQuery = {\n start: query.start,\n end: query.end,\n granularity: query.granularity,\n lod: { priceData: 1 },\n select: { priceData: [AnalyticsPath.fromString(\"atlas\")] },\n metrics: [query.expression.operand.metric],\n currency: query.expression.operand.currency,\n };\n\n const inputExecute = await this.execute(inputsQuery);\n const operandExecute = await this.execute(operandQuery);\n\n if (\n [CompoundOperator.VectorAdd, CompoundOperator.VectorSubtract].includes(\n query.expression.operator,\n )\n ) {\n result = await this._profiler.record(\n \"ApplyVectorOperator\",\n async () =>\n await this._applyVectorOperator(\n inputExecute,\n operandExecute,\n query.expression.operator,\n query.expression.resultCurrency,\n ),\n );\n } else {\n result = await this._profiler.record(\n \"ApplyScalarOperator\",\n async () =>\n await this._applyScalarOperator(\n inputExecute,\n operandExecute,\n query.expression.operator,\n query.expression.operand.useSum,\n query.expression.resultCurrency,\n ),\n );\n }\n\n return result;\n }\n\n public async execute(query: AnalyticsQuery): Promise<GroupedPeriodResults> {\n const seriesResults = await this._executeSeriesQuery(query);\n\n const normalizedSeriesResults = this._profiler.recordSync(\"ApplyLODs\", () =>\n this._applyLods(seriesResults, query.lod),\n );\n\n const dimensions = Object.keys(query.select);\n const discretizedResult = this._profiler.recordSync(\"Discretize\", () =>\n normalizedSeriesResults.length < 1\n ? []\n : AnalyticsDiscretizer.discretize(\n normalizedSeriesResults,\n dimensions,\n query.start,\n query.end,\n query.granularity,\n ),\n );\n return discretizedResult;\n }\n\n public async executeMultiCurrency(\n query: AnalyticsQuery,\n mcc: MultiCurrencyConversion,\n ): Promise<GroupedPeriodResults> {\n const baseQuery: AnalyticsQuery = {\n ...query,\n currency: mcc.targetCurrency ?? query.currency,\n };\n let result = await this.execute(baseQuery);\n\n for (const conversion of mcc.conversions) {\n const nextQuery: CompoundAnalyticsQuery = {\n start: query.start,\n end: query.end,\n granularity: query.granularity,\n lod: query.lod,\n select: query.select,\n expression: {\n inputs: {\n metrics: baseQuery.metrics,\n currency: conversion.currency,\n },\n operator: CompoundOperator.ScalarMultiply,\n operand: {\n metric: conversion.metric,\n currency: mcc.targetCurrency,\n useSum: true,\n },\n resultCurrency: mcc.targetCurrency,\n },\n };\n\n const executedCompound = await this.executeCompound(nextQuery);\n result = await this._applyVectorOperator(\n result,\n executedCompound,\n CompoundOperator.VectorAdd,\n mcc.targetCurrency,\n );\n }\n return result;\n }\n\n private _applyVectorOperator(\n inputsA: GroupedPeriodResults,\n inputsB: GroupedPeriodResults,\n operator: CompoundOperator,\n _resultCurrency?: AnalyticsPath,\n ): Promise<GroupedPeriodResults> {\n if (\n [CompoundOperator.ScalarMultiply, CompoundOperator.ScalarDivide].includes(\n operator,\n )\n ) {\n throw new Error(\"Invalid operator for vector operation\");\n }\n return Promise.resolve(inputsB);\n }\n\n private _applyScalarOperator(\n inputs: GroupedPeriodResults, // expected input is the budget & actuals in 2022 monthly granularity in MKR\n operand: GroupedPeriodResults, // expected input is the daily mkr price change in 2022 monthly granularity in DAI\n operator: CompoundOperator, // expected to me multiply and later addition\n useOperandSum: boolean,\n resultCurrency?: AnalyticsPath, // expected to be DAI\n ): Promise<GroupedPeriodResults> {\n if (\n [CompoundOperator.VectorAdd, CompoundOperator.VectorSubtract].includes(\n operator,\n )\n ) {\n throw new Error(\"Invalid operator for scalar operation\");\n }\n\n const result: GroupedPeriodResults = [];\n const operandMap: Record<string, number> = {};\n const key = useOperandSum ? \"sum\" : \"value\";\n\n for (const operandPeriod of operand) {\n if (operandPeriod.rows.length > 0) {\n operandMap[operandPeriod.period] = operandPeriod.rows[0][key];\n }\n }\n\n // let previousValue: number = 1;\n for (const inputPeriod of inputs) {\n const outputPeriod: GroupedPeriodResult = {\n period: inputPeriod.period,\n start: inputPeriod.start,\n end: inputPeriod.end,\n rows: inputPeriod.rows.map((row) => {\n const newRow = {\n dimensions: row.dimensions,\n metric: row.metric,\n unit: resultCurrency ? resultCurrency.toString() : row.unit,\n value: this._calculateOutputValue(\n row.value,\n operator,\n operandMap[inputPeriod.period],\n ),\n sum: -1,\n };\n return newRow;\n }),\n };\n result.push(outputPeriod);\n }\n\n return Promise.resolve(result);\n }\n\n private _calculateOutputValue(\n input: number,\n operator: CompoundOperator,\n operand: number,\n ): number {\n switch (operator) {\n case CompoundOperator.VectorAdd:\n return input + operand;\n case CompoundOperator.VectorSubtract:\n return input - operand;\n case CompoundOperator.ScalarMultiply:\n return input * operand;\n case CompoundOperator.ScalarDivide:\n return input / operand;\n }\n }\n\n private async _executeSeriesQuery(\n query: AnalyticsQuery,\n ): Promise<AnalyticsSeries[]> {\n const seriesQuery: AnalyticsSeriesQuery = {\n start: query.start,\n end: query.end,\n select: query.select,\n metrics: query.metrics,\n currency: query.currency,\n };\n\n return await this._analyticsStore.getMatchingSeries(seriesQuery);\n }\n\n private _applyLods(\n series: AnalyticsSeries[],\n lods: Record<string, number | null>,\n ): AnalyticsSeries<string>[] {\n return series.map((result) => ({\n ...result,\n dimensions: this._applyDimensionsLods(result.dimensions, lods),\n }));\n }\n\n private _applyDimensionsLods(\n dimensionMap: Record<string, AnalyticsPath> | any,\n lods: Record<string, number | null>,\n ) {\n const result: Record<string, string> | any = {};\n for (const [dimension, lod] of Object.entries(lods)) {\n if (lod !== null && dimensionMap[dimension]) {\n result[dimension] = dimensionMap[dimension][\"path\"]\n .applyLod(lod)\n .toString();\n result[\"icon\"] = dimensionMap[dimension][\"icon\"].toString();\n result[\"label\"] = dimensionMap[dimension][\"label\"].toString();\n result[\"description\"] =\n dimensionMap[dimension][\"description\"].toString();\n }\n }\n return result;\n }\n\n public async getDimensions(): Promise<any> {\n return await this._analyticsStore.getDimensions();\n }\n\n /*public async getMetrics(): Promise<string[]> {\n return await this._analyticsStore.getMetrics();\n }\n\n public async getCurrencies(): Promise<string[]> {\n return await this._analyticsStore.getCurrencies();\n }*/\n}\n","import type { AnalyticsPath } from \"./AnalyticsPath.js\";\nimport type { AnalyticsUpdateCallback } from \"./IAnalyticsStore.js\";\n\nexport class NotificationError extends Error {\n public readonly innerErrors: Error[];\n\n constructor(errors: Error[]) {\n super(errors.map((e) => e.message).join(\"\\n\"));\n\n this.name = \"NotificationError\";\n this.innerErrors = errors;\n }\n}\n\n/**\n * Manages subscriptions for analytics paths.\n */\nexport class AnalyticsSubscriptionManager {\n private _subscriptions: Map<string, Set<AnalyticsUpdateCallback>> = new Map();\n\n /**\n * Subscribe to updates for an analytics path. A subscribed function will be\n * called for:\n *\n * - exact path matches\n * - matching child paths (i.e. an update to /a/b/c will trigger a callback\n * for /a/b/c, /a/b, and /a)\n * - wildcard matches\n *\n * @param path The analytics path to subscribe to.\n * @param callback Function to be called when the path is updated.\n *\n * @returns A function that, when called, unsubscribes from the updates.\n */\n public subscribeToPath(\n path: AnalyticsPath,\n callback: AnalyticsUpdateCallback,\n ): () => void {\n const pathString = this.normalizePath(path.toString(\"/\"));\n\n if (!this._subscriptions.has(pathString)) {\n this._subscriptions.set(pathString, new Set());\n }\n\n this._subscriptions.get(pathString)!.add(callback);\n\n return () => {\n const callbacks = this._subscriptions.get(pathString);\n if (callbacks) {\n callbacks.delete(callback);\n\n // only remove the path entry if there are no more callbacks\n if (callbacks.size === 0) {\n this._subscriptions.delete(pathString);\n }\n }\n };\n }\n\n /**\n * Notifies subscribers about updates to paths.\n *\n * @param paths The paths that were updated.\n */\n public notifySubscribers(paths: AnalyticsPath[]): void {\n if (paths.length === 0 || this._subscriptions.size === 0) {\n return;\n }\n\n const errors: Error[] = [];\n for (const path of paths) {\n const pathString = this.normalizePath(path.toString(\"/\"));\n const pathPrefixes = this.getPathPrefixes(pathString);\n\n const matchingSubscriptions: Array<{\n prefix: string;\n callbacks: Set<AnalyticsUpdateCallback>;\n }> = [];\n\n // add the exact prefix matches\n pathPrefixes\n .filter((prefix) => this._subscriptions.has(prefix))\n .forEach((prefix) => {\n matchingSubscriptions.push({\n prefix,\n callbacks: this._subscriptions.get(prefix)!,\n });\n });\n\n // check all wildcard patterns\n for (const [\n subscriptionPath,\n callbacks,\n ] of this._subscriptions.entries()) {\n // skip if it's already in the exact matches\n if (pathPrefixes.includes(subscriptionPath)) {\n continue;\n }\n\n // hceck if this subscription path (which might have wildcards) matches the update path\n if (this.pathMatchesWildcardPattern(pathString, subscriptionPath)) {\n matchingSubscriptions.push({\n prefix: subscriptionPath,\n callbacks,\n });\n }\n }\n\n if (matchingSubscriptions.length === 0) continue;\n\n // guarantee delivery to all subscribers\n for (const { callbacks } of matchingSubscriptions) {\n for (const callback of callbacks) {\n try {\n callback(path);\n } catch (e) {\n errors.push(e as Error);\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new NotificationError(errors);\n }\n }\n\n /**\n * Normalizes a path string to ensure consistent comparison.\n */\n private normalizePath(path: string): string {\n // Handle potential double slashes by first splitting on slashes and rejoining\n const parts = path.split(\"/\").filter((p) => p.length > 0);\n const normalized = \"/\" + parts.join(\"/\");\n return normalized;\n }\n\n /**\n * Checks if a path matches a subscription pattern that may contain wildcards.\n */\n private pathMatchesWildcardPattern(\n updatePath: string,\n subscriptionPath: string,\n ): boolean {\n // Handle the wildcard segment case\n if (subscriptionPath.includes(\"*\")) {\n const updateSegments = updatePath.split(\"/\").filter((s) => s.length > 0);\n const subscriptionSegments = subscriptionPath\n .split(\"/\")\n .filter((s) => s.length > 0);\n\n // If subscription is longer than the update path, it can't match\n if (subscriptionSegments.length > updateSegments.length) {\n return false;\n }\n\n // Compare each segment\n for (let i = 0; i < subscriptionSegments.length; i++) {\n const subSegment = subscriptionSegments[i];\n const updateSegment = updateSegments[i];\n\n // If segment is * or starts with * (wildcard), it matches anything\n if (subSegment === \"*\" || subSegment.startsWith(\"*:\")) {\n continue;\n }\n\n // Otherwise, segments should match exactly\n if (subSegment !== updateSegment) {\n return false;\n }\n }\n\n return true;\n }\n\n // If no wildcards, check if subscription is a prefix of the update path\n return (\n updatePath === subscriptionPath ||\n updatePath.startsWith(subscriptionPath + \"/\")\n );\n }\n\n /**\n * Gets all path prefixes for a given path.\n *\n * For example, for '/a/b/c' it returns ['/a', '/a/b', '/a/b/c'].\n */\n private getPathPrefixes(path: string): string[] {\n const segments = path.split(\"/\").filter((s) => s.length > 0);\n const prefixes: string[] = [];\n\n let currentPath = \"\";\n for (const segment of segments) {\n currentPath = currentPath ? `${currentPath}/${segment}` : `/${segment}`;\n prefixes.push(currentPath);\n }\n\n if (prefixes.length === 0 && path === \"/\") {\n prefixes.push(\"/\");\n }\n\n return prefixes;\n }\n}\n","import type { SqlQueryLogger, SqlResultsLogger } from \"./types.js\";\n\nexport const defaultQueryLogger =\n (tag: string): SqlQueryLogger =>\n (index: number, query: string) => {\n console.log(`[${tag}][Q:${index}]: ${query}\\n`);\n };\n\nexport const defaultResultsLogger =\n (tag: string): SqlResultsLogger =>\n (index: number, results: any) => {\n if (Array.isArray(results)) {\n console.log(`[${tag}][R:${index}]: ${results.length} results\\n`);\n } else {\n console.log(`[${tag}][R:${index}]: Received ${typeof results}.\\n`);\n }\n };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerhousedao/analytics-engine-core",
3
- "version": "6.1.0-dev.9",
3
+ "version": "6.1.0",
4
4
  "license": "AGPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,7 +23,7 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "luxon": "3.7.2",
26
- "@powerhousedao/shared": "6.1.0-dev.9"
26
+ "@powerhousedao/shared": "6.1.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/luxon": "3.7.1",