Tokamak
Tokamak copied to clipboard
How do I host and launch TokamakUI apps from a Docker image / container? Can I do that using carton?
I am new to the swiftwasm World! Say for Ubuntu, how do I host and launch TokamakUI ( SwiftUI) apps from a Docker image / container? Can I do that using carton?
It looks like carton makes and runs a web server on http://127.0.0.1:8080/
How do we have that server run from inside a container?
Is there a docker compose / Dockerfile that exists? I do not see this documented anywhere?
Hi @curveddesign, thank you for checking it out. Tokamak apps in their basic form require only static assets, which you can host with any server that supports hosting static files from a directory, be it nginx or anything else. I'd personally recommend using a CDN, such as GitHub Pages or Netlify, but you also use any other CDN in front of your server to make static assets load faster.
You can check out an example of a very primitive todo-list app hosted on GitHub Pages. The files to host were generated with a carton bundle
command, which is not available in the latest stable version of carton
, but will be released in the next few days. As soon as it's released, that will become the recommended way to get a bundle of assets generated, and the documentation will be updated accordingly. In the meantine if you're not willing to wait, you can create your own index.html
file, and the source code for the bundle entrypoint is available in the carton
repository. You can then copy the main.wasm
file together with index.html
and bundle.js
to your static files server or a CDN.
Does that answer your question?
To answer your specific question about Docker, I'd personally recommend the nginx
image, check out the "Hosting some simple static content" section in their guide, and just copy the generated assets into the volume.
Yes, that answers my question! I am really looking forward to the carton bundle command working, I am going to try your work around! I am still trying to wrap my head around SwiftWasm and WASM in general, your blog posts below really helped me to understand it!
How WebAssembly changes software distribution
The state of Swift for WebAssembly in 2020 (and earlier)
One more question!!! Can I do network calls from TokamakUI? I am almost afraid to try it! š
Using SwiftWebUI I am able to make network calls using https://github.com/carson-katri/swift-request and I was surprised it actually worked! Since SwiftWasm is its own animal so to speak! Will this work in TokamakUI?
For example:
Request {
Url("http://ip-api.com/json/24.48.0.1")
Method(.get)
Header.Accept(.json)
}
.onJson { json in
print("json.query.string")
print(json.query.string)
}
.onError { error in
print(error.localizedDescription)
}
.call()
Thanks for checking out the blog posts, I really appreciate it!
I assume you've tried vanilla SwiftWebUI with swift-request
, as there's also a WebAssembly fork of SwiftWebUI. Most probably it worked in vanilla, because SwiftWebUI executes all Swift code on the server, not in the WebAssembly environment in your browser.
With Tokamak you'll have to use the Fetch API, and there are no SwiftWasm bindings for it yet, as far as I'm aware. I guess we will have some in the near future as a part of the DOMKit library, but my understanding is that it's not there yet, and is not a part of WebIDL declarations included there, maybe @j-f1 could clarify? Also, bear in mind that fetch
returns a Promise
object, and the API for it is still being developed in https://github.com/swiftwasm/JavaScriptKit/pull/62. Closure-based APIs in SwiftWasm are not very trivial to work with, as you have to be aware of the lifetime of your closure instances and manually release them. This is an inherent problem caused by the differences in how JavaScript (garbage collection) and Swift (reference counting) allocate memory for closures and their context.
I guess in the future we'll have a simpler API (probably based on Combine publishers) for networking that hides all of this complexity from users if they don't need it. In the meantime you can check old code in the swift-web-github-example
repository. It probably won't work with the latest JavaScriptKit 0.6.0, which strictly enforces closure lifetime. It may seem to work in JavaScriptKit 0.5.0, but lack of runtime checks for closure allocations can hide serious bugs.
Overall, if you don't want to dig deep into the technical details, I'd recommend waiting for a bit until the networking/promises part is more or less stable in future versions of JavaScriptKit and DOMKit. Sorry that it's not ready yet, there are many moving parts here that we're working on in parallel, and any help to the development efforts is very welcome.
I started work on an abstraction over fetch that matches URLSession, and it could then be supported in swift-request. But it's not in a working state ATM.
I guess we will have some in the near future as a part of the DOMKit library, but my understanding is that it's not there yet, and is not a part of WebIDL declarations included there, maybe @j-f1 could clarify?
Indeed ā fetch
is a separate spec that would have to be integrated. Iām not sure how the original maintainers got the .webidl
files out of the specs, and I would like to follow the same process for fetch.
Yes, it would be great to know where the WebIDL specs come from, as I'd like many more APIs covered eventually, IndexedDB, WebGL (WebIDL for this one is maintained together with the human readable text spec apparently), Web Animations obviously, and whatever comes next that users would be interested in.
Has there been any progress on getting "carton bundle' to work? If needed I could provide a simple docker-compose & Dockerfile for an NGINX ubuntu image. š
I found a regression in carton test
, which was related to bugs in recent 5.3 toolchains. I just need to verify that it's fixed, and then maybe after I squeeze in a fix for https://github.com/swiftwasm/carton/issues/112, I'll tag a new release in a couple of days if all goes well. It will support carton bundle
as one of the new things in that release.
Great news, carton test
works well now with wasm-5.3-SNAPSHOT-2020-09-25-a
snapshot, so swiftwasm/carton#112 is the only release blocker left. Working on it now...
carton
0.6.0 is now available on Homebrew, but you'll need to wait for https://github.com/TokamakUI/Tokamak/pull/281 to be merged. This new version of carton
ships with new JavaScriptKit runtime, which isn't compatible with the old version we use in Tokamak 0.3.0 or in the main
branch.
@MaxDesiatov Thanks for your hard work! There does not seem to be a lot of documentation for JavaScriptKit or maybe I am not looking in the right place? Can you give some hints on how one would do a JavaScript fetch Request?
Thanks for pointing it out, we've put some effort into improving documentation recently, but I admit there's a lot of work remaining on that front. JavaScriptKit doesn't provide bindings for fetch
, but I'm preparing an example that I hope will clarify things. Will post it here as soon as it's ready.
@curveddesign You can see an example of fetch
usage in this PR to our new OpenCombineJS library. It fetches https://httpbin.org/uuid
URL every 2 seconds and displays the result with current time on the page.
Until that PR is merged and the first version of OpenCombineJS is tagged, just feel free to copy the JSPromise
and JSError
extensions from that PR into your project.
Please let me know how that works for you. š