From a70ccbd4a5abef087f0cd4bc18be5359d1ef8c5e Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Tue, 11 Feb 2020 22:42:58 -0600 Subject: [PATCH] draft --- content/2020-02-11-enterprise-update.md | 14 - content/enterprise/prototype/helloworld.js | 639 +++++++++++++++++++ content/enterprise/prototype/helloworld.wasm | Bin 0 -> 83344 bytes content/enterprise/prototype/index.md | 52 ++ templates/post.html | 1 + 5 files changed, 692 insertions(+), 14 deletions(-) delete mode 100644 content/2020-02-11-enterprise-update.md create mode 100644 content/enterprise/prototype/helloworld.js create mode 100644 content/enterprise/prototype/helloworld.wasm create mode 100644 content/enterprise/prototype/index.md diff --git a/content/2020-02-11-enterprise-update.md b/content/2020-02-11-enterprise-update.md deleted file mode 100644 index 8b60375..0000000 --- a/content/2020-02-11-enterprise-update.md +++ /dev/null @@ -1,14 +0,0 @@ -+++ -title = "enterprise: a new ui framework" -date = 2020-02-11 -draft = true - -[taxonomies] -tags = [] -+++ - -This past weekend, while on my trip to Minneapolis, I completed a very early prototype of "enterprise", a new UI framework I've been kind of envisioning over the past couple of weeks. While the UI framework is mainly targeted at web apps, the hope is that with a bit more effort, native UIs can be produced with almost no changes to existing applications. Before I begin to describe how it works, I'd like to acknowledge [Nathan Ringo][1] for his massively helpful feedback in both the ideation and the implementation process. - -## Goals of the project - -[1]: https://remexre.xyz diff --git a/content/enterprise/prototype/helloworld.js b/content/enterprise/prototype/helloworld.js new file mode 100644 index 0000000..5e8346e --- /dev/null +++ b/content/enterprise/prototype/helloworld.js @@ -0,0 +1,639 @@ +"use strict"; + +if( typeof Rust === "undefined" ) { + var Rust = {}; +} + +(function( root, factory ) { + if( typeof define === "function" && define.amd ) { + define( [], factory ); + } else if( typeof module === "object" && module.exports ) { + module.exports = factory(); + } else { + Rust.helloworld = factory(); + } +}( this, function() { + return (function( module_factory ) { + var instance = module_factory(); + + if( typeof process === "object" && typeof process.versions === "object" && typeof process.versions.node === "string" ) { + var fs = require( "fs" ); + var path = require( "path" ); + var wasm_path = path.join( __dirname, "helloworld.wasm" ); + var buffer = fs.readFileSync( wasm_path ); + var mod = new WebAssembly.Module( buffer ); + var wasm_instance = new WebAssembly.Instance( mod, instance.imports ); + return instance.initialize( wasm_instance ); + } else { + var file = fetch( "helloworld.wasm", {credentials: "same-origin"} ); + + var wasm_instance = ( typeof WebAssembly.instantiateStreaming === "function" + ? WebAssembly.instantiateStreaming( file, instance.imports ) + .then( function( result ) { return result.instance; } ) + + : file + .then( function( response ) { return response.arrayBuffer(); } ) + .then( function( bytes ) { return WebAssembly.compile( bytes ); } ) + .then( function( mod ) { return WebAssembly.instantiate( mod, instance.imports ) } ) ); + + return wasm_instance + .then( function( wasm_instance ) { + var exports = instance.initialize( wasm_instance ); + console.log( "Finished loading Rust wasm module 'helloworld'" ); + return exports; + }) + .catch( function( error ) { + console.log( "Error loading Rust wasm module 'helloworld':", error ); + throw error; + }); + } + }( function() { + var Module = {}; + + Module.STDWEB_PRIVATE = {}; + +// This is based on code from Emscripten's preamble.js. +Module.STDWEB_PRIVATE.to_utf8 = function to_utf8( str, addr ) { + var HEAPU8 = Module.HEAPU8; + for( var i = 0; i < str.length; ++i ) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629 + var u = str.charCodeAt( i ); // possibly a lead surrogate + if( u >= 0xD800 && u <= 0xDFFF ) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt( ++i ) & 0x3FF); + } + + if( u <= 0x7F ) { + HEAPU8[ addr++ ] = u; + } else if( u <= 0x7FF ) { + HEAPU8[ addr++ ] = 0xC0 | (u >> 6); + HEAPU8[ addr++ ] = 0x80 | (u & 63); + } else if( u <= 0xFFFF ) { + HEAPU8[ addr++ ] = 0xE0 | (u >> 12); + HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63); + HEAPU8[ addr++ ] = 0x80 | (u & 63); + } else if( u <= 0x1FFFFF ) { + HEAPU8[ addr++ ] = 0xF0 | (u >> 18); + HEAPU8[ addr++ ] = 0x80 | ((u >> 12) & 63); + HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63); + HEAPU8[ addr++ ] = 0x80 | (u & 63); + } else if( u <= 0x3FFFFFF ) { + HEAPU8[ addr++ ] = 0xF8 | (u >> 24); + HEAPU8[ addr++ ] = 0x80 | ((u >> 18) & 63); + HEAPU8[ addr++ ] = 0x80 | ((u >> 12) & 63); + HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63); + HEAPU8[ addr++ ] = 0x80 | (u & 63); + } else { + HEAPU8[ addr++ ] = 0xFC | (u >> 30); + HEAPU8[ addr++ ] = 0x80 | ((u >> 24) & 63); + HEAPU8[ addr++ ] = 0x80 | ((u >> 18) & 63); + HEAPU8[ addr++ ] = 0x80 | ((u >> 12) & 63); + HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63); + HEAPU8[ addr++ ] = 0x80 | (u & 63); + } + } +}; + +Module.STDWEB_PRIVATE.noop = function() {}; +Module.STDWEB_PRIVATE.to_js = function to_js( address ) { + var kind = Module.HEAPU8[ address + 12 ]; + if( kind === 0 ) { + return undefined; + } else if( kind === 1 ) { + return null; + } else if( kind === 2 ) { + return Module.HEAP32[ address / 4 ]; + } else if( kind === 3 ) { + return Module.HEAPF64[ address / 8 ]; + } else if( kind === 4 ) { + var pointer = Module.HEAPU32[ address / 4 ]; + var length = Module.HEAPU32[ (address + 4) / 4 ]; + return Module.STDWEB_PRIVATE.to_js_string( pointer, length ); + } else if( kind === 5 ) { + return false; + } else if( kind === 6 ) { + return true; + } else if( kind === 7 ) { + var pointer = Module.STDWEB_PRIVATE.arena + Module.HEAPU32[ address / 4 ]; + var length = Module.HEAPU32[ (address + 4) / 4 ]; + var output = []; + for( var i = 0; i < length; ++i ) { + output.push( Module.STDWEB_PRIVATE.to_js( pointer + i * 16 ) ); + } + return output; + } else if( kind === 8 ) { + var arena = Module.STDWEB_PRIVATE.arena; + var value_array_pointer = arena + Module.HEAPU32[ address / 4 ]; + var length = Module.HEAPU32[ (address + 4) / 4 ]; + var key_array_pointer = arena + Module.HEAPU32[ (address + 8) / 4 ]; + var output = {}; + for( var i = 0; i < length; ++i ) { + var key_pointer = Module.HEAPU32[ (key_array_pointer + i * 8) / 4 ]; + var key_length = Module.HEAPU32[ (key_array_pointer + 4 + i * 8) / 4 ]; + var key = Module.STDWEB_PRIVATE.to_js_string( key_pointer, key_length ); + var value = Module.STDWEB_PRIVATE.to_js( value_array_pointer + i * 16 ); + output[ key ] = value; + } + return output; + } else if( kind === 9 ) { + return Module.STDWEB_PRIVATE.acquire_js_reference( Module.HEAP32[ address / 4 ] ); + } else if( kind === 10 || kind === 12 || kind === 13 ) { + var adapter_pointer = Module.HEAPU32[ address / 4 ]; + var pointer = Module.HEAPU32[ (address + 4) / 4 ]; + var deallocator_pointer = Module.HEAPU32[ (address + 8) / 4 ]; + var num_ongoing_calls = 0; + var drop_queued = false; + var output = function() { + if( pointer === 0 || drop_queued === true ) { + if (kind === 10) { + throw new ReferenceError( "Already dropped Rust function called!" ); + } else if (kind === 12) { + throw new ReferenceError( "Already dropped FnMut function called!" ); + } else { + throw new ReferenceError( "Already called or dropped FnOnce function called!" ); + } + } + + var function_pointer = pointer; + if (kind === 13) { + output.drop = Module.STDWEB_PRIVATE.noop; + pointer = 0; + } + + if (num_ongoing_calls !== 0) { + if (kind === 12 || kind === 13) { + throw new ReferenceError( "FnMut function called multiple times concurrently!" ); + } + } + + var args = Module.STDWEB_PRIVATE.alloc( 16 ); + Module.STDWEB_PRIVATE.serialize_array( args, arguments ); + + try { + num_ongoing_calls += 1; + Module.STDWEB_PRIVATE.dyncall( "vii", adapter_pointer, [function_pointer, args] ); + var result = Module.STDWEB_PRIVATE.tmp; + Module.STDWEB_PRIVATE.tmp = null; + } finally { + num_ongoing_calls -= 1; + } + + if( drop_queued === true && num_ongoing_calls === 0 ) { + output.drop(); + } + + return result; + }; + + output.drop = function() { + if (num_ongoing_calls !== 0) { + drop_queued = true; + return; + } + + output.drop = Module.STDWEB_PRIVATE.noop; + var function_pointer = pointer; + pointer = 0; + + if (function_pointer != 0) { + Module.STDWEB_PRIVATE.dyncall( "vi", deallocator_pointer, [function_pointer] ); + } + }; + + return output; + } else if( kind === 14 ) { + var pointer = Module.HEAPU32[ address / 4 ]; + var length = Module.HEAPU32[ (address + 4) / 4 ]; + var array_kind = Module.HEAPU32[ (address + 8) / 4 ]; + var pointer_end = pointer + length; + + switch( array_kind ) { + case 0: + return Module.HEAPU8.subarray( pointer, pointer_end ); + case 1: + return Module.HEAP8.subarray( pointer, pointer_end ); + case 2: + return Module.HEAPU16.subarray( pointer, pointer_end ); + case 3: + return Module.HEAP16.subarray( pointer, pointer_end ); + case 4: + return Module.HEAPU32.subarray( pointer, pointer_end ); + case 5: + return Module.HEAP32.subarray( pointer, pointer_end ); + case 6: + return Module.HEAPF32.subarray( pointer, pointer_end ); + case 7: + return Module.HEAPF64.subarray( pointer, pointer_end ); + } + } else if( kind === 15 ) { + return Module.STDWEB_PRIVATE.get_raw_value( Module.HEAPU32[ address / 4 ] ); + } +}; + +Module.STDWEB_PRIVATE.serialize_object = function serialize_object( address, value ) { + var keys = Object.keys( value ); + var length = keys.length; + var key_array_pointer = Module.STDWEB_PRIVATE.alloc( length * 8 ); + var value_array_pointer = Module.STDWEB_PRIVATE.alloc( length * 16 ); + Module.HEAPU8[ address + 12 ] = 8; + Module.HEAPU32[ address / 4 ] = value_array_pointer; + Module.HEAPU32[ (address + 4) / 4 ] = length; + Module.HEAPU32[ (address + 8) / 4 ] = key_array_pointer; + for( var i = 0; i < length; ++i ) { + var key = keys[ i ]; + var key_address = key_array_pointer + i * 8; + Module.STDWEB_PRIVATE.to_utf8_string( key_address, key ); + + Module.STDWEB_PRIVATE.from_js( value_array_pointer + i * 16, value[ key ] ); + } +}; + +Module.STDWEB_PRIVATE.serialize_array = function serialize_array( address, value ) { + var length = value.length; + var pointer = Module.STDWEB_PRIVATE.alloc( length * 16 ); + Module.HEAPU8[ address + 12 ] = 7; + Module.HEAPU32[ address / 4 ] = pointer; + Module.HEAPU32[ (address + 4) / 4 ] = length; + for( var i = 0; i < length; ++i ) { + Module.STDWEB_PRIVATE.from_js( pointer + i * 16, value[ i ] ); + } +}; + +// New browsers and recent Node +var cachedEncoder = ( typeof TextEncoder === "function" + ? new TextEncoder( "utf-8" ) + // Old Node (before v11) + : ( typeof util === "object" && util && typeof util.TextEncoder === "function" + ? new util.TextEncoder( "utf-8" ) + // Old browsers + : null ) ); + +if ( cachedEncoder != null ) { + Module.STDWEB_PRIVATE.to_utf8_string = function to_utf8_string( address, value ) { + var buffer = cachedEncoder.encode( value ); + var length = buffer.length; + var pointer = 0; + + if ( length > 0 ) { + pointer = Module.STDWEB_PRIVATE.alloc( length ); + Module.HEAPU8.set( buffer, pointer ); + } + + Module.HEAPU32[ address / 4 ] = pointer; + Module.HEAPU32[ (address + 4) / 4 ] = length; + }; + +} else { + Module.STDWEB_PRIVATE.to_utf8_string = function to_utf8_string( address, value ) { + var length = Module.STDWEB_PRIVATE.utf8_len( value ); + var pointer = 0; + + if ( length > 0 ) { + pointer = Module.STDWEB_PRIVATE.alloc( length ); + Module.STDWEB_PRIVATE.to_utf8( value, pointer ); + } + + Module.HEAPU32[ address / 4 ] = pointer; + Module.HEAPU32[ (address + 4) / 4 ] = length; + }; +} + +Module.STDWEB_PRIVATE.from_js = function from_js( address, value ) { + var kind = Object.prototype.toString.call( value ); + if( kind === "[object String]" ) { + Module.HEAPU8[ address + 12 ] = 4; + Module.STDWEB_PRIVATE.to_utf8_string( address, value ); + } else if( kind === "[object Number]" ) { + if( value === (value|0) ) { + Module.HEAPU8[ address + 12 ] = 2; + Module.HEAP32[ address / 4 ] = value; + } else { + Module.HEAPU8[ address + 12 ] = 3; + Module.HEAPF64[ address / 8 ] = value; + } + } else if( value === null ) { + Module.HEAPU8[ address + 12 ] = 1; + } else if( value === undefined ) { + Module.HEAPU8[ address + 12 ] = 0; + } else if( value === false ) { + Module.HEAPU8[ address + 12 ] = 5; + } else if( value === true ) { + Module.HEAPU8[ address + 12 ] = 6; + } else if( kind === "[object Symbol]" ) { + var id = Module.STDWEB_PRIVATE.register_raw_value( value ); + Module.HEAPU8[ address + 12 ] = 15; + Module.HEAP32[ address / 4 ] = id; + } else { + var refid = Module.STDWEB_PRIVATE.acquire_rust_reference( value ); + Module.HEAPU8[ address + 12 ] = 9; + Module.HEAP32[ address / 4 ] = refid; + } +}; + +// New browsers and recent Node +var cachedDecoder = ( typeof TextDecoder === "function" + ? new TextDecoder( "utf-8" ) + // Old Node (before v11) + : ( typeof util === "object" && util && typeof util.TextDecoder === "function" + ? new util.TextDecoder( "utf-8" ) + // Old browsers + : null ) ); + +if ( cachedDecoder != null ) { + Module.STDWEB_PRIVATE.to_js_string = function to_js_string( index, length ) { + return cachedDecoder.decode( Module.HEAPU8.subarray( index, index + length ) ); + }; + +} else { + // This is ported from Rust's stdlib; it's faster than + // the string conversion from Emscripten. + Module.STDWEB_PRIVATE.to_js_string = function to_js_string( index, length ) { + var HEAPU8 = Module.HEAPU8; + index = index|0; + length = length|0; + var end = (index|0) + (length|0); + var output = ""; + while( index < end ) { + var x = HEAPU8[ index++ ]; + if( x < 128 ) { + output += String.fromCharCode( x ); + continue; + } + var init = (x & (0x7F >> 2)); + var y = 0; + if( index < end ) { + y = HEAPU8[ index++ ]; + } + var ch = (init << 6) | (y & 63); + if( x >= 0xE0 ) { + var z = 0; + if( index < end ) { + z = HEAPU8[ index++ ]; + } + var y_z = ((y & 63) << 6) | (z & 63); + ch = init << 12 | y_z; + if( x >= 0xF0 ) { + var w = 0; + if( index < end ) { + w = HEAPU8[ index++ ]; + } + ch = (init & 7) << 18 | ((y_z << 6) | (w & 63)); + + output += String.fromCharCode( 0xD7C0 + (ch >> 10) ); + ch = 0xDC00 + (ch & 0x3FF); + } + } + output += String.fromCharCode( ch ); + continue; + } + return output; + }; +} + +Module.STDWEB_PRIVATE.id_to_ref_map = {}; +Module.STDWEB_PRIVATE.id_to_refcount_map = {}; +Module.STDWEB_PRIVATE.ref_to_id_map = new WeakMap(); +// Not all types can be stored in a WeakMap +Module.STDWEB_PRIVATE.ref_to_id_map_fallback = new Map(); +Module.STDWEB_PRIVATE.last_refid = 1; + +Module.STDWEB_PRIVATE.id_to_raw_value_map = {}; +Module.STDWEB_PRIVATE.last_raw_value_id = 1; + +Module.STDWEB_PRIVATE.acquire_rust_reference = function( reference ) { + if( reference === undefined || reference === null ) { + return 0; + } + + var id_to_refcount_map = Module.STDWEB_PRIVATE.id_to_refcount_map; + var id_to_ref_map = Module.STDWEB_PRIVATE.id_to_ref_map; + var ref_to_id_map = Module.STDWEB_PRIVATE.ref_to_id_map; + var ref_to_id_map_fallback = Module.STDWEB_PRIVATE.ref_to_id_map_fallback; + + var refid = ref_to_id_map.get( reference ); + if( refid === undefined ) { + refid = ref_to_id_map_fallback.get( reference ); + } + if( refid === undefined ) { + refid = Module.STDWEB_PRIVATE.last_refid++; + try { + ref_to_id_map.set( reference, refid ); + } catch (e) { + ref_to_id_map_fallback.set( reference, refid ); + } + } + + if( refid in id_to_ref_map ) { + id_to_refcount_map[ refid ]++; + } else { + id_to_ref_map[ refid ] = reference; + id_to_refcount_map[ refid ] = 1; + } + + return refid; +}; + +Module.STDWEB_PRIVATE.acquire_js_reference = function( refid ) { + return Module.STDWEB_PRIVATE.id_to_ref_map[ refid ]; +}; + +Module.STDWEB_PRIVATE.increment_refcount = function( refid ) { + Module.STDWEB_PRIVATE.id_to_refcount_map[ refid ]++; +}; + +Module.STDWEB_PRIVATE.decrement_refcount = function( refid ) { + var id_to_refcount_map = Module.STDWEB_PRIVATE.id_to_refcount_map; + if( 0 == --id_to_refcount_map[ refid ] ) { + var id_to_ref_map = Module.STDWEB_PRIVATE.id_to_ref_map; + var ref_to_id_map_fallback = Module.STDWEB_PRIVATE.ref_to_id_map_fallback; + var reference = id_to_ref_map[ refid ]; + delete id_to_ref_map[ refid ]; + delete id_to_refcount_map[ refid ]; + ref_to_id_map_fallback.delete(reference); + } +}; + +Module.STDWEB_PRIVATE.register_raw_value = function( value ) { + var id = Module.STDWEB_PRIVATE.last_raw_value_id++; + Module.STDWEB_PRIVATE.id_to_raw_value_map[ id ] = value; + return id; +}; + +Module.STDWEB_PRIVATE.unregister_raw_value = function( id ) { + delete Module.STDWEB_PRIVATE.id_to_raw_value_map[ id ]; +}; + +Module.STDWEB_PRIVATE.get_raw_value = function( id ) { + return Module.STDWEB_PRIVATE.id_to_raw_value_map[ id ]; +}; + +Module.STDWEB_PRIVATE.alloc = function alloc( size ) { + return Module.web_malloc( size ); +}; + +Module.STDWEB_PRIVATE.dyncall = function( signature, ptr, args ) { + return Module.web_table.get( ptr ).apply( null, args ); +}; + +// This is based on code from Emscripten's preamble.js. +Module.STDWEB_PRIVATE.utf8_len = function utf8_len( str ) { + var len = 0; + for( var i = 0; i < str.length; ++i ) { + // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8. + // See http://unicode.org/faq/utf_bom.html#utf16-3 + var u = str.charCodeAt( i ); // possibly a lead surrogate + if( u >= 0xD800 && u <= 0xDFFF ) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt( ++i ) & 0x3FF); + } + + if( u <= 0x7F ) { + ++len; + } else if( u <= 0x7FF ) { + len += 2; + } else if( u <= 0xFFFF ) { + len += 3; + } else if( u <= 0x1FFFFF ) { + len += 4; + } else if( u <= 0x3FFFFFF ) { + len += 5; + } else { + len += 6; + } + } + return len; +}; + +Module.STDWEB_PRIVATE.prepare_any_arg = function( value ) { + var arg = Module.STDWEB_PRIVATE.alloc( 16 ); + Module.STDWEB_PRIVATE.from_js( arg, value ); + return arg; +}; + +Module.STDWEB_PRIVATE.acquire_tmp = function( dummy ) { + var value = Module.STDWEB_PRIVATE.tmp; + Module.STDWEB_PRIVATE.tmp = null; + return value; +}; + + + + var HEAP8 = null; + var HEAP16 = null; + var HEAP32 = null; + var HEAPU8 = null; + var HEAPU16 = null; + var HEAPU32 = null; + var HEAPF32 = null; + var HEAPF64 = null; + + Object.defineProperty( Module, 'exports', { value: {} } ); + + function __web_on_grow() { + var buffer = Module.instance.exports.memory.buffer; + HEAP8 = new Int8Array( buffer ); + HEAP16 = new Int16Array( buffer ); + HEAP32 = new Int32Array( buffer ); + HEAPU8 = new Uint8Array( buffer ); + HEAPU16 = new Uint16Array( buffer ); + HEAPU32 = new Uint32Array( buffer ); + HEAPF32 = new Float32Array( buffer ); + HEAPF64 = new Float64Array( buffer ); + Module.HEAP8 = HEAP8; + Module.HEAP16 = HEAP16; + Module.HEAP32 = HEAP32; + Module.HEAPU8 = HEAPU8; + Module.HEAPU16 = HEAPU16; + Module.HEAPU32 = HEAPU32; + Module.HEAPF32 = HEAPF32; + Module.HEAPF64 = HEAPF64; + } + + return { + imports: { + env: { + "__cargo_web_snippet_09675c7ed2827e045dc760aeac3d286437cfbe5e": function($0, $1, $2, $3) { + $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);$3 = Module.STDWEB_PRIVATE.to_js($3);Module.STDWEB_PRIVATE.from_js($0, (function(){try{return{value:function(){return($1).setAttribute(($2),($3));}(),success:true};}catch(error){return{error:error,success:false};}})()); + }, + "__cargo_web_snippet_0e54fd9c163fcf648ce0a395fde4500fd167a40b": function($0) { + var r = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );return (r instanceof DOMException) && (r.name === "InvalidCharacterError"); + }, + "__cargo_web_snippet_1edaec034bdcb0a749c6d5de76c29f6371afb5a0": function($0) { + var o = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );return (o instanceof Event && o.type === "input"); + }, + "__cargo_web_snippet_2908dbb08792df5e699e324eec3e29fd6a57c2c9": function($0) { + var o = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );return (o instanceof HTMLInputElement); + }, + "__cargo_web_snippet_3c5e83d16a83fc7147ec91e2506438012952f55a": function($0) { + var o = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );return (o instanceof Element); + }, + "__cargo_web_snippet_614a3dd2adb7e9eac4a0ec6e59d37f87e0521c3b": function($0, $1) { + $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return($1).error;})()); + }, + "__cargo_web_snippet_6fcce0aae651e2d748e085ff1f800f87625ff8c8": function($0) { + Module.STDWEB_PRIVATE.from_js($0, (function(){return document;})()); + }, + "__cargo_web_snippet_72fc447820458c720c68d0d8e078ede631edd723": function($0, $1, $2) { + console.error( 'Panic location:', Module.STDWEB_PRIVATE.to_js_string( $0, $1 ) + ':' + $2 ); + }, + "__cargo_web_snippet_80d6d56760c65e49b7be8b6b01c1ea861b046bf0": function($0) { + Module.STDWEB_PRIVATE.decrement_refcount( $0 ); + }, + "__cargo_web_snippet_91749aeb589cd0f9b17cbc01b2872ba709817982": function($0, $1, $2) { + $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){try{return{value:function(){return($1).createElement(($2));}(),success:true};}catch(error){return{error:error,success:false};}})()); + }, + "__cargo_web_snippet_97495987af1720d8a9a923fa4683a7b683e3acd6": function($0, $1) { + console.error( 'Panic error message:', Module.STDWEB_PRIVATE.to_js_string( $0, $1 ) ); + }, + "__cargo_web_snippet_99c4eefdc8d4cc724135163b8c8665a1f3de99e4": function($0, $1, $2, $3) { + $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);$3 = Module.STDWEB_PRIVATE.to_js($3);Module.STDWEB_PRIVATE.from_js($0, (function(){var listener=($1);($2).addEventListener(($3),listener);return listener;})()); + }, + "__cargo_web_snippet_9f22d4ca7bc938409787341b7db181f8dd41e6df": function($0) { + Module.STDWEB_PRIVATE.increment_refcount( $0 ); + }, + "__cargo_web_snippet_ab05f53189dacccf2d365ad26daa407d4f7abea9": function($0, $1) { + $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return($1).value;})()); + }, + "__cargo_web_snippet_afafe9a462a05084fec65cacc7d6598e145ff3e3": function($0, $1, $2) { + $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){return($1).createTextNode(($2));})()); + }, + "__cargo_web_snippet_b06dde4acf09433b5190a4b001259fe5d4abcbc2": function($0, $1) { + $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return($1).success;})()); + }, + "__cargo_web_snippet_d5e30f74cb752784e06bd97a37b1f89b6c3433a7": function($0, $1, $2) { + $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){return($1).getElementById(($2));})()); + }, + "__cargo_web_snippet_dc2fd915bd92f9e9c6a3bd15174f1414eee3dbaf": function() { + console.error( 'Encountered a panic!' ); + }, + "__cargo_web_snippet_e741b9d9071097746386b2c2ec044a2bc73e688c": function($0, $1) { + $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0).appendChild(($1)); + }, + "__cargo_web_snippet_e9638d6405ab65f78daf4a5af9c9de14ecf1e2ec": function($0) { + $0 = Module.STDWEB_PRIVATE.to_js($0);Module.STDWEB_PRIVATE.unregister_raw_value(($0)); + }, + "__cargo_web_snippet_f765b15a1a1b5cd266e922e6fca98dd570f17edc": function($0, $1) { + $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0).textContent=($1); + }, + "__cargo_web_snippet_ff5103e6cc179d13b4c7a785bdce2708fd559fc0": function($0) { + Module.STDWEB_PRIVATE.tmp = Module.STDWEB_PRIVATE.to_js( $0 ); + }, + "__web_on_grow": __web_on_grow + } + }, + initialize: function( instance ) { + Object.defineProperty( Module, 'instance', { value: instance } ); + Object.defineProperty( Module, 'web_malloc', { value: Module.instance.exports.__web_malloc } ); + Object.defineProperty( Module, 'web_free', { value: Module.instance.exports.__web_free } ); + Object.defineProperty( Module, 'web_table', { value: Module.instance.exports.__indirect_function_table } ); + + + __web_on_grow(); + Module.instance.exports.main(); + + return Module.exports; + } + }; +} + )); +})); diff --git a/content/enterprise/prototype/helloworld.wasm b/content/enterprise/prototype/helloworld.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3d6ced23a84fc1042287b9b9add3fd64149fe002 GIT binary patch literal 83344 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 literal 0 HcmV?d00001 diff --git a/content/enterprise/prototype/index.md b/content/enterprise/prototype/index.md new file mode 100644 index 0000000..2e1094c --- /dev/null +++ b/content/enterprise/prototype/index.md @@ -0,0 +1,52 @@ ++++ +title = "enterprise: a new ui framework" +date = 2020-02-11 +draft = true +template = "post.html" + +[taxonomies] +tags = [] + +[extra] +toc = true ++++ + +This past weekend, while on my trip to Minneapolis, I completed a very early prototype of "enterprise", a new UI framework I've been kind of envisioning over the past couple of weeks. While the UI framework is mainly targeted at web apps, the hope is that with a bit more effort, native UIs can be produced with almost no changes to existing applications. Before I begin to describe how it works, I'd like to acknowledge [Nathan Ringo][1] for his massively helpful feedback in both the ideation and the implementation process. + +## Goals of the project + +* **Complete separation of business logic from UI.** Theoretically, one could completely retarget the application to a completely different platform (mobile, web, native, something new that will pop up in 5 years), without changing any of the core logic. As enterprise grows to include a backend, this should be true of the backend as well. It does this by introducing [DSL][2]s that are completely architecture-independent. +* **Frontend relationships should be as static as possible.** + +## Prototype + +The prototype for experimenting is a simple "Hello, world" application. If you've looked at any web framework before, this is probably one of the simplest examples of bindings: type something into a box and watch as the text magically populates with whatever you wrote in the box. If you're using a WASM-compatible browser with JavaScript enabled, you should be able to try out the demo in real-time: + +
+ + +OK, you say, but I could implement this in 3 lines of JavaScript. + +```js +inputEl.addEventListener("change", () => { + spanEl.innerText = inputEl.value; +}); +``` + +Surely, this works, but it doesn't scale. If you try to write a page full of these kind of bindings directly using JavaScript, you're either going to start running into bugs or building up a pile of unmaintainable spaghetti code. + +So how does enterprise represent this? Well, the enterprise DSL has no concrete syntax yet, but if it did, it would look something like this: + +``` +model { + name: String, +} + +view { + + Hello, {name}! +} +``` + +[1]: https://remexre.xyz +[2]: https://en.wikipedia.org/wiki/Domain-specific_language diff --git a/templates/post.html b/templates/post.html index e8955d3..a23857f 100644 --- a/templates/post.html +++ b/templates/post.html @@ -15,6 +15,7 @@ Posted {% if page.extra.author %}by {{ page.extra.author }}{% endif %} on {{ page.date }} + - {{ page.reading_time }} min read {% endif %}