@@ -26,39 +26,52 @@ export function define(cell) {
2626 cellsById . get ( id ) ?. variables . forEach ( ( v ) => v . delete ( ) ) ;
2727 cellsById . set ( id , { cell, variables} ) ;
2828 const root = document . querySelector ( `#cell-${ id } ` ) ;
29- let reset = null ;
30- const clear = ( ) => ( ( root . innerHTML = "" ) , root . classList . remove ( "observablehq--loading" ) , ( reset = null ) ) ;
31- const display = inline
32- ? ( v ) => {
33- reset ?. ( ) ;
34- if ( isNode ( v ) || typeof v === "string" || ! v ?. [ Symbol . iterator ] ) root . append ( v ) ;
35- else root . append ( ...v ) ;
36- return v ;
37- }
38- : ( v ) => {
39- reset ?. ( ) ;
40- root . append ( isNode ( v ) ? v : inspect ( v ) ) ;
41- return v ;
42- } ;
43- const v = main . variable (
44- {
45- _node : root , // for visibility promise
46- pending : ( ) => ( reset = clear ) ,
47- fulfilled : ( ) => reset ?. ( ) ,
48- rejected : ( error ) => ( reset ?. ( ) , console . error ( error ) , root . append ( inspectError ( error ) ) )
49- } ,
50- {
51- shadow : {
52- display : ( ) => display ,
53- view : ( ) => ( v ) => Generators . input ( display ( v ) )
29+ const rejected = ( error ) => ( clear ( root ) , console . error ( error ) , root . append ( inspectError ( error ) ) ) ;
30+ const v = main . variable ( { _node : root , rejected} , { shadow : { } } ) ; // _node for visibility promise
31+ if ( inputs . includes ( "display" ) || inputs . includes ( "view" ) ) {
32+ let displayVersion = - 1 ; // the variable._version of currently-displayed values
33+ const display = inline ? displayInline : displayBlock ;
34+ const vd = new v . constructor ( 2 , v . _module ) ;
35+ vd . define (
36+ inputs . filter ( ( i ) => i !== "display" && i !== "view" ) ,
37+ ( ) => {
38+ let version = v . _version ; // capture version on input change
39+ return ( value ) => {
40+ if ( version < displayVersion ) throw new Error ( "stale display" ) ;
41+ else if ( version > displayVersion ) clear ( root ) ;
42+ displayVersion = version ;
43+ display ( root , value ) ;
44+ return value ;
45+ } ;
5446 }
47+ ) ;
48+ v . _shadow . set ( "display" , vd ) ;
49+ if ( inputs . includes ( "view" ) ) {
50+ const vv = new v . constructor ( 2 , v . _module , null , { shadow : { } } ) ;
51+ vv . _shadow . set ( "display" , vd ) ;
52+ vv . define ( [ "display" ] , ( display ) => ( v ) => Generators . input ( display ( v ) ) ) ;
53+ v . _shadow . set ( "view" , vv ) ;
5554 }
56- ) ;
55+ }
5756 v . define ( outputs . length ? `cell ${ id } ` : null , inputs , body ) ;
5857 variables . push ( v ) ;
5958 for ( const o of outputs ) variables . push ( main . variable ( true ) . define ( o , [ `cell ${ id } ` ] , ( exports ) => exports [ o ] ) ) ;
6059}
6160
61+ function clear ( root ) {
62+ root . innerHTML = "" ;
63+ root . classList . remove ( "observablehq--loading" ) ;
64+ }
65+
66+ function displayInline ( root , value ) {
67+ if ( isNode ( value ) || typeof value === "string" || ! value ?. [ Symbol . iterator ] ) root . append ( value ) ;
68+ else root . append ( ...value ) ;
69+ }
70+
71+ function displayBlock ( root , value ) {
72+ root . append ( isNode ( value ) ? value : inspect ( value ) ) ;
73+ }
74+
6275export function undefine ( id ) {
6376 cellsById . get ( id ) ?. variables . forEach ( ( v ) => v . delete ( ) ) ;
6477 cellsById . delete ( id ) ;
0 commit comments