@warp-drive/core 5.8.0-alpha.40 → 5.8.0-alpha.42

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.
Files changed (95) hide show
  1. package/declarations/configure.d.ts +1 -1
  2. package/declarations/reactive/-private/default-mode.d.ts +1 -1
  3. package/declarations/reactive/-private/fields/extension.d.ts +1 -1
  4. package/declarations/reactive/-private/fields/managed-array.d.ts +2 -2
  5. package/declarations/reactive/-private/fields/managed-object.d.ts +1 -1
  6. package/declarations/reactive.d.ts +2 -3
  7. package/declarations/signals/-leaked.d.ts +2 -0
  8. package/declarations/signals/-private.d.ts +6 -0
  9. package/declarations/{store/-private/new-core-tmp → signals}/promise-state.d.ts +1 -1
  10. package/declarations/{store/-private/new-core-tmp → signals}/request-state.d.ts +5 -5
  11. package/declarations/{store/-private/new-core-tmp → signals}/request-subscription.d.ts +4 -4
  12. package/declarations/store/-private/cache-handler/types.d.ts +2 -16
  13. package/declarations/store/-private/managers/cache-manager.d.ts +1 -14
  14. package/declarations/store/-private/record-arrays/legacy-many-array.d.ts +1 -1
  15. package/declarations/store/-private/record-arrays/resource-array.d.ts +1 -1
  16. package/declarations/store/-private.d.ts +0 -5
  17. package/declarations/store/deprecated/-private.d.ts +1 -1
  18. package/declarations/types/schema/fields.d.ts +4 -4
  19. package/dist/configure-DPUFCemT.js +1940 -0
  20. package/dist/configure.js +2 -1
  21. package/dist/{request-oqoLC9rz.js → future-BKkJJkj7.js} +1 -48
  22. package/dist/graph/-private.js +3 -2
  23. package/dist/{index-BKcD4JZK.js → index-CQP2NSqg.js} +58 -1826
  24. package/dist/index.js +5 -5
  25. package/dist/reactive/-private.js +1 -1
  26. package/dist/reactive.js +4 -129
  27. package/dist/request.js +49 -1
  28. package/dist/signals/-leaked.js +1 -0
  29. package/dist/store/-private.js +1 -2
  30. package/dist/types/-private.js +1 -1
  31. package/dist/unpkg/dev/-leaked-Co0EI6Go.js +1939 -0
  32. package/dist/unpkg/dev/configure.js +1 -1
  33. package/dist/unpkg/dev/{request-CA9K0gXq.js → future-DFfOzSoe.js} +1 -48
  34. package/dist/unpkg/dev/graph/-private.js +3 -2
  35. package/dist/unpkg/dev/{index-DqhXrNZ_.js → index-CepUPZlc.js} +57 -1825
  36. package/dist/unpkg/dev/index.js +4 -4
  37. package/dist/unpkg/dev/reactive/-private.js +1 -1
  38. package/dist/unpkg/dev/reactive.js +3 -127
  39. package/dist/unpkg/dev/request.js +49 -1
  40. package/dist/unpkg/dev/signals/-leaked.js +1 -0
  41. package/dist/unpkg/dev/store/-private.js +2 -3
  42. package/dist/unpkg/dev/types/-private.js +1 -1
  43. package/dist/unpkg/dev-deprecated/-leaked-DjMeRqdU.js +1939 -0
  44. package/dist/unpkg/dev-deprecated/configure.js +1 -1
  45. package/dist/unpkg/dev-deprecated/{request-CA9K0gXq.js → future-DFfOzSoe.js} +1 -48
  46. package/dist/unpkg/dev-deprecated/graph/-private.js +3 -2
  47. package/dist/unpkg/dev-deprecated/{index-BBlq5is_.js → index-C_EEmn_3.js} +56 -1824
  48. package/dist/unpkg/dev-deprecated/index.js +2 -2
  49. package/dist/unpkg/dev-deprecated/reactive.js +2 -126
  50. package/dist/unpkg/dev-deprecated/request.js +49 -1
  51. package/dist/unpkg/dev-deprecated/signals/-leaked.js +1 -0
  52. package/dist/unpkg/dev-deprecated/store/-private.js +1 -2
  53. package/dist/unpkg/dev-deprecated/types/-private.js +1 -1
  54. package/dist/unpkg/prod/-leaked-DUONXQDB.js +1676 -0
  55. package/dist/unpkg/prod/{-private-3C1OkYtZ.js → -private-sql1_mdx.js} +1 -1
  56. package/dist/unpkg/prod/configure.js +2 -1
  57. package/dist/unpkg/prod/graph/-private.js +3 -2
  58. package/dist/unpkg/prod/{handler-LAyD1Y5l.js → handler-EU_8ncB2.js} +2 -2
  59. package/dist/unpkg/prod/index.js +7 -5
  60. package/dist/unpkg/prod/promise-cache-DIT8Ypjq.js +19 -0
  61. package/dist/unpkg/prod/reactive/-private.js +1 -1
  62. package/dist/unpkg/prod/reactive.js +26 -123
  63. package/dist/unpkg/prod/{request-CN2LxbYX.js → request-BrJSCG6r.js} +3 -19
  64. package/dist/unpkg/prod/request.js +2 -1
  65. package/dist/unpkg/prod/{promise-state-ipG60SdD.js → schema-BSkHyoWz.js} +53 -1572
  66. package/dist/unpkg/prod/signals/-leaked.js +1 -0
  67. package/dist/unpkg/prod/store/-private.js +3 -4
  68. package/dist/unpkg/prod/types/-private.js +1 -1
  69. package/dist/unpkg/prod-deprecated/-leaked-DRNv9VIX.js +1676 -0
  70. package/dist/unpkg/prod-deprecated/configure.js +2 -1
  71. package/dist/unpkg/prod-deprecated/graph/-private.js +3 -2
  72. package/dist/unpkg/prod-deprecated/{handler-D639oFvl.js → handler-CCIu4sQ3.js} +1 -1
  73. package/dist/unpkg/prod-deprecated/{hooks-DGvi9teJ.js → hooks-Dv4Np0MY.js} +1 -1
  74. package/dist/unpkg/prod-deprecated/index.js +7 -5
  75. package/dist/unpkg/prod-deprecated/promise-cache-DIT8Ypjq.js +19 -0
  76. package/dist/unpkg/prod-deprecated/reactive.js +4 -125
  77. package/dist/unpkg/prod-deprecated/{request-CN2LxbYX.js → request-BrJSCG6r.js} +3 -19
  78. package/dist/unpkg/prod-deprecated/request.js +2 -1
  79. package/dist/unpkg/prod-deprecated/{promise-state-CYvoIPna.js → schema-CJcjHv0E.js} +52 -1571
  80. package/dist/unpkg/prod-deprecated/signals/-leaked.js +1 -0
  81. package/dist/unpkg/prod-deprecated/store/-private.js +2 -3
  82. package/dist/unpkg/prod-deprecated/types/-private.js +1 -1
  83. package/package.json +3 -3
  84. package/declarations/store/-private/new-core-tmp/expensive-subscription.d.ts +0 -24
  85. package/dist/configure-C3x8YXzL.js +0 -181
  86. package/dist/unpkg/dev/configure-BC66sfNO.js +0 -183
  87. package/dist/unpkg/dev-deprecated/configure-BC66sfNO.js +0 -183
  88. package/dist/unpkg/prod/configure-C0C1LpG6.js +0 -158
  89. package/dist/unpkg/prod/hooks-BfiqDg3O.js +0 -26
  90. package/dist/unpkg/prod-deprecated/configure-BQ8CpIcW.js +0 -158
  91. /package/declarations/{store/-private/new-core-tmp → signals}/reactivity/configure.d.ts +0 -0
  92. /package/declarations/{store/-private/new-core-tmp → signals}/reactivity/internal.d.ts +0 -0
  93. /package/declarations/{store/-private/new-core-tmp → signals}/reactivity/signal.d.ts +0 -0
  94. /package/dist/{unpkg/dev/-private-3C1OkYtZ.js → symbols-3C1OkYtZ.js} +0 -0
  95. /package/dist/{symbols-sql1_mdx.js → unpkg/dev/-private-sql1_mdx.js} +0 -0
@@ -1,482 +1,15 @@
1
+ import { D as Destroy, C as Context, S as SOURCE, a as Checkout, b as Commit } from "./-private-sql1_mdx.js";
2
+ import { d as defineGate, w as withSignalStore, n as notifyInternalSignal, p as peekInternalSignal, a as willSyncFlushWatchers, g as getOrCreateInternalSignal, c as consumeInternalSignal, b as createInternalSignal, A as ARRAY_SIGNAL, S as Signals, e as createSignalDescriptor, f as defineSignal, h as entangleSignal, i as entangleInitiallyStaleSignal, O as OBJECT_SIGNAL, j as createInternalMemo, o as waitFor } from "./-leaked-Co0EI6Go.js";
1
3
  import { EnableHydration, SkipCache, STRUCTURED } from './types/request.js';
2
- import { D as Destroy, a as Context, S as SOURCE, C as Checkout, b as Commit } from "./-private-3C1OkYtZ.js";
3
4
  import { isResourceSchema } from './types/schema/fields.js';
5
+ import { a as cloneResponseProperties, I as IS_CACHE_HANDLER, b as assertValidRequest, e as executeNextHandler, d as getRequestResult, u as upgradePromise, s as setPromiseResult, f as clearRequestResult } from "./future-DFfOzSoe.js";
4
6
  import { getOrSetGlobal, setTransient, peekTransient, peekUniversalTransient, setUniversalTransient } from './types/-private.js';
5
- import { w as withBrand, g as getPromiseResult, s as setPromiseResult, c as cloneResponseProperties, I as IS_CACHE_HANDLER, a as assertValidRequest, e as executeNextHandler, b as getRequestResult, u as upgradePromise, d as clearRequestResult } from "./request-CA9K0gXq.js";
6
- import { c as createSignal, a as consumeSignal, n as notifySignal, b as createMemo, d as willSyncFlushWatchers, A as ARRAY_SIGNAL, O as OBJECT_SIGNAL, w as waitFor } from "./configure-BC66sfNO.js";
7
+ import { DefaultCachePolicy } from './store.js';
8
+ import { withBrand } from './request.js';
7
9
  import { CACHE_OWNER, DEBUG_STALE_CACHE_OWNER, DEBUG_KEY_TYPE, DEBUG_CLIENT_ORIGINATED } from './types/identifier.js';
8
10
  import { g as getGlobalConfig } from "./runtime-DGG4CvlW.js";
9
- import { DefaultCachePolicy } from './store.js';
10
11
  import { setLogging, getRuntimeConfig } from './types/runtime.js';
11
12
  import { RecordStore, Type } from './types/symbols.js';
12
- const INITIALIZER_PROTO = {
13
- isInitializer: true
14
- };
15
- function makeInitializer(fn) {
16
- // we use a prototype to ensure that the initializer is not enumerable
17
- // and does not interfere with the signal's value.
18
- return Object.assign(Object.create(INITIALIZER_PROTO), {
19
- value: fn
20
- });
21
- }
22
- function isInitializer(obj) {
23
- return typeof obj === 'object' && obj !== null && Object.getPrototypeOf(obj) === INITIALIZER_PROTO;
24
- }
25
-
26
- /**
27
- * A WarpDriveSignal is a wrapper around a framework specific or TC39 signal
28
- * that enables us to store and manage the signal in a universal way.
29
- *
30
- * WarpDrive uses signals to manage three separate concepts:
31
- *
32
- * - as a `storage` for a value local to the object that we want to be reactive
33
- * (see `@local` schema field for an example)
34
- * - as a `gate` for a memoized getter that we want to act as a reactive property
35
- * but whose value is computed/pulled from a non-reactive source elsewhere
36
- * and whose latest value is stored in the signal
37
- * (see `field` schema field for an example)
38
- * - as a `gate` with a manually managed value updated on pull when `isStale` is true
39
- *
40
- *
41
- * It offers
42
- *
43
- * - a non-reactive way to access/update the current value
44
- * - a non-reactive way to mark the signal as dirtied
45
- * - a non-reactive way to store content for why the signal was dirtied
46
- * - access to the underlying Signal(s) in-use
47
- *
48
- * For debugging:
49
- * - the "key" or "name" of the signal
50
- * - the "object identity" or "context" to which the signal is attached
51
- *
52
- * @private
53
- */
54
-
55
- /**
56
- * We attach signals to their context object via
57
- * a Map attached to the object via this symbol.
58
- *
59
- * This allows us to store multiple signals
60
- * on the same object with smaller memory
61
- * overhead and no WeakMap lookups.
62
- *
63
- * Performance sensitive objects should
64
- * pre-warm their shape by assigning this
65
- * during initialization.
66
- *
67
- * ```ts
68
- * initializeSignalStore(obj);
69
- * ```
70
- *
71
- * @private
72
- */
73
- const Signals = getOrSetGlobal('Signals', Symbol('Signals'));
74
-
75
- /**
76
- * A util that will create a signal store on the object
77
- * if it does not already exist and returns the associated
78
- * signal store.
79
- *
80
- * @private
81
- */
82
- function withSignalStore(obj) {
83
- if (!obj[Signals]) {
84
- initializeSignalStore(obj);
85
- }
86
- return obj[Signals];
87
- }
88
-
89
- /**
90
- * A util that will create a signal store on the object
91
- * if it does not already exist.
92
- *
93
- * Useful for pre-warming the shape of an object to ensure
94
- * a key-transition to add it is not required later.
95
- *
96
- * @private
97
- */
98
- function initializeSignalStore(obj) {
99
- (test => {
100
- if (!test) {
101
- throw new Error(`Signal store already exists on object`);
102
- }
103
- })(!obj[Signals]);
104
- obj[Signals] = new Map();
105
- }
106
- function createInternalSignal(signals, obj, key, initialValue) {
107
- const warpDriveSignal = {
108
- key,
109
- context: obj,
110
- signal: createSignal(obj, key),
111
- value: isInitializer(initialValue) ? initialValue.value.call(obj) : initialValue,
112
- isStale: false
113
- };
114
- signals.set(key, warpDriveSignal);
115
- return warpDriveSignal;
116
- }
117
- function getOrCreateInternalSignal(signals, obj, key, initialValue) {
118
- let signal = peekInternalSignal(signals, key);
119
- if (!signal) {
120
- signal = createInternalSignal(signals, obj, key, initialValue);
121
- }
122
- return signal;
123
- }
124
- function createInternalMemo(signals, object, key, fn) {
125
- (test => {
126
- if (!test) {
127
- throw new Error(`Expected no signal/memo to exist for key "${String(key)}"`);
128
- }
129
- })(!peekInternalSignal(signals, key));
130
- {
131
- return withFrame(signals, object, key, fn);
132
- }
133
- }
134
- function peekInternalSignal(signals, key) {
135
- return signals?.get(key);
136
- }
137
- function consumeInternalSignal(signal) {
138
- TrackingFrame?.signals.add(signal);
139
- consumeSignal(signal.signal);
140
- }
141
- function notifyInternalSignal(signal) {
142
- if (signal) {
143
- signal.isStale = true;
144
- notifySignal(signal.signal);
145
- }
146
- }
147
- let TrackingFrame = null;
148
-
149
- /**
150
- * This is currently just for signals debugging, but it could be used in production
151
- * if we wanted to eliminate the need for frameworks to implement createMemo / to
152
- * allow us to add our own Watcher.
153
- *
154
- * @internal
155
- */
156
- function withFrame(signals, object, key, fn) {
157
- const frameSignals = new Set();
158
- const frameFn = () => {
159
- if (frameSignals.size) {
160
- frameSignals.clear();
161
- }
162
- TrackingFrame = {
163
- object,
164
- key,
165
- signals: frameSignals,
166
- parent: TrackingFrame
167
- };
168
- try {
169
- return fn();
170
- } finally {
171
- TrackingFrame = TrackingFrame.parent;
172
- }
173
- };
174
- const memo = createMemo(object, key, frameFn);
175
- // @ts-expect-error
176
- memo.signals = frameSignals;
177
- signals.set(key, memo);
178
- return memo;
179
- }
180
- function isMemo(obj) {
181
- // @ts-expect-error
182
- return typeof obj === 'function' && obj.signals instanceof Set;
183
- }
184
- {
185
- // @ts-expect-error adding to global API
186
- globalThis.debugWarpDriveSignals = (obj, key) => {
187
- const signals = obj[Signals];
188
- if (!signals) {
189
- log$1('The object has no associated signals');
190
- return false;
191
- }
192
- if (key) {
193
- const signal = signals.get(key);
194
- if (!signal) {
195
- log$1(`No signal found for key "${String(key)}"`);
196
- return false;
197
- }
198
- log$1(signal);
199
- if (isMemo(signal)) {
200
- colorizeLines(printMemo(signal, key));
201
- return true;
202
- } else {
203
- colorizeLines(printSignal(signal, key));
204
- return true;
205
- }
206
- }
207
- const lines = [];
208
- for (const [k, signal] of signals) {
209
- if (isMemo(signal)) continue;
210
- printSignal(signal, k, lines);
211
- }
212
- for (const [k, signal] of signals) {
213
- if (isMemo(signal)) {
214
- printMemo(signal, k, lines);
215
- }
216
- }
217
- log$1(signals);
218
- colorizeLines(lines);
219
- return true;
220
- };
221
- }
222
- const LightColors = {
223
- red: 'color: red;',
224
- green: 'color: green;',
225
- reset: 'color: inherit;'
226
- };
227
- const DarkColors = {
228
- red: 'color: red;',
229
- green: 'color: lightgreen;',
230
- reset: 'color: inherit;'
231
- };
232
- function isLightMode$1() {
233
- if (window?.matchMedia?.('(prefers-color-scheme: light)').matches) {
234
- return true;
235
- }
236
- return false;
237
- }
238
- const RED = {};
239
- const GREEN = {};
240
- const RESET = {};
241
- const EOL = {};
242
- function colorizeLines(lines) {
243
- const Colors = isLightMode$1() ? LightColors : DarkColors;
244
- const colors = [];
245
- let line = '';
246
- for (const str of lines) {
247
- if (str === RED) {
248
- colors.push(Colors.red);
249
- line += '%c';
250
- } else if (str === GREEN) {
251
- colors.push(Colors.green);
252
- line += '%c';
253
- } else if (str === RESET) {
254
- colors.push(Colors.reset);
255
- line += '%c';
256
- } else if (str === EOL) {
257
- line += '\n';
258
- } else {
259
- line += str;
260
- }
261
- }
262
- log$1(line, ...colors);
263
- }
264
- function log$1(...args) {
265
- // eslint-disable-next-line no-console
266
- console.log(...args);
267
- }
268
- function isDirty(signal) {
269
- return signal.isStale;
270
- }
271
- function isDirtyMemo(memo) {
272
- // iterate simple signals first to get fastest answer
273
- for (const signal of memo.signals) {
274
- if (isMemo(signal)) continue;
275
- if (isDirty(signal)) {
276
- return true;
277
- }
278
- }
279
- for (const signal of memo.signals) {
280
- if (isMemo(signal)) {
281
- return isDirtyMemo(signal);
282
- }
283
- }
284
- return false;
285
- }
286
- function printSignal(signal, key, lines = [], depth = 0) {
287
- const _dirty = isDirty(signal);
288
- lines.push(`${''.padStart(depth * 2, ' ')}${_dirty ? '❌' : '✅'} `, _dirty ? RED : GREEN, `${String(key)}`, RESET, EOL);
289
- return lines;
290
- }
291
- function printMemo(memo, key, lines = [], depth = 0) {
292
- const _dirty = isDirtyMemo(memo);
293
- lines.push(`${''.padStart(depth * 2, ' ')}${_dirty ? '❌' : '✅'} `, _dirty ? RED : GREEN, `<memo> ${String(key)}`, RESET, `: (consumes ${memo.signals.size} signals)`, EOL);
294
- for (const signal of memo.signals) {
295
- if (isMemo(signal)) continue;
296
- printSignal(signal, signal.key, lines, depth + 1);
297
- }
298
- for (const signal of memo.signals) {
299
- if (isMemo(signal)) {
300
- printMemo(signal, signal.key, lines, depth + 1);
301
- }
302
- }
303
- return lines;
304
- }
305
-
306
- /**
307
- * Creates a signal for the key/object pairing and subscribes to the signal.
308
- *
309
- * Use when you need to ensure a signal exists and is subscribed to.
310
- *
311
- * @private
312
- */
313
- function entangleSignal(signals, obj, key, initialValue) {
314
- let internalSignal = peekInternalSignal(signals, key);
315
- if (!internalSignal) {
316
- internalSignal = createInternalSignal(signals, obj, key, initialValue);
317
- }
318
- consumeInternalSignal(internalSignal);
319
- return internalSignal;
320
- }
321
- function entangleInitiallyStaleSignal(signals, obj, key, initialValue) {
322
- let internalSignal = peekInternalSignal(signals, key);
323
- if (!internalSignal) {
324
- internalSignal = createInternalSignal(signals, obj, key, initialValue);
325
- internalSignal.isStale = true; // mark it as stale
326
- }
327
- consumeInternalSignal(internalSignal);
328
- return internalSignal;
329
- }
330
- function createSignalDescriptor(key, intialValue) {
331
- return {
332
- enumerable: true,
333
- configurable: false,
334
- get() {
335
- const signals = withSignalStore(this);
336
- const internalSignal = entangleSignal(signals, this, key, intialValue);
337
- internalSignal.isStale = false; // reset stale state
338
- return internalSignal.value;
339
- },
340
- set(value) {
341
- const signals = withSignalStore(this);
342
- const internalSignal = getOrCreateInternalSignal(signals, this, key, intialValue);
343
- if (internalSignal.value !== value) {
344
- internalSignal.value = value;
345
- notifyInternalSignal(internalSignal);
346
- }
347
- }
348
- };
349
- }
350
-
351
- /**
352
- * define an enumerable signal property.
353
- *
354
- * Akin to Object.defineProperty.
355
- *
356
- * The signal will be lazily created when accessed and scoped to the
357
- * instance of the object.
358
- *
359
- * @private
360
- */
361
- function defineSignal(obj, key, v) {
362
- Object.defineProperty(obj, key, createSignalDescriptor(key, v));
363
- }
364
-
365
- /**
366
- * Define a non-enumerable signal property.
367
- *
368
- * @private
369
- */
370
- function defineNonEnumerableSignal(obj, key, v) {
371
- const desc = createSignalDescriptor(key, v);
372
- desc.enumerable = false;
373
- Object.defineProperty(obj, key, desc);
374
- }
375
- /**
376
- * Decorator version of creating a signal.
377
- */
378
- function signal(target, key, descriptor) {
379
- // Error on `@signal()`, `@signal(...args)``
380
- (test => {
381
- if (!test) {
382
- throw new Error('You attempted to use @signal(), which is not necessary nor supported. Remove the parentheses and you will be good to go!');
383
- }
384
- })(target !== undefined);
385
- (test => {
386
- if (!test) {
387
- throw new Error(`You attempted to use @signal on with ${arguments.length > 1 ? 'arguments' : 'an argument'} ( @signal(${Array.from(arguments).map(d => `'${d}'`).join(', ')}) ), which is not supported. Dependencies are automatically tracked, so you can just use ${'`@signal`'}`);
388
- }
389
- })(typeof target === 'object' && typeof key === 'string' && typeof descriptor === 'object' && arguments.length === 3);
390
- return createSignalDescriptor(key, descriptor.initializer ? makeInitializer(descriptor.initializer) : null);
391
- }
392
-
393
- /**
394
- * Decorator version of creating a memoized getter
395
- */
396
- function memoized(target, key, descriptor) {
397
- // Error on `@memoized()`, `@memoized(...args)`, and `@memoized propName = value;`
398
- (test => {
399
- if (!test) {
400
- throw new Error('You attempted to use @memoized(), which is not necessary nor supported. Remove the parentheses and you will be good to go!');
401
- }
402
- })(target !== undefined);
403
- (test => {
404
- if (!test) {
405
- throw new Error(`You attempted to use @memoized on with ${arguments.length > 1 ? 'arguments' : 'an argument'} ( @memoized(${Array.from(arguments).map(d => `'${d}'`).join(', ')}), which is not supported. Dependencies are automatically tracked, so you can just use ${'`@memoized`'}`);
406
- }
407
- })(typeof target === 'object' && typeof key === 'string' && typeof descriptor === 'object' && arguments.length === 3);
408
- (test => {
409
- if (!test) {
410
- throw new Error(`The @memoized decorator must be applied to getters. '${key}' is not a getter.`);
411
- }
412
- })(typeof descriptor.get === 'function');
413
-
414
- // eslint-disable-next-line @typescript-eslint/unbound-method
415
- const getter = descriptor.get;
416
- descriptor.get = function () {
417
- const signals = withSignalStore(this);
418
- let memoSignal = signals.get(key);
419
- if (!memoSignal) {
420
- memoSignal = createInternalMemo(signals, this, key, getter.bind(this));
421
- }
422
- return memoSignal();
423
- };
424
- return descriptor;
425
- }
426
-
427
- /**
428
- * Decorator version of creating a gate.
429
- *
430
- * @private
431
- */
432
- function gate(_target, key, desc) {
433
- // eslint-disable-next-line @typescript-eslint/unbound-method
434
- const getter = desc.get;
435
- // eslint-disable-next-line @typescript-eslint/unbound-method
436
- const setter = desc.set;
437
- const isLocal = desc.isLocal;
438
- desc.get = function () {
439
- const signals = withSignalStore(this);
440
- let internalSignal = peekInternalSignal(signals, key);
441
- if (!internalSignal) {
442
- internalSignal = createInternalSignal(signals, this, key, getter.call(this));
443
- } else if (internalSignal.isStale) {
444
- internalSignal.isStale = false;
445
- internalSignal.value = getter.call(this);
446
- }
447
- consumeInternalSignal(internalSignal);
448
- return internalSignal.value;
449
- };
450
- if (setter) {
451
- desc.set = function (v) {
452
- const signals = withSignalStore(this);
453
- let internalSignal = peekInternalSignal(signals, key);
454
- if (!internalSignal) {
455
- // we can't use `v` as initialValue here because setters don't
456
- // return the value and the final value may be different
457
- // than what the setter was called with.
458
- internalSignal = createInternalSignal(signals, this, key, undefined);
459
- internalSignal.isStale = true;
460
- }
461
- setter.call(this, v);
462
- // when a gate is set, we do not notify the signal
463
- // as its update is controlled externally.
464
- // unless it specifically sets itself to be locally managed
465
- if (isLocal) {
466
- internalSignal.isStale = true;
467
- notifyInternalSignal(internalSignal);
468
- }
469
- };
470
- }
471
- return desc;
472
- }
473
- function defineGate(obj, key, desc) {
474
- const options = Object.assign({
475
- enumerable: true,
476
- configurable: false
477
- }, gate(obj, key, desc));
478
- Object.defineProperty(obj, key, options);
479
- }
480
13
  function urlFromLink(link) {
481
14
  if (typeof link === 'string') return link;
482
15
  return link.href;
@@ -2212,8 +1745,6 @@ class CacheManager {
2212
1745
  * a `content` member and therefor must not assume the existence
2213
1746
  * of `request` and `response` on the document.
2214
1747
  *
2215
- * @param {StructuredDocument} doc
2216
- * @return {ResourceDocument}
2217
1748
  * @public
2218
1749
  */
2219
1750
  put(doc) {
@@ -2225,7 +1756,6 @@ class CacheManager {
2225
1756
  *
2226
1757
  * @public
2227
1758
  * @param op the operation to perform
2228
- * @return {void}
2229
1759
  */
2230
1760
  patch(op) {
2231
1761
  this.___cache.patch(op);
@@ -2236,7 +1766,6 @@ class CacheManager {
2236
1766
  * on relationships only.
2237
1767
  *
2238
1768
  * @public
2239
- * @param mutation
2240
1769
  */
2241
1770
  mutate(mutation) {
2242
1771
  this.___cache.mutate(mutation);
@@ -2270,8 +1799,7 @@ class CacheManager {
2270
1799
  * notifications for relational data.
2271
1800
  *
2272
1801
  * @public
2273
- * @param {ResourceKey | RequestKey} cacheKey
2274
- * @return {ResourceDocument | ResourceBlob | null} the known resource data
1802
+ * @return the known resource data
2275
1803
  */
2276
1804
 
2277
1805
  peek(cacheKey) {
@@ -2284,8 +1812,6 @@ class CacheManager {
2284
1812
  * Peek the Cache for the existing request data associated with
2285
1813
  * a cacheable request
2286
1814
  *
2287
- * @param {RequestKey}
2288
- * @return {RequestKey | null}
2289
1815
  * @public
2290
1816
  */
2291
1817
  peekRequest(key) {
@@ -2313,7 +1839,6 @@ class CacheManager {
2313
1839
  * utilize this method to fork the cache.
2314
1840
  *
2315
1841
  * @public
2316
- * @return {Promise<Cache>}
2317
1842
  */
2318
1843
  fork() {
2319
1844
  return this.___cache.fork();
@@ -2326,9 +1851,7 @@ class CacheManager {
2326
1851
  * preferring instead to merge at the Store level, which will
2327
1852
  * utilize this method to merge the caches.
2328
1853
  *
2329
- * @param {Cache} cache
2330
1854
  * @public
2331
- * @return {Promise<void>}
2332
1855
  */
2333
1856
  merge(cache) {
2334
1857
  return this.___cache.merge(cache);
@@ -2378,7 +1901,6 @@ class CacheManager {
2378
1901
  * which may be fed back into a new instance of the same Cache
2379
1902
  * via `cache.hydrate`.
2380
1903
  *
2381
- * @return {Promise<ReadableStream>}
2382
1904
  * @public
2383
1905
  */
2384
1906
  dump() {
@@ -2397,8 +1919,6 @@ class CacheManager {
2397
1919
  * behavior supports optimizing pre/fetching of data for route transitions
2398
1920
  * via data-only SSR modes.
2399
1921
  *
2400
- * @param {ReadableStream} stream
2401
- * @return {Promise<void>}
2402
1922
  * @public
2403
1923
  */
2404
1924
  hydrate(stream) {
@@ -5797,7 +5317,7 @@ class RecordReference {
5797
5317
  simplest usage of this API is similar to `store.push`: you provide a
5798
5318
  normalized hash of data and the object represented by the reference
5799
5319
  will update.
5800
- If you pass a promise to `push`, Ember Data will not ask the adapter
5320
+ If you pass a promise to `push`, WarpDrive will not ask the adapter
5801
5321
  for the data if another attempt to fetch it is made in the
5802
5322
  interim. When the promise resolves, the underlying object is updated
5803
5323
  with the new data, and the promise returned by *this function* is resolved
@@ -6284,7 +5804,7 @@ function fetchContentAndHydrate(next, context, identifier, priority) {
6284
5804
 
6285
5805
  ### Inverses
6286
5806
 
6287
- Often, the relationships in Ember Data applications will have
5807
+ Often, the relationships in WarpDrive applications will have
6288
5808
  an inverse. For example, imagine the following models are
6289
5809
  defined:
6290
5810
 
@@ -6599,1180 +6119,59 @@ function mutate(collection, mutation, _SIGNAL) {
6599
6119
  manager.mutate(mutation);
6600
6120
  notifyInternalSignal(_SIGNAL);
6601
6121
  }
6602
- function decorateMethodV2(prototype, prop, decorators) {
6603
- const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
6604
- let desc = {
6605
- ...origDesc
6606
- };
6607
- for (let decorator of decorators) {
6608
- desc = decorator(prototype, prop, desc) || desc;
6609
- }
6610
- if (desc.initializer !== void 0) {
6611
- desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
6612
- desc.initializer = void 0;
6613
- }
6614
- Object.defineProperty(prototype, prop, desc);
6122
+ function getAliasField(context) {
6123
+ (test => {
6124
+ {
6125
+ throw new Error(`Alias field access is not implemented`);
6126
+ }
6127
+ })();
6615
6128
  }
6616
-
6617
- // default to 30 seconds unavailable before we refresh
6618
- const DEFAULT_DEADLINE = 30_000;
6619
- const DISPOSE = Symbol.dispose || Symbol.for('dispose');
6620
- function isNeverString(val) {
6621
- return val;
6129
+ function setAliasField(context) {
6130
+ (test => {
6131
+ {
6132
+ throw new Error(`Alias field setting is not implemented`);
6133
+ }
6134
+ })();
6135
+ return false;
6136
+ }
6137
+ const ARRAY_GETTER_METHODS = new Set([Symbol.iterator, 'concat', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flat', 'flatMap', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'slice', 'some', 'values']);
6138
+ // const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
6139
+ const SYNC_PROPS = new Set(['[]', 'length']);
6140
+ function isArrayGetter(prop) {
6141
+ return ARRAY_GETTER_METHODS.has(prop);
6142
+ }
6143
+ const ARRAY_SETTER_METHODS = new Set(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
6144
+ function isArraySetter(prop) {
6145
+ return ARRAY_SETTER_METHODS.has(prop);
6622
6146
  }
6623
6147
 
6624
- /**
6625
- * Utilities to assist in recovering from the error.
6626
- */
6627
-
6628
- /** @deprecated use {@link RecoveryFeatures} */
6629
-
6630
- /**
6631
- * Utilities for keeping the request fresh
6632
- */
6633
-
6634
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
6635
-
6636
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
6637
-
6638
- /**
6639
- * A reactive class
6640
- *
6641
- * @hideconstructor
6642
- */
6643
- class RequestSubscription {
6644
- /**
6645
- * Whether the browser reports that the network is online.
6646
- */
6148
+ // function isSelfProp<T extends object>(self: T, prop: KeyType): prop is keyof T {
6149
+ // return prop in self;
6150
+ // }
6647
6151
 
6648
- /**
6649
- * Whether the browser reports that the tab is hidden.
6650
- */
6152
+ function convertToInt(prop) {
6153
+ if (typeof prop === 'symbol') return null;
6154
+ const num = Number(prop);
6155
+ if (isNaN(num)) return null;
6156
+ return num % 1 === 0 ? num : null;
6157
+ }
6158
+ function safeForEach(instance, arr, store, callback, target) {
6159
+ if (target === undefined) {
6160
+ target = null;
6161
+ }
6162
+ // clone to prevent mutation
6163
+ arr = arr.slice();
6164
+ (test => {
6165
+ if (!test) {
6166
+ throw new Error('`forEach` expects a function as first argument.');
6167
+ }
6168
+ })(typeof callback === 'function');
6651
6169
 
6652
- /**
6653
- * Whether the component is currently refreshing the request.
6654
- */
6655
-
6656
- /**
6657
- * The most recent blocking request that was made, typically
6658
- * the result of a reload.
6659
- *
6660
- * This will never be the original request passed as an arg to
6661
- * the component.
6662
- *
6663
- * @internal
6664
- */
6665
-
6666
- /**
6667
- * The most recent request that was made, typically due to either a
6668
- * reload or a refresh.
6669
- *
6670
- * This will never be the original request passed as an arg to
6671
- * the component.
6672
- *
6673
- * @internal
6674
- */
6675
-
6676
- /**
6677
- * The time at which the network was reported as offline.
6678
- *
6679
- * @internal
6680
- */
6681
-
6682
- /** @internal */
6683
-
6684
- /** @internal */
6685
-
6686
- /** @internal */
6687
-
6688
- /** @internal */
6689
-
6690
- /** @internal */
6691
-
6692
- /**
6693
- * The event listener for network status changes,
6694
- * cached to use the reference for removal.
6695
- *
6696
- * @internal
6697
- */
6698
-
6699
- /**
6700
- * The event listener for visibility status changes,
6701
- * cached to use the reference for removal.
6702
- *
6703
- * @internal
6704
- */
6705
-
6706
- /**
6707
- * The last request passed as an arg to the component,
6708
- * cached for comparison.
6709
- *
6710
- * @internal
6711
- */
6712
-
6713
- /**
6714
- * The last query passed as an arg to the component,
6715
- * cached for comparison.
6716
- *
6717
- * @internal
6718
- */
6719
-
6720
- /** @internal */
6721
-
6722
- /** @internal */
6723
-
6724
- /** @internal */
6725
-
6726
- /**
6727
- * The Store this subscription subscribes to or the RequestManager
6728
- * which issues this request.
6729
- */
6730
-
6731
- /**
6732
- * The Store or RequestManager that the last subscription is attached to.
6733
- *
6734
- * This differs from 'store' because a <Request /> may be passed a
6735
- * request originating from a different store than the <Request />
6736
- * component would use if it were to issue the request itself.
6737
- *
6738
- * @internal
6739
- */
6740
- _requester;
6741
- constructor(store, args) {
6742
- this._args = args;
6743
- this.store = store;
6744
- this._subscribedTo = null;
6745
- this._subscription = null;
6746
- this._intervalStart = null;
6747
- this._invalidated = false;
6748
- this._nextInterval = null;
6749
- this._requester = null;
6750
- this.isDestroyed = false;
6751
- this[DISPOSE] = _DISPOSE;
6752
- this._installListeners();
6753
- void this._beginPolling();
6754
- }
6755
-
6756
- /**
6757
- * @internal
6758
- */
6759
- async _beginPolling() {
6760
- // await the initial request
6761
- try {
6762
- if (!this.isIdle) {
6763
- await this.request;
6764
- }
6765
- } catch {
6766
- // ignore errors here, we just want to wait for the request to finish
6767
- } finally {
6768
- if (!this.isDestroyed) {
6769
- void this._scheduleInterval();
6770
- }
6771
- }
6772
- }
6773
- get isIdle() {
6774
- const {
6775
- request,
6776
- query
6777
- } = this._args;
6778
- return Boolean(!request && !query);
6779
- }
6780
- static {
6781
- decorateMethodV2(this.prototype, "isIdle", [memoized]);
6782
- }
6783
- get autorefreshTypes() {
6784
- const {
6785
- autorefresh
6786
- } = this._args;
6787
- let types;
6788
- if (autorefresh === true) {
6789
- types = ['online', 'invalid'];
6790
- } else if (typeof autorefresh === 'string') {
6791
- types = autorefresh.split(',');
6792
- } else {
6793
- types = [];
6794
- }
6795
- return new Set(types);
6796
- }
6797
-
6798
- // we only run this function on component creation
6799
- // and when an update is triggered, so it does not
6800
- // react to changes in the autorefreshThreshold
6801
- // or autorefresh args.
6802
- //
6803
- // if we need to react to those changes, we can
6804
- // use a modifier or internal component or some
6805
- // such to trigger a re-run of this function.
6806
- /** @internal */
6807
- static {
6808
- decorateMethodV2(this.prototype, "autorefreshTypes", [memoized]);
6809
- }
6810
- async _scheduleInterval() {
6811
- const {
6812
- autorefreshThreshold
6813
- } = this._args;
6814
- const hasValidThreshold = typeof autorefreshThreshold === 'number' && autorefreshThreshold > 0;
6815
- if (
6816
- // dont schedule in SSR
6817
- typeof window === 'undefined' ||
6818
- // dont schedule without a threshold
6819
- !hasValidThreshold ||
6820
- // dont schedule if we weren't told to
6821
- !this.autorefreshTypes.has('interval') ||
6822
- // dont schedule if we're already scheduled
6823
- this._intervalStart !== null) {
6824
- return;
6825
- }
6826
-
6827
- // if we have a current request, wait for it to finish
6828
- // before scheduling the next one
6829
- if (this._latestRequest) {
6830
- try {
6831
- await this._latestRequest;
6832
- } catch {
6833
- // ignore errors here, we just want to wait for the request to finish
6834
- }
6835
- if (this.isDestroyed) {
6836
- return;
6837
- }
6838
- }
6839
-
6840
- // setup the next interval
6841
- this._intervalStart = Date.now();
6842
- this._nextInterval = setTimeout(() => {
6843
- this._maybeUpdate();
6844
- }, autorefreshThreshold);
6845
- }
6846
-
6847
- /** @internal */
6848
- _clearInterval() {
6849
- if (this._nextInterval) {
6850
- clearTimeout(this._nextInterval);
6851
- this._intervalStart = null;
6852
- }
6853
- }
6854
- /**
6855
- * @internal
6856
- */
6857
- _updateSubscriptions() {
6858
- if (this.isIdle) {
6859
- return;
6860
- }
6861
- const requestId = this._request.lid;
6862
-
6863
- // if we're already subscribed to this request, we don't need to do anything
6864
- if (this._subscribedTo === requestId) {
6865
- return;
6866
- }
6867
-
6868
- // if we're subscribed to a different request, we need to unsubscribe
6869
- this._removeSubscriptions();
6870
-
6871
- // if we have a request, we need to subscribe to it
6872
- const store = this._getRequester();
6873
- this._requester = store;
6874
- if (requestId && isStore(store)) {
6875
- this._subscribedTo = requestId;
6876
- this._subscription = store.notifications.subscribe(requestId, (_id, op) => {
6877
- // ignore subscription events that occur while our own component's request
6878
- // is occurring
6879
- if (this._isUpdating) {
6880
- return;
6881
- }
6882
- switch (op) {
6883
- case 'invalidated':
6884
- {
6885
- // if we're subscribed to invalidations, we need to update
6886
- if (this.autorefreshTypes.has('invalid')) {
6887
- this._invalidated = true;
6888
- this._maybeUpdate();
6889
- }
6890
- break;
6891
- }
6892
- case 'state':
6893
- {
6894
- const latest = store.requestManager._deduped.get(requestId);
6895
- const priority = latest?.priority;
6896
- const state = this.reqState;
6897
- if (!priority) {
6898
- // if there is no priority, we have completed whatever request
6899
- // was occurring and so we are no longer refreshing (if we were)
6900
- this.isRefreshing = false;
6901
- } else if (priority.blocking && !state.isLoading) {
6902
- // if we are blocking, there is an active request for this identity
6903
- // that MUST be fulfilled from network (not cache).
6904
- // Thus this is not "refreshing" because we should clear out and
6905
- // block on this request.
6906
- //
6907
- // we receive state notifications when either a request initiates
6908
- // or completes.
6909
- //
6910
- // In the completes case: we may receive the state notification
6911
- // slightly before the request is finalized because the NotificationManager
6912
- // may sync flush it (and thus deliver it before the microtask completes)
6913
- //
6914
- // In the initiates case: we aren't supposed to receive one unless there
6915
- // is no other request in flight for this identity.
6916
- //
6917
- // However, there is a race condition here where the completed
6918
- // notification can trigger an update that generates a new request
6919
- // thus giving us an initiated notification before the older request
6920
- // finalizes.
6921
- //
6922
- // When this occurs, if the triggered update happens to have caused
6923
- // a new request to be made for the same identity AND that request
6924
- // is the one passed into this component as the @request arg, then
6925
- // getRequestState will return the state of the new request.
6926
- // We can detect this by checking if the request state is "loading"
6927
- // as outside of this case we would have a completed request.
6928
- //
6929
- // That is the reason for the `&& !state.isLoading` check above.
6930
-
6931
- // TODO should we just treat this as refreshing?
6932
- this.isRefreshing = false;
6933
- this._maybeUpdate('policy', true);
6934
- } else {
6935
- this.isRefreshing = true;
6936
- }
6937
- }
6938
- }
6939
- });
6940
- }
6941
- }
6942
-
6943
- /**
6944
- * @internal
6945
- */
6946
- _removeSubscriptions() {
6947
- const store = this._requester;
6948
- if (this._subscription && store && isStore(store)) {
6949
- store.notifications.unsubscribe(this._subscription);
6950
- this._subscribedTo = null;
6951
- this._subscription = null;
6952
- this._requester = null;
6953
- }
6954
- }
6955
-
6956
- /**
6957
- * Install the event listeners for network and visibility changes.
6958
- * This is only done in browser environments with a global `window`.
6959
- *
6960
- * @internal
6961
- */
6962
- _installListeners() {
6963
- if (typeof window === 'undefined') {
6964
- return;
6965
- }
6966
- this.isOnline = window.navigator.onLine;
6967
- this._unavailableStart = this.isOnline ? null : Date.now();
6968
- this.isHidden = document.visibilityState === 'hidden';
6969
- this._onlineChanged = event => {
6970
- this.isOnline = event.type === 'online';
6971
- if (event.type === 'offline' && this._unavailableStart === null) {
6972
- this._unavailableStart = Date.now();
6973
- }
6974
- this._maybeUpdate();
6975
- };
6976
- this._backgroundChanged = () => {
6977
- const isHidden = document.visibilityState === 'hidden';
6978
- this.isHidden = isHidden;
6979
- if (isHidden && this._unavailableStart === null) {
6980
- this._unavailableStart = Date.now();
6981
- }
6982
- this._maybeUpdate();
6983
- };
6984
- window.addEventListener('online', this._onlineChanged, {
6985
- passive: true,
6986
- capture: true
6987
- });
6988
- window.addEventListener('offline', this._onlineChanged, {
6989
- passive: true,
6990
- capture: true
6991
- });
6992
- document.addEventListener('visibilitychange', this._backgroundChanged, {
6993
- passive: true,
6994
- capture: true
6995
- });
6996
- }
6997
-
6998
- /**
6999
- * If the network is online and the tab is visible, either reload or refresh the request
7000
- * based on the component's configuration and the requested update mode.
7001
- *
7002
- * Valid modes are:
7003
- *
7004
- * - `'reload'`: Force a reload of the request.
7005
- * - `'refresh'`: Refresh the request in the background.
7006
- * - `'policy'`: Make the request, letting the store's configured CachePolicy decide whether to reload, refresh, or do nothing.
7007
- * - `undefined`: Make the request using the component's autorefreshBehavior setting if the autorefreshThreshold has passed.
7008
- *
7009
- * @internal
7010
- */
7011
- _maybeUpdate(mode, silent) {
7012
- if (this.isIdle) {
7013
- return;
7014
- }
7015
- const {
7016
- reqState
7017
- } = this;
7018
- if (reqState.isPending) {
7019
- return;
7020
- }
7021
- const canAttempt = Boolean(this.isOnline && !this.isHidden && (mode || this.autorefreshTypes.size));
7022
- if (!canAttempt) {
7023
- if (!silent && mode && mode !== '_invalidated') {
7024
- throw new Error(`Reload not available: the network is not online or the tab is hidden`);
7025
- }
7026
- return;
7027
- }
7028
- const {
7029
- autorefreshTypes
7030
- } = this;
7031
- let shouldAttempt = this._invalidated || Boolean(mode);
7032
- if (!shouldAttempt && autorefreshTypes.has('online')) {
7033
- const {
7034
- _unavailableStart
7035
- } = this;
7036
- const {
7037
- autorefreshThreshold
7038
- } = this._args;
7039
- const deadline = typeof autorefreshThreshold === 'number' ? autorefreshThreshold : DEFAULT_DEADLINE;
7040
- shouldAttempt = Boolean(_unavailableStart && Date.now() - _unavailableStart > deadline);
7041
- }
7042
- if (!shouldAttempt && autorefreshTypes.has('interval')) {
7043
- const {
7044
- _intervalStart
7045
- } = this;
7046
- const {
7047
- autorefreshThreshold
7048
- } = this._args;
7049
- if (_intervalStart && typeof autorefreshThreshold === 'number' && autorefreshThreshold > 0) {
7050
- shouldAttempt = Boolean(Date.now() - _intervalStart >= autorefreshThreshold);
7051
- }
7052
- }
7053
- this._unavailableStart = null;
7054
- this._invalidated = false;
7055
- if (shouldAttempt) {
7056
- this._clearInterval();
7057
- this._isUpdating = true;
7058
- const realMode = mode === '_invalidated' ? null : mode;
7059
- const val = realMode ?? this._args.autorefreshBehavior ?? 'policy';
7060
-
7061
- // if the future was generated by an older store version, it may not have
7062
- // a requester set. In this case we append it to ensure that reload and
7063
- // refresh will work appropriately.
7064
- const requester = this._getRequester();
7065
- if (!reqState._request.requester) {
7066
- reqState._request.requester = requester;
7067
- }
7068
- switch (val) {
7069
- case 'reload':
7070
- this._latestRequest = reqState.reload();
7071
- break;
7072
- case 'refresh':
7073
- this._latestRequest = reqState.refresh();
7074
- break;
7075
- case 'policy':
7076
- this._latestRequest = reqState.refresh(true);
7077
- break;
7078
- default:
7079
- (test => {
7080
- {
7081
- throw new Error(`Invalid ${mode ? 'update mode' : '@autorefreshBehavior'} for <Request />: ${isNeverString(val)}`);
7082
- }
7083
- })();
7084
- }
7085
- if (val !== 'refresh') {
7086
- this._localRequest = this._latestRequest;
7087
- }
7088
- void this._scheduleInterval();
7089
- void this._latestRequest.finally(() => {
7090
- this._isUpdating = false;
7091
- });
7092
- }
7093
- }
7094
-
7095
- /**
7096
- * @internal
7097
- */
7098
- _getRequester() {
7099
- // Note: we check for the requester's presence
7100
- // as well as the request's presence because we may
7101
- // be subscribed to a request issued by a store from an older
7102
- // version of the library that didn't yet set requester.
7103
- if (this._args.request?.requester) {
7104
- return this._args.request.requester;
7105
- }
7106
- return this.store;
7107
- }
7108
-
7109
- /**
7110
- * Retry the request, reloading it from the server.
7111
- */
7112
- retry = async () => {
7113
- this._maybeUpdate('reload');
7114
- await this._localRequest;
7115
- };
7116
-
7117
- /**
7118
- * Refresh the request, updating it in the background.
7119
- */
7120
- refresh = async () => {
7121
- this._maybeUpdate('refresh');
7122
- await this._latestRequest;
7123
- };
7124
-
7125
- /**
7126
- * features to yield to the error slot of a component
7127
- */
7128
- get errorFeatures() {
7129
- return {
7130
- isHidden: this.isHidden,
7131
- isOnline: this.isOnline,
7132
- retry: this.retry
7133
- };
7134
- }
7135
-
7136
- /**
7137
- * features to yield to the content slot of a component
7138
- */
7139
- static {
7140
- decorateMethodV2(this.prototype, "errorFeatures", [memoized]);
7141
- }
7142
- get contentFeatures() {
7143
- const feat = {
7144
- isHidden: this.isHidden,
7145
- isOnline: this.isOnline,
7146
- reload: this.retry,
7147
- refresh: this.refresh,
7148
- isRefreshing: this.isRefreshing,
7149
- latestRequest: this._latestRequest
7150
- };
7151
- if (feat.isRefreshing) {
7152
- feat.abort = () => {
7153
- this._latestRequest?.abort();
7154
- };
7155
- }
7156
- return feat;
7157
- }
7158
-
7159
- /**
7160
- * @internal
7161
- */
7162
- static {
7163
- decorateMethodV2(this.prototype, "contentFeatures", [memoized]);
7164
- }
7165
- get _request() {
7166
- const {
7167
- request,
7168
- query
7169
- } = this._args;
7170
- (test => {
7171
- if (!test) {
7172
- throw new Error(`Cannot use both @request and @query args with the <Request> component`);
7173
- }
7174
- })(!request || !query);
7175
- const {
7176
- _localRequest,
7177
- _originalRequest,
7178
- _originalQuery
7179
- } = this;
7180
- const isOriginalRequest = request === _originalRequest && query === _originalQuery;
7181
- if (_localRequest && isOriginalRequest) {
7182
- return _localRequest;
7183
- }
7184
-
7185
- // update state checks for the next time
7186
- this._originalQuery = query;
7187
- this._originalRequest = request;
7188
- if (request) {
7189
- return request;
7190
- }
7191
- (test => {
7192
- if (!test) {
7193
- throw new Error(`You must provide either @request or an @query arg with the <Request> component`);
7194
- }
7195
- })(query);
7196
- return this.store.request(query);
7197
- }
7198
- static {
7199
- decorateMethodV2(this.prototype, "_request", [memoized]);
7200
- }
7201
- get request() {
7202
- {
7203
- try {
7204
- const request = this._request;
7205
- this._updateSubscriptions();
7206
- return request;
7207
- } catch (e) {
7208
- // eslint-disable-next-line no-console
7209
- console.log(e);
7210
- throw new Error(`Unable to initialize the request`, {
7211
- cause: e
7212
- });
7213
- }
7214
- }
7215
- }
7216
- static {
7217
- decorateMethodV2(this.prototype, "request", [memoized]);
7218
- }
7219
- get reqState() {
7220
- return getRequestState(this.request);
7221
- }
7222
- get result() {
7223
- return this.reqState.result;
7224
- }
7225
- }
7226
- defineSignal(RequestSubscription.prototype, 'isOnline', true);
7227
- defineSignal(RequestSubscription.prototype, 'isHidden', false);
7228
- defineSignal(RequestSubscription.prototype, 'isRefreshing', false);
7229
- defineSignal(RequestSubscription.prototype, '_localRequest', undefined);
7230
- defineSignal(RequestSubscription.prototype, '_latestRequest', undefined);
7231
- function isStore(store) {
7232
- return 'requestManager' in store;
7233
- }
7234
- function createRequestSubscription(store, args) {
7235
- return new RequestSubscription(store, args);
7236
- }
7237
- function upgradeSubscription(sub) {
7238
- return sub;
7239
- }
7240
- function _DISPOSE() {
7241
- const self = upgradeSubscription(this);
7242
- self.isDestroyed = true;
7243
- self._removeSubscriptions();
7244
- if (typeof window === 'undefined') {
7245
- return;
7246
- }
7247
- self._clearInterval();
7248
- window.removeEventListener('online', self._onlineChanged, {
7249
- passive: true,
7250
- capture: true
7251
- });
7252
- window.removeEventListener('offline', self._onlineChanged, {
7253
- passive: true,
7254
- capture: true
7255
- });
7256
- document.removeEventListener('visibilitychange', self._backgroundChanged, {
7257
- passive: true,
7258
- capture: true
7259
- });
7260
- }
7261
- const RequestCache = new WeakMap();
7262
- function isAbortError(error) {
7263
- return error instanceof DOMException && error.name === 'AbortError';
7264
- }
7265
- function upgradeLoadingState(state) {
7266
- return state;
7267
- }
7268
- async function watchStream(stream, loadingState) {
7269
- const state = upgradeLoadingState(loadingState);
7270
- const reader = stream.getReader();
7271
- let bytesLoaded = 0;
7272
- let shouldForward = state._stream !== null && state._stream.readable.locked;
7273
- let isForwarding = shouldForward;
7274
- let writer = state._stream?.writable.getWriter();
7275
- const buffer = [];
7276
- state._isPending = false;
7277
- state._isStarted = true;
7278
- state._startTime = performance.now();
7279
- while (true) {
7280
- const {
7281
- value,
7282
- done
7283
- } = await reader.read();
7284
- if (done) {
7285
- break;
7286
- }
7287
- bytesLoaded += value.byteLength;
7288
- state._bytesLoaded = bytesLoaded;
7289
- state._lastPacketTime = performance.now();
7290
- shouldForward = shouldForward || state._stream !== null && state._stream.readable.locked;
7291
- if (shouldForward) {
7292
- if (!isForwarding) {
7293
- isForwarding = true;
7294
- writer = state._stream.writable.getWriter();
7295
- for (const item of buffer) {
7296
- await writer.ready;
7297
- await writer.write(item);
7298
- }
7299
- buffer.length = 0;
7300
- }
7301
- await writer.ready;
7302
- await writer.write(value);
7303
- } else {
7304
- buffer.push(value);
7305
- }
7306
- }
7307
-
7308
- // if we are still forwarding, we need to close the writer
7309
- if (isForwarding) {
7310
- await writer.ready;
7311
- await writer.close();
7312
- } else if (state._stream) {
7313
- // if we are not forwarding, we need to cancel the stream
7314
- await state._stream.readable.cancel('The Stream Has Already Ended');
7315
- state._stream = null;
7316
- }
7317
- const endTime = performance.now();
7318
- state._endTime = endTime;
7319
- state._isComplete = true;
7320
- state._isStarted = false;
7321
- }
7322
-
7323
- /**
7324
- * Lazily consumes the stream of a request, providing a number of
7325
- * reactive properties that can be used to build UIs that respond
7326
- * to the progress of a request.
7327
- *
7328
- * @hideconstructor
7329
- */
7330
- class RequestLoadingState {
7331
- /** @internal */
7332
-
7333
- /** @internal */
7334
-
7335
- /** @internal */
7336
-
7337
- /** @internal */
7338
-
7339
- /** @internal */
7340
-
7341
- /** @internal */
7342
-
7343
- /** @internal */
7344
-
7345
- /** @internal */
7346
-
7347
- /** @internal */
7348
-
7349
- /** @internal */
7350
-
7351
- /** @internal */
7352
-
7353
- /** @internal */
7354
- _stream = null;
7355
- /** @internal */
7356
- _future;
7357
- /** @internal */
7358
- _triggered = false;
7359
- /** @internal */
7360
- _trigger() {
7361
- if (this._triggered) {
7362
- return;
7363
- }
7364
- this._triggered = true;
7365
- const future = this._future;
7366
- const promise = future.getStream();
7367
- if (promise.sizeHint) {
7368
- this._sizeHint = promise.sizeHint;
7369
- }
7370
- this.promise = promise.then(stream => {
7371
- if (!stream) {
7372
- this._isPending = false;
7373
- this._isComplete = true;
7374
- return;
7375
- }
7376
- return watchStream(stream, this);
7377
- }, error => {
7378
- this._isPending = false;
7379
- this._isStarted = false;
7380
- if (isAbortError(error)) {
7381
- this._isCancelled = true;
7382
- this._isComplete = true;
7383
- }
7384
- this._isErrored = true;
7385
- this._error = error;
7386
- });
7387
- }
7388
- promise = null;
7389
- get isPending() {
7390
- this._trigger();
7391
- return this._isPending;
7392
- }
7393
- get sizeHint() {
7394
- this._trigger();
7395
- return this._sizeHint;
7396
- }
7397
- get stream() {
7398
- this._trigger();
7399
- if (!this._stream) {
7400
- if (this._isComplete || this._isCancelled || this._isErrored) {
7401
- return null;
7402
- }
7403
- this._stream = new TransformStream();
7404
- }
7405
- return this._stream.readable;
7406
- }
7407
- get isStarted() {
7408
- this._trigger();
7409
- return this._isStarted;
7410
- }
7411
- get bytesLoaded() {
7412
- this._trigger();
7413
- return this._bytesLoaded;
7414
- }
7415
- get startTime() {
7416
- this._trigger();
7417
- return this._startTime;
7418
- }
7419
- get endTime() {
7420
- this._trigger();
7421
- return this._endTime;
7422
- }
7423
- get lastPacketTime() {
7424
- this._trigger();
7425
- return this._lastPacketTime;
7426
- }
7427
- get isComplete() {
7428
- this._trigger();
7429
- return this._isComplete;
7430
- }
7431
- get isCancelled() {
7432
- this._trigger();
7433
- return this._isCancelled;
7434
- }
7435
- get isErrored() {
7436
- this._trigger();
7437
- return this._isErrored;
7438
- }
7439
- get error() {
7440
- this._trigger();
7441
- return this._error;
7442
- }
7443
- get elapsedTime() {
7444
- return (this.endTime || this.lastPacketTime) - this.startTime;
7445
- }
7446
- get completedRatio() {
7447
- return this.sizeHint ? this.bytesLoaded / this.sizeHint : 0;
7448
- }
7449
- get remainingRatio() {
7450
- return 1 - this.completedRatio;
7451
- }
7452
- get duration() {
7453
- return this.endTime - this.startTime;
7454
- }
7455
- get speed() {
7456
- // bytes per second
7457
- return this.bytesLoaded / (this.elapsedTime / 1000);
7458
- }
7459
- constructor(future) {
7460
- this._future = future;
7461
- }
7462
- abort = () => {
7463
- this._future.abort();
7464
- };
7465
- }
7466
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isPending', true);
7467
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isStarted', false);
7468
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isComplete', false);
7469
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isCancelled', false);
7470
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isErrored', false);
7471
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_error', null);
7472
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_sizeHint', 0);
7473
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_bytesLoaded', 0);
7474
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_startTime', 0);
7475
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_endTime', 0);
7476
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_lastPacketTime', 0);
7477
-
7478
- /**
7479
- * The state of a request in the "pending"
7480
- * state. This is the default initial state.
7481
- *
7482
- * Extends the {@link PendingPromise} interface.
7483
- *
7484
- */
7485
-
7486
- /**
7487
- * The state of a request in the "fulfilled" state.
7488
- * This is the state of a request that has resolved
7489
- * successfully.
7490
- *
7491
- * Extends the {@link ResolvedPromise} interface.
7492
- *
7493
- */
7494
-
7495
- /**
7496
- * The state of a request in the "rejected" state.
7497
- * This is the state of a request that has rejected
7498
- * with an error.
7499
- *
7500
- * Extends the {@link RejectedPromise} interface.
7501
- *
7502
- */
7503
-
7504
- /**
7505
- * The state of a request in the "cancelled" state.
7506
- * This is the state of a promise that has been
7507
- * cancelled.
7508
- *
7509
- */
7510
-
7511
- /**
7512
- * RequestState extends the concept of {@link PromiseState} to provide a reactive
7513
- * wrapper for a request {@link Future} which allows you write declarative code
7514
- * around a Future's control flow.
7515
- *
7516
- * It is useful in both Template and JavaScript contexts, allowing you
7517
- * to quickly derive behaviors and data from pending, error and success
7518
- * states.
7519
- *
7520
- * The key difference between a {@link Promise} and a Future is that Futures provide
7521
- * access to a {@link ReadableStream | stream} of their content, the {@link RequestKey} of the request (if any)
7522
- * as well as the ability to attempt to {@link Future.abort | abort} the request.
7523
- *
7524
- * ```ts
7525
- * interface Future<T> extends Promise<T>> {
7526
- * getStream(): Promise<ReadableStream>;
7527
- * abort(): void;
7528
- * lid: RequestKey | null;
7529
- * }
7530
- * ```
7531
- *
7532
- * These additional APIs allow us to craft even richer state experiences.
7533
- *
7534
- * To get the state of a request, use {@link getRequestState}.
7535
- *
7536
- * See also:
7537
- * - {@link PendingRequest}
7538
- * - {@link ResolvedRequest}
7539
- * - {@link RejectedRequest}
7540
- * - {@link CancelledRequest}
7541
- *
7542
- */
7543
-
7544
- const RequestStateProto = {};
7545
- function performRefresh(requester, request, isReload) {
7546
- const req = Object.assign({}, request);
7547
- const cacheOptions = Object.assign({}, req.cacheOptions);
7548
- if (isReload) {
7549
- // force direct to network
7550
- cacheOptions.reload = true;
7551
- } else if (isReload === false) {
7552
- // delete reload to ensure we use backgroundReload / policy
7553
- delete cacheOptions.reload;
7554
- cacheOptions.backgroundReload = true;
7555
- } else {
7556
- // delete props to ensure we use the policy
7557
- delete cacheOptions.backgroundReload;
7558
- delete cacheOptions.reload;
7559
- }
7560
- req.cacheOptions = cacheOptions;
7561
- return requester.request(req);
7562
- }
7563
-
7564
- // TODO introduce a new mechanism for defining multiple properties
7565
- // that share a common signal
7566
- defineSignal(RequestStateProto, 'reason', null);
7567
- defineSignal(RequestStateProto, 'value', null);
7568
- defineSignal(RequestStateProto, 'result', null);
7569
- defineSignal(RequestStateProto, 'error', null);
7570
- defineSignal(RequestStateProto, 'status', 'pending');
7571
- defineSignal(RequestStateProto, 'isPending', true);
7572
- defineSignal(RequestStateProto, 'isLoading', true);
7573
- defineSignal(RequestStateProto, 'isSuccess', false);
7574
- defineSignal(RequestStateProto, 'isError', false);
7575
- defineSignal(RequestStateProto, 'request', null);
7576
- defineSignal(RequestStateProto, 'response', null);
7577
- Object.defineProperty(RequestStateProto, 'isCancelled', {
7578
- get() {
7579
- return this.isError && isAbortError(this.reason);
7580
- }
7581
- });
7582
- Object.defineProperty(RequestStateProto, 'loadingState', {
7583
- get() {
7584
- if (!this._loadingState) {
7585
- this._loadingState = new RequestLoadingState(this._request);
7586
- }
7587
- return this._loadingState;
7588
- }
7589
- });
7590
- function createRequestState(future) {
7591
- const state = getPromiseResult(future);
7592
- const promiseState = Object.create(RequestStateProto);
7593
- promiseState._request = future;
7594
- // @ts-expect-error - we still attach it for PendingState
7595
- promiseState.reload = () => {
7596
- (test => {
7597
- if (!test) {
7598
- throw new Error(`Cannot reload a request that is still pending. Await or abort the original request first.`);
7599
- }
7600
- })(!promiseState.isPending);
7601
- return performRefresh(future.requester, promiseState.request, true);
7602
- };
7603
-
7604
- // @ts-expect-error - we still attach it for PendingState
7605
- promiseState.refresh = (usePolicy = false) => {
7606
- (test => {
7607
- if (!test) {
7608
- throw new Error(`Cannot refresh a request that is still pending. Await or abort the original request first.`);
7609
- }
7610
- })(!promiseState.isPending);
7611
- return performRefresh(future.requester, promiseState.request, usePolicy === true ? null : false);
7612
- };
7613
- if (state) {
7614
- if (state.isError) {
7615
- promiseState.error = state.result;
7616
- promiseState.reason = state.result;
7617
- promiseState.status = 'rejected';
7618
- promiseState.isError = true;
7619
- promiseState.isPending = false;
7620
- promiseState.isLoading = false;
7621
- promiseState.request = state.result.request;
7622
- promiseState.response = state.result.response;
7623
- } else {
7624
- promiseState.result = state.result.content;
7625
- promiseState.value = state.result.content;
7626
- promiseState.status = 'fulfilled';
7627
- promiseState.isSuccess = true;
7628
- promiseState.isPending = false;
7629
- promiseState.isLoading = false;
7630
- promiseState.request = state.result.request;
7631
- promiseState.response = state.result.response;
7632
- }
7633
- } else {
7634
- void future.then(result => {
7635
- setPromiseResult(future, {
7636
- isError: false,
7637
- result
7638
- });
7639
- promiseState.result = result.content;
7640
- promiseState.value = result.content;
7641
- promiseState.status = 'fulfilled';
7642
- promiseState.isSuccess = true;
7643
- promiseState.isPending = false;
7644
- promiseState.isLoading = false;
7645
- promiseState.request = result.request;
7646
- promiseState.response = result.response;
7647
- }, error => {
7648
- setPromiseResult(future, {
7649
- isError: true,
7650
- result: error
7651
- });
7652
- promiseState.error = error;
7653
- promiseState.reason = error;
7654
- promiseState.status = 'rejected';
7655
- promiseState.isError = true;
7656
- promiseState.isPending = false;
7657
- promiseState.isLoading = false;
7658
- promiseState.request = error.request;
7659
- promiseState.response = error.response;
7660
- });
7661
- }
7662
- return promiseState;
7663
- }
7664
-
7665
- /**
7666
- * `getRequestState` can be used in both JavaScript and Template contexts.
7667
- *
7668
- * ```ts
7669
- * import { getRequestState } from '@warp-drive/ember';
7670
- *
7671
- * const state = getRequestState(future);
7672
- * ```
7673
- *
7674
- * For instance, we could write a getter on a component that updates whenever
7675
- * the request state advances or the future changes, by combining the function
7676
- * with the use of `@cached`
7677
- *
7678
- * ```ts
7679
- * class Component {
7680
- * @cached
7681
- * get title() {
7682
- * const state = getRequestState(this.args.request);
7683
- * if (state.isPending) {
7684
- * return 'loading...';
7685
- * }
7686
- * if (state.isError) { return null; }
7687
- * return state.result.title;
7688
- * }
7689
- * }
7690
- * ```
7691
- *
7692
- * Or in a template as a helper:
7693
- *
7694
- * ```gjs
7695
- * import { getRequestState } from '@warp-drive/ember';
7696
- *
7697
- * <template>
7698
- * {{#let (getRequestState @request) as |state|}}
7699
- * {{#if state.isPending}}
7700
- * <Spinner />
7701
- * {{else if state.isError}}
7702
- * <ErrorForm @error={{state.error}} />
7703
- * {{else}}
7704
- * <h1>{{state.result.title}}</h1>
7705
- * {{/if}}
7706
- * {{/let}}
7707
- * </template>
7708
- * ```
7709
- *
7710
- * If looking to use in a template, consider also the `<Request />` component
7711
- * which offers a number of additional capabilities for requests *beyond* what
7712
- * `RequestState` provides.
7713
- *
7714
- */
7715
- function getRequestState(future) {
7716
- let state = RequestCache.get(future);
7717
- if (!state) {
7718
- state = createRequestState(future);
7719
- RequestCache.set(future, state);
7720
- }
7721
- return state;
7722
- }
7723
- function getAliasField(context) {
7724
- (test => {
7725
- {
7726
- throw new Error(`Alias field access is not implemented`);
7727
- }
7728
- })();
7729
- }
7730
- function setAliasField(context) {
7731
- (test => {
7732
- {
7733
- throw new Error(`Alias field setting is not implemented`);
7734
- }
7735
- })();
7736
- return false;
7737
- }
7738
- const ARRAY_GETTER_METHODS = new Set([Symbol.iterator, 'concat', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flat', 'flatMap', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'slice', 'some', 'values']);
7739
- // const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
7740
- const SYNC_PROPS = new Set(['[]', 'length']);
7741
- function isArrayGetter(prop) {
7742
- return ARRAY_GETTER_METHODS.has(prop);
7743
- }
7744
- const ARRAY_SETTER_METHODS = new Set(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
7745
- function isArraySetter(prop) {
7746
- return ARRAY_SETTER_METHODS.has(prop);
7747
- }
7748
-
7749
- // function isSelfProp<T extends object>(self: T, prop: KeyType): prop is keyof T {
7750
- // return prop in self;
7751
- // }
7752
-
7753
- function convertToInt(prop) {
7754
- if (typeof prop === 'symbol') return null;
7755
- const num = Number(prop);
7756
- if (isNaN(num)) return null;
7757
- return num % 1 === 0 ? num : null;
7758
- }
7759
- function safeForEach(instance, arr, store, callback, target) {
7760
- if (target === undefined) {
7761
- target = null;
7762
- }
7763
- // clone to prevent mutation
7764
- arr = arr.slice();
7765
- (test => {
7766
- if (!test) {
7767
- throw new Error('`forEach` expects a function as first argument.');
7768
- }
7769
- })(typeof callback === 'function');
7770
-
7771
- // because we retrieveLatest above we need not worry if array is mutated during iteration
7772
- // by unloadRecord/rollbackAttributes
7773
- // push/add/removeObject may still be problematic
7774
- // but this is a more traditionally expected forEach bug.
7775
- const length = arr.length; // we need to access length to ensure we are consumed
6170
+ // because we retrieveLatest above we need not worry if array is mutated during iteration
6171
+ // by unloadRecord/rollbackAttributes
6172
+ // push/add/removeObject may still be problematic
6173
+ // but this is a more traditionally expected forEach bug.
6174
+ const length = arr.length; // we need to access length to ensure we are consumed
7776
6175
 
7777
6176
  for (let index = 0; index < length; index++) {
7778
6177
  callback.call(target, arr[index], index, instance);
@@ -10446,173 +8845,6 @@ function mergeMap(base, toApply) {
10446
8845
  base.set(key, value);
10447
8846
  }
10448
8847
  }
10449
- const PromiseCache = new WeakMap();
10450
-
10451
- /**
10452
- * The state of a promise in the "pending"
10453
- * state. This is the default initial state.
10454
- *
10455
- */
10456
-
10457
- /**
10458
- * The state of a promise in the "fulfilled" state.
10459
- * This is the state of a promise that has resolved
10460
- * successfully.
10461
- *
10462
- */
10463
-
10464
- /**
10465
- * The state of a promise in the "rejected" state.
10466
- * This is the state of a promise that has rejected
10467
- * with an error.
10468
- *
10469
- */
10470
-
10471
- /**
10472
- * The state of a promise. This is the type that is returned
10473
- * from `getPromiseState`.
10474
- *
10475
- * See also:
10476
- * - {@link PendingPromise}
10477
- * - {@link ResolvedPromise}
10478
- * - {@link RejectedPromise}
10479
- *
10480
- */
10481
-
10482
- const PromiseStateProto = {};
10483
-
10484
- // TODO introduce a new mechanism for defining multiple properties
10485
- // that share a common signal
10486
- defineSignal(PromiseStateProto, 'reason', null);
10487
- defineSignal(PromiseStateProto, 'value', null);
10488
- defineSignal(PromiseStateProto, 'result', null);
10489
- defineSignal(PromiseStateProto, 'error', null);
10490
- defineSignal(PromiseStateProto, 'status', 'pending');
10491
- defineSignal(PromiseStateProto, 'isPending', true);
10492
- defineSignal(PromiseStateProto, 'isLoading', true);
10493
- defineSignal(PromiseStateProto, 'isSuccess', false);
10494
- defineSignal(PromiseStateProto, 'isError', false);
10495
- function createPromiseState(promise) {
10496
- const state = getPromiseResult(promise);
10497
- const promiseState = Object.create(PromiseStateProto);
10498
- if (state) {
10499
- if (state.isError) {
10500
- promiseState.error = state.result;
10501
- promiseState.reason = state.result;
10502
- promiseState.status = 'rejected';
10503
- promiseState.isError = true;
10504
- promiseState.isPending = false;
10505
- promiseState.isLoading = false;
10506
- } else {
10507
- promiseState.result = state.result;
10508
- promiseState.value = state.result;
10509
- promiseState.status = 'fulfilled';
10510
- promiseState.isSuccess = true;
10511
- promiseState.isPending = false;
10512
- promiseState.isLoading = false;
10513
- }
10514
- } else {
10515
- void promise.then(result => {
10516
- setPromiseResult(promise, {
10517
- isError: false,
10518
- result
10519
- });
10520
- promiseState.result = result;
10521
- promiseState.value = result;
10522
- promiseState.status = 'fulfilled';
10523
- promiseState.isSuccess = true;
10524
- promiseState.isPending = false;
10525
- promiseState.isLoading = false;
10526
- }, error => {
10527
- setPromiseResult(promise, {
10528
- isError: true,
10529
- result: error
10530
- });
10531
- promiseState.error = error;
10532
- promiseState.reason = error;
10533
- promiseState.status = 'rejected';
10534
- promiseState.isError = true;
10535
- promiseState.isPending = false;
10536
- promiseState.isLoading = false;
10537
- });
10538
- }
10539
- return promiseState;
10540
- }
10541
- const LegacyPromiseProxy = Symbol.for('LegacyPromiseProxy');
10542
- function isLegacyAwaitable(promise) {
10543
- return LegacyPromiseProxy in promise && 'promise' in promise && promise[LegacyPromiseProxy] === true;
10544
- }
10545
- function getPromise(promise) {
10546
- return isLegacyAwaitable(promise) ? promise.promise : promise;
10547
- }
10548
-
10549
- /**
10550
- * Returns a reactive state-machine for the provided promise or awaitable.
10551
- *
10552
- * Repeat calls to `getPromiseState` with the same promise will return the same state object
10553
- * making is safe and easy to use in templates and JavaScript code to produce reactive
10554
- * behaviors around promises.
10555
- *
10556
- * `getPromiseState` can be used in both JavaScript and Template contexts.
10557
- *
10558
- * ```ts
10559
- * import { getPromiseState } from '@warp-drive/ember';
10560
- *
10561
- * const state = getPromiseState(promise);
10562
- * ```
10563
- *
10564
- * For instance, we could write a getter on a component that updates whenever
10565
- * the promise state advances or the promise changes, by combining the function
10566
- * with the use of `@cached`
10567
- *
10568
- * ```ts
10569
- * class Component {
10570
- * @cached
10571
- * get title() {
10572
- * const state = getPromiseState(this.args.request);
10573
- * if (state.isPending) {
10574
- * return 'loading...';
10575
- * }
10576
- * if (state.isError) { return null; }
10577
- * return state.result.title;
10578
- * }
10579
- * }
10580
- * ```
10581
- *
10582
- * Or in a template as a helper:
10583
- *
10584
- * ```gjs
10585
- * import { getPromiseState } from '@warp-drive/ember';
10586
- *
10587
- * <template>
10588
- * {{#let (getPromiseState @request) as |state|}}
10589
- * {{#if state.isPending}} <Spinner />
10590
- * {{else if state.isError}} <ErrorForm @error={{state.error}} />
10591
- * {{else}}
10592
- * <h1>{{state.result.title}}</h1>
10593
- * {{/if}}
10594
- * {{/let}}
10595
- * </template>
10596
- * ```
10597
- *
10598
- * If looking to use in a template, consider also the `<Await />` component.
10599
- *
10600
- * See also {@link PromiseState}
10601
- */
10602
- function getPromiseState(promise) {
10603
- (test => {
10604
- if (!test) {
10605
- throw new Error(`getPromiseState expects to be called with a promise: called with ${String(promise)}`);
10606
- }
10607
- })(promise);
10608
- const _promise = getPromise(promise);
10609
- let state = PromiseCache.get(_promise);
10610
- if (!state) {
10611
- state = createPromiseState(_promise);
10612
- PromiseCache.set(_promise, state);
10613
- }
10614
- return state;
10615
- }
10616
8848
 
10617
8849
  // Lazily close over fetch to avoid breaking Mirage
10618
8850
  const _fetch = typeof fetch !== 'undefined' ? (...args) => fetch(...args) : typeof FastBoot !== 'undefined' ? (...args) => FastBoot.require('node-fetch')(...args) : () => {
@@ -11157,4 +9389,4 @@ function useRecommendedStore(options, StoreKlass = Store) {
11157
9389
  }
11158
9390
  };
11159
9391
  }
11160
- export { setIdentifierResetMethod as $, logGroup as A, signal as B, CacheHandler as C, DISPOSE as D, memoized as E, gate as F, entangleSignal as G, entangleInitiallyStaleSignal as H, defineSignal as I, defineGate as J, defineNonEnumerableSignal as K, Signals as L, peekInternalSignal as M, createInternalMemo as N, withSignalStore as O, notifyInternalSignal as P, consumeInternalSignal as Q, RecordArrayManager as R, SchemaService as S, getOrCreateInternalSignal as T, Fetch as U, RequestManager as V, useRecommendedStore as W, setIdentifierGenerationMethod as X, setIdentifierUpdateMethod as Y, setIdentifierForgetMethod as Z, _clearCaches as _, commit as a, setKeyInfoForResource as a0, createRequestSubscription as b, checkout as c, getPromiseState as d, isResourceKey as e, fromIdentity as f, getRequestState as g, coerceId as h, instantiateRecord as i, Store as j, recordIdentifierFor as k, isRequestKey as l, ensureStringId as m, fastPush as n, assertPrivateStore as o, isPrivateStore as p, assertPrivateCapabilities as q, registerDerivations as r, storeFor as s, teardownRecord as t, setRecordIdentifier as u, StoreMap as v, withDefaults as w, normalizeModelName as x, createLegacyManyArray as y, log as z };
9392
+ export { setIdentifierGenerationMethod as A, setIdentifierUpdateMethod as B, CacheHandler as C, setIdentifierForgetMethod as D, setIdentifierResetMethod as E, Fetch as F, setKeyInfoForResource as G, RecordArrayManager as R, Store as S, _clearCaches as _, isRequestKey as a, assertPrivateStore as b, coerceId as c, isPrivateStore as d, ensureStringId as e, fastPush as f, assertPrivateCapabilities as g, setRecordIdentifier as h, isResourceKey as i, StoreMap as j, createLegacyManyArray as k, log as l, logGroup as m, normalizeModelName as n, checkout as o, instantiateRecord as p, SchemaService as q, recordIdentifierFor as r, storeFor as s, teardownRecord as t, fromIdentity as u, registerDerivations as v, withDefaults as w, commit as x, RequestManager as y, useRecommendedStore as z };