Сергей Орлов
79 subscribers
190 photos
7 videos
3 files
57 links
Это как чат с 谢尔盖 ll↓, только канал с 谢尔盖 ll↓.
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Итак, леди и джентельмены, на этом видео мы можем наблюдать эмбед одного ордо файла в другой. И если этот вкладываемый ордо файл посмел быть текстовым, то его можно редактировать прямо из родительского файла. Невиданное дивное диво! Потестить, как всегда, на margarita.ordo.pink. Напоминаю, пока десктоп онли ☝️
52
Сегодня в орде ничего нового не появилось. Я помогал жене, играл с детями и собирал новую телевизионную тумбу. Вы там тож отдохните, я хз ☝️
4
Я не шучу.
2
Пинкпост от наших дорогих разработчиков:

- Добавлен хоть какой-то вводный экран редактора, когда файл не выбран. А то пустовато было
- К таблице привинчена сортировка по входящим ссылкам
- Исправлена неполадка, в результате которой неверно выполнялась сортировка по исходящим ссылкам: теперь сортировка производится по ссылкам, а не по айдишнику, лол
- Для удобства определения нужного файла, в палитру выбора добавлены иконки соответствуюших файлов
- для текущего файла в таблице теперь можно присваивать не только исходящие, но и входящие ссылки (просто КОСМОС!!!)

Доступно на margarita.ordo.pink
6
Любите, девочки, простых романтиков,
Отважных лётчиков и моряков.
Бросайте, девушки, айтишных мальчиков —
Не стоит им дарить свою любовь.

Браво!
7
Так, ладно, рассказываю. Близится время ререререререлиза (это не клавиатура залипла, это просто уже не помню какой раз, когда я переделываю орду с нуля с учётом всех выявленных недостатков, не совместимых с построением платформы), и я покумекал, поприкладывал всякое к носу, пообкашливал вопросики с братишками, и выглядит так, что это будет работать.

Собственно, что именно будет работать - орда будет датабейслесс. Да, ДАТАБЕЙСЛЕСС. Ничто не будет храниться в базах. Ни в документных, ни в реляционных, ни даже в листовых и кивэльюшных (память текущего сервиса - это тоже ин-мемори БД, прикол! Но это не считается).

FAQ:

> как тогда будет работать авторизация?
Авторизация будет пассвордлесс (да-да, депенденсилесс, датабейслесс, пассвордлесс, юслесс), поэтому в специальном сервисе будет в памяти лежать набор ки-вэлью пар от имейла к коду, отправленному на имейл. Лайфтайм будет n времени. Также при падении сервиса будет обнуляться полностью, так что если падение произошло в момент попытки авторизации код не будет подходить, так что придётся нажимать "Выслать новый код". То же мне проблема, конечно.

> а как идентифицировать пользователя, который аутентифицирован?
We use one cookie. Wait, what?

> где тогда хранятся пользовательские данные?
Они будут храниться прямо в папочке пользователя. Они не будут дублироваться локально, а удалить этот файл будет запрещено законом. Так как все остальные поля пользователя, будем честны, нафиг никому кроме этого пользователя не нужны - пусть у него там и валяется. Заодно GDPRовское право быть забытым будет выполняться простым советским rm -rf /. Да и распределение данных согласно законам Германии, ФЗ и прочих там Карлафоня Прайваси будет реализовано из коробки.

> а можно как-то ссылаться на пользователей вообще?
Ну конечно. У каждого файла есть автор, и не обязательно это будете вы. Есть немалый шанс что это вообще буду только я, но это мы потом увидим. Ну и других пользователей можно собакать через собаку, как и в других приложениях, использующих т.н. username или handle. А для того, чтобы пользователь не смог сбежать от нас после собаканья, редактор будет под капотом подменять username на id. Который, в свою очередь, тоже будет жить в памяти отдельного сервиса, позволяя получать айди по юзернейму, а зная айди можно добыть всё остальное (все файлы пользователей разложены в папки, именованные по айдишнику пользователя). В частности, добывать будем имейл и юзернейм. Имейл будет нужен, когда будем всякие там сторонние авторизации от эполов и гуголов прикручивать будем.

> а если маппинг удалится?
Изи пизи. Если сервис упал, не будет работать автокомплит (то же мне беда!), а после переподнятия сходит и соберёт айдишники из названий папок, а потом и хендлы, хранимые в этих папках.

> а если пользователь поменяет хендл?
Тогда мы просто удаляем его из маппинга и просим его взять новый для конкретного айди. Мы же знаем этот айди. Значит можно сделать.

Итого, получается, что единственный узел системы, неизбежно требующий БД, оказался не таким уж и неизбежно требующим БД, если просто убрать из всей этой схемы пароль. Но если вы настоящий сеньор девелопер, у вас, конечно, на этом этапе уже все волосы должны быть седые, дыбом, и осыпавшиеся.
1005
Добрый доктор всех излечит исцелит.

Но вообще, имею вам сказать, что у меня с ИИ дружба совершенно не клеится. Он не понимает меня, я не понимаю его, руку он опять потерял, а надпись я быстрее сам нарисовал, чем этому дурачку объяснять. Хрень какую-то делал бесконечно.

Скоро релиз орды.
3
Немного новостей

0️⃣ В нашем клубе oath, maoka и zags сегодня появится новый участник — hunt. Hunt — это менеджер команд для внедрения S.P.Q.R. CQRS. Медленно, но верно мы движемся к цели — созданию MAZOHIST-стека!

1️⃣ Zags, отвечающий за query в CQRS паттерне, обзавёлся обновкой — теперь в нём есть метод each, принимающий множественные апдейты. Вызов обработчика подписки с этим методом срабатывает только один раз после применения всех изменений.

2️⃣ В zags заменён принцип сравнения предыдущего и нового состояния. Теперь они сравниваются через deep_equals вместо ссылочного сравнения. Количество вызовов обработчика подписки значительно уменьшено 🤝

3️⃣ Алгоритм deep_equals опубликован отдельным пакетом.

Полезные ссылочки:

- https://jsr.io/@ordo-pink/deep-equals
- https://jsr.io/@ordo-pink/zags
Please open Telegram to view this post
VIEW IN TELEGRAM
8
У меня, короч, давеча спина разболелась. Сильно так, ни согнуться, ни повернуться. В моём возрасте это дело обычное, но привыкнуть к такому нельзя. Хожу, мучаюсь, бахнул обезбола аки врач с тростью. На второй день чую — пора. Руки вперёд вытянул, спину натянул, наклонился, да каааак хрустнул. И всё. Прошло. Как рукой сняло. Ни боли, ни стиснения в движении — как будто и не было ничего. А вы и дальше сидите и думайте, что джаваскрипт плохой язык.
3
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
4
Типы — ПаскальКейсом
Имплементация — снейк _кейсом
Константы — АППЕР_СНЕЙК_КЕЙСОМ

Я что, так многого прошу?
25
Главной причиной, по которой линукс никогда не станет полноценной коммерческой операционной системой является то, что папка opt в нём есть, а папки roznitsa — нет.
7
Основатели ИИ стартапов в 2026 году такие чисто
63
Когда TES6? (в этом меме виноват Женя)
В маоке можно делать рендердом внутри компонента, созданного маокой в рамках другого рендердома. А у вас как дела?
3
Ещё одна имплементация curry

Драсте. Видали вы небось уже тысячу их на своём веку. Через объекты как в лодаше или через оверлоад как в рамде. Или ещё невесть что. Но я, кажется, слепил это дело через старые добрые спреды и рекурсию типов TS5.

Итак, цель. Хотим сделать функцию, частично применимую вплоть до каррирования, да так, чтобы тайп инференс работал. Средство - по сути сама логика имплементации функции curry. Мы принимаем функцию и смотрим на её арность. Если она нулевая, возвращаем обратно - это танк. Если она не нулевая, то спредим, пока не соберём нужное количество аргументов. Причём принимаем пачками - хоть один, хоть десять - лишь бы пролазило в изначальную функцию, которая нам передана. Именно этим путём я и пошёл (в отличие от).

Работать мы будем, конечно же, с кортежами типов. Для того, чтобы полетело, нам нужно:
а) уметь понимать, какие аргументы мы уже частично приняли (звучит как Partial)
б) уметь показывать, какие аргументы нам остались (звучит как Exclude)

У меня вышло как-то так:

export type PartialTuple<$Tuple extends any[]> = $Tuple extends []
? never
: $Tuple extends [...infer _Rest, any]
? $Tuple | PartialTuple<_Rest>
: never

export type ExcludeTuple<$A extends any[], $B extends any[]> = $B extends []
? $A
: $A extends readonly [unknown, ...infer _RestA]
? $B extends readonly [unknown, ...infer _RestB]
? ExcludeTuple<_RestA, _RestB>
: never
: never


Теперь на входе принимаем спред PartialTuple, а на выходе возвращаем результат, если арность аргументов равна длине спреда, либо новый карри, где мы убираем то, что уже передано:

export type Curry<$Args extends any[], $Result> = $Args["length"] extends 0
? () => $Result
: <_NewArgs extends PartialTuple<$Args>>(
...args: _NewArgs extends $Args ? $Args : _NewArgs
) => _NewArgs["length"] extends $Args["length"] ? $Result : Curry<ExcludeTuple<$Args, _NewArgs>, $Result>


Вот, собственно, и вся морока. Всё работает, даже названия параметров подсвечивает на последнем вызове (плюс к карме тому, кто придумает, как поправить, чтобы и на предыдущих подсвечивалось, ибо PartialTuple не спредится как named tuple.

Ну а если забыли импл, то он выглядит например вот так:

import type { Curry } from "./curry.types"

export const curry = <$Args extends any[], $Result>(fn: (...args: $Args) => $Result): Curry<$Args, $Result> =>
function curried(...args: $Args): any {
if (args.length >= fn.length) return fn(...args)
else return (...args2: any[]) => curried(...([...args, ...args2] as $Args))
}

const add = curry((a: number, b: number, c: number) => a + b + c)
console.log(add(1, 2, 3)) // 6
console.log(add(1, 2)(3)) // 6
console.log(add(1)(2, 3)) // 6
console.log(add(1)(2)(3)) // 6


Приятного дня, в общем. Идите работайте.
43
Проверка пермишенов в линуксе работает весьма просто: для каждого действия присвоено значение (1 = Execute, 2 = Write, 4 = Read), а права записаны в виде суммы разрешённых действий, например r-x = 3, а rw- = 6. Теперь, для того, чтобы проверить, можно ли совершить то или иное действие, надо сделать простое советское побитовое И на маску разрешений и на число действия, которое мы хотим выполнить. Если что, маска - это просто максимально допустимое значение пермишена. Прелесть этого бинарного механизма в том, что его можно расширить на любое количество позиций. Например, до пяти, как в орде. It's what makes a Subaru, a Subaru.

export enum PERMISSION {
_____,
____X,
___R_,
___RX,
\__W__,
__W_X,
__WR_,
__WRX,
_U___,
_U__X,
_U_R_,
_U_RX,
_UW__,
_UW_X,
_UWR_,
_UWRX,
S____,
S___X,
S__R_,
S__RX,
S_W__,
S_W_X,
S_WR_,
S_WRX,
SU___,
SU__X,
SU_R_,
SU_RX,
SUW__,
SUW_X,
SUWR_,
SUWRX,
length,
}

export enum ACTION {
EXECUTE = 1,
READ = 2,
WRITE = 4,
UNLINK = 8,
SHARE = 16,
}

export const PERMISSION_MASK = PERMISSION.length - 1

export const check_permission = (
action: ACTION,
permission: PERMISSION
) => !!(p & PERMISSION_MASK & a)
6