@warp-drive/ember 0.0.0-alpha.5 → 0.0.0-alpha.51

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/README.md CHANGED
@@ -22,6 +22,14 @@
22
22
  pnpm install @warp-drive/ember
23
23
  ```
24
24
 
25
+ **Tagged Releases**
26
+
27
+ - ![NPM Canary Version](https://img.shields.io/npm/v/%40warp-drive%2Fember/canary?label=@canary&color=FFBF00)
28
+ - ![NPM Beta Version](https://img.shields.io/npm/v/%40warp-drive%2Fember/bet?label=@beta&color=ff00ff)
29
+ - ![NPM Stable Version](https://img.shields.io/npm/v/%40warp-drive%2Fember/latest?label=@latest&color=90EE90)
30
+ - ![NPM LTS Version](https://img.shields.io/npm/v/%40warp-drive%2Fember/lts?label=@lts&color=0096FF)
31
+ - ![NPM LTS-4-12 Version](https://img.shields.io/npm/v/%40warp-drive%2Fember/lts-4-12?label=@lts-4-12&color=bbbbbb)
32
+
25
33
  ## About
26
34
 
27
35
  This library provides reactive utilities for working with promises and requests, building over these primitives to provide functions and components that enable you to build robust performant apps with elegant control flow
@@ -30,10 +38,10 @@ Documentation
30
38
 
31
39
  - [PromiseState](#promisestate)
32
40
  - [getPromiseState](#getpromisestate)
33
- - [\<Await />](#await)
41
+ - [\<Await />](#await-)
34
42
  - [RequestState](#requeststate)
35
43
  - [getRequestState](#getrequeststate)
36
- - [\<Request />](#request)
44
+ - [\<Request />](#request-)
37
45
 
38
46
  ---
39
47
 
@@ -210,6 +218,9 @@ import { Await } from '@warp-drive/ember';
210
218
  </template>
211
219
  ```
212
220
 
221
+ When using the Await component, if no error block is provided and the promise rejects,
222
+ the error will be thrown.
223
+
213
224
  ### RequestState
214
225
 
215
226
  RequestState extends PromiseState to provide a reactive wrapper for a request `Future` which
@@ -297,7 +308,7 @@ import { Request } from '@warp-drive/ember';
297
308
  <template>
298
309
  <Request @request={{@request}}>
299
310
  <:loading as |state|>
300
- <Spinner @percentDone={{state.completeRatio}} />
311
+ <Spinner @percentDone={{state.completedRatio}} />
301
312
  <button {{on "click" state.abort}}>Cancel</button>
302
313
  </:loading>
303
314
 
@@ -312,6 +323,10 @@ import { Request } from '@warp-drive/ember';
312
323
  </template>
313
324
  ```
314
325
 
326
+ When using the Await component, if no error block is provided and the request rejects,
327
+ the error will be thrown. Cancellation errors are not rethrown if no error block or
328
+ cancellation block is present.
329
+
315
330
  - Streaming Data
316
331
 
317
332
  The loading state exposes the download `ReadableStream` instance for consumption
@@ -357,7 +372,36 @@ import { Request } from '@warp-drive/ember';
357
372
  If a request is aborted but no cancelled block is present, the error will be given
358
373
  to the error block to handle.
359
374
 
360
- If no error block is present, the error will be rethrown.
375
+ If no error block is present, the cancellation error will be swallowed.
376
+
377
+ - retry
378
+
379
+ Cancelled and error'd requests may be retried,
380
+ retry will reuse the error, cancelled and loading
381
+ blocks as appropriate.
382
+
383
+ ```gjs
384
+ import { Request } from '@warp-drive/ember';
385
+ import { on } from '@ember/modifier';
386
+
387
+ <template>
388
+ <Request @request={{@request}}>
389
+ <:cancelled as |error state|>
390
+ <h2>The Request Cancelled</h2>
391
+ <button {{on "click" state.retry}}>Retry</button>
392
+ </:cancelled>
393
+
394
+ <:error as |error state|>
395
+ <ErrorForm @error={{error}} />
396
+ <button {{on "click" state.retry}}>Retry</button>
397
+ </:error>
398
+
399
+ <:content as |result|>
400
+ <h1>{{result.title}}</h1>
401
+ </:content>
402
+ </Request>
403
+ </template>
404
+ ```
361
405
 
362
406
  - Reloading states
363
407
 
@@ -426,21 +470,36 @@ import { Request } from '@warp-drive/ember';
426
470
  </template>
427
471
  ```
428
472
 
429
- - AutoRefresh behavior
473
+ - Autorefresh behavior
430
474
 
431
475
  Requests can be made to automatically refresh when a browser window or tab comes back to the
432
- foreground after being backgrounded.
476
+ foreground after being backgrounded or when the network reports as being online after having
477
+ been offline.
433
478
 
434
479
  ```gjs
435
480
  import { Request } from '@warp-drive/ember';
436
481
 
437
482
  <template>
438
- <Request @request={{@request}} @autoRefresh={{true}}>
483
+ <Request @request={{@request}} @autorefresh={{true}}>
439
484
  <!-- ... -->
440
485
  </Request>
441
486
  </template>
442
487
  ```
443
488
 
489
+ By default, an autorefresh will only occur if the browser was backgrounded or offline for more than
490
+ 30s before coming back available. This amount of time can be tweaked by setting the number of milliseconds
491
+ via `@autorefreshThreshold`.
492
+
493
+ The behavior of the fetch initiated by the autorefresh can also be adjusted by `@autorefreshBehavior`
494
+
495
+ Options are:
496
+
497
+ - `refresh` update while continuing to show the current state.
498
+ - `reload` update and show the loading state until update completes)
499
+ - `delegate` (**default**) trigger the request, but let the cache handler decide whether the update should occur or if the cache is still valid.
500
+
501
+ ---
502
+
444
503
  Similarly, refresh could be set up on a timer or on a websocket subscription by using the yielded
445
504
  refresh function and passing it to another component.
446
505
 
@@ -448,7 +507,7 @@ refresh function and passing it to another component.
448
507
  import { Request } from '@warp-drive/ember';
449
508
 
450
509
  <template>
451
- <Request @request={{@request}} @autoRefresh={{true}}>
510
+ <Request @request={{@request}}>
452
511
  <:content as |result state|>
453
512
  <h1>{{result.title}}</h1>
454
513
 
package/addon-main.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  'use strict';
2
2
 
3
- const { addonV1Shim } = require('@embroider/addon-shim');
3
+ const { addonShim } = require('@warp-drive/build-config/addon-shim.cjs');
4
4
 
5
- module.exports = addonV1Shim(__dirname);
5
+ module.exports = addonShim(__dirname);
@@ -1,16 +1,17 @@
1
1
  import { tracked, cached } from '@glimmer/tracking';
2
2
  import { getPromiseResult, setPromiseResult } from '@ember-data/request';
3
- import { assert } from '@ember/debug';
4
3
  import { service } from '@ember/service';
5
4
  import Component from '@glimmer/component';
6
- import { macroCondition, moduleExists, importSync } from '@embroider/macros';
5
+ import { macroCondition, moduleExists, importSync, getGlobalConfig } from '@embroider/macros';
6
+ import { EnableHydration } from '@warp-drive/core-types/request';
7
7
  import { precompileTemplate } from '@ember/template-compilation';
8
8
  import { setComponentTemplate } from '@ember/component';
9
-
10
9
  var __defProp = Object.defineProperty;
11
10
  var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
11
+ for (var name in all) __defProp(target, name, {
12
+ get: all[name],
13
+ enumerable: true
14
+ });
14
15
  };
15
16
 
16
17
  // src/runtime.ts
@@ -24,11 +25,11 @@ __export(runtime_exports, {
24
25
  n: () => decorateMethodV2,
25
26
  p: () => decoratePOJO
26
27
  });
27
- var deferred = /* @__PURE__ */ new WeakMap();
28
+ var deferred = /* @__PURE__ */new WeakMap();
28
29
  function deferDecorator(proto, prop, desc) {
29
30
  let map = deferred.get(proto);
30
31
  if (!map) {
31
- map = /* @__PURE__ */ new Map();
32
+ map = /* @__PURE__ */new Map();
32
33
  deferred.set(proto, map);
33
34
  }
34
35
  map.set(prop, desc);
@@ -65,12 +66,16 @@ function decorateFieldV2(prototype, prop, decorators, initializer) {
65
66
  deferDecorator(prototype, prop, desc);
66
67
  }
67
68
  }
68
- function decorateMethodV1({ prototype }, prop, decorators) {
69
+ function decorateMethodV1({
70
+ prototype
71
+ }, prop, decorators) {
69
72
  return decorateMethodV2(prototype, prop, decorators);
70
73
  }
71
74
  function decorateMethodV2(prototype, prop, decorators) {
72
75
  const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
73
- let desc = { ...origDesc };
76
+ let desc = {
77
+ ...origDesc
78
+ };
74
79
  for (let decorator of decorators) {
75
80
  desc = decorator(prototype, prop, desc) || desc;
76
81
  }
@@ -92,10 +97,7 @@ function initializeDeferredDecorator(target, prop) {
92
97
  }
93
98
  }
94
99
  function decorateClass(target, decorators) {
95
- return decorators.reduce(
96
- (accum, decorator) => decorator(accum) || accum,
97
- target
98
- );
100
+ return decorators.reduce((accum, decorator) => decorator(accum) || accum, target);
99
101
  }
100
102
  function decoratePOJO(pojo, decorated) {
101
103
  for (let [type, prop, decorators] of decorated) {
@@ -123,7 +125,6 @@ function decoratePojoField(pojo, prop, decorators) {
123
125
  }
124
126
  Object.defineProperty(pojo, prop, desc);
125
127
  }
126
-
127
128
  const RequestCache = new WeakMap();
128
129
  function isAbortError(error) {
129
130
  return error instanceof DOMException && error.name === 'AbortError';
@@ -339,11 +340,11 @@ class RequestLoadingState {
339
340
  get elapsedTime() {
340
341
  return (this.endTime || this.lastPacketTime) - this.startTime;
341
342
  }
342
- get completeRatio() {
343
+ get completedRatio() {
343
344
  return this.sizeHint ? this.bytesLoaded / this.sizeHint : 0;
344
345
  }
345
346
  get remainingRatio() {
346
- return 1 - this.completeRatio;
347
+ return 1 - this.completedRatio;
347
348
  }
348
349
  get duration() {
349
350
  return this.endTime - this.startTime;
@@ -355,9 +356,9 @@ class RequestLoadingState {
355
356
  constructor(future) {
356
357
  this._future = future;
357
358
  }
358
- abort() {
359
+ abort = () => {
359
360
  this._future.abort();
360
- }
361
+ };
361
362
  }
362
363
  class RequestState {
363
364
  #request;
@@ -460,7 +461,6 @@ function getRequestState(future) {
460
461
  }
461
462
  return state;
462
463
  }
463
-
464
464
  const PromiseCache = new WeakMap();
465
465
  class PromiseState {
466
466
  static {
@@ -526,23 +526,29 @@ class PromiseState {
526
526
  }
527
527
  }
528
528
  }
529
+ const LegacyPromiseProxy = Symbol.for('LegacyPromiseProxy');
530
+ function isLegacyAwaitable(promise) {
531
+ return LegacyPromiseProxy in promise && 'promise' in promise && promise[LegacyPromiseProxy] === true;
532
+ }
533
+ function getPromise(promise) {
534
+ return isLegacyAwaitable(promise) ? promise.promise : promise;
535
+ }
529
536
  function getPromiseState(promise) {
530
- let state = PromiseCache.get(promise);
537
+ const _promise = getPromise(promise);
538
+ let state = PromiseCache.get(_promise);
531
539
  if (!state) {
532
- state = new PromiseState(promise);
533
- PromiseCache.set(promise, state);
540
+ state = new PromiseState(_promise);
541
+ PromiseCache.set(_promise, state);
534
542
  }
535
543
  return state;
536
544
  }
537
-
538
- function notNull(x1) {
539
- assert('Expected a non-null value, but got null', x1 !== null);
540
- return x1;
541
- }
542
545
  const and = (x1, y1) => Boolean(x1 && y1);
543
546
  class Throw extends Component {
544
547
  constructor(owner1, args1) {
545
548
  super(owner1, args1);
549
+ // this error is opaque (user supplied) so we don't validate it
550
+ // as an Error instance.
551
+ // eslint-disable-next-line @typescript-eslint/no-throw-literal
546
552
  throw this.args.error;
547
553
  }
548
554
  static {
@@ -555,46 +561,251 @@ class Await extends Component {
555
561
  get state() {
556
562
  return getPromiseState(this.args.promise);
557
563
  }
564
+ get error() {
565
+ return this.state.error;
566
+ }
567
+ get result() {
568
+ return this.state.result;
569
+ }
558
570
  static {
559
- setComponentTemplate(precompileTemplate("\n {{#if this.state.isPending}}\n {{yield to=\"pending\"}}\n {{else if (and this.state.isError (has-block \"error\"))}}\n {{yield (notNull this.state.error) to=\"error\"}}\n {{else if this.state.isSuccess}}\n {{yield (notNull this.state.result) to=\"success\"}}\n {{else}}\n <Throw @error={{(notNull this.state.error)}} />\n {{/if}}\n ", {
571
+ setComponentTemplate(precompileTemplate("\n {{#if this.state.isPending}}\n {{yield to=\"pending\"}}\n {{else if (and this.state.isError (has-block \"error\"))}}\n {{yield this.error to=\"error\"}}\n {{else if this.state.isSuccess}}\n {{yield this.result to=\"success\"}}\n {{else}}\n <Throw @error={{this.error}} />\n {{/if}}\n ", {
572
+ strictMode: true,
560
573
  scope: () => ({
561
574
  and,
562
- notNull,
563
575
  Throw
564
- }),
565
- strictMode: true
576
+ })
566
577
  }), this);
567
578
  }
568
579
  }
569
-
570
- let provide = service;
580
+ function notNull(x1) {
581
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
582
+ if (!test) {
583
+ throw new Error('Expected a non-null value, but got null');
584
+ }
585
+ })(x1 !== null) : {};
586
+ return x1;
587
+ }
588
+ const not = x1 => !x1;
589
+ // default to 30 seconds unavailable before we refresh
590
+ const DEFAULT_DEADLINE = 30_000;
591
+ let consume = service;
571
592
  if (macroCondition(moduleExists('ember-provide-consume-context'))) {
572
593
  const {
573
- consume
594
+ consume: contextConsume
574
595
  } = importSync('ember-provide-consume-context');
575
- provide = consume;
596
+ consume = contextConsume;
597
+ }
598
+ function isNeverString(val1) {
599
+ return val1;
576
600
  }
577
601
  class Request extends Component {
578
602
  static {
579
- decorateFieldV2(this.prototype, "_store", [provide('store')]);
603
+ decorateFieldV2(this.prototype, "_store", [consume('store')]);
580
604
  }
581
605
  #_store = (initializeDeferredDecorator(this, "_store"), void 0);
582
606
  /**
583
607
  * @internal
584
608
  */
585
- retry = () => {};
586
- reload = () => {};
587
- refresh = () => {};
609
+ static {
610
+ decorateFieldV2(this.prototype, "isOnline", [tracked], function () {
611
+ return true;
612
+ });
613
+ }
614
+ #isOnline = (initializeDeferredDecorator(this, "isOnline"), void 0);
615
+ static {
616
+ decorateFieldV2(this.prototype, "isHidden", [tracked], function () {
617
+ return true;
618
+ });
619
+ }
620
+ #isHidden = (initializeDeferredDecorator(this, "isHidden"), void 0);
621
+ static {
622
+ decorateFieldV2(this.prototype, "isRefreshing", [tracked], function () {
623
+ return false;
624
+ });
625
+ }
626
+ #isRefreshing = (initializeDeferredDecorator(this, "isRefreshing"), void 0);
627
+ static {
628
+ decorateFieldV2(this.prototype, "_localRequest", [tracked]);
629
+ }
630
+ #_localRequest = (initializeDeferredDecorator(this, "_localRequest"), void 0);
631
+ static {
632
+ decorateFieldV2(this.prototype, "_latestRequest", [tracked]);
633
+ }
634
+ #_latestRequest = (initializeDeferredDecorator(this, "_latestRequest"), void 0);
635
+ unavailableStart;
636
+ onlineChanged;
637
+ backgroundChanged;
638
+ _originalRequest;
639
+ _originalQuery;
640
+ constructor(owner1, args1) {
641
+ super(owner1, args1);
642
+ this.installListeners();
643
+ }
644
+ installListeners() {
645
+ if (typeof window === 'undefined') {
646
+ return;
647
+ }
648
+ this.isOnline = window.navigator.onLine;
649
+ this.unavailableStart = this.isOnline ? null : Date.now();
650
+ this.isHidden = document.visibilityState === 'hidden';
651
+ this.onlineChanged = event1 => {
652
+ this.isOnline = event1.type === 'online';
653
+ if (event1.type === 'offline' && this.unavailableStart === null) {
654
+ this.unavailableStart = Date.now();
655
+ }
656
+ this.maybeUpdate();
657
+ };
658
+ this.backgroundChanged = () => {
659
+ const isHidden1 = document.visibilityState === 'hidden';
660
+ this.isHidden = isHidden1;
661
+ if (isHidden1 && this.unavailableStart === null) {
662
+ this.unavailableStart = Date.now();
663
+ }
664
+ this.maybeUpdate();
665
+ };
666
+ window.addEventListener('online', this.onlineChanged, {
667
+ passive: true,
668
+ capture: true
669
+ });
670
+ window.addEventListener('offline', this.onlineChanged, {
671
+ passive: true,
672
+ capture: true
673
+ });
674
+ document.addEventListener('visibilitychange', this.backgroundChanged, {
675
+ passive: true,
676
+ capture: true
677
+ });
678
+ }
679
+ maybeUpdate(mode1) {
680
+ if (this.isOnline && !this.isHidden && (mode1 || this.args.autorefresh)) {
681
+ const deadline1 = typeof this.args.autorefreshThreshold === 'number' ? this.args.autorefreshThreshold : DEFAULT_DEADLINE;
682
+ const shouldAttempt1 = mode1 || this.unavailableStart && Date.now() - this.unavailableStart > deadline1;
683
+ this.unavailableStart = null;
684
+ if (shouldAttempt1) {
685
+ const request1 = Object.assign({}, this.reqState.request);
686
+ const val1 = mode1 ?? this.args.autorefreshBehavior ?? 'policy';
687
+ switch (val1) {
688
+ case 'reload':
689
+ request1.cacheOptions = Object.assign({}, request1.cacheOptions, {
690
+ reload: true
691
+ });
692
+ break;
693
+ case 'refresh':
694
+ request1.cacheOptions = Object.assign({}, request1.cacheOptions, {
695
+ backgroundReload: true
696
+ });
697
+ break;
698
+ case 'policy':
699
+ break;
700
+ default:
701
+ throw new Error(`Invalid ${mode1 ? 'update mode' : '@autorefreshBehavior'} for <Request />: ${isNeverString(val1)}`);
702
+ }
703
+ const wasStoreRequest1 = request1[EnableHydration] === true;
704
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
705
+ if (!test) {
706
+ throw new Error(`Cannot supply a different store via context than was used to create the request`);
707
+ }
708
+ })(!request1.store || request1.store === this.store) : {};
709
+ this._latestRequest = wasStoreRequest1 ? this.store.request(request1) : this.store.requestManager.request(request1);
710
+ if (val1 !== 'refresh') {
711
+ this._localRequest = this._latestRequest;
712
+ }
713
+ return;
714
+ }
715
+ }
716
+ if (mode1) {
717
+ throw new Error(`Reload not available: the network is not online or the tab is hidden`);
718
+ }
719
+ }
720
+ retry = async () => {
721
+ this.maybeUpdate('reload');
722
+ await this._localRequest;
723
+ };
724
+ refresh = async () => {
725
+ this.isRefreshing = true;
726
+ this.maybeUpdate('refresh');
727
+ try {
728
+ await this._latestRequest;
729
+ } finally {
730
+ this.isRefreshing = false;
731
+ }
732
+ };
733
+ get errorFeatures() {
734
+ return {
735
+ isHidden: this.isHidden,
736
+ isOnline: this.isOnline,
737
+ retry: this.retry
738
+ };
739
+ }
740
+ static {
741
+ decorateMethodV2(this.prototype, "errorFeatures", [cached]);
742
+ }
743
+ get contentFeatures() {
744
+ const feat1 = {
745
+ isHidden: this.isHidden,
746
+ isOnline: this.isOnline,
747
+ reload: this.retry,
748
+ refresh: this.refresh,
749
+ isRefreshing: this.isRefreshing,
750
+ latestRequest: this._latestRequest
751
+ };
752
+ if (feat1.isRefreshing) {
753
+ feat1.abort = () => {
754
+ this._latestRequest?.abort();
755
+ };
756
+ }
757
+ return feat1;
758
+ }
759
+ static {
760
+ decorateMethodV2(this.prototype, "contentFeatures", [cached]);
761
+ }
762
+ willDestroy() {
763
+ if (typeof window === 'undefined') {
764
+ return;
765
+ }
766
+ window.removeEventListener('online', this.onlineChanged, {
767
+ passive: true,
768
+ capture: true
769
+ });
770
+ window.removeEventListener('offline', this.onlineChanged, {
771
+ passive: true,
772
+ capture: true
773
+ });
774
+ document.removeEventListener('visibilitychange', this.backgroundChanged, {
775
+ passive: true,
776
+ capture: true
777
+ });
778
+ }
588
779
  get request() {
589
780
  const {
590
781
  request: request1,
591
782
  query: query1
592
783
  } = this.args;
593
- assert(`Cannot use both @request and @query args with the <Request> component`, !request1 || !query1);
784
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
785
+ if (!test) {
786
+ throw new Error(`Cannot use both @request and @query args with the <Request> component`);
787
+ }
788
+ })(!request1 || !query1) : {};
789
+ const {
790
+ _localRequest: _localRequest1,
791
+ _originalRequest: _originalRequest1,
792
+ _originalQuery: _originalQuery1
793
+ } = this;
794
+ const isOriginalRequest1 = request1 === _originalRequest1 && query1 === _originalQuery1;
795
+ if (_localRequest1 && isOriginalRequest1) {
796
+ return _localRequest1;
797
+ }
798
+ // update state checks for the next time
799
+ this._originalQuery = query1;
800
+ this._originalRequest = request1;
594
801
  if (request1) {
595
802
  return request1;
596
803
  }
597
- assert(`You must provide either @request or an @query arg with the <Request> component`, query1);
804
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
805
+ if (!test) {
806
+ throw new Error(`You must provide either @request or an @query arg with the <Request> component`);
807
+ }
808
+ })(query1) : {};
598
809
  return this.store.request(query1);
599
810
  }
600
811
  static {
@@ -602,23 +813,29 @@ class Request extends Component {
602
813
  }
603
814
  get store() {
604
815
  const store1 = this.args.store || this._store;
605
- assert(moduleExists('ember-provide-consume-context') ? `No store was provided to the <Request> component. Either provide a store via the @store arg or via the context API provided by ember-provide-consume-context.` : `No store was provided to the <Request> component. Either provide a store via the @store arg or by registering a store service.`, store1);
816
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
817
+ if (!test) {
818
+ throw new Error(moduleExists('ember-provide-consume-context') ? `No store was provided to the <Request> component. Either provide a store via the @store arg or via the context API provided by ember-provide-consume-context.` : `No store was provided to the <Request> component. Either provide a store via the @store arg or by registering a store service.`);
819
+ }
820
+ })(store1) : {};
606
821
  return store1;
607
822
  }
608
823
  get reqState() {
609
824
  return getRequestState(this.request);
610
825
  }
826
+ get result() {
827
+ return this.reqState.result;
828
+ }
611
829
  static {
612
- setComponentTemplate(precompileTemplate("\n {{#if this.reqState.isLoading}}\n {{yield this.reqState.loadingState to=\"loading\"}}\n {{else if (and this.reqState.isCancelled (has-block \"cancelled\"))}}\n {{yield (notNull this.reqState.error) to=\"cancelled\"}}\n {{else if (and this.reqState.isError (has-block \"error\"))}}\n {{yield (notNull this.reqState.error) to=\"error\"}}\n {{else if this.reqState.isSuccess}}\n {{yield (notNull this.reqState.result) to=\"content\"}}\n {{else}}\n <Throw @error={{(notNull this.reqState.error)}} />\n {{/if}}\n ", {
830
+ setComponentTemplate(precompileTemplate("\n {{#if this.reqState.isLoading}}\n {{yield this.reqState.loadingState to=\"loading\"}}\n {{else if (and this.reqState.isCancelled (has-block \"cancelled\"))}}\n {{yield (notNull this.reqState.error) this.errorFeatures to=\"cancelled\"}}\n {{else if (and this.reqState.isError (has-block \"error\"))}}\n {{yield (notNull this.reqState.error) this.errorFeatures to=\"error\"}}\n {{else if this.reqState.isSuccess}}\n {{yield this.result this.contentFeatures to=\"content\"}}\n {{else if (not this.reqState.isCancelled)}}\n <Throw @error={{(notNull this.reqState.error)}} />\n {{/if}}\n {{yield this.reqState to=\"always\"}}\n ", {
831
+ strictMode: true,
613
832
  scope: () => ({
614
833
  and,
615
834
  notNull,
835
+ not,
616
836
  Throw
617
- }),
618
- strictMode: true
837
+ })
619
838
  }), this);
620
839
  }
621
840
  }
622
-
623
- export { Await, Request, Throw, getPromiseState, getRequestState };
624
- //# sourceMappingURL=index.js.map
841
+ export { Await, Request, Throw, getPromiseState, getRequestState };