arrayview 0.41.1__tar.gz → 0.42.0__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 (111) hide show
  1. {arrayview-0.41.1 → arrayview-0.42.0}/PKG-INFO +1 -1
  2. {arrayview-0.41.1 → arrayview-0.42.0}/pyproject.toml +1 -1
  3. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_diagnostics.py +5 -1
  4. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_launcher.py +41 -0
  5. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_query.py +6 -8
  6. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_viewer.html +449 -102
  7. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_vscode_extension.py +169 -1
  8. arrayview-0.42.0/src/arrayview/arrayview-opener.vsix +0 -0
  9. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_launch_diagnostics.py +11 -0
  10. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_lifecycle_contract.py +21 -6
  11. arrayview-0.41.1/src/arrayview/arrayview-opener.vsix +0 -0
  12. {arrayview-0.41.1 → arrayview-0.42.0}/.gitignore +0 -0
  13. {arrayview-0.41.1 → arrayview-0.42.0}/LICENSE +0 -0
  14. {arrayview-0.41.1 → arrayview-0.42.0}/README.md +0 -0
  15. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/ARCHITECTURE.md +0 -0
  16. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/__init__.py +0 -0
  17. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/__main__.py +0 -0
  18. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_analysis.py +0 -0
  19. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_app.py +0 -0
  20. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_config.py +0 -0
  21. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_dicom.py +0 -0
  22. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_diff.py +0 -0
  23. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_icon.png +0 -0
  24. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_imaging.py +0 -0
  25. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_instance_registry.py +0 -0
  26. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_io.py +0 -0
  27. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_launch_plan.py +0 -0
  28. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_launch_trace.py +0 -0
  29. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_lifecycle.py +0 -0
  30. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_overlays.py +0 -0
  31. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_platform.py +0 -0
  32. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_render.py +0 -0
  33. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_analysis.py +0 -0
  34. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_drop.py +0 -0
  35. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_export.py +0 -0
  36. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_loading.py +0 -0
  37. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_persistence.py +0 -0
  38. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_preferences.py +0 -0
  39. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_preload.py +0 -0
  40. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_rendering.py +0 -0
  41. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_segmentation.py +0 -0
  42. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_state.py +0 -0
  43. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_vectorfield.py +0 -0
  44. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_routes_websocket.py +0 -0
  45. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_segmentation.py +0 -0
  46. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_server.py +0 -0
  47. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_session.py +0 -0
  48. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_session_spec.py +0 -0
  49. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_shell.html +0 -0
  50. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_source_safety.py +0 -0
  51. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_synthetic_mri.py +0 -0
  52. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_torch.py +0 -0
  53. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_tutorial.py +0 -0
  54. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_vectorfield.py +0 -0
  55. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_vscode.py +0 -0
  56. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_vscode_browser.py +0 -0
  57. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_vscode_signal.py +0 -0
  58. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/_watch.py +0 -0
  59. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/gsap.min.js +0 -0
  60. {arrayview-0.41.1 → arrayview-0.42.0}/src/arrayview/todo.md +0 -0
  61. {arrayview-0.41.1 → arrayview-0.42.0}/tests/capture_patient_loading.py +0 -0
  62. {arrayview-0.41.1 → arrayview-0.42.0}/tests/capture_v_animation.py +0 -0
  63. {arrayview-0.41.1 → arrayview-0.42.0}/tests/conftest.py +0 -0
  64. {arrayview-0.41.1 → arrayview-0.42.0}/tests/lifecycle_matrix.py +0 -0
  65. {arrayview-0.41.1 → arrayview-0.42.0}/tests/make_vectorfield_test_arrays.py +0 -0
  66. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_1d_arrays.py +0 -0
  67. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_api.py +0 -0
  68. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_backend_shared.py +0 -0
  69. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_browser.py +0 -0
  70. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_cli.py +0 -0
  71. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_colorbar_hover_highlight.py +0 -0
  72. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_config.py +0 -0
  73. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_dicom.py +0 -0
  74. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_display_opener_results.py +0 -0
  75. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_doctor_commands.py +0 -0
  76. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_drop_import.py +0 -0
  77. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_instance_registry.py +0 -0
  78. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_invocation_contract_matrix.py +0 -0
  79. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_io.py +0 -0
  80. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_large_arrays.py +0 -0
  81. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_launch_blackbox.py +0 -0
  82. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_launch_execution_ownership.py +0 -0
  83. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_launch_plan.py +0 -0
  84. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_launch_trace.py +0 -0
  85. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_loading_server.py +0 -0
  86. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_mode_consistency.py +0 -0
  87. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_mode_matrix.py +0 -0
  88. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_mode_roundtrip.py +0 -0
  89. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_nifti_meta.py +0 -0
  90. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_nifti_series.py +0 -0
  91. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_preferences_ui.py +0 -0
  92. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_public_invocation_regressions.py +0 -0
  93. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_render_failure_reporting.py +0 -0
  94. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_render_progress.py +0 -0
  95. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_rgb_pixel_art.py +0 -0
  96. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_safe_server_stop.py +0 -0
  97. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_server_identity_status.py +0 -0
  98. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_session_spec.py +0 -0
  99. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_source_safety.py +0 -0
  100. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_spawn_ownership.py +0 -0
  101. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_torch.py +0 -0
  102. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_tutorial.py +0 -0
  103. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_tutorial_browser.py +0 -0
  104. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_value_formatting.py +0 -0
  105. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_view_handle_lifecycle.py +0 -0
  106. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_view_launch_execution.py +0 -0
  107. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_vscode_ack_protocol.py +0 -0
  108. {arrayview-0.41.1 → arrayview-0.42.0}/tests/test_window_level_preview.py +0 -0
  109. {arrayview-0.41.1 → arrayview-0.42.0}/tests/ui_audit.py +0 -0
  110. {arrayview-0.41.1 → arrayview-0.42.0}/tests/v_anim_frames/.gitkeep +0 -0
  111. {arrayview-0.41.1 → arrayview-0.42.0}/tests/visual_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arrayview
3
- Version: 0.41.1
3
+ Version: 0.42.0
4
4
  Summary: Fast multi-dimensional array viewer
5
5
  Project-URL: Home, https://github.com/oscarvanderheide/arrayview
6
6
  Project-URL: Source, https://github.com/oscarvanderheide/arrayview
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "arrayview"
7
- version = "0.41.1"
7
+ version = "0.42.0"
8
8
  description = "Fast multi-dimensional array viewer"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  requires-python = ">=3.12"
@@ -76,7 +76,11 @@ _DIAGNOSES: list[tuple[str, str, str, str]] = [
76
76
  _RETRY),
77
77
 
78
78
  # ── Timing — slow, not broken ─────────────────────────────────────────
79
- (r"did not render a frame|did not become ready|did not start the viewer",
79
+ (r"did not start the viewer script", ACTION,
80
+ "VS Code opened an integrated-browser tab, but the tab did not navigate "
81
+ "to the ArrayView page.",
82
+ _RETRY + " If it repeats, reload the VS Code window."),
83
+ (r"did not render a frame|did not become ready",
80
84
  ACTION,
81
85
  "The viewer opened but showed no frame before the deadline — usually a "
82
86
  "slow first load.",
@@ -5266,15 +5266,56 @@ def _handle_management_command(argv: list[str]) -> bool:
5266
5266
  ),
5267
5267
  }
5268
5268
  )
5269
+ from arrayview._platform import _in_vscode_terminal # noqa: PLC0415
5270
+ from arrayview._vscode_extension import ( # noqa: PLC0415
5271
+ _describe_window,
5272
+ _opener_version_report,
5273
+ )
5274
+
5275
+ versions = _opener_version_report()
5276
+ if versions["state"] in {"window_older", "window_unversioned"}:
5277
+ remediation.append(
5278
+ {
5279
+ "code": "opener_version_skew",
5280
+ "message": (
5281
+ "Reload this VS Code window to run opener "
5282
+ f"v{versions['bundled_opener']}."
5283
+ ),
5284
+ }
5285
+ )
5269
5286
  report = {
5270
5287
  "snapshot": snapshot_dict,
5271
5288
  "plan": plan.to_dict(),
5272
5289
  "instances": rows,
5273
5290
  "remediation": remediation,
5291
+ "versions": versions,
5274
5292
  }
5275
5293
  if args.json:
5276
5294
  print(json.dumps(report, indent=2, sort_keys=True))
5277
5295
  else:
5296
+ print(
5297
+ f"arrayview {versions['package_version']} "
5298
+ f"({versions['package_path']})"
5299
+ )
5300
+ print(f"Opener bundled here: v{versions['bundled_opener']}")
5301
+ if versions["this_window"] is not None:
5302
+ suffix = {
5303
+ "window_older": " ← older than this arrayview; reload this window",
5304
+ "window_newer": " ← newer than this arrayview; kept and used",
5305
+ "window_unversioned": " ← pre-0.15 build; reload this window",
5306
+ }.get(versions["state"], "")
5307
+ print(
5308
+ "Opener live in this window: "
5309
+ f"{_describe_window(versions['this_window'])}{suffix}"
5310
+ )
5311
+ elif _in_vscode_terminal():
5312
+ print(
5313
+ "Opener live in this window: none — no live VS Code window "
5314
+ "claims this terminal"
5315
+ )
5316
+ for index, other in enumerate(versions["other_windows"]):
5317
+ label = "Opener live in other windows:" if index == 0 else " " * 29
5318
+ print(f"{label} {_describe_window(other)}")
5278
5319
  print(f"Environment: {plan.environment.value}")
5279
5320
  print(
5280
5321
  f"Server: {plan.server_owner.value} on port {plan.effective_port} "
@@ -60,12 +60,11 @@ def register_query_routes(app, *, get_session_or_404, pil_image, pil_imageops) -
60
60
  raise HTTPException(status_code=400, detail="Invalid viewer phase")
61
61
  if phase != "launch-prepared" and not viewer_instance_id:
62
62
  raise HTTPException(status_code=400, detail="Incomplete viewer phase identity")
63
- # `launch-prepared` is control-plane bookkeeping. The viewer is meant
64
- # to open while a large array is still loading, so waiting for the data
65
- # Session here deadlocks that design against the opener's short journal
66
- # timeout. Pending registration is sufficient; later viewer phases
67
- # still wait for the real Session.
68
- if phase == "launch-prepared":
63
+ # Preparation and script startup are control-plane events. The viewer
64
+ # is meant to open while a large array is still loading, so hiding
65
+ # either event behind Session readiness creates a false pre-script
66
+ # timeout. Data-dependent phases still wait for the real Session.
67
+ if phase in {"launch-prepared", "script-loaded"}:
69
68
  if sid not in SESSIONS and sid not in _session_mod.PENDING_SESSIONS:
70
69
  raise HTTPException(status_code=404, detail="Session not found")
71
70
  else:
@@ -208,8 +207,7 @@ def register_query_routes(app, *, get_session_or_404, pil_image, pil_imageops) -
208
207
  @app.get("/viewer-phase/{sid}/{request_id}")
209
208
  async def get_viewer_phases(sid: str, request_id: str, token: str):
210
209
  """Return phases correlated to one browser launch transaction."""
211
- session = SESSIONS.get(sid)
212
- if session is None:
210
+ if sid not in SESSIONS and sid not in _session_mod.PENDING_SESSIONS:
213
211
  raise HTTPException(status_code=404, detail="Session not found")
214
212
  journals = _session_mod.VIEWER_PHASE_JOURNALS.get(sid, {})
215
213
  journal = journals.get(request_id, {})