Проект Fugu — это съедобно?

Никита Дубко, Веб-стандарты

Проект Fugu.
Это съедобно?

🐡

Никита Дубко, Веб-стандарты

Никита
Дубко

Фугу?

Тетродотоксин
Web Capabilities (Project Fugu)
Sensor stack

Веб-приложение
↓↑
Браузер
↓↑
ОС

Просто включите! 🌝

Приватность ⚠️

Распознавание лиц 😱

Геопозиция 🎯

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

Только Chromium? 🤨

Вы можете сделать
много пользователей
счастливее 🤩

Счастье 🤩

Деньги 💰

🪄
Прогрессивное
улучшение

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

Давайте поиграем 🎲

Можем ли мы
что-то сделать
в веб-приложении?

✅ Да

🚫 Нет

Можем ли мы
работать с Bluetooth
в веб-приложении?

✅ Да

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); });

Можем ли мы
менять macOS Touch Bar
из веб-приложения?

🚫 Нет

Issue 897315: macOS Touch Bar API

Можем ли мы
добавить беджик
к иконке приложения
из веб-приложения?

✅ Да

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.
});

Можем ли мы
верифицировать пользователя по SMS
в веб-приложении?

✅ Да

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);
});

Можем ли мы
распознавать
рукописные тексты
в веб-приложении?

✅ Да, но...

Только в ChromeOS 😶

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

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

Я верю в AI 🦾

Можем ли мы
проверять правописание
в веб-приложении?

🚫 Нет, но...

Issue 1216516: Spellcheck API

Можем ли мы
выключить устройство
из веб-приложения?

🚫 Нет, просто нет

Можем ли мы
не давать уснуть экрану
из веб-приложения?

✅ Да

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);

Можем ли мы
получать цвета
с экрана пользователя
в веб-приложении?

✅ Да

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.
}

Можем ли мы
получать информацию об освещении
из веб-приложения?

✅ Да, но...

За флагом 🚩

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();

Можем ли мы
контролировать яркость экрана
из веб-приложения?

🚫 Нет, но...

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
}

Можем ли мы
работать с Lock Screen
из веб-приложения?

🚫 Нет, но...

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");

Можем ли мы
работать с Sony DualShock
из веб-приложения?

✅ Да

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

Можем ли мы
определить,
активен ли пользователь,
из веб-приложения?

✅ Да

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,
});

Можем ли мы
генерировать PDF
из веб-приложения?

🚫 Нет, но...

Issue 1087120: Async Clipboard: Add PDF support

CSS Print Media 🖨

Распечатай мне курсач. На CSS, Никита Дубко

Можем ли мы
управлять множеством экранов
из веб-приложения?

✅ Да

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
}

Можем ли мы
определять степень использования CPU
из веб-приложения?

✅ Да, но...

За флагом 🚩

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

Что дальше? 🔮

Fugu API Tracker
Project Fugu 🐡: What we have enabled

bit.ly/fugu-sync

Project Fugu 🐡: What we have enabled

Участвовать? 🙃

Unlocking new capabilities for the web

Всего хорошего,
и спасибо за рыбу!

mefody.dev/talks/fugu-status/podlodka.html
@dark_mefody
n.a.dubko@gmail.com QR-code with link to the slides
🐡