@jax-data-science/sci-image-visualizer 0.2.4 → 0.2.5

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.
@@ -153,6 +153,16 @@ export declare class OpenSeadragonVisualizerService extends BaseStoreVisualizer
153
153
  /** Only grayscale images get a colormap (RGB tiles pass through untouched). */
154
154
  private isGrayscaleImage;
155
155
  private colormapSub;
156
+ /** Bumped by every display invalidation. A recolor round captures it and, after
157
+ * each `await`, abandons the tile once a newer round has started. Writing a
158
+ * superseded context back is not merely wasted work: OSD's conversion sees a
159
+ * canvas the newer round already replaced, throws `DOMException`, and
160
+ * `_handleConversionError` DESTROYS the cache record and unloads the tile
161
+ * (unlike the drawer's rasterBlob path, it does not re-prepare). Enough of
162
+ * those and the viewer goes white mid-drag. */
163
+ private displayToken;
164
+ /** Pending coalesced invalidation (see {@link scheduleInvalidate}). */
165
+ private invalidateHandle;
156
166
  /** Latest per-channel display state (window/gamma/visibility) from the store,
157
167
  * read synchronously by recolorTile. Channel 0 drives grayscale windowing;
158
168
  * R/G/B (indices 0-2) drive RGB per-channel windowing. */
@@ -301,6 +311,12 @@ export declare class OpenSeadragonVisualizerService extends BaseStoreVisualizer
301
311
  * flooding OSD with "[CacheRecord] … InvalidStateError" and wasting work on tiles
302
312
  * that aren't on screen. The other cached slices are marked stale and re-tinted
303
313
  * lazily when revealed. Composite/grayscale invalidate the world as before. */
314
+ /** Collapse a burst of display-state changes into ONE invalidation on the next
315
+ * frame. Dragging a window slider emits per pixel of travel, and each round
316
+ * restores and re-processes every tile of every channel — so the burst is both
317
+ * wasted work and the race that breaks cache records (see {@link displayToken}).
318
+ * The store write stays live, so the pane itself remains responsive. */
319
+ private scheduleInvalidate;
304
320
  private invalidateDisplay;
305
321
  private destroyViewer;
306
322
  /** This backend's region renderer (the SVG overlay), once a plot is mounted. */
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Keys for the toast outlets the library renders for itself.
3
+ *
4
+ * PrimeNG delivers a message to a `<p-toast>` only when the keys match — a
5
+ * keyless message reaches a keyless toast and nothing else. The library used to
6
+ * emit its notices with no key, or with jit-ui's own keys (`app-toast`,
7
+ * `center-toast`), which meant its user-facing feedback silently depended on the
8
+ * host mounting the right markup. In jit-ui it did; in every other host —
9
+ * including this repo's browser example — errors and results went nowhere, so a
10
+ * failed or no-op action looked like a dead button.
11
+ *
12
+ * These keys are owned by the library and their outlets are rendered by
13
+ * {@link VisualizerComponent}, so the feedback works in any host. A host that
14
+ * wants these notices somewhere else should not render an outlet with the same
15
+ * key — two matching outlets show the message twice.
16
+ */
17
+ /** General notices: save results, validation, action outcomes. Default position. */
18
+ export declare const VIZ_TOAST_KEY = "sci-viz-notice";
19
+ /**
20
+ * Failures that must interrupt: rendering/tile errors that leave the viewer in a
21
+ * bad state. Centered and sticky, matching how these were surfaced before.
22
+ */
23
+ export declare const VIZ_ALERT_TOAST_KEY = "sci-viz-alert";
@@ -32,6 +32,31 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
32
32
  * one key would each render the same message — a duplicate toast. A unique
33
33
  * key per instance scopes the toast to the component that raised it. */
34
34
  private static nextToastId;
35
+ /**
36
+ * The library also raises notices from places that have no instance of their
37
+ * own to key against: {@link PlotlyService} is `providedIn: 'root'`, and the
38
+ * region editor is a child dialog. Those use the fixed
39
+ * {@link VIZ_TOAST_KEY} / {@link VIZ_ALERT_TOAST_KEY} outlets.
40
+ *
41
+ * For the same reason the per-instance key above exists, exactly ONE mounted
42
+ * visualizer may render those shared outlets — otherwise a message from the
43
+ * root service would be shown once per live viewer (jit-ui runs a main view
44
+ * and a pipeline-preview at the same time). The first to init claims them and
45
+ * releases on destroy, so the surviving viewer picks them up.
46
+ */
47
+ private static readonly liveInstances;
48
+ readonly vizToastKey = "sci-viz-notice";
49
+ readonly vizAlertToastKey = "sci-viz-alert";
50
+ /**
51
+ * Whether this instance renders the shared outlets. The owner is simply the
52
+ * oldest live visualizer — a `Set` iterates in insertion order, so when the
53
+ * owner is destroyed the next one takes over on its following change-detection
54
+ * pass. Tracking a set rather than a single owner matters: with a lone
55
+ * `owner` reference, tearing down the owner while a sibling was already
56
+ * initialised would leave nobody rendering the outlets, and every notice from
57
+ * the root service would silently vanish again.
58
+ */
59
+ get ownsSharedToasts(): boolean;
35
60
  isStackEvent: EventEmitter<any>;
36
61
  isGrayscaleEvent: EventEmitter<any>;
37
62
  /** Which toolbar groups to show. A partial override merges over the full set,
@@ -100,6 +125,25 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
100
125
  * every point click, which re-runs inference). */
101
126
  private samToastShown;
102
127
  readonly samToastKey: string;
128
+ /**
129
+ * Outlet for the library's own result/error notices.
130
+ *
131
+ * PrimeNG routes a message to a `<p-toast>` only when the keys match — a
132
+ * keyless message reaches a keyless toast and nothing else. These notices used
133
+ * to be emitted with no key, so they rendered only in hosts that happen to
134
+ * mount a bare `<p-toast>` (jit-ui does, in its file-tree component). Every
135
+ * other host — including this repo's own browser example — dropped them
136
+ * silently, which made a failed or no-op segmentation look like a dead button:
137
+ * the sticky progress toast is cleared in the same tick by hideSamToast, and
138
+ * the message explaining why never appeared anywhere.
139
+ *
140
+ * Keyed to this component instance so the library renders its own outlet and
141
+ * is not dependent on host markup. Deliberately NOT the sticky toast's key:
142
+ * {@link hideSamToast} clears that key in the `finally`, which would wipe the
143
+ * result the moment it was posted, and the sticky toast's custom template is
144
+ * built for the live status + progress bar.
145
+ */
146
+ readonly resultToastKey: string;
103
147
  /** Subscriptions to the point tool's live feeds (status/busy/download). */
104
148
  private samPointSub;
105
149
  /** Vertex eraser radius in image-pixel coordinates. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jax-data-science/sci-image-visualizer",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Browser-based scientific image visualization for Angular — gigapixel whole-slide (OpenSeadragon), 2D/3D (Plotly) and WebGPU (napari-js) rendering, with region/annotation editing and in-browser SAM segmentation.",
5
5
  "keywords": [
6
6
  "angular",