coh-content-db 2.0.0-rc.7 → 2.0.0-rc.9

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.
@@ -1,120 +1,129 @@
1
- import { ContentBundle } from '../api/content-bundle'
1
+ import { BundleData } from '../api/bundle-data'
2
2
  import { Archetype } from './archetype'
3
3
  import { Zone } from './zone'
4
4
  import { Badge } from './badge'
5
- import { BundleMetadata } from './bundle-metadata'
5
+ import { BundleHeader } from './bundle-header'
6
6
  import { BadgeIndex } from './badge-index'
7
7
  import { BadgeSearchOptions } from './badge-search-options'
8
8
  import { Paged } from './paged'
9
9
  import { Contact } from './contact'
10
10
  import { Mission } from './mission'
11
+ import { AbstractIndex } from './abstract-index'
11
12
 
12
13
  export class CohContentDatabase {
13
- readonly #archetypeIndex: Record<string, Archetype> = {}
14
- readonly #zoneIndex: Record<string, Zone> = {}
15
- readonly #contactIndex: Record<string, Contact> = {}
16
- readonly #missionIndex: Record<string, Mission> = {}
17
- readonly #badgeIndex: BadgeIndex
14
+ #archetypeIndex = new AbstractIndex<Archetype>('key')
15
+ #zoneIndex = new AbstractIndex<Zone>('key')
16
+ #contactIndex = new AbstractIndex<Contact>('key')
17
+ #missionIndex = new AbstractIndex<Mission>('key')
18
+ #badgeIndex = new BadgeIndex()
19
+
20
+ #header?: BundleHeader
21
+ #servers?: string[]
22
+
23
+ /**
24
+ * Load the given content bundle, resetting the db if a bundle is already loaded.
25
+ * @param bundle The bundle to load.
26
+ */
27
+ load(bundle: BundleData): void {
28
+ this.#header = new BundleHeader(bundle.header)
29
+ this.#servers = bundle.servers ?? []
30
+
31
+ this.#archetypeIndex.load(bundle.archetypes?.map(x => new Archetype(x)))
32
+ this.#zoneIndex.load(bundle.zones?.map(x => new Zone(x)))
33
+ this.#contactIndex.load(bundle.contacts?.map(x => new Contact(x)))
34
+ this.#missionIndex.load(bundle.missions?.map(x => new Mission(x)))
35
+ this.#badgeIndex.load(bundle.badges?.map(x => new Badge(x)))
36
+ }
18
37
 
19
38
  /**
20
- * Metadata about the content bundle.
39
+ * Header information about the content bundle.
21
40
  */
22
- readonly metadata: BundleMetadata
41
+ get header(): BundleHeader | undefined {
42
+ return this.#header
43
+ }
23
44
 
24
45
  /**
25
46
  * List of the game server names.
26
47
  *
27
48
  * Torchbearer, Excelsior, etc.
28
49
  */
29
- readonly servers: string[]
50
+ get servers(): string[] {
51
+ return this.#servers ?? []
52
+ }
30
53
 
31
54
  /**
32
55
  * List of archetypes.
33
56
  */
34
- readonly archetypes: Archetype[]
57
+ get archetypes(): Archetype[] {
58
+ return this.#archetypeIndex.values
59
+ }
35
60
 
36
61
  /**
37
- * List of game zones.
62
+ * Get archetype by key.
63
+ * @param key The key.
38
64
  */
39
- readonly zones: Zone[]
65
+ getArchetype(key: string | undefined): Archetype | undefined {
66
+ return this.#archetypeIndex.get(key)
67
+ }
40
68
 
41
69
  /**
42
- * List of contacts.
70
+ * List of game zones.
43
71
  */
44
- readonly contacts: Contact[]
72
+ get zones(): Zone[] {
73
+ return this.#zoneIndex.values
74
+ }
45
75
 
46
76
  /**
47
- * List of missions.
77
+ * Get zone by key.
78
+ * @param key The key.
48
79
  */
49
- readonly missions: Contact[]
80
+ getZone(key: string | undefined): Zone | undefined {
81
+ return this.#zoneIndex.get(key)
82
+ }
50
83
 
51
84
  /**
52
- * List of badges.
85
+ * List of contacts.
53
86
  */
54
- readonly badges: Badge[]
87
+ get contacts(): Contact[] {
88
+ return this.#contactIndex.values
89
+ }
55
90
 
56
91
  /**
57
- * Initialize the database with a content bundle.
58
- * @param bundle The data to load.
92
+ * Get contact by key.
93
+ * @param key The key.
59
94
  */
60
- constructor(bundle: ContentBundle) {
61
- this.metadata = new BundleMetadata(bundle)
62
- this.servers = bundle.servers ?? []
63
-
64
- this.archetypes = bundle.archetypes?.map((data) => {
65
- if (this.#archetypeIndex[data.key] !== undefined) throw new Error(`Duplicate archetype key '${data.key}'`)
66
- const archetype = new Archetype(data)
67
- this.#archetypeIndex[archetype.key] = archetype
68
- return archetype
69
- }) ?? []
70
-
71
- this.zones = bundle.zones?.map((data) => {
72
- if (this.#zoneIndex[data.key] !== undefined) throw new Error(`Duplicate zone key '${data.key}'`)
73
- const zone = new Zone(data)
74
- this.#zoneIndex[zone.key] = zone
75
- return zone
76
- }) ?? []
77
-
78
- this.contacts = bundle.contacts?.map((data) => {
79
- if (this.#contactIndex[data.key] !== undefined) throw new Error(`Duplicate contact key '${data.key}'`)
80
- const contact = new Contact(data)
81
- this.#contactIndex[contact.key] = contact
82
- return contact
83
- }) ?? []
84
-
85
- this.missions = bundle.missions?.map((data) => {
86
- if (this.#missionIndex[data.key] !== undefined) throw new Error(`Duplicate mission key '${data.key}'`)
87
- const mission = new Mission(data)
88
- this.#missionIndex[mission.key] = mission
89
- return mission
90
- }) ?? []
91
-
92
- this.badges = bundle.badges?.map(data => new Badge(data)) ?? []
93
- this.#badgeIndex = new BadgeIndex(this.badges)
94
- }
95
-
96
- getArchetype(key?: string): Archetype | undefined {
97
- if (!key) return undefined
98
- return this.#archetypeIndex[key]
95
+ getContact(key: string | undefined): Contact | undefined {
96
+ return this.#contactIndex.get(key)
99
97
  }
100
98
 
101
- getZone(key?: string): Zone | undefined {
102
- if (!key) return undefined
103
- return this.#zoneIndex[key]
99
+ /**
100
+ * List of missions.
101
+ */
102
+ get missions(): Mission[] {
103
+ return this.#missionIndex.values
104
104
  }
105
105
 
106
- getContact(key?: string): Contact | undefined {
107
- if (!key) return undefined
108
- return this.#contactIndex[key]
106
+ /**
107
+ * Get mission by key.
108
+ * @param key The key.
109
+ */
110
+ getMission(key: string | undefined): Mission | undefined {
111
+ return this.#missionIndex.get(key)
109
112
  }
110
113
 
111
- getMission(key?: string): Mission | undefined {
112
- if (!key) return undefined
113
- return this.#missionIndex[key]
114
+ /**
115
+ * List of badges.
116
+ */
117
+ get badges(): Badge[] {
118
+ return this.#badgeIndex.values
114
119
  }
115
120
 
116
- getBadge(key?: string): Badge | undefined {
117
- return this.#badgeIndex.getBadge(key)
121
+ /**
122
+ * Get badge by key.
123
+ * @param key The key.
124
+ */
125
+ getBadge(key: string | undefined): Badge | undefined {
126
+ return this.#badgeIndex.get(key)
118
127
  }
119
128
 
120
129
  /**
@@ -124,6 +133,6 @@ export class CohContentDatabase {
124
133
  * @param options {@link BadgeSearchOptions}
125
134
  */
126
135
  searchBadges(options?: BadgeSearchOptions): Paged<Badge> {
127
- return this.#badgeIndex.searchBadges(options)
136
+ return this.#badgeIndex.search(options)
128
137
  }
129
138
  }
package/src/main/index.ts CHANGED
@@ -6,9 +6,9 @@ export * from './api/badge-data'
6
6
  export * from './api/badge-requirement-data'
7
7
  export * from './api/badge-requirement-type'
8
8
  export * from './api/badge-type'
9
- export * from './api/change'
9
+ export * from './api/bundle-data'
10
+ export * from './api/bundle-header-data'
10
11
  export * from './api/contact-data'
11
- export * from './api/content-bundle'
12
12
  export * from './api/enhancement-category'
13
13
  export * from './api/link'
14
14
  export * from './api/location-data'
@@ -27,7 +27,7 @@ export * from './db/badge'
27
27
  export * from './db/badge-index'
28
28
  export * from './db/badge-requirement'
29
29
  export * from './db/badge-search-options'
30
- export * from './db/bundle-metadata'
30
+ export * from './db/bundle-header'
31
31
  export * from './db/coh-content-database'
32
32
  export * from './db/contact'
33
33
  export * from './db/key'
@@ -38,5 +38,4 @@ export * from './db/paged'
38
38
  export * from './db/zone'
39
39
 
40
40
  // ROOT
41
- export { CHANGELOG } from './changelog'
42
41
  export * from './util'
@@ -0,0 +1,6 @@
1
+ import { defineFixture } from 'efate'
2
+ import { BundleData } from '../../main'
3
+
4
+ export const bundleDataFixture = defineFixture<BundleData>(() => {
5
+ // no mandatory fields
6
+ })
@@ -0,0 +1,6 @@
1
+ import { defineFixture } from 'efate'
2
+ import { BundleHeaderData } from '../../main'
3
+
4
+ export const bundleHeaderDataFixture = defineFixture<BundleHeaderData>(() => {
5
+ // no mandatory fields
6
+ })
@@ -0,0 +1,86 @@
1
+ import { AbstractIndex } from '../../main/db/abstract-index'
2
+
3
+ interface TestObject {
4
+ key: string
5
+ otherValue: number
6
+ }
7
+
8
+ describe(AbstractIndex.name, () => {
9
+ describe('Constructor', () => {
10
+ test(`should accept the key field`, () => {
11
+ new AbstractIndex<TestObject>('key')
12
+ })
13
+ })
14
+
15
+ describe('value', () => {
16
+ test(`should return the original values`, () => {
17
+ const values = [
18
+ { key: '1', otherValue: 1 },
19
+ { key: '2', otherValue: 2 },
20
+ ]
21
+ const index = new AbstractIndex<TestObject>('key')
22
+ index.load(values)
23
+
24
+ expect(index.values).toStrictEqual(values)
25
+ })
26
+ })
27
+
28
+ describe('get', () => {
29
+ test(`should return the indexed value on match`, () => {
30
+ const index = new AbstractIndex<TestObject>('key')
31
+ index.load([
32
+ { key: '1', otherValue: 1 },
33
+ { key: '2', otherValue: 2 },
34
+ ])
35
+
36
+ expect(index.get('2')).toStrictEqual({ key: '2', otherValue: 2 })
37
+ })
38
+
39
+ test(`should return undefined on no match`, () => {
40
+ const index = new AbstractIndex<TestObject>('key')
41
+
42
+ expect(index.get('2')).toBeUndefined()
43
+ })
44
+
45
+ test(`should return undefined on undefined key`, () => {
46
+ const index = new AbstractIndex<TestObject>('key')
47
+ const key = undefined
48
+ expect(index.get(key)).toBeUndefined()
49
+ })
50
+ })
51
+
52
+ describe('load', () => {
53
+ test(`should reset the index when used`, () => {
54
+ const index = new AbstractIndex<TestObject>('key')
55
+ index.load([
56
+ { key: '1', otherValue: 1 },
57
+ { key: '2', otherValue: 2 },
58
+ ])
59
+
60
+ expect(index.get('2')).toStrictEqual({ key: '2', otherValue: 2 })
61
+
62
+ index.load([
63
+ { key: '3', otherValue: 3 },
64
+ ])
65
+ expect(index.get('1')).toBeUndefined()
66
+ expect(index.get('2')).toBeUndefined()
67
+ expect(index.get('3')).toStrictEqual({ key: '3', otherValue: 3 })
68
+ })
69
+
70
+ test(`should accept an undefined value`, () => {
71
+ const index = new AbstractIndex<TestObject>('key')
72
+ const values = undefined
73
+ index.load(values)
74
+
75
+ expect(index.values).toHaveLength(0)
76
+ })
77
+
78
+ test(`should throw an error on duplicate key`, () => {
79
+ const index = new AbstractIndex<TestObject>('key')
80
+ expect(() => index.load([
81
+ { key: '1', otherValue: 1 },
82
+ { key: '1', otherValue: 1 },
83
+ ])).toThrow('Duplicate key [1]')
84
+ })
85
+ })
86
+ })