def setup_sleep(cls): """Setup JavaScript analog of ``sleep`` function. """ def jsext_sleep(amount): """Sleep the specified amount of time. """ time.sleep(amount) src = 'native function sleep(arg);' ext = PyV8.JSExtension('sleep/python', src, lambda _: jsext_sleep) return ext.name
def setup_print(cls): """Setup JavaScript analog of ``print`` statement. """ def jsext_print(*args): """Print values to stdout. """ sys.stdout.write(' '.join(map(str, args)) + '\n') src = 'native function print(arg);' ext = PyV8.JSExtension('print/python', src, lambda _: jsext_print) return ext.name
def get_extensions(self, pagedir, extra_files): ''' pagedir: 'pages-touch/index' ''' suffix = '/'.join(extra_files) name = JS_EXTENSION_NAME % {'pagedir': pagedir, 'suffix': suffix} ext = self.pageextensions.get(name) if ext is None: page_js = self.load_pagejs_data(pagedir, extra_files) ext = PyV8.JSExtension(name, page_js) self.pageextensions[name] = ext return name, ext
def transform_jsx(source, path=None): """ Transform the given JSX source into regular Javascript and return the generated source. Also compile it into a PyV8 object and create an extension to embed in future PyV8 contexts. """ log.debug("Transforming JSX for %r", path) if "lib/jsx" in PyV8.JSExtension.extensions: log.debug("JSX extension already loaded") else: with open(JSX_TRANSFORMER_PATH) as jsxf: jsx_transformer_js = jsxf.read() # Inject the `global` var which it needs to function -- ensure # that it doesn't clobber any existing global var though! jsx_transformer_js = """ var global = ("undefined"!==typeof global) ? global : {}; %s var JSXTransfomer = global.JSXTransformer; """ % jsx_transformer_js log.debug("Read JSXTransformer") ext = PyV8.JSExtension("lib/jsx", jsx_transformer_js) log.debug("Created extension: %r ; now the set is %r", ext, PyV8.JSExtension.extensions) log.debug("Evaluating JSX") script = """ var jsxSource = %r; global.JSXTransformer.transform(jsxSource); """ % source with PyV8.JSContext(extensions=["lib/jsx"]) as ctx: log.debug("running in context: %r", ctx) result = ctx.eval(script) log.debug("evaluated: %r", result) result_code = result.code log.debug("Transformed JSX") return result_code
def make_js_bundle(app_js_path): """ Compile the given application Javascript into a PyV8 JSExtension. Caches extensions it's compiled under their path, so if the path is already compiled doesn't do the work again. Transforms any JSX, not only compiling it as an extension but also writing it to a corresponding .js file for client-side loading. Also bundles the React and Moment.js libraries, which are used by the client-side code. """ if app_js_path in PyV8.JSExtension.extensions: log.debug("Application code already loaded") return log.debug("Loading React library") if "lib/react" in PyV8.JSExtension.extensions: log.debug("Extension already loaded") else: start = time.time() with open(REACT_LIB_PATH, 'r') as react_f: react_js = react_f.read() log.debug("TIME: Read in %.3f", (time.time() - start) * 1000) # Ensure the `global` var is defined, as it's needed, but # don't destroy any existing context react_js = """ var global = ("undefined"!==typeof global) ? global : {}; %s var React = global.React; """ % react_js # Register the extension for later use ext = PyV8.JSExtension("lib/react", react_js) log.debug("Created extension: %r", ext) if "lib/moment" in PyV8.JSExtension.extensions: log.debug("Moment extension already loaded") else: start = time.time() with open(absolute_path_in_app("static/js/moment.min.js"), 'r') as m_f: moment_js = m_f.read() log.debug("TIME: Moment read in %.3f", (time.time() - start) * 1000) # Ensure global and window are defined so we can access the # library later moment_js = """ var window = ("undefined"!==typeof global) ? global : {}; %s var moment = global.moment; """ % moment_js # Register the extension for later use ext = PyV8.JSExtension("lib/moment", moment_js) log.debug("Created Moment extension: %r", ext) log.debug("Loading JS application code") start = time.time() with open(absolute_path_in_app(app_js_path), 'r') as app_f: app_js = app_f.read() if app_js_path.endswith('.jsx'): log.debug("Transforming JSX") app_js = transform_jsx(app_js, app_js_path) log.debug("Writing transformed JS") transformed_path = app_js_path.replace('jsx', 'js') with open(absolute_path_in_app(transformed_path), 'w') as out: out.write(app_js) log.debug("...done") log.debug("TIME: Loaded in %.3f", (time.time() - start) * 1000) start = time.time() ext = PyV8.JSExtension(app_js_path, app_js) log.debug("TIME: Compiled in %.3f", (time.time() - start) * 1000)