33/// <reference lib="dom" />
44
55import type { Socket } from "./socket.ts" ;
6- import type { DataOf , EventMap , ListenEventMap , ResponseOf } from "./types.ts" ;
6+ import {
7+ DataOf ,
8+ EventMap ,
9+ FailedResOf ,
10+ isPageCommitError ,
11+ ListenEventMap ,
12+ Result ,
13+ SuccessResOf ,
14+ TimeoutError ,
15+ UnexpectedError ,
16+ } from "./types.ts" ;
717export * from "./types.ts" ;
818export * from "./socket.ts" ;
919
@@ -12,12 +22,14 @@ export interface SocketOperator {
1222 event : EventName ,
1323 data : DataOf < EventName > ,
1424 ) => Promise <
15- EventName extends "cursor" ? void
16- : ResponseOf < "socket.io-request" > [ "data" ]
25+ Result <
26+ SuccessResOf < EventName > ,
27+ FailedResOf < EventName > | UnexpectedError | TimeoutError
28+ >
1729 > ;
1830 response : < EventName extends keyof ListenEventMap > (
1931 ...events : EventName [ ]
20- ) => AsyncGenerator < Parameters < ListenEventMap [ EventName ] > [ 0 ] , void , unknown > ;
32+ ) => AsyncGenerator < ListenEventMap [ EventName ] , void , unknown > ;
2133}
2234
2335export const wrap = (
@@ -28,34 +40,70 @@ export const wrap = (
2840 event : EventName ,
2941 data : DataOf < EventName > ,
3042 ) : Promise <
31- EventName extends "cursor" ? void
32- : ResponseOf < "socket.io-request" > [ "data" ]
43+ Result <
44+ SuccessResOf < EventName > ,
45+ FailedResOf < EventName > | UnexpectedError | TimeoutError
46+ >
3347 > => {
3448 let id : number | undefined ;
35- type ResolveType = EventName extends "cursor" ? void
36- : ResponseOf < "socket.io-request" > [ "data" ] ;
3749 return new Promise ( ( resolve , reject ) => {
3850 const onDisconnect = ( message : string ) => {
3951 clearTimeout ( id ) ;
4052 reject ( new Error ( message ) ) ;
4153 } ;
42- socket . emit ( event , data , ( response : ResponseOf < EventName > ) => {
43- clearTimeout ( id ) ;
44- socket . off ( "disconnect" , onDisconnect ) ;
45- if ( response . error ) {
54+ socket . emit (
55+ event ,
56+ data ,
57+ ( response : { data : SuccessResOf < EventName > } | { error : unknown } ) => {
58+ clearTimeout ( id ) ;
59+ socket . off ( "disconnect" , onDisconnect ) ;
60+ switch ( event ) {
61+ case "socket.io-request" :
62+ if ( "error" in response ) {
63+ if (
64+ typeof response . error === "object" && response . error &&
65+ "name" in response . error &&
66+ typeof response . error . name === "string" &&
67+ isPageCommitError ( { name : response . error . name } )
68+ ) {
69+ resolve ( { ok : false , value : response . error } ) ;
70+ } else {
71+ resolve ( {
72+ ok : false ,
73+ value : { name : "UnexpectedError" , value : response . error } ,
74+ } ) ;
75+ }
76+ } else if ( "data" in response ) {
77+ resolve ( { ok : true , value : response . data } ) ;
78+ }
79+ break ;
80+ case "cursor" :
81+ if ( "error" in response ) {
82+ resolve ( {
83+ ok : false ,
84+ value : { name : "UnexpectedError" , value : response . error } ,
85+ } ) ;
86+ } else if ( "data" in response ) {
87+ resolve ( { ok : true , value : response . data } ) ;
88+ }
89+ break ;
90+ }
4691 reject (
47- new Error ( JSON . stringify ( response . error ) ) ,
92+ new Error (
93+ 'Invalid response: missing "data" or "error" field' ,
94+ ) ,
4895 ) ;
49- }
50- if ( "data" in response ) {
51- resolve ( response ?. data as ResolveType ) ;
52- } else {
53- resolve ( undefined as ResolveType ) ;
54- }
55- } ) ;
96+ } ,
97+ ) ;
5698 id = setTimeout ( ( ) => {
5799 socket . off ( "disconnect" , onDisconnect ) ;
58- reject ( new Error ( `Timeout: exceeded ${ timeout } ms` ) ) ;
100+ resolve ( {
101+ ok : false ,
102+ value : {
103+ name : "TimeoutError" ,
104+ message : `Timeout: exceeded ${ timeout } ms` ,
105+ } ,
106+ } ) ;
59107 } , timeout ) ;
60108 socket . once ( "disconnect" , onDisconnect ) ;
61109 } ) ;
@@ -64,7 +112,7 @@ export const wrap = (
64112 async function * response < EventName extends keyof ListenEventMap > (
65113 ...events : EventName [ ]
66114 ) {
67- type Data = Parameters < ListenEventMap [ EventName ] > [ 0 ] ;
115+ type Data = ListenEventMap [ EventName ] ;
68116 let _resolve : ( ( data : Data ) => void ) | undefined ;
69117 const waitForEvent = ( ) => new Promise < Data > ( ( res ) => _resolve = res ) ;
70118 const resolve = ( data : Data ) => {
0 commit comments