1 คะแนน โดย GN⁺ 2025-01-18 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ขณะนี้ learn.yjs.dev หยุดการเผยแพร่ชั่วคราว จึงไม่สามารถดูเนื้อหาการเรียนรู้ได้
  • บนหน้าเว็บไม่มี สาเหตุของการหยุด ระบุไว้ นอกเหนือจากสถานะ This deployment is temporarily paused
  • ยังไม่มีการเปิดเผยเวลาหรือกำหนดการที่จะกลับมาเผยแพร่อีกครั้ง
  • ขณะนี้ไม่สามารถตรวจสอบโครงสร้าง ฟีเจอร์ หรือ例อย่างของเนื้อหาการเรียนรู้ Yjs จากหน้าเว็บได้
  • สิ่งที่ตัดสินได้ในตอนนี้มีเพียง learn.yjs.dev อยู่ในสถานะ หยุดชั่วคราว เท่านั้น

1 ความคิดเห็น

 
GN⁺ 2025-01-18
ความคิดเห็นบน Hacker News
  • Hey HN! ผมเป็นนักพัฒนาจาก Jamsocket ที่ทำสิ่งนี้ขึ้นมา ถ้าไม่คุ้นกับ Yjs ให้มองว่าเป็น ไลบรารี CRDT สำหรับสร้างแอปแบบทำงานร่วมกันและ local-first
    ถ้าไม่เคยจัดการสถานะแบบกระจายมาก่อน เส้นโค้งการเรียนรู้จะค่อนข้างชัน และแม้แต่การเพิ่มค่าตัวนับแบบ “hello world” ในเดโมเฟรมเวิร์ก JavaScript ก็ยังยุ่งยากเมื่อมีไคลเอนต์หลายตัวเข้ามาเกี่ยวข้อง
    บทสอนจำนวนมากเป็นแนว “ติดตั้งไลบรารีนี้กับการผสานรวม text editor แล้วแอปก็เสร็จ” จึงไม่ได้ให้ mental model ว่าจริง ๆ แล้วเกิดอะไรขึ้น
    เลยสร้าง Learn Yjs ซึ่งเป็นบทสอน Yjs แบบอินเทอร์แอ็กทีฟ และใส่เดโมที่สำรวจได้กับแบบฝึกเขียนโค้ดไว้มากมาย เพื่อให้คนที่เพิ่งเริ่มพัฒนาแบบ local-first เข้าใจได้อย่างเป็นธรรมชาติ

    • เคยสนใจ CRDT และฟีเจอร์การทำงานร่วมกัน แต่ทุกครั้งที่เริ่มเรียน อุปสรรคใหญ่ที่สุดก็คือบทสอนแนว “ติดตั้งไลบรารีก็จบ” นี่แหละ
      WebSocket ก็ดูเหมือนจะหาโฮสติ้งฟรีได้ยากขึ้นนิดหน่อย และบทสอน CRDT ที่มีอยู่ก็ช่วยได้มากเหมือนกัน
    • สงสัยว่ามีตัวอย่างการสร้างแอปแบบ local-first หรือไม่
      ตอนนี้กำลังทำด้วย HTML/JS ล้วนและ Alpine และอยากรู้ด้วยว่าในแอปแบบนี้จะใช้ Yjs ได้ไหม
    • สงสัยว่าสิ่งนี้ทำงานกับ Yrs [0] ด้วยหรือเปล่า หรือเป็นโปรเจกต์แยกต่างหาก
      และอยากรู้ว่า Y-Sweet ทำงานกับไลบรารี CRDT อื่น ๆ อย่าง Automerge หรือ Loro ด้วยไหม หรือเฉพาะ Yjs เท่านั้น
      โครงสร้างการส่งไฟล์ไบนารีไปมากันดูคล้ายกัน เลยสงสัยว่า Y-Sweet เข้ากันได้กับการใช้งาน CRDT แบบคล้าย ๆ กันได้แค่ไหน
      [0] https://github.com/y-crdt/y-crdt
    • ทำออกมาได้ดีมาก สงสัยว่าสิ่งนี้จะทำให้เข้าใจ CRDT ได้ในที่สุดไหม และตั้งใจจะดูให้จบช่วงสุดสัปดาห์
  • Yjs ดี และทำให้ได้ผลลัพธ์แบบ P2P ได้ง่าย
    แต่แบ็กเอนด์ของ Yjs, persistence, การแก้ความขัดแย้งขั้นสุดท้าย (กรณีมี editor คนหนึ่งออฟไลน์นานเกินไป) และการย้อนประวัติ ดูเป็นโจทย์วิศวกรรมที่แก้ยาก
    เคยอยากได้ประสบการณ์ที่ดีใน block editor อย่าง Platejs https://platejs.org/ อยู่เสมอ
    โซลูชันอย่าง Liveblocks https://liveblocks.io/text-editor ที่พยายามทำให้ประสบการณ์นักพัฒนาง่ายขึ้นนั้นดี แต่ส่วนใหญ่ต้องยอมสละ สิทธิ์ควบคุมข้อมูล ไปบางส่วน
    เวลาค้นคีย์เวิร์ด CRDT บน HN ก็มักเห็นผลลัพธ์ดี ๆ และความสนใจอยู่เสมอ แต่ฝั่งแบ็กเอนด์โอเพนซอร์สดูไม่ค่อยมีตัวเลือกดี ๆ เคยเช็กมาหลายครั้งแล้ว ถ้ามีอะไรที่ผมพลาดไปก็อยากให้บอก
    https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=tru...
    คนส่วนใหญ่คาดหวังอย่างน้อยให้ทำงานเหมือน Google Docs หรือ Notion และจากมุมมองนักพัฒนา ก็อยากให้จัดเก็บแบบ private ในรูปแบบคล้าย Postgres JSONB ได้ โดยไม่ต้องขุดรายละเอียดการ implement ลึกเกินไป

    • ในเชิงทฤษฎี แค่กระจายแพตช์ที่ serialize แล้วก็พอ แต่ในแบ็กเอนด์จริง ๆ อาจต้องรู้ทั้งสถานะเอกสารปัจจุบัน ตัวตนผู้ใช้ และ การควบคุมการเข้าถึง ในระดับหนึ่งด้วย
      เคยอยากใช้ Y.js ในแบ็กเอนด์ Go หลายครั้ง แต่หา implementation อ้างอิงแบบง่าย ๆ ได้ยาก เลยต้องยอมแพ้ทุกครั้งเพราะข้อจำกัดด้านเวลา
      เช็กซ้ำมาหลายปีแล้ว นอก Node.js ก็ยังดูยากอยู่ดี
  • เคยใช้ Yjs ใน side project เล็ก ๆ มาก่อน ฝั่งไคลเอนต์เรียนและใช้งานค่อนข้างง่าย
    ฝั่งเซิร์ฟเวอร์อยาก deploy เป็นไบนารีเดี่ยว แต่ตัวอย่างภาษาที่ไม่ใช่ Node เช่นตัวอย่าง Yrs ซึ่งเป็นพอร์ต Rust แทบจะไม่มีเลย
    สุดท้ายจึงปรับ https://github.com/yjs/y-websocket เล็กน้อยและใส่ persistence บน LevelDB เข้าไป ซึ่งในมุมผมไม่ใช่ทางเลือกที่เหมาะที่สุด
    สงสัยว่ามีเอกสารดี ๆ สำหรับ implement ฝั่งเซิร์ฟเวอร์ที่รวม persistence ด้วยภาษาอย่าง Rust ไหม
    เท่าที่จำได้ เอกสารฝั่งไคลเอนต์ที่มีอยู่ค่อนข้างเอนเอียงไปทางการผสานรวม text editor ดังนั้นบทสอนนี้จึงมีประโยชน์มากจริง ๆ เพราะไม่ได้ใช้การผสานรวม text editor เลยต้องคลำทางเอง

    • Y-Sweet[1] อาจเป็นสิ่งที่ใช่ เป็นเซิร์ฟเวอร์ Rust โอเพนซอร์สที่ขับเคลื่อนแบนเนอร์ของ Learn Yjs
      ใช้ S3 หรือระบบไฟล์ในเครื่องเป็น storage และคอมไพล์เป็นไบนารีขนาดไม่กี่ MB ที่ลิงก์กับ musl
      https://github.com/jamsocket/y-sweet
  • เขาบอกว่าเป็น “เทคนิค fractional indexing ที่ใช้อินเด็กซ์เป็นเศษส่วนแทนที่จะเป็นจำนวนเต็ม” แต่สงสัยว่าต้องใช้ได้กี่ครั้งถึงจะไม่หยุด

    • ลองทดสอบเองแล้วได้ 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)
      ผมดู repository แบบเร็วมาก ๆ แต่ไม่พบว่าปัญหานี้ถูกจัดการตรงไหน และไม่มีเวลาขุดลึก ถ้าเป็น issue จริงก็อาจช่วยแก้ได้
  • ตอนนี้กำลังใช้ Yjs ขณะสร้างแอปที่ต้อง ทำงานแบบออฟไลน์
    จริง ๆ แล้วไม่ใช่แอปทำงานร่วมกันแบบเรียลไทม์ แต่ถ้ามองว่าเซิร์ฟเวอร์เป็นผู้ร่วมงานคนหนึ่ง และแอปเป็นผู้ร่วมงานอีกคน ก็จะนึก use case ได้ง่าย

  • จุดที่ผมยังข้ามผ่านไม่ได้ใน Yjs คือ เมื่อพยายามทำให้ตัวอย่างการย้ายรายการในแอปสิ่งที่ต้องทำของบทเรียนนี้ใช้ได้ทั่วไป มันจะซับซ้อนเร็วเกินไป
    พอมีหลายอ็อบเจกต์ที่มีความสัมพันธ์กัน ก็อยากใส่ไว้ใน Document เดียวกัน และการรักษาความสัมพันธ์นั้นให้อยู่ในสถานะซิงก์ก็มีหลุมพรางมากมาย เช่น fractional indexing ในบทเรียน
    แล้วเมื่อมีรายการสะสมจนมีขนาดระดับฐานข้อมูล โมเดลของเล่นที่เอาทุกอย่างใส่ไว้ในเอกสารเดียวก็หมายความว่า ฝ่ายใดก็ตามที่ต้องการอ่านรายการใด ๆ ต้องได้รับทั้ง DB ทั้งหมดและประวัติของมันไปด้วย
    สุดท้ายก็ต้องแยกรายการออกเป็นอ็อบเจกต์ต่างหากและทำ persistence เอง แต่เอกสารมีแค่บทเรียนนี้ [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 ปีก่อน และการรองรับเอกสารย่อยก็ดูเหมือนกัน

  • ในเดโมแบบอินเทอร์แอคทีฟ แถบเลื่อน latency ทำงานเหมือนบัฟเฟอร์ debounce ไม่ใช่ ความหน่วงของเครือข่าย เลยทำให้งง ไม่เข้าใจว่าทำไมถึงทำแบบนี้

    • เลือก โมเดลความหน่วง ที่ง่ายที่สุดซึ่งเพียงพอจะแสดงปัญหาที่เกิดเมื่อสถานะเปลี่ยนในหลายตำแหน่ง
      ข้อดีของวิธีนี้คือทำได้โดยไม่ซ่อนสถานะใด ๆ จากผู้อ่าน แผนภูมิวงกลมแสดงสถานะภายในเพียงอย่างเดียวที่มีอยู่ตรง ๆ
      เป้าหมายไม่ใช่การจำลองเครือข่ายอย่างแม่นยำ แต่คือการสร้างสัญชาตญาณความเข้าใจ
  • เดโมแบบอินเทอร์แอคทีฟสวยมาก อยากรู้ว่าใช้ไลบรารีอะไรทำ

    • ทั้งไซต์ทำด้วย Astro และเดโมเป็น “เกาะอินเทอร์แอคชัน” ที่ทำด้วย React
      เดโมรัน Yjs อยู่ข้างในจริง ๆ “ไคลเอนต์” แต่ละตัวมีเอกสารของตัวเอง และเมื่อผู้ใช้คลิก ก็จำลองความหน่วงด้วย setTimeout แล้วค่อยรวมเอกสารเข้าหากันแบบแมนนวล ยังมีเอกสารที่สามสำหรับไทม์ไลน์ตรงกลางด้วย
      นอกจากนั้น ใช้ dnd kit [1] สำหรับ drag and drop ในเดโมสิ่งที่ต้องทำ, Motion [2] สำหรับแอนิเมชัน และ CodeMirror [3] สำหรับตัวแก้ไขข้อความ
      [1] https://dndkit.com
      [2] https://motion.dev
      [3] https://codemirror.net
  • เกมรูปแบนเนอร์ดูงี่เง่าแต่สนุกดี

    • ทำให้นึกถึงเกมแบบ place ของ Reddit สมัยก่อน
      Team purple ftw:
      https://imgur.com/a/Oxc6jUA
  • ในที่สุดก็ทำโคลเวอร์สี่แฉกได้แล้ว แต่ผ่านไปประมาณ 2 นาทีมีคนมาทำพัง
    แก้ไข: เดี๋ยวนะ ทุกคนหายไปไหนกันหมด? ดูเหมือนเราทำมันพังหรือไม่ก็ผมโดนบล็อก แต่ยังไงก็ขอปรบมือให้คนทำ ของเจ๋งมาก

    • แน่นอนว่าไม่ได้ถูกบล็อก ดูเหมือนคนจะน้อยลงไปชั่วคราว และตอนนี้เห็นเคอร์เซอร์ค่อนข้างเยอะแล้ว
      อนึ่ง ยังมี อีโมจิลับ อีกสองตัว