1
1
import json
2
2
import js
3
- dircache = {}
4
- objcache = {}
5
- funcache = {}
6
- procache = {}
7
-
8
- #Javascript's JSON Types for eliminating json.loads
9
- true = True
10
- false = False
11
- null = None
12
- undefined = None
13
3
14
4
def js_exec (code , * args ):
15
5
code = format (code , * args )
16
- return js .exec ('(async () => {\n ' + code + '\n })();' )
6
+ result = js .exec ('formatString((() => {\n ' + code + '\n })());' )
7
+ return json .loads (result )
17
8
18
- def py_exec (code , * args ):
19
- code = format (code , * args )
20
- return js .exec ('(async () => {\n return await global.mp_js_do_str(`\n ' + code + '\n `, true);\n })();' )
21
- exec = py_exec
9
+ def js_print (value ):
10
+ js .exec ('console.log(%s)' % (json .dumps (str (value ))))
11
+
12
+ py_print = print
13
+ print = js_print
22
14
23
15
def format (string , * args ):
24
16
for index , arg in enumerate (args ):
25
17
string = string .replace ('{%s}' % (index ), str (arg ))
26
18
return string
27
19
28
- #def print(value):
29
- # js.exec("""console.log(`%s`)""" % (str(value)))
30
-
31
20
def wait (promise ):
32
- procache [promise ._name ] = promise
33
- js_exec ("""
34
- global.promiseWaitInterval = setInterval(() => {
35
- const object = global.mpjscache['{0}'];
36
- //console.log(object)
37
- if (object && object.constructor !== Promise) {
38
- clearInterval(global.promiseWaitInterval);
39
- global.promiseWaitInterval = undefined;
40
- global.mp_js_do_str(`
41
- import js
42
- procache['{0}']._resolved = True
43
- procache['{0}']._value = JS('global.mpjscache["{0}"]')
44
- procache['{0}'] = procache['{0}']._value
45
- `);
46
- }
47
- }, 500);
48
- """ , promise ._name )
49
- exit
50
-
51
- def resolve (cache , name , value ):
52
- object = cache .get (name )
53
- if type (object ) == JSPromise :
54
- cache [name ] = object .resolve (value )
55
- else :
56
- cache [name ] = value
57
-
58
- async_id = 0
59
-
60
- def async_py (function ):
61
- def wrap (** kwargs ):
62
- code_string = function (** kwargs )
63
- for key in kwargs :
64
- if key not in code_string : continue
65
- async_id += 1
66
- asycache [async_id ] = kwargs [key ]
67
- code_string = code_string .replace (key , 'asycache[%s]' % (async_id ))
68
- exec (code_string )
69
- exit
70
- return wrap
21
+ while not promise ._resolved :
22
+ js .sleep (250 )
23
+ result = js_exec ('''
24
+ const object = {0};
25
+ if (object && object.constructor !== Promise) return true;
26
+ ''' , promise ._name )
27
+ if result : promise .resolve (JS (promise ._name ))
28
+ return promise ._value
71
29
72
30
class JSPromise ():
73
31
@@ -81,6 +39,9 @@ def resolve(self, value):
81
39
self ._value = value
82
40
return value
83
41
42
+ def wait (self ):
43
+ return wait (self )
44
+
84
45
class JSObject ():
85
46
86
47
def __init__ (self , name ):
@@ -94,25 +55,17 @@ def __len__(self):
94
55
95
56
def __dir__ (self ):
96
57
if not self ._name : return []
97
- js_exec ("""
98
- let keys = JSON.stringify(Object.keys({0}));
99
- global.mp_js_do_str(`
100
- import js
101
- dircache['{0}'] = ${keys}
102
- `);
103
- """ , self ._name )
104
- return dircache .get (self ._name , [])
58
+ return js_exec ('''
59
+ return Object.keys({0}));
60
+ ''' , self ._name )
105
61
106
62
def __getattr__ (self , key ):
107
63
name = self ._name + '.' + key if self ._name else key
108
- js_exec ("""
64
+ result = js_exec ('''
109
65
let object = {0};
110
66
if (object && object.constructor === Promise) {
111
- await global.mp_js_do_str(`
112
- import js
113
- objcache['{0}'] = JSPromise('{0}')
114
- `)
115
- object = await object;
67
+ object.then((object) => global.mpjscache['{0}'] = object);
68
+ return 'mpjspromiseobject:{0}';
116
69
}
117
70
try {
118
71
if (object && [Array, Object, Number, String, Boolean, Function, AsyncFunction].indexOf(object.constructor) < 0) throw Error('Not JSON Serializable');
@@ -121,83 +74,69 @@ def __getattr__(self, key):
121
74
}
122
75
else if (object && (object.constructor === Function || object.constructor === AsyncFunction)) {
123
76
delete global.mpjscache['{0}'];
124
- return global.mp_js_do_str(`
125
- import js
126
- resolve(objcache, '{0}', JSFunction('{0}'))
127
- `);
77
+ return 'mpjsfunctionobject:{0}';
128
78
}
129
- object = object !== undefined ? JSON.stringify(object) : 'null';
130
- return global.mp_js_do_str(`
131
- import js
132
- import json
133
- resolve(objcache, '{0}', ${object})
134
- `);
79
+ return object;
135
80
}
136
81
catch(error) {
137
- return global.mp_js_do_str(`
138
- import js
139
- resolve(objcache, '{0}', JSObject('{0}'))
140
- `);
82
+ return 'mpjsjavascriptobject:{0}';
141
83
}
142
- """ , name )
143
- return objcache .get (name )
84
+ ''' , name )
85
+ if type (result ) != str : return result
86
+ types = {'promise' : JSPromise , 'function' : JSFunction , 'javascript' : JSObject }
87
+ for object_type in types :
88
+ if 'mpjs' + object_type + 'object' in result :
89
+ result = types [object_type ](result .split (':' )[1 ])
90
+ break
91
+ return result
144
92
145
93
def __setattr__ (self , key , value ):
146
94
if not self ._name : return
147
95
value = json .dumps (value )
148
96
object_name = self ._name + '.' + key
149
- js_exec ("""
97
+ js_exec ('''
150
98
{0} = {1};
151
- """ . format ( object_name , value ) )
99
+ ''' , object_name , value )
152
100
153
101
def JSFunction (name ):
154
102
short_name = name .split ('.' )[- 1 ]
155
103
def function (* args ):
156
104
args = json .dumps (list (args ))
157
- js_exec ("""
105
+ cache_name = 'global.mpjscache' + ('.' + name if '.' not in name else json .dumps ([name ]))
106
+ result = js_exec ('''
158
107
let object;
159
108
if (global.mpjscache['{0}']) {
160
109
object = global.mpjscache['{0}'](...{1});
161
110
}
162
111
else if ({0}) {
163
112
object = {0}(...{1});
164
113
}
165
- //object = object(...{1});
166
114
global.mpjscache['{0}'] = object;
167
115
if (object && object.constructor === Promise) {
168
- await global.mp_js_do_str(`
169
- import js
170
- funcache['{0}'] = JSPromise('{0}')
171
- `)
172
- object = await object;
116
+ object.then((object) => global.mpjscache['{0}'] = object);
117
+ return 'mpjspromiseobject';
173
118
}
174
- global.mpjscache['{0}'] = object;
175
119
try {
176
120
if (object && [Array, Object, Number, String, Boolean, Function, AsyncFunction].indexOf(object.constructor) < 0) throw Error('Not JSON Serializable');
177
121
if (object && object.constructor === Object) for (let key in Object.keys(object)) {
178
122
if (object.indexOf(key) < 0) throw Error('Not a JSON');
179
123
}
180
124
else if (object && (object.constructor === Function || object.constructor === AsyncFunction)) {
181
- return global.mp_js_do_str(`
182
- import js
183
- resolve(funcache, '{0}', JSFunction('{0}'))
184
- `);
125
+ return 'mpjsfunctionobject';
185
126
}
186
- object = object !== undefined ? JSON.stringify(object) : 'null';
187
- return global.mp_js_do_str(`
188
- import js
189
- import json
190
- resolve(funcache, '{0}', ${object})
191
- `);
127
+ return object;
192
128
}
193
129
catch(error) {
194
- return global.mp_js_do_str(`
195
- import js
196
- resolve(funcache, '{0}', JSObject('global.mpjscache{2}'))
197
- `);
130
+ return 'mpjsjavascriptobject';
198
131
}
199
- """ , name , args , '.' + name if '.' not in name else '["%s"]' % (name ))
200
- return funcache .get (name )
132
+ ''' , name , args )
133
+ if type (result ) != str : return result
134
+ types = {'promise' : JSPromise , 'function' : JSFunction , 'javascript' : JSObject }
135
+ for object_type in types :
136
+ if 'mpjs' + object_type + 'object' in result :
137
+ result = types [object_type ](cache_name )
138
+ break
139
+ return result
201
140
return function
202
141
203
142
def JS (variable ):
@@ -208,15 +147,10 @@ def JS(variable):
208
147
#result = require('fs').readFileSync('./test.js').toString()
209
148
#print(result)
210
149
211
- #This code block is adaptable to Javascript's event loop
212
- async {
213
-
214
- require = JS ('require' )
215
- response = require ('node-fetch' )('https://github.com/' )
216
- response = await response
217
- print (response )
218
- result = response .text ()
219
- result = await result
220
- print (result )
150
+ #New API promise.wait(), now works without skipping event loop using emscripten_sleep, requires emterpreter
221
151
222
- } async ()
152
+ #require = JS('require')
153
+ #response = require('node-fetch')('https://github.com/').wait()
154
+ #print(response)
155
+ #result = response.text().wait()
156
+ #print(result)
0 commit comments