@hosty-sdk/app 0.34.1 → 0.34.2

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.
package/dist/ui-host.d.ts CHANGED
@@ -112,7 +112,8 @@ export declare class UiHost implements UiClient {
112
112
  signal?: AbortSignal;
113
113
  }) => Promise<PresentationResult>;
114
114
  private status;
115
- selectPanel: (ref: PanelRef, workspaceId?: string) => Promise<PresentationResult>;
115
+ selectPanel: (ref: PanelRef, workspaceId?: string, signal?: AbortSignal) => Promise<PresentationResult>;
116
+ private selectPanelWithSignal;
116
117
  setExpanded: (expanded: boolean, workspaceId?: string) => void;
117
118
  setWidth: (width: number, workspaceId?: string) => void;
118
119
  setAttention: (panel: PanelRef | string, attention: number) => void;
package/dist/ui-host.js CHANGED
@@ -449,8 +449,10 @@ export class UiHost {
449
449
  return operation;
450
450
  };
451
451
  openSurface = (target, options) => waitForPresentation(this.open(target, options, "local"), options.requestId, options.signal);
452
- open(target, options, source, frame, sourceWorkspace) {
452
+ open(target, options, source, frame, sourceWorkspace, selectionSignal) {
453
453
  const id = options.requestId;
454
+ if (selectionSignal?.aborted)
455
+ return Promise.resolve({ status: "blocked", requestId: id, code: "presentation_cancelled" });
454
456
  if (!this.active || !this.activityReady || this.disposed)
455
457
  return Promise.resolve({ status: "blocked", requestId: id, code: "activity_required" });
456
458
  if (!validId(id) || !validTarget(target) || options.placement !== "side" || options.reuse !== undefined && !["exact", "new"].includes(options.reuse))
@@ -503,6 +505,8 @@ export class UiHost {
503
505
  try {
504
506
  const own = await this.bootstrap(generation);
505
507
  const check = () => {
508
+ if (selectionSignal?.aborted)
509
+ throw new UiError("presentation_cancelled", "This selection was cancelled.");
506
510
  this.checkActivity(generation);
507
511
  this.requireTools(frame);
508
512
  if (!own.canHost)
@@ -763,7 +767,21 @@ export class UiHost {
763
767
  return failure(id, error);
764
768
  }
765
769
  }
766
- selectPanel = async (ref, workspaceId = DEFAULT_WORKSPACE) => {
770
+ // Host-owned selections may cancel before presentation without superseding another selection.
771
+ // PresentationOptions.signal still cancels only a protocol caller's wait.
772
+ selectPanel = async (ref, workspaceId = DEFAULT_WORKSPACE, signal) => {
773
+ const cancel = () => this.invalidateRendererWork();
774
+ signal?.addEventListener("abort", cancel);
775
+ try {
776
+ return await this.selectPanelWithSignal(ref, workspaceId, signal);
777
+ }
778
+ finally {
779
+ signal?.removeEventListener("abort", cancel);
780
+ }
781
+ };
782
+ selectPanelWithSignal = async (ref, workspaceId, signal) => {
783
+ if (signal?.aborted)
784
+ return { status: "blocked", requestId: createPresentationRequestId(), code: "presentation_cancelled" };
767
785
  const opened = this.snapshot.tools.filter(t => t.workspaceId === workspaceId && t.key === panelKey(ref)).sort((a, b) => b.focusedAt - a.focusedAt)[0];
768
786
  if (opened?.resolved.surface) {
769
787
  const requestId = createPresentationRequestId();
@@ -778,6 +796,8 @@ export class UiHost {
778
796
  const resolved = await uiRequest(this.path, "panels/resolve", opened.target);
779
797
  this.checkActivity(generation);
780
798
  this.requireTools();
799
+ if (signal?.aborted)
800
+ throw new UiError("presentation_cancelled", "This selection was cancelled.");
781
801
  if (selection !== state.generation)
782
802
  throw new UiError("presentation_superseded", "A newer action replaced this opening.");
783
803
  if (!resolved.available || !resolved.surface)
@@ -802,7 +822,8 @@ export class UiHost {
802
822
  else if (opened)
803
823
  this.closePresentation(opened.presentationId);
804
824
  const requestId = createPresentationRequestId();
805
- return waitForPresentation(this.open({ panel: ref }, { placement: "side", requestId }, "local", undefined, workspaceId), requestId);
825
+ const opening = this.open({ panel: ref }, { placement: "side", requestId }, "local", undefined, workspaceId, signal);
826
+ return signal ? opening : waitForPresentation(opening, requestId);
806
827
  };
807
828
  setExpanded = (expanded, workspaceId = DEFAULT_WORKSPACE) => {
808
829
  if (!expanded)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hosty-sdk/app",
3
- "version": "0.34.1",
3
+ "version": "0.34.2",
4
4
  "description": "Hosty app auth: session state machine, recovery bridge, Core revalidation, and the embedder responder.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",