Skip to content

Commit debbe39

Browse files
committed
refactor: simpler decode functions
1 parent 112c6d2 commit debbe39

File tree

3 files changed

+52
-40
lines changed

3 files changed

+52
-40
lines changed

src/extensions/CustomScalars/decode.ts

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,29 @@ export const decodeResultData = ({ request, data, sddm, scalars }: {
2828
if (!sddmOutputObject) return
2929
if (!data) return
3030

31-
for (const [key, value] of Object.entries(data)) {
32-
const documentField = findDocumentField(request.operation.selectionSet, key)
33-
const kSchema = documentField?.name.value ?? key
34-
const sddmOutputField = sddmOutputObject.f[kSchema]
35-
if (!sddmOutputField?.nt) continue
36-
37-
decodeResultValue({
38-
parentContext: { type: `object`, object: data, key },
39-
value,
40-
sddmNode: sddmOutputField.nt,
41-
documentPart: documentField?.selectionSet ?? null,
42-
scalars,
43-
})
44-
}
31+
decodeResultValue({
32+
parentContext: null,
33+
value: data,
34+
sddmNode: sddmOutputObject,
35+
documentPart: request.operation.selectionSet,
36+
scalars,
37+
})
4538
}
4639

4740
const decodeResultValue = (input: {
48-
parentContext: { type: `object`; object: Record<string, any>; key: string } | {
49-
type: `list`
50-
object: any[]
51-
key: number
52-
}
53-
value: Value
41+
parentContext:
42+
| null
43+
| {
44+
type: `object`
45+
object: Record<string, any>
46+
fieldName: string
47+
}
48+
| {
49+
type: `list`
50+
object: any[]
51+
index: number
52+
}
53+
value: Grafaid.SomeFieldData
5454
sddmNode: SchemaDrivenDataMap.OutputNodes
5555
documentPart: null | Grafaid.Document.SelectionSetNode
5656
scalars: Schema.Scalar.ScalarMap
@@ -65,7 +65,7 @@ const decodeResultValue = (input: {
6565
// todo test case of array data of scalars
6666
value.forEach((item, index) => {
6767
decodeResultValue({
68-
parentContext: { type: `list`, object: value, key: index },
68+
parentContext: { type: `list`, object: value, index },
6969
value: item,
7070
sddmNode,
7171
documentPart,
@@ -79,34 +79,41 @@ const decodeResultValue = (input: {
7979
// todo in strict mode throw error that sddmNode is inconsistent with data shape.
8080
}
8181
const object = value
82-
for (const [key, value] of Object.entries(object)) {
83-
const documentField = findDocumentField(documentPart, key)
84-
const kSchema = documentField?.name.value ?? key
82+
for (const [fieldName, value] of Object.entries(object)) {
83+
// TODO optimize field lookup
84+
// We need a smart algorithm that considers:
85+
// key space of schema vs key space of data
86+
const documentField = findDocumentField(documentPart, fieldName)
87+
const kSchema = documentField?.name.value ?? fieldName
8588
const sddmOutputField = sddmNode.f[kSchema]
8689
if (!sddmOutputField?.nt) continue
8790
decodeResultValue({
88-
parentContext: { type: `object`, object, key },
91+
parentContext: { type: `object`, object, fieldName },
8992
value,
9093
sddmNode: sddmOutputField.nt,
9194
documentPart: documentField?.selectionSet ?? null,
9295
scalars,
9396
})
9497
}
9598
} else {
99+
if (!parentContext) {
100+
// Should be impossible. Strict mode could error here.
101+
return
102+
}
96103
if (SchemaDrivenDataMap.isScalar(sddmNode)) {
97104
const decodedValue = Schema.Scalar.applyCodec(sddmNode.codec.decode, value)
98105
if (parentContext.type === `object`) {
99-
parentContext.object[parentContext.key] = decodedValue
106+
parentContext.object[parentContext.fieldName] = decodedValue
100107
} else {
101-
parentContext.object[parentContext.key] = decodedValue
108+
parentContext.object[parentContext.index] = decodedValue
102109
}
103110
} else if (SchemaDrivenDataMap.isCustomScalarName(sddmNode)) {
104111
const scalar = Schema.Scalar.lookupCustomScalarOrFallbackToString(scalars, sddmNode)
105112
const decodedValue = Schema.Scalar.applyCodec(scalar.codec.decode, value)
106113
if (parentContext.type === `object`) {
107-
parentContext.object[parentContext.key] = decodedValue
114+
parentContext.object[parentContext.fieldName] = decodedValue
108115
} else {
109-
parentContext.object[parentContext.key] = decodedValue
116+
parentContext.object[parentContext.index] = decodedValue
110117
}
111118
} else {
112119
// enums not decoded.
@@ -116,23 +123,19 @@ const decodeResultValue = (input: {
116123

117124
const findDocumentField = (
118125
selectionSet: null | Grafaid.Document.SelectionSetNode,
119-
k: string,
126+
fieldName: string,
120127
): Grafaid.Document.FieldNode | null => {
121128
if (!selectionSet) return null
122129

123130
for (const selection of selectionSet.selections) {
124-
if (selection.kind === Kind.FIELD && (selection.alias?.value ?? selection.name.value) === k) {
131+
if (selection.kind === Kind.FIELD && (selection.alias?.value ?? selection.name.value) === fieldName) {
125132
return selection
126133
}
127134
if (selection.kind === Kind.INLINE_FRAGMENT) {
128-
const result = findDocumentField(selection.selectionSet, k)
135+
const result = findDocumentField(selection.selectionSet, fieldName)
129136
if (result !== null) return result
130137
}
131138
}
132139

133140
return null
134141
}
135-
136-
type Value = Grafaid.Schema.StandardScalarRuntimeTypes[] | Grafaid.Schema.StandardScalarRuntimeTypes | null | {
137-
[k: string]: Value
138-
}

src/lib/grafaid/request.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,17 @@ export type Variables = {
3131
[key: string]: string | boolean | null | number | Variables
3232
}
3333

34-
export type SomeObjectData = Record<string, any>
35-
export type SomeFieldData = SomeObjectData | Grafaid.Schema.StandardScalarRuntimeTypes
34+
export type SomeObjectData = {
35+
[fieldName: string]: any // SomeFieldData <-- If we put this here tsc has crashes with OOM.
36+
}
37+
38+
export type SomeFieldData =
39+
| null
40+
| Grafaid.Schema.StandardScalarRuntimeTypes
41+
| Grafaid.Schema.StandardScalarRuntimeTypes[]
42+
| {
43+
[fieldName: string]: SomeFieldData
44+
}
3645

3746
export type GraphQLExecutionResultError = Errors.ContextualAggregateError<GraphQLError>
3847

website/content/guides/20_getting-started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Getting Started
44

55
# Getting Started
66

7-
This short guide will shepherd you through an example beginning from basic usage an then demonstrating use of the optional document builder. Node is used but Deno and Bun users should be able to follow along as well.
7+
This short guide will take you from basic usage to use of the optional document builder. Node is used but Deno and Bun users should be able to follow along as well.
88

99
## 🏡 Setup Your Project
1010

@@ -24,7 +24,7 @@ pnpm add --development typescript tsx @tsconfig/strictest
2424
```
2525

2626
```sh
27-
touch tsconfig.json
27+
touch tsconfig.json main.ts
2828
```
2929

3030
```json tsconfig.json

0 commit comments

Comments
 (0)