Work & Beer Balance
1.53K subscribers
117 photos
5 videos
4 files
189 links
Авторский канал @Akiyamka
Поддержать автора можно здесь:
buymeacoffee.com/cherrytea
Download Telegram
Если вам, как мне, периодически хочется написать какую-то утилиту для которой сli не достаточно - обратите внимание на webview.
Это интересный вариант, как сделать графический интерфейс на веб технологиях и без электрона.

В наличии достаточно фреймворков которые под него заточены, а вот этот реп с табличкой в которой они сравниваются, поможет вам определится что взять.

P.S. Лично мне зашел Neutralino.js, он очень простой и компактный, хотя и немного ограничен по функционалу.
Так же интересно выглядит супер компактный wails, если вас так же как и меня смущают бинарники на сотни мегабайт

#webview
👍3💩2🤔1
Интересные моменты из доклада о JS движке - "Nova", который пишется как "самый интересный движок на rust" человеком из комьюнити Deno

🔸Под капотом использует парсер OXC
🔸 В нем вообще нету AST для VM.
🔸Дизайн движка - DoD (Data Oriented Design).
🔸Ориентирован на экономию места в кэше, для того чтобы сделать максимально быстрым доступ к большинству базовых вещей в js.
🔸 Исходный код структурирован так чтобы отражать EcmaScript спеку 1 в 1. В плане - папки с кодом названы так же как разделы спеки, например.

Что интересного можно узнать из доклада:

🔹в ARM архитектуре заложены специальные инструкции для работы с числами, то как с дробными, то как с целыми, в зависимости от операций, что идеально ложится на то как Number работает в js (совпадение?)

🔹v8 хранит числа попадающие в i32 прямо в стеке, вперемешку вместе с ссылками на другие типы, которые тоже представлены как числа. Значения которые являются настоящими числами а не ссылками специальным образом помечаются. JavaScriptCore поступает аналогично, но хранит в стеке f64.
Это позволяет работать с числами очень быстро, но подобный код считается небезопасным (unsafe) в парадигме rust. Кроме того это полностью ломает управление кэшами в ARM (как то связано с криптографией, но этот момент не был достаточно раскрыт).

🔹Вместо этого в Nova решили использовать Enum для хранения типа, и Vec для хранения значения, что позволило упаковать указатели, и реализовать Value (u8, u32).
В оставшиеся 7 байт впихнули самые популярные строки которые используются в js - value, length, data, т.е. они тоже хранятся в стеке и к ним очень быстрый доступ.

🔹 Вместо того чтобы наследовать все не примитивные типы от объекта, т.е. в стиле ООП, используется компонентный подход. Например массивы не наследуются от объекта, а изначально тупые и приближенные к нативному массиву, так как в основном они используются в таком виде, и только в случае если массив используется каким-то способом специфичным для js (например при попытке перебрать свойства прототипа, или добавить новое свойство, т.е. не числовой индекс и и.т.п) создается обертка в виде объекта, что замедляет "странное" использование массивов, но сильно ускоряет "обыкновенное"

🔹Окончание доклада немного скомканное, т.к. у докладчика заканчивалось время, но насколько я понял, благодаря расту им удалось сделать очень быстрый сборщик мусора, так как движок, в силу особенностей работы с памятью в расте, помечает что нужно почистить прямо в то время, как закончил работу с объектом, так что сборщику не нужно потом прыгать по памяти в поиске того что нужно почистить.
(Этот пункт я возможно понял вообще не правильно)
Больше деталей о сборщике мусора и его особенностях есть в блоге автора, там же добавляет что после его доклада многие заинтересовались и присоединились к проекту, и его так же пригласили рассказать о движке на митинге TC39

Ссылка на доклад
Ссылка на реп
👍16🤯4🙏1🎄1
DOGE команда Илоны недавно получила доступ к финансовым базам данных США. Уже тогда было понятно что ничем хорошим это не закончится, но было интересно как именно они нафакапят.

Ответ не заставил себя долго ждать, в сеть утекло множество засекреченных документов, так что кого-то вероятно теперь посадят на бутылку.

https://www.huffpost.com/entry/elon-musk-doge-posts-classified-data_n_67ae646de4b0513a8d767112
🤡6👎1😁1😢1🤣1
Если вы еще не подписаны на этих ребят, обязательно зацените:

🔹Фронтенд для души
Здесь разрабы не просто двигают кнопки и лутают деньги, а создают шедевры!
Канал с вдохновляющим фронтенд комьюнити, фичами, которых нет в других источниках, регулярными трендовыми идеями и книгами.

🔹 @sysadmin1 - специальный канал для сетевых и системных администраторов, а также инженеров DevOps

🔹cherkashin.dev — фронтенд разработчик в американской компании. Написал расширение Яндекс.Музыки для VS Code.

🔹 Злой полицейский - канал тимлида/разработчика/SOER’а.
Делюсь мыслями про веб, программирование, инструменты, WordPress, Joomla, Laravel, MoonShine, мотивацию, психологию, фильмы, сериалы.

🔹Kobezzza. База в программирование
Канал посвящен промышленной разработке, работе в Бигтехах, фундаментальным основам программирования, Computer Science. Автор канала Андрей Кобец , ex-Яндекс, в разработке 20 лет.

🔹@artalog - Канал автора reatom (стейт менеджер на сигнало-подобной апи, как нибудь расскажу про него подробнее). Постит годноту, и холиварные темы, не соскучитесь
🔥11👍3💩2🍌1
Уже сейчас AI генерирует интегральные схемы которые на практике оказались намного эффективнее того что делает опытный человек, и, что ещё более интересно - для человека они выглядят дико и непонятно, поскольку выходят за рамки принятых в индустрии норм и правил.

Как думаете, сколько месяцев или лет пройдет до того момента чтобы подобное произошло в программировании? Долго ли осталось ждать AI компиляторы кода?

Я не уверен, может зря мы ее обучаем кодить на примерах нашего кода, может надо было скормить ей исходники движка хрома? Дать ей возможность и здесь выходить за рамки принятого?

Есть над чем подумать
👍11😢5🍌4😁1🤔1
Прошла презентация framework.
Чего показали кратко:
🔹Новые материнки с процами для 13шек. Мощнее, холоднее, модели с предыдущей версией материнки подешевели (теперь от $ 740)
🔹Релизнули мини атс десктоп для аишек и игр на базе Ryzen AI MAX. Дешевле аналогичного по мощностям mac studio (4800 vs 1999). Приспособлен собираться в стойки из нескольких штук если хочется домашний кластер
🔹Релизнули 12шки, с тачскрином, аудитория - школьники и студенты, сделано с упором на доступность и неубиваемость
🔹Остальное различные косметические мелочи
👍101
Я бы сам лучше не написал
Мир очень жесток к проигравшим. Ничто не повышает чувство важности больше, чем поставить ногу на череп поверженного и сказать: «Я же говорил! Я был прав!»

Firefox находится на рынке браузеров в позиции проигравшего уже с десяток лет. И теперь, когда схема с продажей людей гуглу через поиск по умолчанию ломается (это 80% дохода), им нужно резко искать новые способы дохода.

Они уже полгода назад предложили решение: они будут продавать агрегированные данные людей специальным провайдерам, которые эти данные будут перепродавать рекламщикам. Те же яйца, только теперь инфраструктура перепродажи не в руках гугла.

Лиса начала переход на такую модель, добавляя новые документы. И тут твиттер и телега взорвались. Все очень возмущены: как же так, а где же белые рукавички и пушистая шерстка?

У тебя, дорогой читатель, есть возможность выбрать стратегию прохождения этого энкаунтера:

Близорукость: перейти на Waterfox, Librewolf, Zen и так далее. Забыв, что если Мозилла умрет, то рескины Firefox помрут вместе с ней.

Лицемерие: перейти на Vivaldi, Opera, и так далее. Не забыв при этом еще крикнуть: «да мозилла же данные людей продает!»

Дальнозоркость: верить в развитие Ladybird, Servo. Это рядом с позицией: «Зачем нам воздух чистить, если мы скоро на Марс полетим?»

Наивность: показательно удивляться, что компании необходимо четко выбирать слова, по которым их могут привести в суд, и что она может поменять условия контракта, если в контракте это указано.

Злорадство: сказать, что все и так было давно понятно, и вообще тебе нечего скрывать и Партия зовет на свершения!

Есть конечно еще скрытые руты прохождения:

Индифферентность: просто пройти мимо, ведь тебя это в действительности не касается.

Рьяность: сказать, что ты будешь «поддерживать хоть сатану, лишь бы он объявил войну гитлеру».

Милосердие: пойти задонатить Мозилле на ее продление ее незавидной жизни.
7👍2🤡2😢1
Стоит ли сделать пост о том как сделать очень простую devtools панель экстеншеном, которая будет показывать определенные события в виде красивого лога?

Спойлер, для этого вам понадобится написать минимум 4 файла которые будут общатся друг с другом по средством событий
inject-script -> content-script -> background-script -> devtools-script
🔥26🍌2
Ситуация - жил был бэкэнд, который умел присылать комментарии в которых могли быть прикрепленные файлы.

А потом бэкэнд решили по дробить на микросервисы помельче, и так у нас появилось два бэкэнда - один для файлов а второй для комментариев.
А это значит что теперь нам вместе с комментарием прилетает только набор id файлов, а все метаданные (название файла например) мы должны получить доп запросом в другой сервис.

У бэкенда стал чище код, но у пользователей стал медленее фронт.

Стоило ли оно того? Есть ли решение win win? Если нет, то как убедить коллегу бэкэндера что комфорт пользователя важнее чистого кода
👍7
thinking модель claude 3.7 Sonnet, в браузере, в процессе анализа почему в моем bash скрипте возникла ошибка написала js программу для подсчета кавычек. Это любопытно, предыдущая версия прямо говорила что не может сама запускать код, а вот в 3.7 ей разрешили использовать js для подсчетов
🔥5
А вы знали что в сети есть общий редис к которому у всех есть доступ на запись и чтение (но не удаление / изменение)?

keyval.org

Удобно для онлайн демок, обучения, в примерах кода, PoC, шеринга чего-то временного.
Сейчас данные хранятся вечно, но в будущем будут очищаться каждую неделю или две.

Там всего два эндпоинта для записи и для чтения, поэтому и "SDK" для него получилась всего в несколько строк

 const key = await KeyVal.save('test');
const val = await KeyVal.get(key);
console.assert(val === 'test', 'Should return saved value');

await KeyVal.set('myKey', 'myVal');
const myVal = await KeyVal.get('myKey');
console.assert(myVal === 'myVal', 'Should return value for myKey');


(открыть в repl)
👍13
Если вас так же как и меня бесит что в zed редакторе не работают базовые шорткаты когда вы не на EN раскладке - вот фикс:
1. Menu -> Open Key BIndings -> Add combinations:
2. Добавляем в массив джейсонину
{
"context": "Editor",
"bindings": {
"ctrl-cyrillic_es": "editor::Copy",
"ctrl-cyrillic_em": "editor::Paste",
"ctrl-cyrillic_che": "editor::Cut",
"ctrl-cyrillic_ef": "editor::SelectAll",
"ctrl-cyrillic_ya": "editor::Undo",
"ctrl-cyrillic_en": "editor::Redo",
"ctrl-cyrillic_a": "buffer_search::Deploy",
"ctrl-cyrillic_yeru": "workspace::Save"
}
}


P.S. Кстати в zed завезли панельку для git
👍7👀4🤡2🤣1
Как преобразовать Map в обычный объект в js?
Часто можно встретить такое решение
function headersToRecord(headers: Headers): Record<string, string> {
const result: Record<string, string> = {};

headers.forEach((value, key) => {
result[key] = value;
});

return result;
}

Это рабочий код, но есть вариант элегантнее: Object.fromEntries(headers)
🔥6🤨6💯5👍3🤣1
windserf_update.sh
2.3 KB
Если захотите попробовать windsurf (аишный форк vscode от codeium), и у вас так же как у меня Fedora,
то вы обнаружите что репозиторий у них только для debian дистров.
Я допилил немного найденный в сети bash, для установки и обновления windsurf на Fedora
👍4🔥21🙏1
Разработчики в 2021 - Я иногда копирую код со staсk overflow, а остальное собираю из библиотек и даже не знаю как они работают (борется с синдромом самозванца)

Разработчики в 2025 - Я пишу этот код одной фичи уже целый день, когда другие люди уже написали весь фронт с нуля и половину инфраструктуры с помощью AI (как назовем этот синдром?)
5😢2🤡1🍌1
А вы знали что в chromium браузерах запрос c payload > 64 KB, при заголовке Keep-Alive: true упадет (TypeError: failed to fetch)?

https://stackoverflow.com/a/65599511
🤔7🤯5👍1
В Zed можно запускать тесты вот такой кнопулчекой напротив его названия.
Однако по умолчанию zed попытается запустить их с помощью встроенного jest-a

Вот только jest остался лишь в моих кошмарных снах, я давно уже на vitest, и как же мне заставить zed использовать его.

Достаточно просто если знать что делать:
1) F1 -> zed: open project tasks (иди без project если вы хотите сделать таску глобальной)

2) добавьте в json массив следующее
{
"label": "Run Vitest",
"command": "npx vitest run",
"tags": [
"ts-test",
"js-test",
"tsx-test"
],
"args": [
"\"$ZED_RELATIVE_FILE\" -t=\"$ZED_SYMBOL\""
],
"shell": "system"
}

3. Перезапустите zed

Это необходимый минимум чтобы vitest заработал.

А вообще там много чего можно настроить, полный файл конфига таски с комментариями ищите в первом сообщении под этим постом
👍13💩31🔥1👀1
Загадка:

Есть вот такой вот тест
import { beforeEach, describe, expect, test, vi } from 'vitest';

interface TestCTX {
storage: MockStore;
}

class MockStore {
kv = new Map();

async writeKVPair(key: string, value: string) {
this.kv.set(key, value);
}

async readValue(key: string) {
return this.kv.get(key);
}

dump(): Record<string, string> {
return Object.fromEntries(this.kv);
}
}

describe('Check command "update"', { sequential: true, concurrent: false }, () => {
beforeEach<TestCTX>(async (ctx) => {
const storage = new MockStore();
vi.doMock('./storage', () => ({ storage }));
ctx.storage = storage;
});

test<TestCTX>('Report saved', async (ctx) => {
const { updateCommand } = await import('./update');
await updateCommand('foo');
const result = ctx.storage.dump();
expect(Object.keys(result).length).toEqual(1);
});

test<TestCTX>('Report save value', async (ctx) => {
const { updateCommand } = await import('./update');
await updateCommand('bar');
const result = ctx.storage.dump();
const firstValue = Object.values(result)[0];
expect(firstValue).toEqual('bar');
});
});

Запускаешь только первый или только второй тест он проходит, а сразу два - всегда падаeт второй тест - он получает result === undefined
Почему?



Ответ:
Если вы замокали модуль в beforeEach это еще не значит что ваш код будет в эти моки ходить. И ESM и CommonJs не грузят модуль каждый раз когда он импортирован, инстанцируют его один раз, а потом кладут в кэш.
Поэтому не смотря на то что модуль мокается перед каждым тестом - все тесты будут использовать только первый мок.

Чтобы этого избежать - нужно вызвать vi.resetModules() перед каждым vi.doMock()
🤔5👍2🔥1🤯1
знаете че такое GDPR? Это когда вас мучают распросами про печенье, да? А что такое TCF и CMP?

Давайте быстренько расскажу а потом будет история из практики.

TCF (Transparency and Consent Framework) - это такой стандарт функции управления согласием XD. Короче, спека как спрашивать про куки и что хранить.
Этот стандарт касается только европы, а так то их много разных (IAB CCPA CF, Google CM, Adobe EPCM, DAA Adchoices, CNIL, ISO/IEC 29184:2020 и тп. кто во что гаразд)

CMP - Consent Management Platform. Это программная обертка вокруг стандарта. Ну чтобы можно было просто дергать методы а оно там само все по стандарту оформлялось и хранилось.
Причем одна CMP может внутри реализовать n TCF. Таких оберток естессно тоже на целый зоопарк.

Все это приправлено драконовскими законами со штрафами до 20 миллионов евро, или 4% годовой прибыли например.

И просто взять и написать свой CMP нельзя - его надо написать по спеке, пройти регистрацию, получить айди. Что-то вроде лицензирования.

Теперь когда вы в курсе че как, ситуация - в мобильном приложении мобильный CMP, внутри него есть вебвью где открывается спа (предназначенная так же и для открытия просто в вэбе) где тоже есть свой CMP.
Разработчики мобилки решили что это тупо два раза спрашивать пользователя и не грузят в вэбвью Js-овский CMP, а одна из SDK пытается его найти в window.
Как я понимаю у них там какая-то жесткая изоляция вэбвью так что они мне только через урл могут пробросить TCF (список того на что согласен юзер), а мне надо притворится CMP для SDK и ответить согласно этой строке, т.е. реализовать один метод.

Но так нельзя, помните я говорил про то что надо лицензию получить на своё CMP решение? Вот такая засада
🤯5💩2👍1🏆1