@powerhousedao/analytics-engine-core 6.2.3-dev.42 → 6.2.3-dev.44
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.js +24 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -112,7 +112,7 @@ const _createFactoryFn = (range) => {
|
|
|
112
112
|
case AnalyticsGranularity.Hourly: result = _nextHourlyPeriod(current, range.end);
|
|
113
113
|
}
|
|
114
114
|
if (result === null) current = null;
|
|
115
|
-
else current = result.end
|
|
115
|
+
else current = result.end;
|
|
116
116
|
return result;
|
|
117
117
|
};
|
|
118
118
|
};
|
|
@@ -130,13 +130,14 @@ const _nextAnnualPeriod = (nextStart, seriesEnd) => {
|
|
|
130
130
|
return {
|
|
131
131
|
period: "annual",
|
|
132
132
|
start: nextStart,
|
|
133
|
-
end: DateTime.utc(inputUtc.year,
|
|
133
|
+
end: DateTime.utc(inputUtc.year + 1, 1, 1)
|
|
134
134
|
};
|
|
135
135
|
};
|
|
136
136
|
const _nextSemiAnnualPeriod = (nextStart, seriesEnd) => {
|
|
137
137
|
if (seriesEnd <= nextStart) return null;
|
|
138
|
-
const
|
|
139
|
-
const
|
|
138
|
+
const inputUtc = nextStart.toUTC();
|
|
139
|
+
const midYear = DateTime.utc(inputUtc.year, 7, 1);
|
|
140
|
+
const endYear = DateTime.utc(inputUtc.year + 1, 1, 1);
|
|
140
141
|
let endDate;
|
|
141
142
|
if (midYear > nextStart) endDate = midYear;
|
|
142
143
|
else endDate = endYear;
|
|
@@ -155,7 +156,7 @@ const _nextQuarterlyPeriod = (nextStart, seriesEnd) => {
|
|
|
155
156
|
if (startMonth < 3) endDate = DateTime.utc(nextStartUtc.year, 4, 1);
|
|
156
157
|
else if (startMonth < 6) endDate = DateTime.utc(nextStartUtc.year, 7, 1);
|
|
157
158
|
else if (startMonth < 9) endDate = DateTime.utc(nextStartUtc.year, 10, 1);
|
|
158
|
-
else endDate = DateTime.utc(nextStartUtc.year
|
|
159
|
+
else endDate = DateTime.utc(nextStartUtc.year + 1, 1, 1);
|
|
159
160
|
if (endDate > seriesEnd) endDate = seriesEnd;
|
|
160
161
|
return {
|
|
161
162
|
period: "quarterly",
|
|
@@ -205,7 +206,7 @@ const _nextDailyPeriod = (nextStart, seriesEnd) => {
|
|
|
205
206
|
};
|
|
206
207
|
const _nextHourlyPeriod = (nextStart, seriesEnd) => {
|
|
207
208
|
if (seriesEnd <= nextStart) return null;
|
|
208
|
-
let endDate = nextStart.toUTC().plus({ hours: 1 });
|
|
209
|
+
let endDate = nextStart.toUTC().plus({ hours: 1 }).startOf("hour");
|
|
209
210
|
if (endDate > seriesEnd) {
|
|
210
211
|
if (nextStart.hour !== seriesEnd.hour) endDate = seriesEnd.toUTC();
|
|
211
212
|
}
|
|
@@ -263,29 +264,30 @@ var AnalyticsDiscretizer = class AnalyticsDiscretizer {
|
|
|
263
264
|
return Object.values(result);
|
|
264
265
|
}
|
|
265
266
|
static _getPeriodString(p) {
|
|
267
|
+
const startUtc = p.start.toUTC();
|
|
266
268
|
switch (p.period) {
|
|
267
|
-
case "annual": return
|
|
268
|
-
case "semiAnnual": return `${
|
|
269
|
-
case "quarterly": return `${
|
|
269
|
+
case "annual": return startUtc.year.toString();
|
|
270
|
+
case "semiAnnual": return `${startUtc.year}/${startUtc.month < 7 ? "H1" : "H2"}`;
|
|
271
|
+
case "quarterly": return `${startUtc.year}/Q${getQuarter(startUtc)}`;
|
|
270
272
|
case "monthly":
|
|
271
|
-
const month =
|
|
273
|
+
const month = startUtc.month;
|
|
272
274
|
const formattedMonth = month < 10 ? `0${month}` : `${month}`;
|
|
273
|
-
return `${
|
|
274
|
-
case "weekly": return `${
|
|
275
|
+
return `${startUtc.year}/${formattedMonth}`;
|
|
276
|
+
case "weekly": return `${startUtc.weekYear}/W${startUtc.weekNumber}`;
|
|
275
277
|
case "daily":
|
|
276
|
-
const monthD =
|
|
277
|
-
const day =
|
|
278
|
+
const monthD = startUtc.month;
|
|
279
|
+
const day = startUtc.day;
|
|
278
280
|
const formattedMonthD = monthD < 10 ? `0${monthD}` : `${monthD}`;
|
|
279
281
|
const formattedDay = day < 10 ? `0${day}` : `${day}`;
|
|
280
|
-
return `${
|
|
282
|
+
return `${startUtc.year}/${formattedMonthD}/${formattedDay}`;
|
|
281
283
|
case "hourly":
|
|
282
|
-
const monthH =
|
|
283
|
-
const dayH =
|
|
284
|
-
const hourH =
|
|
284
|
+
const monthH = startUtc.month;
|
|
285
|
+
const dayH = startUtc.day;
|
|
286
|
+
const hourH = startUtc.hour;
|
|
285
287
|
const formattedMonthH = monthH < 10 ? `0${monthH}` : `${monthH}`;
|
|
286
288
|
const formattedDayH = dayH < 10 ? `0${dayH}` : `${dayH}`;
|
|
287
289
|
const formattedHourH = hourH < 10 ? `0${hourH}` : `${hourH}`;
|
|
288
|
-
return `${
|
|
290
|
+
return `${startUtc.year}/${formattedMonthH}/${formattedDayH}/${formattedHourH}`;
|
|
289
291
|
default: return p.period;
|
|
290
292
|
}
|
|
291
293
|
}
|
|
@@ -326,6 +328,7 @@ var AnalyticsDiscretizer = class AnalyticsDiscretizer {
|
|
|
326
328
|
}
|
|
327
329
|
static _discretizeSeries(series, periods) {
|
|
328
330
|
const result = {};
|
|
331
|
+
if (periods.length === 0) return result;
|
|
329
332
|
for (const s of series) {
|
|
330
333
|
let oldSum = this._getValue(s, periods[0].start);
|
|
331
334
|
for (const p of periods) {
|
|
@@ -351,13 +354,13 @@ var AnalyticsDiscretizer = class AnalyticsDiscretizer {
|
|
|
351
354
|
}
|
|
352
355
|
}
|
|
353
356
|
static _getSingleValue(series, when) {
|
|
354
|
-
return when
|
|
357
|
+
return when > series.start ? series.value : 0;
|
|
355
358
|
}
|
|
356
359
|
static _getVestValue(series, when) {
|
|
357
360
|
const now = when;
|
|
358
361
|
const start = series.start;
|
|
359
362
|
const end = series.end;
|
|
360
|
-
const cliff = series.params?.cliff ? DateTime.fromISO(series.params.cliff) : null;
|
|
363
|
+
const cliff = series.params?.cliff ? DateTime.fromISO(series.params.cliff, { zone: "utc" }) : null;
|
|
361
364
|
if (now < start || cliff && now < cliff) return 0;
|
|
362
365
|
else if (end && now >= end) return series.value;
|
|
363
366
|
const a = Interval.fromDateTimes(start, now);
|
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 _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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"}
|
|
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\n// Boundary convention: periods are half-open intervals [start, end), where\n// each period's end is exactly the next period's start. Calendar-aligned\n// granularities anchor to the UTC calendar (ISO 8601): a period boundary sits\n// at T00:00:00.000Z of the first day of the calendar year / half-year /\n// quarter / month / ISO week / day / hour. The first period of a series may\n// be partial (it starts at the query start); subsequent periods start on the\n// calendar boundary. An instant exactly at a boundary belongs to the period\n// that starts there (see AnalyticsDiscretizer._getSingleValue).\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. Periods are half-open\n // [start, end), so the next period starts exactly at this period's end.\n if (result === null) {\n current = null;\n } else {\n current = result.end;\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 // Anchor to the UTC calendar year, like the other granularities: the\n // period ends at January 1st of the following year, so the first period\n // may be partial and every later period spans a full calendar year.\n const inputUtc = nextStart.toUTC();\n const endDate = DateTime.utc(inputUtc.year + 1, 1, 1);\n\n return {\n period: \"annual\",\n start: nextStart,\n end: endDate,\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 inputUtc = nextStart.toUTC();\n const midYear = DateTime.utc(inputUtc.year, 7, 1);\n const endYear = DateTime.utc(inputUtc.year + 1, 1, 1);\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 + 1, 1, 1);\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 // Anchor to the top of the hour: the first period may be partial, every\n // later period covers a full clock hour.\n const startDate = nextStart.toUTC();\n let endDate = startDate.plus({ hours: 1 }).startOf(\"hour\");\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 // Period boundaries are anchored to the UTC calendar (see\n // AnalyticsTimeSlicer), so labels are derived from the UTC view of the\n // period start, never from a zoned start's local calendar fields.\n const startUtc = p.start.toUTC();\n switch (p.period) {\n case \"annual\":\n return startUtc.year.toString();\n case \"semiAnnual\":\n return `${startUtc.year}/${startUtc.month < 7 ? \"H1\" : \"H2\"}`;\n case \"quarterly\":\n return `${startUtc.year}/Q${getQuarter(startUtc)}`;\n case \"monthly\":\n const month = startUtc.month;\n const formattedMonth = month < 10 ? `0${month}` : `${month}`;\n return `${startUtc.year}/${formattedMonth}`;\n case \"weekly\":\n return `${startUtc.weekYear}/W${startUtc.weekNumber}`;\n case \"daily\":\n const monthD = startUtc.month;\n const day = startUtc.day;\n const formattedMonthD = monthD < 10 ? `0${monthD}` : `${monthD}`;\n const formattedDay = day < 10 ? `0${day}` : `${day}`;\n return `${startUtc.year}/${formattedMonthD}/${formattedDay}`;\n case \"hourly\":\n const monthH = startUtc.month;\n const dayH = startUtc.day;\n const hourH = startUtc.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 `${startUtc.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 // An empty range (start equal to end) produces no periods; there is\n // nothing to attribute values to.\n if (periods.length === 0) {\n return result;\n }\n\n for (const s of series) {\n let oldSum = this._getValue(s, periods[0].start);\n for (const p of periods) {\n // Periods are half-open [start, end): the cumulative value \"as of\"\n // a boundary excludes values stamped exactly on it, so a value at\n // an exact period start is attributed to the period that starts\n // there, not the one that ends there.\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 // Strictly greater than: the cumulative value at instant t covers values\n // stamped before t only. Periods are half-open [start, end), so a value\n // stamped exactly at a boundary belongs to the period that starts there.\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, { zone: \"utc\" })\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.2.3-dev.
|
|
3
|
+
"version": "6.2.3-dev.44",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"luxon": "3.7.2",
|
|
27
|
-
"@powerhousedao/shared": "6.2.3-dev.
|
|
27
|
+
"@powerhousedao/shared": "6.2.3-dev.44"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/luxon": "3.7.1",
|