( component: RegisteredComponent, output: unknown, )
| 147 | * This avoids sending huge payloads over Kafka. |
| 148 | */ |
| 149 | export function createLightweightSummary( |
| 150 | component: RegisteredComponent, |
| 151 | output: unknown, |
| 152 | ): Record<string, unknown> { |
| 153 | if (!output || typeof output !== 'object' || Array.isArray(output)) { |
| 154 | return { _value: output } as any; |
| 155 | } |
| 156 | |
| 157 | const obj = output as Record<string, unknown>; |
| 158 | const summary: Record<string, unknown> = {}; |
| 159 | let hasTruncatedContent = false; |
| 160 | |
| 161 | // Copy summary field if it exists |
| 162 | if (obj.summary) { |
| 163 | summary.summary = obj.summary; |
| 164 | } |
| 165 | |
| 166 | for (const [key, value] of Object.entries(obj)) { |
| 167 | // Skip internal fields |
| 168 | if (key.startsWith('__')) continue; |
| 169 | if (key === 'summary') continue; |
| 170 | |
| 171 | if (Array.isArray(value)) { |
| 172 | summary[`${key}Count`] = value.length; |
| 173 | hasTruncatedContent = true; |
| 174 | } else if (value !== null && typeof value === 'object') { |
| 175 | // Nested objects are summarized if they have a summary, otherwise just marked as truncated |
| 176 | if ((value as any).summary) { |
| 177 | summary[key] = { summary: (value as any).summary, _truncated: true }; |
| 178 | } |
| 179 | hasTruncatedContent = true; |
| 180 | } else { |
| 181 | // Primitives (string, number, boolean, null) |
| 182 | summary[key] = value; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | // If output was already a spilled marker, preserve its metadata |
| 187 | if (obj.__spilled__) { |
| 188 | summary.__spilled__ = true; |
| 189 | summary.storageRef = obj.storageRef; |
| 190 | summary.originalSize = obj.originalSize; |
| 191 | hasTruncatedContent = true; |
| 192 | } |
| 193 | |
| 194 | if (hasTruncatedContent) { |
| 195 | summary._truncated = true; |
| 196 | } |
| 197 | |
| 198 | return summary; |
| 199 | } |
no outgoing calls
no test coverage detected