@warp-drive-mirror/ember 5.5.0-alpha.19 → 5.5.0-alpha.20

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,675 +1,12 @@
1
- import { tracked, cached } from '@glimmer/tracking';
2
- import { getPromiseResult, setPromiseResult } from '@ember-data-mirror/request';
3
1
  import { service } from '@ember/service';
4
2
  import Component from '@glimmer/component';
3
+ import { tracked, cached } from '@glimmer/tracking';
5
4
  import { macroCondition, moduleExists, importSync, getGlobalConfig } from '@embroider/macros';
5
+ import { getPromiseState, getRequestState } from '@ember-data-mirror/store/-private';
6
+ export { getPromiseState, getRequestState } from '@ember-data-mirror/store/-private';
6
7
  import { EnableHydration } from '@warp-drive-mirror/core-types/request';
7
8
  import { precompileTemplate } from '@ember/template-compilation';
8
9
  import { setComponentTemplate } from '@ember/component';
9
- const deferred = /* @__PURE__ */new WeakMap();
10
- function deferDecorator(proto, prop, desc) {
11
- let map = deferred.get(proto);
12
- if (!map) {
13
- map = /* @__PURE__ */new Map();
14
- deferred.set(proto, map);
15
- }
16
- map.set(prop, desc);
17
- }
18
- function findDeferredDecorator(target, prop) {
19
- var _a;
20
- let cursor = target.prototype;
21
- while (cursor) {
22
- let desc = (_a = deferred.get(cursor)) == null ? void 0 : _a.get(prop);
23
- if (desc) {
24
- return desc;
25
- }
26
- cursor = cursor.prototype;
27
- }
28
- }
29
- function decorateFieldV2(prototype, prop, decorators, initializer) {
30
- let desc = {
31
- configurable: true,
32
- enumerable: true,
33
- writable: true,
34
- initializer: null
35
- };
36
- if (initializer) {
37
- desc.initializer = initializer;
38
- }
39
- for (let decorator of decorators) {
40
- desc = decorator(prototype, prop, desc) || desc;
41
- }
42
- if (desc.initializer === void 0) {
43
- Object.defineProperty(prototype, prop, desc);
44
- } else {
45
- deferDecorator(prototype, prop, desc);
46
- }
47
- }
48
- function decorateMethodV2(prototype, prop, decorators) {
49
- const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
50
- let desc = {
51
- ...origDesc
52
- };
53
- for (let decorator of decorators) {
54
- desc = decorator(prototype, prop, desc) || desc;
55
- }
56
- if (desc.initializer !== void 0) {
57
- desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
58
- desc.initializer = void 0;
59
- }
60
- Object.defineProperty(prototype, prop, desc);
61
- }
62
- function initializeDeferredDecorator(target, prop) {
63
- let desc = findDeferredDecorator(target.constructor, prop);
64
- if (desc) {
65
- Object.defineProperty(target, prop, {
66
- enumerable: desc.enumerable,
67
- configurable: desc.configurable,
68
- writable: desc.writable,
69
- value: desc.initializer ? desc.initializer.call(target) : void 0
70
- });
71
- }
72
- }
73
-
74
- /**
75
- * @module @warp-drive-mirror/ember
76
- */
77
- const RequestCache = new WeakMap();
78
- function isAbortError(error) {
79
- return error instanceof DOMException && error.name === 'AbortError';
80
- }
81
- async function watchStream(stream, state) {
82
- const reader = stream.getReader();
83
- let bytesLoaded = 0;
84
- let shouldForward = state._stream !== null && state._stream.readable.locked;
85
- let isForwarding = shouldForward;
86
- let writer = state._stream?.writable.getWriter();
87
- const buffer = [];
88
- state._isPending = false;
89
- state._isStarted = true;
90
- state._startTime = performance.now();
91
- while (true) {
92
- const {
93
- value,
94
- done
95
- } = await reader.read();
96
- if (done) {
97
- break;
98
- }
99
- bytesLoaded += value.byteLength;
100
- state._bytesLoaded = bytesLoaded;
101
- state._lastPacketTime = performance.now();
102
- shouldForward = shouldForward || state._stream !== null && state._stream.readable.locked;
103
- if (shouldForward) {
104
- if (!isForwarding) {
105
- isForwarding = true;
106
- writer = state._stream.writable.getWriter();
107
- for (const item of buffer) {
108
- await writer.ready;
109
- await writer.write(item);
110
- }
111
- buffer.length = 0;
112
- }
113
- await writer.ready;
114
- await writer.write(value);
115
- } else {
116
- buffer.push(value);
117
- }
118
- }
119
-
120
- // if we are still forwarding, we need to close the writer
121
- if (isForwarding) {
122
- await writer.ready;
123
- await writer.close();
124
- } else if (state._stream) {
125
- // if we are not forwarding, we need to cancel the stream
126
- await state._stream.readable.cancel('The Stream Has Already Ended');
127
- state._stream = null;
128
- }
129
- const endTime = performance.now();
130
- state._endTime = endTime;
131
- state._isComplete = true;
132
- state._isStarted = false;
133
- }
134
-
135
- /**
136
- * Lazily consumes the stream of a request, providing a number of
137
- * reactive properties that can be used to build UIs that respond
138
- * to the progress of a request.
139
- *
140
- * @class RequestLoadingState
141
- * @public
142
- */
143
- class RequestLoadingState {
144
- _stream = null;
145
- _future;
146
- _triggered = false;
147
- _trigger() {
148
- if (this._triggered) {
149
- return;
150
- }
151
- this._triggered = true;
152
- const future = this._future;
153
- const promise = future.getStream();
154
- if (promise.sizeHint) {
155
- this._sizeHint = promise.sizeHint;
156
- }
157
- this.promise = promise.then(stream => {
158
- if (!stream) {
159
- this._isPending = false;
160
- this._isComplete = true;
161
- return;
162
- }
163
- return watchStream(stream, this);
164
- }, error => {
165
- this._isPending = false;
166
- this._isStarted = false;
167
- if (isAbortError(error)) {
168
- this._isCancelled = true;
169
- this._isComplete = true;
170
- }
171
- this._isErrored = true;
172
- this._error = error;
173
- });
174
- }
175
- promise = null;
176
- static {
177
- decorateFieldV2(this.prototype, "_sizeHint", [tracked], function () {
178
- return 0;
179
- });
180
- }
181
- #_sizeHint = (initializeDeferredDecorator(this, "_sizeHint"), void 0);
182
- static {
183
- decorateFieldV2(this.prototype, "_bytesLoaded", [tracked], function () {
184
- return 0;
185
- });
186
- }
187
- #_bytesLoaded = (initializeDeferredDecorator(this, "_bytesLoaded"), void 0);
188
- static {
189
- decorateFieldV2(this.prototype, "_startTime", [tracked], function () {
190
- return 0;
191
- });
192
- }
193
- #_startTime = (initializeDeferredDecorator(this, "_startTime"), void 0);
194
- static {
195
- decorateFieldV2(this.prototype, "_endTime", [tracked], function () {
196
- return 0;
197
- });
198
- }
199
- #_endTime = (initializeDeferredDecorator(this, "_endTime"), void 0);
200
- static {
201
- decorateFieldV2(this.prototype, "_lastPacketTime", [tracked], function () {
202
- return 0;
203
- });
204
- }
205
- #_lastPacketTime = (initializeDeferredDecorator(this, "_lastPacketTime"), void 0);
206
- static {
207
- decorateFieldV2(this.prototype, "_isPending", [tracked], function () {
208
- return true;
209
- });
210
- }
211
- #_isPending = (initializeDeferredDecorator(this, "_isPending"), void 0);
212
- static {
213
- decorateFieldV2(this.prototype, "_isStarted", [tracked], function () {
214
- return false;
215
- });
216
- }
217
- #_isStarted = (initializeDeferredDecorator(this, "_isStarted"), void 0);
218
- static {
219
- decorateFieldV2(this.prototype, "_isComplete", [tracked], function () {
220
- return false;
221
- });
222
- }
223
- #_isComplete = (initializeDeferredDecorator(this, "_isComplete"), void 0);
224
- static {
225
- decorateFieldV2(this.prototype, "_isCancelled", [tracked], function () {
226
- return false;
227
- });
228
- }
229
- #_isCancelled = (initializeDeferredDecorator(this, "_isCancelled"), void 0);
230
- static {
231
- decorateFieldV2(this.prototype, "_isErrored", [tracked], function () {
232
- return false;
233
- });
234
- }
235
- #_isErrored = (initializeDeferredDecorator(this, "_isErrored"), void 0);
236
- static {
237
- decorateFieldV2(this.prototype, "_error", [tracked], function () {
238
- return null;
239
- });
240
- }
241
- #_error = (initializeDeferredDecorator(this, "_error"), void 0);
242
- get isPending() {
243
- this._trigger();
244
- return this._isPending;
245
- }
246
- get sizeHint() {
247
- this._trigger();
248
- return this._sizeHint;
249
- }
250
- get stream() {
251
- this._trigger();
252
- if (!this._stream) {
253
- if (this._isComplete || this._isCancelled || this._isErrored) {
254
- return null;
255
- }
256
- this._stream = new TransformStream();
257
- }
258
- return this._stream.readable;
259
- }
260
- get isStarted() {
261
- this._trigger();
262
- return this._isStarted;
263
- }
264
- get bytesLoaded() {
265
- this._trigger();
266
- return this._bytesLoaded;
267
- }
268
- get startTime() {
269
- this._trigger();
270
- return this._startTime;
271
- }
272
- get endTime() {
273
- this._trigger();
274
- return this._endTime;
275
- }
276
- get lastPacketTime() {
277
- this._trigger();
278
- return this._lastPacketTime;
279
- }
280
- get isComplete() {
281
- this._trigger();
282
- return this._isComplete;
283
- }
284
- get isCancelled() {
285
- this._trigger();
286
- return this._isCancelled;
287
- }
288
- get isErrored() {
289
- this._trigger();
290
- return this._isErrored;
291
- }
292
- get error() {
293
- this._trigger();
294
- return this._error;
295
- }
296
- get elapsedTime() {
297
- return (this.endTime || this.lastPacketTime) - this.startTime;
298
- }
299
- get completedRatio() {
300
- return this.sizeHint ? this.bytesLoaded / this.sizeHint : 0;
301
- }
302
- get remainingRatio() {
303
- return 1 - this.completedRatio;
304
- }
305
- get duration() {
306
- return this.endTime - this.startTime;
307
- }
308
- get speed() {
309
- // bytes per second
310
- return this.bytesLoaded / (this.elapsedTime / 1000);
311
- }
312
- constructor(future) {
313
- this._future = future;
314
- }
315
- abort = () => {
316
- this._future.abort();
317
- };
318
- }
319
-
320
- /**
321
- * RequestState extends the concept of PromiseState to provide a reactive
322
- * wrapper for a request `Future` which allows you write declarative code
323
- * around a Future's control flow.
324
- *
325
- * It is useful in both Template and JavaScript contexts, allowing you
326
- * to quickly derive behaviors and data from pending, error and success
327
- * states.
328
- *
329
- * The key difference between a Promise and a Future is that Futures provide
330
- * access to a stream of their content, the identity of the request (if any)
331
- * as well as the ability to attempt to abort the request.
332
- *
333
- * ```ts
334
- * interface Future<T> extends Promise<T>> {
335
- * getStream(): Promise<ReadableStream>;
336
- * abort(): void;
337
- * lid: StableDocumentIdentifier | null;
338
- * }
339
- * ```
340
- *
341
- * These additional APIs allow us to craft even richer state experiences.
342
- *
343
- * To get the state of a request, use `getRequestState`.
344
- *
345
- * @class RequestState
346
- * @public
347
- */
348
- class RequestState {
349
- #request;
350
- #loadingState = null;
351
- static {
352
- decorateFieldV2(this.prototype, "result", [tracked], function () {
353
- return null;
354
- });
355
- }
356
- #result = (initializeDeferredDecorator(this, "result"), void 0);
357
- static {
358
- decorateFieldV2(this.prototype, "error", [tracked], function () {
359
- return null;
360
- });
361
- }
362
- #error = (initializeDeferredDecorator(this, "error"), void 0);
363
- static {
364
- decorateFieldV2(this.prototype, "isLoading", [tracked], function () {
365
- return true;
366
- });
367
- }
368
- #isLoading = (initializeDeferredDecorator(this, "isLoading"), void 0);
369
- static {
370
- decorateFieldV2(this.prototype, "isSuccess", [tracked], function () {
371
- return false;
372
- });
373
- }
374
- #isSuccess = (initializeDeferredDecorator(this, "isSuccess"), void 0);
375
- static {
376
- decorateFieldV2(this.prototype, "isError", [tracked], function () {
377
- return false;
378
- });
379
- }
380
- #isError = (initializeDeferredDecorator(this, "isError"), void 0);
381
- static {
382
- decorateFieldV2(this.prototype, "request", [tracked], function () {
383
- return null;
384
- });
385
- }
386
- #request_ = (initializeDeferredDecorator(this, "request"), void 0);
387
- static {
388
- decorateFieldV2(this.prototype, "response", [tracked], function () {
389
- return null;
390
- });
391
- }
392
- #response = (initializeDeferredDecorator(this, "response"), void 0);
393
- get isCancelled() {
394
- return this.isError && isAbortError(this.error);
395
- }
396
- get loadingState() {
397
- if (!this.#loadingState) {
398
- this.#loadingState = new RequestLoadingState(this.#request);
399
- }
400
- return this.#loadingState;
401
- }
402
- constructor(future) {
403
- this.#request = future;
404
- const state = getPromiseResult(future);
405
- if (state) {
406
- this.request = state.result.request;
407
- this.response = state.result.response;
408
- this.isLoading = false;
409
- if (state.isError) {
410
- this.error = state.result;
411
- this.isError = true;
412
- } else {
413
- this.result = state.result.content;
414
- this.isSuccess = true;
415
- }
416
- } else {
417
- void future.then(result => {
418
- setPromiseResult(future, {
419
- isError: false,
420
- result
421
- });
422
- this.result = result.content;
423
- this.isSuccess = true;
424
- this.isLoading = false;
425
- this.request = result.request;
426
- this.response = result.response;
427
- }, error => {
428
- setPromiseResult(future, {
429
- isError: true,
430
- result: error
431
- });
432
- this.error = error;
433
- this.isError = true;
434
- this.isLoading = false;
435
- this.request = error.request;
436
- this.response = error.response;
437
- });
438
- }
439
- }
440
- }
441
-
442
- /**
443
- *
444
- *
445
- * `getRequestState` can be used in both JavaScript and Template contexts.
446
- *
447
- * ```ts
448
- * import { getRequestState } from '@warp-drive-mirror/ember';
449
- *
450
- * const state = getRequestState(future);
451
- * ```
452
- *
453
- * For instance, we could write a getter on a component that updates whenever
454
- * the request state advances or the future changes, by combining the function
455
- * with the use of `@cached`
456
- *
457
- * ```ts
458
- * class Component {
459
- * @cached
460
- * get title() {
461
- * const state = getRequestState(this.args.request);
462
- * if (state.isPending) {
463
- * return 'loading...';
464
- * }
465
- * if (state.isError) { return null; }
466
- * return state.result.title;
467
- * }
468
- * }
469
- * ```
470
- *
471
- * Or in a template as a helper:
472
- *
473
- * ```gjs
474
- * import { getRequestState } from '@warp-drive-mirror/ember';
475
- *
476
- * <template>
477
- * {{#let (getRequestState @request) as |state|}}
478
- * {{#if state.isPending}}
479
- * <Spinner />
480
- * {{else if state.isError}}
481
- * <ErrorForm @error={{state.error}} />
482
- * {{else}}
483
- * <h1>{{state.result.title}}</h1>
484
- * {{/if}}
485
- * {{/let}}
486
- * </template>
487
- * ```
488
- *
489
- * If looking to use in a template, consider also the `<Request />` component
490
- * which offers a numbe of additional capabilities for requests *beyond* what
491
- * `RequestState` provides.
492
- *
493
- * @method getRequestState
494
- * @for @warp-drive-mirror/ember
495
- * @static
496
- * @public
497
- * @param future
498
- * @return {RequestState}
499
- */
500
- function getRequestState(future) {
501
- let state = RequestCache.get(future);
502
- if (!state) {
503
- state = new RequestState(future);
504
- RequestCache.set(future, state);
505
- }
506
- return state;
507
- }
508
-
509
- /**
510
- * @module @warp-drive-mirror/ember
511
- */
512
- const PromiseCache = new WeakMap();
513
-
514
- /**
515
- * PromiseState provides a reactive wrapper for a promise which allows you write declarative
516
- * code around a promise's control flow. It is useful in both Template and JavaScript contexts,
517
- * allowing you to quickly derive behaviors and data from pending, error and success states.
518
- *
519
- * ```ts
520
- * interface PromiseState<T = unknown, E = unknown> {
521
- * isPending: boolean;
522
- * isSuccess: boolean;
523
- * isError: boolean;
524
- * result: T | null;
525
- * error: E | null;
526
- * }
527
- * ```
528
- *
529
- * To get the state of a promise, use `getPromiseState`.
530
- *
531
- * @class PromiseState
532
- * @public
533
- */
534
- class PromiseState {
535
- static {
536
- decorateFieldV2(this.prototype, "result", [tracked], function () {
537
- return null;
538
- });
539
- }
540
- #result = (initializeDeferredDecorator(this, "result"), void 0);
541
- static {
542
- decorateFieldV2(this.prototype, "error", [tracked], function () {
543
- return null;
544
- });
545
- }
546
- #error = (initializeDeferredDecorator(this, "error"), void 0);
547
- static {
548
- decorateFieldV2(this.prototype, "isPending", [tracked], function () {
549
- return true;
550
- });
551
- }
552
- #isPending = (initializeDeferredDecorator(this, "isPending"), void 0);
553
- static {
554
- decorateFieldV2(this.prototype, "isSuccess", [tracked], function () {
555
- return false;
556
- });
557
- }
558
- #isSuccess = (initializeDeferredDecorator(this, "isSuccess"), void 0);
559
- static {
560
- decorateFieldV2(this.prototype, "isError", [tracked], function () {
561
- return false;
562
- });
563
- }
564
- #isError = (initializeDeferredDecorator(this, "isError"), void 0);
565
- constructor(promise) {
566
- const state = getPromiseResult(promise);
567
- if (state) {
568
- if (state.isError) {
569
- this.error = state.result;
570
- this.isError = true;
571
- this.isPending = false;
572
- } else {
573
- this.result = state.result;
574
- this.isSuccess = true;
575
- this.isPending = false;
576
- }
577
- } else {
578
- void promise.then(result => {
579
- setPromiseResult(promise, {
580
- isError: false,
581
- result
582
- });
583
- this.result = result;
584
- this.isSuccess = true;
585
- this.isPending = false;
586
- }, error => {
587
- setPromiseResult(promise, {
588
- isError: true,
589
- result: error
590
- });
591
- this.error = error;
592
- this.isError = true;
593
- this.isPending = false;
594
- });
595
- }
596
- }
597
- }
598
- const LegacyPromiseProxy = Symbol.for('LegacyPromiseProxy');
599
- function isLegacyAwaitable(promise) {
600
- return LegacyPromiseProxy in promise && 'promise' in promise && promise[LegacyPromiseProxy] === true;
601
- }
602
- function getPromise(promise) {
603
- return isLegacyAwaitable(promise) ? promise.promise : promise;
604
- }
605
-
606
- /**
607
- * Returns a reactive state-machine for the provided promise or awaitable.
608
- *
609
- * Repeat calls to `getPromiseState` with the same promise will return the same state object
610
- * making is safe and easy to use in templates and JavaScript code to produce reactive
611
- * behaviors around promises.
612
- *
613
- * `getPromiseState` can be used in both JavaScript and Template contexts.
614
- *
615
- * ```ts
616
- * import { getPromiseState } from '@warp-drive-mirror/ember';
617
- *
618
- * const state = getPromiseState(promise);
619
- * ```
620
- *
621
- * For instance, we could write a getter on a component that updates whenever
622
- * the promise state advances or the promise changes, by combining the function
623
- * with the use of `@cached`
624
- *
625
- * ```ts
626
- * class Component {
627
- * @cached
628
- * get title() {
629
- * const state = getPromiseState(this.args.request);
630
- * if (state.isPending) {
631
- * return 'loading...';
632
- * }
633
- * if (state.isError) { return null; }
634
- * return state.result.title;
635
- * }
636
- * }
637
- * ```
638
- *
639
- * Or in a template as a helper:
640
- *
641
- * ```gjs
642
- * import { getPromiseState } from '@warp-drive-mirror/ember';
643
- *
644
- * <template>
645
- * {{#let (getPromiseState @request) as |state|}}
646
- * {{#if state.isPending}} <Spinner />
647
- * {{else if state.isError}} <ErrorForm @error={{state.error}} />
648
- * {{else}}
649
- * <h1>{{state.result.title}}</h1>
650
- * {{/if}}
651
- * {{/let}}
652
- * </template>
653
- * ```
654
- *
655
- * If looking to use in a template, consider also the `<Await />` component.
656
- *
657
- * @method getPromiseState
658
- * @for @warp-drive-mirror/ember
659
- * @static
660
- * @public
661
- * @param {Promise<T> | Awaitable<T, E>} promise
662
- * @return {PromiseState<T, E>}
663
- */
664
- function getPromiseState(promise) {
665
- const _promise = getPromise(promise);
666
- let state = PromiseCache.get(_promise);
667
- if (!state) {
668
- state = new PromiseState(_promise);
669
- PromiseCache.set(_promise, state);
670
- }
671
- return state;
672
- }
673
10
 
674
11
  /**
675
12
  * @module @warp-drive-mirror/ember
@@ -758,6 +95,70 @@ class Await extends Component {
758
95
  }), this);
759
96
  }
760
97
  }
98
+ const deferred = /* @__PURE__ */new WeakMap();
99
+ function deferDecorator(proto, prop, desc) {
100
+ let map = deferred.get(proto);
101
+ if (!map) {
102
+ map = /* @__PURE__ */new Map();
103
+ deferred.set(proto, map);
104
+ }
105
+ map.set(prop, desc);
106
+ }
107
+ function findDeferredDecorator(target, prop) {
108
+ var _a;
109
+ let cursor = target.prototype;
110
+ while (cursor) {
111
+ let desc = (_a = deferred.get(cursor)) == null ? void 0 : _a.get(prop);
112
+ if (desc) {
113
+ return desc;
114
+ }
115
+ cursor = cursor.prototype;
116
+ }
117
+ }
118
+ function decorateFieldV2(prototype, prop, decorators, initializer) {
119
+ let desc = {
120
+ configurable: true,
121
+ enumerable: true,
122
+ writable: true,
123
+ initializer: null
124
+ };
125
+ if (initializer) {
126
+ desc.initializer = initializer;
127
+ }
128
+ for (let decorator of decorators) {
129
+ desc = decorator(prototype, prop, desc) || desc;
130
+ }
131
+ if (desc.initializer === void 0) {
132
+ Object.defineProperty(prototype, prop, desc);
133
+ } else {
134
+ deferDecorator(prototype, prop, desc);
135
+ }
136
+ }
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
+ function initializeDeferredDecorator(target, prop) {
152
+ let desc = findDeferredDecorator(target.constructor, prop);
153
+ if (desc) {
154
+ Object.defineProperty(target, prop, {
155
+ enumerable: desc.enumerable,
156
+ configurable: desc.configurable,
157
+ writable: desc.writable,
158
+ value: desc.initializer ? desc.initializer.call(target) : void 0
159
+ });
160
+ }
161
+ }
761
162
 
762
163
  /**
763
164
  * @module @warp-drive-mirror/ember
@@ -1560,4 +961,4 @@ class Request extends Component {
1560
961
  }), this);
1561
962
  }
1562
963
  }
1563
- export { Await, Request, Throw, getPromiseState, getRequestState };
964
+ export { Await, Request, Throw };