Git Product home page Git Product logo

asm-dom's Introduction

:rage4: asm-dom :rage4:

experimental Build Status npm version npm downloads Join the chat at https://gitter.im/mbasso/asm-dom

A minimal WebAssembly virtual DOM to build C++ SPA (Single page applications)

Table of Contents

Motivation

asm-dom is a minimal WebAssembly virtual DOM to build C++ SPA (Single page applications). You can write an entire SPA in C++ and compile it to WebAssembly (or asmjs as fallback) using Emscripten, asm-dom will call DOM APIs for you. This will produce an app that aims to execute at native speed by taking advantage of common hardware capabilities, also, you can use your C/C++ code without any change, you haven't to create a binding layer to use it (as we have to do if we want to use a C++ lib from JS). Basically we are creating an app in C++ that call javascript if needed instead of the opposite. You can write only once in C++ and share as much code as possible with desktop/mobile apps and web site. If you want to learn more about performance, please see this.

How can I structure my application with asm-dom?

asm-dom is a low-level virtual DOM library. It is unopinionated with regards to how you should structure your application.

How did you come up with the concept of asm-dom?

At the beginning asm-dom is born from the idea to test the powerful of WebAssembly in a common use case that is not gaming, VR, AR or Image / video editing. Unfortunately, at the moment, GC/DOM Integration is a future feature ๐Ÿฆ„, so, asm-dom isn't totally developed in wasm. All interactions with the DOM are written in Javascript. This is a big disadvantage because of the overhead of the binding between JS and WASM, in the future asm-dom will be even more powerful, anyway results are satisfying.

Inline Example

#include "asm-dom.hpp"

using namespace asmdom;

int main() {
  Config config = Config();
  init(config);

  // asm-dom can be used with a JSX like syntax thanks to gccx
  VNode* vnode = (
    <div
      onclick={[](emscripten::val e) -> bool {
        emscripten::val::global("console").call<void>("log", emscripten::val("clicked"));
        return true;
      }}
    >
      <span style="font-weight: bold">This is bold</span>
      and this is just normal text
      <a href="/foo">I'll take you places!</a>
    </div>
  );

  // Patch into empty DOM element โ€“ this modifies the DOM as a side effect
  patch(
    emscripten::val::global("document").call<emscripten::val>(
      "getElementById",
      std::string("root")
    ),
    vnode
  );

  // without gccx
  VNode* newVnode = h("div",
    Data(
      Callbacks {
        {"onclick", [](emscripten::val e) -> bool {
          emscripten::val::global("console").call<void>("log", emscripten::val("another click"));
          return true;
        }}
      }
    ),
    Children {
      h("span",
        Data(
          Attrs {
            {"style", "font-weight: normal; font-style: italic"}
          }
        ),
        std::string("This is now italic type")
      ),
      h(" and this is just normal text", true),
      h("a",
        Data(
          Attrs {
            {"href", "/bar"}
          }
        ),
        std::string("I'll take you places!")
      )
    }
  );

  // Second `patch` invocation
  patch(vnode, newVnode); // asm-dom efficiently updates the old view to the new state

  return 0;
};

Getting started

asm-dom aims to be used from C++, however it can be used also from javascript, here you can find the doc of both:

Ecosystem

Here you can find a list of related projects:

  • gccx - CPX (JSX like syntax) support.
  • asm-dom-boilerplate - A simple boilerplate to start using asm-dom without configuration.

Examples

Examples are available in the examples folder.

Also, here is the list of third-party examples:

and online Demos:

Roadmap

  • Thunks support
  • asm-dom aims to be even more powerful with GC/DOM Integration. Unfortunately this is a future feature ๐Ÿฆ„, so, we have to be patient and wait a bit.

Change Log

This project adheres to Semantic Versioning.
Every release, along with the migration instructions, is documented on the Github Releases page.

Authors

Matteo Basso

Copyright and License

Copyright for portions of project asm-dom are held by:

  • Simon Friis Vindum, 2015 as part of project snabbdom
  • project snabbdom-to-html

All other copyright for project asm-dom are held by Matteo Basso.

Copyright (c) 2016, Matteo Basso.

asm-dom source code is licensed under the MIT License.

asm-dom's People

Contributors

arthursonzogni avatar botcheddevil avatar coledeanshepherd avatar dependabot[bot] avatar mbasso avatar talentlessguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asm-dom's Issues

Compilation fails because of undefined behaviour catched by `-Wunsequenced`

General Information

  • Bug
  • Improvement
  • Feature
  • Other

Description

There is an undefined behaviour in asmdom::addVNodes because EM_ASM is a macro which evaluates arguments twice when expanded (see corresponding issue). And evaluating startIdx++ twice is undefined behaviour.

Steps to reproduce

I use Windows (probably irrelevant) and emcc (Emscripten gcc/clang-like replacement) 1.38.38 (commit 49652605051d9faca2dcb781918a028bdfbc2703) (probably relevant).

git clone https://github.com/mbasso/asm-dom-boilerplate.git
cd asm-dom-boilerplate
npm install
# if you are using windows, you have to make a little change to the Makefile in the root of the project, just open it and follow the instructions at the top
make start

Observe the following warning:

emcc \
	-O3 -Wall -Werror -Wall -Wno-deprecated -Wno-parentheses -Wno-format \
	--bind \
	-include node_modules/asm-dom/cpp/asm-dom.hpp \
	temp/o/index.o \
	node_modules/asm-dom/cpp/asm-dom.cpp \
	-o temp/app.bc
In file included from node_modules/asm-dom/cpp/asm-dom.cpp:6:
node_modules/asm-dom/cpp/Patch/patch.cpp:93:43: error: multiple unsequenced modifications to 'startIdx' [-Werror,-Wunsequenced]
                        }, parentElm, createElm(vnodes[startIdx++]), before);
                                                               ^~
C:\emsdk\upstream\emscripten\system\include\emscripten/em_asm.h:213:77: note: expanded from macro 'EM_ASM_'
#define EM_ASM_(code, ...) emscripten_asm_const_int(#code _EM_ASM_PREP_ARGS(__VA_ARGS__))
                                                                            ^~~~~~~~~~~
C:\emsdk\upstream\emscripten\system\include\emscripten/em_asm.h:122:42: note: expanded from macro '_EM_ASM_PREP_ARGS'
    , __em_asm_sig_builder::__em_asm_sig(__VA_ARGS__).buffer, ##__VA_ARGS__
                                         ^                      ~~~~~~~~~~~
1 error generated.
shared:ERROR: compiler frontend failed to generate LLVM bitcode, halting
make: *** [Makefile:95: temp/app.bc] Error 1

Suggested fix
Move the offending expression to a separate statement:

			int elm = createElm(vnodes[startIdx++]);
			EM_ASM_({
				Module.insertBefore($0, $1, $2)
			}, parentElm, elm, before);

Versions

  • asm-dom: current HEAD, ea3dba7
  • Browser: N/A

Shared logic for desktop/mobile and web browser

General Information

  • [ +] Improvement
  • [ +] Feature

Description

What do you think about that idea:

Create app logic in C++, so it can be used both by desktop/mobile and web browser. For browser use emscripten/WASM.

Use asm-dom in browser, so we will get native html/css.

Use something similar to blockspacer/skia-opengl-emscripten#5 for desktop/mobile, so we will be able to render and use same html/css.

Add custom HTML/CSS tags/styles e.t.c. to create something similar to Angular/React/Vue. For browser use 'shadow' dom or JS scripts (or even some existing JS framework).

Become next-gen web framework after WASM GC/DOM Integration. Target all platforms, browsers and even 3D apps/games.

Who uses asm-dom?

If you are using asm-dom, please let us know who are you, how it's used and give us a feedback!

HTML parser from cobalt

General Information

  • [+ ] Improvement
  • [+ ] Feature

Description

It may be useful: High-quality C++ HTML parser from cobalt.foo project. CMake port of it can be found at blockspacer/skia-opengl-emscripten#5 and https://github.com/blockspacer/skia-opengl-emscripten/blob/master/src/cobalt/cobalt_dom.cmake#L32

Some possible use cases:

  • Create something similar to gccx - CPX (JSX like syntax) support.
    We can use C++ template engine - CXTPL and code generation to convert JSX into C++ (see https://github.com/blockspacer/CXXCTP )
    With cobalt.foo html parser - create HTML parser with custom tags/JSX syntax.
    With CXXCTP - create code generation rule - from JSX to HTMl/CSS.
    With CXTPL - just combine C++ and HTML/CSS (and pass any complex C++ variables to HTML/CSS without binding!).
  • ...

WebGL, WebGPU etc. for rich graphics?

General Information

  • Bug
  • Improvement
  • Feature
  • Other

Description

I didn't find a mention of WebGL or WebGPU. Is support for these a potential future feature?

JSX support

Use asm-dom with the h function is a little bit verbose, for this reason we have to develop a parser that allows us to write a JSX like syntax in C++:

#include <iostream>
#include "asm-dom.hpp"

int main() {
  VNode* vnode = <span />;
  // translated to:
  // VNode* vnode = asmdom::h(u8"span");
}

At the moment there is a work in progress command line interface (cli) called gccx. However, other ideas and implementations are welcome.
After that we have reached a good point, we have to add a section to asm-dom docs that links the right tool to do this.

Any input, if I'd wish to see an usability comparison of asm-dom to existing JS frameworks?

General Information

  • Bug
  • Improvement
  • Feature
  • Other

Description

I am very interested in using asm-dom, but I find very little to no real-world examples of it.

Do you have any input, if trying to do such as a third party is waste of time? I cannot quite grasp the current scope of this project.

But if I decide to use it, then I'd expect it to compare to e.g. Chrome V8 and React.

Inline Example in README.md is missing a closing parenthesis.

Inline Example in README.md is missing a closing parenthesis on line 78, after std::string("root"),.

  // Patch into empty DOM element รขโ‚ฌโ€œ this modifies the DOM as a side effect
  patch(
    emscripten::val::global("document").call<emscripten::val>(
    "getElementById",
    std::string("root"),
    vnode
  );

VNode reuse

General Information

  • Bug
  • Improvement
  • Feature
  • Other

Depends on the answer to my question I suppose. ;-)

Description

Hi, awesome library! :-) I've been developing a declarative UI library, and hooking it up to asm-dom has enabled me to create live examples of it in the documentation:

https://tmadden.github.io/alia

I've been considering creating a production-grade interface to asm-dom, but I have a question about doing this properly... My own library provides the mechanics for tracking whether portions of the UI specification have changed since the last update. Ideally, when I know that an element hasn't changed, I'd like to reuse the VNode from before rather than recreating it with h(). However, it seems that asm-dom does some subtle things with VNodes during patching that make this complicated. I thought I had this working at one point, but then when I reordered my nodes within their parent container, things broke. (Some of the nodes had apparently overwritten others in the resulting UI.)

Do you have any guidance on this? Is it a supported use case? Are there rules one could follow to at least reuse some nodes safely?

Thanks!

Versions

  • asm-dom: 0.6.0
  • Browser: Chrome (Windows, some official release from this year)

Regression: children aren't displayed when appended manually to a parent with no child.

I discovered my example:
https://github.com/ArthurSonzogni/asm-dom-starter/blob/master/src/index.cpp

doesn't work anymore on version 0.6.2

Here is the relevant snippet:

  // Limit the number of actions to 10.
  asmdom::VNode *action_list = <ul class = "action_list"></ ul>;
  int start = std::max(0, (int)actions.size() - 10);
  for (int i = start; i < actions.size(); ++i) {
    std::string label = "action[" + std::to_string(i) + "] = " + actions[i];
    action_list->children.push_back(<li>{label}</ li>);
  }

I tried adding one child in the initial action_list element. Then my manually added children are properly displayed.

It looks like a regression. Or maybe I was using it the wrong way.

Could there be a browser that supports cpx? Or is this entirely out of scope?

General Information

  • Bug
  • Improvement
  • Feature
  • Other

Description

Could there be a browser that supports cpx? Or is this entirely out of scope?

I was initially looking for something that allows me to write something else than JS, but now it seems that while asm-dom looks awesome, it's still connecting with JS. Then I was just interested whether the WebAssembly backend or something allows one to pass JS totally.

Featuring asm-dom in Docusaurus

Hello, we would like to feature your project to the Docusaurus users page.

Are you with me on this? Also, can you provide your logo?

More info about this here

Question: Using CLion, Compiling to Native

Thank you for your work.

I have a question. In order to get the benefit of C++ IDE's like CLion, we would need to be able to compile the bulk of our code to native, otherwise Clang/GCC, and thus the IDE would throw up its hands.

Is it possible to compile some or all of a project to native for the purpose of IDE tooling a C++ unit tests?

Let's assume for a moment that we would be fine forgoing CSX for this purpose.

language clarity

I think you should:

`s/Web App/browser app/g`

Because web-apps in C++ were regular in the 90's via CGI-BIN and Apache. Doesn't need to be capitalized, either.

C++ for production web development?

I found this after much googling for the possibility of making a website entirely with C++ and webassembly. So far it's quite impressive, everything I have seen so far I would have done the same way. I am trying understand it a bit more. I am really interested in pushing to create a full C++ tooling to do production web apps, hopefully being a complete alternative to react and node.

This project seems to be the only thing I've seen so far that has taken seemingly a correct step in that direction. So I am curious to almost like brainstorm on this. Where do you see asm-dom going? Are you hopeful for comprehensive C++ web tooling? Is such a thing plausible or ideal? What missing components do you think are necessary?

git submodule init fails.

There are no .gitmodule defined in this project, but there is still a placeholder for a subproject here:
website/build/asm-dom-gh-pages

Some tools like cmake FetchContent automatically init submodule. It fails with asm-dom.

It needs to be removed. I will do it.

Support for web components

This is potentially an idea for improvement. Is there support for the web components standards: template, custom elements, shadow DOM?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.