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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
import CacheableObject from '#cacheable-object';
import find from '#find';
import {withEntries} from '#sugar';
import Thing from '#thing';
import thingConstructors from '#things';
import {linkWikiDataArrays} from '#yaml';
export function linkAndBindWikiData(wikiData, {
inferAlbumsOwnTrackData = true,
} = {}) {
function customLinkWikiDataArrays(wikiData, options = {}) {
linkWikiDataArrays(
(options.XXX_decacheWikiData
? withEntries(wikiData, entries => entries
.map(([key, value]) => [key, value.slice()]))
: wikiData));
}
customLinkWikiDataArrays(wikiData);
return {
// Mutate to make the below functions aware of new data objects, or of
// reordering the existing ones. Don't mutate arrays such as trackData
// in-place; assign completely new arrays to this wikiData object instead.
wikiData,
// Use this after you've mutated wikiData to assign new data arrays.
// It'll automatically relink everything on wikiData so all the objects
// are caught up to date.
linkWikiDataArrays:
customLinkWikiDataArrays
.bind(null, wikiData),
// Use this if you HAVEN'T mutated wikiData and just need to decache
// indirect dependencies on exposed properties of other data objects.
//
// XXX_decacheWikiData option should be used specifically to mark points
// where you *aren't* replacing any of the arrays under wikiData with
// new values, and are using linkWikiDataArrays to instead "decache" data
// properties which depend on any of them. It's currently not possible for
// a CacheableObject to depend directly on the value of a property exposed
// on some other CacheableObject, so when those values change, you have to
// manually decache before the object will realize its cache isn't valid
// anymore.
//
// The previous implementation for this involved overwriting the relevant
// wikiData properties with null, then replacing it with the original
// array, which effectively cleared a CacheableObject cache. But it isn't
// enough to clear other caches that depend on the identity of wikiData
// arrays, such as withReverseReferenceList, so now it replaces with fresh
// copies of the data arrays instead; the original identities don't get
// reused.
XXX_decacheWikiData:
customLinkWikiDataArrays
.bind(null, wikiData, {XXX_decacheWikiData: true}),
};
}
export function stubWikiData() {
return {
albumData: [],
artistData: [],
artTagData: [],
flashData: [],
flashActData: [],
flashSideData: [],
groupData: [],
groupCategoryData: [],
newsData: [],
staticPageData: [],
trackData: [],
trackSectionData: [],
};
}
export function stubThing(wikiData, constructor, properties = {}) {
const thing = Reflect.construct(constructor, []);
Object.assign(thing, properties);
const wikiDataSpec = {
Album: 'albumData',
Artist: 'artistData',
ArtTag: 'artTagData',
Flash: 'flashData',
FlashAct: 'flashActData',
FlashSide: 'flashSideData',
Group: 'groupData',
GroupCategory: 'groupCategoryData',
NewsEntry: 'newsData',
StaticPage: 'staticPageData',
Track: 'trackData',
TrackSection: 'trackSectionData',
};
const wikiDataMap =
new Map(
Object.entries(wikiDataSpec)
.map(([thingKey, wikiDataKey]) => [
thingConstructors[thingKey],
wikiData[wikiDataKey],
]));
const wikiDataArray =
wikiDataMap.get(constructor);
wikiDataArray.push(thing);
return thing;
}
export function stubTrackAndAlbum(wikiData, trackDirectory = null, albumDirectory = null) {
const {Track, TrackSection, Album} = thingConstructors;
const track =
stubThing(wikiData, Track, {directory: trackDirectory});
const section =
stubThing(wikiData, TrackSection, {tracks: [track]});
const album =
stubThing(wikiData, Album, {directory: albumDirectory, trackSections: [section]});
return {track, album, section};
}
export function stubArtistAndContribs(wikiData, artistName = `Test Artist`) {
const {Artist} = thingConstructors;
const artist =
stubThing(wikiData, Artist, {name: artistName});
const contribs =
[{artist: artistName, annotation: null}];
const badContribs =
[{artist: `Figment of Your Imagination`, annotation: null}];
return {artist, contribs, badContribs};
}
export function stubFlashAndAct(wikiData, flashDirectory = null) {
const {Flash, FlashAct} = thingConstructors;
const flash =
stubThing(wikiData, Flash, {directory: flashDirectory});
const flashAct =
stubThing(wikiData, FlashAct, {
flashes: [Thing.getReference(flash)],
});
return {flash, flashAct};
}
|