@ember-data/store 4.10.0-alpha.2 → 4.10.0-alpha.21

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 (39) hide show
  1. package/addon/-private.js +1 -0
  2. package/addon/-private.js.map +1 -0
  3. package/addon/index-12e1fcb9.js +7660 -0
  4. package/addon/index-12e1fcb9.js.map +1 -0
  5. package/addon/index.js +1 -0
  6. package/addon/index.js.map +1 -0
  7. package/addon-main.js +90 -0
  8. package/package.json +44 -15
  9. package/addon/-private/caches/identifier-cache.ts +0 -686
  10. package/addon/-private/caches/instance-cache.ts +0 -695
  11. package/addon/-private/caches/record-data-for.ts +0 -34
  12. package/addon/-private/index.ts +0 -59
  13. package/addon/-private/legacy-model-support/record-reference.ts +0 -240
  14. package/addon/-private/legacy-model-support/schema-definition-service.ts +0 -148
  15. package/addon/-private/legacy-model-support/shim-model-class.ts +0 -97
  16. package/addon/-private/managers/record-array-manager.ts +0 -379
  17. package/addon/-private/managers/record-data-manager.ts +0 -845
  18. package/addon/-private/managers/record-data-store-wrapper.ts +0 -425
  19. package/addon/-private/managers/record-notification-manager.ts +0 -111
  20. package/addon/-private/network/fetch-manager.ts +0 -567
  21. package/addon/-private/network/finders.js +0 -104
  22. package/addon/-private/network/request-cache.ts +0 -132
  23. package/addon/-private/network/snapshot-record-array.ts +0 -209
  24. package/addon/-private/network/snapshot.ts +0 -563
  25. package/addon/-private/proxies/promise-proxies.ts +0 -228
  26. package/addon/-private/proxies/promise-proxy-base.js +0 -7
  27. package/addon/-private/record-arrays/identifier-array.ts +0 -929
  28. package/addon/-private/store-service.ts +0 -2896
  29. package/addon/-private/utils/coerce-id.ts +0 -41
  30. package/addon/-private/utils/common.js +0 -65
  31. package/addon/-private/utils/construct-resource.ts +0 -61
  32. package/addon/-private/utils/identifer-debug-consts.ts +0 -3
  33. package/addon/-private/utils/is-non-empty-string.ts +0 -3
  34. package/addon/-private/utils/normalize-model-name.ts +0 -21
  35. package/addon/-private/utils/promise-record.ts +0 -15
  36. package/addon/-private/utils/serializer-response.ts +0 -86
  37. package/addon/-private/utils/uuid-polyfill.ts +0 -73
  38. package/addon/index.ts +0 -14
  39. package/index.js +0 -49
@@ -1,929 +0,0 @@
1
- /**
2
- @module @ember-data/store
3
- */
4
- import { assert, deprecate } from '@ember/debug';
5
- import { get, set } from '@ember/object';
6
- import { dependentKeyCompat } from '@ember/object/compat';
7
- import { compare } from '@ember/utils';
8
- import { DEBUG } from '@glimmer/env';
9
- import { tracked } from '@glimmer/tracking';
10
- import Ember from 'ember';
11
-
12
- import {
13
- DEPRECATE_A_USAGE,
14
- DEPRECATE_ARRAY_LIKE,
15
- DEPRECATE_PROMISE_PROXIES,
16
- DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS,
17
- } from '@ember-data/private-build-infra/deprecations';
18
- import { addToTransaction, subscribe } from '@ember-data/tracking/-private';
19
- import { Links, PaginationLinks } from '@ember-data/types/q/ember-data-json-api';
20
- import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
21
- import type { RecordInstance } from '@ember-data/types/q/record-instance';
22
- import { Dict } from '@ember-data/types/q/utils';
23
-
24
- import { recordIdentifierFor } from '../caches/instance-cache';
25
- import type RecordArrayManager from '../managers/record-array-manager';
26
- import { PromiseArray, promiseArray } from '../proxies/promise-proxies';
27
- import type Store from '../store-service';
28
-
29
- type KeyType = string | symbol | number;
30
- const ARRAY_GETTER_METHODS = new Set<KeyType>([
31
- Symbol.iterator,
32
- 'concat',
33
- 'entries',
34
- 'every',
35
- 'fill',
36
- 'filter',
37
- 'find',
38
- 'findIndex',
39
- 'flat',
40
- 'flatMap',
41
- 'forEach',
42
- 'includes',
43
- 'indexOf',
44
- 'join',
45
- 'keys',
46
- 'lastIndexOf',
47
- 'map',
48
- 'reduce',
49
- 'reduceRight',
50
- 'slice',
51
- 'some',
52
- 'values',
53
- ]);
54
- const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
55
- const SYNC_PROPS = new Set<KeyType>(['[]', 'length', 'links', 'meta']);
56
- function isArrayGetter(prop: KeyType): boolean {
57
- return ARRAY_GETTER_METHODS.has(prop);
58
- }
59
- function isArraySetter(prop: KeyType): boolean {
60
- return ARRAY_SETTER_METHODS.has(prop);
61
- }
62
-
63
- export const IDENTIFIER_ARRAY_TAG = Symbol('#tag');
64
- export const SOURCE = Symbol('#source');
65
- export const MUTATE = Symbol('#update');
66
-
67
- function convertToInt(prop: KeyType): number | null {
68
- if (typeof prop === 'symbol') return null;
69
-
70
- const num = Number(prop);
71
-
72
- if (isNaN(num)) return null;
73
-
74
- return num % 1 === 0 ? num : null;
75
- }
76
-
77
- class Tag {
78
- @tracked ref = null;
79
- shouldReset: boolean = false;
80
- t = false;
81
- }
82
-
83
- type ProxiedMethod = (...args: unknown[]) => unknown;
84
- declare global {
85
- interface ProxyConstructor {
86
- new <TSource extends object, TTarget extends object>(target: TSource, handler: ProxyHandler<TSource>): TTarget;
87
- }
88
- }
89
-
90
- export type IdentifierArrayCreateOptions = {
91
- identifiers: StableRecordIdentifier[];
92
- type: string;
93
- store: Store;
94
- allowMutation: boolean;
95
- manager: RecordArrayManager;
96
- links?: Links | PaginationLinks | null;
97
- meta?: Dict<unknown> | null;
98
- };
99
-
100
- function deprecateArrayLike(className: string, fnName: string, replName: string) {
101
- deprecate(
102
- `The \`${fnName}\` method on the class ${className} is deprecated. Use the native array method \`${replName}\` instead.`,
103
- false,
104
- {
105
- id: 'ember-data:deprecate-array-like',
106
- until: '5.0',
107
- since: { enabled: '4.7', available: '4.7' },
108
- for: 'ember-data',
109
- }
110
- );
111
- }
112
-
113
- interface PrivateState {
114
- links: Links | PaginationLinks | null;
115
- meta: Dict<unknown> | null;
116
- }
117
-
118
- /**
119
- A record array is an array that contains records of a certain type (or modelName).
120
- The record array materializes records as needed when they are retrieved for the first
121
- time. You should not create record arrays yourself. Instead, an instance of
122
- `RecordArray` or its subclasses will be returned by your application's store
123
- in response to queries.
124
-
125
- This class should not be imported and instantiated by consuming applications.
126
-
127
- @class RecordArray
128
- @public
129
- */
130
-
131
- interface IdentifierArray {
132
- [MUTATE]?(prop: string, args: unknown[], result?: unknown): void;
133
- }
134
- interface IdentifierArray extends Array<RecordInstance> {}
135
- class IdentifierArray {
136
- declare DEPRECATED_CLASS_NAME: string;
137
- /**
138
- The flag to signal a `RecordArray` is currently loading data.
139
- Example
140
- ```javascript
141
- let people = store.peekAll('person');
142
- people.isUpdating; // false
143
- people.update();
144
- people.isUpdating; // true
145
- ```
146
- @property isUpdating
147
- @public
148
- @type Boolean
149
- */
150
- @tracked isUpdating: boolean = false;
151
- isLoaded: boolean = true;
152
- isDestroying: boolean = false;
153
- isDestroyed: boolean = false;
154
- _updatingPromise: PromiseArray<RecordInstance, IdentifierArray> | Promise<IdentifierArray> | null = null;
155
-
156
- [IDENTIFIER_ARRAY_TAG] = new Tag();
157
- [SOURCE]: StableRecordIdentifier[];
158
-
159
- declare links: Links | PaginationLinks | null;
160
- declare meta: Dict<unknown> | null;
161
-
162
- /**
163
- The modelClass represented by this record array.
164
-
165
- @property type
166
- @public
167
- @deprecated
168
- @type {subclass of Model}
169
- */
170
- declare modelName: string;
171
- /**
172
- The store that created this record array.
173
-
174
- @property store
175
- @private
176
- @type Store
177
- */
178
- declare store: Store;
179
- declare _manager: RecordArrayManager;
180
-
181
- destroy() {
182
- this.isDestroying = true;
183
- // changing the reference breaks the Proxy
184
- // this[SOURCE] = [];
185
- this[SOURCE].length = 0;
186
- this[IDENTIFIER_ARRAY_TAG].ref = null;
187
- this.isDestroyed = true;
188
- }
189
-
190
- // length must be on self for proxied methods to work properly
191
- @dependentKeyCompat
192
- get length() {
193
- return this[SOURCE].length;
194
- }
195
- set length(value) {
196
- this[SOURCE].length = value;
197
- }
198
-
199
- constructor(options: IdentifierArrayCreateOptions) {
200
- // eslint-disable-next-line @typescript-eslint/no-this-alias
201
- let self = this;
202
- this.modelName = options.type;
203
- this.store = options.store;
204
- this._manager = options.manager;
205
- this[SOURCE] = options.identifiers;
206
- const store = options.store;
207
- const boundFns = new Map<KeyType, ProxiedMethod>();
208
- const _TAG = this[IDENTIFIER_ARRAY_TAG];
209
- const PrivateState: PrivateState = {
210
- links: options.links || null,
211
- meta: options.meta || null,
212
- };
213
- let transaction: boolean = false;
214
-
215
- // when a mutation occurs
216
- // we track all mutations within the call
217
- // and forward them as one
218
-
219
- const proxy = new Proxy<StableRecordIdentifier[], RecordInstance[]>(this[SOURCE], {
220
- get(target: StableRecordIdentifier[], prop: KeyType, receiver: IdentifierArray): unknown {
221
- let index = convertToInt(prop);
222
- if (_TAG.shouldReset && (index !== null || SYNC_PROPS.has(prop) || isArrayGetter(prop))) {
223
- options.manager._syncArray(receiver as unknown as IdentifierArray);
224
- _TAG.t = false;
225
- _TAG.shouldReset = false;
226
- }
227
-
228
- if (index !== null) {
229
- const identifier = target[index];
230
- if (!transaction) {
231
- subscribe(_TAG);
232
- }
233
- return identifier && store._instanceCache.getRecord(identifier);
234
- }
235
-
236
- if (prop === 'meta') return subscribe(_TAG), PrivateState.meta;
237
- if (prop === 'links') return subscribe(_TAG), PrivateState.links;
238
- if (prop === '[]') return subscribe(_TAG), receiver;
239
-
240
- if (isArrayGetter(prop)) {
241
- let fn = boundFns.get(prop);
242
-
243
- if (fn === undefined) {
244
- fn = function () {
245
- subscribe(_TAG);
246
- // array functions must run through Reflect to work properly
247
- // binding via other means will not work.
248
- transaction = true;
249
- let result = Reflect.apply(target[prop] as ProxiedMethod, receiver, arguments) as unknown;
250
- transaction = false;
251
- return result;
252
- };
253
-
254
- boundFns.set(prop, fn);
255
- }
256
-
257
- return fn;
258
- }
259
-
260
- if (isArraySetter(prop)) {
261
- let fn = boundFns.get(prop);
262
-
263
- if (fn === undefined) {
264
- fn = function () {
265
- // array functions must run through Reflect to work properly
266
- // binding via other means will not work.
267
- if (!options.allowMutation) {
268
- assert(`Mutating this array of records via ${String(prop)} is not allowed.`, options.allowMutation);
269
- return;
270
- }
271
- const args: unknown[] = Array.prototype.slice.call(arguments);
272
- assert(`Cannot start a new array transaction while a previous transaction is underway`, !transaction);
273
- transaction = true;
274
- let result = Reflect.apply(target[prop] as ProxiedMethod, receiver, args) as unknown;
275
- self[MUTATE]!(prop as string, args, result);
276
- addToTransaction(_TAG);
277
- // TODO handle cache updates
278
- transaction = false;
279
- return result;
280
- };
281
-
282
- boundFns.set(prop, fn);
283
- }
284
-
285
- return fn;
286
- }
287
-
288
- if (prop in self) {
289
- if (DEPRECATE_ARRAY_LIKE) {
290
- if (prop === 'firstObject') {
291
- deprecateArrayLike(self.DEPRECATED_CLASS_NAME, prop, '[0]');
292
- return receiver[0];
293
- } else if (prop === 'lastObject') {
294
- deprecateArrayLike(self.DEPRECATED_CLASS_NAME, prop, 'at(-1)');
295
- return receiver[receiver.length - 1];
296
- }
297
- }
298
-
299
- let fn = boundFns.get(prop);
300
- if (fn) return fn;
301
-
302
- let outcome: unknown = self[prop];
303
-
304
- if (typeof outcome === 'function') {
305
- fn = function () {
306
- subscribe(_TAG);
307
- // array functions must run through Reflect to work properly
308
- // binding via other means will not work.
309
- return Reflect.apply(outcome as ProxiedMethod, receiver, arguments) as unknown;
310
- };
311
-
312
- boundFns.set(prop, fn);
313
- return fn;
314
- }
315
-
316
- return subscribe(_TAG), outcome;
317
- }
318
-
319
- return target[prop];
320
- },
321
-
322
- set(target: StableRecordIdentifier[], prop: KeyType, value: unknown /*, receiver */): boolean {
323
- if (prop === 'length') {
324
- if (!transaction && value === 0) {
325
- transaction = true;
326
- addToTransaction(_TAG);
327
- Reflect.set(target, prop, value);
328
- self[MUTATE]!('length 0', []);
329
- transaction = false;
330
- return true;
331
- } else if (transaction) {
332
- return Reflect.set(target, prop, value);
333
- } else {
334
- assert(`unexpected length set`);
335
- }
336
- }
337
- if (prop === 'links') {
338
- PrivateState.links = (value || null) as PaginationLinks | Links | null;
339
- return true;
340
- }
341
- if (prop === 'meta') {
342
- PrivateState.meta = (value || null) as Dict<unknown> | null;
343
- return true;
344
- }
345
- let index = convertToInt(prop);
346
-
347
- if (index === null || index > target.length) {
348
- if (prop in self) {
349
- self[prop] = value;
350
- return true;
351
- }
352
- return false;
353
- }
354
-
355
- if (!options.allowMutation) {
356
- assert(`Mutating ${String(prop)} on this RecordArray is not allowed.`, options.allowMutation);
357
- return false;
358
- }
359
-
360
- let original: StableRecordIdentifier | undefined = target[index];
361
- let newIdentifier = extractIdentifierFromRecord(value as RecordInstance);
362
- (target as unknown as Record<KeyType, unknown>)[index] = newIdentifier;
363
- if (!transaction) {
364
- self[MUTATE]!('replace cell', [index, original, newIdentifier]);
365
- addToTransaction(_TAG);
366
- }
367
-
368
- return true;
369
- },
370
-
371
- deleteProperty(target: StableRecordIdentifier[], prop: string | symbol): boolean {
372
- assert(`Deleting keys on managed arrays is disallowed`, transaction);
373
- if (!transaction) {
374
- return false;
375
- }
376
- return Reflect.deleteProperty(target, prop);
377
- },
378
-
379
- getPrototypeOf() {
380
- return IdentifierArray.prototype;
381
- },
382
- }) as IdentifierArray;
383
-
384
- if (DEPRECATE_A_USAGE) {
385
- const meta = Ember.meta(this);
386
- meta.hasMixin = (mixin: Object) => {
387
- deprecate(`Do not call A() on EmberData RecordArrays`, false, {
388
- id: 'ember-data:no-a-with-array-like',
389
- until: '5.0',
390
- since: { enabled: '4.7', available: '4.7' },
391
- for: 'ember-data',
392
- });
393
- // @ts-expect-error ArrayMixin is more than a type
394
- if (mixin === NativeArray || mixin === ArrayMixin) {
395
- return true;
396
- }
397
- return false;
398
- };
399
- } else if (DEBUG) {
400
- const meta = Ember.meta(this);
401
- meta.hasMixin = (mixin: Object) => {
402
- assert(`Do not call A() on EmberData RecordArrays`);
403
- };
404
- }
405
-
406
- return proxy;
407
- }
408
-
409
- /**
410
- Used to get the latest version of all of the records in this array
411
- from the adapter.
412
-
413
- Example
414
-
415
- ```javascript
416
- let people = store.peekAll('person');
417
- people.isUpdating; // false
418
-
419
- people.update().then(function() {
420
- people.isUpdating; // false
421
- });
422
-
423
- people.isUpdating; // true
424
- ```
425
-
426
- @method update
427
- @public
428
- */
429
- update(): PromiseArray<RecordInstance, IdentifierArray> | Promise<IdentifierArray> {
430
- if (this.isUpdating) {
431
- return this._updatingPromise!;
432
- }
433
-
434
- this.isUpdating = true;
435
-
436
- let updatingPromise = this._update();
437
- updatingPromise.finally(() => {
438
- this._updatingPromise = null;
439
- if (this.isDestroying || this.isDestroyed) {
440
- return;
441
- }
442
- this.isUpdating = false;
443
- });
444
-
445
- this._updatingPromise = updatingPromise;
446
-
447
- return updatingPromise;
448
- }
449
-
450
- /*
451
- Update this RecordArray and return a promise which resolves once the update
452
- is finished.
453
- */
454
- _update(): PromiseArray<RecordInstance, IdentifierArray> | Promise<IdentifierArray> {
455
- return this.store.findAll(this.modelName, { reload: true });
456
- }
457
-
458
- // TODO deprecate
459
- /**
460
- Saves all of the records in the `RecordArray`.
461
-
462
- Example
463
-
464
- ```javascript
465
- let messages = store.peekAll('message');
466
- messages.forEach(function(message) {
467
- message.hasBeenSeen = true;
468
- });
469
- messages.save();
470
- ```
471
-
472
- @method save
473
- @public
474
- @return {PromiseArray} promise
475
- */
476
- save(): PromiseArray<RecordInstance, IdentifierArray> | Promise<IdentifierArray> {
477
- let promise = Promise.all(this.map((record) => this.store.saveRecord(record))).then(() => this);
478
-
479
- if (DEPRECATE_PROMISE_PROXIES) {
480
- return promiseArray<RecordInstance, IdentifierArray>(promise);
481
- }
482
-
483
- return promise;
484
- }
485
- }
486
-
487
- export default IdentifierArray;
488
-
489
- if (DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS) {
490
- Object.defineProperty(IdentifierArray.prototype, 'type', {
491
- get() {
492
- deprecate(
493
- `Using RecordArray.type to access the ModelClass for a record is deprecated. Use store.modelFor(<modelName>) instead.`,
494
- false,
495
- {
496
- id: 'ember-data:deprecate-snapshot-model-class-access',
497
- until: '5.0',
498
- for: 'ember-data',
499
- since: { available: '4.5.0', enabled: '4.5.0' },
500
- }
501
- );
502
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
503
- if (!this.modelName) {
504
- return null;
505
- }
506
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
507
- return this.store.modelFor(this.modelName);
508
- },
509
- });
510
- }
511
-
512
- export type CollectionCreateOptions = IdentifierArrayCreateOptions & {
513
- query: Dict<unknown> | null;
514
- isLoaded: boolean;
515
- };
516
- export class Collection extends IdentifierArray {
517
- query: Dict<unknown> | null = null;
518
-
519
- constructor(options: CollectionCreateOptions) {
520
- super(options as IdentifierArrayCreateOptions);
521
- this.query = options.query || null;
522
- this.isLoaded = options.isLoaded || false;
523
- }
524
-
525
- _update(): PromiseArray<RecordInstance, Collection> | Promise<Collection> {
526
- const { store, query } = this;
527
-
528
- // TODO save options from initial request?
529
- const promise = store.query(this.modelName, query, { _recordArray: this });
530
-
531
- if (DEPRECATE_PROMISE_PROXIES) {
532
- return promiseArray(promise);
533
- }
534
- return promise;
535
- }
536
-
537
- destroy() {
538
- super.destroy();
539
- this._manager._managed.delete(this);
540
- this._manager._pending.delete(this);
541
- }
542
- }
543
- // trick the proxy "in" check
544
- Collection.prototype.query = null;
545
-
546
- // Ensure instanceof works correctly
547
- // Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
548
-
549
- if (DEPRECATE_ARRAY_LIKE) {
550
- IdentifierArray.prototype.DEPRECATED_CLASS_NAME = 'RecordArray';
551
- Collection.prototype.DEPRECATED_CLASS_NAME = 'RecordArray';
552
- const EmberObjectMethods = [
553
- 'addObserver',
554
- 'cacheFor',
555
- 'decrementProperty',
556
- 'get',
557
- 'getProperties',
558
- 'incrementProperty',
559
- 'notifyPropertyChange',
560
- 'removeObserver',
561
- 'set',
562
- 'setProperties',
563
- 'toggleProperty',
564
- ];
565
- EmberObjectMethods.forEach((method) => {
566
- IdentifierArray.prototype[method] = function delegatedMethod(...args: unknown[]): unknown {
567
- deprecate(
568
- `The EmberObject ${method} method on the class ${this.DEPRECATED_CLASS_NAME} is deprecated. Use dot-notation javascript get/set access instead.`,
569
- false,
570
- {
571
- id: 'ember-data:deprecate-array-like',
572
- until: '5.0',
573
- since: { enabled: '4.7', available: '4.7' },
574
- for: 'ember-data',
575
- }
576
- );
577
- return (Ember[method] as (...args: unknown[]) => unknown)(this, ...args);
578
- };
579
- });
580
-
581
- IdentifierArray.prototype.addObject = function (obj: RecordInstance) {
582
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'addObject', 'push');
583
- let index = this.indexOf(obj);
584
- if (index === -1) {
585
- this.push(obj);
586
- }
587
- return this;
588
- };
589
-
590
- IdentifierArray.prototype.addObjects = function (objs: RecordInstance[]) {
591
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'addObjects', 'push');
592
- objs.forEach((obj: RecordInstance) => {
593
- let index = this.indexOf(obj);
594
- if (index === -1) {
595
- this.push(obj);
596
- }
597
- });
598
- return this;
599
- };
600
-
601
- IdentifierArray.prototype.popObject = function () {
602
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'popObject', 'pop');
603
- return this.pop() as RecordInstance;
604
- };
605
-
606
- IdentifierArray.prototype.pushObject = function (obj: RecordInstance) {
607
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'pushObject', 'push');
608
- this.push(obj);
609
- return obj;
610
- };
611
-
612
- IdentifierArray.prototype.pushObjects = function (objs: RecordInstance[]) {
613
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'pushObjects', 'push');
614
- this.push(...objs);
615
- return this;
616
- };
617
-
618
- IdentifierArray.prototype.shiftObject = function () {
619
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'shiftObject', 'shift');
620
- return this.shift()!;
621
- };
622
-
623
- IdentifierArray.prototype.unshiftObject = function (obj: RecordInstance) {
624
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'unshiftObject', 'unshift');
625
- this.unshift(obj);
626
- return obj;
627
- };
628
-
629
- IdentifierArray.prototype.unshiftObjects = function (objs: RecordInstance[]) {
630
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'unshiftObjects', 'unshift');
631
- this.unshift(...objs);
632
- return this;
633
- };
634
-
635
- IdentifierArray.prototype.objectAt = function (index: number) {
636
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'objectAt', 'at');
637
- //For negative index values go back from the end of the array
638
- let arrIndex = Math.sign(index) === -1 ? this.length + index : index;
639
- return this[arrIndex];
640
- };
641
-
642
- IdentifierArray.prototype.objectsAt = function (indeces: number[]) {
643
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'objectsAt', 'at');
644
- return indeces.map((index) => this.objectAt(index)!);
645
- };
646
-
647
- IdentifierArray.prototype.removeAt = function (index: number) {
648
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'removeAt', 'splice');
649
- this.splice(index, 1);
650
- return this;
651
- };
652
-
653
- IdentifierArray.prototype.insertAt = function (index: number, obj: RecordInstance) {
654
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'insertAt', 'splice');
655
- this.splice(index, 0, obj);
656
- return this;
657
- };
658
-
659
- IdentifierArray.prototype.removeObject = function (obj: RecordInstance) {
660
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'removeObject', 'splice');
661
- this.splice(this.indexOf(obj), 1);
662
- return this;
663
- };
664
-
665
- IdentifierArray.prototype.removeObjects = function (objs: RecordInstance[]) {
666
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'removeObjects', 'splice');
667
- objs.forEach((obj) => this.splice(this.indexOf(obj), 1));
668
- return this;
669
- };
670
-
671
- IdentifierArray.prototype.toArray = function () {
672
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'toArray', 'slice');
673
- return this.slice();
674
- };
675
-
676
- IdentifierArray.prototype.replace = function (idx: number, amt: number, objects?: RecordInstance[]) {
677
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'replace', 'splice');
678
- if (objects) {
679
- this.splice(idx, amt, ...objects);
680
- } else {
681
- this.splice(idx, amt);
682
- }
683
- };
684
-
685
- IdentifierArray.prototype.clear = function () {
686
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'clear', 'length = 0');
687
- this.splice(0, this.length);
688
- return this;
689
- };
690
-
691
- IdentifierArray.prototype.setObjects = function (objects: RecordInstance[]) {
692
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'clear', 'length = 0');
693
- assert(
694
- `${this.DEPRECATED_CLASS_NAME}.setObjects expects to receive an array as its argument`,
695
- Array.isArray(objects)
696
- );
697
- this.splice(0, this.length);
698
- this.push(...objects);
699
- return this;
700
- };
701
-
702
- IdentifierArray.prototype.reverseObjects = function () {
703
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'reverseObjects', 'reverse');
704
- this.reverse();
705
- return this;
706
- };
707
-
708
- IdentifierArray.prototype.compact = function () {
709
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'compact', 'filter');
710
- return this.filter((v) => v !== null && v !== undefined);
711
- };
712
-
713
- IdentifierArray.prototype.any = function (callback, target) {
714
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'any', 'some');
715
- return this.some(callback, target);
716
- };
717
-
718
- IdentifierArray.prototype.isAny = function (prop, value) {
719
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'isAny', 'some');
720
- let hasValue = arguments.length === 2;
721
- return this.some((v) => (hasValue ? v[prop] === value : v[prop] === true));
722
- };
723
-
724
- IdentifierArray.prototype.isEvery = function (prop, value) {
725
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'isEvery', 'every');
726
- let hasValue = arguments.length === 2;
727
- return this.every((v) => (hasValue ? v[prop] === value : v[prop] === true));
728
- };
729
-
730
- IdentifierArray.prototype.getEach = function (key: string) {
731
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'getEach', 'map');
732
- return this.map((value) => get(value, key));
733
- };
734
-
735
- IdentifierArray.prototype.mapBy = function (key: string) {
736
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'mapBy', 'map');
737
- return this.map((value) => get(value, key));
738
- };
739
-
740
- IdentifierArray.prototype.findBy = function (key: string, value?: unknown) {
741
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'findBy', 'find');
742
- if (arguments.length === 2) {
743
- return this.find((val) => {
744
- return get(val, key) === value;
745
- });
746
- } else {
747
- return this.find((val) => Boolean(get(val, key)));
748
- }
749
- };
750
-
751
- IdentifierArray.prototype.filterBy = function (key: string, value?: unknown) {
752
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'filterBy', 'filter');
753
- if (arguments.length === 2) {
754
- return this.filter((record) => {
755
- return get(record, key) === value;
756
- });
757
- }
758
- return this.filter((record) => {
759
- return Boolean(get(record, key));
760
- });
761
- };
762
-
763
- IdentifierArray.prototype.sortBy = function (...sortKeys: string[]) {
764
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'sortBy', '.slice().sort');
765
- return this.slice().sort((a, b) => {
766
- for (let i = 0; i < sortKeys.length; i++) {
767
- let key = sortKeys[i];
768
- let propA = get(a, key);
769
- let propB = get(b, key);
770
- // return 1 or -1 else continue to the next sortKey
771
- let compareValue = compare(propA, propB);
772
-
773
- if (compareValue) {
774
- return compareValue;
775
- }
776
- }
777
- return 0;
778
- });
779
- };
780
-
781
- // @ts-expect-error
782
- IdentifierArray.prototype.invoke = function (key: string, ...args: unknown[]) {
783
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'invoke', 'forEach');
784
- return this.map((value) => (value[key] as (...args: unknown[]) => unknown)(...args));
785
- };
786
-
787
- // @ts-expect-error
788
- IdentifierArray.prototype.addArrayObserver = function () {
789
- deprecateArrayLike(
790
- this.DEPRECATED_CLASS_NAME,
791
- 'addArrayObserver',
792
- 'derived state or reacting at the change source'
793
- );
794
- };
795
-
796
- // @ts-expect-error
797
- IdentifierArray.prototype.removeArrayObserver = function () {
798
- deprecateArrayLike(
799
- this.DEPRECATED_CLASS_NAME,
800
- 'removeArrayObserver',
801
- 'derived state or reacting at the change source'
802
- );
803
- };
804
-
805
- // @ts-expect-error
806
- IdentifierArray.prototype.arrayContentWillChange = function () {
807
- deprecateArrayLike(
808
- this.DEPRECATED_CLASS_NAME,
809
- 'arrayContentWillChange',
810
- 'derived state or reacting at the change source'
811
- );
812
- };
813
-
814
- // @ts-expect-error
815
- IdentifierArray.prototype.arrayContentDidChange = function () {
816
- deprecateArrayLike(
817
- this.DEPRECATED_CLASS_NAME,
818
- 'arrayContentDidChange',
819
- 'derived state or reacting at the change source.'
820
- );
821
- };
822
-
823
- // @ts-expect-error
824
- IdentifierArray.prototype.reject = function (key: string, value?: unknown) {
825
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'reject', 'filter');
826
- if (arguments.length === 2) {
827
- return this.filter((value) => {
828
- return !get(value, key);
829
- });
830
- }
831
- return this.filter((value) => {
832
- return !get(value, key);
833
- });
834
- };
835
-
836
- IdentifierArray.prototype.rejectBy = function (key: string, value?: unknown) {
837
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'rejectBy', 'filter');
838
- if (arguments.length === 2) {
839
- return this.filter((value) => {
840
- return !get(value, key);
841
- });
842
- }
843
- return this.filter((value) => {
844
- return !get(value, key);
845
- });
846
- };
847
-
848
- IdentifierArray.prototype.setEach = function (key: string, value: unknown) {
849
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'setEach', 'forEach');
850
- this.forEach((item) => set(item, key, value));
851
- };
852
-
853
- IdentifierArray.prototype.uniq = function () {
854
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'uniq', 'filter');
855
- // all current managed arrays are already enforced as unique
856
- return this.slice();
857
- };
858
-
859
- // @ts-expect-error
860
- IdentifierArray.prototype.uniqBy = function (key: string) {
861
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'uniqBy', 'filter');
862
- // all current managed arrays are already enforced as unique
863
- let seen = new Set();
864
- let result: RecordInstance[] = [];
865
- this.forEach((item) => {
866
- let value = get(item, key);
867
- if (seen.has(value)) {
868
- return;
869
- }
870
- seen.add(value);
871
- result.push(item);
872
- });
873
- return result;
874
- };
875
-
876
- IdentifierArray.prototype.without = function (value: RecordInstance) {
877
- deprecateArrayLike(this.DEPRECATED_CLASS_NAME, 'without', 'slice');
878
- const newArr = this.slice();
879
- const index = this.indexOf(value);
880
- if (index !== -1) {
881
- newArr.splice(index, 1);
882
- }
883
- return newArr;
884
- };
885
-
886
- // @ts-expect-error
887
- IdentifierArray.prototype.firstObject = null;
888
- // @ts-expect-error
889
- IdentifierArray.prototype.lastObject = null;
890
- }
891
-
892
- type PromiseProxyRecord = { then(): void; content: RecordInstance | null | undefined };
893
-
894
- function assertRecordPassedToHasMany(record: RecordInstance | PromiseProxyRecord) {
895
- assert(
896
- `All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`,
897
- (function () {
898
- try {
899
- recordIdentifierFor(record);
900
- return true;
901
- } catch {
902
- return false;
903
- }
904
- })()
905
- );
906
- }
907
-
908
- function extractIdentifierFromRecord(recordOrPromiseRecord: PromiseProxyRecord | RecordInstance | null) {
909
- if (!recordOrPromiseRecord) {
910
- return null;
911
- }
912
-
913
- if (isPromiseRecord(recordOrPromiseRecord)) {
914
- let content = recordOrPromiseRecord.content;
915
- assert(
916
- 'You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo relationship.',
917
- content !== undefined && content !== null
918
- );
919
- assertRecordPassedToHasMany(content);
920
- return recordIdentifierFor(content);
921
- }
922
-
923
- assertRecordPassedToHasMany(recordOrPromiseRecord);
924
- return recordIdentifierFor(recordOrPromiseRecord);
925
- }
926
-
927
- function isPromiseRecord(record: PromiseProxyRecord | RecordInstance): record is PromiseProxyRecord {
928
- return !!record.then;
929
- }