@@ -26,39 +26,52 @@ export function define(cell) {
26
26
cellsById . get ( id ) ?. variables . forEach ( ( v ) => v . delete ( ) ) ;
27
27
cellsById . set ( id , { cell, variables} ) ;
28
28
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
+ } ;
54
46
}
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 ) ;
55
54
}
56
- ) ;
55
+ }
57
56
v . define ( outputs . length ? `cell ${ id } ` : null , inputs , body ) ;
58
57
variables . push ( v ) ;
59
58
for ( const o of outputs ) variables . push ( main . variable ( true ) . define ( o , [ `cell ${ id } ` ] , ( exports ) => exports [ o ] ) ) ;
60
59
}
61
60
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
+
62
75
export function undefine ( id ) {
63
76
cellsById . get ( id ) ?. variables . forEach ( ( v ) => v . delete ( ) ) ;
64
77
cellsById . delete ( id ) ;
0 commit comments