@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 3.78 kB
Source Map (JSON)
{"version":3,"file":"build-usage-chart-series.mjs","names":[],"sources":["../../../../src/services/ai/helpers/build-usage-chart-series.ts"],"sourcesContent":["import type { AiUsageChartRowPropT } from \"../../../libs/repositories/index.js\";\nimport type { AiUsageChartMetric } from \"../../../types/response.js\";\nimport { getNumber, getObject } from \"../../../utils/helpers/index.js\";\nimport { addDays, getDateKey, parseStoredTimestamp } from \"./date-helpers.js\";\n\nconst buildInitialPoints = (start: Date, end: Date) => {\n\tconst points = new Map<string, number>();\n\tlet cursor = new Date(start);\n\n\twhile (cursor.getTime() <= end.getTime()) {\n\t\tpoints.set(getDateKey(cursor), 0);\n\t\tcursor = addDays(cursor, 1);\n\t}\n\n\treturn points;\n};\n\nconst getMetricValue = (\n\trow: AiUsageChartRowPropT,\n\tmetric: AiUsageChartMetric,\n) => {\n\tswitch (metric) {\n\t\tcase \"requests\":\n\t\t\treturn 1;\n\t\tcase \"cost\":\n\t\t\treturn row.cost_total_minor ?? 0;\n\t\tdefault: {\n\t\t\tconst usage = getObject(row.usage);\n\t\t\tconst tokens = getObject(usage?.tokens);\n\t\t\treturn getNumber(tokens?.total) ?? 0;\n\t\t}\n\t}\n};\n\n/**\n * Buckets raw AI usage rows into complete daily chart series, filling missing\n * dates with zeroes so the frontend can render a stable line chart.\n */\nconst buildUsageChartSeries = (props: {\n\trows: AiUsageChartRowPropT[];\n\tmetrics: AiUsageChartMetric[];\n\tstart: Date;\n\tend: Date;\n}) => {\n\tconst pointMaps = new Map(\n\t\tprops.metrics.map((metric) => [\n\t\t\tmetric,\n\t\t\tbuildInitialPoints(props.start, props.end),\n\t\t]),\n\t);\n\tconst firstPointMap = pointMaps.get(props.metrics[0] ?? \"totalTokens\");\n\tlet currency: string | null = null;\n\n\tfor (const row of props.rows) {\n\t\tconst createdAt = parseStoredTimestamp(row.created_at);\n\t\tif (Number.isNaN(createdAt.getTime())) continue;\n\n\t\tconst dateKey = getDateKey(createdAt);\n\t\tif (!firstPointMap?.has(dateKey)) continue;\n\n\t\tif (!currency && row.cost_currency) {\n\t\t\tcurrency = row.cost_currency;\n\t\t}\n\n\t\tfor (const metric of props.metrics) {\n\t\t\tconst pointMap = pointMaps.get(metric);\n\t\t\tif (!pointMap) continue;\n\n\t\t\tpointMap.set(\n\t\t\t\tdateKey,\n\t\t\t\t(pointMap.get(dateKey) ?? 0) + getMetricValue(row, metric),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn {\n\t\tcurrency,\n\t\tseries: props.metrics.map((metric) => ({\n\t\t\tmetric,\n\t\t\tpoints: Array.from(\n\t\t\t\t(\n\t\t\t\t\tpointMaps.get(metric) ?? buildInitialPoints(props.start, props.end)\n\t\t\t\t).entries(),\n\t\t\t).map(([date, value]) => ({\n\t\t\t\tdate,\n\t\t\t\tvalue,\n\t\t\t})),\n\t\t})),\n\t};\n};\n\nexport default buildUsageChartSeries;\n"],"mappings":"6KAKA,MAAM,GAAsB,EAAa,IAAc,CACtD,IAAM,EAAS,IAAI,IACf,EAAS,IAAI,KAAK,CAAK,EAE3B,KAAO,EAAO,QAAQ,GAAK,EAAI,QAAQ,GACtC,EAAO,IAAI,EAAW,CAAM,EAAG,CAAC,EAChC,EAAS,EAAQ,EAAQ,CAAC,EAG3B,OAAO,CACR,EAEM,GACL,EACA,IACI,CACJ,OAAQ,EAAR,CACC,IAAK,WACJ,MAAO,GACR,IAAK,OACJ,OAAO,EAAI,kBAAoB,EAChC,QAGC,OAAO,EADQ,EADD,EAAU,EAAI,KACC,CAAC,EAAE,MACV,CAAC,EAAE,KAAK,GAAK,CAErC,CACD,EAMM,EAAyB,GAKzB,CACL,IAAM,EAAY,IAAI,IACrB,EAAM,QAAQ,IAAK,GAAW,CAC7B,EACA,EAAmB,EAAM,MAAO,EAAM,GAAG,CAC1C,CAAC,CACF,EACM,EAAgB,EAAU,IAAI,EAAM,QAAQ,IAAM,aAAa,EACjE,EAA0B,KAE9B,IAAK,IAAM,KAAO,EAAM,KAAM,CAC7B,IAAM,EAAY,EAAqB,EAAI,UAAU,EACrD,GAAI,OAAO,MAAM,EAAU,QAAQ,CAAC,EAAG,SAEvC,IAAM,EAAU,EAAW,CAAS,EAC/B,MAAe,IAAI,CAAO,EAE/B,CAAI,CAAC,GAAY,EAAI,gBACpB,EAAW,EAAI,eAGhB,IAAK,IAAM,KAAU,EAAM,QAAS,CACnC,IAAM,EAAW,EAAU,IAAI,CAAM,EAChC,GAEL,EAAS,IACR,GACC,EAAS,IAAI,CAAO,GAAK,GAAK,EAAe,EAAK,CAAM,CAC1D,CACD,CAXgB,CAYjB,CAEA,MAAO,CACN,WACA,OAAQ,EAAM,QAAQ,IAAK,IAAY,CACtC,SACA,OAAQ,MAAM,MAEZ,EAAU,IAAI,CAAM,GAAK,EAAmB,EAAM,MAAO,EAAM,GAAG,EAAA,CACjE,QAAQ,CACX,CAAC,CAAC,KAAK,CAAC,EAAM,MAAY,CACzB,OACA,OACD,EAAE,CACH,EAAE,CACH,CACD"}