@webqit/oohtml 4.3.8 → 4.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "wicg-proposal"
15
15
  ],
16
16
  "homepage": "https://webqit.io/tooling/oohtml",
17
- "version": "4.3.8",
17
+ "version": "4.3.10",
18
18
  "license": "MIT",
19
19
  "repository": {
20
20
  "type": "git",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@webqit/quantum-js": "^4.5.26",
43
- "@webqit/realdom": "^2.1.32",
43
+ "@webqit/realdom": "^2.1.33",
44
44
  "@webqit/util": "^0.8.11"
45
45
  },
46
46
  "devDependencies": {
@@ -22,9 +22,9 @@ export default class HTMLImportsContext extends DOMContext {
22
22
  request.detail = detail;
23
23
  request.targetContext = Infinity;
24
24
  } else if ( detail?.startsWith( '@' ) ) {
25
- const [ targetContext, ...detail ] = detail.slice( 1 ).split( /(?<=\w)(?=\/|#)/ ).map( s => s.trim() );
25
+ const [ targetContext, ..._detail ] = detail.slice( 1 ).split( /(?<=\w)(?=\/|#)/ ).map( s => s.trim() );
26
26
  request.targetContext = targetContext;
27
- request.detail = detail.join( '' );
27
+ request.detail = _detail.join( '' );
28
28
  } else { request.detail = detail; }
29
29
  return request;
30
30
  }
@@ -33,38 +33,31 @@ export default class HTMLImportsContext extends DOMContext {
33
33
  * @localModules
34
34
  */
35
35
  get localModules() { return getDefs( this.host ); }
36
+ get inheritedModules() { return this.#inheritedModules; }
37
+ #inheritedModules = {};
36
38
 
37
39
  /**
38
40
  * @handle()
39
41
  */
42
+
40
43
  handle( event ) {
41
44
  const { window: { webqit: { Observer } } } = env;
42
45
  // Any existing event.meta.controller? Abort!
43
46
  event.meta.controller?.abort();
44
-
45
47
  // Parse and translate detail
46
- if ( ( event.detail || '' ).trim() === '/' ) return event.respondWith( this.localModules );
47
48
  let path = ( event.detail || '' ).split( /\/|(?<=\w)(?=#)/g ).map( x => x.trim() ).filter( x => x );
48
49
  if ( !path.length ) return event.respondWith();
49
- path = path.join( `/${ this.configs.HTML_IMPORTS.api.defs }/` )?.split( '/' ) || [];
50
-
50
+ path = path.join( `/${ this.configs.HTML_IMPORTS.api.defs }/` )?.split( '/' ).map( x => x === '*' ? Infinity : x ) || [];
51
51
  // We'll now fulfill request
52
52
  const options = { live: event.live, signal: event.signal, descripted: true };
53
- // Find a way to resolve request against two sources
54
- event.meta.controller = Observer.reduce( this.localModules, path, Observer.get, ( result, { signal } = {} ) => {
55
- const _result = Array.isArray( result ) ? result : result.value;
56
- const _isValidLocalResult = Array.isArray( result ) ? result.length : result.value;
57
- if ( !_isValidLocalResult && this.host.isConnected === false ) return; // Subtree is being disposed
58
- if ( _isValidLocalResult || !this.contextModules ) {
59
- event._isValidLocalResult = _isValidLocalResult;
60
- return event.respondWith( _result );
61
- }
62
- // This superModules binding is automatically aborted by the injected control.signal; see below
63
- return Observer.reduce( this.contextModules, path, Observer.get, result => {
64
- event._currentSource = 'context';
65
- return event.respondWith( Array.isArray( result ) ? result : result.value );
66
- }, { ...options, signal } );
67
- }, { lifecycleSignals: true, ...options } );
53
+ event.meta.controller = Observer.reduce( this.#modules, path, Observer.get, ( m ) => {
54
+ if ( Array.isArray( m ) ) {
55
+ // Paths with wildcard
56
+ for ( const n of m ) {
57
+ event.respondWith( n );
58
+ }
59
+ } else event.respondWith( m.value );
60
+ }, options );
68
61
  }
69
62
 
70
63
  /**
@@ -73,49 +66,56 @@ export default class HTMLImportsContext extends DOMContext {
73
66
  unsubscribed( event ) { event.meta.controller?.abort(); }
74
67
 
75
68
  /**
76
- * @startRealtime()
69
+ * @initialize()
77
70
  */
78
- realtimeSources( host ) {
71
+ #modules;
72
+ #controller1;
73
+ #controller2;
74
+ initialize( host ) {
79
75
  this.host = host;
76
+ const { window: { webqit: { Observer } } } = env;
80
77
  // ----------------
81
- const update = () => {
82
- for ( const subscriptionEvent of this.subscriptions ) {
83
- if ( subscriptionEvent._isValidLocalResult ) continue;
84
- this.handle( subscriptionEvent );
78
+ // Observe local
79
+ this.#modules = { ...this.localModules };
80
+ this.#controller1?.abort();
81
+ this.#controller1 = Observer.observe( this.localModules, ( mutations ) => {
82
+ for ( const m of mutations ) {
83
+ if ( m.type === 'delete' ) {
84
+ if ( this.inheritedModules && Observer.has( this.inheritedModules, m.key ) ) {
85
+ Observer.set( this.#modules, m.key, Observer.get( this.inheritedModules, m.key ) );
86
+ } else Observer.deleteProperty( this.#modules, m.key );
87
+ } else Observer.set( this.#modules, m.key, m.value );
85
88
  }
86
- };
89
+ }, { timing: 'sync' } );
87
90
  // ----------------
88
- const $config = this.configs.HTML_IMPORTS;
89
- if ( !this.host.matches || !$config.attr.importscontext ) return;
90
- // Any existing this.refdSourceController? Abort!
91
- this.refdSourceController?.disconnect();
92
- const realdom = this.host.ownerDocument.defaultView.webqit.realdom;
93
- let prevRef;
94
- this.refdSourceController = realdom.realtime( this.host ).attr( $config.attr.importscontext, ( record, { signal } ) => {
95
- if (record.value === prevRef) return;
96
- prevRef = record.value;
97
- // No importscontext attr set. But we're still watching
98
- if ( !record.value ) {
99
- this.contextModules = undefined;
100
- return update();
101
- }
102
- // This superModules contextrequest is automatically aborted by the injected signal below
103
- const request = { ...this.constructor.createRequest( record.value.trim() ), live: true, signal, diff: true };
104
- this.host.parentNode[ this.configs.CONTEXT_API.api.contexts ].request( request, response => {
105
- this.contextModules = !( response && Object.getPrototypeOf( response ) ) ? response : getDefs( response );
106
- update();
107
- } );
108
- }, { live: true, timing: 'sync', lifecycleSignals: true } );
109
- }
110
-
111
- /**
112
- * @initialize()
113
- */
114
- initialize( host ) {
115
91
  // If host has importscontext attr, compute that
116
- this.realtimeSources( host );
117
- // Now, listen for contextrequest and contextclaim events
118
- // And process own claim
92
+ const $config = this.configs.HTML_IMPORTS;
93
+ if ( this.host.matches && $config.attr.importscontext ) {
94
+ const realdom = this.host.ownerDocument.defaultView.webqit.realdom;
95
+ let prevRef;
96
+ this.#controller2?.disconnect();
97
+ this.#controller2 = realdom.realtime( this.host ).attr( $config.attr.importscontext, ( record, { signal } ) => {
98
+ const moduleRef = ( record.value || '' ).trim();
99
+ if ( moduleRef === prevRef ) return;
100
+ prevRef = moduleRef;
101
+ // This superModules contextrequest is automatically aborted by the injected signal below
102
+ const request = { ...this.constructor.createRequest( moduleRef ? `${moduleRef}/*` : '*' ), live: true, signal, diff: true };
103
+ this.host.parentNode[ this.configs.CONTEXT_API.api.contexts ].request( request, ( m ) => {
104
+ if ( m.type === 'delete' ) {
105
+ Reflect.deleteProperty( this.inheritedModules, m.key );
106
+ if ( !Observer.has( this.localModules, m.key ) ) {
107
+ Observer.deleteProperty( this.#modules, m.key );
108
+ }
109
+ } else {
110
+ Reflect.set( this.inheritedModules, m.key, m.value );
111
+ if ( !Observer.has( this.localModules, m.key ) ) {
112
+ Observer.set( this.#modules, m.key, m.value );
113
+ }
114
+ }
115
+ } );
116
+ }, { live: true, timing: 'sync', oldValue: true, lifecycleSignals: true } );
117
+ }
118
+ // ----------------
119
119
  return super.initialize( host );
120
120
  }
121
121
 
@@ -124,7 +124,8 @@ export default class HTMLImportsContext extends DOMContext {
124
124
  */
125
125
  dispose( host ) {
126
126
  // Stop listening for sources
127
- this.refdSourceController?.disconnect();
127
+ this.#controller1?.abort();
128
+ this.#controller2?.disconnect();
128
129
  // Now, stop listening for contextrequest and contextclaim events
129
130
  // And relinquish own subscribers to owner context
130
131
  return super.dispose( host );
@@ -186,6 +186,7 @@ describe(`HTML Modules`, function() {
186
186
  // -------
187
187
  scoped.remove();
188
188
  expect( defsObjs ).to.have.length( 3 );
189
+
189
190
  expect( defsObjs[ 2 ] ).to.have.property( 'scoped', false );
190
191
  // -------
191
192
  document.body.appendChild( scoped );