@warp-drive/core 5.7.0-alpha.0 → 5.7.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,788 @@
1
+ import type { TypeFromInstance } from "../../types/record.js";
2
+ import type { ResourceIdentifierObject } from "../../types/spec/json-api-raw.js";
3
+ import type { CollectionRecordArray, LiveArray } from "../-private.js";
4
+ import { Store } from "../-private/store-service.js";
5
+ import type { FindAllOptions, FindRecordOptions, LegacyResourceQuery, ModelSchema, QueryOptions } from "./-private.js";
6
+ import { RecordReference } from "./-private.js";
7
+ /////////////// IMPORTANT ///////////////////
8
+ ///// Move Module Augmentation Into The /////
9
+ ///// Legacy Package Once Removed Here /////
10
+ /////////////////////////////////////////////
11
+ declare module "../-private/store-service" {
12
+ interface Store {
13
+ /**
14
+ This method returns a record for a given identifier or type and id combination.
15
+
16
+ The `findRecord` method will always resolve its promise with the same
17
+ object for a given identifier or type and `id`.
18
+
19
+ The `findRecord` method will always return a **promise** that will be
20
+ resolved with the record.
21
+
22
+ **Example 1**
23
+
24
+ ```js [app/routes/post.js]
25
+ export default class PostRoute extends Route {
26
+ model({ post_id }) {
27
+ return this.store.findRecord('post', post_id);
28
+ }
29
+ }
30
+ ```
31
+
32
+ **Example 2**
33
+
34
+ `findRecord` can be called with a single identifier argument instead of the combination
35
+ of `type` (modelName) and `id` as separate arguments. You may recognize this combo as
36
+ the typical pairing from [JSON:API](https://jsonapi.org/format/#document-resource-object-identification)
37
+
38
+ ```js [app/routes/post.js]
39
+ export default class PostRoute extends Route {
40
+ model({ post_id: id }) {
41
+ return this.store.findRecord({ type: 'post', id });
42
+ }
43
+ }
44
+ ```
45
+
46
+ **Example 3**
47
+
48
+ If you have previously received an lid via an Identifier for this record, and the record
49
+ has already been assigned an id, you can find the record again using just the lid.
50
+
51
+ ```js [app/routes/post.js]
52
+ store.findRecord({ lid });
53
+ ```
54
+
55
+ If the record is not yet available, the store will ask the adapter's `findRecord`
56
+ method to retrieve and supply the necessary data. If the record is already present
57
+ in the store, it depends on the reload behavior _when_ the returned promise
58
+ resolves.
59
+
60
+ ### Preloading
61
+
62
+ You can optionally `preload` specific attributes and relationships that you know of
63
+ by passing them via the passed `options`.
64
+
65
+ For example, if your Ember route looks like `/posts/1/comments/2` and your API route
66
+ for the comment also looks like `/posts/1/comments/2` if you want to fetch the comment
67
+ without also fetching the post you can pass in the post to the `findRecord` call:
68
+
69
+ ```js [app/routes/post-comments.js]
70
+ export default class PostRoute extends Route {
71
+ model({ post_id, comment_id: id }) {
72
+ return this.store.findRecord({ type: 'comment', id, { preload: { post: post_id }} });
73
+ }
74
+ }
75
+ ```
76
+
77
+ In your adapter you can then access this id without triggering a network request via the
78
+ snapshot:
79
+
80
+ ```js [app/adapters/application.js]
81
+ export default class Adapter {
82
+
83
+ findRecord(store, schema, id, snapshot) {
84
+ let type = schema.modelName;
85
+
86
+ if (type === 'comment')
87
+ let postId = snapshot.belongsTo('post', { id: true });
88
+
89
+ return fetch(`./posts/${postId}/comments/${id}`)
90
+ .then(response => response.json())
91
+ }
92
+ }
93
+
94
+ static create() {
95
+ return new this();
96
+ }
97
+ }
98
+ ```
99
+
100
+ This could also be achieved by supplying the post id to the adapter via the adapterOptions
101
+ property on the options hash.
102
+
103
+ ```js [app/routes/post-comments.js]
104
+ export default class PostRoute extends Route {
105
+ model({ post_id, comment_id: id }) {
106
+ return this.store.findRecord({ type: 'comment', id, { adapterOptions: { post: post_id }} });
107
+ }
108
+ }
109
+ ```
110
+
111
+ ```js [app/adapters/application.js]
112
+ export default class Adapter {
113
+ findRecord(store, schema, id, snapshot) {
114
+ let type = schema.modelName;
115
+
116
+ if (type === 'comment')
117
+ let postId = snapshot.adapterOptions.post;
118
+
119
+ return fetch(`./posts/${postId}/comments/${id}`)
120
+ .then(response => response.json())
121
+ }
122
+ }
123
+
124
+ static create() {
125
+ return new this();
126
+ }
127
+ }
128
+ ```
129
+
130
+ If you have access to the post model you can also pass the model itself to preload:
131
+
132
+ ```javascript
133
+ let post = await store.findRecord('post', '1');
134
+ let comment = await store.findRecord('comment', '2', { post: myPostModel });
135
+ ```
136
+
137
+ ### Reloading
138
+
139
+ The reload behavior is configured either via the passed `options` hash or
140
+ the result of the adapter's `shouldReloadRecord`.
141
+
142
+ If `{ reload: true }` is passed or `adapter.shouldReloadRecord` evaluates
143
+ to `true`, then the returned promise resolves once the adapter returns
144
+ data, regardless if the requested record is already in the store:
145
+
146
+ ```js
147
+ store.push({
148
+ data: {
149
+ id: 1,
150
+ type: 'post',
151
+ revision: 1
152
+ }
153
+ });
154
+
155
+ // adapter#findRecord resolves with
156
+ // [
157
+ // {
158
+ // id: 1,
159
+ // type: 'post',
160
+ // revision: 2
161
+ // }
162
+ // ]
163
+ store.findRecord('post', '1', { reload: true }).then(function(post) {
164
+ post.revision; // 2
165
+ });
166
+ ```
167
+
168
+ If no reload is indicated via the above mentioned ways, then the promise
169
+ immediately resolves with the cached version in the store.
170
+
171
+ ### Background Reloading
172
+
173
+ Optionally, if `adapter.shouldBackgroundReloadRecord` evaluates to `true`,
174
+ then a background reload is started, which updates the records' data, once
175
+ it is available:
176
+
177
+ ```js
178
+ // app/adapters/post.js
179
+ import ApplicationAdapter from "./application";
180
+
181
+ export default class PostAdapter extends ApplicationAdapter {
182
+ shouldReloadRecord(store, snapshot) {
183
+ return false;
184
+ },
185
+
186
+ shouldBackgroundReloadRecord(store, snapshot) {
187
+ return true;
188
+ }
189
+ });
190
+
191
+ // ...
192
+
193
+ store.push({
194
+ data: {
195
+ id: 1,
196
+ type: 'post',
197
+ revision: 1
198
+ }
199
+ });
200
+
201
+ let blogPost = store.findRecord('post', '1').then(function(post) {
202
+ post.revision; // 1
203
+ });
204
+
205
+ // later, once adapter#findRecord resolved with
206
+ // [
207
+ // {
208
+ // id: 1,
209
+ // type: 'post',
210
+ // revision: 2
211
+ // }
212
+ // ]
213
+
214
+ blogPost.revision; // 2
215
+ ```
216
+
217
+ If you would like to force or prevent background reloading, you can set a
218
+ boolean value for `backgroundReload` in the options object for
219
+ `findRecord`.
220
+
221
+ ```js [app/routes/post/edit.js]
222
+ export default class PostEditRoute extends Route {
223
+ model(params) {
224
+ return this.store.findRecord('post', params.post_id, { backgroundReload: false });
225
+ }
226
+ }
227
+ ```
228
+
229
+ If you pass an object on the `adapterOptions` property of the options
230
+ argument it will be passed to your adapter via the snapshot
231
+
232
+ ```js [app/routes/post/edit.js]
233
+ export default class PostEditRoute extends Route {
234
+ model(params) {
235
+ return this.store.findRecord('post', params.post_id, {
236
+ adapterOptions: { subscribe: false }
237
+ });
238
+ }
239
+ }
240
+ ```
241
+
242
+ ```js [app/adapters/post.js]
243
+ import MyCustomAdapter from './custom-adapter';
244
+
245
+ export default class PostAdapter extends MyCustomAdapter {
246
+ findRecord(store, type, id, snapshot) {
247
+ if (snapshot.adapterOptions.subscribe) {
248
+ // ...
249
+ }
250
+ // ...
251
+ }
252
+ }
253
+ ```
254
+
255
+ See [peekRecord](../methods/peekRecord?anchor=peekRecord) to get the cached version of a record.
256
+
257
+ ### Retrieving Related Model Records
258
+
259
+ If you use an adapter such as Ember's default
260
+ [`JSONAPIAdapter`](/ember-data/release/classes/JSONAPIAdapter)
261
+ that supports the [JSON API specification](http://jsonapi.org/) and if your server
262
+ endpoint supports the use of an
263
+ ['include' query parameter](http://jsonapi.org/format/#fetching-includes),
264
+ you can use `findRecord()` or `findAll()` to automatically retrieve additional records related to
265
+ the one you request by supplying an `include` parameter in the `options` object.
266
+
267
+ For example, given a `post` model that has a `hasMany` relationship with a `comment`
268
+ model, when we retrieve a specific post we can have the server also return that post's
269
+ comments in the same request:
270
+
271
+ ```js [app/routes/post.js]
272
+ export default class PostRoute extends Route {
273
+ model(params) {
274
+ return this.store.findRecord('post', params.post_id, { include: ['comments'] });
275
+ }
276
+ }
277
+ ```
278
+
279
+ ```js [app/adapters/application.js]
280
+ export default class Adapter {
281
+ findRecord(store, schema, id, snapshot) {
282
+ let type = schema.modelName;
283
+
284
+ if (type === 'post')
285
+ let includes = snapshot.adapterOptions.include;
286
+
287
+ return fetch(`./posts/${postId}?include=${includes}`)
288
+ .then(response => response.json())
289
+ }
290
+ }
291
+
292
+ static create() {
293
+ return new this();
294
+ }
295
+ }
296
+ ```
297
+
298
+ In this case, the post's comments would then be available in your template as
299
+ `model.comments`.
300
+
301
+ Multiple relationships can be requested using an `include` parameter consisting of a
302
+ list of relationship names, while nested relationships can be specified
303
+ using a dot-separated sequence of relationship names. So to request both the post's
304
+ comments and the authors of those comments the request would look like this:
305
+
306
+ ```js [app/routes/post.js]
307
+ export default class PostRoute extends Route {
308
+ model(params) {
309
+ return this.store.findRecord('post', params.post_id, { include: ['comments','comments.author'] });
310
+ }
311
+ }
312
+ ```
313
+
314
+ ### Retrieving Specific Fields by Type
315
+
316
+ If your server endpoint supports the use of a ['fields' query parameter](https://jsonapi.org/format/#fetching-sparse-fieldsets),
317
+ you can use pass those fields through to your server. At this point in time, this requires a few manual steps on your part.
318
+
319
+ 1. Implement `buildQuery` in your adapter.
320
+
321
+ ```js [app/adapters/application.js]
322
+ buildQuery(snapshot) {
323
+ let query = super.buildQuery(...arguments);
324
+
325
+ let { fields } = snapshot.adapterOptions;
326
+
327
+ if (fields) {
328
+ query.fields = fields;
329
+ }
330
+
331
+ return query;
332
+ }
333
+ ```
334
+
335
+ 2. Then pass through the applicable fields to your `findRecord` request.
336
+
337
+ Given a `post` model with attributes body, title, publishDate and meta, you can retrieve a filtered list of attributes.
338
+
339
+ ```js [app/routes/post.js]
340
+ export default class extends Route {
341
+ model(params) {
342
+ return this.store.findRecord('post', params.post_id, { adapterOptions: { fields: { post: 'body,title' } });
343
+ }
344
+ }
345
+ ```
346
+
347
+ Moreover, you can filter attributes on related models as well. If a `post` has a `belongsTo` relationship to a user,
348
+ just include the relationship key and attributes.
349
+
350
+ ```js [app/routes/post.js]
351
+ export default class extends Route {
352
+ model(params) {
353
+ return this.store.findRecord('post', params.post_id, { adapterOptions: { fields: { post: 'body,title', user: 'name,email' } });
354
+ }
355
+ }
356
+ ```
357
+
358
+ @public
359
+ @deprecated use {@link Store.request} instead
360
+ @until 6.0
361
+ @since 1.13.0
362
+ @param type - either a string representing the name of the resource or a ResourceIdentifier object containing both the type (a string) and the id (a string) for the record or an lid (a string) of an existing record
363
+ @param id - optional object with options for the request only if the first param is a ResourceIdentifier, else the string id of the record to be retrieved
364
+ @param options - if the first param is a string this will be the optional options for the request. See examples for available options.
365
+ */
366
+ findRecord<T>(type: TypeFromInstance<T>, id: string | number, options?: FindRecordOptions<T>): Promise<T>;
367
+ /** @deprecated */
368
+ findRecord(type: string, id: string | number, options?: FindRecordOptions): Promise<unknown>;
369
+ /** @deprecated */
370
+ findRecord<T>(resource: ResourceIdentifierObject<TypeFromInstance<T>>, options?: FindRecordOptions<T>): Promise<T>;
371
+ /** @deprecated */
372
+ findRecord(resource: ResourceIdentifierObject, options?: FindRecordOptions): Promise<unknown>;
373
+ /**
374
+ `findAll` asks the adapter's `findAll` method to find the records for the
375
+ given type, and returns a promise which will resolve with all records of
376
+ this type present in the store, even if the adapter only returns a subset
377
+ of them.
378
+
379
+ ```js [app/routes/authors.js]
380
+ export default class AuthorsRoute extends Route {
381
+ model(params) {
382
+ return this.store.findAll('author');
383
+ }
384
+ }
385
+ ```
386
+
387
+ _When_ the returned promise resolves depends on the reload behavior,
388
+ configured via the passed `options` hash and the result of the adapter's
389
+ `shouldReloadAll` method.
390
+
391
+ ### Reloading
392
+
393
+ If `{ reload: true }` is passed or `adapter.shouldReloadAll` evaluates to
394
+ `true`, then the returned promise resolves once the adapter returns data,
395
+ regardless if there are already records in the store:
396
+
397
+ ```js
398
+ store.push({
399
+ data: {
400
+ id: 'first',
401
+ type: 'author'
402
+ }
403
+ });
404
+
405
+ // adapter#findAll resolves with
406
+ // [
407
+ // {
408
+ // id: 'second',
409
+ // type: 'author'
410
+ // }
411
+ // ]
412
+ store.findAll('author', { reload: true }).then(function(authors) {
413
+ authors.getEach('id'); // ['first', 'second']
414
+ });
415
+ ```
416
+
417
+ If no reload is indicated via the above mentioned ways, then the promise
418
+ immediately resolves with all the records currently loaded in the store.
419
+
420
+ ### Background Reloading
421
+
422
+ Optionally, if `adapter.shouldBackgroundReloadAll` evaluates to `true`,
423
+ then a background reload is started. Once this resolves, the array with
424
+ which the promise resolves, is updated automatically so it contains all the
425
+ records in the store:
426
+
427
+ ```js [app/adapters/application.js]
428
+ import Adapter from '@ember-data/adapter';
429
+
430
+ export default class ApplicationAdapter extends Adapter {
431
+ shouldReloadAll(store, snapshotsArray) {
432
+ return false;
433
+ },
434
+
435
+ shouldBackgroundReloadAll(store, snapshotsArray) {
436
+ return true;
437
+ }
438
+ });
439
+
440
+ // ...
441
+
442
+ store.push({
443
+ data: {
444
+ id: 'first',
445
+ type: 'author'
446
+ }
447
+ });
448
+
449
+ let allAuthors;
450
+ store.findAll('author').then(function(authors) {
451
+ authors.getEach('id'); // ['first']
452
+
453
+ allAuthors = authors;
454
+ });
455
+
456
+ // later, once adapter#findAll resolved with
457
+ // [
458
+ // {
459
+ // id: 'second',
460
+ // type: 'author'
461
+ // }
462
+ // ]
463
+
464
+ allAuthors.getEach('id'); // ['first', 'second']
465
+ ```
466
+
467
+ If you would like to force or prevent background reloading, you can set a
468
+ boolean value for `backgroundReload` in the options object for
469
+ `findAll`.
470
+
471
+ ```js [app/routes/post/edit.js]
472
+ export default class PostEditRoute extends Route {
473
+ model() {
474
+ return this.store.findAll('post', { backgroundReload: false });
475
+ }
476
+ }
477
+ ```
478
+
479
+ If you pass an object on the `adapterOptions` property of the options
480
+ argument it will be passed to you adapter via the `snapshotRecordArray`
481
+
482
+ ```js [app/routes/posts.js]
483
+ export default class PostsRoute extends Route {
484
+ model(params) {
485
+ return this.store.findAll('post', {
486
+ adapterOptions: { subscribe: false }
487
+ });
488
+ }
489
+ }
490
+ ```
491
+
492
+ ```js [app/adapters/post.js]
493
+ import MyCustomAdapter from './custom-adapter';
494
+
495
+ export default class UserAdapter extends MyCustomAdapter {
496
+ findAll(store, type, sinceToken, snapshotRecordArray) {
497
+ if (snapshotRecordArray.adapterOptions.subscribe) {
498
+ // ...
499
+ }
500
+ // ...
501
+ }
502
+ }
503
+ ```
504
+
505
+ See [peekAll](../methods/peekAll?anchor=peekAll) to get an array of current records in the
506
+ store, without waiting until a reload is finished.
507
+
508
+ ### Retrieving Related Model Records
509
+
510
+ If you use an adapter such as Ember's default
511
+ [`JSONAPIAdapter`](/ember-data/release/classes/JSONAPIAdapter)
512
+ that supports the [JSON API specification](http://jsonapi.org/) and if your server
513
+ endpoint supports the use of an
514
+ ['include' query parameter](http://jsonapi.org/format/#fetching-includes),
515
+ you can use `findAll()` to automatically retrieve additional records related to
516
+ those requested by supplying an `include` parameter in the `options` object.
517
+
518
+ For example, given a `post` model that has a `hasMany` relationship with a `comment`
519
+ model, when we retrieve all of the post records we can have the server also return
520
+ all of the posts' comments in the same request:
521
+
522
+ ```js [app/routes/posts.js]
523
+ export default class PostsRoute extends Route {
524
+ model() {
525
+ return this.store.findAll('post', { include: ['comments'] });
526
+ }
527
+ }
528
+ ```
529
+ Multiple relationships can be requested using an `include` parameter consisting of a
530
+ list or relationship names, while nested relationships can be specified
531
+ using a dot-separated sequence of relationship names. So to request both the posts'
532
+ comments and the authors of those comments the request would look like this:
533
+
534
+ ```js [app/routes/posts.js]
535
+ export default class PostsRoute extends Route {
536
+ model() {
537
+ return this.store.findAll('post', { include: ['comments','comments.author'] });
538
+ }
539
+ }
540
+ ```
541
+
542
+ See [query](../methods/query?anchor=query) to only get a subset of records from the server.
543
+
544
+ @public
545
+ @deprecated use {@link Store.request} instead
546
+ @until 6.0
547
+ @since 1.13.0
548
+ @param type the name of the resource
549
+ @param options
550
+ */
551
+ findAll<T>(type: TypeFromInstance<T>, options?: FindAllOptions<T>): Promise<LiveArray<T>>;
552
+ /** @deprecated */
553
+ findAll(type: string, options?: FindAllOptions): Promise<LiveArray>;
554
+ /**
555
+ This method delegates a query to the adapter. This is the one place where
556
+ adapter-level semantics are exposed to the application.
557
+
558
+ Each time this method is called a new request is made through the adapter.
559
+
560
+ Exposing queries this way seems preferable to creating an abstract query
561
+ language for all server-side queries, and then require all adapters to
562
+ implement them.
563
+
564
+ ---
565
+
566
+ If you do something like this:
567
+
568
+ ```javascript
569
+ store.query('person', { page: 1 });
570
+ ```
571
+
572
+ The request made to the server will look something like this:
573
+
574
+ ```
575
+ GET "/api/v1/person?page=1"
576
+ ```
577
+
578
+ ---
579
+
580
+ If you do something like this:
581
+
582
+ ```javascript
583
+ store.query('person', { ids: ['1', '2', '3'] });
584
+ ```
585
+
586
+ The request made to the server will look something like this:
587
+
588
+ ```
589
+ GET "/api/v1/person?ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=3"
590
+ decoded: "/api/v1/person?ids[]=1&ids[]=2&ids[]=3"
591
+ ```
592
+
593
+ This method returns a promise, which is resolved with a
594
+ [`Collection`](/ember-data/release/classes/Collection)
595
+ once the server returns.
596
+
597
+ @public
598
+ @deprecated use {@link Store.request} instead
599
+ @until 6.0
600
+ @since 1.13.0
601
+ @param type the name of the resource
602
+ @param query a query to be used by the adapter
603
+ @param options optional, may include `adapterOptions` hash which will be passed to adapter.query
604
+ */
605
+ query<T>(type: TypeFromInstance<T>, query: LegacyResourceQuery<T>, options?: QueryOptions): Promise<CollectionRecordArray<T>>;
606
+ /** @deprecated */
607
+ query(type: string, query: LegacyResourceQuery, options?: QueryOptions): Promise<CollectionRecordArray>;
608
+ /**
609
+ This method makes a request for one record, where the `id` is not known
610
+ beforehand (if the `id` is known, use [`findRecord`](../methods/findRecord?anchor=findRecord)
611
+ instead).
612
+
613
+ This method can be used when it is certain that the server will return a
614
+ single object for the primary data.
615
+
616
+ Each time this method is called a new request is made through the adapter.
617
+
618
+ Let's assume our API provides an endpoint for the currently logged in user
619
+ via:
620
+
621
+ ```
622
+ // GET /api/current_user
623
+ {
624
+ user: {
625
+ id: 1234,
626
+ username: 'admin'
627
+ }
628
+ }
629
+ ```
630
+
631
+ Since the specific `id` of the `user` is not known beforehand, we can use
632
+ `queryRecord` to get the user:
633
+
634
+ ```javascript
635
+ store.queryRecord('user', {}).then(function(user) {
636
+ let username = user.username;
637
+ // do thing
638
+ });
639
+ ```
640
+
641
+ The request is made through the adapters' `queryRecord`:
642
+
643
+ ```js [app/adapters/user.js]
644
+ import Adapter from '@ember-data/adapter';
645
+ import $ from 'jquery';
646
+
647
+ export default class UserAdapter extends Adapter {
648
+ queryRecord(modelName, query) {
649
+ return $.getJSON('/api/current_user');
650
+ }
651
+ }
652
+ ```
653
+
654
+ Note: the primary use case for `store.queryRecord` is when a single record
655
+ is queried and the `id` is not known beforehand. In all other cases
656
+ `store.query` and using the first item of the array is likely the preferred
657
+ way:
658
+
659
+ ```
660
+ // GET /users?username=unique
661
+ {
662
+ data: [{
663
+ id: 1234,
664
+ type: 'user',
665
+ attributes: {
666
+ username: "unique"
667
+ }
668
+ }]
669
+ }
670
+ ```
671
+
672
+ ```javascript
673
+ store.query('user', { username: 'unique' }).then(function(users) {
674
+ return users.firstObject;
675
+ }).then(function(user) {
676
+ let id = user.id;
677
+ });
678
+ ```
679
+
680
+ This method returns a promise, which resolves with the found record.
681
+
682
+ If the adapter returns no data for the primary data of the payload, then
683
+ `queryRecord` resolves with `null`:
684
+
685
+ ```
686
+ // GET /users?username=unique
687
+ {
688
+ data: null
689
+ }
690
+ ```
691
+
692
+ ```javascript
693
+ store.queryRecord('user', { username: 'unique' }).then(function(user) {
694
+ // user is null
695
+ });
696
+ ```
697
+
698
+ @public
699
+ @deprecated use {@link Store.request} instead
700
+ @until 6.0
701
+ @since 1.13.0
702
+ @param type
703
+ @param query an opaque query to be used by the adapter
704
+ @param options optional, may include `adapterOptions` hash which will be passed to adapter.queryRecord
705
+ @return promise which resolves with the found record or `null`
706
+ */
707
+ queryRecord<T>(type: TypeFromInstance<T>, query: LegacyResourceQuery<T>, options?: QueryOptions): Promise<T | null>;
708
+ /** @deprecated */
709
+ queryRecord(type: string, query: LegacyResourceQuery, options?: QueryOptions): Promise<unknown | null>;
710
+ /**
711
+ Get the reference for the specified record.
712
+
713
+ Example
714
+
715
+ ```javascript
716
+ let userRef = store.getReference('user', '1');
717
+
718
+ // check if the user is loaded
719
+ let isLoaded = userRef.value() !== null;
720
+
721
+ // get the record of the reference (null if not yet available)
722
+ let user = userRef.value();
723
+
724
+ // get the identifier of the reference
725
+ if (userRef.remoteType() === 'id') {
726
+ let id = userRef.id();
727
+ }
728
+
729
+ // load user (via store.find)
730
+ userRef.load().then(...)
731
+
732
+ // or trigger a reload
733
+ userRef.reload().then(...)
734
+
735
+ // provide data for reference
736
+ userRef.push({ id: 1, username: '@user' }).then(function(user) {
737
+ userRef.value() === user;
738
+ });
739
+ ```
740
+
741
+ @public
742
+ @deprecated use {@link Store.request} for loading and {@link Store.cache} for direct data insertion instead
743
+ @until 6.0
744
+ @since 2.5.0
745
+ @param resource - modelName (string) or Identifier (object)
746
+ @param id
747
+ */
748
+ getReference(resource: string | ResourceIdentifierObject, id: string | number): RecordReference;
749
+ /**
750
+ Returns the schema for a particular resource type (modelName).
751
+
752
+ When used with Model from @ember-data/model the return is the model class,
753
+ but this is not guaranteed.
754
+
755
+ If looking to query attribute or relationship information it is
756
+ recommended to use `getSchemaDefinitionService` instead. This method
757
+ should be considered legacy and exists primarily to continue to support
758
+ Adapter/Serializer APIs which expect it's return value in their method
759
+ signatures.
760
+
761
+ The class of a model might be useful if you want to get a list of all the
762
+ relationship names of the model, see
763
+ [`relationshipNames`](/ember-data/release/classes/Model?anchor=relationshipNames)
764
+ for example.
765
+
766
+ @public
767
+ @deprecated use {@link Store.schema} instead
768
+ @until 6.0
769
+ @param type
770
+ */
771
+ modelFor<T>(type: TypeFromInstance<T>): ModelSchema<T>;
772
+ /** @deprecated */
773
+ modelFor(type: string): ModelSchema;
774
+ /**
775
+ * Trigger a save for a Record.
776
+ *
777
+ * Returns a promise resolving with the same record when the save is complete.
778
+ *
779
+ * @deprecated use {@link Store.request} instead
780
+ * @until 6.0
781
+ * @public
782
+ * @param record
783
+ * @param options
784
+ */
785
+ saveRecord<T>(record: T, options?: Record<string, unknown>): Promise<T>;
786
+ }
787
+ }
788
+ export { Store };