MCPcopy
hub / github.com/loggerhead/json4u / createArrayNode

Function createArrayNode

src/lib/table/createNode.ts:60–176  ·  view source on GitHub ↗

* Creates a `TableNode` for a JSON array. This is one of the most complex parts of the builder, * as it needs to handle arrays of primitives, arrays of objects, and mixed (heterogeneous) arrays. * It creates a columnar layout for arrays of objects. * @param ctx The current build context. * @para

(ctx: CreateContext, tree: Tree, node: Node)

Source from the content-addressed store, hash-verified

58 * @param node The JSON `Node` representing the array.
59 */
60function createArrayNode(ctx: CreateContext, tree: Tree, node: Node): TableNode {
61 // An array is considered heterogeneous if it contains both primitive values (leaf nodes) and objects/arrays (non-leaf nodes).
62 // The `existsLeafNode` flag is used to track whether at least one primitive value exists.
63 // e.g., `[1, {"a": 2}, 3]`
64 let existsLeafNode = false;
65 // Collect all unique keys from child objects to form the table headers.
66 const headers = union(
67 ...tree.childrenNodes(node).map((child) => {
68 existsLeafNode = existsLeafNode || !hasChildren(child);
69 return child.childrenKeys;
70 }),
71 );
72
73 const rows: TableNode[][] = [];
74
75 // If there are headers, it means we have an array of objects. Create a header row.
76 if (headers.length > 0) {
77 let firstRow = headers.map((key) =>
78 newNode(ctx, "header")
79 .setText(key || '""')
80 .addClass(key ? "text-hl-key" : "text-hl-empty")
81 .setId(node.id),
82 );
83
84 // For heterogeneous arrays, add dummy columns for the index and value of primitive elements.
85 if (existsLeafNode) {
86 const dummyIdxNode = newNode(ctx, "dummyIndex", node.id);
87 const dummyNode = newNode(ctx, "dummyHeader", node.id);
88 firstRow = [dummyIdxNode, dummyNode, ...firstRow];
89 }
90
91 rows.push(firstRow);
92 }
93
94 let deltaSpan = rows.length;
95
96 // Iterate over each child of the array to create the data rows.
97 tree.mapChildren(node, (child, idxAsKey) => {
98 const newCtx = { ...ctx, row: ctx.row + deltaSpan };
99 const rowNodes: TableNode[] = [];
100
101 if (existsLeafNode) {
102 // For heterogeneous arrays, create an index cell and a value cell for primitives.
103 const idxNode = newNode(newCtx, "index").setId(child.id).setText(idxAsKey);
104 const valNode = hasChildren(child) ? newNode(newCtx, "dummyValue") : createNode(newCtx, tree, child);
105 rowNodes.push(idxNode, valNode);
106 }
107
108 // Create cells for each header key.
109 for (let i = 0; i < headers.length; i++) {
110 const key = headers[i];
111 const colNode = hasChildren(child)
112 ? createNode(newCtx, tree, tree.getChild(child, key)!) // If child is object, get value for key.
113 : newNode(newCtx, "dummyValue"); // If child is primitive, add a placeholder.
114
115 rowNodes.push(colNode);
116 }
117

Callers

nothing calls this directly

Calls 15

hasChildrenFunction · 0.90
newNodeFunction · 0.85
createNodeFunction · 0.85
childrenNodesMethod · 0.80
setIdMethod · 0.80
addClassMethod · 0.80
setTextMethod · 0.80
mapChildrenMethod · 0.80
getChildMethod · 0.80
setBorderFlagMethod · 0.80
setUpMethod · 0.80
setParentMethod · 0.80

Tested by

no test coverage detected