@commitspark/graphql-api 1.0.0-beta.5 → 1.0.0-beta.6

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,10 +1,11 @@
1
1
  import { Entry, GitAdapterError } from '@commitspark/git-adapter'
2
2
  import { ApolloContext } from '../client'
3
- import { createError } from '../graphql/errors'
3
+ import { createError, ErrorCode } from '../graphql/errors'
4
4
 
5
5
  type Ref = string
6
6
  type EntriesCache = Map<Ref, EntriesRecord>
7
7
  type SchemaCache = Map<Ref, string>
8
+ type InflightEntries = Map<Ref, Promise<EntriesRecord>>
8
9
 
9
10
  interface EntriesRecord {
10
11
  byId: Map<string, Entry>
@@ -21,8 +22,10 @@ export interface RepositoryCacheHandler {
21
22
 
22
23
  const MAX_CACHE_ENTRIES = 50
23
24
 
24
- const getEntriesRecordByRef = async (
25
+ // intentionally not async so that the same in-flight promise is returned to all callers
26
+ const getEntriesRecordByRef = (
25
27
  entriesCache: EntriesCache,
28
+ inflightEntries: InflightEntries,
26
29
  cacheSize: number,
27
30
  context: ApolloContext,
28
31
  ref: string,
@@ -33,9 +36,32 @@ const getEntriesRecordByRef = async (
33
36
  entriesCache.delete(ref)
34
37
  entriesCache.set(ref, cacheRecord)
35
38
 
36
- return cacheRecord
39
+ return Promise.resolve(cacheRecord)
37
40
  }
38
41
 
42
+ const inflightPromise = inflightEntries.get(ref)
43
+ if (inflightPromise) {
44
+ return inflightPromise
45
+ }
46
+
47
+ const fetchPromise = fetchAndCacheEntries(
48
+ entriesCache,
49
+ cacheSize,
50
+ context,
51
+ ref,
52
+ ).finally(() => inflightEntries.delete(ref))
53
+
54
+ inflightEntries.set(ref, fetchPromise)
55
+
56
+ return fetchPromise
57
+ }
58
+
59
+ const fetchAndCacheEntries = async (
60
+ entriesCache: EntriesCache,
61
+ cacheSize: number,
62
+ context: ApolloContext,
63
+ ref: string,
64
+ ): Promise<EntriesRecord> => {
39
65
  let allEntries: Entry[]
40
66
  try {
41
67
  allEntries = await context.gitAdapter.getEntries(ref)
@@ -43,14 +69,16 @@ const getEntriesRecordByRef = async (
43
69
  if (err instanceof GitAdapterError) {
44
70
  throw createError(err.message, err.code, {})
45
71
  }
46
- throw err
72
+ const message = err instanceof Error ? err.message : String(err)
73
+ throw createError(message, ErrorCode.INTERNAL_ERROR, {})
47
74
  }
75
+
48
76
  const entriesById = new Map(allEntries.map((entry) => [entry.id, entry]))
49
77
  const entriesByType = new Map<string, Entry[]>()
50
78
  for (const entry of allEntries) {
51
- const arr = entriesByType.get(entry.metadata.type) || []
52
- arr.push(entry)
53
- entriesByType.set(entry.metadata.type, arr)
79
+ const existingEntriesOfType = entriesByType.get(entry.metadata.type) || []
80
+ existingEntriesOfType.push(entry)
81
+ entriesByType.set(entry.metadata.type, existingEntriesOfType)
54
82
  }
55
83
 
56
84
  const newCacheRecord = {
@@ -93,7 +121,8 @@ const getSchemaStringByRef = async (
93
121
  if (err instanceof GitAdapterError) {
94
122
  throw createError(err.message, err.code, {})
95
123
  }
96
- throw err
124
+ const message = err instanceof Error ? err.message : String(err)
125
+ throw createError(message, ErrorCode.INTERNAL_ERROR, {})
97
126
  }
98
127
 
99
128
  schemaCache.set(ref, schemaString)
@@ -114,9 +143,13 @@ export const createCacheHandler = (
114
143
  ): RepositoryCacheHandler => {
115
144
  const entriesCache: EntriesCache = new Map<Ref, EntriesRecord>()
116
145
  const schemaCache: SchemaCache = new Map<Ref, string>()
146
+ const inflightEntries: InflightEntries = new Map<
147
+ Ref,
148
+ Promise<EntriesRecord>
149
+ >()
117
150
  return {
118
151
  getEntriesRecord: (...args) =>
119
- getEntriesRecordByRef(entriesCache, cacheSize, ...args),
152
+ getEntriesRecordByRef(entriesCache, inflightEntries, cacheSize, ...args),
120
153
  getSchema: (...args) =>
121
154
  getSchemaStringByRef(schemaCache, cacheSize, ...args),
122
155
  }