@commitspark/graphql-api 1.0.0-beta.4 → 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.
- package/CHANGELOG.md +18 -0
- package/dist/cjs/client.js +16 -14
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/graphql/resolvers/field-resolvers/entry-reference-resolver.js +2 -1
- package/dist/cjs/graphql/resolvers/field-resolvers/entry-reference-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/field-resolvers/field-default-value-resolver.js +2 -12
- package/dist/cjs/graphql/resolvers/field-resolvers/field-default-value-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/object-type-field-default-value-resolver-generator.js +1 -5
- package/dist/cjs/graphql/resolvers/object-type-field-default-value-resolver-generator.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js +6 -8
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js +4 -4
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js +6 -6
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js +3 -2
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js +3 -2
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.js +3 -2
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.js.map +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js +1 -1
- package/dist/cjs/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js.map +1 -1
- package/dist/cjs/graphql/schema-generator.js +1 -1
- package/dist/cjs/graphql/schema-generator.js.map +1 -1
- package/dist/cjs/graphql/schema-utils/entry-reference-util.js +2 -2
- package/dist/cjs/graphql/schema-utils/entry-reference-util.js.map +1 -1
- package/dist/cjs/graphql/schema-validator.js +1 -1
- package/dist/cjs/graphql/schema-validator.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/persistence/cache.js +105 -0
- package/dist/cjs/persistence/cache.js.map +1 -0
- package/dist/cjs/persistence/persistence.js +13 -41
- package/dist/cjs/persistence/persistence.js.map +1 -1
- package/dist/esm/client.js +16 -14
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/graphql/resolvers/field-resolvers/entry-reference-resolver.js +2 -1
- package/dist/esm/graphql/resolvers/field-resolvers/entry-reference-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/field-resolvers/field-default-value-resolver.js +2 -4
- package/dist/esm/graphql/resolvers/field-resolvers/field-default-value-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/object-type-field-default-value-resolver-generator.js +1 -2
- package/dist/esm/graphql/resolvers/object-type-field-default-value-resolver-generator.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js +6 -8
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js +4 -4
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js +6 -6
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js +3 -2
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js +3 -2
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-every-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.js +3 -2
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.js.map +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js +1 -1
- package/dist/esm/graphql/resolvers/query-mutation-resolvers/union-type-resolver.js.map +1 -1
- package/dist/esm/graphql/schema-generator.js +1 -1
- package/dist/esm/graphql/schema-generator.js.map +1 -1
- package/dist/esm/graphql/schema-utils/entry-reference-util.js +2 -2
- package/dist/esm/graphql/schema-utils/entry-reference-util.js.map +1 -1
- package/dist/esm/graphql/schema-validator.js +1 -1
- package/dist/esm/graphql/schema-validator.js.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/persistence/cache.js +92 -0
- package/dist/esm/persistence/cache.js.map +1 -0
- package/dist/esm/persistence/persistence.js +12 -41
- package/dist/esm/persistence/persistence.js.map +1 -1
- package/dist/tsconfig.build.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.build.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.build.types.tsbuildinfo +1 -1
- package/dist/types/client.d.ts +6 -4
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/field-resolvers/entry-reference-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/field-resolvers/field-default-value-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/field-resolvers/types.d.ts +3 -4
- package/dist/types/graphql/resolvers/field-resolvers/types.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/object-type-field-default-value-resolver-generator.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query-mutation-resolvers/query-every-resolver.d.ts.map +1 -1
- package/dist/types/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.d.ts.map +1 -1
- package/dist/types/graphql/schema-generator.d.ts.map +1 -1
- package/dist/types/graphql/schema-utils/entry-reference-util.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/persistence/cache.d.ts +13 -0
- package/dist/types/persistence/cache.d.ts.map +1 -0
- package/dist/types/persistence/persistence.d.ts +6 -5
- package/dist/types/persistence/persistence.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +20 -14
- package/src/graphql/resolvers/field-resolvers/entry-reference-resolver.ts +2 -5
- package/src/graphql/resolvers/field-resolvers/field-default-value-resolver.ts +2 -4
- package/src/graphql/resolvers/field-resolvers/types.ts +3 -4
- package/src/graphql/resolvers/object-type-field-default-value-resolver-generator.ts +1 -2
- package/src/graphql/resolvers/query-mutation-resolvers/mutation-create-resolver.ts +6 -21
- package/src/graphql/resolvers/query-mutation-resolvers/mutation-delete-resolver.ts +4 -13
- package/src/graphql/resolvers/query-mutation-resolvers/mutation-update-resolver.ts +6 -21
- package/src/graphql/resolvers/query-mutation-resolvers/query-by-id-resolver.ts +3 -7
- package/src/graphql/resolvers/query-mutation-resolvers/query-every-resolver.ts +3 -6
- package/src/graphql/resolvers/query-mutation-resolvers/query-type-by-id-resolver.ts +3 -2
- package/src/graphql/resolvers/query-mutation-resolvers/union-type-resolver.ts +1 -1
- package/src/graphql/schema-generator.ts +3 -2
- package/src/graphql/schema-utils/entry-reference-util.ts +2 -6
- package/src/graphql/schema-validator.ts +1 -1
- package/src/index.ts +4 -2
- package/src/persistence/cache.ts +156 -0
- package/src/persistence/persistence.ts +20 -45
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Entry, GitAdapterError } from '@commitspark/git-adapter'
|
|
2
|
+
import { ApolloContext } from '../client'
|
|
3
|
+
import { createError, ErrorCode } from '../graphql/errors'
|
|
4
|
+
|
|
5
|
+
type Ref = string
|
|
6
|
+
type EntriesCache = Map<Ref, EntriesRecord>
|
|
7
|
+
type SchemaCache = Map<Ref, string>
|
|
8
|
+
type InflightEntries = Map<Ref, Promise<EntriesRecord>>
|
|
9
|
+
|
|
10
|
+
interface EntriesRecord {
|
|
11
|
+
byId: Map<string, Entry>
|
|
12
|
+
byType: Map<string, Entry[]>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface RepositoryCacheHandler {
|
|
16
|
+
getEntriesRecord: (
|
|
17
|
+
context: ApolloContext,
|
|
18
|
+
ref: string,
|
|
19
|
+
) => Promise<EntriesRecord>
|
|
20
|
+
getSchema: (context: ApolloContext, ref: string) => Promise<string>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const MAX_CACHE_ENTRIES = 50
|
|
24
|
+
|
|
25
|
+
// intentionally not async so that the same in-flight promise is returned to all callers
|
|
26
|
+
const getEntriesRecordByRef = (
|
|
27
|
+
entriesCache: EntriesCache,
|
|
28
|
+
inflightEntries: InflightEntries,
|
|
29
|
+
cacheSize: number,
|
|
30
|
+
context: ApolloContext,
|
|
31
|
+
ref: string,
|
|
32
|
+
): Promise<EntriesRecord> => {
|
|
33
|
+
const cacheRecord = entriesCache.get(ref)
|
|
34
|
+
if (cacheRecord !== undefined) {
|
|
35
|
+
// move map key back to end of list (newest)
|
|
36
|
+
entriesCache.delete(ref)
|
|
37
|
+
entriesCache.set(ref, cacheRecord)
|
|
38
|
+
|
|
39
|
+
return Promise.resolve(cacheRecord)
|
|
40
|
+
}
|
|
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> => {
|
|
65
|
+
let allEntries: Entry[]
|
|
66
|
+
try {
|
|
67
|
+
allEntries = await context.gitAdapter.getEntries(ref)
|
|
68
|
+
} catch (err) {
|
|
69
|
+
if (err instanceof GitAdapterError) {
|
|
70
|
+
throw createError(err.message, err.code, {})
|
|
71
|
+
}
|
|
72
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
73
|
+
throw createError(message, ErrorCode.INTERNAL_ERROR, {})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const entriesById = new Map(allEntries.map((entry) => [entry.id, entry]))
|
|
77
|
+
const entriesByType = new Map<string, Entry[]>()
|
|
78
|
+
for (const entry of allEntries) {
|
|
79
|
+
const existingEntriesOfType = entriesByType.get(entry.metadata.type) || []
|
|
80
|
+
existingEntriesOfType.push(entry)
|
|
81
|
+
entriesByType.set(entry.metadata.type, existingEntriesOfType)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const newCacheRecord = {
|
|
85
|
+
byType: entriesByType,
|
|
86
|
+
byId: entriesById,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
entriesCache.set(ref, newCacheRecord)
|
|
90
|
+
|
|
91
|
+
if (entriesCache.size > cacheSize) {
|
|
92
|
+
// get first map key (oldest)
|
|
93
|
+
const oldestKey = entriesCache.keys().next().value as Ref | undefined
|
|
94
|
+
if (oldestKey !== undefined) {
|
|
95
|
+
entriesCache.delete(oldestKey)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return newCacheRecord
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const getSchemaStringByRef = async (
|
|
103
|
+
schemaCache: SchemaCache,
|
|
104
|
+
cacheSize: number,
|
|
105
|
+
context: ApolloContext,
|
|
106
|
+
ref: string,
|
|
107
|
+
): Promise<string> => {
|
|
108
|
+
const schemaCacheRecord = schemaCache.get(ref)
|
|
109
|
+
if (schemaCacheRecord !== undefined) {
|
|
110
|
+
// move map key back to end of list (newest)
|
|
111
|
+
schemaCache.delete(ref)
|
|
112
|
+
schemaCache.set(ref, schemaCacheRecord)
|
|
113
|
+
|
|
114
|
+
return schemaCacheRecord
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let schemaString
|
|
118
|
+
try {
|
|
119
|
+
schemaString = await context.gitAdapter.getSchema(ref)
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (err instanceof GitAdapterError) {
|
|
122
|
+
throw createError(err.message, err.code, {})
|
|
123
|
+
}
|
|
124
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
125
|
+
throw createError(message, ErrorCode.INTERNAL_ERROR, {})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
schemaCache.set(ref, schemaString)
|
|
129
|
+
|
|
130
|
+
if (schemaCache.size > cacheSize) {
|
|
131
|
+
// get first map key (oldest)
|
|
132
|
+
const oldestKey = schemaCache.keys().next().value as Ref | undefined
|
|
133
|
+
if (oldestKey !== undefined) {
|
|
134
|
+
schemaCache.delete(oldestKey)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return schemaString
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export const createCacheHandler = (
|
|
142
|
+
cacheSize: number = MAX_CACHE_ENTRIES,
|
|
143
|
+
): RepositoryCacheHandler => {
|
|
144
|
+
const entriesCache: EntriesCache = new Map<Ref, EntriesRecord>()
|
|
145
|
+
const schemaCache: SchemaCache = new Map<Ref, string>()
|
|
146
|
+
const inflightEntries: InflightEntries = new Map<
|
|
147
|
+
Ref,
|
|
148
|
+
Promise<EntriesRecord>
|
|
149
|
+
>()
|
|
150
|
+
return {
|
|
151
|
+
getEntriesRecord: (...args) =>
|
|
152
|
+
getEntriesRecordByRef(entriesCache, inflightEntries, cacheSize, ...args),
|
|
153
|
+
getSchema: (...args) =>
|
|
154
|
+
getSchemaStringByRef(schemaCache, cacheSize, ...args),
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -1,30 +1,24 @@
|
|
|
1
|
-
import { Entry
|
|
1
|
+
import { Entry } from '@commitspark/git-adapter'
|
|
2
2
|
import { createError, ErrorCode } from '../graphql/errors'
|
|
3
|
+
import { ApolloContext } from '../client'
|
|
3
4
|
|
|
4
5
|
export async function getTypeById(
|
|
5
|
-
|
|
6
|
-
commitHash: string,
|
|
6
|
+
context: ApolloContext,
|
|
7
7
|
id: string,
|
|
8
8
|
): Promise<string> {
|
|
9
|
-
const requestedEntry = await findById(
|
|
9
|
+
const requestedEntry = await findById(context, id)
|
|
10
10
|
return requestedEntry.metadata.type
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export async function findById(
|
|
14
|
-
|
|
15
|
-
commitHash: string,
|
|
14
|
+
context: ApolloContext,
|
|
16
15
|
id: string,
|
|
17
16
|
): Promise<Entry> {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
throw createError(err.message, err.code, {})
|
|
24
|
-
}
|
|
25
|
-
throw err
|
|
26
|
-
}
|
|
27
|
-
const requestedEntry = allEntries.find((entry: Entry) => entry.id === id)
|
|
17
|
+
const entriesRecord = await context.repositoryCache.getEntriesRecord(
|
|
18
|
+
context,
|
|
19
|
+
context.getCurrentHash(),
|
|
20
|
+
)
|
|
21
|
+
const requestedEntry = entriesRecord.byId.get(id)
|
|
28
22
|
if (requestedEntry === undefined) {
|
|
29
23
|
throw createError(`No entry with ID "${id}" exists.`, ErrorCode.NOT_FOUND, {
|
|
30
24
|
argumentName: 'id',
|
|
@@ -36,42 +30,23 @@ export async function findById(
|
|
|
36
30
|
}
|
|
37
31
|
|
|
38
32
|
export async function findByType(
|
|
39
|
-
|
|
40
|
-
commitHash: string,
|
|
33
|
+
context: ApolloContext,
|
|
41
34
|
type: string,
|
|
42
35
|
): Promise<Entry[]> {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
throw createError(err.message, err.code, {})
|
|
49
|
-
}
|
|
50
|
-
throw err
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return allEntries.filter((entry: Entry) => entry.metadata.type === type)
|
|
36
|
+
const entriesRecord = await context.repositoryCache.getEntriesRecord(
|
|
37
|
+
context,
|
|
38
|
+
context.getCurrentHash(),
|
|
39
|
+
)
|
|
40
|
+
return entriesRecord.byType.get(type) ?? []
|
|
54
41
|
}
|
|
55
42
|
|
|
56
43
|
export async function findByTypeId(
|
|
57
|
-
|
|
58
|
-
commitHash: string,
|
|
44
|
+
context: ApolloContext,
|
|
59
45
|
type: string,
|
|
60
46
|
id: string,
|
|
61
47
|
): Promise<Entry> {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
allEntries = await gitAdapter.getEntries(commitHash)
|
|
65
|
-
} catch (err) {
|
|
66
|
-
if (err instanceof GitAdapterError) {
|
|
67
|
-
throw createError(err.message, err.code, {})
|
|
68
|
-
}
|
|
69
|
-
throw err
|
|
70
|
-
}
|
|
71
|
-
const requestedEntry = allEntries.find(
|
|
72
|
-
(entry: Entry) => entry.id === id && entry.metadata.type === type,
|
|
73
|
-
)
|
|
74
|
-
if (requestedEntry === undefined) {
|
|
48
|
+
const entryById = await findById(context, id)
|
|
49
|
+
if (entryById === undefined || entryById.metadata.type !== type) {
|
|
75
50
|
throw createError(
|
|
76
51
|
`No entry of type "${type}" with ID "${id}" exists.`,
|
|
77
52
|
ErrorCode.NOT_FOUND,
|
|
@@ -83,5 +58,5 @@ export async function findByTypeId(
|
|
|
83
58
|
)
|
|
84
59
|
}
|
|
85
60
|
|
|
86
|
-
return
|
|
61
|
+
return entryById
|
|
87
62
|
}
|