The Newest JavaScript Technologies in GNOME

igalia 17 views 40 slides Jul 29, 2024
Slide 1
Slide 1 of 40
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40

About This Presentation

An overview of the latest additions to GNOME's JS support.


Slide Content

The Newest JavaScript
Technologies in GNOME
Evan Welsh
 @ewlsh:gnome.org
 ewlsh
Philip Chimento
 @ptomato:gnome.org
 ptomato
GUADEC, July 19, 2024
1

Introduction: What this talk is
about
Using TypeScript to write GNOME apps
Community-led documentation updates
What's new and what's next in GJS?
Thanks to everyone who contributed!
2

Introduction
Presentation is full of links if you want to click through later
If you want to follow along: ptomato.name/talks/guadec2024
㊻, ㊼,
3

CommunityCommunityCommunity
444

State of TypeScript for GNOME
The first beta of unified TypeScript definitions has been published
Since then Pascal has been working on filling in feature gaps and Evan
has been bug hunting.
Thanks to STF funding
5

How to use TypeScript today
A massive shoutout to Chris Davis for working continuously on a
TypeScript template for GJS
Most apps should start there!
6

How to use TypeScript today
(experimental)
If you're developing Shell extensions or are adventurous, the beta
bindings are currently published as NPM packages
Distro packaging with NPM packages is not simple, so proceed
with caution for apps.
We're working to support an ideal format for the TypeScript template
and distro packaging, reach out if you want to help!
7

More Community initiatives
We have a GNOME-home for JavaScript projects now!
gjs.guide
gjs.guide has a new (more official) home at
https://gitlab.gnome.org/World/javascript/gjs-guide
the TypeScript template
The TypeScript template is at
https://gitlab.gnome.org/World/javascript/gnome-typescript-template
8

gjs.guide
Updated and upgraded with better search and easier navigation
Docs written this year...
Extensions, the Shell, and GNOME 46 ( Andy, Javad)
D-Bus ( Andy)
St widget examples ( Nitin Dhembare)
to Sebastian Wiesner, Daniel Steele, Adrien Delessert, Evangelos
Paterakis, "Bytez", Jeffery To, Marko Kocic, Pedro Sader Azevedo and
many more for adding examples, fixing typos, and making the
community better
9

Workbench
10

Workbench improvements
TypeScript support!
Write JS/TS code in Workbench
with autocomplete support
using the language server!
Angelo Verlain
11

What's new in GJSWhat's new in GJSWhat's new in GJS
for GNOME ㊻ and ㊼?for GNOME ㊻ and ㊼?for GNOME ㊻ and ㊼?
121212

Console output ㊻ ㊼
Improvements in logging repository namespaces, e.g.
imports.gi.GLib ㊻ Sriyansh Shivam
Recent improvements in logging objects with circular references,
ParamSpecs, Uint8Arrays ㊼ Gary Li
Improvements to pretty printing in console.log/REPL/debugger is
a great place to get started if you want to contribute to GJS
13

Performance improvements ㊻ ㊼
Performance of setting/getting GObject properties improved
More improvements to come
Marco Trevisan, as usual!
14

Gtk.AccessibleList ㊻
Gtk.AccessibleList can be used to represent list relationships in
GTK4 for better accessibility
widget.update_relation(
Gtk.AccessibleRelation.LABELLED_BY,
new Gtk.AccessibleList([label1, label2]
);
Thanks to STF funding
15

An update on async support
We've been working on getting rid of Gio._promisify...
GObject Introspection now has async annotations ㊻
GLib + GObject Introspection will soon support native async
operations
GJS has a draft MR to support the work ... ㊼?
Thanks to STF funding
16

JS engine upgrades ㊼
GJS's underlying JavaScript engine is the one from Firefox, but
embedded.
Tracks Firefox's long-term support version (currently Firefox ESR
115)
Brings in newer editions of the JS language, and security updates
GNOME ㊼ will upgrade to Firefox ESR 128
17

Intl.Segmenter ㊼
const segmenter = new Intl.Segmenter('en', { granularity: 'word' });
const segments = segmenter.segment('The mile-high city');
for (const { segment, isWordLike } of segments) {
if (isWordLike) {
console.log(segment);
}
}
// The
// mile
// high
// city
18

groupBy ㊼
array = ['the', 'array', 'has', 'words'];
Object.groupBy(array, word => word.length);
// => {
// '3': ['the', 'has'],
// '5': ['array', 'words'],
// }
compare Lodash's _.groupBy()
also Map.groupBy() to create a Map instead of plain object
19

Promise.withResolvers ㊼
Useful for integrating promises with signal-based APIs
function promisifyWebKitDownload(dl) {
let {promise, resolve, reject} = Promise.withResolvers();
const finishID = dl.connect('finished', resolve);
const failID = dl.connect('failed', (_, error) => reject(error));
return promise.finally(() => {
dl.disconnect(finishID);
dl.disconnect(failID);
});
}
20

ArrayBuffer transfer ㊼
Zero-copy ownership takeover of data buffers
async function validateAndWrite(arrayBuffer, stream, prio, cancellable) {
const owned = arrayBuffer.transfer();
// transfer() "detaches" the old object and creates a new one without copying. If we
// didn't transfer, other code might modify arrayBuffer while we await validate()
await validate(owned, cancellable);
const bytes = new Uint8Array(owned);
await stream.write_bytes_async(bytes, prio, cancellable);
}
const bytes = new TextEncoder().encode("a string");
validateAndWrite(bytes.buffer, stream, ...asyncArgs);
setTimeout(() => (bytes[0] = 0x00), 5); //
21

Update your code
GLibUnix / GioUnix / GLibWin32 / GioWin32 ㊻
new Gio.FileIcon(myFile) vs Gio.FileIcon.new(myFile) ㊼
get_data()/set_data() and ref()/unref() are blocked ㊼
22

What's coming down the line in JSWhat's coming down the line in JSWhat's coming down the line in JS
232323

Already implemented in nightly Firefox
new Set methods (union, intersection, etc)
Resizable ArrayBuffer
We'll get these in next year's SpiderMonkey update
24

WinterCG
Common Minimum API Proposal
Any interest in joining this group on GNOME's behalf?
25

Other exciting proposals coming 2025
or 2026
Temporal (I gave a talk on it if you want to know more)
Decorators
Iterator methods
using statements
26

Intl.MessageFormat
Stage 1 proposal, coming farther in the future
Gettext is central to GNOME's workflow, but ...
xgettext has always been a bit hacky to integrate with JS and is
just flat-out broken for backtick strings
We could drop Gettext integration in JS and move to
Intl.MessageFormat for the developer API, while still consuming
the Gettext files from GNOME's translation workflow
Is anyone interested in a proof of concept?
27

And on that note...And on that note...And on that note...
282828

292929

GNOME and Intl
Intl is a global object
Does internationalization stuff for you
Some things awkward to do with Gettext. Intl makes them easy
Some things Gettext does well. Intl is gaining those capabilities...
30

Intl
Intl.Collator - locale-sensitive sort
Intl.DateTimeFormat - print dates and times ("Fri Jul 19")
Intl.DisplayNames - translate names of regions, languages, ...
Intl.ListFormat - print lists ("A, B, and C")
Intl.Locale - information about user's locale conventions
Intl.NumberFormat - print numbers ("€ 0,00")
Intl.PluralRules - select appropriate plural form for language
Intl.RelativeTimeFormat - print relative times ("3 days ago")
Intl.Segmenter ㊼ - split strings into graphemes/words/sentences
31

Why you should use Intl
/* Translators: this is the month name and day number
followed by a time string in 24h format.
i.e. "May 25, 14:30" */
format = N_("%B %-d, %H\u2236%M");
How does the translator know what to put there for their locale?
32

“Well why don't they just read the
manual for strftime?”
33

Why you should use Intl
#. Translators: this is the month name and day number
#. followed by a time string in 24h format.
#. i.e. "May 25, 14:30"
#: js/misc/util.js:255
#, no-c-format
msgid "%B %-d, %H∶%M"
msgstr "%j, %R %p"
34

Why you should use Intl
More readable, even if longer
Less burden on GNOME
translators
format = new Intl.DateTimeFormat(myLocale, {
dateStyle: 'medium',
timeStyle: 'short',
hourCycle: 'h24',
});
format.format(Date.now());
// ⇒ "Jul 17, 2024, 15:36" in my locale
35

Why you should use Intl
Who does translate those, anyway?
ICU project
Unicode Common Locale Data Repository (CLDR)
They have the power of major browser vendors behind them
36

Why you should use Intl
What if I don't like the ICU/CLDR's translations in my UI?
You can still customize them using formatToParts()
37

Why you should use Intl
What if I don't like the ICU/CLDR's translations in my UI?
You can still customize them using formatToParts()
12:00 12∶00
38

Thanks
GJS contributors from 46 and 47
License
Presentation licensed under Creative Commons BY-NC-ND 4.0
39

Questions?Questions?Questions?
‍‍‍
Image: Image: Image: IRCatIRCatIRCat from from from PixabayPixabayPixabay 404040