1
- import { createOk , isErr , type Result , unwrapOk } from "option-t/plain_result" ;
2
1
import type {
3
2
NotFoundError ,
4
3
NotLoggedInError ,
5
4
NotMemberError ,
6
5
} from "@cosense/types/rest" ;
7
- import type {
8
- ProjectUpdatesStreamCommit ,
9
- ProjectUpdatesStreamEvent ,
10
- } from "./emit.ts" ;
11
6
import type { HTTPError } from "../../rest/responseIntoResult.ts" ;
12
7
import type { AbortError , NetworkError } from "../../rest/robustFetch.ts" ;
13
- import { getProjectId } from "./pull.ts" ;
14
- import { connect , disconnect } from "./socket.ts" ;
15
- import type { Socket } from "socket.io-client" ;
8
+ import type { ScrapboxSocket } from "./socket.ts" ;
9
+ import type { ListenEvents } from "./listen-events.ts" ;
16
10
17
11
export type {
18
12
ProjectUpdatesStreamCommit ,
19
13
ProjectUpdatesStreamEvent ,
20
- } from "./websocket-types .ts" ;
14
+ } from "./listen-events .ts" ;
21
15
22
16
export interface ListenStreamOptions {
23
- socket ?: Socket ;
17
+ signal ?: AbortSignal ;
18
+ once ?: boolean ;
24
19
}
25
20
26
21
export type ListenStreamError =
@@ -37,46 +32,21 @@ export type ListenStreamError =
37
32
* @param events 購読したいevent。配列で指定する
38
33
* @param options 使用したいSocketがあれば指定する
39
34
*/
40
- export async function * listenStream (
41
- project : string ,
42
- events : [ "commit" | "event" , ...( "commit" | "event" ) [ ] ] ,
35
+ export const listen = < EventName extends keyof ListenEvents > (
36
+ socket : ScrapboxSocket ,
37
+ event : EventName ,
38
+ listener : ListenEvents [ EventName ] ,
43
39
options ?: ListenStreamOptions ,
44
- ) : AsyncGenerator <
45
- Result <
46
- ProjectUpdatesStreamEvent | ProjectUpdatesStreamCommit ,
47
- ListenStreamError
48
- > ,
49
- void ,
50
- unknown
51
- > {
52
- const result = await getProjectId ( project ) ;
53
- if ( isErr ( result ) ) {
54
- yield result ;
55
- return ;
56
- }
57
- const projectId = unwrapOk ( result ) ;
40
+ ) : void => {
41
+ if ( options ?. signal ?. aborted ) return ;
58
42
59
- const injectedSocket = options ?. socket ;
60
- const result2 = await connect ( injectedSocket ) ;
61
- if ( isErr ( result2 ) ) throw new Error ( "Failed to connect to websocket" ) ;
62
- const socket = unwrapOk ( result2 ) ;
63
- const { request, response } = wrap ( socket ) ;
43
+ // deno-lint-ignore no-explicit-any
44
+ ( options ?. once ? socket . once : socket . on ) ( event , listener as any ) ;
64
45
65
- try {
66
- // 部屋に入って購読し始める
67
- await request ( "socket.io-request" , {
68
- method : "room:join" ,
69
- data : { projectId, pageId : null , projectUpdatesStream : true } ,
70
- } ) ;
71
-
72
- for await (
73
- const streamEvent of response (
74
- ...events . map ( ( event ) => `projectUpdatesStream:${ event } ` as const ) ,
75
- )
76
- ) {
77
- yield createOk ( streamEvent ) ;
78
- }
79
- } finally {
80
- if ( ! injectedSocket ) await disconnect ( socket ) ;
81
- }
82
- }
46
+ options ?. signal ?. addEventListener ?.(
47
+ "abort" ,
48
+ // deno-lint-ignore no-explicit-any
49
+ ( ) => socket . off ( event , listener as any ) ,
50
+ { once : true } ,
51
+ ) ;
52
+ } ;
0 commit comments