@burdenoff/microfe-bigconsole 2026.730.7 → 2026.731.2

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.
@@ -30,49 +30,49 @@ function l(e) {
30
30
  function u(e) {
31
31
  return e < 60 ? `${e} seconds` : e < 3600 ? `${Math.floor(e / 60)} minutes` : e < 86400 ? `${Math.floor(e / 3600)} hours` : `${Math.floor(e / 86400)} days`;
32
32
  }
33
- var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p }) {
34
- let [m, h] = i(!l(e) && e !== null), [g, _] = i(e?.toString() || ""), [v, y] = i(null), b = r(e);
33
+ var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p, hideLabel: m = !1 }) {
34
+ let [h, g] = i(!l(e) && e !== null), [_, v] = i(e?.toString() || ""), [y, b] = i(null), x = r(e);
35
35
  n(() => {
36
- b.current !== e && (b.current = e, e !== null && !l(e) && queueMicrotask(() => {
37
- _(e.toString()), h(!0);
36
+ x.current !== e && (x.current = e, e !== null && !l(e) && queueMicrotask(() => {
37
+ v(e.toString()), g(!0);
38
38
  }));
39
39
  }, [e]);
40
- let x = t((e) => {
41
- f || (h(!1), d(e));
42
- }, [f, d]), S = t(() => {
40
+ let S = t((e) => {
41
+ f || (g(!1), d(e));
42
+ }, [f, d]), C = t(() => {
43
43
  if (f) return;
44
- h(!0);
45
- let e = parseInt(g);
44
+ g(!0);
45
+ let e = parseInt(_);
46
46
  !isNaN(e) && e >= 30 && e <= 86400 && d(e);
47
47
  }, [
48
48
  f,
49
- g,
49
+ _,
50
50
  d
51
- ]), C = t((e) => {
51
+ ]), w = t((e) => {
52
52
  let t = e.target.value;
53
- if (_(t), t === "") {
54
- y(null);
53
+ if (v(t), t === "") {
54
+ b(null);
55
55
  return;
56
56
  }
57
57
  let n = parseInt(t);
58
58
  if (isNaN(n)) {
59
- y("Please enter a valid number");
59
+ b("Please enter a valid number");
60
60
  return;
61
61
  }
62
62
  if (n < 30) {
63
- y("Minimum cache duration is 30 seconds");
63
+ b("Minimum cache duration is 30 seconds");
64
64
  return;
65
65
  }
66
66
  if (n > 86400) {
67
- y("Maximum cache duration is 86400 seconds (24 hours)");
67
+ b("Maximum cache duration is 86400 seconds (24 hours)");
68
68
  return;
69
69
  }
70
- y(null), d(n);
70
+ b(null), d(n);
71
71
  }, [d]);
72
72
  return /* @__PURE__ */ s("div", {
73
73
  className: "space-y-3",
74
74
  children: [
75
- /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("label", {
75
+ !m && /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("label", {
76
76
  className: "block text-sm font-medium text-text-primary mb-1",
77
77
  children: "Cache Duration"
78
78
  }), /* @__PURE__ */ o("p", {
@@ -89,13 +89,13 @@ var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p }) {
89
89
  cursor-pointer
90
90
  transition-all
91
91
  ${f ? "opacity-50 cursor-not-allowed" : ""}
92
- ${!m && e === t.value ? "border-action-primary-bg bg-action-primary-bg/5" : "border-border-default hover:border-border-hover"}
92
+ ${!h && e === t.value ? "border-action-primary-bg bg-action-primary-bg/5" : "border-border-default hover:border-border-hover"}
93
93
  `,
94
94
  children: [/* @__PURE__ */ o("input", {
95
95
  type: "radio",
96
96
  name: "cache-ttl",
97
- checked: !m && e === t.value,
98
- onChange: () => x(t.value),
97
+ checked: !h && e === t.value,
98
+ onChange: () => S(t.value),
99
99
  disabled: f,
100
100
  className: "\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n "
101
101
  }), /* @__PURE__ */ s("div", {
@@ -122,13 +122,13 @@ var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p }) {
122
122
  cursor-pointer
123
123
  transition-all
124
124
  ${f ? "opacity-50 cursor-not-allowed" : ""}
125
- ${m ? "border-action-primary-bg bg-action-primary-bg/5" : "border-border-default hover:border-border-hover"}
125
+ ${h ? "border-action-primary-bg bg-action-primary-bg/5" : "border-border-default hover:border-border-hover"}
126
126
  `,
127
127
  children: [/* @__PURE__ */ o("input", {
128
128
  type: "radio",
129
129
  name: "cache-ttl",
130
- checked: m,
131
- onChange: S,
130
+ checked: h,
131
+ onChange: C,
132
132
  disabled: f,
133
133
  className: "\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n "
134
134
  }), /* @__PURE__ */ s("div", {
@@ -142,13 +142,13 @@ var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p }) {
142
142
  className: "text-xs text-text-secondary mt-0.5",
143
143
  children: "Enter a custom cache duration (30 - 86400 seconds)"
144
144
  }),
145
- m && /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ s("div", {
145
+ h && /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ s("div", {
146
146
  className: "mt-3 flex items-center gap-2",
147
147
  children: [
148
148
  /* @__PURE__ */ o("input", {
149
149
  type: "number",
150
- value: g,
151
- onChange: C,
150
+ value: _,
151
+ onChange: w,
152
152
  disabled: f,
153
153
  min: 30,
154
154
  max: 86400,
@@ -163,23 +163,23 @@ var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p }) {
163
163
  focus:border-action-primary-bg
164
164
  focus:ring-2
165
165
  focus:ring-action-primary-bg/20
166
- ${p || v ? "border-status-error-border" : "border-border-default"}
166
+ ${p || y ? "border-status-error-border" : "border-border-default"}
167
167
  `
168
168
  }),
169
169
  /* @__PURE__ */ o("span", {
170
170
  className: "text-sm text-text-secondary",
171
171
  children: "seconds"
172
172
  }),
173
- g && !isNaN(parseInt(g)) && !v && /* @__PURE__ */ s("span", {
173
+ _ && !isNaN(parseInt(_)) && !y && /* @__PURE__ */ s("span", {
174
174
  className: "text-xs text-text-tertiary",
175
175
  children: [
176
176
  "(",
177
- u(parseInt(g)),
177
+ u(parseInt(_)),
178
178
  ")"
179
179
  ]
180
180
  })
181
181
  ]
182
- }), v && /* @__PURE__ */ s("div", {
182
+ }), y && /* @__PURE__ */ s("div", {
183
183
  className: "flex items-center gap-1 mt-1",
184
184
  children: [/* @__PURE__ */ o("svg", {
185
185
  className: "w-3.5 h-3.5 text-status-error-text flex-shrink-0",
@@ -194,7 +194,7 @@ var d = e(function({ value: e, onChange: d, disabled: f = !1, error: p }) {
194
194
  })
195
195
  }), /* @__PURE__ */ o("span", {
196
196
  className: "text-xs text-status-error-text",
197
- children: v
197
+ children: y
198
198
  })]
199
199
  })] })
200
200
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"CacheTTLSelector.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/CacheTTLSelector.tsx"],"sourcesContent":["/**\n * Cache TTL Selector\n *\n * Component for selecting cache duration with preset options and custom input.\n */\n\nimport { memo, useState, useEffect, useCallback, useRef } from 'react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface CacheTTLOption {\n value: number;\n label: string;\n description: string;\n recommended?: boolean;\n}\n\ninterface CacheTTLSelectorProps {\n /** Current TTL value in seconds (null for no cache) */\n value: number | null;\n /** Callback when value changes */\n onChange: (value: number) => void;\n /** Whether selector is disabled */\n disabled?: boolean;\n /** Error message */\n error?: string;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst PRESET_OPTIONS: CacheTTLOption[] = [\n {\n value: 300, // 5 minutes\n label: '5 minutes',\n description: 'Best for real-time dashboards',\n },\n {\n value: 900, // 15 minutes\n label: '15 minutes',\n description: 'Balanced performance',\n recommended: true,\n },\n {\n value: 3600, // 1 hour\n label: '1 hour',\n description: 'For data that changes hourly',\n },\n {\n value: 86400, // 24 hours\n label: '24 hours',\n description: 'For daily reports',\n },\n];\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Check if value is a preset option\n */\nfunction isPresetValue(value: number | null): boolean {\n if (value === null) return false;\n return PRESET_OPTIONS.some((opt) => opt.value === value);\n}\n\n/**\n * Format seconds to human-readable string\n */\nfunction formatDuration(seconds: number): string {\n if (seconds < 60) {\n return `${seconds} seconds`;\n }\n if (seconds < 3600) {\n return `${Math.floor(seconds / 60)} minutes`;\n }\n if (seconds < 86400) {\n return `${Math.floor(seconds / 3600)} hours`;\n }\n return `${Math.floor(seconds / 86400)} days`;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const CacheTTLSelector = memo(function CacheTTLSelector({\n value,\n onChange,\n disabled = false,\n error,\n}: CacheTTLSelectorProps) {\n // Track whether custom mode is active\n const [isCustom, setIsCustom] = useState(!isPresetValue(value) && value !== null);\n const [customValue, setCustomValue] = useState(value?.toString() || '');\n const [validationError, setValidationError] = useState<string | null>(null);\n const prevValueRef = useRef(value);\n\n // Sync custom value when external value changes (using deferred update to avoid cascading renders)\n useEffect(() => {\n if (prevValueRef.current !== value) {\n prevValueRef.current = value;\n if (value !== null && !isPresetValue(value)) {\n // Defer state update to avoid synchronous setState in effect\n queueMicrotask(() => {\n setCustomValue(value.toString());\n setIsCustom(true);\n });\n }\n }\n }, [value]);\n\n // Handle preset selection\n const handlePresetChange = useCallback(\n (presetValue: number) => {\n if (disabled) return;\n setIsCustom(false);\n onChange(presetValue);\n },\n [disabled, onChange]\n );\n\n // Handle custom mode activation\n const handleCustomSelect = useCallback(() => {\n if (disabled) return;\n setIsCustom(true);\n const parsed = parseInt(customValue);\n if (!isNaN(parsed) && parsed >= 30 && parsed <= 86400) {\n onChange(parsed);\n }\n }, [disabled, customValue, onChange]);\n\n // Handle custom value change with validation\n const handleCustomChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = e.target.value;\n setCustomValue(inputValue);\n\n // Validate input\n if (inputValue === '') {\n setValidationError(null);\n return;\n }\n\n const parsed = parseInt(inputValue);\n\n if (isNaN(parsed)) {\n setValidationError('Please enter a valid number');\n return;\n }\n\n if (parsed < 30) {\n setValidationError('Minimum cache duration is 30 seconds');\n return;\n }\n\n if (parsed > 86400) {\n setValidationError('Maximum cache duration is 86400 seconds (24 hours)');\n return;\n }\n\n // Valid value\n setValidationError(null);\n onChange(parsed);\n },\n [onChange]\n );\n\n return (\n <div className=\"space-y-3\">\n {/* Label */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Cache Duration</label>\n <p className=\"text-xs text-text-secondary\">How long should data be cached before refreshing?</p>\n </div>\n\n {/* Options */}\n <div className=\"space-y-2\">\n {/* Preset options */}\n {PRESET_OPTIONS.map((option) => (\n <label\n key={option.value}\n className={`\n flex items-start gap-3\n p-3\n border rounded-lg\n cursor-pointer\n transition-all\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${\n !isCustom && value === option.value\n ? 'border-action-primary-bg bg-action-primary-bg/5'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <input\n type=\"radio\"\n name=\"cache-ttl\"\n checked={!isCustom && value === option.value}\n onChange={() => handlePresetChange(option.value)}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-text-primary\">{option.label}</span>\n {option.recommended && (\n <span className=\"px-1.5 py-0.5 text-xs font-medium bg-action-primary-bg/10 text-action-primary-bg rounded\">\n Recommended\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary mt-0.5\">{option.description}</p>\n </div>\n </label>\n ))}\n\n {/* Custom option */}\n <label\n className={`\n flex items-start gap-3\n p-3\n border rounded-lg\n cursor-pointer\n transition-all\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${\n isCustom\n ? 'border-action-primary-bg bg-action-primary-bg/5'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <input\n type=\"radio\"\n name=\"cache-ttl\"\n checked={isCustom}\n onChange={handleCustomSelect}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <span className=\"text-sm font-medium text-text-primary\">Custom</span>\n <p className=\"text-xs text-text-secondary mt-0.5\">Enter a custom cache duration (30 - 86400 seconds)</p>\n {isCustom && (\n <>\n <div className=\"mt-3 flex items-center gap-2\">\n <input\n type=\"number\"\n value={customValue}\n onChange={handleCustomChange}\n disabled={disabled}\n min={30}\n max={86400}\n placeholder=\"300\"\n className={`\n w-32 px-3 py-2\n bg-bg-sunken\n border rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n ${error || validationError ? 'border-status-error-border' : 'border-border-default'}\n `}\n />\n <span className=\"text-sm text-text-secondary\">seconds</span>\n {customValue && !isNaN(parseInt(customValue)) && !validationError && (\n <span className=\"text-xs text-text-tertiary\">({formatDuration(parseInt(customValue))})</span>\n )}\n </div>\n {validationError && (\n <div className=\"flex items-center gap-1 mt-1\">\n <svg\n className=\"w-3.5 h-3.5 text-status-error-text flex-shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span className=\"text-xs text-status-error-text\">{validationError}</span>\n </div>\n )}\n </>\n )}\n </div>\n </label>\n </div>\n\n {/* Error message */}\n {error && (\n <div className=\"flex items-start gap-2\">\n <svg\n className=\"w-4 h-4 text-status-error-text flex-shrink-0 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <p className=\"text-xs text-status-error-text\">{error}</p>\n </div>\n )}\n\n {/* Info message */}\n {value !== null && !error && (\n <div className=\"flex items-center gap-2 text-xs text-text-secondary\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span>Data will be cached for {formatDuration(value)} before being refreshed</span>\n </div>\n )}\n </div>\n );\n});\n\nexport default CacheTTLSelector;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CacheTTLSelector.js","names":[],"sources":["../../../../src/bigconsole/components/datasink/CacheTTLSelector.tsx"],"sourcesContent":["/**\n * Cache TTL Selector\n *\n * Component for selecting cache duration with preset options and custom input.\n */\n\nimport { memo, useState, useEffect, useCallback, useRef } from 'react';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface CacheTTLOption {\n value: number;\n label: string;\n description: string;\n recommended?: boolean;\n}\n\ninterface CacheTTLSelectorProps {\n /** Current TTL value in seconds (null for no cache) */\n value: number | null;\n /** Callback when value changes */\n onChange: (value: number) => void;\n /** Whether selector is disabled */\n disabled?: boolean;\n /** Error message */\n error?: string;\n /**\n * Hide the built-in \"Cache Duration\" heading + description. Use when the\n * surrounding form already renders its own label for this control, to avoid a\n * duplicated heading.\n */\n hideLabel?: boolean;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst PRESET_OPTIONS: CacheTTLOption[] = [\n {\n value: 300, // 5 minutes\n label: '5 minutes',\n description: 'Best for real-time dashboards',\n },\n {\n value: 900, // 15 minutes\n label: '15 minutes',\n description: 'Balanced performance',\n recommended: true,\n },\n {\n value: 3600, // 1 hour\n label: '1 hour',\n description: 'For data that changes hourly',\n },\n {\n value: 86400, // 24 hours\n label: '24 hours',\n description: 'For daily reports',\n },\n];\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\n/**\n * Check if value is a preset option\n */\nfunction isPresetValue(value: number | null): boolean {\n if (value === null) return false;\n return PRESET_OPTIONS.some((opt) => opt.value === value);\n}\n\n/**\n * Format seconds to human-readable string\n */\nfunction formatDuration(seconds: number): string {\n if (seconds < 60) {\n return `${seconds} seconds`;\n }\n if (seconds < 3600) {\n return `${Math.floor(seconds / 60)} minutes`;\n }\n if (seconds < 86400) {\n return `${Math.floor(seconds / 3600)} hours`;\n }\n return `${Math.floor(seconds / 86400)} days`;\n}\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const CacheTTLSelector = memo(function CacheTTLSelector({\n value,\n onChange,\n disabled = false,\n error,\n hideLabel = false,\n}: CacheTTLSelectorProps) {\n // Track whether custom mode is active\n const [isCustom, setIsCustom] = useState(!isPresetValue(value) && value !== null);\n const [customValue, setCustomValue] = useState(value?.toString() || '');\n const [validationError, setValidationError] = useState<string | null>(null);\n const prevValueRef = useRef(value);\n\n // Sync custom value when external value changes (using deferred update to avoid cascading renders)\n useEffect(() => {\n if (prevValueRef.current !== value) {\n prevValueRef.current = value;\n if (value !== null && !isPresetValue(value)) {\n // Defer state update to avoid synchronous setState in effect\n queueMicrotask(() => {\n setCustomValue(value.toString());\n setIsCustom(true);\n });\n }\n }\n }, [value]);\n\n // Handle preset selection\n const handlePresetChange = useCallback(\n (presetValue: number) => {\n if (disabled) return;\n setIsCustom(false);\n onChange(presetValue);\n },\n [disabled, onChange]\n );\n\n // Handle custom mode activation\n const handleCustomSelect = useCallback(() => {\n if (disabled) return;\n setIsCustom(true);\n const parsed = parseInt(customValue);\n if (!isNaN(parsed) && parsed >= 30 && parsed <= 86400) {\n onChange(parsed);\n }\n }, [disabled, customValue, onChange]);\n\n // Handle custom value change with validation\n const handleCustomChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = e.target.value;\n setCustomValue(inputValue);\n\n // Validate input\n if (inputValue === '') {\n setValidationError(null);\n return;\n }\n\n const parsed = parseInt(inputValue);\n\n if (isNaN(parsed)) {\n setValidationError('Please enter a valid number');\n return;\n }\n\n if (parsed < 30) {\n setValidationError('Minimum cache duration is 30 seconds');\n return;\n }\n\n if (parsed > 86400) {\n setValidationError('Maximum cache duration is 86400 seconds (24 hours)');\n return;\n }\n\n // Valid value\n setValidationError(null);\n onChange(parsed);\n },\n [onChange]\n );\n\n return (\n <div className=\"space-y-3\">\n {/* Label (optional — hidden when the surrounding form supplies its own) */}\n {!hideLabel && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Cache Duration</label>\n <p className=\"text-xs text-text-secondary\">How long should data be cached before refreshing?</p>\n </div>\n )}\n\n {/* Options */}\n <div className=\"space-y-2\">\n {/* Preset options */}\n {PRESET_OPTIONS.map((option) => (\n <label\n key={option.value}\n className={`\n flex items-start gap-3\n p-3\n border rounded-lg\n cursor-pointer\n transition-all\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${\n !isCustom && value === option.value\n ? 'border-action-primary-bg bg-action-primary-bg/5'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <input\n type=\"radio\"\n name=\"cache-ttl\"\n checked={!isCustom && value === option.value}\n onChange={() => handlePresetChange(option.value)}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-text-primary\">{option.label}</span>\n {option.recommended && (\n <span className=\"px-1.5 py-0.5 text-xs font-medium bg-action-primary-bg/10 text-action-primary-bg rounded\">\n Recommended\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary mt-0.5\">{option.description}</p>\n </div>\n </label>\n ))}\n\n {/* Custom option */}\n <label\n className={`\n flex items-start gap-3\n p-3\n border rounded-lg\n cursor-pointer\n transition-all\n ${disabled ? 'opacity-50 cursor-not-allowed' : ''}\n ${\n isCustom\n ? 'border-action-primary-bg bg-action-primary-bg/5'\n : 'border-border-default hover:border-border-hover'\n }\n `}\n >\n <input\n type=\"radio\"\n name=\"cache-ttl\"\n checked={isCustom}\n onChange={handleCustomSelect}\n disabled={disabled}\n className={`\n mt-0.5\n w-4 h-4\n text-action-primary-bg\n border-border-default\n focus:ring-action-primary-bg\n focus:ring-offset-0\n `}\n />\n <div className=\"flex-1\">\n <span className=\"text-sm font-medium text-text-primary\">Custom</span>\n <p className=\"text-xs text-text-secondary mt-0.5\">Enter a custom cache duration (30 - 86400 seconds)</p>\n {isCustom && (\n <>\n <div className=\"mt-3 flex items-center gap-2\">\n <input\n type=\"number\"\n value={customValue}\n onChange={handleCustomChange}\n disabled={disabled}\n min={30}\n max={86400}\n placeholder=\"300\"\n className={`\n w-32 px-3 py-2\n bg-bg-sunken\n border rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n ${error || validationError ? 'border-status-error-border' : 'border-border-default'}\n `}\n />\n <span className=\"text-sm text-text-secondary\">seconds</span>\n {customValue && !isNaN(parseInt(customValue)) && !validationError && (\n <span className=\"text-xs text-text-tertiary\">({formatDuration(parseInt(customValue))})</span>\n )}\n </div>\n {validationError && (\n <div className=\"flex items-center gap-1 mt-1\">\n <svg\n className=\"w-3.5 h-3.5 text-status-error-text flex-shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span className=\"text-xs text-status-error-text\">{validationError}</span>\n </div>\n )}\n </>\n )}\n </div>\n </label>\n </div>\n\n {/* Error message */}\n {error && (\n <div className=\"flex items-start gap-2\">\n <svg\n className=\"w-4 h-4 text-status-error-text flex-shrink-0 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <p className=\"text-xs text-status-error-text\">{error}</p>\n </div>\n )}\n\n {/* Info message */}\n {value !== null && !error && (\n <div className=\"flex items-center gap-2 text-xs text-text-secondary\">\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span>Data will be cached for {formatDuration(value)} before being refreshed</span>\n </div>\n )}\n </div>\n );\n});\n\nexport default CacheTTLSelector;\n"],"mappings":"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"}
@@ -115,7 +115,10 @@ function p(p = {}) {
115
115
  success: t.success,
116
116
  output: t.output,
117
117
  error: t.error,
118
- executionTimeMs: t.executionTimeMs
118
+ executionTimeMs: t.executionTimeMs,
119
+ sampled: t.sampled,
120
+ sampledRows: t.sampledRows,
121
+ totalRows: t.totalRows
119
122
  } : null;
120
123
  } catch (e) {
121
124
  return y(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to test expression")), null;
@@ -1 +1 @@
1
- {"version":3,"file":"useParserOperations.js","names":[],"sources":["../../../src/bigconsole/hooks/useParserOperations.ts"],"sourcesContent":["/**\n * Parser Operations Hook\n *\n * Custom hook for Parser CRUD operations with Apollo Client.\n * Integrates with the Parser Zustand store for state management.\n */\n\nimport { useState, useMemo, useCallback, useEffect } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { useParserStore } from '../store/parserStore';\nimport {\n ListParsersDocument,\n GetParserDocument,\n CreateParserDocument,\n UpdateParserDocument,\n DeleteParserDocument,\n ExecuteParserDocument,\n TestParserExpressionDocument,\n} from '../../generated/wspace-operations';\nimport type { Parser, ParserType, ParserStatus } from '../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface UseParserOperationsOptions {\n consoleId?: string;\n skipFetch?: boolean;\n}\n\ninterface ParserFilters {\n type?: ParserType;\n status?: ParserStatus;\n}\n\ninterface CreateParserInput {\n consoleId: string;\n name: string;\n type: ParserType;\n expression: string;\n inputSinkKey: string;\n outputKey: string;\n description?: string;\n ttl?: number;\n}\n\ninterface UpdateParserInput {\n name?: string;\n description?: string;\n type?: ParserType;\n expression?: string;\n inputSinkKey?: string;\n outputKey?: string;\n // Allow explicit null so callers can distinguish \"clear caching\"\n // (send null) from \"don't touch\" (omit the field / undefined).\n ttl?: number | null;\n status?: ParserStatus;\n}\n\ninterface TestParserInput {\n type: ParserType;\n expression: string;\n sampleData: unknown; // Parsed JSON object\n}\n\ninterface TestParserResult {\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n}\n\ninterface ExecuteParserResult {\n parserId: string;\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n cachedAt: string | null;\n}\n\n// GraphQL Query/Mutation Result Types\ninterface ListParsersResult {\n listParsers?: {\n edges: Array<{ node: Parser }>;\n pageInfo?: { hasNextPage: boolean; endCursor?: string };\n };\n}\n\ninterface GetParserResult {\n parser?: Parser;\n}\n\ninterface CreateParserResult {\n createParser?: Parser;\n}\n\ninterface UpdateParserResult {\n updateParser?: Parser;\n}\n\ninterface DeleteParserResult {\n deleteParser?: boolean;\n}\n\ninterface ExecuteParserMutationResult {\n executeParser?: {\n parserId: string;\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n cachedAt: string | null;\n };\n}\n\ninterface TestParserExpressionResult {\n testParserExpression?: {\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n };\n}\n\n// ============================================================================\n// HOOK\n// ============================================================================\n\nexport function useParserOperations(options: UseParserOperationsOptions = {}) {\n const { consoleId, skipFetch = false } = options;\n\n // Local state\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Apollo client\n const client = useApolloClient();\n\n // Store selectors and actions\n const parsersMap = useParserStore((state) => state.parsers);\n const setParsers = useParserStore((state) => state.setParsers);\n const addParser = useParserStore((state) => state.addParser);\n const updateParserInStore = useParserStore((state) => state.updateParser);\n const removeParser = useParserStore((state) => state.removeParser);\n const setParserTesting = useParserStore((state) => state.setParserTesting);\n\n // Memoized array of parsers\n const parsers = useMemo(() => Array.from(parsersMap.values()), [parsersMap]);\n\n // ============================================================================\n // OPERATIONS\n // ============================================================================\n\n /**\n * Fetch all parsers with optional filters\n */\n const fetchParsers = useCallback(\n async (filters?: ParserFilters): Promise<Parser[]> => {\n if (!consoleId) {\n return [];\n }\n\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.query<ListParsersResult>({\n query: ListParsersDocument,\n variables: {\n consoleId,\n type: filters?.type,\n status: filters?.status,\n first: 100,\n },\n fetchPolicy: 'network-only',\n });\n\n const edges = result.data?.listParsers?.edges || [];\n const normalized = edges.map((edge: { node: Parser }) => edge.node);\n\n setParsers(normalized);\n return normalized;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to fetch parsers');\n setError(error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [client, consoleId, setParsers]\n );\n\n /**\n * Fetch a single parser by ID\n */\n const fetchParser = useCallback(\n async (id: string): Promise<Parser | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.query<GetParserResult>({\n query: GetParserDocument,\n variables: { id },\n fetchPolicy: 'network-only',\n });\n\n const parser = result.data?.parser;\n if (parser) {\n addParser(parser);\n return parser;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to fetch parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client, addParser]\n );\n\n /**\n * Create a new parser\n */\n const createParser = useCallback(\n async (input: CreateParserInput): Promise<Parser | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.mutate<CreateParserResult>({\n mutation: CreateParserDocument,\n variables: { input },\n });\n\n const parser = result.data?.createParser;\n if (parser) {\n addParser(parser);\n return parser;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to create parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client, addParser]\n );\n\n /**\n * Update an existing parser\n */\n const updateParser = useCallback(\n async (id: string, input: UpdateParserInput, version: number): Promise<Parser | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.mutate<UpdateParserResult>({\n mutation: UpdateParserDocument,\n variables: { id, input, version },\n });\n\n const parser = result.data?.updateParser;\n if (parser) {\n updateParserInStore(id, parser);\n return parser;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client, updateParserInStore]\n );\n\n /**\n * Delete a parser\n */\n const deleteParser = useCallback(\n async (id: string): Promise<boolean> => {\n try {\n setLoading(true);\n setError(null);\n\n await client.mutate<DeleteParserResult>({\n mutation: DeleteParserDocument,\n variables: { id },\n });\n\n removeParser(id);\n return true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to delete parser');\n setError(error);\n return false;\n } finally {\n setLoading(false);\n }\n },\n [client, removeParser]\n );\n\n /**\n * Execute a parser against its input data sink\n */\n const executeParser = useCallback(\n async (id: string): Promise<ExecuteParserResult | null> => {\n try {\n setLoading(true);\n setError(null);\n setParserTesting(id, true);\n\n const result = await client.mutate<ExecuteParserMutationResult>({\n mutation: ExecuteParserDocument,\n variables: { id },\n });\n\n const execution = result.data?.executeParser;\n if (execution) {\n return {\n parserId: execution.parserId,\n success: execution.success,\n output: execution.output,\n error: execution.error,\n executionTimeMs: execution.executionTimeMs,\n cachedAt: execution.cachedAt,\n };\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to execute parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n setParserTesting(id, false);\n }\n },\n [client, setParserTesting]\n );\n\n /**\n * Test a parser expression with sample input\n */\n const testParserExpression = useCallback(\n async (input: TestParserInput): Promise<TestParserResult | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.query<TestParserExpressionResult>({\n query: TestParserExpressionDocument,\n variables: { input },\n fetchPolicy: 'network-only',\n });\n\n const testResult = result.data?.testParserExpression;\n if (testResult) {\n return {\n success: testResult.success,\n output: testResult.output,\n error: testResult.error,\n executionTimeMs: testResult.executionTimeMs,\n };\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to test expression');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n /**\n * Refetch all parsers\n */\n const refetch = useCallback(async () => {\n await fetchParsers();\n }, [fetchParsers]);\n\n // Auto-fetch on mount if not skipped\n useEffect(() => {\n if (consoleId && !skipFetch) {\n fetchParsers();\n }\n }, [consoleId, skipFetch, fetchParsers]);\n\n return {\n loading,\n error,\n parsers,\n fetchParsers,\n fetchParser,\n createParser,\n updateParser,\n deleteParser,\n executeParser,\n testParserExpression,\n refetch,\n };\n}\n\nexport default useParserOperations;\n"],"mappings":"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"}
1
+ {"version":3,"file":"useParserOperations.js","names":[],"sources":["../../../src/bigconsole/hooks/useParserOperations.ts"],"sourcesContent":["/**\n * Parser Operations Hook\n *\n * Custom hook for Parser CRUD operations with Apollo Client.\n * Integrates with the Parser Zustand store for state management.\n */\n\nimport { useState, useMemo, useCallback, useEffect } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { useParserStore } from '../store/parserStore';\nimport {\n ListParsersDocument,\n GetParserDocument,\n CreateParserDocument,\n UpdateParserDocument,\n DeleteParserDocument,\n ExecuteParserDocument,\n TestParserExpressionDocument,\n} from '../../generated/wspace-operations';\nimport type { Parser, ParserType, ParserStatus } from '../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface UseParserOperationsOptions {\n consoleId?: string;\n skipFetch?: boolean;\n}\n\ninterface ParserFilters {\n type?: ParserType;\n status?: ParserStatus;\n}\n\ninterface CreateParserInput {\n consoleId: string;\n name: string;\n type: ParserType;\n expression: string;\n inputSinkKey: string;\n outputKey: string;\n description?: string;\n ttl?: number;\n}\n\ninterface UpdateParserInput {\n name?: string;\n description?: string;\n type?: ParserType;\n expression?: string;\n inputSinkKey?: string;\n outputKey?: string;\n // Allow explicit null so callers can distinguish \"clear caching\"\n // (send null) from \"don't touch\" (omit the field / undefined).\n ttl?: number | null;\n status?: ParserStatus;\n}\n\ninterface TestParserInput {\n type: ParserType;\n expression: string;\n // Provide EXACTLY ONE of an inline sampleData blob or a DataSink reference\n // (BOFF-5518). With a reference the backend loads the payload server-side, so\n // the client sends only the key — no data blob.\n sampleData?: unknown; // Parsed JSON object (sample mode)\n dataSinkId?: string;\n dataSinkKey?: string; // reference mode\n sampleLimit?: number; // cap rows evaluated server-side\n}\n\ninterface TestParserResult {\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n // Sampling metadata for a DataSink-reference test (null for inline sampleData).\n sampled?: boolean | null;\n sampledRows?: number | null;\n totalRows?: number | null;\n}\n\ninterface ExecuteParserResult {\n parserId: string;\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n cachedAt: string | null;\n}\n\n// GraphQL Query/Mutation Result Types\ninterface ListParsersResult {\n listParsers?: {\n edges: Array<{ node: Parser }>;\n pageInfo?: { hasNextPage: boolean; endCursor?: string };\n };\n}\n\ninterface GetParserResult {\n parser?: Parser;\n}\n\ninterface CreateParserResult {\n createParser?: Parser;\n}\n\ninterface UpdateParserResult {\n updateParser?: Parser;\n}\n\ninterface DeleteParserResult {\n deleteParser?: boolean;\n}\n\ninterface ExecuteParserMutationResult {\n executeParser?: {\n parserId: string;\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n cachedAt: string | null;\n };\n}\n\ninterface TestParserExpressionResult {\n testParserExpression?: {\n success: boolean;\n output: unknown;\n error: string | null;\n executionTimeMs: number;\n sampled?: boolean | null;\n sampledRows?: number | null;\n totalRows?: number | null;\n };\n}\n\n// ============================================================================\n// HOOK\n// ============================================================================\n\nexport function useParserOperations(options: UseParserOperationsOptions = {}) {\n const { consoleId, skipFetch = false } = options;\n\n // Local state\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Apollo client\n const client = useApolloClient();\n\n // Store selectors and actions\n const parsersMap = useParserStore((state) => state.parsers);\n const setParsers = useParserStore((state) => state.setParsers);\n const addParser = useParserStore((state) => state.addParser);\n const updateParserInStore = useParserStore((state) => state.updateParser);\n const removeParser = useParserStore((state) => state.removeParser);\n const setParserTesting = useParserStore((state) => state.setParserTesting);\n\n // Memoized array of parsers\n const parsers = useMemo(() => Array.from(parsersMap.values()), [parsersMap]);\n\n // ============================================================================\n // OPERATIONS\n // ============================================================================\n\n /**\n * Fetch all parsers with optional filters\n */\n const fetchParsers = useCallback(\n async (filters?: ParserFilters): Promise<Parser[]> => {\n if (!consoleId) {\n return [];\n }\n\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.query<ListParsersResult>({\n query: ListParsersDocument,\n variables: {\n consoleId,\n type: filters?.type,\n status: filters?.status,\n first: 100,\n },\n fetchPolicy: 'network-only',\n });\n\n const edges = result.data?.listParsers?.edges || [];\n const normalized = edges.map((edge: { node: Parser }) => edge.node);\n\n setParsers(normalized);\n return normalized;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to fetch parsers');\n setError(error);\n return [];\n } finally {\n setLoading(false);\n }\n },\n [client, consoleId, setParsers]\n );\n\n /**\n * Fetch a single parser by ID\n */\n const fetchParser = useCallback(\n async (id: string): Promise<Parser | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.query<GetParserResult>({\n query: GetParserDocument,\n variables: { id },\n fetchPolicy: 'network-only',\n });\n\n const parser = result.data?.parser;\n if (parser) {\n addParser(parser);\n return parser;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to fetch parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client, addParser]\n );\n\n /**\n * Create a new parser\n */\n const createParser = useCallback(\n async (input: CreateParserInput): Promise<Parser | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.mutate<CreateParserResult>({\n mutation: CreateParserDocument,\n variables: { input },\n });\n\n const parser = result.data?.createParser;\n if (parser) {\n addParser(parser);\n return parser;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to create parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client, addParser]\n );\n\n /**\n * Update an existing parser\n */\n const updateParser = useCallback(\n async (id: string, input: UpdateParserInput, version: number): Promise<Parser | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.mutate<UpdateParserResult>({\n mutation: UpdateParserDocument,\n variables: { id, input, version },\n });\n\n const parser = result.data?.updateParser;\n if (parser) {\n updateParserInStore(id, parser);\n return parser;\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client, updateParserInStore]\n );\n\n /**\n * Delete a parser\n */\n const deleteParser = useCallback(\n async (id: string): Promise<boolean> => {\n try {\n setLoading(true);\n setError(null);\n\n await client.mutate<DeleteParserResult>({\n mutation: DeleteParserDocument,\n variables: { id },\n });\n\n removeParser(id);\n return true;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to delete parser');\n setError(error);\n return false;\n } finally {\n setLoading(false);\n }\n },\n [client, removeParser]\n );\n\n /**\n * Execute a parser against its input data sink\n */\n const executeParser = useCallback(\n async (id: string): Promise<ExecuteParserResult | null> => {\n try {\n setLoading(true);\n setError(null);\n setParserTesting(id, true);\n\n const result = await client.mutate<ExecuteParserMutationResult>({\n mutation: ExecuteParserDocument,\n variables: { id },\n });\n\n const execution = result.data?.executeParser;\n if (execution) {\n return {\n parserId: execution.parserId,\n success: execution.success,\n output: execution.output,\n error: execution.error,\n executionTimeMs: execution.executionTimeMs,\n cachedAt: execution.cachedAt,\n };\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to execute parser');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n setParserTesting(id, false);\n }\n },\n [client, setParserTesting]\n );\n\n /**\n * Test a parser expression with sample input\n */\n const testParserExpression = useCallback(\n async (input: TestParserInput): Promise<TestParserResult | null> => {\n try {\n setLoading(true);\n setError(null);\n\n const result = await client.query<TestParserExpressionResult>({\n query: TestParserExpressionDocument,\n variables: { input },\n fetchPolicy: 'network-only',\n });\n\n const testResult = result.data?.testParserExpression;\n if (testResult) {\n return {\n success: testResult.success,\n output: testResult.output,\n error: testResult.error,\n executionTimeMs: testResult.executionTimeMs,\n sampled: testResult.sampled,\n sampledRows: testResult.sampledRows,\n totalRows: testResult.totalRows,\n };\n }\n\n return null;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to test expression');\n setError(error);\n return null;\n } finally {\n setLoading(false);\n }\n },\n [client]\n );\n\n /**\n * Refetch all parsers\n */\n const refetch = useCallback(async () => {\n await fetchParsers();\n }, [fetchParsers]);\n\n // Auto-fetch on mount if not skipped\n useEffect(() => {\n if (consoleId && !skipFetch) {\n fetchParsers();\n }\n }, [consoleId, skipFetch, fetchParsers]);\n\n return {\n loading,\n error,\n parsers,\n fetchParsers,\n fetchParser,\n createParser,\n updateParser,\n deleteParser,\n executeParser,\n testParserExpression,\n refetch,\n };\n}\n\nexport default useParserOperations;\n"],"mappings":"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"}