Skip to content

Commit d1ebb6e

Browse files
committed
Phase 7e: rename the whole's wire protocol from *_global to *_whole
The Python API and the panels say "whole"; the wire protocol still said "global". Shipping 1.0 with that contradiction is not acceptable, and with no external users there is no back-compat to keep. set_global_representation -> set_whole_representation, show_global -> show_whole, hide_global -> hide_whole, and the target: "global" payload -> "whole" (the "all" target is unchanged). The TS message types (SetWholeRepresentationMessage, ShowWholeMessage, HideWholeMessage) and handlers (setWholeRepresentation, showWhole, hideWhole) follow. Internal names that are not wire protocol -- globalReprs, currentGlobalRepresentationRefs, the { tag: "global" } Mol* state tags -- are left as they are. Verified end to end in real Mol*: set_whole_representation renders the whole, hide_whole/show_whole toggle it, with no console errors. Python and JS suites green; tsc unchanged. This closes Phase 7. Deferred to Phase 12 (Whole subpanel GUI): the whole's PanelAction family and the whole summary payload -- GUI infrastructure with no consumer until the subpanel exists.
1 parent 9bb5928 commit d1ebb6e

20 files changed

Lines changed: 115 additions & 115 deletions

devguide/pending_proposals/scene_master_plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ none were reported by a failing test.
690690
| 4 | Contract B/O: colour + order | L || 2026-07-11 | *(this commit)* | **Passed.** Done in two slices (4a colour/decorator, 4b order→render + region-vs-region ownership). Decorator, layers, precedence, region-vs-region masking + R-O1 all mutation-verified in real Mol\*. `order` serialisation deferred to P6. |
691691
| 5 | Contract R: recipes | L || 2026-07-11 | *(this commit)* | **Passed.** provenance/uid/mode/frame_dependent, uid-referenced recipes, operand-deletion freeze, read-only atom_indices, and rebuild re-evaluation (not remap) all mutation-verified. `mode` is a validating setter, not a `new_region` arg. Dynamic evaluation → P10, serialisation → P6. |
692692
| 6 | Contract C: state v2 | M || 2026-07-11 | *(this commit)* | **Passed.** Implemented by Claude (author == auditor; flagged). Round-trip overlap winner, order high-water mark, topological restore, transient filter, whole restore all mutation-verified. No v1 reader. Layer-membership is a format-only field (behaviour → P9). |
693-
| 7 | API completeness & symmetry | L | | | | |
693+
| 7 | API completeness & symmetry | L | | 2026-07-11 | `cb7a26dd`+ | **Passed.** Done in five slices 7a–7e (variadic booleans + count + complement-of-many; visible/set_color_scheme/manager parity; read-only state; view.regions.add; protocol rename *_global→*_whole verified in real Mol\*). Implemented by Claude. **Deferred to P12:** the whole PanelAction family and whole summary (GUI infrastructure, no consumer until the Whole subpanel). |
694694
| 8 | Contract H: command history | L |||||
695695
| 9 | Layer membership | M |||||
696696
| 10 | Dynamic-region evaluation | L |||||

molsysviewer/js/src/managers/handlers/state-handlers.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ import {
2424
DeleteLayerMessage,
2525
DeleteRegionMessage,
2626
RenameRegionMessage,
27-
HideGlobalMessage,
27+
HideWholeMessage,
2828
HideLayerMessage,
2929
HideRegionMessage,
3030
SetAtomColorsMessage,
31-
SetGlobalRepresentationMessage,
31+
SetWholeRepresentationMessage,
3232
SetFocusFadeMessage,
3333
SetLayerTagMessage,
3434
SetRegionRepresentationMessage,
3535
SetRegionOrderMessage,
3636
SetRegionsVisibilityMessage,
3737
SetRegionSummariesMessage,
3838
BatchRegionOperationsMessage,
39-
ShowGlobalMessage,
39+
ShowWholeMessage,
4040
ShowLayerMessage,
4141
ShowRegionMessage,
4242
UpdateVisibilityMessage,
@@ -98,7 +98,7 @@ export class StateHandlers {
9898
private readonly layerMeta = new Map<string, { kind?: string; meta?: Record<string, unknown> }>();
9999
private readonly tagIndex = new Map<string, Set<StateTransform.Ref>>();
100100
private readonly globalReprs = new Set<StateTransform.Ref>();
101-
private readonly pendingGlobalOps: Array<{ hide: boolean; target: "global" | "all" }> = [];
101+
private readonly pendingGlobalOps: Array<{ hide: boolean; target: "whole" | "all" }> = [];
102102
private readonly pendingLayerVisibility = new Map<string, boolean>();
103103
private readonly pendingRegions: CreateRegionMessage[] = [];
104104
private regionStyleOptions = { representations: [] as string[], presets: [] as string[] };
@@ -1075,7 +1075,7 @@ export class StateHandlers {
10751075
}
10761076
}
10771077

1078-
async setGlobalRepresentation(msg: SetGlobalRepresentationMessage) {
1078+
async setWholeRepresentation(msg: SetWholeRepresentationMessage) {
10791079
const structureRef = this.callbacks.getLoadedStructure()?.structure;
10801080
if (!structureRef) return;
10811081

@@ -1217,12 +1217,12 @@ export class StateHandlers {
12171217
await this.applyComposedTransparency();
12181218
}
12191219

1220-
async showGlobal(msg: ShowGlobalMessage) {
1221-
await this.handleShowHideGlobal(false, msg.target ?? "global");
1220+
async showWhole(msg: ShowWholeMessage) {
1221+
await this.handleShowHideGlobal(false, msg.target ?? "whole");
12221222
}
12231223

1224-
async hideGlobal(msg: HideGlobalMessage) {
1225-
await this.handleShowHideGlobal(true, msg.target ?? "global");
1224+
async hideWhole(msg: HideWholeMessage) {
1225+
await this.handleShowHideGlobal(true, msg.target ?? "whole");
12261226
}
12271227

12281228
async zoom(msg: ZoomMessage) {
@@ -1280,7 +1280,7 @@ export class StateHandlers {
12801280
await this.ensureDefaultGlobalRepresentation();
12811281
}
12821282
if (this.requestedGlobalHidden !== null) {
1283-
await this.handleShowHideGlobal(this.requestedGlobalHidden, "global");
1283+
await this.handleShowHideGlobal(this.requestedGlobalHidden, "whole");
12841284
}
12851285
}
12861286

@@ -1323,8 +1323,8 @@ export class StateHandlers {
13231323
this.tagIndex.delete(tag);
13241324
}
13251325

1326-
private async handleShowHideGlobal(hide: boolean, target: "global" | "all" = "global") {
1327-
if (target === "global") {
1326+
private async handleShowHideGlobal(hide: boolean, target: "whole" | "all" = "whole") {
1327+
if (target === "whole") {
13281328
this.requestedGlobalHidden = hide;
13291329
}
13301330
if (!this.callbacks.getStructure()) {
@@ -1343,7 +1343,7 @@ export class StateHandlers {
13431343
if (entry.hidden) hiddenRegionReprRefs.add(ref as any);
13441344
}));
13451345

1346-
if (target === "global") {
1346+
if (target === "whole") {
13471347
this.globalReprs.forEach(ref => {
13481348
refs.push(ref);
13491349
baselineRefs.push(ref);
@@ -1396,7 +1396,7 @@ export class StateHandlers {
13961396
if (baselineRefs.length) {
13971397
baselineRefs.forEach(ref => setSubtreeVisibility(this.plugin.state.data, ref, true));
13981398
} else {
1399-
this.pendingGlobalOps.push({ hide: true, target: "global" });
1399+
this.pendingGlobalOps.push({ hide: true, target: "whole" });
14001400
}
14011401
}
14021402
}

molsysviewer/js/src/managers/viewer-controller.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const PANEL_REFRESH_BY_OPERATION: Partial<Record<ViewerMessage["op"], readonly P
7777
set_figure_spec: ["addons"],
7878
set_user_preset: ["addons"],
7979
set_canvas_visibility: ["addons"],
80-
set_global_representation: ["addons"],
80+
set_whole_representation: ["addons"],
8181
load_molsys_payload: ["addons"],
8282
load_structure_from_string: ["addons"],
8383
load_pdb_string: ["addons"],
@@ -2187,9 +2187,9 @@ export class MolSysViewerController {
21872187
await this.state.clearAtomColors(msg as any);
21882188
this.groupPanel.render();
21892189
break;
2190-
case "set_global_representation": await this.state.setGlobalRepresentation(msg); break;
2191-
case "show_global": await this.state.showGlobal(msg); break;
2192-
case "hide_global": await this.state.hideGlobal(msg); break;
2190+
case "set_whole_representation": await this.state.setWholeRepresentation(msg); break;
2191+
case "show_whole": await this.state.showWhole(msg); break;
2192+
case "hide_whole": await this.state.hideWhole(msg); break;
21932193
case "zoom": await this.state.zoom(msg); break;
21942194
case "zoom_to_position": await this.scene.zoomToPosition(msg as any); break;
21952195
case "set_camera_snapshot": await this.setCameraSnapshot((msg as any).snapshot, (msg as any).duration_ms); break;
@@ -2851,7 +2851,7 @@ export class MolSysViewerController {
28512851
return;
28522852
}
28532853

2854-
if (op === "set_global_representation") {
2854+
if (op === "set_whole_representation") {
28552855
const styleTag =
28562856
typeof (msg as any).user_preset?.name === "string"
28572857
? (msg as any).user_preset.name

molsysviewer/js/src/messages/viewer-messages.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -526,8 +526,8 @@ export type SetLayerTagMessage = {
526526
new_tag: string;
527527
};
528528

529-
export type SetGlobalRepresentationMessage = {
530-
op: "set_global_representation";
529+
export type SetWholeRepresentationMessage = {
530+
op: "set_whole_representation";
531531
representation?: string;
532532
preset?: string;
533533
user_preset?: any;
@@ -541,14 +541,14 @@ export type SetFigureSpecMessage = {
541541
figure_variants?: string[];
542542
};
543543

544-
export type ShowGlobalMessage = {
545-
op: "show_global";
546-
target?: "global" | "all";
544+
export type ShowWholeMessage = {
545+
op: "show_whole";
546+
target?: "whole" | "all";
547547
};
548548

549-
export type HideGlobalMessage = {
550-
op: "hide_global";
551-
target?: "global" | "all";
549+
export type HideWholeMessage = {
550+
op: "hide_whole";
551+
target?: "whole" | "all";
552552
};
553553

554554
export type ZoomMessage = {
@@ -810,10 +810,10 @@ export type ViewerMessage =
810810
HideLayerMessage |
811811
DeleteLayerMessage |
812812
SetLayerTagMessage |
813-
SetGlobalRepresentationMessage |
813+
SetWholeRepresentationMessage |
814814
SetFigureSpecMessage |
815-
ShowGlobalMessage |
816-
HideGlobalMessage |
815+
ShowWholeMessage |
816+
HideWholeMessage |
817817
ZoomMessage |
818818
ZoomToPositionMessage |
819819
SetCameraSnapshotMessage |

molsysviewer/js/tests/e2e/harness.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ export async function profileExclusiveOwnership(
619619
const fullWhole = atomRange(0, atoms);
620620
const complementWhole = atomRange(ownedAtoms, atoms);
621621

622-
await profiled.handleMessage({ op: "hide_global", target: "global" });
622+
await profiled.handleMessage({ op: "hide_whole", target: "whole" });
623623
await profiled.handleMessage({ op: "create_region", tag: "__exclusive_owned_region__", atom_indices: owned });
624624
await profiled.handleMessage({
625625
op: "set_region_representation",
@@ -821,7 +821,7 @@ export async function probeExclusiveOwnershipPicking(
821821
if (!structure) throw new Error("Exclusive ownership picking probe requires a loaded structure.");
822822

823823
const owned = atomRange(0, ownedAtoms);
824-
await profiled.handleMessage({ op: "hide_global", target: "global" });
824+
await profiled.handleMessage({ op: "hide_whole", target: "whole" });
825825
const explicitWhole = await buildExclusiveWhole(profiled, atomRange(0, atoms), "cartoon");
826826
const explicitWholeComponent = findComponentByRef(profiled, explicitWhole.componentRef);
827827
if (!explicitWholeComponent) throw new Error("Exclusive ownership picking probe failed to create explicit whole component.");
@@ -930,7 +930,7 @@ export async function probeGlobalRepresentationOwnershipMask(
930930
representation: "ball-and-stick",
931931
});
932932
await profiled.handleMessage({
933-
op: "set_global_representation",
933+
op: "set_whole_representation",
934934
...options.globalMessage,
935935
} as any);
936936

@@ -975,7 +975,7 @@ export async function probePerAtomColorDecorator(
975975
if (!structure) throw new Error("Per-atom color decorator probe requires a loaded structure.");
976976

977977
await profiled.handleMessage({
978-
op: "set_global_representation",
978+
op: "set_whole_representation",
979979
representation: "ball-and-stick",
980980
params: { color_scheme: "element_cpk" },
981981
} as any);

molsysviewer/js/tests/unit/popup-logic.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ test("bootPopup replays initial sync and enables autohide listeners", async () =
196196
data: {
197197
type: "molsysviewer-initial-sync",
198198
data: {
199-
messages: [{ op: "load_molsys_payload" }, { op: "hide_global", target: "global" }],
199+
messages: [{ op: "load_molsys_payload" }, { op: "hide_whole", target: "whole" }],
200200
cameraSnapshot: { target: [0, 0, 0] },
201201
isSpinActive: true,
202202
isSwingActive: true,
@@ -209,7 +209,7 @@ test("bootPopup replays initial sync and enables autohide listeners", async () =
209209

210210
assert.deepStrictEqual(calls.handled, [
211211
{ op: "load_molsys_payload" },
212-
{ op: "hide_global", target: "global" },
212+
{ op: "hide_whole", target: "whole" },
213213
]);
214214
assert.deepStrictEqual(calls.camera, [
215215
{ snapshot: { target: [0, 0, 0] }, duration: 0 },
@@ -372,13 +372,13 @@ test("bootPopup dispatches molsysviewer-sync-op to controller (live mirror)", as
372372
await flushAsync();
373373

374374
env.windowObj.dispatch("message", {
375-
data: { type: "molsysviewer-sync-op", data: { op: "show_global", target: "global" } },
375+
data: { type: "molsysviewer-sync-op", data: { op: "show_whole", target: "whole" } },
376376
});
377377
await flushAsync();
378378

379379
assert.deepStrictEqual(handled, [
380380
{ op: "hide_region", tag: "r1" },
381-
{ op: "show_global", target: "global" },
381+
{ op: "show_whole", target: "whole" },
382382
]);
383383
} finally {
384384
(globalThis as any).window = previousWindow;

molsysviewer/js/tests/unit/state-handler.test.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -638,14 +638,14 @@ test("state handler queues global visibility ops when structure is not ready", a
638638
notify: (_msg: any) => {},
639639
});
640640

641-
await handler.hideGlobal({ op: "hide_global" });
641+
await handler.hideWhole({ op: "hide_whole" });
642642
const pendingOpsA = (handler as any).pendingGlobalOps as Array<{ hide: boolean; target: string }>;
643643
const requestedA = (handler as any).requestedGlobalHidden as boolean | null;
644644
assert.strictEqual(pendingOpsA.length, 1);
645-
assert.deepStrictEqual(pendingOpsA[0], { hide: true, target: "global" });
645+
assert.deepStrictEqual(pendingOpsA[0], { hide: true, target: "whole" });
646646
assert.strictEqual(requestedA, true);
647647

648-
await handler.showGlobal({ op: "show_global", target: "all" });
648+
await handler.showWhole({ op: "show_whole", target: "all" });
649649
const pendingOpsB = (handler as any).pendingGlobalOps as Array<{ hide: boolean; target: string }>;
650650
const requestedB = (handler as any).requestedGlobalHidden as boolean | null;
651651
assert.strictEqual(pendingOpsB.length, 2);
@@ -728,8 +728,8 @@ test("state handler clears orphan default global representations before applying
728728
};
729729
(handler as any).handleShowHideGlobal = async () => {};
730730

731-
await handler.setGlobalRepresentation({
732-
op: "set_global_representation",
731+
await handler.setWholeRepresentation({
732+
op: "set_whole_representation",
733733
preset: "auto",
734734
params: {},
735735
} as any);
@@ -781,8 +781,8 @@ test("state handler replaces prior explicit global representation on subsequent
781781
};
782782
(handler as any).handleShowHideGlobal = async () => {};
783783

784-
await handler.setGlobalRepresentation({ op: "set_global_representation", preset: "auto", params: {} } as any);
785-
await handler.setGlobalRepresentation({ op: "set_global_representation", preset: "polymer-cartoon", params: {} } as any);
784+
await handler.setWholeRepresentation({ op: "set_whole_representation", preset: "auto", params: {} } as any);
785+
await handler.setWholeRepresentation({ op: "set_whole_representation", preset: "polymer-cartoon", params: {} } as any);
786786

787787
assert.deepStrictEqual(removed, ["first-global-repr"]);
788788
const globalReprs = (handler as any).globalReprs as Set<string>;
@@ -880,8 +880,8 @@ test("state handler maps structural color_scheme to a Mol* color theme for direc
880880
});
881881
(handler as any).handleShowHideGlobal = async () => {};
882882

883-
await handler.setGlobalRepresentation({
884-
op: "set_global_representation",
883+
await handler.setWholeRepresentation({
884+
op: "set_whole_representation",
885885
representation: "cartoon",
886886
params: { color_scheme: "secondary_structure_default" },
887887
} as any);
@@ -948,8 +948,8 @@ test("state handler maps curated structural color and size schemes for direct gl
948948
});
949949
(handler as any).handleShowHideGlobal = async () => {};
950950

951-
await handler.setGlobalRepresentation({
952-
op: "set_global_representation",
951+
await handler.setWholeRepresentation({
952+
op: "set_whole_representation",
953953
representation: "cartoon",
954954
params: { color_scheme: "residue_name", size_scheme: "physical" },
955955
} as any);
@@ -1017,8 +1017,8 @@ test("state handler accepts advanced Mol* color and size themes for direct globa
10171017
});
10181018
(handler as any).handleShowHideGlobal = async () => {};
10191019

1020-
await handler.setGlobalRepresentation({
1021-
op: "set_global_representation",
1020+
await handler.setWholeRepresentation({
1021+
op: "set_whole_representation",
10221022
representation: "cartoon",
10231023
params: {
10241024
molstar_color_theme: { name: "residue-name", params: { saturation: 0 } },
@@ -1089,8 +1089,8 @@ test("state handler gives curated structural color and size schemes priority ove
10891089
});
10901090
(handler as any).handleShowHideGlobal = async () => {};
10911091

1092-
await handler.setGlobalRepresentation({
1093-
op: "set_global_representation",
1092+
await handler.setWholeRepresentation({
1093+
op: "set_whole_representation",
10941094
representation: "cartoon",
10951095
params: {
10961096
color_scheme: "secondary_structure_default",

0 commit comments

Comments
 (0)