Yjs를 활용한 인터랙티브 학습
(learn.yjs.dev)- learn.yjs.dev는 현재 배포가 일시 중지되어 학습 콘텐츠를 확인할 수 없음
- 페이지에는
This deployment is temporarily paused라는 상태 외에 중지 원인이 나와 있지 않음 - 배포 재개 시점이나 일정도 공개되어 있지 않음
- Yjs 학습 콘텐츠의 구성, 기능, 예제는 현재 페이지에서 확인할 수 없음
- 지금 판단할 수 있는 범위는 learn.yjs.dev가 임시 중지 상태라는 점뿐임
댓글과 토론
Hacker News 의견들
-
Hey HN! 이걸 만든 Jamsocket 개발자임. Yjs가 익숙하지 않다면, 협업 및 로컬 우선 앱을 만들기 위한 CRDT 라이브러리라고 보면 됨
분산 상태를 다뤄본 적이 없으면 학습 곡선이 꽤 있고, JavaScript 프레임워크 데모의 “hello world” 같은 카운터 증가조차 여러 클라이언트가 끼면 까다로워짐
많은 튜토리얼이 “이 라이브러리와 텍스트 편집기 통합을 설치하면 앱 완성” 식이라 실제로 무슨 일이 벌어지는지에 대한 정신 모델을 주지 못함
그래서 대화형 Yjs 튜토리얼인 Learn Yjs를 만들었고, 로컬 우선 개발을 처음 접하는 사람도 직관적으로 이해하도록 탐색 가능한 데모와 코딩 연습을 많이 넣었음- CRDT와 협업 기능에 관심이 있었는데, 입문할 때마다 가장 큰 장벽이 바로 “라이브러리 설치하면 끝” 식 튜토리얼이었음
WebSocket도 무료 호스팅을 찾기가 조금 더 어려워 보이고, 기존 CRDT 튜토리얼들도 큰 도움이 됐음 - 로컬 우선 앱을 만드는 예제가 있는지 궁금함
순수 HTML/JS와 Alpine으로 작업 중인데, 이런 앱에서도 Yjs를 쓸 수 있는지도 알고 싶음 - 이게 Yrs [0]와도 동작하는지, 아니면 별도 프로젝트인지 궁금함
또 Y-Sweet이 Automerge나 Loro 같은 다른 CRDT 라이브러리와도 동작하는지, 아니면 Yjs 전용인지 알고 싶음
다들 바이너리 파일을 주고받는 구조가 비슷해 보여서 Y-Sweet이 유사 CRDT 구현들과 얼마나 호환되는지 궁금했음
[0] https://github.com/y-crdt/y-crdt - 정말 잘 만들었음. 이걸로 드디어 CRDT를 이해할 수 있을지 궁금하고, 주말에 끝까지 볼 예정임
- CRDT와 협업 기능에 관심이 있었는데, 입문할 때마다 가장 큰 장벽이 바로 “라이브러리 설치하면 끝” 식 튜토리얼이었음
-
Yjs는 좋고, P2P 결과를 얻기 쉬움
다만 Yjs 백엔드, 영속성, 최종적 충돌 해결(편집자 한 명이 너무 오래 오프라인이었던 경우), 기록 되감기는 풀기 어려운 엔지니어링 과제로 보임
Platejs https://platejs.org/ 같은 블록 편집기에서 좋은 경험을 늘 원했음
Liveblocks https://liveblocks.io/text-editor 같은 솔루션이 개발 경험을 단순화하려는 시도는 좋지만, 대부분은 데이터 통제권을 일부 포기해야 함
HN에서 CRDT 키워드 검색을 하면 늘 좋은 결과와 관심이 보이지만, 오픈소스 백엔드 쪽에는 좋은 선택지가 잘 안 보였음. 과거에 여러 번 확인했는데 놓친 게 있다면 알려주면 좋겠음
https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=tru...
대부분은 최소한 Google Docs나 Notion처럼 동작하길 기대하고, 개발자 입장에서는 세부 구현을 깊게 파지 않고도 Postgres JSONB 비슷한 형식으로 비공개 저장되길 바람- 이론상으로는 직렬화된 패치만 배포하면 되지만, 실제 백엔드에서는 현재 문서 상태, 사용자 신원, 어느 정도의 접근 제어까지 함께 알아야 할 수 있음
Go 백엔드에서 Y.js를 쓰고 싶었던 적이 여러 번 있었지만, 단순한 참고 구현을 찾기 어려워 시간 제약 때문에 매번 포기했음
몇 년째 다시 확인해도 Node.js 밖에서는 여전히 어렵게 보임
- 이론상으로는 직렬화된 패치만 배포하면 되지만, 실제 백엔드에서는 현재 문서 상태, 사용자 신원, 어느 정도의 접근 제어까지 함께 알아야 할 수 있음
-
예전에 작은 사이드 프로젝트에서 Yjs를 썼음. 클라이언트 쪽은 배우고 쓰기 꽤 쉬웠음
서버 쪽에서는 단일 바이너리로 배포하고 싶었는데, Node가 아닌 언어 예제, 예를 들어 Rust 포트인 Yrs 예제는 거의 없는 수준이었음
결국 https://github.com/yjs/y-websocket을 약간 수정하고 LevelDB 기반 영속성을 붙였는데, 내 기준으로는 최적이 아니었음
Rust 같은 언어로 영속성을 포함한 서버 쪽을 구현하는 좋은 자료가 있는지 궁금함
기억상 기존 클라이언트 자료는 텍스트 편집기 통합에 많이 치우쳐 있어서, 이 튜토리얼이 정말 유용함. 텍스트 편집기 통합을 쓰지 않았기 때문에 직접 더듬어야 했음- Y-Sweet[1]이 맞을 수도 있음. Learn Yjs의 배너를 구동하는 오픈소스 Rust 서버임
저장소로 S3나 로컬 파일시스템을 쓰고, musl 링크된 몇 MB짜리 바이너리로 컴파일됨
https://github.com/jamsocket/y-sweet
- Y-Sweet[1]이 맞을 수도 있음. Learn Yjs의 배너를 구동하는 오픈소스 Rust 서버임
-
“인덱스를 정수가 아니라 분수로 두는 분수 인덱싱 기법”이라고 하는데, 몇 번이나 쓸 수 있어야 멈추지 않는지 궁금함
- 직접 테스트해보니 1075번이었고, 엄청 큰 값은 아니라서 이 라이브러리의 주요 문제가 될 수도 있어 보임
테스트 코드는 다음과 같음:
let left = 0, right = 1
let rightPrevious = 2
let counter = 0;
while (right > left && right < rightPrevious) {
rightPrevious = right;
right /= 2;
counter++
}
console.log(counter)
저장소를 아주 잠깐 봤지만 이 문제가 처리되는 위치를 찾지는 못했고, 깊게 팔 시간은 없었음. 실제 이슈라면 해결을 도울 수도 있음
- 직접 테스트해보니 1075번이었고, 엄청 큰 값은 아니라서 이 라이브러리의 주요 문제가 될 수도 있어 보임
-
지금 오프라인 동작이 필요한 앱을 만들면서 Yjs를 쓰고 있음
실제로 실시간 협업 앱은 아니지만, 서버를 한 협업자, 앱을 다른 협업자로 생각하면 활용 사례를 쉽게 떠올릴 수 있음 -
Yjs에서 끝내 넘지 못했던 지점은, 이 튜토리얼의 할 일 앱 항목 이동 예제를 일반화하면 너무 빨리 복잡해진다는 것임
서로 관계가 있는 여러 객체가 있으면 같은 Document 안에 넣고 싶어지고, 그 관계를 동기화 상태로 유지하는 데는 튜토리얼의 분수 인덱싱 같은 함정이 많음
그러다 데이터베이스 규모의 항목이 쌓이면 모든 것을 하나의 문서에 넣는 장난감 모델은 어떤 항목이든 읽으려는 쪽에 전체 DB와 그 기록을 보내야 한다는 뜻이 됨
결국 항목을 별도 객체로 나누고 직접 영속화해야 하는데, 문서는 이 튜토리얼 [0] 말고는 없고, 스포일러를 하자면 몇 년째 “Work in Progress - come back later”인 빈 페이지임
그래서 Provider를 만들어 관리하려고 해도 문서 상황은 똑같음 [1]
Subdocuments를 발견하고 이 흔한 문제의 해결책이 있나 싶어 기뻐하지만 [2], 어떤 Provider는 하위 문서 간 관계를 처리하지 못하고, 어떤 Provider는 하위 문서 자체를 지원하지 않음. 결국 직접 Provider를 만들어야 하는데 문서가 없다는 문제로 돌아감
코드를 읽어보려 하면, 결국 Yjs의 핵심은 프로토콜이라는 걸 알게 됨. 그런데 Yjs의 본질인 그 프로토콜도 완전히 문서화되어 있지 않고, 꽤 특이한 코드 여러 곳에 흩어져 있음. 10년 전 Yjs 전신이 어떻게 동작했는지 다룬 논문을 문서로 치지 않는다면 말임
불평으로 쓰려던 건 아니지만, 몇 년 동안 동작하게 만들려고 너무 많은 시간을 썼고, “마법처럼 되죠!” 식 장난감 데모와 실제 무언가 사이의 간격이 너무 큼. 그 부분 문서는 10년 동안 “Work in Progress” 말고는 비어 있었음
이 글의 작성자처럼 Yjs로 수익화를 시도하는 회사들이 그 간극을 메워주길 기대함
[0] https://docs.yjs.dev/tutorials/persisting-the-document-to-a-...
[1] https://docs.yjs.dev/tutorials/creating-a-custom-provider
[2] https://docs.yjs.dev/api/subdocuments
[3] 이 글을 쓰면서 상황이 바뀌었길 바랐지만, 모든 문서는 5년 전처럼 여전히 작업 중이고 하위 문서 지원도 마찬가지로 보임 -
대화형 데모에서 지연 시간 슬라이더가 네트워크 지연이 아니라 디바운스 버퍼처럼 동작해서 당황스러움. 왜 이렇게 했는지 이해가 안 됨
- 여러 위치에서 상태가 변경될 때 생기는 문제를 보여주기에 충분한 가장 단순한 지연 모델을 택했음
이 방식의 장점은 독자에게 어떤 상태도 숨기지 않고 구현할 수 있다는 것임. 파이 차트가 존재하는 유일한 내부 상태를 그대로 드러냄
정확한 네트워크 시뮬레이션이 목적이 아니라, 직관을 만드는 데 목적이 있음
- 여러 위치에서 상태가 변경될 때 생기는 문제를 보여주기에 충분한 가장 단순한 지연 모델을 택했음
-
대화형 데모가 아름다움. 만드는 데 어떤 라이브러리를 썼는지 궁금함
- 사이트 전체는 Astro로 만들었고, 데모는 React로 만든 “상호작용 섬”임
데모는 실제로 내부에서 Yjs를 돌림. 각 “클라이언트”가 자기 문서를 갖고, 사용자가 클릭하면setTimeout으로 지연을 시뮬레이션한 뒤 문서들을 수동으로 서로 병합함. 가운데 타임라인용 세 번째 문서도 있음
그 밖에는 할 일 데모의 드래그 앤 드롭에 dnd kit [1], 애니메이션에 Motion [2], 텍스트 편집기에 CodeMirror [3]를 씀
[1] https://dndkit.com
[2] https://motion.dev
[3] https://codemirror.net
- 사이트 전체는 Astro로 만들었고, 데모는 React로 만든 “상호작용 섬”임
-
배너 이미지 게임이 바보 같지만 재미있음
- 예전 Reddit의 place 같은 놀이가 떠오름
Team purple ftw:
https://imgur.com/a/Oxc6jUA
- 예전 Reddit의 place 같은 놀이가 떠오름
-
드디어 네잎클로버를 만들었는데, 2분쯤 지나 누가 망쳐버렸음
수정: 잠깐, 다들 어디 갔지? 우리가 망가뜨렸거나 내가 차단된 것 같음. 그래도 만든 사람에게 박수를 보냄. 멋진 물건임- 차단된 건 확실히 아님. 잠깐 사람들이 줄어든 것 같고, 지금은 커서가 꽤 많이 보임
참고로 비밀 이모지가 두 개 더 있음
- 차단된 건 확실히 아님. 잠깐 사람들이 줄어든 것 같고, 지금은 커서가 꽤 많이 보임