| ... | @@ -639,6 +639,115 @@ describe("WsTransport", () => { | ... | @@ -639,6 +639,115 @@ describe("WsTransport", () => { |
| 639 | await transport.dispose(); | 639 | await transport.dispose(); |
| 640 | }); | 640 | }); |
| 641 | | 641 | |
| | 642 | it("re-subscribes live stream listeners after an explicit transport reconnect", async () => { |
| | 643 | const transport = createTransport("ws://localhost:3020"); |
| | 644 | const listener = vi.fn(); |
| | 645 | const onResubscribe = vi.fn(); |
| | 646 | |
| | 647 | const unsubscribe = transport.subscribe( |
| | 648 | (client) => client[WS_METHODS.subscribeServerLifecycle]({}), |
| | 649 | listener, |
| | 650 | { onResubscribe }, |
| | 651 | ); |
| | 652 | |
| | 653 | await waitFor(() => { |
| | 654 | expect(sockets).toHaveLength(1); |
| | 655 | }); |
| | 656 | |
| | 657 | const firstSocket = getSocket(); |
| | 658 | firstSocket.open(); |
| | 659 | |
| | 660 | await waitFor(() => { |
| | 661 | expect(firstSocket.sent).toHaveLength(1); |
| | 662 | }); |
| | 663 | |
| | 664 | const firstRequest = JSON.parse(firstSocket.sent[0] ?? "{}") as { id: string }; |
| | 665 | const firstEvent = { |
| | 666 | version: 1, |
| | 667 | sequence: 1, |
| | 668 | type: "welcome", |
| | 669 | payload: { |
| | 670 | environment: { |
| | 671 | environmentId: "environment-local", |
| | 672 | label: "Local environment", |
| | 673 | platform: { os: "darwin", arch: "arm64" }, |
| | 674 | serverVersion: "0.0.0-test", |
| | 675 | capabilities: { repositoryIdentity: true }, |
| | 676 | }, |
| | 677 | cwd: "/tmp/one", |
| | 678 | projectName: "one", |
| | 679 | }, |
| | 680 | }; |
| | 681 | |
| | 682 | firstSocket.serverMessage( |
| | 683 | JSON.stringify({ |
| | 684 | _tag: "Chunk", |
| | 685 | requestId: firstRequest.id, |
| | 686 | values: [firstEvent], |
| | 687 | }), |
| | 688 | ); |
| | 689 | |
| | 690 | await waitFor(() => { |
| | 691 | expect(listener).toHaveBeenLastCalledWith(firstEvent); |
| | 692 | }); |
| | 693 | |
| | 694 | await transport.reconnect(); |
| | 695 | |
| | 696 | await waitFor(() => { |
| | 697 | expect(sockets).toHaveLength(2); |
| | 698 | }); |
| | 699 | |
| | 700 | const secondSocket = getSocket(); |
| | 701 | expect(secondSocket).not.toBe(firstSocket); |
| | 702 | expect(firstSocket.readyState).toBe(MockWebSocket.CLOSED); |
| | 703 | |
| | 704 | secondSocket.open(); |
| | 705 | |
| | 706 | await waitFor(() => { |
| | 707 | expect(secondSocket.sent).toHaveLength(1); |
| | 708 | }); |
| | 709 | |
| | 710 | const secondRequest = JSON.parse(secondSocket.sent[0] ?? "{}") as { |
| | 711 | id: string; |
| | 712 | tag: string; |
| | 713 | }; |
| | 714 | expect(secondRequest.tag).toBe(WS_METHODS.subscribeServerLifecycle); |
| | 715 | expect(secondRequest.id).not.toBe(firstRequest.id); |
| | 716 | expect(onResubscribe).toHaveBeenCalledOnce(); |
| | 717 | |
| | 718 | const secondEvent = { |
| | 719 | version: 1, |
| | 720 | sequence: 2, |
| | 721 | type: "welcome", |
| | 722 | payload: { |
| | 723 | environment: { |
| | 724 | environmentId: "environment-local", |
| | 725 | label: "Local environment", |
| | 726 | platform: { os: "darwin", arch: "arm64" }, |
| | 727 | serverVersion: "0.0.0-test", |
| | 728 | capabilities: { repositoryIdentity: true }, |
| | 729 | }, |
| | 730 | cwd: "/tmp/two", |
| | 731 | projectName: "two", |
| | 732 | }, |
| | 733 | }; |
| | 734 | |
| | 735 | secondSocket.serverMessage( |
| | 736 | JSON.stringify({ |
| | 737 | _tag: "Chunk", |
| | 738 | requestId: secondRequest.id, |
| | 739 | values: [secondEvent], |
| | 740 | }), |
| | 741 | ); |
| | 742 | |
| | 743 | await waitFor(() => { |
| | 744 | expect(listener).toHaveBeenLastCalledWith(secondEvent); |
| | 745 | }); |
| | 746 | |
| | 747 | unsubscribe(); |
| | 748 | await transport.dispose(); |
| | 749 | }); |
| | 750 | |
| 642 | it("does not fire onResubscribe when the first stream attempt exits before any value", async () => { | 751 | it("does not fire onResubscribe when the first stream attempt exits before any value", async () => { |
| 643 | const transport = createTransport("ws://localhost:3020"); | 752 | const transport = createTransport("ws://localhost:3020"); |
| 644 | const listener = vi.fn(); | 753 | const listener = vi.fn(); |