Skip to content

Commit 1440c82

Browse files
committed
docs: document realtimeStabilizationDelayMs option in client documentation (#378)
1 parent 0b0a7cf commit 1440c82

File tree

3 files changed

+136
-14
lines changed

3 files changed

+136
-14
lines changed

pkgs/website/src/content/docs/build/starting-flows/typescript-client.mdx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ const pgflow = new PgflowClient(supabase);
5252

5353
## Starting and Waiting for Workflows
5454

55+
:::caution[Important: Realtime Stabilization Delay]
56+
When starting flows or retrieving runs, the client waits for a [`realtimeStabilizationDelayMs`](/reference/pgflow-client/#constructor) delay (default: `300ms`) after subscribing to Realtime channels. This works around a [known Supabase Realtime limitation](https://github.com/supabase/supabase-js/issues/1599) where backend routing isn't fully established when the SUBSCRIBED event is emitted.
57+
58+
**If you experience missed events or connection issues, increase this value to `400-500ms`:**
59+
60+
```typescript
61+
const pgflow = new PgflowClient(supabase, {
62+
realtimeStabilizationDelayMs: 400,
63+
});
64+
```
65+
66+
You can also disable the delay by setting it to `0`, though this may cause missed events in some environments:
67+
68+
```typescript
69+
const pgflow = new PgflowClient(supabase, {
70+
realtimeStabilizationDelayMs: 0,
71+
});
72+
```
73+
:::
74+
5575
The simplest pattern is to start a workflow and wait for it to complete:
5676

5777
```typescript
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
draft: false
3+
title: 'pgflow 0.7.3: Improved Supabase Realtime Connection Reliability'
4+
description: 'Configurable stabilization delay improves Realtime subscription reliability'
5+
date: 2025-11-17
6+
authors:
7+
- jumski
8+
tags:
9+
- bugfix
10+
- realtime
11+
- client
12+
featured: true
13+
---
14+
15+
import { Aside } from "@astrojs/starlight/components";
16+
17+
pgflow 0.7.3 introduces a configurable `realtimeStabilizationDelayMs` option that addresses a known Supabase Realtime limitation where backend routing isn't fully established when the SUBSCRIBED event is emitted.
18+
19+
## What's New
20+
21+
The TypeScript client now includes a `realtimeStabilizationDelayMs` configuration option (default: 300ms) that adds a delay after subscribing to Realtime channels. This works around a [known Supabase Realtime issue](https://github.com/supabase/supabase-js/issues/1599) where messages sent immediately after subscription confirmation may be missed because backend routing takes additional time to fully establish.
22+
23+
**When starting flows or retrieving runs**, the client waits for this stabilization period after receiving the SUBSCRIBED event, ensuring that all subsequent realtime events are properly received.
24+
25+
## Configuration
26+
27+
The default 300ms delay works reliably in most environments. If you experience missed events or connection issues, increase the delay to 400-500ms:
28+
29+
```typescript
30+
import { PgflowClient } from '@pgflow/client';
31+
32+
// Increase stabilization delay for unreliable connections
33+
const pgflow = new PgflowClient(supabase, {
34+
realtimeStabilizationDelayMs: 400,
35+
});
36+
```
37+
38+
You can also disable the delay by setting it to 0, though this may cause missed events in some environments:
39+
40+
```typescript
41+
// Disable delay (may cause missed events)
42+
const pgflow = new PgflowClient(supabase, {
43+
realtimeStabilizationDelayMs: 0,
44+
});
45+
```
46+
47+
See the [TypeScript Client documentation](/build/starting-flows/typescript-client/) and [PgflowClient API reference](/reference/pgflow-client/) for complete details.
48+
49+
## Upgrading
50+
51+
<Aside type="note" title="No Migration Required">
52+
This release only updates the TypeScript client package. No database migrations are needed.
53+
</Aside>
54+
55+
Follow the [update guide](/deploy/update-pgflow/) to upgrade your `@pgflow/client` dependency to 0.7.3.
56+
57+
---
58+
59+
**Questions or issues?** Join our [Discord community](https://www.pgflow.dev/discord/) or [open an issue on GitHub](https://github.com/pgflow-dev/pgflow/issues).

pkgs/website/src/content/docs/reference/pgflow-client.mdx

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,19 @@ Main client class for interacting with pgflow flows.
3535
### Constructor
3636

3737
```typescript
38-
new PgflowClient(supabase: SupabaseClient)
38+
new PgflowClient(supabase: SupabaseClient, options?: PgflowClientOptions)
3939
```
4040

41-
| Parameter | Type | Description |
42-
|-----------|------|-------------|
43-
| `supabase` | `SupabaseClient` | Initialized Supabase client instance |
41+
| Parameter | Type | Required | Description |
42+
|-----------|------|----------|-------------|
43+
| `supabase` | `SupabaseClient` | Yes | Initialized Supabase client instance |
44+
| `options` | `PgflowClientOptions` | No | Client configuration options |
45+
46+
**PgflowClientOptions:**
47+
48+
##### `realtimeStabilizationDelayMs` (`number`, default: `300`)
49+
50+
Delay in milliseconds after subscribing to Supabase Realtime channels. This addresses a known Supabase Realtime limitation where the backend routing isn't fully established when the SUBSCRIBED event is emitted. Increase to `400-500ms` if experiencing missed events or connection issues.
4451

4552
### Methods
4653

@@ -110,24 +117,35 @@ Represents a single flow execution instance.
110117
| `status` | `FlowRunStatus` | Current run status |
111118
| `input` | `object` | Flow input data |
112119
| `output` | `object \| null` | Flow output data (available when completed) |
120+
| `error` | `Error \| null` | Error object (available when failed) |
113121
| `error_message` | `string \| null` | Error message (available when failed) |
114122
| `started_at` | `Date \| null` | Timestamp when run started |
115-
| `completed_at` | `Date \| null` | Timestamp when run completed or failed |
123+
| `completed_at` | `Date \| null` | Timestamp when run completed |
124+
| `failed_at` | `Date \| null` | Timestamp when run failed |
125+
| `remaining_steps` | `number` | Number of steps remaining to complete |
116126

117127
### Methods
118128

119129
#### `waitForStatus(status, options?)`
120130

121-
Waits for the run to reach a specific status or one of multiple statuses.
131+
Waits for the run to reach a terminal status (completed or failed).
122132

123133
**Parameters:**
124134

125135
| Parameter | Type | Required | Description |
126136
|-----------|------|----------|-------------|
127-
| `status` | `FlowRunStatus \| FlowRunStatus[]` | Yes | Target status or array of statuses |
137+
| `status` | `'completed' \| 'failed'` | Yes | Target terminal status to wait for |
128138
| `options` | `object` | No | Wait options |
129-
| `options.timeoutMs` | `number` | No | Timeout in milliseconds |
130-
| `options.signal` | `AbortSignal` | No | Abort signal to cancel waiting |
139+
140+
**Wait options:**
141+
142+
##### `timeoutMs` (`number`, optional)
143+
144+
Timeout in milliseconds.
145+
146+
##### `signal` (`AbortSignal`, optional)
147+
148+
Abort signal to cancel waiting.
131149

132150
**Returns:** `Promise<FlowRun>` - Updated FlowRun instance
133151

@@ -149,6 +167,20 @@ Accesses a specific step within the flow run.
149167

150168
---
151169

170+
#### `hasStep(step_slug)`
171+
172+
Checks if a step exists in the flow run.
173+
174+
**Parameters:**
175+
176+
| Parameter | Type | Required | Description |
177+
|-----------|------|----------|-------------|
178+
| `step_slug` | `string` | Yes | Step identifier to check |
179+
180+
**Returns:** `boolean` - `true` if the step exists, `false` otherwise
181+
182+
---
183+
152184
#### `on(event, handler)`
153185

154186
Subscribes to run-level events.
@@ -209,27 +241,38 @@ Represents a single step within a flow run.
209241

210242
| Property | Type | Description |
211243
|----------|------|-------------|
244+
| `run_id` | `string` | Run identifier this step belongs to |
212245
| `step_slug` | `string` | Step identifier |
213246
| `status` | `FlowStepStatus` | Current step status |
214247
| `output` | `object \| null` | Step output data (available when completed) |
248+
| `error` | `Error \| null` | Error object (available when failed) |
215249
| `error_message` | `string \| null` | Error message (available when failed) |
216250
| `started_at` | `Date \| null` | Timestamp when step started |
217-
| `completed_at` | `Date \| null` | Timestamp when step completed or failed |
251+
| `completed_at` | `Date \| null` | Timestamp when step completed |
252+
| `failed_at` | `Date \| null` | Timestamp when step failed |
218253

219254
### Methods
220255

221256
#### `waitForStatus(status, options?)`
222257

223-
Waits for the step to reach a specific status or one of multiple statuses.
258+
Waits for the step to reach a specific status.
224259

225260
**Parameters:**
226261

227262
| Parameter | Type | Required | Description |
228263
|-----------|------|----------|-------------|
229-
| `status` | `FlowStepStatus \| FlowStepStatus[]` | Yes | Target status or array of statuses |
264+
| `status` | `'started' \| 'completed' \| 'failed'` | Yes | Target status to wait for |
230265
| `options` | `object` | No | Wait options |
231-
| `options.timeoutMs` | `number` | No | Timeout in milliseconds |
232-
| `options.signal` | `AbortSignal` | No | Abort signal to cancel waiting |
266+
267+
**Wait options:**
268+
269+
##### `timeoutMs` (`number`, optional)
270+
271+
Timeout in milliseconds.
272+
273+
##### `signal` (`AbortSignal`, optional)
274+
275+
Abort signal to cancel waiting.
233276

234277
**Returns:** `Promise<FlowStep>` - Updated FlowStep instance
235278

0 commit comments

Comments
 (0)