1
1
import { PluginClient } from '@remixproject/plugin'
2
2
import { createClient } from '@remixproject/plugin-webview'
3
3
import EventManager from 'events'
4
- // @ts -ignore
5
- import { compile_program , createFileManager } from '@noir-lang/noir_wasm/default'
6
- import type { FileManager } from '@noir-lang/noir_wasm/dist/node/main'
7
- import pathModule from 'path'
8
4
import { DEFAULT_TOML_CONFIG } from '../actions/constants'
9
5
import NoirParser from './noirParser'
10
6
import { extractNameFromKey } from '@remix-ui/helper'
7
+ import axios from 'axios'
11
8
export class NoirPluginClient extends PluginClient {
12
9
public internalEvents : EventManager
13
- public fm : FileManager
14
10
public parser : NoirParser
15
11
16
12
constructor ( ) {
17
13
super ( )
18
14
this . methods = [ 'init' , 'parse' , 'compile' ]
19
15
createClient ( this )
20
16
this . internalEvents = new EventManager ( )
21
- this . fm = createFileManager ( '/' )
22
17
this . parser = new NoirParser ( )
23
18
this . onload ( )
24
19
}
@@ -37,14 +32,6 @@ export class NoirPluginClient extends PluginClient {
37
32
38
33
if ( ! nargoTomlExists ) {
39
34
await this . call ( 'fileManager' , 'writeFile' , 'Nargo.toml' , DEFAULT_TOML_CONFIG )
40
- const fileBytes = new TextEncoder ( ) . encode ( DEFAULT_TOML_CONFIG )
41
-
42
- await this . fm . writeFile ( 'Nargo.toml' , new Blob ( [ fileBytes ] ) . stream ( ) )
43
- } else {
44
- const nargoToml = await this . call ( 'fileManager' , 'readFile' , 'Nargo.toml' )
45
- const fileBytes = new TextEncoder ( ) . encode ( nargoToml )
46
-
47
- await this . fm . writeFile ( 'Nargo.toml' , new Blob ( [ fileBytes ] ) . stream ( ) )
48
35
}
49
36
}
50
37
@@ -55,17 +42,30 @@ export class NoirPluginClient extends PluginClient {
55
42
// @ts -ignore
56
43
this . call ( 'terminal' , 'log' , { type : 'log' , value : 'Compiling ' + path } )
57
44
await this . setupNargoToml ( )
58
- const program = await compile_program ( this . fm , null , this . logFn . bind ( this ) , this . debugFn . bind ( this ) )
59
- const filename = extractNameFromKey ( path )
60
- const outputPath = `build/${ filename . replace ( '.nr' , '.json' ) } `
61
-
62
- this . call ( 'fileManager' , 'writeFile' , outputPath , JSON . stringify ( program , null , 2 ) )
63
- this . internalEvents . emit ( 'noir_compiling_done' )
64
- this . emit ( 'statusChanged' , { key : 'succeed' , title : 'Noir circuit compiled successfully' , type : 'success' } )
65
45
// @ts -ignore
66
- this . call ( 'terminal' , 'log' , { type : 'log' , value : 'Compiled successfully' } )
46
+ const zippedProject : Blob = await this . call ( 'fileManager' , 'download' , '/' , false )
47
+ const formData = new FormData ( )
48
+
49
+ formData . append ( 'file' , zippedProject , `${ extractNameFromKey ( path ) } .zip` )
67
50
// @ts -ignore
68
- await this . call ( 'editor' , 'clearErrorMarkers' , [ path ] )
51
+ const response = await axios . post ( `${ BASE_URL } /compile` , formData )
52
+
53
+ if ( ! response . data || ! response . data . success ) {
54
+ this . internalEvents . emit ( 'noir_compiling_errored' , new Error ( 'Compilation failed' ) )
55
+ this . logFn ( 'Compilation failed' )
56
+ return
57
+ } else {
58
+ const { compiledJson, proverToml } = response . data
59
+
60
+ this . call ( 'fileManager' , 'writeFile' , 'build/program.json' , compiledJson )
61
+ this . call ( 'fileManager' , 'writeFile' , 'build/prover.toml' , proverToml )
62
+ this . internalEvents . emit ( 'noir_compiling_done' )
63
+ this . emit ( 'statusChanged' , { key : 'succeed' , title : 'Noir circuit compiled successfully' , type : 'success' } )
64
+ // @ts -ignore
65
+ this . debugFn ( 'Compiled successfully' )
66
+ // @ts -ignore
67
+ await this . call ( 'editor' , 'clearErrorMarkers' , [ path ] )
68
+ }
69
69
} catch ( e ) {
70
70
const regex = / ^ \s * ( \/ [ ^ : ] + ) : ( \d + ) : / gm;
71
71
const pathContent = await this . call ( 'fileManager' , 'readFile' , path )
@@ -109,57 +109,11 @@ export class NoirPluginClient extends PluginClient {
109
109
// @ts -ignore
110
110
await this . call ( 'editor' , 'addErrorMarker' , markers )
111
111
} else {
112
- await this . resolveDependencies ( path , content )
113
- const fileBytes = new TextEncoder ( ) . encode ( content )
114
-
115
- await this . fm . writeFile ( `${ path } ` , new Blob ( [ fileBytes ] ) . stream ( ) )
116
112
// @ts -ignore
117
113
await this . call ( 'editor' , 'clearErrorMarkers' , [ path ] )
118
114
}
119
115
}
120
116
121
- async resolveDependencies ( filePath : string , fileContent : string , parentPath : string = '' , visited : Record < string , string [ ] > = { } ) : Promise < void > {
122
- const imports = Array . from ( fileContent . matchAll ( / m o d \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * ( = \s * [ " ' ] ( .* ?) [ " ' ] ) ? \s * ; / g) , match => match [ 3 ] || match [ 1 ] ) ;
123
-
124
- for ( let dep of imports ) {
125
- if ( ! dep . endsWith ( '.nr' ) ) dep += '.nr'
126
- if ( visited [ filePath ] && visited [ filePath ] . includes ( parentPath ) ) return console . log ( 'circular dependency detected' )
127
- let dependencyContent = ''
128
- let path = dep . replace ( / ( \. \. \/ ) + / g, '' )
129
-
130
- // @ts -ignore
131
- const pathExists = await this . call ( 'fileManager' , 'exists' , path )
132
-
133
- if ( pathExists ) {
134
- dependencyContent = await this . call ( 'fileManager' , 'readFile' , path )
135
- } else {
136
- let relativePath = pathModule . resolve ( filePath . slice ( 0 , filePath . lastIndexOf ( '/' ) ) , dep )
137
-
138
- if ( relativePath . indexOf ( '/' ) === 0 ) relativePath = relativePath . slice ( 1 )
139
- // @ts -ignore
140
- const relativePathExists = await this . call ( 'fileManager' , 'exists' , relativePath )
141
-
142
- if ( relativePathExists ) {
143
- path = relativePath
144
- dependencyContent = await this . call ( 'fileManager' , 'readFile' , relativePath )
145
- visited [ filePath ] = visited [ filePath ] ? [ ...visited [ filePath ] , path ] : [ path ]
146
- // extract all mod imports from the dependency content
147
- const depImports = Array . from ( fileContent . matchAll ( / m o d \s + ( [ a - z A - Z _ ] [ a - z A - Z 0 - 9 _ ] * ) \s * ( = \s * [ " ' ] ( .* ?) [ " ' ] ) ? \s * ; / g) , match => match [ 3 ] || match [ 1 ] )
148
-
149
- if ( depImports . length > 0 && dependencyContent . length > 0 ) {
150
- const fileBytes = new TextEncoder ( ) . encode ( dependencyContent )
151
- const writePath = parentPath ? `${ filePath . replace ( '.nr' , '' ) } /${ dep } ` : path
152
-
153
- this . fm . writeFile ( writePath , new Blob ( [ fileBytes ] ) . stream ( ) )
154
- await this . resolveDependencies ( path , dependencyContent , filePath , visited )
155
- }
156
- } else {
157
- throw new Error ( `Dependency ${ dep } not found in Remix file system` )
158
- }
159
- }
160
- }
161
- }
162
-
163
117
logFn ( log ) {
164
118
this . call ( 'terminal' , 'log' , { type : 'error' , value : log } )
165
119
}
0 commit comments