@parall/sdk 1.31.0 → 1.32.1
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/client.d.ts +36 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +167 -37
- package/dist/constants.d.ts +20 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +230 -38
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/types.d.ts +153 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/ws.d.ts +3 -3
- package/dist/ws.d.ts.map +1 -1
- package/dist/ws.js +12 -7
- package/package.json +1 -1
- package/src/client.ts +764 -181
- package/src/constants.ts +292 -88
- package/src/index.ts +7 -1
- package/src/types.ts +254 -20
- package/src/ws.ts +26 -11
package/src/types.ts
CHANGED
|
@@ -104,15 +104,22 @@ export interface TransferChatOwnershipRequest {
|
|
|
104
104
|
export interface UnreadEntry {
|
|
105
105
|
count: number;
|
|
106
106
|
mentions: number;
|
|
107
|
+
since?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface ThreadUnreadEntry {
|
|
111
|
+
unread: number;
|
|
112
|
+
total: number;
|
|
113
|
+
since: string | null;
|
|
107
114
|
}
|
|
108
115
|
|
|
109
116
|
export type MessageType =
|
|
110
117
|
| 'text'
|
|
111
|
-
| 'file'
|
|
112
|
-
| 'tool_call'
|
|
113
|
-
| 'tool_result'
|
|
114
|
-
| 'approval_card'
|
|
115
|
-
| 'state_delta'
|
|
118
|
+
| 'file' // deprecated: attachments are now schema-level on Message
|
|
119
|
+
| 'tool_call' // deprecated: use AgentStep
|
|
120
|
+
| 'tool_result' // deprecated: use AgentStep
|
|
121
|
+
| 'approval_card' // deprecated: use 'card' with card_type='approval'
|
|
122
|
+
| 'state_delta' // deprecated: use AgentStep
|
|
116
123
|
| 'card'
|
|
117
124
|
| 'system';
|
|
118
125
|
|
|
@@ -197,7 +204,13 @@ export type CardContent =
|
|
|
197
204
|
| ApprovalCardContent
|
|
198
205
|
| { card_type: string; entity_id?: string; data?: Record<string, unknown> };
|
|
199
206
|
|
|
200
|
-
export type AgentState =
|
|
207
|
+
export type AgentState =
|
|
208
|
+
| 'thinking'
|
|
209
|
+
| 'tool_calling'
|
|
210
|
+
| 'streaming'
|
|
211
|
+
| 'waiting_approval'
|
|
212
|
+
| 'completed'
|
|
213
|
+
| 'error';
|
|
201
214
|
|
|
202
215
|
export interface StateDeltaContent {
|
|
203
216
|
state: AgentState;
|
|
@@ -317,6 +330,9 @@ export interface Organization {
|
|
|
317
330
|
created_at: string;
|
|
318
331
|
/** Per-member flag: true when the user has dismissed the onboarding popup for this org. */
|
|
319
332
|
onboarding_dismissed: boolean;
|
|
333
|
+
/** Caller's membership role in this org (owner/admin/member). Present on the
|
|
334
|
+
* GET /orgs list response; omitted on single-org fetches that don't join membership. */
|
|
335
|
+
role?: OrgMemberRole;
|
|
320
336
|
}
|
|
321
337
|
|
|
322
338
|
export interface OrgInviteCode {
|
|
@@ -375,6 +391,7 @@ export interface OrgInviteLink {
|
|
|
375
391
|
org_id: string;
|
|
376
392
|
token: string;
|
|
377
393
|
require_approval: boolean;
|
|
394
|
+
expires_at: string;
|
|
378
395
|
created_at: string;
|
|
379
396
|
regenerated_at: string;
|
|
380
397
|
}
|
|
@@ -675,7 +692,14 @@ export interface UpdateAgentRequest {
|
|
|
675
692
|
|
|
676
693
|
// ---- Machine types ----
|
|
677
694
|
|
|
678
|
-
export type MachineStatus =
|
|
695
|
+
export type MachineStatus =
|
|
696
|
+
| 'provisioning'
|
|
697
|
+
| 'starting'
|
|
698
|
+
| 'restarting'
|
|
699
|
+
| 'running'
|
|
700
|
+
| 'stopped'
|
|
701
|
+
| 'error'
|
|
702
|
+
| 'terminated';
|
|
679
703
|
|
|
680
704
|
export interface Machine {
|
|
681
705
|
id: string;
|
|
@@ -863,6 +887,13 @@ export interface MachineUpdateData {
|
|
|
863
887
|
reason?: string;
|
|
864
888
|
}
|
|
865
889
|
|
|
890
|
+
export interface MachineClipInstallData {
|
|
891
|
+
clip_id: string;
|
|
892
|
+
alias: string;
|
|
893
|
+
source_ref: string;
|
|
894
|
+
version?: string;
|
|
895
|
+
}
|
|
896
|
+
|
|
866
897
|
export interface AgentNewSessionData {
|
|
867
898
|
previous_session_id?: string;
|
|
868
899
|
}
|
|
@@ -928,8 +959,20 @@ export interface AvatarUploadResponse {
|
|
|
928
959
|
|
|
929
960
|
export type TaskStatus = 'todo' | 'in_progress' | 'in_review' | 'done' | 'canceled';
|
|
930
961
|
export type TaskPriority = 'high' | 'normal' | 'low';
|
|
931
|
-
export type TaskRelationTargetType =
|
|
932
|
-
|
|
962
|
+
export type TaskRelationTargetType =
|
|
963
|
+
| 'task'
|
|
964
|
+
| 'message'
|
|
965
|
+
| 'chat'
|
|
966
|
+
| 'agent_session'
|
|
967
|
+
| 'wiki_changeset';
|
|
968
|
+
export type TaskRelationType =
|
|
969
|
+
| 'blocks'
|
|
970
|
+
| 'related'
|
|
971
|
+
| 'duplicate'
|
|
972
|
+
| 'source'
|
|
973
|
+
| 'reference'
|
|
974
|
+
| 'discussion'
|
|
975
|
+
| 'execution';
|
|
933
976
|
|
|
934
977
|
export interface Task {
|
|
935
978
|
id: string;
|
|
@@ -1096,6 +1139,8 @@ export interface Schedule {
|
|
|
1096
1139
|
attached_to_uri: string | null;
|
|
1097
1140
|
name: string;
|
|
1098
1141
|
description: string;
|
|
1142
|
+
attachment_ids: string[];
|
|
1143
|
+
attachments?: Attachment[];
|
|
1099
1144
|
spec_type: ScheduleSpecType;
|
|
1100
1145
|
cron_expr: string | null;
|
|
1101
1146
|
interval_seconds: number | null;
|
|
@@ -1124,6 +1169,8 @@ export interface ScheduleRun {
|
|
|
1124
1169
|
status: ScheduleRunStatus;
|
|
1125
1170
|
fired_description: string | null;
|
|
1126
1171
|
fired_attached_uri: string | null;
|
|
1172
|
+
fired_attachment_ids: string[];
|
|
1173
|
+
fired_attachments?: Attachment[];
|
|
1127
1174
|
error: string | null;
|
|
1128
1175
|
created_at: string;
|
|
1129
1176
|
}
|
|
@@ -1133,6 +1180,7 @@ export interface CreateScheduleInput {
|
|
|
1133
1180
|
description: string;
|
|
1134
1181
|
target_ids: string[];
|
|
1135
1182
|
attached_to_uri?: string;
|
|
1183
|
+
attachment_ids?: string[];
|
|
1136
1184
|
spec_type: ScheduleSpecType;
|
|
1137
1185
|
cron_expr?: string;
|
|
1138
1186
|
interval_seconds?: number;
|
|
@@ -1152,6 +1200,9 @@ export interface UpdateScheduleInput {
|
|
|
1152
1200
|
attached_to_uri?: string;
|
|
1153
1201
|
/** Explicitly clear attached_to_uri. Server honors this over `attached_to_uri`. */
|
|
1154
1202
|
attached_to_uri_clear?: boolean;
|
|
1203
|
+
attachment_ids?: string[];
|
|
1204
|
+
/** Explicitly clear attachment_ids. Server honors this over `attachment_ids`. */
|
|
1205
|
+
attachment_ids_clear?: boolean;
|
|
1155
1206
|
cron_expr?: string;
|
|
1156
1207
|
interval_seconds?: number;
|
|
1157
1208
|
run_at?: string;
|
|
@@ -1631,7 +1682,23 @@ export interface ChatCreatedData extends Chat {}
|
|
|
1631
1682
|
|
|
1632
1683
|
export interface ChatUpdateData {
|
|
1633
1684
|
chat_id: string;
|
|
1634
|
-
changes: Partial<
|
|
1685
|
+
changes: Partial<
|
|
1686
|
+
Pick<
|
|
1687
|
+
Chat,
|
|
1688
|
+
| 'name'
|
|
1689
|
+
| 'avatar_url'
|
|
1690
|
+
| 'description'
|
|
1691
|
+
| 'visibility'
|
|
1692
|
+
| 'agent_routing_mode'
|
|
1693
|
+
| 'smart_routing_strategy'
|
|
1694
|
+
| 'smart_routing_agent_id'
|
|
1695
|
+
| 'last_message_at'
|
|
1696
|
+
| 'last_message_preview'
|
|
1697
|
+
| 'last_message_sender'
|
|
1698
|
+
| 'archived_at'
|
|
1699
|
+
| 'deleted_at'
|
|
1700
|
+
>
|
|
1701
|
+
>;
|
|
1635
1702
|
}
|
|
1636
1703
|
|
|
1637
1704
|
export interface ChatDeletedData {
|
|
@@ -1736,7 +1803,7 @@ export interface AgentSessionDB {
|
|
|
1736
1803
|
id: string;
|
|
1737
1804
|
agent_id: string;
|
|
1738
1805
|
org_id: string;
|
|
1739
|
-
status: string;
|
|
1806
|
+
status: string; // open | closed | failed | cancelled | superseded
|
|
1740
1807
|
runtime_type: string;
|
|
1741
1808
|
runtime_key: string | null;
|
|
1742
1809
|
runtime_lane_key: string;
|
|
@@ -1832,6 +1899,7 @@ export interface Comment {
|
|
|
1832
1899
|
export interface CreateCommentRequest {
|
|
1833
1900
|
target_uri: string;
|
|
1834
1901
|
body: string;
|
|
1902
|
+
parent_id?: string;
|
|
1835
1903
|
}
|
|
1836
1904
|
|
|
1837
1905
|
export interface UpdateCommentRequest {
|
|
@@ -1851,9 +1919,14 @@ export interface CommentDeletedData {
|
|
|
1851
1919
|
// ============================================================
|
|
1852
1920
|
|
|
1853
1921
|
export type InboxItemType =
|
|
1854
|
-
| 'mention'
|
|
1855
|
-
| '
|
|
1856
|
-
| '
|
|
1922
|
+
| 'mention'
|
|
1923
|
+
| 'task_assign'
|
|
1924
|
+
| 'task_update'
|
|
1925
|
+
| 'task_comment'
|
|
1926
|
+
| 'approval_request'
|
|
1927
|
+
| 'agent_alert'
|
|
1928
|
+
| 'invitation'
|
|
1929
|
+
| 'schedule_fire'
|
|
1857
1930
|
| 'thread_reply';
|
|
1858
1931
|
|
|
1859
1932
|
export interface InboxItem {
|
|
@@ -1885,8 +1958,15 @@ export interface InboxItem {
|
|
|
1885
1958
|
// Dispatch Types (agent event delivery)
|
|
1886
1959
|
// ============================================================
|
|
1887
1960
|
|
|
1888
|
-
export type DispatchEventType =
|
|
1889
|
-
|
|
1961
|
+
export type DispatchEventType =
|
|
1962
|
+
| 'message'
|
|
1963
|
+
| 'task_assign'
|
|
1964
|
+
| 'task_update'
|
|
1965
|
+
| 'task_comment'
|
|
1966
|
+
| 'wiki_comment'
|
|
1967
|
+
| 'schedule.fire'
|
|
1968
|
+
| 'approval_decided';
|
|
1969
|
+
export type DispatchStatus = 'pending' | 'received' | 'acked';
|
|
1890
1970
|
export type DispatchDeliveryReason = 'mention' | 'watcher' | 'assignee' | 'creator';
|
|
1891
1971
|
|
|
1892
1972
|
export interface DispatchEvent {
|
|
@@ -1919,6 +1999,16 @@ export interface DispatchEvent {
|
|
|
1919
1999
|
|
|
1920
2000
|
export type DispatchNewData = DispatchEvent;
|
|
1921
2001
|
|
|
2002
|
+
export interface DispatchReceivedData {
|
|
2003
|
+
agent_id: string;
|
|
2004
|
+
event_type: string;
|
|
2005
|
+
source_type: string;
|
|
2006
|
+
source_id: string;
|
|
2007
|
+
chat_id?: string | null;
|
|
2008
|
+
task_id?: string | null;
|
|
2009
|
+
org_id: string;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
1922
2012
|
export type InboxNewData = InboxItem;
|
|
1923
2013
|
|
|
1924
2014
|
export interface InboxUpdateData {
|
|
@@ -1950,7 +2040,7 @@ export interface NotificationAlertData {
|
|
|
1950
2040
|
}
|
|
1951
2041
|
|
|
1952
2042
|
export type WsEventMap = {
|
|
1953
|
-
|
|
2043
|
+
hello: HelloData;
|
|
1954
2044
|
'message.new': MessageNewData;
|
|
1955
2045
|
'message.patch': MessagePatchData;
|
|
1956
2046
|
'message.edit': MessageEditData;
|
|
@@ -1962,8 +2052,8 @@ export type WsEventMap = {
|
|
|
1962
2052
|
'approval.update': ApprovalUpdateData; // deprecated, kept for backward compat
|
|
1963
2053
|
'card.update': CardUpdateData;
|
|
1964
2054
|
'recovery.overflow': RecoveryOverflowData;
|
|
1965
|
-
|
|
1966
|
-
|
|
2055
|
+
watching: WatchingData;
|
|
2056
|
+
pong: { ts: number };
|
|
1967
2057
|
'membership.changed': MembershipChangedData;
|
|
1968
2058
|
'task.created': TaskCreatedData;
|
|
1969
2059
|
'task.updated': TaskUpdatedData;
|
|
@@ -1997,6 +2087,7 @@ export type WsEventMap = {
|
|
|
1997
2087
|
'inbox.bulk_update': InboxBulkUpdateData;
|
|
1998
2088
|
'read_position.updated': ReadPositionUpdateData;
|
|
1999
2089
|
'dispatch.new': DispatchNewData;
|
|
2090
|
+
'dispatch.received': DispatchReceivedData;
|
|
2000
2091
|
'schedule.created': ScheduleCreatedData;
|
|
2001
2092
|
'schedule.updated': ScheduleUpdatedData;
|
|
2002
2093
|
'schedule.deleted': ScheduleDeletedData;
|
|
@@ -2014,6 +2105,10 @@ export type WsEventMap = {
|
|
|
2014
2105
|
'machine.stop': MachineStopData;
|
|
2015
2106
|
'machine.filesystem.browse': MachineFilesystemBrowseData;
|
|
2016
2107
|
'machine.update': MachineUpdateData;
|
|
2108
|
+
'machine.clip.install': MachineClipInstallData;
|
|
2109
|
+
'clip.installed': ClipInstalledData;
|
|
2110
|
+
'clip.removed': ClipRemovedData;
|
|
2111
|
+
'clip.updated': ClipUpdatedData;
|
|
2017
2112
|
'agent.new_session': AgentNewSessionData;
|
|
2018
2113
|
};
|
|
2019
2114
|
|
|
@@ -2285,7 +2380,17 @@ export interface CreditWallet {
|
|
|
2285
2380
|
export interface CreditTransaction {
|
|
2286
2381
|
id: string;
|
|
2287
2382
|
org_id: string;
|
|
2288
|
-
type:
|
|
2383
|
+
type:
|
|
2384
|
+
| 'topup'
|
|
2385
|
+
| 'auto_reload'
|
|
2386
|
+
| 'llm_deduct'
|
|
2387
|
+
| 'compute_deduct'
|
|
2388
|
+
| 'compute_hold'
|
|
2389
|
+
| 'compute_settle'
|
|
2390
|
+
| 'adjustment'
|
|
2391
|
+
| 'refund'
|
|
2392
|
+
| 'grant'
|
|
2393
|
+
| 'grant_expire';
|
|
2289
2394
|
amount: number;
|
|
2290
2395
|
balance_after: number;
|
|
2291
2396
|
grant_id: string | null;
|
|
@@ -2442,3 +2547,132 @@ export interface BillingMachineStoppedEvent {
|
|
|
2442
2547
|
export interface BillingInsufficientEvent {
|
|
2443
2548
|
org_id: string;
|
|
2444
2549
|
}
|
|
2550
|
+
|
|
2551
|
+
// ============================================================
|
|
2552
|
+
// Clip Types
|
|
2553
|
+
// ============================================================
|
|
2554
|
+
|
|
2555
|
+
export type ClipSourceType = 'registry' | 'custom' | 'builtin';
|
|
2556
|
+
export type ClipStatus = 'active' | 'disabled';
|
|
2557
|
+
|
|
2558
|
+
export interface Clip {
|
|
2559
|
+
id: string;
|
|
2560
|
+
org_id: string;
|
|
2561
|
+
alias: string;
|
|
2562
|
+
name: string;
|
|
2563
|
+
description: string | null;
|
|
2564
|
+
manifest: Record<string, unknown>;
|
|
2565
|
+
source_type: ClipSourceType;
|
|
2566
|
+
source_ref: string | null;
|
|
2567
|
+
version: string | null;
|
|
2568
|
+
status: ClipStatus;
|
|
2569
|
+
created_by: string | null;
|
|
2570
|
+
/** Registry clip that reconciles onto every org machine, including machines
|
|
2571
|
+
* that join after creation. Targeted installs leave this false and persist
|
|
2572
|
+
* per-machine pending clip_instances instead. */
|
|
2573
|
+
install_on_all_machines: boolean;
|
|
2574
|
+
created_at: string;
|
|
2575
|
+
updated_at: string;
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
export interface AgentClip {
|
|
2579
|
+
agent_id: string;
|
|
2580
|
+
clip_id: string;
|
|
2581
|
+
config: Record<string, unknown> | null;
|
|
2582
|
+
created_at: string;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
export interface CreateClipRequest {
|
|
2586
|
+
alias: string;
|
|
2587
|
+
name: string;
|
|
2588
|
+
description?: string;
|
|
2589
|
+
manifest: Record<string, unknown>;
|
|
2590
|
+
source_type?: ClipSourceType;
|
|
2591
|
+
source_ref?: string;
|
|
2592
|
+
version?: string;
|
|
2593
|
+
target_machine_ids?: string[];
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
export interface UpdateClipRequest {
|
|
2597
|
+
name?: string;
|
|
2598
|
+
description?: string;
|
|
2599
|
+
manifest?: Record<string, unknown>;
|
|
2600
|
+
status?: ClipStatus;
|
|
2601
|
+
version?: string;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
export interface BindAgentClipRequest {
|
|
2605
|
+
clip_id: string;
|
|
2606
|
+
config?: Record<string, unknown>;
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
export interface InvokeClipRequest {
|
|
2610
|
+
alias: string;
|
|
2611
|
+
command: string;
|
|
2612
|
+
input?: unknown;
|
|
2613
|
+
timeout_ms?: number;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
export interface InvokeClipResponse {
|
|
2617
|
+
output: unknown;
|
|
2618
|
+
error: string | null;
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
export type ClipInstanceStatus = 'pending' | 'installed' | 'running' | 'stopped' | 'error';
|
|
2622
|
+
|
|
2623
|
+
export interface ClipInstance {
|
|
2624
|
+
id: string;
|
|
2625
|
+
clip_id: string;
|
|
2626
|
+
machine_id: string | null;
|
|
2627
|
+
status: ClipInstanceStatus;
|
|
2628
|
+
version: string | null;
|
|
2629
|
+
error_msg: string | null;
|
|
2630
|
+
last_seen: string | null;
|
|
2631
|
+
created_at: string;
|
|
2632
|
+
updated_at: string;
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
export interface OnlineClipInfo {
|
|
2636
|
+
alias: string;
|
|
2637
|
+
name: string;
|
|
2638
|
+
version: string;
|
|
2639
|
+
commands: Array<{ name: string; description: string }>;
|
|
2640
|
+
provider_name: string;
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
// Durable install reconcile — a registry clip the machine should install.
|
|
2644
|
+
export interface MachineClipInstall {
|
|
2645
|
+
clip_id: string;
|
|
2646
|
+
alias: string;
|
|
2647
|
+
source_ref?: string;
|
|
2648
|
+
version?: string;
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
// Pinix registry catalog clip info (from GET /clip/v1/registry/clips,
|
|
2652
|
+
// which proxies the public Pinix registry GET /search).
|
|
2653
|
+
export interface RegistryCommandInfo {
|
|
2654
|
+
name: string;
|
|
2655
|
+
description: string;
|
|
2656
|
+
input?: string;
|
|
2657
|
+
output?: string;
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
export interface RegistryClipInfo {
|
|
2661
|
+
name: string; // @scope/name (canonical package id)
|
|
2662
|
+
package: string; // @scope/name (alias derivation + install source_ref)
|
|
2663
|
+
version: string;
|
|
2664
|
+
type: string; // registry package type (e.g. "clip")
|
|
2665
|
+
description?: string;
|
|
2666
|
+
domain?: string;
|
|
2667
|
+
author?: string;
|
|
2668
|
+
commands: RegistryCommandInfo[];
|
|
2669
|
+
dependencies: string[];
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
// Clip WS event data types
|
|
2673
|
+
export type ClipInstalledData = Clip;
|
|
2674
|
+
export type ClipUpdatedData = Clip;
|
|
2675
|
+
export interface ClipRemovedData {
|
|
2676
|
+
clip_id: string;
|
|
2677
|
+
org_id: string;
|
|
2678
|
+
}
|
package/src/ws.ts
CHANGED
|
@@ -5,9 +5,9 @@ export type WsEventType = keyof WsEventMap;
|
|
|
5
5
|
export type WsEventHandler<T extends WsEventType> = (data: WsEventMap[T], seq?: number) => void;
|
|
6
6
|
|
|
7
7
|
export type WsClientEventMap = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
ping: { ts: number };
|
|
9
|
+
typing: { chat_id: string; thread_root_id: string | null; action: 'start' | 'stop' };
|
|
10
|
+
watch: { chat_ids: string[] };
|
|
11
11
|
'agent.heartbeat': { session_id: string; telemetry?: Record<string, unknown> };
|
|
12
12
|
};
|
|
13
13
|
|
|
@@ -26,10 +26,10 @@ export interface ParallWsOptions {
|
|
|
26
26
|
|
|
27
27
|
function isRetryableNetworkError(err: unknown): boolean {
|
|
28
28
|
return (
|
|
29
|
-
err instanceof Error
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
err instanceof Error &&
|
|
30
|
+
err.name === 'ApiError' &&
|
|
31
|
+
'status' in err &&
|
|
32
|
+
(err as { status?: unknown }).status === 0
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -39,7 +39,11 @@ function isBrowserRuntime(): boolean {
|
|
|
39
39
|
|
|
40
40
|
export class ParallWs {
|
|
41
41
|
private ws: WebSocket | null = null;
|
|
42
|
-
private options: ParallWsOptions & {
|
|
42
|
+
private options: ParallWsOptions & {
|
|
43
|
+
reconnect: boolean;
|
|
44
|
+
reconnectInterval: number;
|
|
45
|
+
maxReconnectInterval: number;
|
|
46
|
+
};
|
|
43
47
|
private listeners = new Map<string, Set<WsEventHandler<WsEventType>>>();
|
|
44
48
|
private stateListeners = new Set<(state: WsConnectionState) => void>();
|
|
45
49
|
private heartbeatTimer: ReturnType<typeof setInterval> | null = null;
|
|
@@ -115,7 +119,11 @@ export class ParallWs {
|
|
|
115
119
|
ws.onclose = null;
|
|
116
120
|
ws.onopen = null;
|
|
117
121
|
ws.onerror = null;
|
|
118
|
-
try {
|
|
122
|
+
try {
|
|
123
|
+
ws.close();
|
|
124
|
+
} catch {
|
|
125
|
+
/* ignore */
|
|
126
|
+
}
|
|
119
127
|
// Only reconnect if this socket is still the active one.
|
|
120
128
|
// If connect() was called again, a newer socket owns the lifecycle.
|
|
121
129
|
if (ws !== this.ws) return;
|
|
@@ -271,7 +279,10 @@ export class ParallWs {
|
|
|
271
279
|
// event-loop stalls. Probe with a 5s timeout rather than force-
|
|
272
280
|
// reconnecting, so healthy connections that were merely timer-starved
|
|
273
281
|
// survive while genuinely dead sockets are caught quickly.
|
|
274
|
-
if (
|
|
282
|
+
if (
|
|
283
|
+
this.lastReceivedAt > 0 &&
|
|
284
|
+
Date.now() - this.lastReceivedAt > this.heartbeatIntervalMs * 1.5
|
|
285
|
+
) {
|
|
275
286
|
this.probeConnection();
|
|
276
287
|
return;
|
|
277
288
|
}
|
|
@@ -320,7 +331,11 @@ export class ParallWs {
|
|
|
320
331
|
this.ws.onopen = null;
|
|
321
332
|
this.ws.onerror = null;
|
|
322
333
|
this.ws.onmessage = null;
|
|
323
|
-
try {
|
|
334
|
+
try {
|
|
335
|
+
this.ws.close();
|
|
336
|
+
} catch {
|
|
337
|
+
/* ignore */
|
|
338
|
+
}
|
|
324
339
|
this.ws = null;
|
|
325
340
|
}
|
|
326
341
|
if (this.options.reconnect && !this.intentionalClose) {
|