{
"name": "@blocknote/example-liveblocks",
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
"private": true,
"version": "0.12.4",
"scripts": {
"start": "vite",
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint . --max-warnings 0"
},
"engines": {
"node": "^18.19.1"
},
"dependencies": {
"@blocknote/ariakit": "latest",
"@blocknote/core": "latest",
"@blocknote/mantine": "latest",
"@blocknote/react": "latest",
"@blocknote/shadcn": "latest",
"@liveblocks/yjs": "^1.10.0",
"@y-sweet/react": "^0.8.2",
"fs": "^0.0.1-security",
"path": "^0.12.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"sweetalert2": "^11.17.2",
"yjs": "^13.6.19"
},
"devDependencies": {
"@types/node": "^22.7.4",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.10.0",
"vite": "^5.3.4"
},
"eslintConfig": {
"extends": [
"../../../.eslintrc.js"
]
},
"eslintIgnore": [
"dist"
]
}
"use client";
import { useEffect, useState } from "react";
import { YDocProvider, useYDoc, useYjsProvider } from "@y-sweet/react";
import { useCreateBlockNote, DefaultReactSuggestionItem, SuggestionMenuController } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import "./common.css";
import { BlockNoteSchema, defaultInlineContentSpecs, filterSuggestionItems } from "@blocknote/core";
import Swal from "sweetalert2";
import {
fetchWikiData,
frontEndPoint,
getArtifactDetails,
getInitiativeDetails,
getRandomColorFromSet,
handleRedirections,
saveToStorage,
setSubscriptionAndInitiativeId,
uploadFile
} from "./common";
import { Mention } from "./Mention";
// 🔐 Extract encoded data
const search = window.location.search;
const urlParams = new URLSearchParams(search);
const encodedData = urlParams.get("data");
let jsonData = {
alias: "",
initiativeId: "",
id: 0,
userName: "",
subscriptionId: "",
teamId: 0,
isAssociatedWithWorkItem: false,
environmentName: "dev",
userId: 0,
};
if (encodedData) {
const decodedData = atob(encodedData);
const {
alias,
initiativeId,
id,
subscriptionId,
userName,
teamId = 0,
isAssociatedWithWorkItem = false,
environmentName,
userId = 0,
} = JSON.parse(decodedData);
if (!alias || !initiativeId || !id || !subscriptionId || !userName) {
handleRedirections();
}
jsonData = {
alias,
initiativeId,
id,
subscriptionId,
userName,
teamId,
isAssociatedWithWorkItem,
environmentName,
userId,
};
} else {
handleRedirections();
}
if (!jsonData.subscriptionId || !jsonData.initiativeId) {
//@ts-ignore
Swal.fire({
icon: "warning",
title: "Not Logged In",
text: "You are not logged in. Please log in to continue.",
showConfirmButton: false,
timer: null,
backdrop: false,
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false,
showClass: { popup: "" },
hideClass: { popup: "" },
});
throw new Error("You are not logged in. Please log in to continue.");
}
// 🧠 Set default state
setSubscriptionAndInitiativeId(jsonData);
// 📜 Define schema with mention
const schema = BlockNoteSchema.create({
inlineContentSpecs: {
...defaultInlineContentSpecs,
mention: Mention,
},
});
// 🌟 Top-level component with YDocProvider
export default function App() {
const docId = `${jsonData.subscriptionId}_${jsonData.initiativeId}_${jsonData.id}`;
return (
<YDocProvider
docId={docId}
authEndpoint="https://live.example.com/api/auth"
>
<Document />
</YDocProvider>
);
}
// 📄 Main editor document component
let initiativeDetails: any = [];
let artifactDetails: any = [];
function Document() {
const provider = useYjsProvider();
const doc = useYDoc();
const [loading, setLoading] = useState(true);
const editor = useCreateBlockNote({
schema,
collaboration: {
provider,
fragment: doc.getXmlFragment("blocknote"),
user: {
name: jsonData.userName,
color: getRandomColorFromSet(),
},
},
uploadFile,
trailingBlock: false,
});
useEffect(() => {
const init = async () => {
if (!provider.synced || !editor) return;
const isEditorEmpty =
editor.document.length === 1 &&
editor.document[0]?.type === "paragraph" &&
editor.document[0]?.content?.length === 0;
// Only populate if there's no remote content synced
if (isEditorEmpty) {
await fetchWikiData(jsonData, editor);
}
initiativeDetails = await getInitiativeDetails();
artifactDetails = await getArtifactDetails();
setLoading(false);
};
provider.on("sync", init);
return () => provider.off("sync", init);
}, [provider, editor]);
if (loading) return <div>Loading...</div>;
const getMentionMenuItems = (): DefaultReactSuggestionItem[] => {
const users = initiativeDetails.map((item: any) => item.user.firstName);
return users.map((user: any) => ({
title: user,
onItemClick: () =>
editor.insertInlineContent([
{
type: "mention",
props: { user },
},
" ",
]),
}));
};
const getArtifactMenuItems = (): DefaultReactSuggestionItem[] => {
return artifactDetails.map((artifact: any) => ({
title: `${artifact.externalKey} ${artifact.text}`,
onItemClick: () => {
editor.createLink(`${frontEndPoint}${artifact.path}`, artifact.text);
},
}));
};
return (
<BlockNoteView
editor={editor}
theme="light"
onChange={() => {
//@ts-ignore
saveToStorage(editor, editor.document, jsonData);
}}
>
<SuggestionMenuController
triggerCharacter={"@"}
getItems={async (query) =>
//@ts-ignore
filterSuggestionItems(getMentionMenuItems(), query)
}
/>
<SuggestionMenuController
triggerCharacter={"#"}
getItems={async (query) =>
//@ts-ignore
filterSuggestionItems(getArtifactMenuItems(), query)
}
/>
</BlockNoteView>
);
}
As soon as I run the project, I see the content coming in the doc. but withing seconds it goes with a console warning:
TextSelection endpoint not pointing into a node with inline content (doc)
Describe the bug
I started using y-sweet in my project for realtime update, and this error has started coming:
TextSelection endpoint not pointing into a node with inline content (doc)however this a warning but still clears the content from the document
To Reproduce
Package.json:
my App.jsx:
As soon as I run the project, I see the content coming in the doc. but withing seconds it goes with a console warning:
TextSelection endpoint not pointing into a node with inline content (doc)Misc
Any help is highly appreciated!!