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

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,287 +1,14 @@
1
+ import { d as defineGate, w as withSignalStore, n as notifyInternalSignal, p as peekInternalSignal, b as willSyncFlushWatchers, e as getOrCreateInternalSignal, f as consumeInternalSignal, h as createInternalSignal, A as ARRAY_SIGNAL, S as Signals, i as createSignalDescriptor, j as defineSignal, k as entangleSignal, l as entangleInitiallyStaleSignal, O as OBJECT_SIGNAL, m as createInternalMemo } from "./-leaked-DRNv9VIX.js";
1
2
  import { EnableHydration, SkipCache, STRUCTURED } from './types/request.js';
2
- import { getOrSetGlobal, peekTransient, setTransient } from './types/-private.js';
3
+ import { peekTransient, setTransient, getOrSetGlobal } from './types/-private.js';
3
4
  import { isResourceSchema } from './types/schema/fields.js';
4
5
  import { D as Destroy, a as Context, S as SOURCE, C as Checkout, b as Commit } from "./-private-3C1OkYtZ.js";
5
- import { w as withBrand, b as getPromiseResult, s as setPromiseResult } from "./request-CN2LxbYX.js";
6
+ import { w as withBrand } from "./request-BrJSCG6r.js";
6
7
  import { CACHE_OWNER } from './types/identifier.js';
7
8
  import { dasherize } from './utils/string.js';
8
9
  import './types/runtime.js';
9
10
  import { RecordStore, Type } from './types/symbols.js';
10
- import { c as createSignal, a as consumeSignal, n as notifySignal, b as createMemo, d as willSyncFlushWatchers, A as ARRAY_SIGNAL, O as OBJECT_SIGNAL } from "./configure-BQ8CpIcW.js";
11
11
  import * as _importSync20 from '@ember/object';
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
- obj[Signals] = new Map();
100
- }
101
- function createInternalSignal(signals, obj, key, initialValue) {
102
- const warpDriveSignal = {
103
- key,
104
- context: obj,
105
- signal: createSignal(obj, key),
106
- value: isInitializer(initialValue) ? initialValue.value.call(obj) : initialValue,
107
- isStale: false
108
- };
109
- signals.set(key, warpDriveSignal);
110
- return warpDriveSignal;
111
- }
112
- function getOrCreateInternalSignal(signals, obj, key, initialValue) {
113
- let signal = peekInternalSignal(signals, key);
114
- if (!signal) {
115
- signal = createInternalSignal(signals, obj, key, initialValue);
116
- }
117
- return signal;
118
- }
119
- function createInternalMemo(signals, object, key, fn) {
120
- {
121
- const memo = createMemo(object, key, fn);
122
- signals.set(key, memo);
123
- return memo;
124
- }
125
- }
126
- function peekInternalSignal(signals, key) {
127
- return signals?.get(key);
128
- }
129
- function consumeInternalSignal(signal) {
130
- consumeSignal(signal.signal);
131
- }
132
- function notifyInternalSignal(signal) {
133
- if (signal) {
134
- signal.isStale = true;
135
- notifySignal(signal.signal);
136
- }
137
- }
138
-
139
- /**
140
- * Creates a signal for the key/object pairing and subscribes to the signal.
141
- *
142
- * Use when you need to ensure a signal exists and is subscribed to.
143
- *
144
- * @private
145
- */
146
- function entangleSignal(signals, obj, key, initialValue) {
147
- let internalSignal = peekInternalSignal(signals, key);
148
- if (!internalSignal) {
149
- internalSignal = createInternalSignal(signals, obj, key, initialValue);
150
- }
151
- consumeInternalSignal(internalSignal);
152
- return internalSignal;
153
- }
154
- function entangleInitiallyStaleSignal(signals, obj, key, initialValue) {
155
- let internalSignal = peekInternalSignal(signals, key);
156
- if (!internalSignal) {
157
- internalSignal = createInternalSignal(signals, obj, key, initialValue);
158
- internalSignal.isStale = true; // mark it as stale
159
- }
160
- consumeInternalSignal(internalSignal);
161
- return internalSignal;
162
- }
163
- function createSignalDescriptor(key, intialValue) {
164
- return {
165
- enumerable: true,
166
- configurable: false,
167
- get() {
168
- const signals = withSignalStore(this);
169
- const internalSignal = entangleSignal(signals, this, key, intialValue);
170
- internalSignal.isStale = false; // reset stale state
171
- return internalSignal.value;
172
- },
173
- set(value) {
174
- const signals = withSignalStore(this);
175
- const internalSignal = getOrCreateInternalSignal(signals, this, key, intialValue);
176
- if (internalSignal.value !== value) {
177
- internalSignal.value = value;
178
- notifyInternalSignal(internalSignal);
179
- }
180
- }
181
- };
182
- }
183
-
184
- /**
185
- * define an enumerable signal property.
186
- *
187
- * Akin to Object.defineProperty.
188
- *
189
- * The signal will be lazily created when accessed and scoped to the
190
- * instance of the object.
191
- *
192
- * @private
193
- */
194
- function defineSignal(obj, key, v) {
195
- Object.defineProperty(obj, key, createSignalDescriptor(key, v));
196
- }
197
-
198
- /**
199
- * Define a non-enumerable signal property.
200
- *
201
- * @private
202
- */
203
- function defineNonEnumerableSignal(obj, key, v) {
204
- const desc = createSignalDescriptor(key, v);
205
- desc.enumerable = false;
206
- Object.defineProperty(obj, key, desc);
207
- }
208
- /**
209
- * Decorator version of creating a signal.
210
- */
211
- function signal(target, key, descriptor) {
212
- return createSignalDescriptor(key, descriptor.initializer ? makeInitializer(descriptor.initializer) : null);
213
- }
214
-
215
- /**
216
- * Decorator version of creating a memoized getter
217
- */
218
- function memoized(target, key, descriptor) {
219
- // eslint-disable-next-line @typescript-eslint/unbound-method
220
- const getter = descriptor.get;
221
- descriptor.get = function () {
222
- const signals = withSignalStore(this);
223
- let memoSignal = signals.get(key);
224
- if (!memoSignal) {
225
- memoSignal = createInternalMemo(signals, this, key, getter.bind(this));
226
- }
227
- return memoSignal();
228
- };
229
- return descriptor;
230
- }
231
-
232
- /**
233
- * Decorator version of creating a gate.
234
- *
235
- * @private
236
- */
237
- function gate(_target, key, desc) {
238
- // eslint-disable-next-line @typescript-eslint/unbound-method
239
- const getter = desc.get;
240
- // eslint-disable-next-line @typescript-eslint/unbound-method
241
- const setter = desc.set;
242
- const isLocal = desc.isLocal;
243
- desc.get = function () {
244
- const signals = withSignalStore(this);
245
- let internalSignal = peekInternalSignal(signals, key);
246
- if (!internalSignal) {
247
- internalSignal = createInternalSignal(signals, this, key, getter.call(this));
248
- } else if (internalSignal.isStale) {
249
- internalSignal.isStale = false;
250
- internalSignal.value = getter.call(this);
251
- }
252
- consumeInternalSignal(internalSignal);
253
- return internalSignal.value;
254
- };
255
- if (setter) {
256
- desc.set = function (v) {
257
- const signals = withSignalStore(this);
258
- let internalSignal = peekInternalSignal(signals, key);
259
- if (!internalSignal) {
260
- // we can't use `v` as initialValue here because setters don't
261
- // return the value and the final value may be different
262
- // than what the setter was called with.
263
- internalSignal = createInternalSignal(signals, this, key, undefined);
264
- internalSignal.isStale = true;
265
- }
266
- setter.call(this, v);
267
- // when a gate is set, we do not notify the signal
268
- // as its update is controlled externally.
269
- // unless it specifically sets itself to be locally managed
270
- if (isLocal) {
271
- internalSignal.isStale = true;
272
- notifyInternalSignal(internalSignal);
273
- }
274
- };
275
- }
276
- return desc;
277
- }
278
- function defineGate(obj, key, desc) {
279
- const options = Object.assign({
280
- enumerable: true,
281
- configurable: false
282
- }, gate(obj, key, desc));
283
- Object.defineProperty(obj, key, options);
284
- }
285
12
  function urlFromLink(link) {
286
13
  if (typeof link === 'string') return link;
287
14
  return link.href;
@@ -4191,7 +3918,7 @@ class RecordReference {
4191
3918
  simplest usage of this API is similar to `store.push`: you provide a
4192
3919
  normalized hash of data and the object represented by the reference
4193
3920
  will update.
4194
- If you pass a promise to `push`, Ember Data will not ask the adapter
3921
+ If you pass a promise to `push`, WarpDrive will not ask the adapter
4195
3922
  for the data if another attempt to fetch it is made in the
4196
3923
  interim. When the promise resolves, the underlying object is updated
4197
3924
  with the new data, and the promise returned by *this function* is resolved
@@ -4563,7 +4290,7 @@ function constructResource(type, id, lid) {
4563
4290
 
4564
4291
  ### Inverses
4565
4292
 
4566
- Often, the relationships in Ember Data applications will have
4293
+ Often, the relationships in WarpDrive applications will have
4567
4294
  an inverse. For example, imagine the following models are
4568
4295
  defined:
4569
4296
 
@@ -4882,1143 +4609,59 @@ function mutate(collection, mutation, _SIGNAL) {
4882
4609
  manager.mutate(mutation);
4883
4610
  notifyInternalSignal(_SIGNAL);
4884
4611
  }
4885
- function decorateMethodV2(prototype, prop, decorators) {
4886
- const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
4887
- let desc = {
4888
- ...origDesc
4889
- };
4890
- for (let decorator of decorators) {
4891
- desc = decorator(prototype, prop, desc) || desc;
4892
- }
4893
- if (desc.initializer !== void 0) {
4894
- desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
4895
- desc.initializer = void 0;
4896
- }
4897
- Object.defineProperty(prototype, prop, desc);
4612
+ function getAliasField(context) {}
4613
+ function setAliasField(context) {
4614
+ return false;
4615
+ }
4616
+ 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']);
4617
+ // const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
4618
+ const SYNC_PROPS = new Set(['[]', 'length']);
4619
+ function isArrayGetter(prop) {
4620
+ return ARRAY_GETTER_METHODS.has(prop);
4621
+ }
4622
+ const ARRAY_SETTER_METHODS = new Set(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
4623
+ function isArraySetter(prop) {
4624
+ return ARRAY_SETTER_METHODS.has(prop);
4898
4625
  }
4899
4626
 
4900
- // default to 30 seconds unavailable before we refresh
4901
- const DEFAULT_DEADLINE = 30_000;
4902
- const DISPOSE = Symbol.dispose || Symbol.for('dispose');
4903
-
4904
- /**
4905
- * Utilities to assist in recovering from the error.
4906
- */
4907
-
4908
- /** @deprecated use {@link RecoveryFeatures} */
4909
-
4910
- /**
4911
- * Utilities for keeping the request fresh
4912
- */
4913
-
4914
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4915
-
4916
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4917
-
4918
- /**
4919
- * A reactive class
4920
- *
4921
- * @hideconstructor
4922
- */
4923
- class RequestSubscription {
4924
- /**
4925
- * Whether the browser reports that the network is online.
4926
- */
4927
-
4928
- /**
4929
- * Whether the browser reports that the tab is hidden.
4930
- */
4931
-
4932
- /**
4933
- * Whether the component is currently refreshing the request.
4934
- */
4935
-
4936
- /**
4937
- * The most recent blocking request that was made, typically
4938
- * the result of a reload.
4939
- *
4940
- * This will never be the original request passed as an arg to
4941
- * the component.
4942
- *
4943
- * @internal
4944
- */
4945
-
4946
- /**
4947
- * The most recent request that was made, typically due to either a
4948
- * reload or a refresh.
4949
- *
4950
- * This will never be the original request passed as an arg to
4951
- * the component.
4952
- *
4953
- * @internal
4954
- */
4955
-
4956
- /**
4957
- * The time at which the network was reported as offline.
4958
- *
4959
- * @internal
4960
- */
4961
-
4962
- /** @internal */
4963
-
4964
- /** @internal */
4965
-
4966
- /** @internal */
4967
-
4968
- /** @internal */
4969
-
4970
- /** @internal */
4971
-
4972
- /**
4973
- * The event listener for network status changes,
4974
- * cached to use the reference for removal.
4975
- *
4976
- * @internal
4977
- */
4978
-
4979
- /**
4980
- * The event listener for visibility status changes,
4981
- * cached to use the reference for removal.
4982
- *
4983
- * @internal
4984
- */
4985
-
4986
- /**
4987
- * The last request passed as an arg to the component,
4988
- * cached for comparison.
4989
- *
4990
- * @internal
4991
- */
4992
-
4993
- /**
4994
- * The last query passed as an arg to the component,
4995
- * cached for comparison.
4996
- *
4997
- * @internal
4998
- */
4999
-
5000
- /** @internal */
5001
-
5002
- /** @internal */
5003
-
5004
- /** @internal */
5005
-
5006
- /**
5007
- * The Store this subscription subscribes to or the RequestManager
5008
- * which issues this request.
5009
- */
4627
+ // function isSelfProp<T extends object>(self: T, prop: KeyType): prop is keyof T {
4628
+ // return prop in self;
4629
+ // }
5010
4630
 
5011
- /**
5012
- * The Store or RequestManager that the last subscription is attached to.
5013
- *
5014
- * This differs from 'store' because a <Request /> may be passed a
5015
- * request originating from a different store than the <Request />
5016
- * component would use if it were to issue the request itself.
5017
- *
5018
- * @internal
5019
- */
5020
- _requester;
5021
- constructor(store, args) {
5022
- this._args = args;
5023
- this.store = store;
5024
- this._subscribedTo = null;
5025
- this._subscription = null;
5026
- this._intervalStart = null;
5027
- this._invalidated = false;
5028
- this._nextInterval = null;
5029
- this._requester = null;
5030
- this.isDestroyed = false;
5031
- this[DISPOSE] = _DISPOSE;
5032
- this._installListeners();
5033
- void this._beginPolling();
4631
+ function convertToInt(prop) {
4632
+ if (typeof prop === 'symbol') return null;
4633
+ const num = Number(prop);
4634
+ if (isNaN(num)) return null;
4635
+ return num % 1 === 0 ? num : null;
4636
+ }
4637
+ function safeForEach(instance, arr, store, callback, target) {
4638
+ if (target === undefined) {
4639
+ target = null;
5034
4640
  }
4641
+ // clone to prevent mutation
4642
+ arr = arr.slice();
5035
4643
 
5036
- /**
5037
- * @internal
5038
- */
5039
- async _beginPolling() {
5040
- // await the initial request
5041
- try {
5042
- if (!this.isIdle) {
5043
- await this.request;
5044
- }
5045
- } catch {
5046
- // ignore errors here, we just want to wait for the request to finish
5047
- } finally {
5048
- if (!this.isDestroyed) {
5049
- void this._scheduleInterval();
5050
- }
5051
- }
5052
- }
5053
- get isIdle() {
5054
- const {
5055
- request,
5056
- query
5057
- } = this._args;
5058
- return Boolean(!request && !query);
5059
- }
5060
- static {
5061
- decorateMethodV2(this.prototype, "isIdle", [memoized]);
5062
- }
5063
- get autorefreshTypes() {
5064
- const {
5065
- autorefresh
5066
- } = this._args;
5067
- let types;
5068
- if (autorefresh === true) {
5069
- types = ['online', 'invalid'];
5070
- } else if (typeof autorefresh === 'string') {
5071
- types = autorefresh.split(',');
5072
- } else {
5073
- types = [];
5074
- }
5075
- return new Set(types);
5076
- }
4644
+ // because we retrieveLatest above we need not worry if array is mutated during iteration
4645
+ // by unloadRecord/rollbackAttributes
4646
+ // push/add/removeObject may still be problematic
4647
+ // but this is a more traditionally expected forEach bug.
4648
+ const length = arr.length; // we need to access length to ensure we are consumed
5077
4649
 
5078
- // we only run this function on component creation
5079
- // and when an update is triggered, so it does not
5080
- // react to changes in the autorefreshThreshold
5081
- // or autorefresh args.
5082
- //
5083
- // if we need to react to those changes, we can
5084
- // use a modifier or internal component or some
5085
- // such to trigger a re-run of this function.
5086
- /** @internal */
5087
- static {
5088
- decorateMethodV2(this.prototype, "autorefreshTypes", [memoized]);
4650
+ for (let index = 0; index < length; index++) {
4651
+ callback.call(target, arr[index], index, instance);
5089
4652
  }
5090
- async _scheduleInterval() {
5091
- const {
5092
- autorefreshThreshold
5093
- } = this._args;
5094
- const hasValidThreshold = typeof autorefreshThreshold === 'number' && autorefreshThreshold > 0;
5095
- if (
5096
- // dont schedule in SSR
5097
- typeof window === 'undefined' ||
5098
- // dont schedule without a threshold
5099
- !hasValidThreshold ||
5100
- // dont schedule if we weren't told to
5101
- !this.autorefreshTypes.has('interval') ||
5102
- // dont schedule if we're already scheduled
5103
- this._intervalStart !== null) {
5104
- return;
5105
- }
5106
-
5107
- // if we have a current request, wait for it to finish
5108
- // before scheduling the next one
5109
- if (this._latestRequest) {
5110
- try {
5111
- await this._latestRequest;
5112
- } catch {
5113
- // ignore errors here, we just want to wait for the request to finish
5114
- }
5115
- if (this.isDestroyed) {
5116
- return;
5117
- }
5118
- }
5119
-
5120
- // setup the next interval
5121
- this._intervalStart = Date.now();
5122
- this._nextInterval = setTimeout(() => {
5123
- this._maybeUpdate();
5124
- }, autorefreshThreshold);
5125
- }
5126
-
5127
- /** @internal */
5128
- _clearInterval() {
5129
- if (this._nextInterval) {
5130
- clearTimeout(this._nextInterval);
5131
- this._intervalStart = null;
5132
- }
5133
- }
5134
- /**
5135
- * @internal
5136
- */
5137
- _updateSubscriptions() {
5138
- if (this.isIdle) {
5139
- return;
5140
- }
5141
- const requestId = this._request.lid;
5142
-
5143
- // if we're already subscribed to this request, we don't need to do anything
5144
- if (this._subscribedTo === requestId) {
5145
- return;
5146
- }
5147
-
5148
- // if we're subscribed to a different request, we need to unsubscribe
5149
- this._removeSubscriptions();
5150
-
5151
- // if we have a request, we need to subscribe to it
5152
- const store = this._getRequester();
5153
- this._requester = store;
5154
- if (requestId && isStore(store)) {
5155
- this._subscribedTo = requestId;
5156
- this._subscription = store.notifications.subscribe(requestId, (_id, op) => {
5157
- // ignore subscription events that occur while our own component's request
5158
- // is occurring
5159
- if (this._isUpdating) {
5160
- return;
5161
- }
5162
- switch (op) {
5163
- case 'invalidated':
5164
- {
5165
- // if we're subscribed to invalidations, we need to update
5166
- if (this.autorefreshTypes.has('invalid')) {
5167
- this._invalidated = true;
5168
- this._maybeUpdate();
5169
- }
5170
- break;
5171
- }
5172
- case 'state':
5173
- {
5174
- const latest = store.requestManager._deduped.get(requestId);
5175
- const priority = latest?.priority;
5176
- const state = this.reqState;
5177
- if (!priority) {
5178
- // if there is no priority, we have completed whatever request
5179
- // was occurring and so we are no longer refreshing (if we were)
5180
- this.isRefreshing = false;
5181
- } else if (priority.blocking && !state.isLoading) {
5182
- // if we are blocking, there is an active request for this identity
5183
- // that MUST be fulfilled from network (not cache).
5184
- // Thus this is not "refreshing" because we should clear out and
5185
- // block on this request.
5186
- //
5187
- // we receive state notifications when either a request initiates
5188
- // or completes.
5189
- //
5190
- // In the completes case: we may receive the state notification
5191
- // slightly before the request is finalized because the NotificationManager
5192
- // may sync flush it (and thus deliver it before the microtask completes)
5193
- //
5194
- // In the initiates case: we aren't supposed to receive one unless there
5195
- // is no other request in flight for this identity.
5196
- //
5197
- // However, there is a race condition here where the completed
5198
- // notification can trigger an update that generates a new request
5199
- // thus giving us an initiated notification before the older request
5200
- // finalizes.
5201
- //
5202
- // When this occurs, if the triggered update happens to have caused
5203
- // a new request to be made for the same identity AND that request
5204
- // is the one passed into this component as the @request arg, then
5205
- // getRequestState will return the state of the new request.
5206
- // We can detect this by checking if the request state is "loading"
5207
- // as outside of this case we would have a completed request.
5208
- //
5209
- // That is the reason for the `&& !state.isLoading` check above.
5210
-
5211
- // TODO should we just treat this as refreshing?
5212
- this.isRefreshing = false;
5213
- this._maybeUpdate('policy', true);
5214
- } else {
5215
- this.isRefreshing = true;
5216
- }
5217
- }
5218
- }
5219
- });
5220
- }
5221
- }
5222
-
5223
- /**
5224
- * @internal
5225
- */
5226
- _removeSubscriptions() {
5227
- const store = this._requester;
5228
- if (this._subscription && store && isStore(store)) {
5229
- store.notifications.unsubscribe(this._subscription);
5230
- this._subscribedTo = null;
5231
- this._subscription = null;
5232
- this._requester = null;
5233
- }
5234
- }
5235
-
5236
- /**
5237
- * Install the event listeners for network and visibility changes.
5238
- * This is only done in browser environments with a global `window`.
5239
- *
5240
- * @internal
5241
- */
5242
- _installListeners() {
5243
- if (typeof window === 'undefined') {
5244
- return;
5245
- }
5246
- this.isOnline = window.navigator.onLine;
5247
- this._unavailableStart = this.isOnline ? null : Date.now();
5248
- this.isHidden = document.visibilityState === 'hidden';
5249
- this._onlineChanged = event => {
5250
- this.isOnline = event.type === 'online';
5251
- if (event.type === 'offline' && this._unavailableStart === null) {
5252
- this._unavailableStart = Date.now();
5253
- }
5254
- this._maybeUpdate();
5255
- };
5256
- this._backgroundChanged = () => {
5257
- const isHidden = document.visibilityState === 'hidden';
5258
- this.isHidden = isHidden;
5259
- if (isHidden && this._unavailableStart === null) {
5260
- this._unavailableStart = Date.now();
5261
- }
5262
- this._maybeUpdate();
5263
- };
5264
- window.addEventListener('online', this._onlineChanged, {
5265
- passive: true,
5266
- capture: true
5267
- });
5268
- window.addEventListener('offline', this._onlineChanged, {
5269
- passive: true,
5270
- capture: true
5271
- });
5272
- document.addEventListener('visibilitychange', this._backgroundChanged, {
5273
- passive: true,
5274
- capture: true
5275
- });
5276
- }
5277
-
5278
- /**
5279
- * If the network is online and the tab is visible, either reload or refresh the request
5280
- * based on the component's configuration and the requested update mode.
5281
- *
5282
- * Valid modes are:
5283
- *
5284
- * - `'reload'`: Force a reload of the request.
5285
- * - `'refresh'`: Refresh the request in the background.
5286
- * - `'policy'`: Make the request, letting the store's configured CachePolicy decide whether to reload, refresh, or do nothing.
5287
- * - `undefined`: Make the request using the component's autorefreshBehavior setting if the autorefreshThreshold has passed.
5288
- *
5289
- * @internal
5290
- */
5291
- _maybeUpdate(mode, silent) {
5292
- if (this.isIdle) {
5293
- return;
5294
- }
5295
- const {
5296
- reqState
5297
- } = this;
5298
- if (reqState.isPending) {
5299
- return;
5300
- }
5301
- const canAttempt = Boolean(this.isOnline && !this.isHidden && (mode || this.autorefreshTypes.size));
5302
- if (!canAttempt) {
5303
- if (!silent && mode && mode !== '_invalidated') {
5304
- throw new Error(`Reload not available: the network is not online or the tab is hidden`);
5305
- }
5306
- return;
5307
- }
5308
- const {
5309
- autorefreshTypes
5310
- } = this;
5311
- let shouldAttempt = this._invalidated || Boolean(mode);
5312
- if (!shouldAttempt && autorefreshTypes.has('online')) {
5313
- const {
5314
- _unavailableStart
5315
- } = this;
5316
- const {
5317
- autorefreshThreshold
5318
- } = this._args;
5319
- const deadline = typeof autorefreshThreshold === 'number' ? autorefreshThreshold : DEFAULT_DEADLINE;
5320
- shouldAttempt = Boolean(_unavailableStart && Date.now() - _unavailableStart > deadline);
5321
- }
5322
- if (!shouldAttempt && autorefreshTypes.has('interval')) {
5323
- const {
5324
- _intervalStart
5325
- } = this;
5326
- const {
5327
- autorefreshThreshold
5328
- } = this._args;
5329
- if (_intervalStart && typeof autorefreshThreshold === 'number' && autorefreshThreshold > 0) {
5330
- shouldAttempt = Boolean(Date.now() - _intervalStart >= autorefreshThreshold);
5331
- }
5332
- }
5333
- this._unavailableStart = null;
5334
- this._invalidated = false;
5335
- if (shouldAttempt) {
5336
- this._clearInterval();
5337
- this._isUpdating = true;
5338
- const realMode = mode === '_invalidated' ? null : mode;
5339
- const val = realMode ?? this._args.autorefreshBehavior ?? 'policy';
5340
-
5341
- // if the future was generated by an older store version, it may not have
5342
- // a requester set. In this case we append it to ensure that reload and
5343
- // refresh will work appropriately.
5344
- const requester = this._getRequester();
5345
- if (!reqState._request.requester) {
5346
- reqState._request.requester = requester;
5347
- }
5348
- switch (val) {
5349
- case 'reload':
5350
- this._latestRequest = reqState.reload();
5351
- break;
5352
- case 'refresh':
5353
- this._latestRequest = reqState.refresh();
5354
- break;
5355
- case 'policy':
5356
- this._latestRequest = reqState.refresh(true);
5357
- break;
5358
- }
5359
- if (val !== 'refresh') {
5360
- this._localRequest = this._latestRequest;
5361
- }
5362
- void this._scheduleInterval();
5363
- void this._latestRequest.finally(() => {
5364
- this._isUpdating = false;
5365
- });
5366
- }
5367
- }
5368
-
5369
- /**
5370
- * @internal
5371
- */
5372
- _getRequester() {
5373
- // Note: we check for the requester's presence
5374
- // as well as the request's presence because we may
5375
- // be subscribed to a request issued by a store from an older
5376
- // version of the library that didn't yet set requester.
5377
- if (this._args.request?.requester) {
5378
- return this._args.request.requester;
5379
- }
5380
- return this.store;
5381
- }
5382
-
5383
- /**
5384
- * Retry the request, reloading it from the server.
5385
- */
5386
- retry = async () => {
5387
- this._maybeUpdate('reload');
5388
- await this._localRequest;
5389
- };
5390
-
5391
- /**
5392
- * Refresh the request, updating it in the background.
5393
- */
5394
- refresh = async () => {
5395
- this._maybeUpdate('refresh');
5396
- await this._latestRequest;
5397
- };
5398
-
5399
- /**
5400
- * features to yield to the error slot of a component
5401
- */
5402
- get errorFeatures() {
5403
- return {
5404
- isHidden: this.isHidden,
5405
- isOnline: this.isOnline,
5406
- retry: this.retry
5407
- };
5408
- }
5409
-
5410
- /**
5411
- * features to yield to the content slot of a component
5412
- */
5413
- static {
5414
- decorateMethodV2(this.prototype, "errorFeatures", [memoized]);
5415
- }
5416
- get contentFeatures() {
5417
- const feat = {
5418
- isHidden: this.isHidden,
5419
- isOnline: this.isOnline,
5420
- reload: this.retry,
5421
- refresh: this.refresh,
5422
- isRefreshing: this.isRefreshing,
5423
- latestRequest: this._latestRequest
5424
- };
5425
- if (feat.isRefreshing) {
5426
- feat.abort = () => {
5427
- this._latestRequest?.abort();
5428
- };
5429
- }
5430
- return feat;
5431
- }
5432
-
5433
- /**
5434
- * @internal
5435
- */
5436
- static {
5437
- decorateMethodV2(this.prototype, "contentFeatures", [memoized]);
5438
- }
5439
- get _request() {
5440
- const {
5441
- request,
5442
- query
5443
- } = this._args;
5444
- const {
5445
- _localRequest,
5446
- _originalRequest,
5447
- _originalQuery
5448
- } = this;
5449
- const isOriginalRequest = request === _originalRequest && query === _originalQuery;
5450
- if (_localRequest && isOriginalRequest) {
5451
- return _localRequest;
5452
- }
5453
-
5454
- // update state checks for the next time
5455
- this._originalQuery = query;
5456
- this._originalRequest = request;
5457
- if (request) {
5458
- return request;
5459
- }
5460
- return this.store.request(query);
5461
- }
5462
- static {
5463
- decorateMethodV2(this.prototype, "_request", [memoized]);
5464
- }
5465
- get request() {
5466
- {
5467
- const request = this._request;
5468
- this._updateSubscriptions();
5469
- return request;
5470
- }
5471
- }
5472
- static {
5473
- decorateMethodV2(this.prototype, "request", [memoized]);
5474
- }
5475
- get reqState() {
5476
- return getRequestState(this.request);
5477
- }
5478
- get result() {
5479
- return this.reqState.result;
5480
- }
5481
- }
5482
- defineSignal(RequestSubscription.prototype, 'isOnline', true);
5483
- defineSignal(RequestSubscription.prototype, 'isHidden', false);
5484
- defineSignal(RequestSubscription.prototype, 'isRefreshing', false);
5485
- defineSignal(RequestSubscription.prototype, '_localRequest', undefined);
5486
- defineSignal(RequestSubscription.prototype, '_latestRequest', undefined);
5487
- function isStore(store) {
5488
- return 'requestManager' in store;
5489
- }
5490
- function createRequestSubscription(store, args) {
5491
- return new RequestSubscription(store, args);
5492
- }
5493
- function upgradeSubscription(sub) {
5494
- return sub;
5495
- }
5496
- function _DISPOSE() {
5497
- const self = upgradeSubscription(this);
5498
- self.isDestroyed = true;
5499
- self._removeSubscriptions();
5500
- if (typeof window === 'undefined') {
5501
- return;
5502
- }
5503
- self._clearInterval();
5504
- window.removeEventListener('online', self._onlineChanged, {
5505
- passive: true,
5506
- capture: true
5507
- });
5508
- window.removeEventListener('offline', self._onlineChanged, {
5509
- passive: true,
5510
- capture: true
5511
- });
5512
- document.removeEventListener('visibilitychange', self._backgroundChanged, {
5513
- passive: true,
5514
- capture: true
5515
- });
5516
- }
5517
- const RequestCache = new WeakMap();
5518
- function isAbortError(error) {
5519
- return error instanceof DOMException && error.name === 'AbortError';
5520
- }
5521
- function upgradeLoadingState(state) {
5522
- return state;
5523
- }
5524
- async function watchStream(stream, loadingState) {
5525
- const state = upgradeLoadingState(loadingState);
5526
- const reader = stream.getReader();
5527
- let bytesLoaded = 0;
5528
- let shouldForward = state._stream !== null && state._stream.readable.locked;
5529
- let isForwarding = shouldForward;
5530
- let writer = state._stream?.writable.getWriter();
5531
- const buffer = [];
5532
- state._isPending = false;
5533
- state._isStarted = true;
5534
- state._startTime = performance.now();
5535
- while (true) {
5536
- const {
5537
- value,
5538
- done
5539
- } = await reader.read();
5540
- if (done) {
5541
- break;
5542
- }
5543
- bytesLoaded += value.byteLength;
5544
- state._bytesLoaded = bytesLoaded;
5545
- state._lastPacketTime = performance.now();
5546
- shouldForward = shouldForward || state._stream !== null && state._stream.readable.locked;
5547
- if (shouldForward) {
5548
- if (!isForwarding) {
5549
- isForwarding = true;
5550
- writer = state._stream.writable.getWriter();
5551
- for (const item of buffer) {
5552
- await writer.ready;
5553
- await writer.write(item);
5554
- }
5555
- buffer.length = 0;
5556
- }
5557
- await writer.ready;
5558
- await writer.write(value);
5559
- } else {
5560
- buffer.push(value);
5561
- }
5562
- }
5563
-
5564
- // if we are still forwarding, we need to close the writer
5565
- if (isForwarding) {
5566
- await writer.ready;
5567
- await writer.close();
5568
- } else if (state._stream) {
5569
- // if we are not forwarding, we need to cancel the stream
5570
- await state._stream.readable.cancel('The Stream Has Already Ended');
5571
- state._stream = null;
5572
- }
5573
- const endTime = performance.now();
5574
- state._endTime = endTime;
5575
- state._isComplete = true;
5576
- state._isStarted = false;
5577
- }
5578
-
5579
- /**
5580
- * Lazily consumes the stream of a request, providing a number of
5581
- * reactive properties that can be used to build UIs that respond
5582
- * to the progress of a request.
5583
- *
5584
- * @hideconstructor
5585
- */
5586
- class RequestLoadingState {
5587
- /** @internal */
5588
-
5589
- /** @internal */
5590
-
5591
- /** @internal */
5592
-
5593
- /** @internal */
5594
-
5595
- /** @internal */
5596
-
5597
- /** @internal */
5598
-
5599
- /** @internal */
5600
-
5601
- /** @internal */
5602
-
5603
- /** @internal */
5604
-
5605
- /** @internal */
5606
-
5607
- /** @internal */
5608
-
5609
- /** @internal */
5610
- _stream = null;
5611
- /** @internal */
5612
- _future;
5613
- /** @internal */
5614
- _triggered = false;
5615
- /** @internal */
5616
- _trigger() {
5617
- if (this._triggered) {
5618
- return;
5619
- }
5620
- this._triggered = true;
5621
- const future = this._future;
5622
- const promise = future.getStream();
5623
- if (promise.sizeHint) {
5624
- this._sizeHint = promise.sizeHint;
5625
- }
5626
- this.promise = promise.then(stream => {
5627
- if (!stream) {
5628
- this._isPending = false;
5629
- this._isComplete = true;
5630
- return;
5631
- }
5632
- return watchStream(stream, this);
5633
- }, error => {
5634
- this._isPending = false;
5635
- this._isStarted = false;
5636
- if (isAbortError(error)) {
5637
- this._isCancelled = true;
5638
- this._isComplete = true;
5639
- }
5640
- this._isErrored = true;
5641
- this._error = error;
5642
- });
5643
- }
5644
- promise = null;
5645
- get isPending() {
5646
- this._trigger();
5647
- return this._isPending;
5648
- }
5649
- get sizeHint() {
5650
- this._trigger();
5651
- return this._sizeHint;
5652
- }
5653
- get stream() {
5654
- this._trigger();
5655
- if (!this._stream) {
5656
- if (this._isComplete || this._isCancelled || this._isErrored) {
5657
- return null;
5658
- }
5659
- this._stream = new TransformStream();
5660
- }
5661
- return this._stream.readable;
5662
- }
5663
- get isStarted() {
5664
- this._trigger();
5665
- return this._isStarted;
5666
- }
5667
- get bytesLoaded() {
5668
- this._trigger();
5669
- return this._bytesLoaded;
5670
- }
5671
- get startTime() {
5672
- this._trigger();
5673
- return this._startTime;
5674
- }
5675
- get endTime() {
5676
- this._trigger();
5677
- return this._endTime;
5678
- }
5679
- get lastPacketTime() {
5680
- this._trigger();
5681
- return this._lastPacketTime;
5682
- }
5683
- get isComplete() {
5684
- this._trigger();
5685
- return this._isComplete;
5686
- }
5687
- get isCancelled() {
5688
- this._trigger();
5689
- return this._isCancelled;
5690
- }
5691
- get isErrored() {
5692
- this._trigger();
5693
- return this._isErrored;
5694
- }
5695
- get error() {
5696
- this._trigger();
5697
- return this._error;
5698
- }
5699
- get elapsedTime() {
5700
- return (this.endTime || this.lastPacketTime) - this.startTime;
5701
- }
5702
- get completedRatio() {
5703
- return this.sizeHint ? this.bytesLoaded / this.sizeHint : 0;
5704
- }
5705
- get remainingRatio() {
5706
- return 1 - this.completedRatio;
5707
- }
5708
- get duration() {
5709
- return this.endTime - this.startTime;
5710
- }
5711
- get speed() {
5712
- // bytes per second
5713
- return this.bytesLoaded / (this.elapsedTime / 1000);
5714
- }
5715
- constructor(future) {
5716
- this._future = future;
5717
- }
5718
- abort = () => {
5719
- this._future.abort();
5720
- };
5721
- }
5722
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isPending', true);
5723
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isStarted', false);
5724
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isComplete', false);
5725
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isCancelled', false);
5726
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_isErrored', false);
5727
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_error', null);
5728
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_sizeHint', 0);
5729
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_bytesLoaded', 0);
5730
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_startTime', 0);
5731
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_endTime', 0);
5732
- defineNonEnumerableSignal(RequestLoadingState.prototype, '_lastPacketTime', 0);
5733
-
5734
- /**
5735
- * The state of a request in the "pending"
5736
- * state. This is the default initial state.
5737
- *
5738
- * Extends the {@link PendingPromise} interface.
5739
- *
5740
- */
5741
-
5742
- /**
5743
- * The state of a request in the "fulfilled" state.
5744
- * This is the state of a request that has resolved
5745
- * successfully.
5746
- *
5747
- * Extends the {@link ResolvedPromise} interface.
5748
- *
5749
- */
5750
-
5751
- /**
5752
- * The state of a request in the "rejected" state.
5753
- * This is the state of a request that has rejected
5754
- * with an error.
5755
- *
5756
- * Extends the {@link RejectedPromise} interface.
5757
- *
5758
- */
5759
-
5760
- /**
5761
- * The state of a request in the "cancelled" state.
5762
- * This is the state of a promise that has been
5763
- * cancelled.
5764
- *
5765
- */
5766
-
5767
- /**
5768
- * RequestState extends the concept of {@link PromiseState} to provide a reactive
5769
- * wrapper for a request {@link Future} which allows you write declarative code
5770
- * around a Future's control flow.
5771
- *
5772
- * It is useful in both Template and JavaScript contexts, allowing you
5773
- * to quickly derive behaviors and data from pending, error and success
5774
- * states.
5775
- *
5776
- * The key difference between a {@link Promise} and a Future is that Futures provide
5777
- * access to a {@link ReadableStream | stream} of their content, the {@link RequestKey} of the request (if any)
5778
- * as well as the ability to attempt to {@link Future.abort | abort} the request.
5779
- *
5780
- * ```ts
5781
- * interface Future<T> extends Promise<T>> {
5782
- * getStream(): Promise<ReadableStream>;
5783
- * abort(): void;
5784
- * lid: RequestKey | null;
5785
- * }
5786
- * ```
5787
- *
5788
- * These additional APIs allow us to craft even richer state experiences.
5789
- *
5790
- * To get the state of a request, use {@link getRequestState}.
5791
- *
5792
- * See also:
5793
- * - {@link PendingRequest}
5794
- * - {@link ResolvedRequest}
5795
- * - {@link RejectedRequest}
5796
- * - {@link CancelledRequest}
5797
- *
5798
- */
5799
-
5800
- const RequestStateProto = {};
5801
- function performRefresh(requester, request, isReload) {
5802
- const req = Object.assign({}, request);
5803
- const cacheOptions = Object.assign({}, req.cacheOptions);
5804
- if (isReload) {
5805
- // force direct to network
5806
- cacheOptions.reload = true;
5807
- } else if (isReload === false) {
5808
- // delete reload to ensure we use backgroundReload / policy
5809
- delete cacheOptions.reload;
5810
- cacheOptions.backgroundReload = true;
5811
- } else {
5812
- // delete props to ensure we use the policy
5813
- delete cacheOptions.backgroundReload;
5814
- delete cacheOptions.reload;
5815
- }
5816
- req.cacheOptions = cacheOptions;
5817
- return requester.request(req);
5818
- }
5819
-
5820
- // TODO introduce a new mechanism for defining multiple properties
5821
- // that share a common signal
5822
- defineSignal(RequestStateProto, 'reason', null);
5823
- defineSignal(RequestStateProto, 'value', null);
5824
- defineSignal(RequestStateProto, 'result', null);
5825
- defineSignal(RequestStateProto, 'error', null);
5826
- defineSignal(RequestStateProto, 'status', 'pending');
5827
- defineSignal(RequestStateProto, 'isPending', true);
5828
- defineSignal(RequestStateProto, 'isLoading', true);
5829
- defineSignal(RequestStateProto, 'isSuccess', false);
5830
- defineSignal(RequestStateProto, 'isError', false);
5831
- defineSignal(RequestStateProto, 'request', null);
5832
- defineSignal(RequestStateProto, 'response', null);
5833
- Object.defineProperty(RequestStateProto, 'isCancelled', {
5834
- get() {
5835
- return this.isError && isAbortError(this.reason);
5836
- }
5837
- });
5838
- Object.defineProperty(RequestStateProto, 'loadingState', {
5839
- get() {
5840
- if (!this._loadingState) {
5841
- this._loadingState = new RequestLoadingState(this._request);
5842
- }
5843
- return this._loadingState;
5844
- }
5845
- });
5846
- function createRequestState(future) {
5847
- const state = getPromiseResult(future);
5848
- const promiseState = Object.create(RequestStateProto);
5849
- promiseState._request = future;
5850
- // @ts-expect-error - we still attach it for PendingState
5851
- promiseState.reload = () => {
5852
- return performRefresh(future.requester, promiseState.request, true);
5853
- };
5854
-
5855
- // @ts-expect-error - we still attach it for PendingState
5856
- promiseState.refresh = (usePolicy = false) => {
5857
- return performRefresh(future.requester, promiseState.request, usePolicy === true ? null : false);
5858
- };
5859
- if (state) {
5860
- if (state.isError) {
5861
- promiseState.error = state.result;
5862
- promiseState.reason = state.result;
5863
- promiseState.status = 'rejected';
5864
- promiseState.isError = true;
5865
- promiseState.isPending = false;
5866
- promiseState.isLoading = false;
5867
- promiseState.request = state.result.request;
5868
- promiseState.response = state.result.response;
5869
- } else {
5870
- promiseState.result = state.result.content;
5871
- promiseState.value = state.result.content;
5872
- promiseState.status = 'fulfilled';
5873
- promiseState.isSuccess = true;
5874
- promiseState.isPending = false;
5875
- promiseState.isLoading = false;
5876
- promiseState.request = state.result.request;
5877
- promiseState.response = state.result.response;
5878
- }
5879
- } else {
5880
- void future.then(result => {
5881
- setPromiseResult(future, {
5882
- isError: false,
5883
- result
5884
- });
5885
- promiseState.result = result.content;
5886
- promiseState.value = result.content;
5887
- promiseState.status = 'fulfilled';
5888
- promiseState.isSuccess = true;
5889
- promiseState.isPending = false;
5890
- promiseState.isLoading = false;
5891
- promiseState.request = result.request;
5892
- promiseState.response = result.response;
5893
- }, error => {
5894
- setPromiseResult(future, {
5895
- isError: true,
5896
- result: error
5897
- });
5898
- promiseState.error = error;
5899
- promiseState.reason = error;
5900
- promiseState.status = 'rejected';
5901
- promiseState.isError = true;
5902
- promiseState.isPending = false;
5903
- promiseState.isLoading = false;
5904
- promiseState.request = error.request;
5905
- promiseState.response = error.response;
5906
- });
5907
- }
5908
- return promiseState;
5909
- }
5910
-
5911
- /**
5912
- * `getRequestState` can be used in both JavaScript and Template contexts.
5913
- *
5914
- * ```ts
5915
- * import { getRequestState } from '@warp-drive/ember';
5916
- *
5917
- * const state = getRequestState(future);
5918
- * ```
5919
- *
5920
- * For instance, we could write a getter on a component that updates whenever
5921
- * the request state advances or the future changes, by combining the function
5922
- * with the use of `@cached`
5923
- *
5924
- * ```ts
5925
- * class Component {
5926
- * @cached
5927
- * get title() {
5928
- * const state = getRequestState(this.args.request);
5929
- * if (state.isPending) {
5930
- * return 'loading...';
5931
- * }
5932
- * if (state.isError) { return null; }
5933
- * return state.result.title;
5934
- * }
5935
- * }
5936
- * ```
5937
- *
5938
- * Or in a template as a helper:
5939
- *
5940
- * ```gjs
5941
- * import { getRequestState } from '@warp-drive/ember';
5942
- *
5943
- * <template>
5944
- * {{#let (getRequestState @request) as |state|}}
5945
- * {{#if state.isPending}}
5946
- * <Spinner />
5947
- * {{else if state.isError}}
5948
- * <ErrorForm @error={{state.error}} />
5949
- * {{else}}
5950
- * <h1>{{state.result.title}}</h1>
5951
- * {{/if}}
5952
- * {{/let}}
5953
- * </template>
5954
- * ```
5955
- *
5956
- * If looking to use in a template, consider also the `<Request />` component
5957
- * which offers a number of additional capabilities for requests *beyond* what
5958
- * `RequestState` provides.
5959
- *
5960
- */
5961
- function getRequestState(future) {
5962
- let state = RequestCache.get(future);
5963
- if (!state) {
5964
- state = createRequestState(future);
5965
- RequestCache.set(future, state);
5966
- }
5967
- return state;
5968
- }
5969
- function getAliasField(context) {}
5970
- function setAliasField(context) {
5971
- return false;
5972
- }
5973
- 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']);
5974
- // const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
5975
- const SYNC_PROPS = new Set(['[]', 'length']);
5976
- function isArrayGetter(prop) {
5977
- return ARRAY_GETTER_METHODS.has(prop);
5978
- }
5979
- const ARRAY_SETTER_METHODS = new Set(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
5980
- function isArraySetter(prop) {
5981
- return ARRAY_SETTER_METHODS.has(prop);
5982
- }
5983
-
5984
- // function isSelfProp<T extends object>(self: T, prop: KeyType): prop is keyof T {
5985
- // return prop in self;
5986
- // }
5987
-
5988
- function convertToInt(prop) {
5989
- if (typeof prop === 'symbol') return null;
5990
- const num = Number(prop);
5991
- if (isNaN(num)) return null;
5992
- return num % 1 === 0 ? num : null;
5993
- }
5994
- function safeForEach(instance, arr, store, callback, target) {
5995
- if (target === undefined) {
5996
- target = null;
5997
- }
5998
- // clone to prevent mutation
5999
- arr = arr.slice();
6000
-
6001
- // because we retrieveLatest above we need not worry if array is mutated during iteration
6002
- // by unloadRecord/rollbackAttributes
6003
- // push/add/removeObject may still be problematic
6004
- // but this is a more traditionally expected forEach bug.
6005
- const length = arr.length; // we need to access length to ensure we are consumed
6006
-
6007
- for (let index = 0; index < length; index++) {
6008
- callback.call(target, arr[index], index, instance);
6009
- }
6010
- return instance;
6011
- }
6012
- // eslint-disable-next-line @typescript-eslint/no-extraneous-class
6013
- class ManagedArray {
6014
- constructor(context, owner, data) {
6015
- // eslint-disable-next-line @typescript-eslint/no-this-alias
6016
- const self = this;
6017
- this[SOURCE] = data?.slice();
6018
- const IS_EDITABLE = context.editable ?? false;
6019
- this[Context] = context;
6020
- const schema = context.store.schema;
6021
- const cache = context.store.cache;
4653
+ return instance;
4654
+ }
4655
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
4656
+ class ManagedArray {
4657
+ constructor(context, owner, data) {
4658
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
4659
+ const self = this;
4660
+ this[SOURCE] = data?.slice();
4661
+ const IS_EDITABLE = context.editable ?? false;
4662
+ this[Context] = context;
4663
+ const schema = context.store.schema;
4664
+ const cache = context.store.cache;
6022
4665
  const {
6023
4666
  field
6024
4667
  } = context;
@@ -8293,166 +6936,4 @@ function mergeMap(base, toApply) {
8293
6936
  base.set(key, value);
8294
6937
  }
8295
6938
  }
8296
- const PromiseCache = new WeakMap();
8297
-
8298
- /**
8299
- * The state of a promise in the "pending"
8300
- * state. This is the default initial state.
8301
- *
8302
- */
8303
-
8304
- /**
8305
- * The state of a promise in the "fulfilled" state.
8306
- * This is the state of a promise that has resolved
8307
- * successfully.
8308
- *
8309
- */
8310
-
8311
- /**
8312
- * The state of a promise in the "rejected" state.
8313
- * This is the state of a promise that has rejected
8314
- * with an error.
8315
- *
8316
- */
8317
-
8318
- /**
8319
- * The state of a promise. This is the type that is returned
8320
- * from `getPromiseState`.
8321
- *
8322
- * See also:
8323
- * - {@link PendingPromise}
8324
- * - {@link ResolvedPromise}
8325
- * - {@link RejectedPromise}
8326
- *
8327
- */
8328
-
8329
- const PromiseStateProto = {};
8330
-
8331
- // TODO introduce a new mechanism for defining multiple properties
8332
- // that share a common signal
8333
- defineSignal(PromiseStateProto, 'reason', null);
8334
- defineSignal(PromiseStateProto, 'value', null);
8335
- defineSignal(PromiseStateProto, 'result', null);
8336
- defineSignal(PromiseStateProto, 'error', null);
8337
- defineSignal(PromiseStateProto, 'status', 'pending');
8338
- defineSignal(PromiseStateProto, 'isPending', true);
8339
- defineSignal(PromiseStateProto, 'isLoading', true);
8340
- defineSignal(PromiseStateProto, 'isSuccess', false);
8341
- defineSignal(PromiseStateProto, 'isError', false);
8342
- function createPromiseState(promise) {
8343
- const state = getPromiseResult(promise);
8344
- const promiseState = Object.create(PromiseStateProto);
8345
- if (state) {
8346
- if (state.isError) {
8347
- promiseState.error = state.result;
8348
- promiseState.reason = state.result;
8349
- promiseState.status = 'rejected';
8350
- promiseState.isError = true;
8351
- promiseState.isPending = false;
8352
- promiseState.isLoading = false;
8353
- } else {
8354
- promiseState.result = state.result;
8355
- promiseState.value = state.result;
8356
- promiseState.status = 'fulfilled';
8357
- promiseState.isSuccess = true;
8358
- promiseState.isPending = false;
8359
- promiseState.isLoading = false;
8360
- }
8361
- } else {
8362
- void promise.then(result => {
8363
- setPromiseResult(promise, {
8364
- isError: false,
8365
- result
8366
- });
8367
- promiseState.result = result;
8368
- promiseState.value = result;
8369
- promiseState.status = 'fulfilled';
8370
- promiseState.isSuccess = true;
8371
- promiseState.isPending = false;
8372
- promiseState.isLoading = false;
8373
- }, error => {
8374
- setPromiseResult(promise, {
8375
- isError: true,
8376
- result: error
8377
- });
8378
- promiseState.error = error;
8379
- promiseState.reason = error;
8380
- promiseState.status = 'rejected';
8381
- promiseState.isError = true;
8382
- promiseState.isPending = false;
8383
- promiseState.isLoading = false;
8384
- });
8385
- }
8386
- return promiseState;
8387
- }
8388
- const LegacyPromiseProxy = Symbol.for('LegacyPromiseProxy');
8389
- function isLegacyAwaitable(promise) {
8390
- return LegacyPromiseProxy in promise && 'promise' in promise && promise[LegacyPromiseProxy] === true;
8391
- }
8392
- function getPromise(promise) {
8393
- return isLegacyAwaitable(promise) ? promise.promise : promise;
8394
- }
8395
-
8396
- /**
8397
- * Returns a reactive state-machine for the provided promise or awaitable.
8398
- *
8399
- * Repeat calls to `getPromiseState` with the same promise will return the same state object
8400
- * making is safe and easy to use in templates and JavaScript code to produce reactive
8401
- * behaviors around promises.
8402
- *
8403
- * `getPromiseState` can be used in both JavaScript and Template contexts.
8404
- *
8405
- * ```ts
8406
- * import { getPromiseState } from '@warp-drive/ember';
8407
- *
8408
- * const state = getPromiseState(promise);
8409
- * ```
8410
- *
8411
- * For instance, we could write a getter on a component that updates whenever
8412
- * the promise state advances or the promise changes, by combining the function
8413
- * with the use of `@cached`
8414
- *
8415
- * ```ts
8416
- * class Component {
8417
- * @cached
8418
- * get title() {
8419
- * const state = getPromiseState(this.args.request);
8420
- * if (state.isPending) {
8421
- * return 'loading...';
8422
- * }
8423
- * if (state.isError) { return null; }
8424
- * return state.result.title;
8425
- * }
8426
- * }
8427
- * ```
8428
- *
8429
- * Or in a template as a helper:
8430
- *
8431
- * ```gjs
8432
- * import { getPromiseState } from '@warp-drive/ember';
8433
- *
8434
- * <template>
8435
- * {{#let (getPromiseState @request) as |state|}}
8436
- * {{#if state.isPending}} <Spinner />
8437
- * {{else if state.isError}} <ErrorForm @error={{state.error}} />
8438
- * {{else}}
8439
- * <h1>{{state.result.title}}</h1>
8440
- * {{/if}}
8441
- * {{/let}}
8442
- * </template>
8443
- * ```
8444
- *
8445
- * If looking to use in a template, consider also the `<Await />` component.
8446
- *
8447
- * See also {@link PromiseState}
8448
- */
8449
- function getPromiseState(promise) {
8450
- const _promise = getPromise(promise);
8451
- let state = PromiseCache.get(_promise);
8452
- if (!state) {
8453
- state = createPromiseState(_promise);
8454
- PromiseCache.set(_promise, state);
8455
- }
8456
- return state;
8457
- }
8458
- export { peekInternalSignal as A, createInternalMemo as B, withSignalStore as C, DISPOSE as D, notifyInternalSignal as E, consumeInternalSignal as F, getOrCreateInternalSignal as G, checkout as H, SchemaService as I, withDefaults as J, fromIdentity as K, registerDerivations as L, commit as M, getPromiseState as N, ReactiveResource as O, createReactiveDocument as P, setIdentifierGenerationMethod as Q, RecordArrayManager as R, Store as S, setIdentifierUpdateMethod as T, setIdentifierForgetMethod as U, setIdentifierResetMethod as V, setKeyInfoForResource as W, _clearCaches as _, isRequestKey as a, coerceId as b, constructResource as c, assertPrivateStore as d, ensureStringId as e, fastPush as f, isPrivateStore as g, assertPrivateCapabilities as h, isResourceKey as i, setRecordIdentifier as j, StoreMap as k, createLegacyManyArray as l, createRequestSubscription as m, normalizeModelName as n, getRequestState as o, signal as p, memoized as q, recordIdentifierFor as r, storeFor as s, gate as t, entangleSignal as u, entangleInitiallyStaleSignal as v, defineSignal as w, defineGate as x, defineNonEnumerableSignal as y, Signals as z };
6939
+ export { setIdentifierResetMethod as A, setKeyInfoForResource as B, RecordArrayManager as R, SchemaService as S, _clearCaches as _, commit as a, Store as b, checkout as c, recordIdentifierFor as d, isRequestKey as e, fromIdentity as f, constructResource as g, coerceId as h, isResourceKey as i, ensureStringId as j, fastPush as k, assertPrivateStore as l, isPrivateStore as m, assertPrivateCapabilities as n, setRecordIdentifier as o, StoreMap as p, normalizeModelName as q, registerDerivations as r, storeFor as s, createLegacyManyArray as t, ReactiveResource as u, createReactiveDocument as v, withDefaults as w, setIdentifierGenerationMethod as x, setIdentifierUpdateMethod as y, setIdentifierForgetMethod as z };