-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathmany-array-manager.ts
98 lines (81 loc) · 3.21 KB
/
many-array-manager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import type Store from '@ember-data/store';
import type { RelatedCollection as ManyArray } from '@ember-data/store/-private';
import { fastPush, SOURCE } from '@ember-data/store/-private';
import { assert } from '@warp-drive/build-config/macros';
import type { StableRecordIdentifier } from '@warp-drive/core-types';
import type { Cache } from '@warp-drive/core-types/cache';
import type { CollectionRelationship } from '@warp-drive/core-types/cache/relationship';
import type { LocalRelationshipOperation } from '@warp-drive/core-types/graph';
import type { CacheOptions } from '@warp-drive/core-types/request';
import { EnableHydration } from '@warp-drive/core-types/request';
import type { CollectionResourceRelationship } from '@warp-drive/core-types/spec/json-api-raw';
import { RecordStore } from '@warp-drive/core-types/symbols';
import type { SchemaRecord } from '../record';
import { Identifier } from '../symbols';
export interface FindHasManyOptions {
reload?: boolean;
backgroundReload?: boolean;
}
export class ManyArrayManager {
declare record: SchemaRecord;
declare store: Store;
declare cache: Cache;
declare identifier: StableRecordIdentifier;
constructor(record: SchemaRecord) {
this.record = record;
this.store = record[RecordStore];
this.identifier = record[Identifier];
}
_syncArray(array: ManyArray) {
const rawValue = this.store.cache.getRelationship(this.identifier, array.key) as CollectionRelationship;
if (rawValue.meta) {
array.meta = rawValue.meta;
}
if (rawValue.links) {
array.links = rawValue.links;
}
const currentState = array[SOURCE];
currentState.length = 0;
fastPush(currentState, rawValue.data as StableRecordIdentifier[]);
}
reloadHasMany<T>(key: string, options?: FindHasManyOptions): Promise<ManyArray<T>> {
const field = this.store.schema.fields(this.identifier).get(key);
assert(`Expected a hasMany field for ${key}`, field?.kind === 'hasMany');
const cacheOptions = options ? extractCacheOptions(options) : { reload: true };
cacheOptions.types = [field.type];
const rawValue = this.store.cache.getRelationship(this.identifier, key) as CollectionRelationship;
const req = {
url: getRelatedLink(rawValue),
op: 'findHasMany',
method: 'GET' as const,
records: rawValue.data as StableRecordIdentifier[],
cacheOptions,
options: {
field,
identifier: this.identifier,
links: rawValue.links,
meta: rawValue.meta,
},
[EnableHydration]: false,
};
return this.store.request(req) as unknown as Promise<ManyArray<T>>;
}
mutate(mutation: LocalRelationshipOperation): void {
this.cache.mutate(mutation);
}
}
function getRelatedLink(resource: CollectionResourceRelationship): string {
const related = resource.links?.related;
assert(`Expected a related link`, related);
return typeof related === 'object' ? related.href : related;
}
function extractCacheOptions(options: FindHasManyOptions) {
const cacheOptions: CacheOptions = {};
if ('reload' in options) {
cacheOptions.reload = options.reload;
}
if ('backgroundReload' in options) {
cacheOptions.backgroundReload = options.backgroundReload;
}
return cacheOptions;
}