@@ -57,7 +57,7 @@ function createProtocol<P extends Protocol>(script: string) {
57
57
new Promise < P [ K ] [ 'out' ] > ( ( resolve , reject ) => {
58
58
let worker = new Worker ( script )
59
59
worker . onerror = reject
60
- worker . onmessage = event => resolve ( event . data . data )
60
+ worker . onmessage = event => resolve ( event . data )
61
61
worker . postMessage ( { command, args} )
62
62
} )
63
63
}
@@ -73,32 +73,59 @@ parallelDeterminant([[1, 2], [3, 4]]).then(
73
73
74
74
// WorkerScript.ts
75
75
76
- let handlers : {
77
- [ C in keyof MatrixProtocol ] : (
78
- ...args : MatrixProtocol [ C ] [ 'in' ]
79
- ) => MatrixProtocol [ C ] [ 'out' ]
80
- } = {
81
- determinant ( matrix ) {
82
- return determinant ( matrix )
83
- } ,
84
- [ 'dot-product' ] ( a , b ) {
85
- return dotProduct ( a , b )
86
- } ,
87
- invert ( matrix ) {
88
- return invert ( matrix )
76
+ type Data <
77
+ P extends Protocol ,
78
+ C extends keyof P = keyof P
79
+ > = C extends C
80
+ ? { command : C ; args : P [ C ] [ 'in' ] }
81
+ : never
82
+
83
+ function handle (
84
+ data : Data < MatrixProtocol >
85
+ ) : MatrixProtocol [ typeof data . command ] [ 'out' ] {
86
+ switch ( data . command ) {
87
+ case 'determinant' :
88
+ return determinant ( ...data . args )
89
+ case 'dot-product' :
90
+ return dotProduct ( ...data . args )
91
+ case 'invert' :
92
+ return invert ( ...data . args )
89
93
}
90
94
}
91
95
92
- onmessage = < C extends keyof MatrixProtocol > ( {
93
- data : { command, args}
94
- } : {
95
- data : { command : C ; args : MatrixProtocol [ C ] [ 'in' ] }
96
- } ) => {
97
- let handler = handlers [ command ]
98
- let result = handler ( ...args )
99
- postMessage ( result )
100
- }
96
+ onmessage = ( { data} ) => postMessage ( handle ( data ) )
101
97
102
98
declare function determinant ( matrix : Matrix ) : number
103
99
declare function dotProduct ( matrixA : Matrix , matrixB : Matrix ) : Matrix
104
100
declare function invert ( matrix : Matrix ) : Matrix
101
+
102
+ // 3. Use a mapped type (as in 「8.6.1 In the Browser: With Web Workers★」) to implement a typesafe message-passing protocol for NodeJS's `child_process`.
103
+
104
+ // MainThread.ts
105
+ import { fork } from 'child_process'
106
+
107
+ function createProtocolCP < P extends Protocol > ( script : string ) {
108
+ return < K extends keyof P > ( command : K ) => ( ...args : P [ K ] [ 'in' ] ) =>
109
+ new Promise < P [ K ] [ 'out' ] > ( ( resolve , reject ) => {
110
+ let child = fork ( script )
111
+ child . on ( 'error' , reject )
112
+ child . on ( 'message' , resolve )
113
+ child . send ( { command, args} )
114
+ } )
115
+ }
116
+
117
+ let runWithMatrixProtocolCP = createProtocolCP < MatrixProtocol > (
118
+ './ChildThread.js'
119
+ )
120
+ let parallelDeterminantCP = runWithMatrixProtocolCP ( 'determinant' )
121
+
122
+ parallelDeterminantCP ( [ [ 1 , 2 ] , [ 3 , 4 ] ] ) . then (
123
+ determinant => console . log ( determinant ) // -2
124
+ )
125
+
126
+ // ChildThread.ts
127
+
128
+ // type Data ...
129
+ // function handle ...
130
+
131
+ process . on ( 'message' , data => process . send ! ( handle ( data ) ) )
0 commit comments