@graphcommerce/graphql 3.4.5 → 3.4.8
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 +23 -0
- package/measurePerformanceLink.ts +144 -38
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 3.4.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1622](https://github.com/graphcommerce-org/graphcommerce/pull/1622) [`396b5de5d`](https://github.com/graphcommerce-org/graphcommerce/commit/396b5de5d50c7b8f59bf636807e7a4b50f14e0b2) Thanks [@paales](https://github.com/paales)! - Make sure the measurePerformanceLink only gets included on the server and flush the current timings.
|
|
8
|
+
|
|
9
|
+
## 3.4.7
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`860b4afc0`](https://github.com/graphcommerce-org/graphcommerce/commit/860b4afc0a2f79b1e660a5f9ce204532ce4fca47)]:
|
|
14
|
+
- @graphcommerce/graphql-codegen-near-operation-file@3.0.18
|
|
15
|
+
|
|
16
|
+
## 3.4.6
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- [#1598](https://github.com/graphcommerce-org/graphcommerce/pull/1598) [`707dbc73d`](https://github.com/graphcommerce-org/graphcommerce/commit/707dbc73d181204d88fdbbd2e09340e25b2b5f7b) Thanks [@paales](https://github.com/paales)! - Upgraded dependencies
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`707dbc73d`](https://github.com/graphcommerce-org/graphcommerce/commit/707dbc73d181204d88fdbbd2e09340e25b2b5f7b)]:
|
|
23
|
+
- @graphcommerce/graphql-codegen-near-operation-file@3.0.17
|
|
24
|
+
- @graphcommerce/graphql-codegen-relay-optimizer-plugin@3.0.10
|
|
25
|
+
|
|
3
26
|
## 3.4.5
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { ApolloLink } from '@apollo/client'
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const running = new Map<
|
|
5
|
+
string,
|
|
6
|
+
{ start: Date; end?: Date; internalStart?: Date; operationName: string }
|
|
7
|
+
>()
|
|
6
8
|
|
|
7
9
|
interface TracingFormat {
|
|
8
10
|
version: 1
|
|
@@ -21,46 +23,150 @@ interface TracingFormat {
|
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
const renderLine = (line: {
|
|
27
|
+
serverStart: number
|
|
28
|
+
requestStart: number
|
|
29
|
+
requestEnd: number
|
|
30
|
+
colDivider: number
|
|
31
|
+
additional: string[]
|
|
32
|
+
}) => {
|
|
33
|
+
const duration = line.requestEnd - line.requestStart
|
|
34
|
+
const serverDuration = duration - line.serverStart
|
|
35
|
+
const waitTime = duration - serverDuration
|
|
36
|
+
|
|
37
|
+
const reqStart = Math.floor(line.requestStart / line.colDivider)
|
|
38
|
+
const startSpacing = reqStart >= 1 ? ' '.repeat(reqStart) : ''
|
|
39
|
+
|
|
40
|
+
const waitDotsRound = Math.floor(waitTime / line.colDivider - 1)
|
|
41
|
+
const waitDots = waitDotsRound >= 1 ? `${'╌'.repeat(waitDotsRound)}` : ''
|
|
42
|
+
|
|
43
|
+
const dashrepeat = Math.floor(serverDuration / line.colDivider)
|
|
44
|
+
|
|
45
|
+
const dashes =
|
|
46
|
+
dashrepeat >= 1 ? `${waitDotsRound > 1 ? '┼' : ''}${'─'.repeat(dashrepeat - 1)}` : ''
|
|
47
|
+
const result = `${startSpacing}├${waitDots}${dashes}┤`
|
|
48
|
+
|
|
49
|
+
return ['', ...line.additional, result]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const flushMeasurePerf = () => {
|
|
53
|
+
const entries = Array.from(running.entries())
|
|
54
|
+
if (entries.length === 0 || !entries.every(([k, v]) => v.end)) return
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Print to the console a timeline that gives a visual reprentation of the starting time and
|
|
58
|
+
* duration of each operation like so;
|
|
59
|
+
*
|
|
60
|
+
* ╞═════════ QueryOne (250ms) ═════════╡ ╞══════════════════ Query Two (450ms)
|
|
61
|
+
* ══════════════════╡ ╞═════════ QueryThree ═════════╡
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
let start = Number.MAX_VALUE
|
|
65
|
+
let end = 0
|
|
66
|
+
entries.forEach(([_, value]) => {
|
|
67
|
+
if (value.start.getTime() < start) start = value.start.getTime()
|
|
68
|
+
if (value.end && value.end.getTime() > end) end = value.end.getTime()
|
|
69
|
+
})
|
|
70
|
+
end -= start
|
|
71
|
+
|
|
72
|
+
const colDivider = Math.max(Math.floor(end / 150), 20)
|
|
73
|
+
|
|
74
|
+
const lines = entries.map(([_, value]) => {
|
|
75
|
+
const requestStart = value.start.getTime() - start
|
|
76
|
+
const requestEnd = value.end ? value.end.getTime() - start : 0
|
|
77
|
+
const duration = requestEnd - requestStart
|
|
78
|
+
|
|
79
|
+
const serverStart = value.internalStart
|
|
80
|
+
? value.internalStart.getTime() - value.start.getTime()
|
|
81
|
+
: 0
|
|
82
|
+
|
|
83
|
+
return renderLine({
|
|
84
|
+
serverStart,
|
|
85
|
+
requestStart,
|
|
86
|
+
requestEnd,
|
|
87
|
+
additional: [
|
|
88
|
+
value.operationName,
|
|
89
|
+
`${duration - (duration - serverStart)}ms`,
|
|
90
|
+
`${duration - serverStart}ms`,
|
|
91
|
+
],
|
|
92
|
+
colDivider,
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
const items = [
|
|
97
|
+
['', 'GraphQL requests', 'Bootup', 'Mesh', 'Waterfall'],
|
|
98
|
+
['', '', '', '', ''],
|
|
99
|
+
...lines,
|
|
100
|
+
renderLine({
|
|
101
|
+
serverStart: 0,
|
|
102
|
+
requestStart: 0,
|
|
103
|
+
requestEnd: end,
|
|
104
|
+
additional: [`Total time`, '', `${end}ms`],
|
|
105
|
+
colDivider,
|
|
106
|
+
}),
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
// Rewrite the above so it can handle abritraty columns
|
|
110
|
+
const colWidths: number[] = Array(items[0].length).fill(0)
|
|
111
|
+
items.forEach((item) => {
|
|
112
|
+
item.forEach((t, index) => {
|
|
113
|
+
colWidths[index] = Math.max(colWidths[index], t.length)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
// padd the items to the max length
|
|
118
|
+
items.forEach((item) => {
|
|
119
|
+
item.forEach((_, index) => {
|
|
120
|
+
item[index] = `${item[index].padEnd(colWidths[index], ' ')}${
|
|
121
|
+
index !== item.length - 1 ? ` │ ` : ''
|
|
122
|
+
}`
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
// render the items to a string
|
|
127
|
+
const output = [[''], ...items].map((item) => item.join(' ')).join('\n')
|
|
128
|
+
console.log(output)
|
|
129
|
+
|
|
130
|
+
running.clear()
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let timeout: NodeJS.Timeout | undefined
|
|
134
|
+
const markTimeout = () => {
|
|
135
|
+
if (timeout) clearTimeout(timeout)
|
|
136
|
+
timeout = setTimeout(flushMeasurePerf, 1000)
|
|
137
|
+
}
|
|
138
|
+
|
|
24
139
|
/**
|
|
25
140
|
* This doesn't work with the current implementation of the Apollo client. We're using SchemaLink
|
|
26
141
|
* which doesn't support additional links.
|
|
27
142
|
*/
|
|
28
143
|
export const measurePerformanceLink = new ApolloLink((operation, forward) => {
|
|
29
|
-
if (typeof
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
operation.setContext({ measurePerformanceLinkStart: new Date().valueOf() })
|
|
34
|
-
return forward(operation).map((data) => {
|
|
35
|
-
// Called after server responds
|
|
36
|
-
const time: number =
|
|
37
|
-
new Date().valueOf() - (operation.getContext().measurePerformanceLinkStart as number)
|
|
38
|
-
let vars =
|
|
144
|
+
if (typeof window === 'undefined') {
|
|
145
|
+
// Called before operation is sent to server
|
|
146
|
+
operation.setContext({ measurePerformanceLinkStart: new Date() })
|
|
147
|
+
const vars =
|
|
39
148
|
Object.keys(operation.variables).length > 0 ? `(${JSON.stringify(operation.variables)})` : ''
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return data
|
|
65
|
-
})
|
|
149
|
+
const operationString = `${operation.operationName}${vars}`
|
|
150
|
+
|
|
151
|
+
running.set(operationString, { start: new Date(), operationName: operation.operationName })
|
|
152
|
+
markTimeout()
|
|
153
|
+
|
|
154
|
+
// console.info(`GraphQL start ${operationString}`)
|
|
155
|
+
return forward(operation).map((data) => {
|
|
156
|
+
const tracing = data.extensions?.tracing as TracingFormat | undefined
|
|
157
|
+
|
|
158
|
+
// Called after server responds
|
|
159
|
+
running.set(operationString, {
|
|
160
|
+
internalStart: tracing ? new Date(tracing.startTime) : undefined,
|
|
161
|
+
start: operation.getContext().measurePerformanceLinkStart as Date,
|
|
162
|
+
end: new Date(),
|
|
163
|
+
operationName: operation.operationName,
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
markTimeout()
|
|
167
|
+
|
|
168
|
+
return data
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
return forward(operation)
|
|
66
172
|
})
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/graphql",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "3.4.
|
|
5
|
+
"version": "3.4.8",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"main": "index.ts",
|
|
8
8
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
@@ -13,24 +13,24 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
|
-
"@graphcommerce/eslint-config-pwa": "^4.1.
|
|
16
|
+
"@graphcommerce/eslint-config-pwa": "^4.1.10",
|
|
17
17
|
"@graphcommerce/prettier-config-pwa": "^4.0.6",
|
|
18
18
|
"@graphcommerce/typescript-config-pwa": "^4.0.4",
|
|
19
19
|
"@playwright/test": "^1.21.1"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@apollo/client": "^3.6.9",
|
|
23
|
-
"@graphcommerce/graphql-codegen-near-operation-file": "3.0.
|
|
24
|
-
"@graphcommerce/graphql-codegen-relay-optimizer-plugin": "3.0.
|
|
25
|
-
"@graphql-codegen/add": "3.2.
|
|
26
|
-
"@graphql-codegen/fragment-matcher": "3.3.
|
|
27
|
-
"@graphql-codegen/introspection": "2.2.
|
|
28
|
-
"@graphql-codegen/schema-ast": "2.5.
|
|
29
|
-
"@graphql-codegen/typed-document-node": "2.3.
|
|
30
|
-
"@graphql-codegen/typescript": "2.7.
|
|
31
|
-
"@graphql-codegen/typescript-apollo-client-helpers": "2.2.
|
|
32
|
-
"@graphql-codegen/typescript-document-nodes": "2.3.
|
|
33
|
-
"@graphql-codegen/typescript-operations": "2.5.
|
|
23
|
+
"@graphcommerce/graphql-codegen-near-operation-file": "3.0.18",
|
|
24
|
+
"@graphcommerce/graphql-codegen-relay-optimizer-plugin": "3.0.10",
|
|
25
|
+
"@graphql-codegen/add": "3.2.1",
|
|
26
|
+
"@graphql-codegen/fragment-matcher": "3.3.1",
|
|
27
|
+
"@graphql-codegen/introspection": "2.2.1",
|
|
28
|
+
"@graphql-codegen/schema-ast": "2.5.1",
|
|
29
|
+
"@graphql-codegen/typed-document-node": "2.3.3",
|
|
30
|
+
"@graphql-codegen/typescript": "2.7.3",
|
|
31
|
+
"@graphql-codegen/typescript-apollo-client-helpers": "2.2.3",
|
|
32
|
+
"@graphql-codegen/typescript-document-nodes": "2.3.3",
|
|
33
|
+
"@graphql-codegen/typescript-operations": "2.5.3",
|
|
34
34
|
"apollo3-cache-persist": "^0.14.1",
|
|
35
35
|
"graphql": "16.5.0"
|
|
36
36
|
},
|