@burdenoff/microfe-bigconsole 2026.1101.1 → 2026.1103.1

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.
@@ -0,0 +1,15 @@
1
+ import { DataSink, DataSinkSetupState } from '../types';
2
+ /** What is still missing before a data sink counts as set up. */
3
+ export type DataSinkSetupGap = 'data' | 'ttl';
4
+ type SetupInput = Pick<DataSink, 'setupState' | 'ttl' | 'sizeBytes' | 'fluidGridsWorkflowId'>;
5
+ export declare function resolveSetupState(sink: SetupInput): DataSinkSetupState;
6
+ /**
7
+ * The missing pieces behind an incomplete setup; empty once the sink is set up.
8
+ * Also empty while its workflow is running: the workflow is producing the data,
9
+ * so "no data yet" would send the user to fill in what is already on its way.
10
+ */
11
+ export declare function getSetupGaps(sink: SetupInput): DataSinkSetupGap[];
12
+ type Translate = (key: string, fallback: string, params?: Record<string, string | number>) => string;
13
+ /** "Setup incomplete: no data yet, no cache TTL set", or the bare label when no gap is known. */
14
+ export declare function describeSetupGaps(gaps: readonly DataSinkSetupGap[], t: Translate): string;
15
+ export {};
@@ -0,0 +1,23 @@
1
+ import { hasDataSinkPayload as e } from "./dataSinkPayload.js";
2
+ //#region src/bigconsole/utils/dataSinkSetup.ts
3
+ var t = [
4
+ "workflow_pending",
5
+ "workflow_running",
6
+ "workflow_completed",
7
+ "configuration_pending",
8
+ "completed"
9
+ ], n = (e) => typeof e.ttl == "number" && e.ttl > 0;
10
+ function r(r) {
11
+ return t.includes(r.setupState) ? r.setupState : e(r) ? n(r) ? "completed" : "configuration_pending" : r.fluidGridsWorkflowId ? "workflow_running" : "workflow_pending";
12
+ }
13
+ function i(t) {
14
+ let i = r(t);
15
+ if (i === "completed" || i === "workflow_running") return [];
16
+ let a = [];
17
+ return e(t) || a.push("data"), n(t) || a.push("ttl"), a;
18
+ }
19
+ function a(e, t) {
20
+ return e.length === 0 ? t("bigconsole.dataSinks.setup.incomplete", "Setup incomplete") : t("bigconsole.dataSinks.setup.incompleteWithGaps", "Setup incomplete: {{gaps}}", { gaps: e.map((e) => e === "data" ? t("bigconsole.dataSinks.setup.gapData", "no data yet") : t("bigconsole.dataSinks.setup.gapTtl", "no cache TTL set")).join(", ") });
21
+ }
22
+ //#endregion
23
+ export { a as describeSetupGaps, i as getSetupGaps, r as resolveSetupState };
@@ -0,0 +1,47 @@
1
+ import { PipelineExecution, PipelineExecutionStatus, PipelineStage, StageExecutionStatus } from '../types';
2
+ /** Visual tone shared by run and stage statuses. */
3
+ export type ExecutionTone = 'success' | 'danger' | 'warning' | 'info' | 'neutral';
4
+ export interface StageTimelineRow {
5
+ id: string;
6
+ /** 1-based position in the run. */
7
+ step: number;
8
+ name: string;
9
+ status: StageExecutionStatus;
10
+ tone: ExecutionTone;
11
+ durationMs: number | null;
12
+ /** Bar start as a percentage of the run's summed stage time (0–100). */
13
+ offsetPercent: number;
14
+ /** Bar width as a percentage of the run's summed stage time (0–100). */
15
+ widthPercent: number;
16
+ inputKey: string | null;
17
+ outputKey: string | null;
18
+ error: string | null;
19
+ output: unknown;
20
+ hasOutput: boolean;
21
+ }
22
+ export interface StageTimeline {
23
+ rows: StageTimelineRow[];
24
+ /** Sum of recorded stage durations, used as the bar scale. */
25
+ totalStageMs: number;
26
+ counts: Record<'success' | 'skipped' | 'failed' | 'other', number>;
27
+ }
28
+ export declare function runStatusTone(status: PipelineExecutionStatus): ExecutionTone;
29
+ export declare function stageStatusTone(status: StageExecutionStatus): ExecutionTone;
30
+ /** Runs that belong to `pipelineId`, newest first (stable for equal timestamps). */
31
+ export declare function orderExecutionsForPipeline(executions: readonly PipelineExecution[], pipelineId: string | undefined): PipelineExecution[];
32
+ /**
33
+ * Keep the user's selected run if it is still in the list, otherwise select
34
+ * the newest one (or nothing when the pipeline has no runs).
35
+ */
36
+ export declare function pickSelectedExecution(ordered: readonly PipelineExecution[], selectedId: string | null | undefined): PipelineExecution | null;
37
+ /** Duration of a run: the recorded total, else completedAt − startedAt, else null. */
38
+ export declare function runDurationMs(execution: PipelineExecution): number | null;
39
+ /** Human duration: "—", "850 ms", "1.25 s", "2 m 05 s". */
40
+ export declare function formatDurationMs(ms: number | null | undefined): string;
41
+ /**
42
+ * Who started the run, from the viewer's perspective. Returns `null` for the
43
+ * viewer themselves so the caller can render a translated "You".
44
+ */
45
+ export declare function triggeredByLabel(executedBy: string, currentActorId: string | null | undefined): string | null;
46
+ /** Build the waterfall rows for one run against the pipeline's current stages. */
47
+ export declare function buildStageTimeline(execution: PipelineExecution, stages: readonly PipelineStage[] | null | undefined): StageTimeline;
@@ -0,0 +1,87 @@
1
+ //#region src/bigconsole/utils/pipelineExecutionTimeline.ts
2
+ var e = {
3
+ completed: "success",
4
+ failed: "danger",
5
+ running: "info",
6
+ pending: "neutral"
7
+ }, t = {
8
+ success: "success",
9
+ failed: "danger",
10
+ skipped: "warning",
11
+ running: "info",
12
+ pending: "neutral"
13
+ }, n = 2;
14
+ function r(t) {
15
+ return e[t] ?? "neutral";
16
+ }
17
+ function i(e) {
18
+ return t[e] ?? "neutral";
19
+ }
20
+ function a(e) {
21
+ let t = Date.parse(e.startedAt ?? e.createdAt);
22
+ return Number.isNaN(t) ? 0 : t;
23
+ }
24
+ function o(e, t) {
25
+ return t ? e.map((e, t) => ({
26
+ execution: e,
27
+ index: t
28
+ })).filter(({ execution: e }) => e.pipelineId === t).sort((e, t) => a(t.execution) - a(e.execution) || e.index - t.index).map(({ execution: e }) => e) : [];
29
+ }
30
+ function s(e, t) {
31
+ if (t) {
32
+ let n = e.find((e) => e.id === t);
33
+ if (n) return n;
34
+ }
35
+ return e[0] ?? null;
36
+ }
37
+ function c(e) {
38
+ if (e.totalExecutionTimeMs != null) return e.totalExecutionTimeMs;
39
+ if (!e.startedAt || !e.completedAt) return null;
40
+ let t = Date.parse(e.completedAt) - Date.parse(e.startedAt);
41
+ return Number.isFinite(t) && t >= 0 ? t : null;
42
+ }
43
+ function l(e) {
44
+ if (e == null || !Number.isFinite(e) || e < 0) return "—";
45
+ if (e < 1e3) return `${Math.round(e)} ms`;
46
+ if (e < 6e4) return `${(e / 1e3).toFixed(2).replace(/\.?0+$/, "")} s`;
47
+ let t = Math.floor(e / 6e4), n = Math.round(e % 6e4 / 1e3);
48
+ return `${t} m ${String(n).padStart(2, "0")} s`;
49
+ }
50
+ function u(e, t) {
51
+ return t && e === t ? null : e.length > 12 ? `${e.slice(0, 8)}…` : e;
52
+ }
53
+ function d(e, t, n) {
54
+ return e.stageName || t?.parserName || `Stage ${n}`;
55
+ }
56
+ function f(e, t) {
57
+ let r = new Map((t ?? []).map((e) => [e.id, e])), a = e.stageResults ?? [], o = a.map((e) => e.executionTimeMs != null && Number.isFinite(e.executionTimeMs) && e.executionTimeMs > 0 ? e.executionTimeMs : 0), s = o.reduce((e, t) => e + t, 0), c = {
58
+ success: 0,
59
+ skipped: 0,
60
+ failed: 0,
61
+ other: 0
62
+ }, l = 0;
63
+ return {
64
+ rows: a.map((e, t) => {
65
+ let u = r.get(e.stageId), f = o[t] ?? 0, p = s > 0 ? l / s * 100 : t / a.length * 100, m = s > 0 ? f / s * 100 : 100 / a.length, h = Math.min(100 - Math.min(p, 100 - n), Math.max(m, n));
66
+ return l += f, e.status === "success" || e.status === "skipped" || e.status === "failed" ? c[e.status] += 1 : c.other += 1, {
67
+ id: e.id,
68
+ step: t + 1,
69
+ name: d(e, u, t + 1),
70
+ status: e.status,
71
+ tone: i(e.status),
72
+ durationMs: e.executionTimeMs ?? null,
73
+ offsetPercent: Math.min(p, 100 - n),
74
+ widthPercent: h,
75
+ inputKey: u?.inputKey ?? null,
76
+ outputKey: u?.outputKey ?? null,
77
+ error: e.error,
78
+ output: e.output,
79
+ hasOutput: e.output !== null && e.output !== void 0
80
+ };
81
+ }),
82
+ totalStageMs: s,
83
+ counts: c
84
+ };
85
+ }
86
+ //#endregion
87
+ export { f as buildStageTimeline, l as formatDurationMs, o as orderExecutionsForPipeline, s as pickSelectedExecution, c as runDurationMs, r as runStatusTone, i as stageStatusTone, u as triggeredByLabel };
@@ -0,0 +1,41 @@
1
+ import { ParserType, PipelineStage, StageErrorHandling } from '../types';
2
+ /** Editable stage state held by the pipeline builder. */
3
+ export interface PipelineStageForm {
4
+ id?: string;
5
+ parserId: string;
6
+ parserName: string;
7
+ parserType: ParserType | null;
8
+ /** Inline expression stages carry no parser; kept so a save cannot drop it. */
9
+ expression: string;
10
+ inputKey: string;
11
+ outputKey: string;
12
+ enabled: boolean;
13
+ onError: StageErrorHandling;
14
+ /** JSON text; empty means "no fallback". */
15
+ fallbackValue: string;
16
+ description: string;
17
+ }
18
+ /** Stage payload accepted by both CreatePipelineStageInput and UpdatePipelineStageInput. */
19
+ export interface PipelineStagePayload {
20
+ parserId: string;
21
+ parserName?: string;
22
+ parserType?: ParserType;
23
+ expression?: string;
24
+ inputKey: string;
25
+ outputKey: string;
26
+ enabled: boolean;
27
+ onError: StageErrorHandling;
28
+ fallbackValue?: unknown;
29
+ description?: string;
30
+ }
31
+ /** Thrown when a stage's fallback value is not valid JSON. */
32
+ export declare class InvalidFallbackValueError extends Error {
33
+ readonly stageIndex: number;
34
+ constructor(stageIndex: number, cause: unknown);
35
+ }
36
+ /** Seed builder form rows from persisted stages, preserving their order. */
37
+ export declare function stagesToForm(stages: readonly PipelineStage[] | null | undefined): PipelineStageForm[];
38
+ /** A stage can run when it has a parser or an inline expression, and both keys. */
39
+ export declare function isStageFormComplete(stage: PipelineStageForm): boolean;
40
+ /** Map builder rows to the stage payload, in display order. */
41
+ export declare function formToStageInputs(stages: readonly PipelineStageForm[]): PipelineStagePayload[];
@@ -0,0 +1,49 @@
1
+ //#region src/bigconsole/utils/pipelineStages.ts
2
+ var e = class extends Error {
3
+ stageIndex;
4
+ constructor(e, t) {
5
+ super(`Stage ${e + 1}: the fallback value is not valid JSON (${t instanceof Error ? t.message : String(t)}).`), this.stageIndex = e, this.name = "InvalidFallbackValueError";
6
+ }
7
+ };
8
+ function t(e) {
9
+ return [...e ?? []].sort((e, t) => e.position - t.position).map((e) => ({
10
+ id: e.id,
11
+ parserId: e.parserId ?? "",
12
+ parserName: e.parserName ?? "",
13
+ parserType: e.parserType ?? null,
14
+ expression: e.expression ?? "",
15
+ inputKey: e.inputKey,
16
+ outputKey: e.outputKey,
17
+ enabled: e.enabled,
18
+ onError: e.onError,
19
+ fallbackValue: e.fallbackValue == null ? "" : JSON.stringify(e.fallbackValue),
20
+ description: e.description ?? ""
21
+ }));
22
+ }
23
+ function n(e) {
24
+ return !!((e.parserId || e.expression.trim()) && e.inputKey.trim() && e.outputKey.trim());
25
+ }
26
+ function r(t) {
27
+ return t.map((t, n) => {
28
+ let r;
29
+ if (t.fallbackValue.trim() !== "") try {
30
+ r = JSON.parse(t.fallbackValue);
31
+ } catch (t) {
32
+ throw new e(n, t);
33
+ }
34
+ return {
35
+ parserId: t.parserId,
36
+ parserName: t.parserName || void 0,
37
+ parserType: t.parserType ?? void 0,
38
+ expression: t.expression.trim() ? t.expression : void 0,
39
+ inputKey: t.inputKey,
40
+ outputKey: t.outputKey,
41
+ enabled: t.enabled,
42
+ onError: t.onError,
43
+ fallbackValue: r,
44
+ description: t.description || void 0
45
+ };
46
+ });
47
+ }
48
+ //#endregion
49
+ export { e as InvalidFallbackValueError, r as formToStageInputs, n as isStageFormComplete, t as stagesToForm };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-bigconsole",
3
- "version": "2026.1101.1",
3
+ "version": "2026.1103.1",
4
4
  "description": "BigConsole - AI-powered analytics and dashboard platform",
5
5
  "type": "module",
6
6
  "files": [