mishig HF Staff commited on
Commit
74918fc
·
verified ·
1 Parent(s): efa4294

Add url-sync helper + wire into viewer

Browse files
Files changed (2) hide show
  1. src/lib/TraceViewer.svelte +8 -0
  2. src/lib/url-sync.js +46 -0
src/lib/TraceViewer.svelte CHANGED
@@ -2,6 +2,7 @@
2
  import { tick, onMount, onDestroy } from 'svelte';
3
  import { parseJsonl, toRawUrl } from './parse.js';
4
  import { renderMarkdown } from './markdown.js';
 
5
 
6
  const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
7
  let spinnerFrame = $state(0);
@@ -73,6 +74,7 @@
73
  if (parsed.length === 0) {
74
  error = 'No messages parsed from this file.';
75
  } else {
 
76
  await tick();
77
  playback();
78
  }
@@ -236,6 +238,12 @@
236
  spinnerInterval = setInterval(() => {
237
  spinnerFrame = (spinnerFrame + 1) % spinnerFrames.length;
238
  }, 90);
 
 
 
 
 
 
239
  });
240
 
241
  onDestroy(() => {
 
2
  import { tick, onMount, onDestroy } from 'svelte';
3
  import { parseJsonl, toRawUrl } from './parse.js';
4
  import { renderMarkdown } from './markdown.js';
5
+ import { getParam, setParam } from './url-sync.js';
6
 
7
  const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
8
  let spinnerFrame = $state(0);
 
74
  if (parsed.length === 0) {
75
  error = 'No messages parsed from this file.';
76
  } else {
77
+ setParam('url', url);
78
  await tick();
79
  playback();
80
  }
 
238
  spinnerInterval = setInterval(() => {
239
  spinnerFrame = (spinnerFrame + 1) % spinnerFrames.length;
240
  }, 90);
241
+
242
+ const shared = getParam('url');
243
+ if (shared) {
244
+ url = shared;
245
+ load();
246
+ }
247
  });
248
 
249
  onDestroy(() => {
src/lib/url-sync.js ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Sync shareable URL query params between this iframe and the HF Spaces
2
+ // parent frame (huggingface.co/spaces/<owner>/<name>?...).
3
+ //
4
+ // Pattern borrowed from lerobot-dataset-visualizer:
5
+ // - On mount, read the iframe's own query string (HF forwards the parent's
6
+ // params into the iframe's URL on first load).
7
+ // - On state change, update our own URL via history.replaceState AND
8
+ // postMessage({ queryString }) to the parent so the shareable link on
9
+ // huggingface.co reflects our state.
10
+
11
+ const HF_PARENT_ORIGIN = 'https://huggingface.co';
12
+
13
+ export function getParam(key) {
14
+ try {
15
+ return new URLSearchParams(window.location.search).get(key);
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+
21
+ export function setParam(key, value) {
22
+ try {
23
+ const params = new URLSearchParams(window.location.search);
24
+ if (value == null || value === '') params.delete(key);
25
+ else params.set(key, value);
26
+ const qs = params.toString();
27
+ const newUrl = `${window.location.pathname}${qs ? '?' + qs : ''}`;
28
+ window.history.replaceState(null, '', newUrl);
29
+ postToParent(params);
30
+ } catch {
31
+ // Ignore — standalone deploy or cross-origin blocked.
32
+ }
33
+ }
34
+
35
+ function postToParent(params) {
36
+ try {
37
+ if (window.parent && window.parent !== window) {
38
+ window.parent.postMessage(
39
+ { queryString: params.toString() },
40
+ HF_PARENT_ORIGIN
41
+ );
42
+ }
43
+ } catch {
44
+ // Ignore.
45
+ }
46
+ }