@webqit/fetch-plus 0.1.13 → 0.1.14

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
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "homepage": "https://fetch-plus.netlify.app/",
13
13
  "icon": "https://webqit.io/icon.svg",
14
- "version": "0.1.13",
14
+ "version": "0.1.14",
15
15
  "license": "MIT",
16
16
  "repository": {
17
17
  "type": "git",
@@ -6,16 +6,26 @@ import { ResponsePlus } from './ResponsePlus.js';
6
6
 
7
7
  export class LiveResponse extends EventTarget {
8
8
 
9
+ get [Symbol.toStringTag]() {
10
+ return 'LiveResponse';
11
+ }
12
+
13
+ static [Symbol.hasInstance](instance) {
14
+ return instance instanceof EventTarget
15
+ && instance?.[Symbol.toStringTag] === 'LiveResponse'
16
+ && typeof instance.replaceWith === 'function'
17
+ && typeof instance.now === 'function';
18
+ }
19
+
9
20
  static get xHeaderName() {
10
21
  return 'X-Message-Port';
11
22
  }
12
23
 
13
24
  static test(unknown) {
14
- if (unknown instanceof LiveResponse
15
- || unknown?.[Symbol.toStringTag] === 'LiveResponse') {
25
+ if (unknown instanceof LiveResponse) {
16
26
  return 'LiveResponse';
17
27
  }
18
- if (unknown?.[Symbol.toStringTag] === 'LiveProgramHandle') {
28
+ if (unknown instanceof LiveProgramHandleX) {
19
29
  return 'LiveProgramHandle';
20
30
  }
21
31
  if (unknown instanceof Response) {
@@ -34,7 +44,8 @@ export class LiveResponse extends EventTarget {
34
44
  }
35
45
 
36
46
  static getPort(respone, { handshake = 1 } = {}) {
37
- if (!/Response/.test(this.test(respone))) {
47
+ if (!(respone instanceof Response
48
+ || respone instanceof LiveResponse)) {
38
49
  return;
39
50
  }
40
51
 
@@ -72,7 +83,7 @@ export class LiveResponse extends EventTarget {
72
83
  }
73
84
 
74
85
  static from(data, ...args) {
75
- if (this.test(data) === 'LiveResponse') {
86
+ if (data instanceof LiveResponse) {
76
87
  return data.clone(...args);
77
88
  }
78
89
  return new this(data, ...args);
@@ -80,17 +91,32 @@ export class LiveResponse extends EventTarget {
80
91
 
81
92
  /* INSTANCE */
82
93
 
83
- [Symbol.toStringTag] = 'LiveResponse';
84
-
85
94
  #listenersRegistry;
95
+ #readyStates;
96
+
97
+ #abortController = new AbortController;
98
+ #concurrencyAbortController = new AbortController;
86
99
 
87
100
  constructor(body, ...args) {
88
101
  super();
89
102
  this.#listenersRegistry = ListenerRegistry.getInstance(this, true);
90
103
 
91
- const readyStateInternals = getReadyStateInternals.call(this);
92
- const frame = readyStateInternals.now;
104
+ const $ref = (o) => {
105
+ o.promise = new Promise((res, rej) => (o.resolve = res, o.reject = rej));
106
+ return o;
107
+ };
108
+ this.#readyStates = {
109
+ live: $ref({}),
110
+ done: $ref({}),
111
+ };
112
+ const readyStates = this.#readyStates;
113
+ (function refresh() {
114
+ readyStates.now = $ref({});
115
+ readyStates.now.refresh = refresh;
116
+ return readyStates.now;
117
+ })();
93
118
 
119
+ const frame = this.#readyStates.now;
94
120
  this.#replaceWith(frame, body, ...args).catch((e) => {
95
121
  frame.reject(e);
96
122
  });
@@ -128,11 +154,6 @@ export class LiveResponse extends EventTarget {
128
154
 
129
155
  get ok() { return !!(this.#status >= 200 && this.#status < 299); }
130
156
 
131
- async now() {
132
- const readyStateInternals = getReadyStateInternals.call(this);
133
- return readyStateInternals.now.promise;
134
- }
135
-
136
157
  /* Level 3 props */
137
158
 
138
159
  #port;
@@ -140,21 +161,16 @@ export class LiveResponse extends EventTarget {
140
161
 
141
162
  // Lifecycle
142
163
 
143
- #abortController = new AbortController;
144
- #concurrencyAbortController = new AbortController;
145
-
146
164
  get readyState() {
147
- const readyStateInternals = getReadyStateInternals.call(this);
148
- return readyStateInternals.done.state ? 'done'
149
- : (readyStateInternals.live.state ? 'live' : 'waiting');
165
+ return this.#readyStates.done.state ? 'done'
166
+ : (this.#readyStates.live.state ? 'live' : 'waiting');
150
167
  }
151
168
 
152
169
  readyStateChange(query) {
153
170
  if (!['live', 'now', 'done'].includes(query)) {
154
171
  throw new Error(`Invalid readyState query "${query}"`);
155
172
  }
156
- const readyStateInternals = getReadyStateInternals.call(this);
157
- return readyStateInternals[query].promise;
173
+ return this.#readyStates[query].promise;
158
174
  }
159
175
 
160
176
  disconnect(dispose = false) {
@@ -168,27 +184,28 @@ export class LiveResponse extends EventTarget {
168
184
 
169
185
  #currentFramePromise;
170
186
  #extendLifecycle(promise) {
171
- const readyStateInternals = getReadyStateInternals.call(this);
172
- if (readyStateInternals.done.state) {
187
+ if (this.#readyStates.done.state) {
173
188
  throw new Error('Response already done.');
174
189
  }
175
190
  this.#currentFramePromise = promise;
176
191
  promise.then((value) => {
177
192
  if (this.#currentFramePromise === promise) {
178
193
  this.#currentFramePromise = null;
179
- readyStateInternals.done.state = true;
180
- readyStateInternals.done.resolve(value);
194
+ this.#readyStates.done.state = true;
195
+ this.#readyStates.done.resolve(value);
181
196
  }
182
197
  }).catch((e) => {
183
198
  if (this.#currentFramePromise === promise) {
184
199
  this.#currentFramePromise = null;
185
- readyStateInternals.done.state = true;
186
- readyStateInternals.done.reject(e);
200
+ this.#readyStates.done.state = true;
201
+ this.#readyStates.done.reject(e);
187
202
  }
188
203
  });
189
204
  return promise;
190
205
  }
191
206
 
207
+ async now() { return this.#readyStates.now.promise; }
208
+
192
209
  async replaceWith(body, ...args) {
193
210
  if (this.readyState === 'done') {
194
211
  throw new Error('Response already done.');
@@ -198,8 +215,7 @@ export class LiveResponse extends EventTarget {
198
215
  }
199
216
 
200
217
  async #replaceWith(__frame, body, ...args) {
201
- const readyStateInternals = getReadyStateInternals.call(this);
202
- const frame = __frame || readyStateInternals.now.refresh();
218
+ const frame = __frame || this.#readyStates.now.refresh();
203
219
 
204
220
  // ----------- Promise input
205
221
 
@@ -231,7 +247,7 @@ export class LiveResponse extends EventTarget {
231
247
  return;
232
248
  }
233
249
 
234
- const frame = __frame || readyStateInternals.now.refresh();
250
+ const frame = __frame || this.#readyStates.now.refresh();
235
251
 
236
252
  const $body = responseFrame.body;
237
253
 
@@ -273,8 +289,8 @@ export class LiveResponse extends EventTarget {
273
289
 
274
290
  // Must come first so that observers below here see this state
275
291
 
276
- readyStateInternals.live.state = true;
277
- readyStateInternals.live.resolve(this);
292
+ this.#readyStates.live.state = true;
293
+ this.#readyStates.live.resolve(this);
278
294
 
279
295
  // May trigger "done" ready state
280
296
  frame.resolve(responseFrame);
@@ -326,7 +342,7 @@ export class LiveResponse extends EventTarget {
326
342
  url: response.url,
327
343
  });
328
344
 
329
- if (this.constructor.test(response) === 'LiveResponse') {
345
+ if (response instanceof LiveResponse) {
330
346
  const replaceHandler = () => {
331
347
  wrapReplaceWith(null, response.body, response);
332
348
  };
@@ -429,17 +445,18 @@ export class LiveResponse extends EventTarget {
429
445
 
430
446
  // ----------- Dispatch time
431
447
 
432
- if (/Response/.test(this.constructor.test(body))) {
448
+ if (body instanceof Response
449
+ || body instanceof LiveResponse) {
433
450
  if (frameClosure) {
434
451
  throw new Error(`frameClosure is not supported for responses.`);
435
452
  }
436
453
  frame.donePromise = execReplaceWithResponse(frame, body, frameOptions);
437
- } else if (this.constructor.test(body) === 'Generator') {
454
+ } else if (isGenerator(body)) {
438
455
  if (frameClosure) {
439
456
  throw new Error(`frameClosure is not supported for generators.`);
440
457
  }
441
458
  frame.donePromise = execReplaceWithGenerator(frame, body, frameOptions);
442
- } else if (this.constructor.test(body) === 'LiveProgramHandle') {
459
+ } else if (body instanceof LiveProgramHandleX) {
443
460
  if (frameClosure) {
444
461
  throw new Error(`frameClosure is not supported for live program handles.`);
445
462
  }
@@ -554,29 +571,15 @@ export const isGenerator = (obj) => {
554
571
  typeof obj?.return === 'function';
555
572
  };
556
573
 
557
- export function getReadyStateInternals() {
558
- const portPlusMeta = _meta(this);
559
- if (!portPlusMeta.has('readystate_registry')) {
560
- const $ref = (o) => {
561
- o.promise = new Promise((res, rej) => (o.resolve = res, o.reject = rej));
562
- return o;
563
- };
564
- const states = {
565
- live: $ref({}),
566
- done: $ref({}),
567
- };
568
- (function refresh() {
569
- states.now = $ref({});
570
- states.now.refresh = refresh;
571
- return states.now;
572
- })();
573
- portPlusMeta.set('readystate_registry', states);
574
- }
575
- return portPlusMeta.get('readystate_registry');
576
- }
577
-
578
574
  export class ReplaceEvent extends Event {
579
575
 
576
+ [Symbol.toStringTag] = 'ReplaceEvent';
577
+
578
+ static [Symbol.hasInstance](instance) {
579
+ return instance instanceof Event
580
+ && instance[Symbol.toStringTag] === 'ReplaceEvent';
581
+ }
582
+
580
583
  #data;
581
584
  get data() { return this.#data; }
582
585
 
@@ -588,5 +591,10 @@ export class ReplaceEvent extends Event {
588
591
 
589
592
  export class LiveProgramHandleX {
590
593
  [Symbol.toStringTag] = 'LiveProgramHandle';
594
+
595
+ static [Symbol.hasInstance](instance) {
596
+ return instance?.[Symbol.toStringTag] === 'LiveProgramHandle';
597
+ }
598
+
591
599
  abort() { }
592
600
  }