1
1
/* eslint-disable @typescript-eslint/no-explicit-any */
2
2
3
- import { reactive } from "vue" ;
4
3
import { plainToInstance } from "class-transformer" ;
5
-
6
4
import {
5
+ JsMessage ,
7
6
DisplayConfirmationToCloseAllDocuments ,
8
7
DisplayConfirmationToCloseDocument ,
9
8
DisplayError ,
10
9
DisplayPanic ,
11
10
ExportDocument ,
12
- newDisplayFolderTreeStructure ,
11
+ newDisplayFolderTreeStructure as DisplayFolderTreeStructure ,
13
12
OpenDocumentBrowse ,
14
13
SaveDocument ,
15
14
SetActiveDocument ,
@@ -22,29 +21,16 @@ import {
22
21
UpdateScrollbars ,
23
22
UpdateWorkingColors ,
24
23
UpdateLayer ,
25
- JsMessage ,
26
- } from "./js-messages" ;
27
-
28
- type JsMessageCallback < T extends JsMessage > = ( responseData : T ) => void ;
29
- type JsMessageCallbackMap = {
30
- [ response : string ] : JsMessageCallback < any > | undefined ;
31
- } ;
24
+ } from "@/utilities/js-messages" ;
32
25
33
- const state = reactive ( {
34
- responseMap : { } as JsMessageCallbackMap ,
35
- } ) ;
36
-
37
- type Constructs < T > = new ( ...args : any [ ] ) => T ;
38
- type ConstructsJsMessage = Constructs < JsMessage > & typeof JsMessage ;
39
-
40
- const responseMap = {
26
+ const messageConstructors = {
41
27
UpdateCanvas,
42
28
UpdateScrollbars,
43
29
UpdateRulers,
44
30
ExportDocument,
45
31
SaveDocument,
46
32
OpenDocumentBrowse,
47
- DisplayFolderTreeStructure : newDisplayFolderTreeStructure ,
33
+ DisplayFolderTreeStructure,
48
34
UpdateLayer,
49
35
SetActiveTool,
50
36
SetActiveDocument,
@@ -57,39 +43,51 @@ const responseMap = {
57
43
DisplayConfirmationToCloseDocument,
58
44
DisplayConfirmationToCloseAllDocuments,
59
45
} as const ;
46
+ type JsMessageType = keyof typeof messageConstructors ;
47
+
48
+ type JsMessageCallback < T extends JsMessage > = ( messageData : T ) => void ;
49
+ type JsMessageCallbackMap = {
50
+ [ message : string ] : JsMessageCallback < any > | undefined ;
51
+ } ;
60
52
61
- export type JsMessageType = keyof typeof responseMap ;
53
+ type Constructs < T > = new ( ...args : any [ ] ) => T ;
54
+ type ConstructsJsMessage = Constructs < JsMessage > & typeof JsMessage ;
62
55
63
- function isJsMessageConstructor ( fn : ConstructsJsMessage | ( ( data : any ) => JsMessage ) ) : fn is ConstructsJsMessage {
64
- return ( fn as ConstructsJsMessage ) . jsMessageMarker !== undefined ;
65
- }
56
+ const subscriptions = { } as JsMessageCallbackMap ;
66
57
67
- export function handleJsMessage ( responseType : JsMessageType , responseData : any ) {
68
- const messageMaker = responseMap [ responseType ] ;
69
- let message : JsMessage ;
58
+ export function subscribeJsMessage < T extends JsMessage > ( messageType : Constructs < T > , callback : JsMessageCallback < T > ) {
59
+ subscriptions [ messageType . name ] = callback ;
60
+ }
70
61
71
- if ( ! messageMaker ) {
62
+ export function handleJsMessage ( messageType : JsMessageType , messageData : any ) {
63
+ const messageConstructor = messageConstructors [ messageType ] ;
64
+ if ( ! messageConstructor ) {
72
65
// eslint-disable-next-line no-console
73
- console . error ( `Received a Response of type "${ responseType } " but but was not able to parse the data.` ) ;
66
+ console . error ( `Received a frontend message of type "${ messageType } " but but was not able to parse the data.` ) ;
67
+ return ;
74
68
}
75
69
76
- if ( isJsMessageConstructor ( messageMaker ) ) {
77
- message = plainToInstance ( messageMaker , responseData [ responseType ] ) ;
70
+ // Messages with non-empty data are provided by wasm-bindgen as an object with one key as the message name, like: { NameOfThisMessage: { ... } }
71
+ // Messages with empty data are provided by wasm-bindgen as a string with the message name, like: "NameOfThisMessage"
72
+ const unwrappedMessageData = messageData [ messageType ] || { } ;
73
+
74
+ const isJsMessageConstructor = ( fn : ConstructsJsMessage | ( ( data : any ) => JsMessage ) ) : fn is ConstructsJsMessage => {
75
+ return ( fn as ConstructsJsMessage ) . jsMessageMarker !== undefined ;
76
+ } ;
77
+ let message : JsMessage ;
78
+ if ( isJsMessageConstructor ( messageConstructor ) ) {
79
+ message = plainToInstance ( messageConstructor , unwrappedMessageData ) ;
78
80
} else {
79
- message = messageMaker ( responseData [ responseType ] ) ;
81
+ message = messageConstructor ( unwrappedMessageData ) ;
80
82
}
81
83
82
84
// It is ok to use constructor.name even with minification since it is used consistently with registerHandler
83
- const callback = state . responseMap [ message . constructor . name ] ;
85
+ const callback = subscriptions [ message . constructor . name ] ;
84
86
85
87
if ( callback && message ) {
86
88
callback ( message ) ;
87
89
} else if ( message ) {
88
90
// eslint-disable-next-line no-console
89
- console . error ( `Received a Response of type "${ responseType } " but no handler was registered for it from the client.` ) ;
91
+ console . error ( `Received a frontend message of type "${ messageType } " but no handler was registered for it from the client.` ) ;
90
92
}
91
93
}
92
-
93
- export function subscribeJsMessage < T extends JsMessage > ( responseType : Constructs < T > , callback : JsMessageCallback < T > ) {
94
- state . responseMap [ responseType . name ] = callback ;
95
- }
0 commit comments