@@ -117,7 +117,12 @@ export function traceCellMessage(cell: NotebookCell, message: string | (() => st
117117
118118const cellOutputMappers = new Map <
119119 nbformat . OutputType ,
120- ( output : nbformat . IOutput , cellIndex ?: number , cellId ?: string ) => NotebookCellOutput
120+ (
121+ output : nbformat . IOutput ,
122+ cellIndex ?: number ,
123+ cellId ?: string ,
124+ cellMetadata ?: Record < string , unknown >
125+ ) => NotebookCellOutput
121126> ( ) ;
122127// eslint-disable-next-line @typescript-eslint/no-explicit-any
123128cellOutputMappers . set ( 'display_data' , translateDisplayDataOutput as any ) ;
@@ -132,7 +137,8 @@ cellOutputMappers.set('update_display_data', translateDisplayDataOutput as any);
132137export function cellOutputToVSCCellOutput (
133138 output : nbformat . IOutput ,
134139 cellIndex ?: number ,
135- cellId ?: string
140+ cellId ?: string ,
141+ cellMetadata ?: Record < string , unknown >
136142) : NotebookCellOutput {
137143 /**
138144 * Stream, `application/x.notebook.stream`
@@ -160,29 +166,39 @@ export function cellOutputToVSCCellOutput(
160166 const fn = cellOutputMappers . get ( output . output_type as nbformat . OutputType ) ;
161167 let result : NotebookCellOutput ;
162168 if ( fn ) {
163- result = fn ( output , cellIndex , cellId ) ;
169+ result = fn ( output , cellIndex , cellId , cellMetadata ) ;
164170 } else {
165171 logger . warn ( `Unable to translate cell from ${ output . output_type } to NotebookCellData for VS Code.` ) ;
166172 // eslint-disable-next-line @typescript-eslint/no-explicit-any
167- result = translateDisplayDataOutput ( output as any , cellIndex , cellId ) ;
173+ result = translateDisplayDataOutput ( output as any , cellIndex , cellId , cellMetadata ) ;
168174 }
169175 return result ;
170176}
171177
172- function getOutputMetadata ( output : nbformat . IOutput , cellIndex ?: number , cellId ?: string ) : CellOutputMetadata {
173- // Add on transient data if we have any. This should be removed by our save functions elsewhere.
178+ function getOutputMetadata (
179+ output : nbformat . IOutput ,
180+ cellIndex ?: number ,
181+ cellId ?: string ,
182+ cellMetadata ?: Record < string , unknown >
183+ ) : CellOutputMetadata {
184+ // Merge in order: cellId, cellMetadata, cellIndex, then output-specific metadata (output metadata wins conflicts)
174185 const metadata : CellOutputMetadata = {
175186 outputType : output . output_type
176187 } ;
177188
178- if ( cellIndex !== undefined ) {
179- metadata . cellIndex = cellIndex ;
180- }
181-
182189 if ( cellId ) {
183190 metadata . cellId = cellId ;
184191 }
185192
193+ // Merge cell metadata next (block-level metadata from Deepnote)
194+ if ( cellMetadata ) {
195+ Object . assign ( metadata , cellMetadata ) ;
196+ }
197+
198+ if ( cellIndex !== undefined ) {
199+ metadata . cellIndex = cellIndex ;
200+ }
201+
186202 if ( output . transient ) {
187203 // eslint-disable-next-line @typescript-eslint/no-explicit-any
188204 metadata . transient = output . transient as any ;
@@ -193,7 +209,10 @@ function getOutputMetadata(output: nbformat.IOutput, cellIndex?: number, cellId?
193209 case 'execute_result' :
194210 case 'update_display_data' : {
195211 metadata . executionCount = output . execution_count ;
196- metadata . metadata = output . metadata ? JSON . parse ( JSON . stringify ( output . metadata ) ) : { } ;
212+ // Output metadata is merged last so it overrides block metadata
213+ if ( output . metadata ) {
214+ Object . assign ( metadata , output . metadata ) ;
215+ }
197216 break ;
198217 }
199218 default :
@@ -218,7 +237,8 @@ export function getNotebookCellOutputMetadata(output: {
218237function translateDisplayDataOutput (
219238 output : nbformat . IDisplayData | nbformat . IDisplayUpdate | nbformat . IExecuteResult ,
220239 cellIndex ?: number ,
221- cellId ?: string
240+ cellId ?: string ,
241+ cellMetadata ?: Record < string , unknown >
222242) : NotebookCellOutput {
223243 // Metadata could be as follows:
224244 // We'll have metadata specific to each mime type as well as generic metadata.
@@ -237,7 +257,7 @@ function translateDisplayDataOutput(
237257 }
238258 }
239259 */
240- const metadata = getOutputMetadata ( output , cellIndex , cellId ) ;
260+ const metadata = getOutputMetadata ( output , cellIndex , cellId , cellMetadata ) ;
241261 // If we have SVG or PNG, then add special metadata to indicate whether to display `open plot`
242262 if ( 'image/svg+xml' in output . data || 'image/png' in output . data ) {
243263 metadata . __displayOpenPlotIcon = true ;
@@ -253,10 +273,15 @@ function translateDisplayDataOutput(
253273 return new NotebookCellOutput ( sortOutputItemsBasedOnDisplayOrder ( items ) , metadata ) ;
254274}
255275
256- function translateStreamOutput ( output : nbformat . IStream , cellIndex ?: number , cellId ?: string ) : NotebookCellOutput {
276+ function translateStreamOutput (
277+ output : nbformat . IStream ,
278+ cellIndex ?: number ,
279+ cellId ?: string ,
280+ cellMetadata ?: Record < string , unknown >
281+ ) : NotebookCellOutput {
257282 const value = concatMultilineString ( output . text ) ;
258283 const factoryFn = output . name === 'stderr' ? NotebookCellOutputItem . stderr : NotebookCellOutputItem . stdout ;
259- return new NotebookCellOutput ( [ factoryFn ( value ) ] , getOutputMetadata ( output , cellIndex , cellId ) ) ;
284+ return new NotebookCellOutput ( [ factoryFn ( value ) ] , getOutputMetadata ( output , cellIndex , cellId , cellMetadata ) ) ;
260285}
261286
262287// Output stream can only have stderr or stdout so just check the first output. Undefined if no outputs
@@ -568,7 +593,12 @@ export function translateCellDisplayOutput(output: NotebookCellOutput): JupyterO
568593 * As we're displaying the error in the statusbar, we don't want this dup error in output.
569594 * Hence remove this.
570595 */
571- function translateErrorOutput ( output ?: nbformat . IError , cellIndex ?: number , cellId ?: string ) : NotebookCellOutput {
596+ function translateErrorOutput (
597+ output ?: nbformat . IError ,
598+ cellIndex ?: number ,
599+ cellId ?: string ,
600+ cellMetadata ?: Record < string , unknown >
601+ ) : NotebookCellOutput {
572602 output = output || { output_type : 'error' , ename : '' , evalue : '' , traceback : [ ] } ;
573603 return new NotebookCellOutput (
574604 [
@@ -578,7 +608,7 @@ function translateErrorOutput(output?: nbformat.IError, cellIndex?: number, cell
578608 stack : ( output ?. traceback || [ ] ) . join ( '\n' )
579609 } )
580610 ] ,
581- { ...getOutputMetadata ( output , cellIndex , cellId ) , originalError : output }
611+ { ...getOutputMetadata ( output , cellIndex , cellId , cellMetadata ) , originalError : output }
582612 ) ;
583613}
584614
0 commit comments