@atlaskit/editor-plugin-autocomplete 3.4.0 → 3.5.0

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,26 @@
1
1
  # @atlaskit/editor-plugin-autocomplete
2
2
 
3
+ ## 3.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`52c7f5f973025`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/52c7f5f973025) -
8
+ Switch the CTC autocomplete debug toggle off `localStorage` and onto a storage-free mechanism.
9
+ Debug logging is now enabled via the `__atlCtcDebug__.enable()` / `.disable()` console API for the
10
+ current session, or by appending `?atlCtcDebug=1` to the URL to have it active from initial load
11
+ (and survive reloads). This avoids browser-storage consent controls (BSC) that can block
12
+ uncategorized `localStorage` writes in some products. The `isAutocompleteDebugEnabled()` API is
13
+ unchanged for callers.
14
+
15
+ ## 3.4.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [`4129a00a1ae04`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4129a00a1ae04) -
20
+ Add `completionSource` attribute to contextual typeahead analytics events to distinguish between
21
+ cold (frequency-only), server slow-lane, and on-device local LLM scoring paths
22
+ - Updated dependencies
23
+
3
24
  ## 3.4.0
4
25
 
5
26
  ### Minor Changes
@@ -223,6 +223,18 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
223
223
  var dismissedContext = null;
224
224
  var lastSuggestionTypedLength = 0;
225
225
  var lastSuggestionLength = 0;
226
+
227
+ /**
228
+ * cold → no slow-lane vector received yet; frequency-only trie scoring
229
+ * server → server slow-lane API returned the context vector
230
+ * localLlm → on-device WebGPU/MLC model returned the context vector
231
+ */
232
+ var getCompletionSource = function getCompletionSource() {
233
+ if (!slowLaneClient.getContextVector()) {
234
+ return 'cold';
235
+ }
236
+ return options !== null && options !== void 0 && options.useLocalModel ? 'localLlm' : 'server';
237
+ };
226
238
  var fireSuggestionDismissedAnalytics = function fireSuggestionDismissedAnalytics(reason) {
227
239
  var _api$analytics;
228
240
  api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
@@ -230,6 +242,7 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
230
242
  actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
231
243
  eventType: _analytics.EVENT_TYPE.TRACK,
232
244
  attributes: {
245
+ completionSource: getCompletionSource(),
233
246
  reason: reason
234
247
  }
235
248
  });
@@ -244,6 +257,7 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
244
257
  actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
245
258
  eventType: _analytics.EVENT_TYPE.TRACK,
246
259
  attributes: {
260
+ completionSource: getCompletionSource(),
247
261
  suggestionLength: suggestionLength,
248
262
  typedLength: typedLength,
249
263
  kssDelta: kssDelta
@@ -410,7 +424,10 @@ var createAutocompletePlugin = exports.createAutocompletePlugin = function creat
410
424
  api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
411
425
  action: _analytics.ACTION.SUGGESTION_VIEWED,
412
426
  actionSubject: _analytics.ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
413
- eventType: _analytics.EVENT_TYPE.TRACK
427
+ eventType: _analytics.EVENT_TYPE.TRACK,
428
+ attributes: {
429
+ completionSource: getCompletionSource()
430
+ }
414
431
  });
415
432
  }
416
433
  }
@@ -7,18 +7,59 @@ exports.isAutocompleteDebugEnabled = void 0;
7
7
  /**
8
8
  * Contextual Typeahead Completions (CTC) debug logging utility.
9
9
  *
10
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
10
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
11
11
  *
12
- * localStorage.setItem('atl-ctc-dbg', '1')
12
+ * // Live, for the current session (no reload required):
13
+ * __atlCtcDebug__.enable()
13
14
  *
14
- * Then reload the page. To disable:
15
+ * // To disable:
16
+ * __atlCtcDebug__.disable()
15
17
  *
16
- * localStorage.removeItem('atl-ctc-dbg')
18
+ * // From initial page load (survives reload) — append to the URL:
19
+ * ?atlCtcDebug=1
20
+ *
21
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
22
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
17
23
  */
18
- var isAutocompleteDebugEnabled = exports.isAutocompleteDebugEnabled = function isAutocompleteDebugEnabled() {
24
+
25
+ var hasUrlDebugFlag = function hasUrlDebugFlag() {
26
+ if (typeof window === 'undefined') {
27
+ return false;
28
+ }
19
29
  try {
20
- return typeof localStorage !== 'undefined' && localStorage.getItem('atl-ctc-dbg') === '1';
30
+ return new URLSearchParams(window.location.search).get('atlCtcDebug') === '1';
21
31
  } catch (_unused) {
22
32
  return false;
23
33
  }
24
- };
34
+ };
35
+
36
+ // State lives on the window object (not a module closure) so duplicate copies of this
37
+ // module across separate bundles/realms share one source of truth and the console API
38
+ // controls them all. In-memory only; persisted across reload via the URL flag.
39
+ var getDebugApi = function getDebugApi() {
40
+ if (typeof window === 'undefined') {
41
+ return undefined;
42
+ }
43
+ if (!window.__atlCtcDebug__) {
44
+ var debugEnabled = hasUrlDebugFlag();
45
+ window.__atlCtcDebug__ = {
46
+ enable: function enable() {
47
+ debugEnabled = true;
48
+ },
49
+ disable: function disable() {
50
+ debugEnabled = false;
51
+ },
52
+ isEnabled: function isEnabled() {
53
+ return debugEnabled;
54
+ }
55
+ };
56
+ }
57
+ return window.__atlCtcDebug__;
58
+ };
59
+ var isAutocompleteDebugEnabled = exports.isAutocompleteDebugEnabled = function isAutocompleteDebugEnabled() {
60
+ var _getDebugApi$isEnable, _getDebugApi;
61
+ return (_getDebugApi$isEnable = (_getDebugApi = getDebugApi()) === null || _getDebugApi === void 0 ? void 0 : _getDebugApi.isEnabled()) !== null && _getDebugApi$isEnable !== void 0 ? _getDebugApi$isEnable : false;
62
+ };
63
+
64
+ // Eagerly install so the console API is available on load, regardless of call order.
65
+ getDebugApi();
@@ -211,6 +211,18 @@ export const createAutocompletePlugin = (options, api) => {
211
211
  let dismissedContext = null;
212
212
  let lastSuggestionTypedLength = 0;
213
213
  let lastSuggestionLength = 0;
214
+
215
+ /**
216
+ * cold → no slow-lane vector received yet; frequency-only trie scoring
217
+ * server → server slow-lane API returned the context vector
218
+ * localLlm → on-device WebGPU/MLC model returned the context vector
219
+ */
220
+ const getCompletionSource = () => {
221
+ if (!slowLaneClient.getContextVector()) {
222
+ return 'cold';
223
+ }
224
+ return options !== null && options !== void 0 && options.useLocalModel ? 'localLlm' : 'server';
225
+ };
214
226
  const fireSuggestionDismissedAnalytics = reason => {
215
227
  var _api$analytics;
216
228
  api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent({
@@ -218,6 +230,7 @@ export const createAutocompletePlugin = (options, api) => {
218
230
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
219
231
  eventType: EVENT_TYPE.TRACK,
220
232
  attributes: {
233
+ completionSource: getCompletionSource(),
221
234
  reason
222
235
  }
223
236
  });
@@ -232,6 +245,7 @@ export const createAutocompletePlugin = (options, api) => {
232
245
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
233
246
  eventType: EVENT_TYPE.TRACK,
234
247
  attributes: {
248
+ completionSource: getCompletionSource(),
235
249
  suggestionLength,
236
250
  typedLength,
237
251
  kssDelta
@@ -392,7 +406,10 @@ export const createAutocompletePlugin = (options, api) => {
392
406
  api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions.fireAnalyticsEvent({
393
407
  action: ACTION.SUGGESTION_VIEWED,
394
408
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
395
- eventType: EVENT_TYPE.TRACK
409
+ eventType: EVENT_TYPE.TRACK,
410
+ attributes: {
411
+ completionSource: getCompletionSource()
412
+ }
396
413
  });
397
414
  }
398
415
  }
@@ -1,18 +1,57 @@
1
1
  /**
2
2
  * Contextual Typeahead Completions (CTC) debug logging utility.
3
3
  *
4
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
4
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
5
5
  *
6
- * localStorage.setItem('atl-ctc-dbg', '1')
6
+ * // Live, for the current session (no reload required):
7
+ * __atlCtcDebug__.enable()
7
8
  *
8
- * Then reload the page. To disable:
9
+ * // To disable:
10
+ * __atlCtcDebug__.disable()
9
11
  *
10
- * localStorage.removeItem('atl-ctc-dbg')
12
+ * // From initial page load (survives reload) — append to the URL:
13
+ * ?atlCtcDebug=1
14
+ *
15
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
16
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
11
17
  */
12
- export const isAutocompleteDebugEnabled = () => {
18
+
19
+ const hasUrlDebugFlag = () => {
20
+ if (typeof window === 'undefined') {
21
+ return false;
22
+ }
13
23
  try {
14
- return typeof localStorage !== 'undefined' && localStorage.getItem('atl-ctc-dbg') === '1';
24
+ return new URLSearchParams(window.location.search).get('atlCtcDebug') === '1';
15
25
  } catch {
16
26
  return false;
17
27
  }
18
- };
28
+ };
29
+
30
+ // State lives on the window object (not a module closure) so duplicate copies of this
31
+ // module across separate bundles/realms share one source of truth and the console API
32
+ // controls them all. In-memory only; persisted across reload via the URL flag.
33
+ const getDebugApi = () => {
34
+ if (typeof window === 'undefined') {
35
+ return undefined;
36
+ }
37
+ if (!window.__atlCtcDebug__) {
38
+ let debugEnabled = hasUrlDebugFlag();
39
+ window.__atlCtcDebug__ = {
40
+ enable: () => {
41
+ debugEnabled = true;
42
+ },
43
+ disable: () => {
44
+ debugEnabled = false;
45
+ },
46
+ isEnabled: () => debugEnabled
47
+ };
48
+ }
49
+ return window.__atlCtcDebug__;
50
+ };
51
+ export const isAutocompleteDebugEnabled = () => {
52
+ var _getDebugApi$isEnable, _getDebugApi;
53
+ return (_getDebugApi$isEnable = (_getDebugApi = getDebugApi()) === null || _getDebugApi === void 0 ? void 0 : _getDebugApi.isEnabled()) !== null && _getDebugApi$isEnable !== void 0 ? _getDebugApi$isEnable : false;
54
+ };
55
+
56
+ // Eagerly install so the console API is available on load, regardless of call order.
57
+ getDebugApi();
@@ -216,6 +216,18 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
216
216
  var dismissedContext = null;
217
217
  var lastSuggestionTypedLength = 0;
218
218
  var lastSuggestionLength = 0;
219
+
220
+ /**
221
+ * cold → no slow-lane vector received yet; frequency-only trie scoring
222
+ * server → server slow-lane API returned the context vector
223
+ * localLlm → on-device WebGPU/MLC model returned the context vector
224
+ */
225
+ var getCompletionSource = function getCompletionSource() {
226
+ if (!slowLaneClient.getContextVector()) {
227
+ return 'cold';
228
+ }
229
+ return options !== null && options !== void 0 && options.useLocalModel ? 'localLlm' : 'server';
230
+ };
219
231
  var fireSuggestionDismissedAnalytics = function fireSuggestionDismissedAnalytics(reason) {
220
232
  var _api$analytics;
221
233
  api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
@@ -223,6 +235,7 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
223
235
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
224
236
  eventType: EVENT_TYPE.TRACK,
225
237
  attributes: {
238
+ completionSource: getCompletionSource(),
226
239
  reason: reason
227
240
  }
228
241
  });
@@ -237,6 +250,7 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
237
250
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
238
251
  eventType: EVENT_TYPE.TRACK,
239
252
  attributes: {
253
+ completionSource: getCompletionSource(),
240
254
  suggestionLength: suggestionLength,
241
255
  typedLength: typedLength,
242
256
  kssDelta: kssDelta
@@ -403,7 +417,10 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
403
417
  api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
404
418
  action: ACTION.SUGGESTION_VIEWED,
405
419
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
406
- eventType: EVENT_TYPE.TRACK
420
+ eventType: EVENT_TYPE.TRACK,
421
+ attributes: {
422
+ completionSource: getCompletionSource()
423
+ }
407
424
  });
408
425
  }
409
426
  }
@@ -1,18 +1,59 @@
1
1
  /**
2
2
  * Contextual Typeahead Completions (CTC) debug logging utility.
3
3
  *
4
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
4
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
5
5
  *
6
- * localStorage.setItem('atl-ctc-dbg', '1')
6
+ * // Live, for the current session (no reload required):
7
+ * __atlCtcDebug__.enable()
7
8
  *
8
- * Then reload the page. To disable:
9
+ * // To disable:
10
+ * __atlCtcDebug__.disable()
9
11
  *
10
- * localStorage.removeItem('atl-ctc-dbg')
12
+ * // From initial page load (survives reload) — append to the URL:
13
+ * ?atlCtcDebug=1
14
+ *
15
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
16
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
11
17
  */
12
- export var isAutocompleteDebugEnabled = function isAutocompleteDebugEnabled() {
18
+
19
+ var hasUrlDebugFlag = function hasUrlDebugFlag() {
20
+ if (typeof window === 'undefined') {
21
+ return false;
22
+ }
13
23
  try {
14
- return typeof localStorage !== 'undefined' && localStorage.getItem('atl-ctc-dbg') === '1';
24
+ return new URLSearchParams(window.location.search).get('atlCtcDebug') === '1';
15
25
  } catch (_unused) {
16
26
  return false;
17
27
  }
18
- };
28
+ };
29
+
30
+ // State lives on the window object (not a module closure) so duplicate copies of this
31
+ // module across separate bundles/realms share one source of truth and the console API
32
+ // controls them all. In-memory only; persisted across reload via the URL flag.
33
+ var getDebugApi = function getDebugApi() {
34
+ if (typeof window === 'undefined') {
35
+ return undefined;
36
+ }
37
+ if (!window.__atlCtcDebug__) {
38
+ var debugEnabled = hasUrlDebugFlag();
39
+ window.__atlCtcDebug__ = {
40
+ enable: function enable() {
41
+ debugEnabled = true;
42
+ },
43
+ disable: function disable() {
44
+ debugEnabled = false;
45
+ },
46
+ isEnabled: function isEnabled() {
47
+ return debugEnabled;
48
+ }
49
+ };
50
+ }
51
+ return window.__atlCtcDebug__;
52
+ };
53
+ export var isAutocompleteDebugEnabled = function isAutocompleteDebugEnabled() {
54
+ var _getDebugApi$isEnable, _getDebugApi;
55
+ return (_getDebugApi$isEnable = (_getDebugApi = getDebugApi()) === null || _getDebugApi === void 0 ? void 0 : _getDebugApi.isEnabled()) !== null && _getDebugApi$isEnable !== void 0 ? _getDebugApi$isEnable : false;
56
+ };
57
+
58
+ // Eagerly install so the console API is available on load, regardless of call order.
59
+ getDebugApi();
@@ -1,12 +1,27 @@
1
1
  /**
2
2
  * Contextual Typeahead Completions (CTC) debug logging utility.
3
3
  *
4
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
4
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
5
5
  *
6
- * localStorage.setItem('atl-ctc-dbg', '1')
6
+ * // Live, for the current session (no reload required):
7
+ * __atlCtcDebug__.enable()
7
8
  *
8
- * Then reload the page. To disable:
9
+ * // To disable:
10
+ * __atlCtcDebug__.disable()
9
11
  *
10
- * localStorage.removeItem('atl-ctc-dbg')
12
+ * // From initial page load (survives reload) — append to the URL:
13
+ * ?atlCtcDebug=1
14
+ *
15
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
16
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
11
17
  */
18
+ declare global {
19
+ interface Window {
20
+ __atlCtcDebug__?: {
21
+ enable: () => void;
22
+ disable: () => void;
23
+ isEnabled: () => boolean;
24
+ };
25
+ }
26
+ }
12
27
  export declare const isAutocompleteDebugEnabled: () => boolean;
@@ -1,12 +1,27 @@
1
1
  /**
2
2
  * Contextual Typeahead Completions (CTC) debug logging utility.
3
3
  *
4
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
4
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
5
5
  *
6
- * localStorage.setItem('atl-ctc-dbg', '1')
6
+ * // Live, for the current session (no reload required):
7
+ * __atlCtcDebug__.enable()
7
8
  *
8
- * Then reload the page. To disable:
9
+ * // To disable:
10
+ * __atlCtcDebug__.disable()
9
11
  *
10
- * localStorage.removeItem('atl-ctc-dbg')
12
+ * // From initial page load (survives reload) — append to the URL:
13
+ * ?atlCtcDebug=1
14
+ *
15
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
16
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
11
17
  */
18
+ declare global {
19
+ interface Window {
20
+ __atlCtcDebug__?: {
21
+ enable: () => void;
22
+ disable: () => void;
23
+ isEnabled: () => boolean;
24
+ };
25
+ }
26
+ }
12
27
  export declare const isAutocompleteDebugEnabled: () => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-autocomplete",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "Client-side text autocomplete plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -35,7 +35,7 @@
35
35
  "wink-nlp": "^2.4.0"
36
36
  },
37
37
  "peerDependencies": {
38
- "@atlaskit/editor-common": "^115.7.0",
38
+ "@atlaskit/editor-common": "^115.8.0",
39
39
  "@atlaskit/editor-plugin-analytics": "^11.0.0",
40
40
  "react": "^18.2.0"
41
41
  },
@@ -277,12 +277,24 @@ export const createAutocompletePlugin = (
277
277
  let lastSuggestionTypedLength = 0;
278
278
  let lastSuggestionLength = 0;
279
279
 
280
+ /**
281
+ * cold → no slow-lane vector received yet; frequency-only trie scoring
282
+ * server → server slow-lane API returned the context vector
283
+ * localLlm → on-device WebGPU/MLC model returned the context vector
284
+ */
285
+ const getCompletionSource = (): 'cold' | 'server' | 'localLlm' => {
286
+ if (!slowLaneClient.getContextVector()) {
287
+ return 'cold';
288
+ }
289
+ return options?.useLocalModel ? 'localLlm' : 'server';
290
+ };
291
+
280
292
  const fireSuggestionDismissedAnalytics = (reason: 'escape' | 'blur'): void => {
281
293
  api?.analytics?.actions.fireAnalyticsEvent({
282
294
  action: ACTION.SUGGESTION_DISMISSED,
283
295
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
284
296
  eventType: EVENT_TYPE.TRACK,
285
- attributes: { reason },
297
+ attributes: { completionSource: getCompletionSource(), reason },
286
298
  });
287
299
  };
288
300
 
@@ -296,6 +308,7 @@ export const createAutocompletePlugin = (
296
308
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
297
309
  eventType: EVENT_TYPE.TRACK,
298
310
  attributes: {
311
+ completionSource: getCompletionSource(),
299
312
  suggestionLength,
300
313
  typedLength,
301
314
  kssDelta,
@@ -484,6 +497,7 @@ export const createAutocompletePlugin = (
484
497
  action: ACTION.SUGGESTION_VIEWED,
485
498
  actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
486
499
  eventType: EVENT_TYPE.TRACK,
500
+ attributes: { completionSource: getCompletionSource() },
487
501
  });
488
502
  }
489
503
  }
@@ -1,18 +1,65 @@
1
1
  /**
2
2
  * Contextual Typeahead Completions (CTC) debug logging utility.
3
3
  *
4
- * Logs are silent by default. To enable in any environment (dev, staging, prod):
4
+ * Logs are silent by default. Enable in any environment (dev, staging, prod):
5
5
  *
6
- * localStorage.setItem('atl-ctc-dbg', '1')
6
+ * // Live, for the current session (no reload required):
7
+ * __atlCtcDebug__.enable()
7
8
  *
8
- * Then reload the page. To disable:
9
+ * // To disable:
10
+ * __atlCtcDebug__.disable()
9
11
  *
10
- * localStorage.removeItem('atl-ctc-dbg')
12
+ * // From initial page load (survives reload) — append to the URL:
13
+ * ?atlCtcDebug=1
14
+ *
15
+ * Storage-free by design: avoids browser-storage consent controls (BSC), which can
16
+ * block uncategorized localStorage/sessionStorage/cookie writes in some products.
11
17
  */
12
- export const isAutocompleteDebugEnabled = (): boolean => {
18
+
19
+ declare global {
20
+ interface Window {
21
+ __atlCtcDebug__?: {
22
+ enable: () => void;
23
+ disable: () => void;
24
+ isEnabled: () => boolean;
25
+ };
26
+ }
27
+ }
28
+
29
+ const hasUrlDebugFlag = (): boolean => {
30
+ if (typeof window === 'undefined') {
31
+ return false;
32
+ }
13
33
  try {
14
- return typeof localStorage !== 'undefined' && localStorage.getItem('atl-ctc-dbg') === '1';
34
+ return new URLSearchParams(window.location.search).get('atlCtcDebug') === '1';
15
35
  } catch {
16
36
  return false;
17
37
  }
18
38
  };
39
+
40
+ // State lives on the window object (not a module closure) so duplicate copies of this
41
+ // module across separate bundles/realms share one source of truth and the console API
42
+ // controls them all. In-memory only; persisted across reload via the URL flag.
43
+ const getDebugApi = (): Window['__atlCtcDebug__'] => {
44
+ if (typeof window === 'undefined') {
45
+ return undefined;
46
+ }
47
+ if (!window.__atlCtcDebug__) {
48
+ let debugEnabled = hasUrlDebugFlag();
49
+ window.__atlCtcDebug__ = {
50
+ enable: () => {
51
+ debugEnabled = true;
52
+ },
53
+ disable: () => {
54
+ debugEnabled = false;
55
+ },
56
+ isEnabled: () => debugEnabled,
57
+ };
58
+ }
59
+ return window.__atlCtcDebug__;
60
+ };
61
+
62
+ export const isAutocompleteDebugEnabled = (): boolean => getDebugApi()?.isEnabled() ?? false;
63
+
64
+ // Eagerly install so the console API is available on load, regardless of call order.
65
+ getDebugApi();