| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import { |
| addAuthorRecord, |
| appendInline, |
| buildEmptyParagraph, |
| connectPersona, |
| insertInlineNode, |
| registerCitation, |
| typeIntoParagraph, |
| } from "./lib/yjs-client.js"; |
| import * as Y from "yjs"; |
|
|
| async function main() { |
| console.log("connecting to ws://localhost:5678/collab ..."); |
| const probe = await connectPersona({ |
| url: "ws://localhost:5678/collab", |
| docName: "default", |
| user: { name: "Probe", color: "#ff8800" }, |
| }); |
| console.log("synced"); |
|
|
| |
| addAuthorRecord(probe, { |
| name: "Probe Author", |
| newAffiliation: { name: "Test Lab" }, |
| }); |
| console.log("author pushed, total authors:", probe.frontmatter.authors.length); |
|
|
| |
| |
| |
| const heading = new Y.XmlElement("heading"); |
| heading.setAttribute("level", 2); |
| const paragraph = buildEmptyParagraph(); |
| probe.ydoc.transact(() => { |
| probe.fragment.push([heading, paragraph]); |
| const headingText = new Y.XmlText(); |
| heading.push([headingText]); |
| headingText.insert(0, "Yjs probe section"); |
| }); |
| console.log("heading + empty paragraph pushed"); |
|
|
| await typeIntoParagraph( |
| paragraph, |
| "Typed via a Node-side Yjs peer: text, math ", |
| { cps: 30 }, |
| ); |
| await insertInlineNode(paragraph, { type: "inlineMath", latex: "e^{i\\pi}" }, 120); |
| await typeIntoParagraph(paragraph, ", and a citation chip ", { cps: 30 }); |
|
|
| registerCitation(probe, "probe2026yjs", { |
| id: "probe2026yjs", |
| "citation-key": "probe2026yjs", |
| type: "article-journal", |
| title: "Probing Yjs via a Node peer", |
| author: [{ family: "Probe", given: "Test" }], |
| issued: { "date-parts": [[2026]] }, |
| }); |
| appendInline(paragraph, [ |
| { |
| type: "citation", |
| key: "probe2026yjs", |
| label: "(Probe, 2026)", |
| }, |
| ]); |
| await typeIntoParagraph(paragraph, ".", { cps: 30 }); |
|
|
| |
| console.log("\nfinal paragraph text:"); |
| const walk = (el: Y.XmlElement | Y.XmlText): string => { |
| if (el instanceof Y.XmlText) return el.toString(); |
| if (el.nodeName === "inlineMath") return `$${el.getAttribute("latex")}$`; |
| if (el.nodeName === "citation") return `[${el.getAttribute("label")}]`; |
| return el |
| .toArray() |
| .map((c) => walk(c as Y.XmlElement | Y.XmlText)) |
| .join(""); |
| }; |
| console.log( |
| paragraph |
| .toArray() |
| .map((c) => walk(c as Y.XmlElement | Y.XmlText)) |
| .join(""), |
| ); |
|
|
| console.log("\nclosing..."); |
| probe.destroy(); |
| process.exit(0); |
| } |
|
|
| main().catch((err) => { |
| console.error("probe failed:", err); |
| process.exit(1); |
| }); |
|
|