generated at
scrapbox-userscript-websocket
2024-08-06 scrapbox-userscript-stdと統合したためdeprecated

hr

ScrapboxのUserScriptでWebSocketを使用するための低レイヤーlibrary

提供する機能
socketIO()
CDN経由でSocket.IOのlibraryを読み込み、 Socket を生成して返す
wrap()
Socket の型付きPromise wrapper
socket.io-requestを参考にしている
Scrapboxが使っている通信objectの型定義
ScrapboxがWebSocketで通信しているobjectの一覧で調べた型情報を詰め込んである
helper函数は実装しない

実装したいこと
event listenerの型定義を簡単にする
現状
Parameter<> が入れ子になるなど、型定義が読みにくくなっている
どうするか
入力の型と出力の型とのペアを代わりに使う
これちょっと難しそうだったtakker
response() のほうはそんなに難しそうではないけど
request() のほうがややこしい
入力の型が複数あったりする
現状問題は起きていないので放置する
scrapbox-userscript-stdと分ける必要ある?
型定義の修正で、いちいち2つのrepoを操作しないといけないのが面倒
replacelinksなど、いくつか共通する型定義がある

2022-02-11
16:46:15 ImageCommit image: null も受け取るようだ
修正しよう
16:48:33 done


mod.ts
export * from "https://raw.githubusercontent.com/takker99/scrapbox-userscript-websocket/0.2.4/mod.ts";

mod.js
var m="4.2.0",f=`https://cdnjs.cloudflare.com/ajax/libs/socket.io/${m}/socket.io.min.js`,u;async function v(){let o=(await l())("https://scrapbox.io",{reconnectionDelay:5e3,transports:["websocket"]});return await new Promise((n,s)=>{let r=i=>s(i);o.once("connect",()=>{o.off("disconnect",r),n()}),o.once("disconnect",r)}),o}async function l(){if(!document.querySelector(`script[src="${f}"]`)){let e=document.createElement("script");e.src=f,await new Promise((o,n)=>{e.onload=()=>o(),e.onerror=s=>{u=s,n(s)},document.head.append(e)})}return new Promise((e,o)=>{let n=setInterval(()=>{window.io&&(clearInterval(n),e(window.io))},500)})}function w(e,o=9e4){function n(r,i){let c;return new Promise((d,t)=>{let p=a=>{clearTimeout(c),t(new Error(a))};e.emit(r,i,a=>{clearTimeout(c),e.off("disconnect",p),a.error&&t(new Error(JSON.stringify(a.error))),"data"in a?d(a?.data):d(void 0)}),c=setTimeout(()=>{e.off("disconnect",p),t(new Error(`Timeout: exceeded ${o}ms`))},o),e.once("disconnect",p)})}async function*s(...r){let i,c=()=>new Promise(t=>i=t),d=t=>{i?.(t)};for(let t of r)e.on(t,d);try{for(;;)yield await c()}finally{for(let t of r)e.off(t,d)}}return{request:n,response:s}}export{v as socketIO,w as wrap};

test
streamを購読する.js
import { socketIO, wrap } from "./mod.js"; const io = await socketIO(); const { request, response } = wrap(io); try { await request("socket.io-request", { method: "room:join", data: { projectUpdatesStream: true, projectId: "5f2f02f3c4a48d00237e1534", // takker pageId: null, }, }); for await (const data of response("projectUpdatesStream:commit")) { console.debug(data); } } catch (e) { console.error(e); }


#2024-08-08 09:14:51
#2024-04-19 10:55:18
#2022-02-11 16:49:09
#2021-12-29 07:23:49
#2021-12-09 21:11:14
#2021-12-08 04:46:34
#2021-10-25 17:44:49
#2021-10-24 23:33:05