Project Fugu. Is it edible?

Nikita Dubko, Web Standards

Project Fugu.
Is it edible?

๐Ÿก

Nikita Dubko, Web Standards

Nikita
Dubko

Fugu?

Tetrodotoxin
Web Capabilities (Project Fugu)
Sensor stack

Web App
โ†“โ†‘
Browser
โ†“โ†‘
OS

Just enable it! ๐ŸŒ

Privacy โš ๏ธ

Face detection ๐Ÿ˜ฑ

Geofencing ๐ŸŽฏ

Mozilla Specification Positions
WebKit Feature Status
WebKit's positions on emerging web specifications
Chromium

Just Chromium? ๐Ÿคจ

You can make
a lot of users
happier ๐Ÿคฉ

Happiness ๐Ÿคฉ
โ†“
Money ๐Ÿ’ฐ

๐Ÿช„
Progressive
enhancement

Progressively enhance your PWA
if ('contacts' in navigator) {
    import('./contacts.mjs');
}
const copy = async (blob) => {
    try {
        await navigator.clipboard.write([
            new ClipboardItem({
                [blob.type]: blob,
            }),
        ]);
    } catch (err) {
        console.error(err.name, err.message);
    }
};
Fugu API Tracker

Let's play a game ๐ŸŽฒ

Can we
do something
in web app?

โœ… Yes

๐Ÿšซ No

Can we
work with Bluetooth
in web app?

โœ… Yes

Communicating with Bluetooth devices over JavaScript
navigator.bluetooth.requestDevice({
        filters: [{
            services: [
                0x1234,
                0x12345678,
                '99999999-0000-1000-8000-00805f9b34fb'
            ]
        }]
    })
    .then(device => { /* โ€ฆ */ })
    .catch(error => { console.error(error); });

Can we
change macOS Touch Bar
from web app?

๐Ÿšซ No

Issue 897315: macOS Touch Bar API

Can we
add a badge
to an app icon
from web app?

โœ… Yes

Badging for app icons
const unreadCount = 24;

// Set the badge
navigator.setAppBadge(unreadCount).catch((error) => {
    // Do something with the error.
});

// Clear the badge
navigator.clearAppBadge().catch((error) => {
    // Do something with the error.
});

Can we
verify user via SMS
in web app?

โœ… Yes

Verify phone numbers on the web with the WebOTP API
const ac = new AbortController();

navigator.credentials.get({
    otp: { transport: ['sms'] },
    signal: ac.signal
}).then(otp => {
    input.value = otp.code;
    if (form) form.submit();
}).catch(err => {
    console.log(err);
});

Can we
recognize
handwritten texts
in web app?

โœ… Yes, but...

ChromeOS only ๐Ÿ˜ถ

const modelConstraint = {
    languages: ['en']
};

try {
    const recognizer = await navigator
        .createHandwritingRecognizer(modelConstraint);
    // Do something with recognizer
} catch (err) {
    // Ooops
}

I believe in AI ๐Ÿฆพ

Can we
spellcheck with JS
in web app?

๐Ÿšซ No, but...

Issue 1216516: Spellcheck API

Can we
turn off the device
from web app?

๐Ÿšซ No, just no

Can we
disable locking the screen
from web app?

โœ… Yes

Stay awake with the Screen Wake Lock API
const requestWakeLock = async () => {
    try {
        wakeLock = await navigator.wakeLock.request();
        wakeLock.addEventListener('release', () => {
            console.log('Screen Wake Lock released:', wakeLock.released);
        });
    } catch (err) {
        // Oops
    }
};

await requestWakeLock();
window.setTimeout(() => {
    wakeLock.release();
    wakeLock = null;
}, 5000);

Can we
pick colors
from the screen
in web app?

โœ… Yes

Picking colors of any pixel on the screen with the EyeDropper API
const eyeDropper = new EyeDropper();

try {
    const result = await eyeDropper.open();
    // The user selected a pixel, here is its color:
    const colorHexValue = result.sRGBHex;
} catch (err) {
    // The user escaped the eyedropper mode.
}

Can we
get illuminance data
from web app?

โœ… Yes, but...

Behind a flag ๐Ÿšฉ

const sensor = new AmbientLightSensor();

sensor.addEventListener('reading', (event) => {
    console.log('Current light level:', sensor.illuminance);
});

sensor.addEventListener('error', (event) => {
    console.log(event.error.name, event.error.message);
});

sensor.start();

Can we
control screen brightness
from web app?

๐Ÿšซ No, but...

Design Document: the need to control screen brightness
const lock = await navigator.wakeLock.request({
    increaseBrightness: true
});

// Or
try {
    const sentinel = await screen.requestBrightnessIncrease();
    window.setTimeout(() => {
        await sentinel.release();
    }, 5000);
} catch (e) {
    // Oops
}

Can we
work with Lock Screen
from web app?

๐Ÿšซ No, but...

Issue 1006642: Web API to allow apps to run on the lock screen
// app.manifest
"lock_screen": {
    "start_url": "/some/url"
}

// app.js
const data = await window.getLockScreenData();
await data.setData("my-key", "my-content");

Can we
work with Sony DualShock
from web app?

โœ… Yes

Connecting to uncommon HID devices
WebHID API: Control Everything via USB

Can we
detect user's inactivity
from web app?

โœ… Yes

Detect inactive users with the Idle Detection API
const controller = new AbortController();
const signal = controller.signal;

const idleDetector = new IdleDetector();
idleDetector.addEventListener('change', () => {
    const userState = idleDetector.userState;
    const screenState = idleDetector.screenState;
    console.log(`Idle change: ${userState}, ${screenState}.`);
});

await idleDetector.start({
    threshold: 60000,
    signal,
});

Can we
generate PDF
from web app?

๐Ÿšซ No, but...

Issue 1087120: Async Clipboard: Add PDF support

CSS Print Media ๐Ÿ–จ

Can we
control multiple screens
from web app?

โœ… Yes

Managing several displays with the Multi-Screen Window Placement API
try {
    const screenDetails = await window.getScreenDetails();
    const primaryScreen = screenDetails
        .screens
        .filter((screen) => screen.isPrimary)[0];
    await document.body.requestFullscreen({
        screen: primaryScreen
    });
} catch (err) {
    // Oops
}

Can we
detect CPU utilization
from web app?

โœ… Yes, but...

Behind a flag ๐Ÿšฉ

Observing compute pressure
function callback(update) {
    if (update.cpuSpeed > 0.5) {
        // The CPU is running at faster than base speed.
    } else {
        // The CPU is running at normal or reduced speed.
    }

    if (update.cpuUtilization >= 0.9) {
        // CPU utilization is over 90%.
    } else if (update.cpuUtilization >= 0.5) {
        // CPU utilization is over 50%.
    } else {
        // CPU utilization is under 50%.
    }
}
const observer = new ComputePressureObserver(callback, {
    cpuUtilizationThresholds: [0.5, 0.9],
    cpuSpeedThresholds: [0.5],
});

observer.observe();

// Later
observer.unobserve();

Can I Use? ๐Ÿค”

Project Fugu API showcase
Project Fugu ๐Ÿก API Detector
Project Fugu Detector

What's next? ๐Ÿ”ฎ

Fugu API Tracker
Project Fugu ๐Ÿก: What we have enabled

bit.ly/fugu-sync

Project Fugu ๐Ÿก: What we have enabled

Participate? ๐Ÿ™ƒ

Unlocking new capabilities for the web

Thanks for all the fish!

mefody.dev/talks/fugu-status/
@dark_mefody
n.a.dubko@gmail.com QR-code with link to the slides
๐Ÿก