@bian-womp/spark-workbench 0.1.16 → 0.1.17
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/lib/cjs/index.cjs +139 -11
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/index.d.ts +1 -0
- package/lib/cjs/src/index.d.ts.map +1 -1
- package/lib/cjs/src/misc/DebugEvents.d.ts.map +1 -1
- package/lib/cjs/src/misc/DefaultNode.d.ts.map +1 -1
- package/lib/cjs/src/misc/Inspector.d.ts.map +1 -1
- package/lib/cjs/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/cjs/src/misc/mapping.d.ts +1 -0
- package/lib/cjs/src/misc/mapping.d.ts.map +1 -1
- package/lib/cjs/src/misc/value.d.ts +3 -0
- package/lib/cjs/src/misc/value.d.ts.map +1 -1
- package/lib/esm/index.js +136 -12
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/index.d.ts +1 -0
- package/lib/esm/src/index.d.ts.map +1 -1
- package/lib/esm/src/misc/DebugEvents.d.ts.map +1 -1
- package/lib/esm/src/misc/DefaultNode.d.ts.map +1 -1
- package/lib/esm/src/misc/Inspector.d.ts.map +1 -1
- package/lib/esm/src/misc/WorkbenchStudio.d.ts.map +1 -1
- package/lib/esm/src/misc/mapping.d.ts +1 -0
- package/lib/esm/src/misc/mapping.d.ts.map +1 -1
- package/lib/esm/src/misc/value.d.ts +3 -0
- package/lib/esm/src/misc/value.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -827,6 +827,90 @@ function formatDeclaredTypeSignature(declared) {
|
|
|
827
827
|
return declared.join(" | ");
|
|
828
828
|
return declared ?? "";
|
|
829
829
|
}
|
|
830
|
+
// Pre-format common structures for display; return undefined to defer to caller
|
|
831
|
+
function preformatValueForDisplay(typeId, value, registry) {
|
|
832
|
+
if (value === undefined || value === null)
|
|
833
|
+
return "";
|
|
834
|
+
// Unwrap typed outputs
|
|
835
|
+
if (sparkGraph.isTypedOutput(value)) {
|
|
836
|
+
return preformatValueForDisplay(String(value.__spark_type), value.__spark_value, registry);
|
|
837
|
+
}
|
|
838
|
+
// Enums
|
|
839
|
+
if (typeId && typeId.includes("enum:") && registry) {
|
|
840
|
+
const n = Number(value);
|
|
841
|
+
const label = registry.enums.get(typeId)?.valueToLabel.get(n);
|
|
842
|
+
if (label)
|
|
843
|
+
return label;
|
|
844
|
+
}
|
|
845
|
+
// Use deep summarization for strings, arrays and nested objects to avoid huge HTML payloads
|
|
846
|
+
const summarized = summarizeDeep(value);
|
|
847
|
+
if (typeof summarized === "string")
|
|
848
|
+
return summarized;
|
|
849
|
+
// Resource-like objects with url/title (after summarization)
|
|
850
|
+
if (summarized && typeof summarized === "object") {
|
|
851
|
+
const urlMaybe = summarized.url;
|
|
852
|
+
if (typeof urlMaybe === "string") {
|
|
853
|
+
const title = summarized.title || "";
|
|
854
|
+
const shortUrl = urlMaybe.length > 32 ? urlMaybe.slice(0, 32) + "…" : urlMaybe;
|
|
855
|
+
return title ? `${title} (${shortUrl})` : shortUrl;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return undefined;
|
|
859
|
+
}
|
|
860
|
+
function summarizeDeep(value, registry) {
|
|
861
|
+
// Strings: summarize data URLs and trim extremely long strings
|
|
862
|
+
if (typeof value === "string") {
|
|
863
|
+
if (value.startsWith("data:")) {
|
|
864
|
+
try {
|
|
865
|
+
const semi = value.indexOf(";");
|
|
866
|
+
const comma = value.indexOf(",");
|
|
867
|
+
const mime = value.slice(5, semi > 0 ? semi : undefined).toUpperCase();
|
|
868
|
+
const b64 = comma >= 0 ? value.slice(comma + 1) : "";
|
|
869
|
+
const bytes = Math.floor((b64.length * 3) / 4);
|
|
870
|
+
return `${mime} Data (${bytes} bytes)`;
|
|
871
|
+
}
|
|
872
|
+
catch {
|
|
873
|
+
return value.length > 64 ? value.slice(0, 64) + "…" : value;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return value.length > 512 ? value.slice(0, 512) + "…" : value;
|
|
877
|
+
}
|
|
878
|
+
// Typed output wrapper
|
|
879
|
+
if (sparkGraph.isTypedOutput(value)) {
|
|
880
|
+
return summarizeDeep(value.__spark_value);
|
|
881
|
+
}
|
|
882
|
+
// Arrays
|
|
883
|
+
if (Array.isArray(value)) {
|
|
884
|
+
return value.map((v) => summarizeDeep(v));
|
|
885
|
+
}
|
|
886
|
+
// Objects
|
|
887
|
+
if (value && typeof value === "object") {
|
|
888
|
+
const obj = value;
|
|
889
|
+
const out = {};
|
|
890
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
891
|
+
// Special-case any 'url' field
|
|
892
|
+
if (typeof v === "string" &&
|
|
893
|
+
k.toLowerCase() === "url" &&
|
|
894
|
+
v.startsWith("data:")) {
|
|
895
|
+
try {
|
|
896
|
+
const semi = v.indexOf(";");
|
|
897
|
+
const comma = v.indexOf(",");
|
|
898
|
+
const mime = v.slice(5, semi > 0 ? semi : undefined).toUpperCase();
|
|
899
|
+
const b64 = comma >= 0 ? v.slice(comma + 1) : "";
|
|
900
|
+
const bytes = Math.floor((b64.length * 3) / 4);
|
|
901
|
+
out[k] = `${mime} Data (${bytes} bytes)`;
|
|
902
|
+
continue;
|
|
903
|
+
}
|
|
904
|
+
catch {
|
|
905
|
+
// fallthrough
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
out[k] = summarizeDeep(v);
|
|
909
|
+
}
|
|
910
|
+
return out;
|
|
911
|
+
}
|
|
912
|
+
return value;
|
|
913
|
+
}
|
|
830
914
|
|
|
831
915
|
function toReactFlow(def, positions, registry, opts) {
|
|
832
916
|
const nodeHandleMap = {};
|
|
@@ -893,6 +977,7 @@ function toReactFlow(def, positions, registry, opts) {
|
|
|
893
977
|
: undefined,
|
|
894
978
|
animated: isRunning,
|
|
895
979
|
style,
|
|
980
|
+
label: e.typeId || undefined,
|
|
896
981
|
};
|
|
897
982
|
});
|
|
898
983
|
return { nodes, edges };
|
|
@@ -1025,8 +1110,8 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, children, }) {
|
|
|
1025
1110
|
layers.push(layer);
|
|
1026
1111
|
q.splice(0, q.length, ...next);
|
|
1027
1112
|
}
|
|
1028
|
-
const X =
|
|
1029
|
-
const Y =
|
|
1113
|
+
const X = 480;
|
|
1114
|
+
const Y = 240;
|
|
1030
1115
|
const pos = {};
|
|
1031
1116
|
layers.forEach((layer, layerIndex) => {
|
|
1032
1117
|
layer.forEach((id, itemIndex) => {
|
|
@@ -1396,7 +1481,8 @@ function DebugEvents({ autoScroll, onAutoScrollChange, hideWorkbench, onHideWork
|
|
|
1396
1481
|
}, [rows, autoScroll]);
|
|
1397
1482
|
const renderPayload = (v) => {
|
|
1398
1483
|
try {
|
|
1399
|
-
|
|
1484
|
+
const summarized = summarizeDeep(v);
|
|
1485
|
+
return JSON.stringify(summarized, null, 0);
|
|
1400
1486
|
}
|
|
1401
1487
|
catch {
|
|
1402
1488
|
return String(v);
|
|
@@ -1408,9 +1494,18 @@ function DebugEvents({ autoScroll, onAutoScrollChange, hideWorkbench, onHideWork
|
|
|
1408
1494
|
function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHideWorkbenchChange, toString, toElement, setInput, }) {
|
|
1409
1495
|
const safeToString = (typeId, value) => {
|
|
1410
1496
|
try {
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1497
|
+
if (typeof toString === "function") {
|
|
1498
|
+
// Special-case data URLs for readability
|
|
1499
|
+
if (typeof value === "string" && value.startsWith("data:image/")) {
|
|
1500
|
+
const comma = value.indexOf(",");
|
|
1501
|
+
const b64 = comma >= 0 ? value.slice(comma + 1) : "";
|
|
1502
|
+
const bytes = Math.floor((b64.length * 3) / 4);
|
|
1503
|
+
const fmt = value.slice(5, value.indexOf(";")) || "image";
|
|
1504
|
+
return `${fmt.toUpperCase()} Data (${bytes} bytes)`;
|
|
1505
|
+
}
|
|
1506
|
+
return toString(typeId, value);
|
|
1507
|
+
}
|
|
1508
|
+
return String(value ?? "");
|
|
1414
1509
|
}
|
|
1415
1510
|
catch {
|
|
1416
1511
|
return String(value ?? "");
|
|
@@ -1521,7 +1616,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
1521
1616
|
const title = inIssues
|
|
1522
1617
|
.map((v) => `${v.code}: ${v.message}`)
|
|
1523
1618
|
.join("; ");
|
|
1524
|
-
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsxRuntime.jsxs("label", { className: "w-
|
|
1619
|
+
return (jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [jsxRuntime.jsxs("label", { className: "w-32", children: [h, jsxRuntime.jsx("span", { className: "text-gray-500 ml-1 text-[11px]", children: selectedDesc?.inputs?.[h] })] }), hasValidation && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 24, className: "ml-1 w-6 h-6", title: title })), isEnum ? (jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500 w-full", value: current !== undefined && current !== null
|
|
1525
1620
|
? String(current)
|
|
1526
1621
|
: "", onChange: (e) => {
|
|
1527
1622
|
const val = e.target.value;
|
|
@@ -1607,10 +1702,8 @@ const DefaultNode = React.memo(function DefaultNode({ id, data, selected, isConn
|
|
|
1607
1702
|
const title = vIssues
|
|
1608
1703
|
.map((v) => `${v.code}: ${v.message}`)
|
|
1609
1704
|
.join("; ");
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
return toString(typeId, value);
|
|
1613
|
-
})() }))] })] }, `out-${entry.id}`));
|
|
1705
|
+
const resolved = resolveOutputDisplay(outputValues?.[entry.id], entry.typeId);
|
|
1706
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx(ReactFlow.Handle, { id: entry.id, type: "source", position: ReactFlow.Position.Right, isConnectable: isConnectable, className: cx("!w-3 !h-3 !bg-white !dark:bg-stone-900 !border-gray-500 dark:!border-gray-400 !rounded-none", hasAny && (hasErr ? "!border-red-500" : "!border-amber-500")), style: { right: -5, top: topFor(i) } }), jsxRuntime.jsxs("div", { className: "absolute right-2 text-[11px] text-gray-700 dark:text-gray-300 pointer-events-none", style: { top: topFor(i) - 8, textAlign: "right" }, title: `${entry.id}: ${entry.typeId}`, children: [entry.id, resolved.typeId && (jsxRuntime.jsxs("span", { className: "ml-1 opacity-60", children: ["(", resolved.typeId, ")"] })), hasAny && (jsxRuntime.jsx(IssueBadge, { level: hasErr ? "error" : "warning", size: 12, className: "ml-1", title: title })), showValues && (jsxRuntime.jsx("span", { className: "ml-1 opacity-60", children: toString(resolved.typeId, resolved.value) }))] })] }, `out-${entry.id}`));
|
|
1614
1707
|
})] }));
|
|
1615
1708
|
});
|
|
1616
1709
|
DefaultNode.displayName = "DefaultNode";
|
|
@@ -2106,6 +2199,37 @@ function WorkbenchStudioCanvas({ setRegistry, autoScroll, onAutoScrollChange, ex
|
|
|
2106
2199
|
const baseToString = React.useCallback((typeId, value) => {
|
|
2107
2200
|
if (value === undefined || value === null)
|
|
2108
2201
|
return "";
|
|
2202
|
+
// Normalize typed wrapper
|
|
2203
|
+
if (sparkGraph.isTypedOutput(value)) {
|
|
2204
|
+
return baseToString(String(value.__spark_type), value.__spark_value);
|
|
2205
|
+
}
|
|
2206
|
+
const pre = preformatValueForDisplay(typeId, value, registry);
|
|
2207
|
+
if (pre !== undefined)
|
|
2208
|
+
return pre;
|
|
2209
|
+
if (typeof value === "object" &&
|
|
2210
|
+
value !== null &&
|
|
2211
|
+
typeof value.url === "string") {
|
|
2212
|
+
const title = value.title || "";
|
|
2213
|
+
const url = String(value.url || "");
|
|
2214
|
+
if (url.startsWith("data:image/")) {
|
|
2215
|
+
try {
|
|
2216
|
+
const semi = url.indexOf(";");
|
|
2217
|
+
const comma = url.indexOf(",");
|
|
2218
|
+
const mime = url
|
|
2219
|
+
.slice(5, semi > 0 ? semi : undefined)
|
|
2220
|
+
.toUpperCase();
|
|
2221
|
+
const b64 = comma >= 0 ? url.slice(comma + 1) : "";
|
|
2222
|
+
const bytes = Math.floor((b64.length * 3) / 4);
|
|
2223
|
+
return title
|
|
2224
|
+
? `${title} (${mime} ${bytes} bytes)`
|
|
2225
|
+
: `${mime} Data (${bytes} bytes)`;
|
|
2226
|
+
}
|
|
2227
|
+
catch {
|
|
2228
|
+
return title || url.slice(0, 32) + (url.length > 32 ? "…" : "");
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
return title || url.slice(0, 32) + (url.length > 32 ? "…" : "");
|
|
2232
|
+
}
|
|
2109
2233
|
if (typeId && typeId.includes("enum:")) {
|
|
2110
2234
|
const n = Number(value);
|
|
2111
2235
|
const label = registry.enums.get(typeId)?.valueToLabel.get(n);
|
|
@@ -2203,7 +2327,11 @@ exports.WorkbenchCanvas = WorkbenchCanvas;
|
|
|
2203
2327
|
exports.WorkbenchContext = WorkbenchContext;
|
|
2204
2328
|
exports.WorkbenchProvider = WorkbenchProvider;
|
|
2205
2329
|
exports.WorkbenchStudio = WorkbenchStudio;
|
|
2330
|
+
exports.formatDeclaredTypeSignature = formatDeclaredTypeSignature;
|
|
2206
2331
|
exports.getNodeBorderClassNames = getNodeBorderClassNames;
|
|
2332
|
+
exports.preformatValueForDisplay = preformatValueForDisplay;
|
|
2333
|
+
exports.resolveOutputDisplay = resolveOutputDisplay;
|
|
2334
|
+
exports.summarizeDeep = summarizeDeep;
|
|
2207
2335
|
exports.toReactFlow = toReactFlow;
|
|
2208
2336
|
exports.useQueryParamBoolean = useQueryParamBoolean;
|
|
2209
2337
|
exports.useQueryParamString = useQueryParamString;
|