@mindful-web/marko-web-identity-x 1.80.1 → 1.80.3

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/CLAUDE.md CHANGED
@@ -94,7 +94,21 @@ segment — a trace is the only place a call still *in flight* when its transact
94
94
  record. Same treatment on the Omeda client in `marko-web-omeda/middleware/graphql-client.js`
95
95
  (20s, `OMEDA_REQUEST_TIMEOUT_MS`), which had the identical no-timeout defect and sits on the blocking
96
96
  path of authentication. To compare upstreams:
97
- `SELECT count(*), average(ms), percentile(ms, 95), max(ms) FROM MindfulApiCall FACET api, operation, outcome`.
97
+ `SELECT sum(sampleRate) FROM MindfulApiCall FACET api, operation`.
98
+
99
+ **`MindfulApiCall` is sampled.** Unsampled it ran ~55k events/hour / ~40M per month on the Fusable
100
+ fleet, 88.9% of it `GetActiveAppContext` + `CheckContentAccess` — per-page-load context calls that
101
+ are uniformly fast and analytically useless. Kept: **every non-`ok` outcome**, **every `ok` call
102
+ >= `MINDFUL_API_CALL_SLOW_MS`** (default 250ms — deliberately under Omeda's observed p95 of 282ms, so
103
+ ordinary Omeda latency stays visible while fast idx calls fall away), and **1 in
104
+ `MINDFUL_API_CALL_SAMPLE_RATE`** (default 100) of the rest. Each event carries `sampleRate` = the
105
+ number of real calls it represents, so `sum(sampleRate)` recovers true volume; `sampleRate = 1` means
106
+ the call was kept because it failed or was slow.
107
+
108
+ Consequences when querying: `average(ms)` over everything **skews high** (fast calls are
109
+ under-represented by design) — filter `WHERE sampleRate = 1` for the error/slow tail, or
110
+ `WHERE sampleRate > 1` for a fast-call view. Set `MINDFUL_API_CALL_SAMPLE_RATE=1` to record
111
+ everything again during an investigation, no deploy required.
98
112
 
99
113
  It wraps `client.query`/`client.mutate`, **not** `fetch` — `@parameter1/omeda-graphql-client` sets
100
114
  `fetch` *after* spreading the caller's `linkConfig`, so a wrapped transport cannot be injected from
@@ -170,9 +184,26 @@ simply cannot authorize this mutation, and the fix is to stop using it — backf
170
184
  via `setUnverifiedAppUserData` (org-token, but writes *unverified* data, so it is a semantic change
171
185
  worth deciding deliberately).
172
186
 
173
- `idxGoogleStepMs` records elapsed ms at the start of each step, making the route self-profiling:
174
- `FACET idxGoogleStep SELECT max(idxGoogleStepMs)` shows where the ~12s on a *successful* sign-in
175
- goes, and a request that dies mid-flight still reports how far it got. Responds `{ ok, requiresUserInput,
187
+ **Timing comes in two parts, deliberately.** `idxGoogleStepMs` is elapsed-at-last-step and
188
+ **last-write-wins** — on a completed request it is effectively total route time, and on one that dies
189
+ mid-flight it says how far in it got. It cannot attribute time to a step: every `setStep` overwrites
190
+ it, which is why the per-step breakdown it was originally meant to provide never actually survived
191
+ (confirmed in production — the query returned one value per transaction, not a profile).
192
+
193
+ `idxMs<Step>` is the real breakdown: one attribute per step (`idxMsVerifyCredential`,
194
+ `idxMsImpersonateAppUser`, `idxMsHooksLoginLinkSent`, `idxMsHooksAuthenticationSuccess`, …), each
195
+ holding how long **that step** took, emitted when the next step begins. `complete` has no duration of
196
+ its own — it is a marker, not work. The durations sum to `idxGoogleStepMs`. About ten attributes, well
197
+ inside New Relic's per-transaction budget.
198
+
199
+ ```
200
+ SELECT average(idxMsHooksAuthenticationSuccess), average(idxMsImpersonateAppUser),
201
+ average(idxMsHooksLoginLinkSent), average(idxGoogleStepMs)
202
+ FROM Transaction WHERE name LIKE '%__idx/google%'
203
+ ```
204
+
205
+ Both hook steps sit on the blocking path and Omeda shows a ~4s tail, so this is what says whether
206
+ they own the remaining latency. Responds `{ ok, requiresUserInput,
176
207
  redirectTo, user, entity, additionalEventData, … }`; the client redirects to `/user/profile` when
177
208
  input is required.
178
209
 
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/access.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/access.marko",
6
6
  marko_component = require("./access.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -53,7 +53,7 @@ marko_template._ = marko_renderer(render, {
53
53
  }, marko_component);
54
54
 
55
55
  marko_template.meta = {
56
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/access.marko",
56
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/access.marko",
57
57
  component: "./access.marko",
58
58
  tags: [
59
59
  "@mindful-web/marko-core/components/resolve.marko"
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/comment-stream.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/comment-stream.marko",
6
6
  marko_component = require("./comment-stream.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -91,7 +91,7 @@ marko_template._ = marko_renderer(render, {
91
91
  }, marko_component);
92
92
 
93
93
  marko_template.meta = {
94
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/comment-stream.marko",
94
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/comment-stream.marko",
95
95
  component: "./comment-stream.marko",
96
96
  tags: [
97
97
  "@mindful-web/marko-web/components/browser-component.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/context.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/context.marko",
6
6
  marko_component = require("./context.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  marko_dynamicTag = require("marko/dist/runtime/helpers/dynamic-tag"),
@@ -49,7 +49,7 @@ marko_template._ = marko_renderer(render, {
49
49
  }, marko_component);
50
50
 
51
51
  marko_template.meta = {
52
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/context.marko",
52
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/context.marko",
53
53
  component: "./context.marko",
54
54
  tags: [
55
55
  "@mindful-web/marko-core/components/resolve.marko"
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-access.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-access.marko",
6
6
  marko_component = require("./form-access.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_defaultValue = require("@mindful-web/marko-core/utils/default-value"),
@@ -179,7 +179,7 @@ marko_template._ = marko_renderer(render, {
179
179
  }, marko_component);
180
180
 
181
181
  marko_template.meta = {
182
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-access.marko",
182
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-access.marko",
183
183
  component: "./form-access.marko",
184
184
  tags: [
185
185
  "@mindful-web/marko-web/components/browser-component.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-authenticate.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-authenticate.marko",
6
6
  marko_component = require("./form-authenticate.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -81,7 +81,7 @@ marko_template._ = marko_renderer(render, {
81
81
  }, marko_component);
82
82
 
83
83
  marko_template.meta = {
84
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-authenticate.marko",
84
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-authenticate.marko",
85
85
  component: "./form-authenticate.marko",
86
86
  tags: [
87
87
  "@mindful-web/marko-web/components/browser-component.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-change-email.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-change-email.marko",
6
6
  marko_component = require("./form-change-email.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -59,7 +59,7 @@ marko_template._ = marko_renderer(render, {
59
59
  }, marko_component);
60
60
 
61
61
  marko_template.meta = {
62
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-change-email.marko",
62
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-change-email.marko",
63
63
  component: "./form-change-email.marko",
64
64
  tags: [
65
65
  "@mindful-web/marko-web/components/browser-component.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-login.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-login.marko",
6
6
  marko_component = require("./form-login.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -92,7 +92,7 @@ marko_template._ = marko_renderer(render, {
92
92
  }, marko_component);
93
93
 
94
94
  marko_template.meta = {
95
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-login.marko",
95
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-login.marko",
96
96
  component: "./form-login.marko",
97
97
  tags: [
98
98
  "@mindful-web/marko-web/components/browser-component.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-logout.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-logout.marko",
6
6
  marko_renderer = require("marko/dist/runtime/components/renderer"),
7
7
  module_defaultValue = require("@mindful-web/marko-core/utils/default-value"),
8
8
  defaultValue = module_defaultValue.default || module_defaultValue,
@@ -29,7 +29,7 @@ marko_template._ = marko_renderer(render, {
29
29
  });
30
30
 
31
31
  marko_template.meta = {
32
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-logout.marko",
32
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-logout.marko",
33
33
  tags: [
34
34
  "@mindful-web/marko-web/components/browser-component.marko"
35
35
  ]
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-profile.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-profile.marko",
6
6
  marko_component = require("./form-profile.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -84,7 +84,7 @@ marko_template._ = marko_renderer(render, {
84
84
  }, marko_component);
85
85
 
86
86
  marko_template.meta = {
87
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-profile.marko",
87
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-profile.marko",
88
88
  component: "./form-profile.marko",
89
89
  tags: [
90
90
  "@mindful-web/marko-web/components/browser-component.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/form-register.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/form-register.marko",
6
6
  marko_renderer = require("marko/dist/runtime/components/renderer"),
7
7
  marko_assign = require("marko/dist/runtime/helpers/assign"),
8
8
  marko_web_identity_x_form_login_template = require("./form-login.marko"),
@@ -25,7 +25,7 @@ marko_template._ = marko_renderer(render, {
25
25
  });
26
26
 
27
27
  marko_template.meta = {
28
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/form-register.marko",
28
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/form-register.marko",
29
29
  tags: [
30
30
  "./form-login.marko"
31
31
  ]
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/google-init.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/google-init.marko",
6
6
  marko_renderer = require("marko/dist/runtime/components/renderer"),
7
7
  marko_attr = require("marko/dist/runtime/html/helpers/attr"),
8
8
  marko_str = require("marko/dist/runtime/helpers/to-string");
@@ -239,5 +239,5 @@ marko_template._ = marko_renderer(render, {
239
239
  });
240
240
 
241
241
  marko_template.meta = {
242
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/google-init.marko"
242
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/google-init.marko"
243
243
  };
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/google-sign-in-button.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/google-sign-in-button.marko",
6
6
  marko_renderer = require("marko/dist/runtime/components/renderer"),
7
7
  helpers_escape_xml = require("marko/dist/runtime/html/helpers/escape-xml"),
8
8
  marko_escapeXml = helpers_escape_xml.x,
@@ -40,5 +40,5 @@ marko_template._ = marko_renderer(render, {
40
40
  });
41
41
 
42
42
  marko_template.meta = {
43
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/google-sign-in-button.marko"
43
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/google-sign-in-button.marko"
44
44
  };
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/identify.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/identify.marko",
6
6
  marko_component = require("./identify.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -50,7 +50,7 @@ marko_template._ = marko_renderer(render, {
50
50
  }, marko_component);
51
51
 
52
52
  marko_template.meta = {
53
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/identify.marko",
53
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/identify.marko",
54
54
  component: "./identify.marko",
55
55
  tags: [
56
56
  "@mindful-web/marko-web-gtm/components/push.marko",
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/non-auth-identify.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/non-auth-identify.marko",
6
6
  marko_component = require("./non-auth-identify.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  marko_dynamicTag = require("marko/dist/runtime/helpers/dynamic-tag"),
@@ -45,7 +45,7 @@ marko_template._ = marko_renderer(render, {
45
45
  }, marko_component);
46
46
 
47
47
  marko_template.meta = {
48
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/non-auth-identify.marko",
48
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/non-auth-identify.marko",
49
49
  component: "./non-auth-identify.marko",
50
50
  tags: [
51
51
  "@mindful-web/marko-core/components/resolve.marko"
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var marko_template = module.exports = require("marko/dist/html").t(__filename),
5
- marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.1/components/subscribe.marko",
5
+ marko_componentType = "/@mindful-web/marko-web-identity-x$1.80.3/components/subscribe.marko",
6
6
  marko_component = require("./subscribe.marko"),
7
7
  marko_renderer = require("marko/dist/runtime/components/renderer"),
8
8
  module_objectPath_module = require("@mindful-web/object-path"),
@@ -73,7 +73,7 @@ marko_template._ = marko_renderer(render, {
73
73
  }, marko_component);
74
74
 
75
75
  marko_template.meta = {
76
- id: "/@mindful-web/marko-web-identity-x$1.80.1/components/subscribe.marko",
76
+ id: "/@mindful-web/marko-web-identity-x$1.80.3/components/subscribe.marko",
77
77
  component: "./subscribe.marko",
78
78
  tags: [
79
79
  "@mindful-web/marko-web/components/browser-component.marko",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindful-web/marko-web-identity-x",
3
- "version": "1.80.1",
3
+ "version": "1.80.3",
4
4
  "description": "Marko Wrapper for IdentityX",
5
5
  "repository": "https://github.com/parameter1/mindful-web/tree/main/packages/marko-web-identity-x",
6
6
  "author": "Josh Worden <josh@parameter1.com>",
@@ -13,9 +13,9 @@
13
13
  "test": "yarn compile --no-clean && yarn lint"
14
14
  },
15
15
  "dependencies": {
16
- "@mindful-web/marko-web-gtm": "^1.80.0",
17
- "@mindful-web/object-path": "^1.80.0",
18
- "@mindful-web/utils": "^1.80.0",
16
+ "@mindful-web/marko-web-gtm": "^1.80.2",
17
+ "@mindful-web/object-path": "^1.80.2",
18
+ "@mindful-web/utils": "^1.80.2",
19
19
  "apollo-cache-inmemory": "^1.6.6",
20
20
  "apollo-client": "^2.6.10",
21
21
  "apollo-link-context": "^1.0.20",
@@ -38,5 +38,5 @@
38
38
  "publishConfig": {
39
39
  "access": "public"
40
40
  },
41
- "gitHead": "956e3462d636f6e7785c1e82b99d66b4c410e9df"
41
+ "gitHead": "02de6be94c16fd962d5c94b37b9f09a151142f48"
42
42
  }
package/routes/google.js CHANGED
@@ -105,18 +105,44 @@ module.exports = asyncRoute(async (req, res) => {
105
105
  // the request dies is the step that failed, so an error arrives already
106
106
  // localized instead of being a bare GraphQL message to reverse-engineer.
107
107
  //
108
- // `idxGoogleStepMs` is the elapsed time when each step *began*, which makes the
109
- // route self-profiling: `FACET idxGoogleStep` with `max(idxGoogleStepMs)` shows
110
- // where the time goes, and a request that dies mid-flight still reports how far
111
- // it got and when. Sign-ins here average ~12s even when they succeed, and
112
- // without this there is no way to tell which of the ~10 sequential upstream
113
- // calls owns that.
108
+ // Timing comes in two parts, because they answer different questions.
109
+ //
110
+ // `idxGoogleStepMs` is elapsed-at-last-step: last-write-wins, so on a completed
111
+ // request it is effectively total route time, and on one that dies mid-flight it
112
+ // says how far in it got. Useful, but it cannot attribute time to a *step* —
113
+ // every `setStep` overwrites the previous value, so the breakdown it was
114
+ // originally meant to provide never survived.
115
+ //
116
+ // `idxMs<Step>` fixes that: one attribute per step, holding how long that step
117
+ // took. Emitted when the *next* step starts, since that is when the previous
118
+ // one is known to be over. `complete` therefore has no duration of its own,
119
+ // which is correct — it is a marker, not work. Roughly ten attributes, well
120
+ // inside New Relic's per-transaction custom attribute budget.
121
+ //
122
+ // SELECT average(idxMsHooksAuthenticationSuccess), average(idxMsImpersonateAppUser),
123
+ // average(idxMsHooksLoginLinkSent)
124
+ // FROM Transaction WHERE name LIKE '%__idx/google%'
125
+ //
126
+ // With Omeda calls showing a ~4s tail and both hook steps sitting on the
127
+ // blocking path, this is what says whether they own the remaining latency.
114
128
  const startedAt = Date.now();
115
129
  const addAttrs = config.get('addRequestAttributes') || (() => {});
116
- const setStep = (step) => addAttrs({
117
- idxGoogleStep: step,
118
- idxGoogleStepMs: Date.now() - startedAt,
119
- });
130
+
131
+ // 'hooks-login-link-sent' -> 'idxMsHooksLoginLinkSent'
132
+ const attrNameForStep = (step) => `idxMs${step.split('-').map((part) => (
133
+ part.charAt(0).toUpperCase() + part.slice(1)
134
+ )).join('')}`;
135
+
136
+ let currentStep;
137
+ let currentStepStartedAt = startedAt;
138
+ const setStep = (step) => {
139
+ const now = Date.now();
140
+ // Close out the step being left, not the one being entered.
141
+ if (currentStep) addAttrs({ [attrNameForStep(currentStep)]: now - currentStepStartedAt });
142
+ currentStep = step;
143
+ currentStepStartedAt = now;
144
+ addAttrs({ idxGoogleStep: step, idxGoogleStepMs: now - startedAt });
145
+ };
120
146
 
121
147
  const { clientId, missingFieldsBehavior = 'profile-gate' } = config.getAsObject('googleAuth');
122
148
  // `surface` is the GIS `select_by` bucket ('button' | 'prompt'), sent by the