labnotes 0.0.71__tar.gz → 0.0.73__tar.gz

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.
Files changed (129) hide show
  1. {labnotes-0.0.71 → labnotes-0.0.73}/PKG-INFO +1 -1
  2. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/experiment.js +30 -8
  3. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/labnotes.css +1 -1
  4. {labnotes-0.0.71 → labnotes-0.0.73}/.gitignore +0 -0
  5. {labnotes-0.0.71 → labnotes-0.0.73}/CHANGELOG.md +0 -0
  6. {labnotes-0.0.71 → labnotes-0.0.73}/MIGRATIONS.md +0 -0
  7. {labnotes-0.0.71 → labnotes-0.0.73}/README.md +0 -0
  8. {labnotes-0.0.71 → labnotes-0.0.73}/pyproject.toml +0 -0
  9. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/__init__.py +0 -0
  10. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/__main__.py +0 -0
  11. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/asset_url.py +0 -0
  12. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/check_counts.py +0 -0
  13. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/cli.py +0 -0
  14. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/context.md +0 -0
  15. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/context_guide.py +0 -0
  16. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/count_runs.py +0 -0
  17. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/create_app.py +0 -0
  18. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/create_experiment.py +0 -0
  19. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/create_note.py +0 -0
  20. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/__init__.py +0 -0
  21. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/daemon_app.py +0 -0
  22. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/daemon_client.py +0 -0
  23. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/daemon_running.py +0 -0
  24. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/daemon_server.py +0 -0
  25. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/ensure_daemon.py +0 -0
  26. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/exit_when_idle.py +0 -0
  27. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/remote_start.py +0 -0
  28. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/run_daemon.py +0 -0
  29. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/serve_daemon.py +0 -0
  30. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/socket_path.py +0 -0
  31. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon/stop_runs.py +0 -0
  32. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/daemon_command.py +0 -0
  33. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/data_html.py +0 -0
  34. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/default_config_text.py +0 -0
  35. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/default_counts.py +0 -0
  36. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/drain_watch.py +0 -0
  37. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/experiment_notes.py +0 -0
  38. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/experiment_runs.py +0 -0
  39. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/experiments.py +0 -0
  40. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/file_changes.py +0 -0
  41. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/format_duration.py +0 -0
  42. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/format_value.py +0 -0
  43. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/group_runs.py +0 -0
  44. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/init.py +0 -0
  45. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/invocation_started.py +0 -0
  46. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/is_positive_int.py +0 -0
  47. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/list_experiments.py +0 -0
  48. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/list_runs.py +0 -0
  49. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/load_config.py +0 -0
  50. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/load_experiment.py +0 -0
  51. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/models.py +0 -0
  52. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/modes.py +0 -0
  53. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/nests_runs.py +0 -0
  54. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/note_path.py +0 -0
  55. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/notebook_kernel.py +0 -0
  56. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/output_html.py +0 -0
  57. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/parse_run_view.py +0 -0
  58. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/print_rows.py +0 -0
  59. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/python_blocks.py +0 -0
  60. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/read_config.py +0 -0
  61. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/read_path.py +0 -0
  62. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/render_markdown.py +0 -0
  63. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/run_command.py +0 -0
  64. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/__init__.py +0 -0
  65. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/describe_event.py +0 -0
  66. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/execute_run.py +0 -0
  67. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/hold_folder.py +0 -0
  68. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/new_param_run_id.py +0 -0
  69. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/new_run_id.py +0 -0
  70. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/new_stamped_run_id.py +0 -0
  71. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/param_args.py +0 -0
  72. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/param_grid.py +0 -0
  73. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/param_run_name.py +0 -0
  74. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/plan_runs.py +0 -0
  75. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/prepare_experiment.py +0 -0
  76. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/read_experiment_config.py +0 -0
  77. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/run_experiment.py +0 -0
  78. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/run_folder.py +0 -0
  79. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/run_headless.py +0 -0
  80. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/runs_parent.py +0 -0
  81. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/shell_command.py +0 -0
  82. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/signal_tree.py +0 -0
  83. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/stop_then_kill.py +0 -0
  84. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/wait_for_tree.py +0 -0
  85. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/runner/write_run_json.py +0 -0
  86. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/save_conflict_copy.py +0 -0
  87. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/save_note.py +0 -0
  88. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/saved_outputs.py +0 -0
  89. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/serve_app.py +0 -0
  90. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/server.py +0 -0
  91. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/sort_href.py +0 -0
  92. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/sql_quote.py +0 -0
  93. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/new-note.js +0 -0
  94. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/note-edit.js +0 -0
  95. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/note-editor.js +0 -0
  96. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/row-link.js +0 -0
  97. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/run-cell.js +0 -0
  98. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/static/view-toggle.js +0 -0
  99. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/summarize_config.py +0 -0
  100. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/__init__.py +0 -0
  101. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/experiment_rows.py +0 -0
  102. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/experiment_run_ids.py +0 -0
  103. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/file_prefix.py +0 -0
  104. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/file_text.py +0 -0
  105. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/iso_time.py +0 -0
  106. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/list_experiment_runs.py +0 -0
  107. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/note_text.py +0 -0
  108. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/open_tables.py +0 -0
  109. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/path_glob.py +0 -0
  110. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/path_pattern.py +0 -0
  111. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/read_experiment.py +0 -0
  112. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/read_file.py +0 -0
  113. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/read_run.py +0 -0
  114. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tables/summarize_experiments.py +0 -0
  115. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/templates/base.html +0 -0
  116. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/templates/editor_imports.html +0 -0
  117. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/templates/experiment.html +0 -0
  118. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/templates/index.html +0 -0
  119. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/templates/note.html +0 -0
  120. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tui/__init__.py +0 -0
  121. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tui/dim.py +0 -0
  122. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tui/format_elapsed.py +0 -0
  123. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tui/run_app.py +0 -0
  124. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tui/run_tui.py +0 -0
  125. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/tui/runs_table.py +0 -0
  126. {labnotes-0.0.71 → labnotes-0.0.73}/src/labnotes/wait_for_note.py +0 -0
  127. {labnotes-0.0.71 → labnotes-0.0.73}/testing-conventions.toml +0 -0
  128. {labnotes-0.0.71 → labnotes-0.0.73}/tests/integration/conftest.py +0 -0
  129. {labnotes-0.0.71 → labnotes-0.0.73}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: labnotes
3
- Version: 0.0.71
3
+ Version: 0.0.73
4
4
  Summary: Browse experiment designs, notes, and run data from a folder.
5
5
  Project-URL: Repository, https://github.com/thekevinscott/labnotes
6
6
  Author-email: Kevin Scott <me@thekevinscott.com>
@@ -28,24 +28,26 @@ if (filters) {
28
28
  let pending;
29
29
  let latest;
30
30
 
31
- const refresh = async () => {
31
+ const load = async (url) => {
32
32
  clearTimeout(pending);
33
- const params = new URLSearchParams();
34
- for (const [key, value] of new FormData(filters)) {
35
- if (value) params.append(key, value);
36
- }
37
- const url = new URL(location.href);
38
- url.search = params;
39
33
  latest = url.href;
40
34
  const response = await fetch(url);
41
35
  if (latest !== url.href) return;
42
36
  const fresh = new DOMParser()
43
37
  .parseFromString(await response.text(), "text/html")
44
38
  .querySelector("#runs");
39
+ const scroller = runs.querySelector(".scroll");
40
+ const { scrollX, scrollY } = window;
41
+ const { scrollLeft } = scroller;
42
+ const header = runs.querySelector("thead tr");
43
+ const focused = [...header.querySelectorAll("a.sort")].indexOf(document.activeElement);
45
44
  runs.querySelector(".narrowed")?.remove();
46
45
  const narrowed = fresh.querySelector(".narrowed");
47
46
  if (narrowed) runs.prepend(narrowed);
48
- runs.querySelector("thead tr").replaceWith(fresh.querySelector("thead tr"));
47
+ const freshHeader = fresh.querySelector("thead tr");
48
+ header.replaceWith(freshHeader);
49
+ for (const input of filters.querySelectorAll("input[type=hidden]")) input.remove();
50
+ filters.prepend(...fresh.querySelectorAll("#run-filters input[type=hidden]"));
49
51
  const table = runs.querySelector("table");
50
52
  const opened = new Set([...table.querySelectorAll(".group.open")].map((group) => group.dataset.name));
51
53
  for (const body of table.querySelectorAll("tbody")) body.remove();
@@ -58,8 +60,28 @@ if (filters) {
58
60
  summary.textContent = summaries[index].textContent;
59
61
  });
60
62
  history.replaceState(null, "", url);
63
+ scroller.scrollLeft = scrollLeft;
64
+ window.scrollTo(scrollX, scrollY);
65
+ if (focused >= 0) freshHeader.querySelectorAll("a.sort")[focused].focus({ preventScroll: true });
61
66
  };
62
67
 
68
+ const refresh = () => {
69
+ const params = new URLSearchParams();
70
+ for (const [key, value] of new FormData(filters)) {
71
+ if (value) params.append(key, value);
72
+ }
73
+ const url = new URL(location.href);
74
+ url.search = params;
75
+ return load(url);
76
+ };
77
+
78
+ runs.addEventListener("click", (event) => {
79
+ const link = event.target.closest("a.sort");
80
+ if (!link || event.button || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
81
+ event.preventDefault();
82
+ load(new URL(link.href));
83
+ });
84
+
63
85
  filters.addEventListener("submit", (event) => {
64
86
  event.preventDefault();
65
87
  refresh();
@@ -287,7 +287,7 @@ h3 {
287
287
  .run-row td { max-width: 24rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
288
288
  .run-row:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }
289
289
  .group-row { cursor: pointer; background: var(--paper); }
290
- .group-row td { font-weight: 600; white-space: nowrap; }
290
+ .group-row td { white-space: nowrap; }
291
291
  .group-row .good { color: var(--good); }
292
292
  .group-row .bad { color: var(--bad); }
293
293
  .group-toggle { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes