@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 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 slowOperationThreshold = 1000
5
- const slowResolverThreshold = 300
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 global.window !== 'undefined') {
30
- return forward(operation)
31
- }
32
- // Called before operation is sent to server
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
- if (vars.length > 100) {
41
- vars = `${vars.substring(0, 100)}…`
42
- }
43
-
44
- if (data.extensions?.tracing && time > slowOperationThreshold) {
45
- const tracing = data.extensions?.tracing as TracingFormat
46
-
47
- const duration = Math.round(tracing.duration / (1000 * 1000))
48
-
49
- console.group(`GraphQL slow query/mutation '${operation.operationName}'${vars}`)
50
- console.info(`operations ${duration}ms, mesh: ${time - duration}ms`)
51
-
52
- tracing.execution.resolvers
53
- .filter((resolver) => resolver.duration > slowResolverThreshold * 1000 * 1000)
54
- .forEach((resolver) =>
55
- console.info(
56
- `${operation.operationName}.${resolver.path.join('.')}[${Math.round(
57
- resolver.duration / (1000 * 1000),
58
- )}ms]`,
59
- ),
60
- )
61
- console.groupEnd()
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",
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.9",
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.16",
24
- "@graphcommerce/graphql-codegen-relay-optimizer-plugin": "3.0.9",
25
- "@graphql-codegen/add": "3.2.0",
26
- "@graphql-codegen/fragment-matcher": "3.3.0",
27
- "@graphql-codegen/introspection": "2.2.0",
28
- "@graphql-codegen/schema-ast": "2.5.0",
29
- "@graphql-codegen/typed-document-node": "2.3.1",
30
- "@graphql-codegen/typescript": "2.7.1",
31
- "@graphql-codegen/typescript-apollo-client-helpers": "2.2.1",
32
- "@graphql-codegen/typescript-document-nodes": "2.3.1",
33
- "@graphql-codegen/typescript-operations": "2.5.1",
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
  },