@webqit/port-plus 0.1.19 → 0.1.21

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
  ],
15
15
  "homepage": "https://port-plus.netlify.app/",
16
16
  "icon": "https://webqit.io/icon.svg",
17
- "version": "0.1.19",
17
+ "version": "0.1.21",
18
18
  "license": "MIT",
19
19
  "repository": {
20
20
  "type": "git",
@@ -3,8 +3,20 @@ import { MessagePortPlus, applyMutations, _options } from './MessagePortPlus.js'
3
3
 
4
4
  export class MessageEventPlus extends MessageEvent {
5
5
 
6
- #originalTarget;
7
- get originalTarget() { return this.#originalTarget; }
6
+ static setCurrentTarget(event, currentTarget) {
7
+ event.#currentTarget = currentTarget;
8
+ if (!event.#target) {
9
+ event.#target = currentTarget;
10
+ }
11
+ }
12
+
13
+ // ----------
14
+
15
+ #currentTarget;
16
+ get currentTarget() { return this.#currentTarget; }
17
+
18
+ #target;
19
+ get target() { return this.#target; }
8
20
 
9
21
  #eventID;
10
22
  get eventID() { return this.#eventID; }
@@ -28,7 +40,7 @@ export class MessageEventPlus extends MessageEvent {
28
40
  get ports() { return this.#ports; }
29
41
 
30
42
  constructor(data, {
31
- originalTarget = null,
43
+ target = null,
32
44
  type = 'message',
33
45
  eventID,
34
46
  live = false,
@@ -42,7 +54,7 @@ export class MessageEventPlus extends MessageEvent {
42
54
  }
43
55
  super(type);
44
56
  this.#data = data;
45
- this.#originalTarget = originalTarget;
57
+ this.#target = target;
46
58
  this.#eventID = eventID;
47
59
  this.#live = live;
48
60
  this.#bubbles = bubbles;
@@ -56,7 +68,7 @@ export class MessageEventPlus extends MessageEvent {
56
68
  if (typeof eventID !== 'string') {
57
69
  throw new TypeError('eventID must be a non-empty string');
58
70
  }
59
- applyMutations.call(originalTarget, this.#data, this.#eventID, { honourDoneMutationFlags: this.#honourDoneMutationFlags });
71
+ applyMutations.call(target, this.#data, this.#eventID, { honourDoneMutationFlags: this.#honourDoneMutationFlags });
60
72
  }
61
73
  }
62
74
 
@@ -1,8 +1,8 @@
1
1
  import { _wq as $wq } from '@webqit/util/js/index.js';
2
2
  import { _isObject, _isTypeObject } from '@webqit/util/js/index.js';
3
3
  import { MessageEventPlus } from './MessageEventPlus.js';
4
- import { Observer } from '@webqit/observer';
5
4
  import { WebSocketPort } from './WebSocketPort.js';
5
+ import { Observer } from '@webqit/observer';
6
6
 
7
7
  export const _wq = (target, ...args) => $wq(target, 'port+', ...args);
8
8
  export const _meta = (target, ...args) => $wq(target, 'port+', 'meta', ...args);
@@ -211,7 +211,7 @@ export function MessagePortPlusMixin(superClass) {
211
211
  }
212
212
 
213
213
  const eventPlus = new MessageEventPlus(message, {
214
- originalTarget: port,
214
+ target: port,
215
215
  ...wqOptions,
216
216
  ports: e.ports,
217
217
  });
@@ -322,13 +322,19 @@ export function MessagePortPlusMixin(superClass) {
322
322
  }
323
323
 
324
324
  dispatchEvent(event) {
325
+ if (event instanceof MessageEventPlus) {
326
+ MessageEventPlus.setCurrentTarget(event, this);
327
+ }
328
+
325
329
  const returnValue = this._dispatchEvent
326
330
  ? this._dispatchEvent(event)
327
331
  : super.dispatchEvent(event);
332
+
328
333
  if (event instanceof MessageEventPlus) {
329
334
  // Bubble semantics
330
335
  propagateEvent.call(this, event);
331
336
  }
337
+
332
338
  return returnValue;
333
339
  }
334
340
 
@@ -681,13 +687,11 @@ export function propagateEvent(event) {
681
687
  if (event.propagationStopped) return;
682
688
  const portMeta = _meta(this);
683
689
 
684
- if (portMeta.get('parentNode') instanceof EventTarget && (
690
+ if (portMeta.get('parentPort') instanceof EventTarget && (
685
691
  event.bubbles
686
- || portMeta.get('parentNode')?.findPort?.((port) => port === this) && event instanceof MessageEventPlus)
692
+ || portMeta.get('parentPort')?.findPort?.((port) => port === this) && event instanceof MessageEventPlus)
687
693
  ) {
688
- portMeta.get('parentNode').dispatchEvent(event);
689
- // "parentNode" is typically a StarPort feature
690
- // in case "this" is a RelayPort
694
+ portMeta.get('parentPort').dispatchEvent(event);
691
695
  }
692
696
 
693
697
  const downstreamRegistry = getDownstreamRegistry.call(this);
package/src/StarPort.js CHANGED
@@ -7,6 +7,9 @@ import {
7
7
 
8
8
  export class StarPort extends MessagePortPlus {
9
9
 
10
+ #tags = new Map;
11
+ get tags() { return this.#tags; }
12
+
10
13
  #ports = new Set;
11
14
  #startCalled = false;
12
15
  #closeCalled = false;
@@ -20,6 +23,34 @@ export class StarPort extends MessagePortPlus {
20
23
  if (handshake === 0) this.start();
21
24
  }
22
25
 
26
+ #autoCloseX;
27
+ get autoCloseXPromise() { return this.#autoCloseX?.p; }
28
+
29
+ #autoCloseXPromises = new Set;
30
+ extendAutoClose(promise) {
31
+ const readyStateInternals = getReadyStateInternals.call(this);
32
+
33
+ if (readyStateInternals.close.state) {
34
+ throw new Error('Port lifecycle already complete.');
35
+ }
36
+
37
+ promise = Promise.resolve(promise);
38
+ this.#autoCloseXPromises.add(promise);
39
+ if (!this.#autoCloseX) {
40
+ let r;
41
+ const p = new Promise(res => (r = res));
42
+ this.#autoCloseX = { p, r };
43
+ }
44
+
45
+ return promise.finally(() => {
46
+ this.#autoCloseXPromises.delete(promise);
47
+ if (!this.#autoCloseXPromises.size) {
48
+ this.#autoCloseX.r();
49
+ this.#autoCloseX = null;
50
+ }
51
+ });
52
+ }
53
+
23
54
  addPort(portPlus, { enableBubbling = true } = {}) {
24
55
  if (!(portPlus instanceof MessagePortPlus)) {
25
56
  throw new TypeError('Port must be a WQMessagePort instance.');
@@ -38,10 +69,10 @@ export class StarPort extends MessagePortPlus {
38
69
  const portPlusMeta = _meta(portPlus);
39
70
 
40
71
  if (enableBubbling) {
41
- if (portPlusMeta.get('parentNode')) {
72
+ if (portPlusMeta.get('parentPort')) {
42
73
  throw new TypeError('Incoming port already has a parent node.');
43
74
  }
44
- portPlusMeta.set('parentNode', this); // @ORDER: 2
75
+ portPlusMeta.set('parentPort', this); // @ORDER: 2
45
76
  }
46
77
 
47
78
  if (this.options.handshake) {
@@ -62,15 +93,21 @@ export class StarPort extends MessagePortPlus {
62
93
  this.#ports.delete(portPlus);
63
94
 
64
95
  if (enableBubbling
65
- && portPlusMeta.get('parentNode') === this) {
66
- portPlusMeta.set('parentNode', null);
96
+ && portPlusMeta.get('parentPort') === this) {
97
+ portPlusMeta.set('parentPort', null);
67
98
  }
68
99
 
69
- if (this.#ports.size === 0
70
- && _options(this).autoClose) {
71
- readyStateInternals.close.state = true;
72
- readyStateInternals.close.resolve(this);
73
- }
100
+ const resolveClose = () => {
101
+ if (this.#ports.size === 0
102
+ && _options(this).autoClose) {
103
+ readyStateInternals.close.state = true;
104
+ readyStateInternals.close.resolve(this);
105
+ }
106
+ };
107
+
108
+ if (this.#autoCloseX) {
109
+ this.#autoCloseX.p.finally(resolveClose);
110
+ } else resolveClose();
74
111
  };
75
112
 
76
113
  return cleanup;
@@ -113,6 +150,7 @@ export class StarPort extends MessagePortPlus {
113
150
  for (const portPlus of this.#ports) {
114
151
  portPlus.close(...args);
115
152
  }
153
+ this.#autoCloseX?.r();
116
154
 
117
155
  if (!this.options.handshake || !this.#ports.size) {
118
156
  const readyStateInternals = getReadyStateInternals.call(this);