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