@c15t/dev-tools 2.0.0-rc.6 → 2.0.0-rc.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/dist/379.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { subscribeToScriptDebugEvents } from "c15t";
1
2
  import { __webpack_require__ } from "./0~rslib-runtime.js";
2
3
  __webpack_require__.add({
3
4
  "../../node_modules/.bun/@rsbuild+core@2.0.0-beta.11+490411ac90707e06/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].oneOf[2].use[2]!./src/styles/animations.module.css" (module, __webpack_exports__, __webpack_require__) {
@@ -2293,7 +2294,7 @@ function getPreferenceCenterOpener(namespace = 'c15tStore') {
2293
2294
  }
2294
2295
  return null;
2295
2296
  }
2296
- const version = '2.0.0-rc.6';
2297
+ const version = '2.0.0-rc.8';
2297
2298
  const DEVTOOLS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446 445" aria-label="c15t">
2298
2299
  <path fill="currentColor" d="M223.178.313c39.064 0 70.732 31.668 70.732 70.732-.001 39.064-31.668 70.731-70.732 70.731-12.181 0-23.642-3.079-33.649-8.502l-55.689 55.689a70.267 70.267 0 0 1 5.574 13.441h167.531c8.695-29.217 35.762-50.523 67.804-50.523 39.064 0 70.731 31.668 70.731 70.732s-31.668 70.732-70.731 70.732c-32.042 0-59.108-21.306-67.803-50.523H139.413a70.417 70.417 0 0 1-7.888 17.396l54.046 54.046c10.893-6.851 23.786-10.815 37.605-10.815 39.064 0 70.732 31.669 70.732 70.733 0 39.064-31.668 70.731-70.732 70.731s-70.732-31.667-70.732-70.731c0-10.518 2.296-20.499 6.414-29.471l-57.78-57.78c-8.972 4.117-18.952 6.414-29.47 6.414-39.063 0-70.731-31.668-70.732-70.732 0-39.064 31.669-70.732 70.733-70.732 12.18 0 23.642 3.079 33.649 8.502l55.688-55.688c-5.423-10.007-8.502-21.469-8.502-33.65 0-39.064 31.668-70.733 70.732-70.733Zm0 343.555c-16.742 0-30.314 13.572-30.314 30.314 0 16.741 13.572 30.313 30.314 30.313s30.314-13.572 30.314-30.313c0-16.742-13.572-30.314-30.314-30.314ZM71.611 192.299c-16.742 0-30.315 13.572-30.315 30.314s13.573 30.314 30.315 30.314c16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314Zm303.138 0c-16.729 0-30.294 13.551-30.315 30.275l.001.039-.001.038c.021 16.725 13.586 30.276 30.315 30.276 16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314ZM223.178 40.73c-16.742 0-30.314 13.573-30.314 30.315s13.573 30.313 30.314 30.313c16.742 0 30.313-13.572 30.314-30.313 0-16.742-13.572-30.314-30.314-30.315Z"/>
2299
2300
  </svg>`;
@@ -4015,7 +4016,8 @@ const EVENT_FILTERS = [
4015
4016
  'error',
4016
4017
  'consent',
4017
4018
  'network',
4018
- 'iab'
4019
+ 'iab',
4020
+ "script"
4019
4021
  ];
4020
4022
  function createFilterButton(filter, active, onClick) {
4021
4023
  return createButton({
@@ -4030,6 +4032,7 @@ function matchesFilter(event, filter) {
4030
4032
  if ('error' === filter) return 'error' === event.type;
4031
4033
  if ('consent' === filter) return 'consent_set' === event.type || 'consent_save' === event.type || 'consent_reset' === event.type;
4032
4034
  if ('network' === filter) return 'network' === event.type;
4035
+ if ("script" === filter) return "script" === event.type;
4033
4036
  return 'iab' === event.type;
4034
4037
  }
4035
4038
  function matchesSearch(event, query) {
@@ -4153,6 +4156,8 @@ function getEventIcon(type) {
4153
4156
  return '◉';
4154
4157
  case 'iab':
4155
4158
  return '◆';
4159
+ case "script":
4160
+ return '⌘';
4156
4161
  default:
4157
4162
  return '○';
4158
4163
  }
@@ -4170,6 +4175,8 @@ function getEventColor(type) {
4170
4175
  return 'var(--c15t-devtools-badge-warning, #f59e0b)';
4171
4176
  case 'iab':
4172
4177
  return 'var(--c15t-devtools-badge-info, #3b82f6)';
4178
+ case "script":
4179
+ return 'var(--c15t-devtools-badge-info, #14b8a6)';
4173
4180
  default:
4174
4181
  return 'var(--c15t-text-muted)';
4175
4182
  }
@@ -5470,6 +5477,20 @@ const CODE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" f
5470
5477
  <polyline points="8 6 2 12 8 18"></polyline>
5471
5478
  </svg>`;
5472
5479
  const scriptsSearchByContainer = new WeakMap();
5480
+ const expandedScriptsByContainer = new WeakMap();
5481
+ const CHEVRON_DOWN_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
5482
+ <polyline points="6 9 12 15 18 9"></polyline>
5483
+ </svg>`;
5484
+ const CHEVRON_RIGHT_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
5485
+ <polyline points="9 18 15 12 9 6"></polyline>
5486
+ </svg>`;
5487
+ function getExpandedScripts(container) {
5488
+ const existing = expandedScriptsByContainer.get(container);
5489
+ if (existing) return existing;
5490
+ const expanded = new Set();
5491
+ expandedScriptsByContainer.set(container, expanded);
5492
+ return expanded;
5493
+ }
5473
5494
  function renderScriptsPanel(container, options) {
5474
5495
  const { getState, getEvents } = options;
5475
5496
  clearElement(container);
@@ -5531,6 +5552,10 @@ function renderScriptsPanel(container, options) {
5531
5552
  for (const script of filteredScripts){
5532
5553
  const scriptId = script.id;
5533
5554
  const isLoaded = true === loadedScripts[scriptId];
5555
+ const scriptEvents = getScriptActivityEvents(events, scriptId);
5556
+ const latestActivity = scriptEvents[scriptEvents.length - 1];
5557
+ const expandedScripts = getExpandedScripts(container);
5558
+ const isExpanded = expandedScripts.has(scriptId);
5534
5559
  const category = script.category;
5535
5560
  const categoryDisplay = 'string' == typeof category ? category : JSON.stringify(category);
5536
5561
  let status = 'pending';
@@ -5552,7 +5577,7 @@ function renderScriptsPanel(container, options) {
5552
5577
  text: status.charAt(0).toUpperCase() + status.slice(1),
5553
5578
  variant: statusVariant
5554
5579
  });
5555
- const row = renderer_div({
5580
+ const header = renderer_div({
5556
5581
  style: {
5557
5582
  display: 'flex',
5558
5583
  alignItems: 'center',
@@ -5591,19 +5616,57 @@ function renderScriptsPanel(container, options) {
5591
5616
  whiteSpace: 'nowrap'
5592
5617
  },
5593
5618
  text: `Category: ${categoryDisplay}`
5594
- })
5619
+ }),
5620
+ ...latestActivity && scriptEvents.length > 0 ? [
5621
+ renderer_div({
5622
+ style: {
5623
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5624
+ color: 'var(--c15t-text-muted)',
5625
+ overflow: 'hidden',
5626
+ textOverflow: 'ellipsis',
5627
+ whiteSpace: 'nowrap'
5628
+ },
5629
+ text: `Activity: ${latestActivity.message} (${scriptEvents.length} event${1 === scriptEvents.length ? '' : 's'})`
5630
+ })
5631
+ ] : []
5595
5632
  ]
5596
5633
  }),
5597
5634
  renderer_div({
5598
5635
  style: {
5599
- flexShrink: '0'
5636
+ flexShrink: '0',
5637
+ display: 'flex',
5638
+ alignItems: 'center',
5639
+ gap: '8px'
5600
5640
  },
5601
5641
  children: [
5602
- badge
5642
+ badge,
5643
+ ...scriptEvents.length > 0 ? [
5644
+ createAccordionToggle({
5645
+ scriptId,
5646
+ isExpanded,
5647
+ onToggle: ()=>{
5648
+ if (isExpanded) expandedScripts.delete(scriptId);
5649
+ else expandedScripts.add(scriptId);
5650
+ renderScriptsPanel(container, options);
5651
+ }
5652
+ })
5653
+ ] : []
5603
5654
  ]
5604
5655
  })
5605
5656
  ]
5606
5657
  });
5658
+ const details = isExpanded && scriptEvents.length > 0 ? createScriptActivityDetails(scriptEvents) : null;
5659
+ const row = renderer_div({
5660
+ style: {
5661
+ display: 'flex',
5662
+ flexDirection: 'column',
5663
+ borderBottom: '1px solid var(--c15t-border)'
5664
+ },
5665
+ children: [
5666
+ header,
5667
+ details
5668
+ ]
5669
+ });
5607
5670
  scriptsList.appendChild(row);
5608
5671
  }
5609
5672
  const lastRow = scriptsList.lastElementChild;
@@ -5740,13 +5803,172 @@ function getEventUrl(event) {
5740
5803
  return 'string' == typeof url ? url : event.message;
5741
5804
  }
5742
5805
  function formatEventTime(timestamp) {
5743
- return new Date(timestamp).toLocaleTimeString('en-US', {
5744
- hour12: false,
5745
- hour: '2-digit',
5746
- minute: '2-digit',
5747
- second: '2-digit'
5806
+ const date = new Date(timestamp);
5807
+ const hours = String(date.getHours()).padStart(2, '0');
5808
+ const minutes = String(date.getMinutes()).padStart(2, '0');
5809
+ const seconds = String(date.getSeconds()).padStart(2, '0');
5810
+ const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
5811
+ return `${hours}:${minutes}:${seconds}.${milliseconds}`;
5812
+ }
5813
+ function getScriptActivityEvents(events, scriptId) {
5814
+ return events.filter((event)=>{
5815
+ if ("script" !== event.type) return false;
5816
+ const data = event.data;
5817
+ if (data?.scriptId !== scriptId) return false;
5818
+ return data?.scope === 'lifecycle' || data?.scope === 'phase';
5819
+ }).sort((left, right)=>left.timestamp - right.timestamp);
5820
+ }
5821
+ function createAccordionToggle(options) {
5822
+ const { scriptId, isExpanded, onToggle } = options;
5823
+ const toggle = renderer_button({
5824
+ ariaLabel: `${isExpanded ? 'Collapse' : 'Expand'} ${scriptId} activity`,
5825
+ ariaExpanded: isExpanded ? 'true' : 'false',
5826
+ style: {
5827
+ display: 'inline-flex',
5828
+ alignItems: 'center',
5829
+ justifyContent: 'center',
5830
+ width: '24px',
5831
+ height: '24px',
5832
+ padding: '0',
5833
+ border: '1px solid var(--c15t-border)',
5834
+ borderRadius: '6px',
5835
+ background: 'transparent',
5836
+ color: 'var(--c15t-text-muted)',
5837
+ cursor: 'pointer',
5838
+ flexShrink: '0'
5839
+ },
5840
+ onClick: onToggle
5841
+ });
5842
+ toggle.innerHTML = isExpanded ? CHEVRON_DOWN_ICON : CHEVRON_RIGHT_ICON;
5843
+ return toggle;
5844
+ }
5845
+ function createScriptActivityDetails(events) {
5846
+ const groupedEvents = groupScriptActivityEvents(events.slice(-8));
5847
+ return renderer_div({
5848
+ style: {
5849
+ display: 'flex',
5850
+ flexDirection: 'column',
5851
+ gap: '6px',
5852
+ padding: '0 0 10px 0',
5853
+ marginLeft: '0'
5854
+ },
5855
+ children: groupedEvents.map(([groupName, groupEvents])=>createScriptActivityGroup(groupName, groupEvents))
5748
5856
  });
5749
5857
  }
5858
+ function createScriptActivityGroup(groupName, events) {
5859
+ return renderer_div({
5860
+ style: {
5861
+ display: 'flex',
5862
+ flexDirection: 'column',
5863
+ gap: '4px'
5864
+ },
5865
+ children: [
5866
+ renderer_span({
5867
+ style: {
5868
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5869
+ fontWeight: '600',
5870
+ color: 'var(--c15t-text)',
5871
+ textTransform: 'none'
5872
+ },
5873
+ text: groupName
5874
+ }),
5875
+ ...events.map((event)=>createScriptActivityRow(event))
5876
+ ]
5877
+ });
5878
+ }
5879
+ function createScriptActivityRow(event) {
5880
+ const data = event.data ?? {};
5881
+ const scope = 'string' == typeof data.scope ? data.scope : void 0;
5882
+ const phase = 'string' == typeof data.phase ? data.phase : void 0;
5883
+ const stepType = 'string' == typeof data.stepType ? data.stepType : void 0;
5884
+ const metadata = [
5885
+ scope,
5886
+ phase,
5887
+ stepType
5888
+ ].filter(Boolean).join(' / ');
5889
+ return renderer_div({
5890
+ style: {
5891
+ display: 'flex',
5892
+ flexDirection: 'column',
5893
+ gap: '2px',
5894
+ padding: '6px 10px',
5895
+ marginLeft: '0',
5896
+ borderLeft: '2px solid var(--c15t-border)',
5897
+ backgroundColor: 'var(--c15t-devtools-surface-secondary, rgba(127,127,127,0.06))',
5898
+ borderRadius: '0 8px 8px 0'
5899
+ },
5900
+ children: [
5901
+ renderer_div({
5902
+ style: {
5903
+ display: 'flex',
5904
+ alignItems: 'center',
5905
+ justifyContent: 'space-between',
5906
+ gap: '8px'
5907
+ },
5908
+ children: [
5909
+ renderer_span({
5910
+ style: {
5911
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5912
+ fontWeight: '600',
5913
+ color: 'var(--c15t-text)'
5914
+ },
5915
+ text: event.message
5916
+ }),
5917
+ renderer_span({
5918
+ style: {
5919
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5920
+ color: 'var(--c15t-text-muted)',
5921
+ flexShrink: '0'
5922
+ },
5923
+ text: formatEventTime(event.timestamp)
5924
+ })
5925
+ ]
5926
+ }),
5927
+ ...metadata ? [
5928
+ renderer_span({
5929
+ style: {
5930
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5931
+ color: 'var(--c15t-text-muted)'
5932
+ },
5933
+ text: metadata
5934
+ })
5935
+ ] : []
5936
+ ]
5937
+ });
5938
+ }
5939
+ function groupScriptActivityEvents(events) {
5940
+ const groups = new Map();
5941
+ for (const event of events){
5942
+ const groupName = getScriptActivityGroupName(event);
5943
+ const existing = groups.get(groupName);
5944
+ if (existing) existing.push(event);
5945
+ else groups.set(groupName, [
5946
+ event
5947
+ ]);
5948
+ }
5949
+ const orderedGroupNames = [
5950
+ 'onBeforeLoad',
5951
+ 'onLoad',
5952
+ 'onConsentChange',
5953
+ 'other'
5954
+ ];
5955
+ return orderedGroupNames.map((groupName)=>{
5956
+ const groupEvents = groups.get(groupName);
5957
+ return groupEvents ? [
5958
+ groupName,
5959
+ groupEvents
5960
+ ] : null;
5961
+ }).filter((group)=>null !== group);
5962
+ }
5963
+ function getScriptActivityGroupName(event) {
5964
+ const data = event.data ?? {};
5965
+ if ('string' == typeof data.callback) return data.callback;
5966
+ const phase = 'string' == typeof data.phase ? data.phase : '';
5967
+ if ('bootstrap' === phase || 'consent-default' === phase || 'setup' === phase || 'onBeforeLoadGranted' === phase || 'onBeforeLoadDenied' === phase) return 'onBeforeLoad';
5968
+ if ('afterLoad' === phase || 'onLoadGranted' === phase || 'onLoadDenied' === phase) return 'onLoad';
5969
+ if ('consent-update' === phase || 'onConsentChange' === phase || 'onConsentGranted' === phase || 'onConsentDenied' === phase) return 'onConsentChange';
5970
+ return 'other';
5971
+ }
5750
5972
  function scripts_truncateText(text, maxLength) {
5751
5973
  if (text.length <= maxLength) return text;
5752
5974
  return `${text.slice(0, maxLength - 3)}...`;
@@ -6324,6 +6546,7 @@ function restoreInstrumentation(entry) {
6324
6546
  const state = entry.store.getState();
6325
6547
  state.setCallback('onBannerFetched', entry.originalCallbacks.onBannerFetched);
6326
6548
  state.setCallback('onConsentSet', entry.originalCallbacks.onConsentSet);
6549
+ state.setCallback('onConsentChanged', entry.originalCallbacks.onConsentChanged);
6327
6550
  state.setCallback('onError', entry.originalCallbacks.onError);
6328
6551
  state.setCallback('onBeforeConsentRevocationReload', entry.originalCallbacks.onBeforeConsentRevocationReload);
6329
6552
  const blocker = state.networkBlocker;
@@ -6361,6 +6584,14 @@ function createInstrumentationEntry(store) {
6361
6584
  });
6362
6585
  if ('function' == typeof entry.originalCallbacks.onConsentSet) entry.originalCallbacks.onConsentSet(payload);
6363
6586
  });
6587
+ store.getState().setCallback('onConsentChanged', (payload)=>{
6588
+ emitEvent(entry, {
6589
+ type: 'consent_save',
6590
+ message: 'Consent preferences changed',
6591
+ data: payload
6592
+ });
6593
+ if ('function' == typeof entry.originalCallbacks.onConsentChanged) entry.originalCallbacks.onConsentChanged(payload);
6594
+ });
6364
6595
  store.getState().setCallback('onError', (payload)=>{
6365
6596
  const errorMessage = payload.error;
6366
6597
  emitEvent(entry, {
@@ -6501,6 +6732,25 @@ function createStateCopy(state) {
6501
6732
  loadedScripts: state.loadedScripts
6502
6733
  };
6503
6734
  }
6735
+ function scriptDebugEventToLogEntry(event) {
6736
+ return {
6737
+ type: "script",
6738
+ message: event.message,
6739
+ data: {
6740
+ ...event.data ?? {},
6741
+ source: event.source,
6742
+ scope: event.scope,
6743
+ action: event.action,
6744
+ scriptId: event.scriptId,
6745
+ elementId: event.elementId,
6746
+ hasConsent: event.hasConsent,
6747
+ callback: event.callback,
6748
+ phase: event.phase,
6749
+ stepType: event.stepType,
6750
+ stepIndex: event.stepIndex
6751
+ }
6752
+ };
6753
+ }
6504
6754
  function createDevTools(options = {}) {
6505
6755
  const { namespace = 'c15tStore', position = 'bottom-right', defaultOpen = false } = options;
6506
6756
  const stateManager = createStateManager({
@@ -6508,6 +6758,7 @@ function createDevTools(options = {}) {
6508
6758
  isOpen: defaultOpen
6509
6759
  });
6510
6760
  let detachInstrumentation = null;
6761
+ let detachScriptDebug = null;
6511
6762
  const storeConnector = createStoreConnector({
6512
6763
  namespace,
6513
6764
  onConnect: (_state, store)=>{
@@ -6519,6 +6770,10 @@ function createDevTools(options = {}) {
6519
6770
  stateManager.addEvent(event);
6520
6771
  }
6521
6772
  });
6773
+ detachScriptDebug?.();
6774
+ detachScriptDebug = subscribeToScriptDebugEvents((event)=>{
6775
+ stateManager.addEvent(scriptDebugEventToLogEntry(event));
6776
+ });
6522
6777
  stateManager.setConnected(true);
6523
6778
  stateManager.addEvent({
6524
6779
  type: 'info',
@@ -6555,6 +6810,8 @@ function createDevTools(options = {}) {
6555
6810
  stateManager.setConnected(false);
6556
6811
  detachInstrumentation?.();
6557
6812
  detachInstrumentation = null;
6813
+ detachScriptDebug?.();
6814
+ detachScriptDebug = null;
6558
6815
  stateManager.addEvent({
6559
6816
  type: 'error',
6560
6817
  message: 'Disconnected from c15tStore'
@@ -6644,6 +6901,8 @@ function createDevTools(options = {}) {
6644
6901
  destroy: ()=>{
6645
6902
  detachInstrumentation?.();
6646
6903
  detachInstrumentation = null;
6904
+ detachScriptDebug?.();
6905
+ detachScriptDebug = null;
6647
6906
  panelHeightAnimator.destroy();
6648
6907
  tabsInstance?.destroy();
6649
6908
  panelInstance.destroy();
@@ -6658,6 +6917,7 @@ function createDevTools(options = {}) {
6658
6917
  function createDevToolsPanel(options) {
6659
6918
  const { namespace = 'c15tStore' } = options;
6660
6919
  let detachInstrumentation = null;
6920
+ let detachScriptDebug = null;
6661
6921
  const stateManager = createStateManager({
6662
6922
  isOpen: true
6663
6923
  });
@@ -6670,6 +6930,10 @@ function createDevToolsPanel(options) {
6670
6930
  store,
6671
6931
  onEvent: (event)=>stateManager.addEvent(event)
6672
6932
  });
6933
+ detachScriptDebug?.();
6934
+ detachScriptDebug = subscribeToScriptDebugEvents((event)=>{
6935
+ stateManager.addEvent(scriptDebugEventToLogEntry(event));
6936
+ });
6673
6937
  stateManager.setConnected(true);
6674
6938
  const persistedOverrides = loadPersistedOverrides();
6675
6939
  if (persistedOverrides) {
@@ -6686,6 +6950,8 @@ function createDevToolsPanel(options) {
6686
6950
  stateManager.setConnected(false);
6687
6951
  detachInstrumentation?.();
6688
6952
  detachInstrumentation = null;
6953
+ detachScriptDebug?.();
6954
+ detachScriptDebug = null;
6689
6955
  }
6690
6956
  });
6691
6957
  const panelRenderer = createPanelRenderer({
@@ -6778,6 +7044,8 @@ function createDevToolsPanel(options) {
6778
7044
  destroy: ()=>{
6779
7045
  detachInstrumentation?.();
6780
7046
  detachInstrumentation = null;
7047
+ detachScriptDebug?.();
7048
+ detachScriptDebug = null;
6781
7049
  unsubscribe();
6782
7050
  tabsInstance?.destroy();
6783
7051
  storeConnector.destroy();