Fork resource subscriptions by protocol era: legacy keeps resources/subscribe; modern (2026-07-28) models subscriptions as a filter over one long-lived subscriptions/listen stream with reconnect-by-re-listen (capped backoff), an optimistic Connecting→Listening header badge, and a fix so the browser proxy no longer blocks listen() ~60s. Closes #1630.
This commit is contained in:
parent
a71e6d2012
commit
320daf2f67
2 changed files with 1656 additions and 90 deletions
|
|
@ -239,6 +239,27 @@ export const SubscriptionsUnsupported: Story = {
|
|||
},
|
||||
};
|
||||
|
||||
// Modern (2026-07-28) era: subscriptions ride one `subscriptions/listen`
|
||||
// stream, so the Subscriptions section shows a stream-status badge in its panel
|
||||
// and a status dot in its header (#1630).
|
||||
export const ModernSubscriptionStream: Story = {
|
||||
args: {
|
||||
resources: sampleResources,
|
||||
templates: sampleTemplates,
|
||||
subscriptions: sampleSubscriptions,
|
||||
protocolEra: "modern",
|
||||
subscriptionStreamState: {
|
||||
active: true,
|
||||
status: "acknowledged",
|
||||
honoredUris: sampleSubscriptions.map((s) => s.resource.uri),
|
||||
},
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
expect(await canvas.findByText("Listening")).toBeInTheDocument();
|
||||
},
|
||||
};
|
||||
|
||||
const manyResources: Resource[] = Array.from({ length: 40 }, (_, i) => ({
|
||||
name: `resource-${String(i + 1).padStart(2, "0")}.wav`,
|
||||
uri: `file:///kit/resource-${i + 1}.wav`,
|
||||
|
|
|
|||
|
|
@ -9,11 +9,15 @@ import {
|
|||
Text,
|
||||
} from "@mantine/core";
|
||||
import type {
|
||||
ProtocolEra,
|
||||
ReadResourceResult,
|
||||
Resource,
|
||||
ResourceTemplateType as ResourceTemplate,
|
||||
} from "@modelcontextprotocol/client";
|
||||
import type { InspectorResourceSubscription } from "../../../../../../core/mcp/types.js";
|
||||
import type {
|
||||
InspectorResourceSubscription,
|
||||
ResourceSubscriptionStreamState,
|
||||
} from "../../../../../../core/mcp/types.js";
|
||||
import { ResourceControls } from "../../groups/ResourceControls/ResourceControls";
|
||||
import type { ListPaginationControlsProps } from "../../elements/ListPaginationControls/ListPaginationControls";
|
||||
import { ResourcePreviewPanel } from "../../groups/ResourcePreviewPanel/ResourcePreviewPanel";
|
||||
|
|
@ -32,6 +36,14 @@ export interface ResourcesScreenProps {
|
|||
resources: Resource[];
|
||||
templates: ResourceTemplate[];
|
||||
subscriptions: InspectorResourceSubscription[];
|
||||
/**
|
||||
* Modern-era `subscriptions/listen` stream state (#1630). On the modern era
|
||||
* the Subscriptions section shows a stream-status badge and a header dot;
|
||||
* `active: false` (the legacy default) renders neither.
|
||||
*/
|
||||
subscriptionStreamState?: ResourceSubscriptionStreamState;
|
||||
/** Negotiated protocol era; gates the modern subscription stream chrome. */
|
||||
protocolEra?: ProtocolEra;
|
||||
readState?: ReadResourceState;
|
||||
ui: ResourcesUiState;
|
||||
listChanged: boolean;
|
||||
|
|
@ -137,6 +149,8 @@ export function ResourcesScreen({
|
|||
resources,
|
||||
templates,
|
||||
subscriptions,
|
||||
subscriptionStreamState,
|
||||
protocolEra,
|
||||
readState,
|
||||
ui,
|
||||
listChanged,
|
||||
|
|
@ -291,6 +305,8 @@ export function ResourcesScreen({
|
|||
templates={templates}
|
||||
subscriptions={subscriptions}
|
||||
subscriptionsSupported={subscriptionsSupported}
|
||||
subscriptionStreamState={subscriptionStreamState}
|
||||
protocolEra={protocolEra}
|
||||
selectedUri={selectedResourceUri}
|
||||
selectedTemplateUri={selectedTemplateUri}
|
||||
searchText={search}
|
||||
|
|
|
|||
Loading…
Reference in a new issue