Skip to content

Commit 7e664c6

Browse files
authored
Announce SwiftWasm 5.5.0 and related releases (#12)
* Announce SwiftWasm 5.5.0 and related releases * Apply suggestions from code review Co-authored-by: Jed Fox <git@jedfox.com> * Mention `JSClosure` reference cycles
1 parent ff12f3e commit 7e664c6

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

Content/posts/5-5-released.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
date: 2021-11-29 10:10
3+
description: SwiftWasm 5.5.0 with support for `async`/`await` and Apple Silicon has been released.
4+
---
5+
6+
# SwiftWasm 5.5.0 is now available
7+
8+
We're happy to announce the new release of SwiftWasm tracking upstream Swift 5.5! Notably, in
9+
this release we've added support for `async`/`await`. This new feature of Swift can be integrated
10+
with JavaScript promises when you're using a new version of
11+
[JavaScriptKit](https://github.com/swiftwasm/JavaScriptKit) that was recently tagged. See the corresponding
12+
section below for more details.
13+
14+
Since multi-threading in WebAssembly is still not supported across all browsers
15+
([Safari is the only one lagging behind](https://webassembly.org/roadmap/)), this release of
16+
SwiftWasm doesn't include the Dispatch library and ships with a single-threaded cooperative executor. This means
17+
that `actor` declarations in your code will behave as plain reference types and will all be scheduled
18+
on the main thread. If you need true parallel computation, you’ll have to write
19+
custom code against the
20+
[Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)
21+
(either via JavaScriptKit or delegating to raw JavaScript) to synchronize
22+
multiple SwiftWasm runtimes.
23+
24+
Additionally, 5.5.0 is the first release of SwiftWasm that supports Apple Silicon natively.
25+
The latest version of [`carton`](https://github.com/swiftwasm/carton) (0.12.0)
26+
will download the `arm64` distribution on Apple Silicon devices.
27+
28+
## New JavaScriptKit runtime
29+
30+
The 0.11 release of [JavaScriptKit](https://github.com/swiftwasm/JavaScriptKit) adds
31+
support for `async`/`await` and `JSPromise` integration. Now instances of this
32+
class have an effectful `async` property `value`. Here's example code that shows you how
33+
can `fetch` browser API be used without callbacks:
34+
35+
```swift
36+
import JavaScriptKit
37+
import JavaScriptEventLoop
38+
39+
// This line is required for `JSPromise.value` to work.
40+
JavaScriptEventLoop.installGlobalExecutor()
41+
42+
private let jsFetch = JSObject.global.fetch.function!
43+
func fetch(_ url: String) -> JSPromise {
44+
JSPromise(jsFetch(url).object!)!
45+
}
46+
47+
struct Response: Decodable {
48+
let uuid: String
49+
}
50+
51+
let alert = JSObject.global.alert.function!
52+
let document = JSObject.global.document
53+
54+
var asyncButtonElement = document.createElement("button")
55+
asyncButtonElement.innerText = "Fetch UUID demo"
56+
asyncButtonElement.onclick = .object(JSClosure { _ in
57+
Task {
58+
do {
59+
let response = try await fetch("https://httpbin.org/uuid").value
60+
let json = try await JSPromise(response.json().object!)!.value
61+
let parsedResponse = try JSValueDecoder().decode(Response.self, from: json)
62+
alert(parsedResponse.uuid)
63+
} catch {
64+
print(error)
65+
}
66+
}
67+
68+
return .undefined
69+
})
70+
71+
_ = document.body.appendChild(asyncButtonElement)
72+
```
73+
74+
Also, in this version of JavaScriptKit we're simplifying the `JSClosure` API. You no longer need to
75+
release instances of this class manually, as they will be automatically garbage-collected by the browser
76+
after neither your Swift code nor the JavaScript runtime hold any references to them. This is achieved with the new
77+
`FinalizationRegistry` Web API, for which we had to significantly increase minimum browser versions
78+
required for JavaScriptKit to work. See [`README.md`](https://github.com/swiftwasm/JavaScriptKit#readme)
79+
in the project repository for more details.
80+
81+
We have to mention that there's still a possibility of reference cycles with this new API. `FinalizationRegistry`
82+
doesn't implement full GC for JS closures, but it only solves dangling closure issue. For example,
83+
in this code
84+
85+
```
86+
var button = document.createElement("button")
87+
button.onclick = .object(JSClosure { [button] in
88+
// this capture makes a reference cycle
89+
print(button)
90+
})
91+
```
92+
93+
a reference cycle is created
94+
95+
```
96+
┌─> JSObject (button in Swift) -> HTMLElement (button in JS) ────┐
97+
└── JSClosure (onclick in Swift) <─> Closure (onclick in JS) <───┘
98+
```
99+
100+
In this case, when `button` element is removed from the main DOM tree, it cannot be deallocated.
101+
The `onlick` closure is still referenced by the button itself. These reference cycles can be resolved
102+
with the usual `weak` captures you're probably used to writing in your AppKit and UIKit code.
103+
104+
## Tokamak
105+
106+
Based on the improvements to JavaScriptKit and major work by our contributors, we're also tagging
107+
a new 0.9.0 release of [Tokamak](https://github.com/TokamakUI/Tokamak), a SwiftUI-compatible
108+
framework for building browser apps with WebAssembly. We've added:
109+
110+
- `Canvas` and `TimelineView` types;
111+
- `onHover` modifier;
112+
- `task` modifier for running `async` functions;
113+
- Sanitizers for the `Text` view.
114+
115+
Tokamak v0.9.0 now requires Swift 5.4 or newer. Swift 5.5 (with SwiftWasm
116+
5.5 when targeting the browser environment) is recommended.
117+
118+
## Acknowledgements
119+
120+
We'd like to thank [our sponsors](https://github.com/sponsors/swiftwasm) for their support, which
121+
allowed us to continue working on SwiftWasm and related project.
122+
123+
Additionally, we'd like to thank everyone who contributed their work and helped us make this release
124+
happen. These new releases wouldn't be possible without the hard work of (in alphabetical order):
125+
126+
- [@agg23](https://github.com/agg23)
127+
- [@carson-katri](https://github.com/carson-katri)
128+
- [@ezraberch](https://github.com/ezraberch)
129+
- [@Feuermurmel](https://github.com/Feuermurmel)
130+
- [@kateinoigakukun](https://github.com/kateinoigakukun)
131+
- [@MaxDesiatov](https://github.com/MaxDesiatov)
132+
- [@mbrandonw](https://github.com/mbrandonw)
133+
- [@PatrickPijnappel](https://github.com/PatrickPijnappel)
134+
- [@yonihemi](https://github.com/yonihemi/)
135+
- all of our users, and everyone working on the Swift project and libraries we depend on!

0 commit comments

Comments
 (0)