@warp-drive/ember 5.6.0-alpha.5 → 5.6.0-beta.1

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/dist/index.js CHANGED
@@ -1,12 +1,11 @@
1
1
  import { service } from '@ember/service';
2
2
  import Component from '@glimmer/component';
3
- import { tracked, cached } from '@glimmer/tracking';
4
3
  import { macroCondition, moduleExists, importSync, getGlobalConfig } from '@embroider/macros';
5
- import { getPromiseState, getRequestState } from '@ember-data/store/-private';
6
- export { getPromiseState, getRequestState } from '@ember-data/store/-private';
7
- import { EnableHydration } from '@warp-drive/core-types/request';
4
+ import { getPromiseState, DISPOSE, createRequestSubscription } from '@warp-drive/core/store/-private';
5
+ export { getPromiseState, getRequestState } from '@warp-drive/core/store/-private';
8
6
  import { precompileTemplate } from '@ember/template-compilation';
9
7
  import { setComponentTemplate } from '@ember/component';
8
+
10
9
  const and = (x, y) => Boolean(x && y);
11
10
  /**
12
11
  * The `<Throw />` component is used to throw an error in a template.
@@ -90,6 +89,7 @@ class Await extends Component {
90
89
  }), this);
91
90
  }
92
91
  }
92
+
93
93
  const deferred = /* @__PURE__ */new WeakMap();
94
94
  function deferDecorator(proto, prop, desc) {
95
95
  let map = deferred.get(proto);
@@ -129,20 +129,6 @@ function decorateFieldV2(prototype, prop, decorators, initializer) {
129
129
  deferDecorator(prototype, prop, desc);
130
130
  }
131
131
  }
132
- function decorateMethodV2(prototype, prop, decorators) {
133
- const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
134
- let desc = {
135
- ...origDesc
136
- };
137
- for (let decorator of decorators) {
138
- desc = decorator(prototype, prop, desc) || desc;
139
- }
140
- if (desc.initializer !== void 0) {
141
- desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
142
- desc.initializer = void 0;
143
- }
144
- Object.defineProperty(prototype, prop, desc);
145
- }
146
132
  function initializeDeferredDecorator(target, prop) {
147
133
  let desc = findDeferredDecorator(target.constructor, prop);
148
134
  if (desc) {
@@ -154,6 +140,7 @@ function initializeDeferredDecorator(target, prop) {
154
140
  });
155
141
  }
156
142
  }
143
+
157
144
  function notNull(x) {
158
145
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
159
146
  if (!test) {
@@ -163,8 +150,6 @@ function notNull(x) {
163
150
  return x;
164
151
  }
165
152
  const not = x => !x;
166
- // default to 30 seconds unavailable before we refresh
167
- const DEFAULT_DEADLINE = 30_000;
168
153
  const IdleBlockMissingError = new Error('No idle block provided for <Request> component, and no query or request was provided.');
169
154
  let consume = service;
170
155
  if (macroCondition(moduleExists('ember-provide-consume-context'))) {
@@ -173,9 +158,6 @@ if (macroCondition(moduleExists('ember-provide-consume-context'))) {
173
158
  } = importSync('ember-provide-consume-context');
174
159
  consume = contextConsume;
175
160
  }
176
- function isNeverString(val) {
177
- return val;
178
- }
179
161
  /**
180
162
  * The `<Request />` component is a powerful tool for managing data fetching and
181
163
  * state in your Ember application. It provides a declarative approach to reactive
@@ -404,516 +386,6 @@ class Request extends Component {
404
386
  *
405
387
  * @internal
406
388
  */
407
- static {
408
- decorateFieldV2(this.prototype, "isOnline", [tracked], function () {
409
- return true;
410
- });
411
- }
412
- #isOnline = (initializeDeferredDecorator(this, "isOnline"), void 0);
413
- /**
414
- * Whether the browser reports that the network is online.
415
- *
416
- * @internal
417
- */
418
- static {
419
- decorateFieldV2(this.prototype, "isHidden", [tracked], function () {
420
- return true;
421
- });
422
- }
423
- #isHidden = (initializeDeferredDecorator(this, "isHidden"), void 0);
424
- /**
425
- * Whether the browser reports that the tab is hidden.
426
- *
427
- * @internal
428
- */
429
- static {
430
- decorateFieldV2(this.prototype, "isRefreshing", [tracked], function () {
431
- return false;
432
- });
433
- }
434
- #isRefreshing = (initializeDeferredDecorator(this, "isRefreshing"), void 0);
435
- /**
436
- * Whether the component is currently refreshing the request.
437
- *
438
- * @internal
439
- */
440
- static {
441
- decorateFieldV2(this.prototype, "_localRequest", [tracked]);
442
- }
443
- #_localRequest = (initializeDeferredDecorator(this, "_localRequest"), void 0);
444
- /**
445
- * The most recent blocking request that was made, typically
446
- * the result of a reload.
447
- *
448
- * This will never be the original request passed as an arg to
449
- * the component.
450
- *
451
- * @internal
452
- */
453
- static {
454
- decorateFieldV2(this.prototype, "_latestRequest", [tracked]);
455
- }
456
- #_latestRequest = (initializeDeferredDecorator(this, "_latestRequest"), void 0);
457
- /**
458
- * The most recent request that was made, typically due to either a
459
- * reload or a refresh.
460
- *
461
- * This will never be the original request passed as an arg to
462
- * the component.
463
- *
464
- * @internal
465
- */
466
- /**
467
- * The time at which the network was reported as offline.
468
- *
469
- * @internal
470
- */
471
-
472
- /**
473
- * The event listener for network status changes,
474
- * cached to use the reference for removal.
475
- *
476
- * @internal
477
- */
478
- /**
479
- * The event listener for visibility status changes,
480
- * cached to use the reference for removal.
481
- *
482
- * @internal
483
- */
484
- /**
485
- * The last request passed as an arg to the component,
486
- * cached for comparison.
487
- *
488
- * @internal
489
- */
490
- /**
491
- * The last query passed as an arg to the component,
492
- * cached for comparison.
493
- *
494
- * @internal
495
- */
496
-
497
- constructor(owner, args) {
498
- super(owner, args);
499
- this._subscribedTo = null;
500
- this._subscription = null;
501
- this.intervalStart = null;
502
- this.invalidated = false;
503
- this.nextInterval = null;
504
- this.installListeners();
505
- void this.beginPolling();
506
- }
507
- async beginPolling() {
508
- // await the initial request
509
- try {
510
- await this.request;
511
- } catch {
512
- // ignore errors here, we just want to wait for the request to finish
513
- } finally {
514
- if (!this.isDestroyed) {
515
- void this.scheduleInterval();
516
- }
517
- }
518
- }
519
- get isIdle() {
520
- const {
521
- request,
522
- query
523
- } = this.args;
524
- return Boolean(!request && !query);
525
- }
526
- static {
527
- decorateMethodV2(this.prototype, "isIdle", [cached]);
528
- }
529
- get autorefreshTypes() {
530
- const {
531
- autorefresh
532
- } = this.args;
533
- let types;
534
- if (autorefresh === true) {
535
- types = ['online', 'invalid'];
536
- } else if (typeof autorefresh === 'string') {
537
- types = autorefresh.split(',');
538
- } else {
539
- types = [];
540
- }
541
- return new Set(types);
542
- }
543
- // we only run this function on component creation
544
- // and when an update is triggered, so it does not
545
- // react to changes in the autorefreshThreshold
546
- // or autorefresh args.
547
- //
548
- // if we need to react to those changes, we can
549
- // use a modifier or internal component or some
550
- // such to trigger a re-run of this function.
551
- static {
552
- decorateMethodV2(this.prototype, "autorefreshTypes", [cached]);
553
- }
554
- async scheduleInterval() {
555
- const {
556
- autorefreshThreshold
557
- } = this.args;
558
- const hasValidThreshold = typeof autorefreshThreshold === 'number' && autorefreshThreshold > 0;
559
- if (typeof window === 'undefined' ||
560
- // dont schedule without a threshold
561
- !hasValidThreshold ||
562
- // dont schedule if we weren't told to
563
- !this.autorefreshTypes.has('interval') ||
564
- // dont schedule if we're already scheduled
565
- this.intervalStart !== null) {
566
- return;
567
- }
568
- // if we have a current request, wait for it to finish
569
- // before scheduling the next one
570
- if (this._latestRequest) {
571
- try {
572
- await this._latestRequest;
573
- } catch {
574
- // ignore errors here, we just want to wait for the request to finish
575
- }
576
- if (this.isDestroyed) {
577
- return;
578
- }
579
- }
580
- // setup the next interval
581
- this.intervalStart = Date.now();
582
- this.nextInterval = setTimeout(() => {
583
- this.maybeUpdate();
584
- }, autorefreshThreshold);
585
- }
586
- clearInterval() {
587
- if (this.nextInterval) {
588
- clearTimeout(this.nextInterval);
589
- this.intervalStart = null;
590
- }
591
- }
592
- updateSubscriptions() {
593
- if (this.isIdle) {
594
- return;
595
- }
596
- const requestId = this._request.lid;
597
- // if we're already subscribed to this request, we don't need to do anything
598
- if (this._subscribedTo === requestId) {
599
- return;
600
- }
601
- // if we're subscribed to a different request, we need to unsubscribe
602
- this.removeSubscriptions();
603
- // if we have a request, we need to subscribe to it
604
- if (requestId) {
605
- this._subscribedTo = requestId;
606
- this._subscription = this.store.notifications.subscribe(requestId, (_id, op) => {
607
- // ignore subscription events that occur while our own component's request
608
- // is ocurring
609
- if (this.isUpdating) {
610
- return;
611
- }
612
- switch (op) {
613
- case 'invalidated':
614
- {
615
- // if we're subscribed to invalidations, we need to update
616
- if (this.autorefreshTypes.has('invalid')) {
617
- this.invalidated = true;
618
- this.maybeUpdate();
619
- }
620
- break;
621
- }
622
- case 'state':
623
- {
624
- const latest = this.store.requestManager._deduped.get(requestId);
625
- const priority = latest?.priority;
626
- const state = this.reqState;
627
- if (!priority) {
628
- // if there is no priority, we have completed whatever request
629
- // was occurring and so we are no longer refreshing (if we were)
630
- this.isRefreshing = false;
631
- } else if (priority.blocking && !state.isLoading) {
632
- // if we are blocking, there is an active request for this identity
633
- // that MUST be fulfilled from network (not cache).
634
- // Thus this is not "refreshing" because we should clear out and
635
- // block on this request.
636
- //
637
- // we receive state notifications when either a request initiates
638
- // or completes.
639
- //
640
- // In the completes case: we may receive the state notification
641
- // slightly before the request is finalized because the NotificationManager
642
- // may sync flush it (and thus deliver it before the microtask completes)
643
- //
644
- // In the initiates case: we aren't supposed to receive one unless there
645
- // is no other request in flight for this identity.
646
- //
647
- // However, there is a race condition here where the completed
648
- // notification can trigger an update that generates a new request
649
- // thus giving us an initiated notification before the older request
650
- // finalizes.
651
- //
652
- // When this occurs, if the triggered update happens to have caused
653
- // a new request to be made for the same identity AND that request
654
- // is the one passed into this component as the @request arg, then
655
- // getRequestState will return the state of the new request.
656
- // We can detect this by checking if the request state is "loading"
657
- // as outside of this case we would have a completed request.
658
- //
659
- // That is the reason for the `&& !state.isLoading` check above.
660
- // TODO should we just treat this as refreshing?
661
- this.isRefreshing = false;
662
- this.maybeUpdate('policy', true);
663
- } else {
664
- this.isRefreshing = true;
665
- }
666
- }
667
- }
668
- });
669
- }
670
- }
671
- removeSubscriptions() {
672
- if (this._subscription) {
673
- this.store.notifications.unsubscribe(this._subscription);
674
- this._subscribedTo = null;
675
- this._subscription = null;
676
- }
677
- }
678
- /**
679
- * Install the event listeners for network and visibility changes.
680
- * This is only done in browser environments with a global `window`.
681
- *
682
- * @internal
683
- */
684
- installListeners() {
685
- if (typeof window === 'undefined') {
686
- return;
687
- }
688
- this.isOnline = window.navigator.onLine;
689
- this.unavailableStart = this.isOnline ? null : Date.now();
690
- this.isHidden = document.visibilityState === 'hidden';
691
- this.onlineChanged = event => {
692
- this.isOnline = event.type === 'online';
693
- if (event.type === 'offline' && this.unavailableStart === null) {
694
- this.unavailableStart = Date.now();
695
- }
696
- this.maybeUpdate();
697
- };
698
- this.backgroundChanged = () => {
699
- const isHidden = document.visibilityState === 'hidden';
700
- this.isHidden = isHidden;
701
- if (isHidden && this.unavailableStart === null) {
702
- this.unavailableStart = Date.now();
703
- }
704
- this.maybeUpdate();
705
- };
706
- window.addEventListener('online', this.onlineChanged, {
707
- passive: true,
708
- capture: true
709
- });
710
- window.addEventListener('offline', this.onlineChanged, {
711
- passive: true,
712
- capture: true
713
- });
714
- document.addEventListener('visibilitychange', this.backgroundChanged, {
715
- passive: true,
716
- capture: true
717
- });
718
- }
719
- /**
720
- * If the network is online and the tab is visible, either reload or refresh the request
721
- * based on the component's configuration and the requested update mode.
722
- *
723
- * Valid modes are:
724
- *
725
- * - `'reload'`: Force a reload of the request.
726
- * - `'refresh'`: Refresh the request in the background.
727
- * - `'policy'`: Make the request, letting the store's configured CachePolicy decide whether to reload, refresh, or do nothing.
728
- * - `undefined`: Make the request using the component's autorefreshBehavior setting if the autorefreshThreshold has passed.
729
- *
730
- * @internal
731
- */
732
- maybeUpdate(mode, silent) {
733
- if (this.isIdle) {
734
- return;
735
- }
736
- const canAttempt = Boolean(this.isOnline && !this.isHidden && (mode || this.autorefreshTypes.size));
737
- if (!canAttempt) {
738
- if (!silent && mode && mode !== 'invalidated') {
739
- throw new Error(`Reload not available: the network is not online or the tab is hidden`);
740
- }
741
- return;
742
- }
743
- const {
744
- autorefreshTypes
745
- } = this;
746
- let shouldAttempt = this.invalidated || Boolean(mode);
747
- if (!shouldAttempt && autorefreshTypes.has('online')) {
748
- const {
749
- unavailableStart
750
- } = this;
751
- const {
752
- autorefreshThreshold
753
- } = this.args;
754
- const deadline = typeof autorefreshThreshold === 'number' ? autorefreshThreshold : DEFAULT_DEADLINE;
755
- shouldAttempt = Boolean(unavailableStart && Date.now() - unavailableStart > deadline);
756
- }
757
- if (!shouldAttempt && autorefreshTypes.has('interval')) {
758
- const {
759
- intervalStart
760
- } = this;
761
- const {
762
- autorefreshThreshold
763
- } = this.args;
764
- if (intervalStart && typeof autorefreshThreshold === 'number' && autorefreshThreshold > 0) {
765
- shouldAttempt = Boolean(Date.now() - intervalStart >= autorefreshThreshold);
766
- }
767
- }
768
- this.unavailableStart = null;
769
- this.invalidated = false;
770
- if (shouldAttempt) {
771
- this.clearInterval();
772
- const request = Object.assign({}, this.reqState.request);
773
- const realMode = mode === 'invalidated' ? null : mode;
774
- const val = realMode ?? this.args.autorefreshBehavior ?? 'policy';
775
- switch (val) {
776
- case 'reload':
777
- request.cacheOptions = Object.assign({}, request.cacheOptions, {
778
- reload: true
779
- });
780
- break;
781
- case 'refresh':
782
- request.cacheOptions = Object.assign({}, request.cacheOptions, {
783
- backgroundReload: true
784
- });
785
- break;
786
- case 'policy':
787
- break;
788
- default:
789
- throw new Error(`Invalid ${mode ? 'update mode' : '@autorefreshBehavior'} for <Request />: ${isNeverString(val)}`);
790
- }
791
- const wasStoreRequest = request[EnableHydration] === true;
792
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
793
- if (!test) {
794
- throw new Error(`Cannot supply a different store via context than was used to create the request`);
795
- }
796
- })(!request.store || request.store === this.store) : {};
797
- this.isUpdating = true;
798
- this._latestRequest = wasStoreRequest ? this.store.request(request) : this.store.requestManager.request(request);
799
- if (val !== 'refresh') {
800
- this._localRequest = this._latestRequest;
801
- }
802
- void this.scheduleInterval();
803
- void this._latestRequest.finally(() => {
804
- this.isUpdating = false;
805
- });
806
- }
807
- }
808
- /**
809
- * Retry the request, reloading it from the server.
810
- *
811
- * @internal
812
- */
813
- retry = async () => {
814
- this.maybeUpdate('reload');
815
- await this._localRequest;
816
- };
817
- /**
818
- * Refresh the request, updating it in the background.
819
- *
820
- * @internal
821
- */
822
- refresh = async () => {
823
- this.maybeUpdate('refresh');
824
- await this._latestRequest;
825
- };
826
- get errorFeatures() {
827
- return {
828
- isHidden: this.isHidden,
829
- isOnline: this.isOnline,
830
- retry: this.retry
831
- };
832
- }
833
- static {
834
- decorateMethodV2(this.prototype, "errorFeatures", [cached]);
835
- }
836
- get contentFeatures() {
837
- const feat = {
838
- isHidden: this.isHidden,
839
- isOnline: this.isOnline,
840
- reload: this.retry,
841
- refresh: this.refresh,
842
- isRefreshing: this.isRefreshing,
843
- latestRequest: this._latestRequest
844
- };
845
- if (feat.isRefreshing) {
846
- feat.abort = () => {
847
- this._latestRequest?.abort();
848
- };
849
- }
850
- return feat;
851
- }
852
- static {
853
- decorateMethodV2(this.prototype, "contentFeatures", [cached]);
854
- }
855
- willDestroy() {
856
- this.removeSubscriptions();
857
- if (typeof window === 'undefined') {
858
- return;
859
- }
860
- this.clearInterval();
861
- window.removeEventListener('online', this.onlineChanged, {
862
- passive: true,
863
- capture: true
864
- });
865
- window.removeEventListener('offline', this.onlineChanged, {
866
- passive: true,
867
- capture: true
868
- });
869
- document.removeEventListener('visibilitychange', this.backgroundChanged, {
870
- passive: true,
871
- capture: true
872
- });
873
- }
874
- get _request() {
875
- const {
876
- request,
877
- query
878
- } = this.args;
879
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
880
- if (!test) {
881
- throw new Error(`Cannot use both @request and @query args with the <Request> component`);
882
- }
883
- })(!request || !query) : {};
884
- const {
885
- _localRequest,
886
- _originalRequest,
887
- _originalQuery
888
- } = this;
889
- const isOriginalRequest = request === _originalRequest && query === _originalQuery;
890
- if (_localRequest && isOriginalRequest) {
891
- return _localRequest;
892
- }
893
- // update state checks for the next time
894
- this._originalQuery = query;
895
- this._originalRequest = request;
896
- if (request) {
897
- return request;
898
- }
899
- macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
900
- if (!test) {
901
- throw new Error(`You must provide either @request or an @query arg with the <Request> component`);
902
- }
903
- })(query) : {};
904
- return this.store.request(query);
905
- }
906
- static {
907
- decorateMethodV2(this.prototype, "_request", [cached]);
908
- }
909
- get request() {
910
- const request = this._request;
911
- this.updateSubscriptions();
912
- return request;
913
- }
914
- static {
915
- decorateMethodV2(this.prototype, "request", [cached]);
916
- }
917
389
  get store() {
918
390
  const store = this.args.store || this._store;
919
391
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
@@ -923,14 +395,29 @@ class Request extends Component {
923
395
  })(store) : {};
924
396
  return store;
925
397
  }
926
- get reqState() {
927
- return getRequestState(this.request);
398
+ _state = null;
399
+ get state() {
400
+ let {
401
+ _state
402
+ } = this;
403
+ const {
404
+ store
405
+ } = this;
406
+ if (_state && _state.store !== store) {
407
+ _state[DISPOSE]();
408
+ _state = null;
409
+ }
410
+ if (!_state) {
411
+ this._state = _state = createRequestSubscription(store, this.args);
412
+ }
413
+ return _state;
928
414
  }
929
- get result() {
930
- return this.reqState.result;
415
+ willDestroy() {
416
+ this._state[DISPOSE]();
417
+ this._state = null;
931
418
  }
932
419
  static {
933
- setComponentTemplate(precompileTemplate("\n {{#if (and this.isIdle (has-block \"idle\"))}}\n {{yield to=\"idle\"}}\n {{else if this.isIdle}}\n <Throw @error={{IdleBlockMissingError}} />\n {{else 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 ", {
420
+ setComponentTemplate(precompileTemplate("\n {{#if (and this.state.isIdle (has-block \"idle\"))}}\n {{yield to=\"idle\"}}\n\n {{else if this.state.isIdle}}\n <Throw @error={{IdleBlockMissingError}} />\n\n {{else if this.state.reqState.isLoading}}\n {{yield this.state.reqState.loadingState to=\"loading\"}}\n\n {{else if (and this.state.reqState.isCancelled (has-block \"cancelled\"))}}\n {{yield (notNull this.state.reqState.reason) this.state.errorFeatures to=\"cancelled\"}}\n\n {{else if (and this.state.reqState.isError (has-block \"error\"))}}\n {{yield (notNull this.state.reqState.reason) this.state.errorFeatures to=\"error\"}}\n\n {{else if this.state.reqState.isSuccess}}\n {{yield this.state.result this.state.contentFeatures to=\"content\"}}\n\n {{else if (not this.state.reqState.isCancelled)}}\n <Throw @error={{(notNull this.state.reqState.reason)}} />\n {{/if}}\n\n {{yield this.state.reqState to=\"always\"}}\n ", {
934
421
  strictMode: true,
935
422
  scope: () => ({
936
423
  and,
@@ -942,4 +429,5 @@ class Request extends Component {
942
429
  }), this);
943
430
  }
944
431
  }
945
- export { Await, Request, Throw };
432
+
433
+ export { Await, Request, Throw };
package/dist/install.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { tagForProperty } from '@ember/-internals/metal';
2
2
  import { _backburner } from '@ember/runloop';
3
3
  import { createCache, track, updateTag, consumeTag, getValue, dirtyTag } from '@glimmer/validator';
4
- import { setupSignals } from '@ember-data/store/configure';
5
- import { macroCondition, getGlobalConfig } from '@embroider/macros';
4
+ import { macroCondition, getGlobalConfig, importSync } from '@embroider/macros';
5
+ import { setupSignals } from '@warp-drive/core/configure';
6
+
6
7
  const emberDirtyTag = dirtyTag;
7
8
  function buildSignalConfig(options) {
8
9
  const ARRAY_SIGNAL = options.wellknown.Array;
@@ -59,8 +60,18 @@ function buildSignalConfig(options) {
59
60
  willSyncFlushWatchers: () => {
60
61
  //@ts-expect-error
61
62
  return !!_backburner.currentInstance && _backburner._autorun !== true;
63
+ },
64
+ waitFor: async promise => {
65
+ if (macroCondition(getGlobalConfig().WarpDrive.env.TESTING)) {
66
+ const {
67
+ waitForPromise
68
+ } = importSync('@ember/test-waiters');
69
+ return waitForPromise(promise);
70
+ }
71
+ return promise;
62
72
  }
63
73
  };
64
74
  }
65
75
  setupSignals(buildSignalConfig);
66
- export { buildSignalConfig };
76
+
77
+ export { buildSignalConfig };