Giter Club home page Giter Club logo

y-codemirror.next's Issues

Missing license file

Hello.

Could you please add a LICENSE file to the repository? It's defacto standard to have. It also seems that the license specification is missing somewhere in the configuration because on npmjs.com the license field has "none".

image

Thank you.

Doesn't work as intended without being `mounted` in Vue3/Nuxt.

Checklist

Describe the bug

When the CodeMirror 6 instance is not mounted in Vue3(Nuxt, in my case), there are problems with synchronisations. When an instance is running with some text and a new instance is created in another browser tab, there is no synchronisation and there are errors in the console. Errors in the console:
Screenshot 2022-10-13 at 11 06 35 PM
Screenshot 2022-10-13 at 11 06 56 PM

To Reproduce
Steps to reproduce the behavior:

  1. Create a sample Nuxt3 project.
  2. Replace the index.vue with the code bellow, and install libraries as needed:
<template>
    <div class="main" ref="main"></div>
</template>

<script lang="ts">
import Vue from 'vue'

import { EditorState } from '@codemirror/basic-setup'
import { EditorView } from '@codemirror/view'

import * as Y from 'yjs'
// @ts-ignore
import {
    yCollab,
    yUndoManagerKeymap,
} from '~/y-codemirror.next'
import { WebrtcProvider } from 'y-webrtc'
import * as random from 'lib0/random'

const usercolors = [
    { color: '#30bced', light: '#30bced33' },
    { color: '#6eeb83', light: '#6eeb8333' },
    { color: '#ffbc42', light: '#ffbc4233' },
    { color: '#ecd444', light: '#ecd44433' },
    { color: '#ee6352', light: '#ee635233' },
    { color: '#9ac2c9', light: '#9ac2c933' },
    { color: '#8acb88', light: '#8acb8833' },
    { color: '#1be7ff', light: '#1be7ff33' },
]

const userColor = usercolors[random.uint32() % usercolors.length]

const ydoc = new Y.Doc()

const provider = new WebrtcProvider('codemirror6-demo-room-2', ydoc)
const ytext = ydoc.getText('codemirror')

provider.awareness.setLocalStateField('user', {
    name: 'Anonymous ' + Math.floor(Math.random() * 100),
    color: userColor.color,
    colorLight: userColor.light,
})


// This doesn't work as intended:
let state = EditorState.create({
	doc: ytext.toString(),
	extensions: [
		EditorView.lineWrapping,
		yCollab(ytext, provider.awareness),
	],
})

export default Vue.extend({
    name: 'IndexPage',
    mounted() {
		
		// This Works as intended:
		// let state = EditorState.create({
		//     doc: ytext.toString(),
		//     extensions: [
		//         EditorView.lineWrapping,
		//         yCollab(ytext, provider.awareness),
		//     ],
		// })

        /* eslint-env browser */
        new EditorView({
            state,
            // parent: document.body,
            parent: this.$refs.main as Element,
        })
    },
})
</script>

Expected behavior
state should be able to be created without being inside mounted. I have never needed to create state inside mounted before, and there is nothing in the documentation that indicates this should be the case, therefore I believe this is an issue.

Screenshots
Given above.

Environment Information

  • Chromium / Edge
  • Yjs latest version.

Reading ySyncFacet dynamically.

Is your feature request related to a problem? Please describe.

Hi, I am working on this PR jupyterlab/jupyterlab#13093 . There is a need to dynamically update YSyncConfig after the initialization of EditorView. I think ySyncFacet is a nice place to do this. However YSyncPluginValue reads this facet during construction, and caches its value. So changing ySyncFacet after the initialization of EditorView has no effect on YSyncPluginValue.

I am changing ySyncFacet by using CodeMirror compartment.

packages/codemirror/src/editor.ts

...
    const ySyncFacetCompartment = new Compartment();
...
    this._editor = Private.createEditor(
      host,
      fullConfig,
      this._yeditorBinding,
      this._editorConfig,
      [
        this._markField,
        Prec.high(domEventHandlers),
        updateListener,
        translation,
        // might need some precedence setup here.
        ySyncFacetCompartment.of(
          ySyncFacet.of(
            new YSyncConfig(
              this._yeditorBinding?.text,
              this._yeditorBinding?.awareness
            )
          )
        ),
      ]
    );
...
    // every time the model is switched, we need to re-initialize the editor binding
    this.model.sharedModelSwitched.connect(() => {
      this._initializeEditorBinding();

      // it does change ySyncFacet. However YSyncPluginValue already cached old value.
      this._editor.dispatch({
        effects: ySyncFacetCompartment.reconfigure(
          ySyncFacet.of(
            new YSyncConfig(
              this._yeditorBinding?.text,
              this._yeditorBinding?.awareness
            )
          )
        )
      });
    }, this);
...

Describe the solution you'd like

I think just not caching the facet value can solve the problem.

Describe alternatives you've considered

No

Additional context

jupyterlab/jupyterlab#13093

Bump @codemirror peer dependencies to include 0.19?

Is your feature request related to a problem? Please describe.

The current version of @codemirror/state is 0.19.2 and @codemirror/view is 0.19.9. y-codemirror.next specifies ^0.18.0 and this excludes 0.19.*, as far as I understand, because 0.x.y versions are considered to break on every x increment.

As far as I can tell (which is, admittedly, not very far), y-codemirror.next continues to function if @codemirror/* packages are upgraded to 0.19.*, except that npm reports a broken peer dependency.

Describe the solution you’d like

It would be nice if someone knowledgeable about both Yjs and CodeMirror 6 were to review the changes listed as breaking in @codemirror/state 0.19.0 and in @codemirror/view 0.19.1, and either support them in y-codemirror.next or declare that no changes are needed and bump the peer dependency versions to maybe ^0.18.0 || ^0.19.0 or >= 0.18.0 <0.20.

Describe alternatives you’ve considered

For the application I’m trying to develop, staying on CodeMirror 6 0.18 is suboptimal because 0.19 seems to fix some user-visible bugs.

I don’t want to build with CodeMirror 5 now and have to migrate to 6 later, as that would incur twice the integration effort.

Import error

Checklist

Describe the bug

When trying to import { yCollab } from "y-codemirror.next; in a TypeScript file compiled with Webpack 5, I receive the following error:

Module not found: Error: Can't resolve 'y-codemirror.next' in '{absolute-path-to-directory-containing-file-where-imported}'
resolve 'y-codemirror.next' in '{absolute-path-to-directory-containing-file-where-imported}'

...

Field 'browser' doesn't contain a valid alias configuration

...

To Reproduce

Steps to reproduce the behavior:

  1. Attempt the import statement above in a TypeScript project compiled with Webpack 5.

Expected behavior

The import would succeed without incident.

Environment Information

  • [email protected]
  • Potentially relevant tsconfig.json options—
    "compilerOptions": {
      "module": "ES6",
      "moduleResolution": "node",
    },

Additional Information

Thank you for Yjs!!

Set a Default Value to yCollab for The First Co-User

Is your feature request related to a problem? Please describe.
I am creating a collab script editor. It can fetch script from backend, then store is in memfs.

While Open the editor, I don't know how to give a initila value to yCollab.

If give initContent to EditorState.create, some strange things happen

image

export const createEditor = (params: {
  el: HTMLElement;
  provider: WebrtcProvider;
  onSave?: () => boolean;
  initContent?: string;
}) => {
  const { el, provider, onSave, initContent } = params;

  const ydoc = provider.doc;
  const ytext = ydoc.getText("codemirror");

  const undoManager = new Y.UndoManager(ytext);

  provider.awareness.setLocalStateField("user", {
    name: "Anonymous " + Math.floor(Math.random() * 100),
    color: userColor.color,
    colorLight: userColor.light,
  });

  const collabExt = yCollab(ytext, provider.awareness, { undoManager });

  // if (ytext.toJSON().length === 0 && initContent) ytext.insert(0, initContent);

  const state = EditorState.create({
    doc: initContent,
    extensions: [
      basicSetup,
      javascript(),
      collabExt,
      keymap.of([
        {
          key: "Ctrl-s",
          run: onSave,
        },
      ]),
    ],
  });

  const view = new EditorView({
    state,
    parent: el,
  });

  return {
    view,
  };
};

Describe the solution you'd like
I haven't figured out how y-codemirror.next works.

If adding a parameter, will it make the user more clear how to use the default data

const collabExt = yCollab(ytext, provider.awareness, { undoManager, initContent });

Remote Selection Ribbon Doesn't Match That Remote User's Version

The selection ribbon doesn't fill to the right on the first line of multiple selections, for the remote user.

To Reproduce
Steps to reproduce the behavior:

  1. Use Google Chrome to open demo page in two tabs, put each tab's window side by side, left and right
  2. Set the following as the editor content:
const i = 10;
const j = i+1;
  1. On the left tab select from just after the ; on the first line, through to the last ; on the second line
  2. You should be seeing something like the following
    code-mirror-ribbon

Expected behavior
Ribbon for the remainder of the top line in a remote user's multi-line selection should match what the remote user sees. See rounded rectangle on the right of the above screenshot

Environment Information

Import of type-only types in bundled JS breaks build

Describe the bug

The y-codemirror.next package contains invalid JS that causes esbuild to break.
Several files in the package import types from @codemirror/X packages that are not exported by that package.
As it turns out, all those types are used in type annotation comments (which makes sense as they can't be used in code as they're not exported).
As these types are not actually exported, esbuild (correctly) produces an error like: No matching export in "node_modules/@codemirror/X/dist/index.js" for import "Y"

Here are some links to the source:

To Reproduce

Go to https://stackblitz.com/edit/node-jla3pz?file=package.json

In the console, do:

> npm install

Then do:

> npm run build

You should then see the following errors:

❯ npm run build
$ esbuild index.js --bundle --outfile=out.js --external:vue --format=esm
✘ [ERROR] No matching export in "node_modules/@codemirror/view/dist/index.js" for import "DecorationSet"

    node_modules/y-codemirror.next/src/y-remote-selections.js:2:57:
      2 │ ..., EditorView, Decoration, DecorationSet, WidgetType } from '@cod...
        ╵                              ~~~~~~~~~~~~~

✘ [ERROR] No matching export in "node_modules/@codemirror/state/dist/index.js" for import "StateCommand"

    node_modules/y-codemirror.next/src/y-undomanager.js:3:15:
      3 │   EditorState, StateCommand, Facet, Annotation, AnnotationType // e...
        ╵                ~~~~~~~~~~~~

✘ [ERROR] No matching export in "node_modules/@codemirror/view/dist/index.js" for import "KeyBinding"

    node_modules/y-codemirror.next/src/y-undomanager.js:6:33:
      6 │ ... { ViewPlugin, ViewUpdate, KeyBinding, EditorView } from '@codem...
        ╵                               ~~~~~~~~~~

✘ [ERROR] No matching export in "node_modules/@codemirror/state/dist/index.js" for import "Extension"

    node_modules/y-codemirror.next/src/index.js:4:9:
      4 │ import { Extension } from '@codemirror/state' // eslint-disable-line
        ╵          ~~~~~~~~~

4 errors

Expected behavior

The package should by default (without any modifications) also build using esbuild.

Environment Information

  • Browser: Chrome
  • Packages:
  • "@codemirror/basic-setup": "^0.19.0",
  • "@codemirror/lang-javascript": "^0.19.0",
  • "@codemirror/state": "^0.19.0",
  • "@codemirror/view": "^0.19.0",
  • "y-codemirror.next": "^0.1.0",
  • "y-websocket": "^1.3.18",
  • "yjs": "^13.5.22"
  • "esbuild": "^0.14.22"

Additional context

The demo project in the yjs-demos project does work, but that is very likely due to it using webpack and webpack doing some transformations on the source code.

Also see evanw/esbuild#2029 for the original discussion on esbuild's repo.

During collaborative editing, if the user's cursor is on the top, bottom, left, and right borders of the editor, the user name will be overflowed and hidden.

Please save me some time and use the following template. In 90% of all issues I can't reproduce the problem because I don't know what exactly you are doing, in which environment, or which y-* version is responsible. Just use the following template even if you think the problem is obvious.

Checklist

  • During collaborative editing, if the user's cursor is on the top, bottom, left, and right borders of the editor, the user name will be overflowed and hidden.

Describe the bug
During collaborative editing, if the user's cursor is on the top, bottom, left, and right borders of the editor, the user name will be overflowed and hidden.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://demos.yjs.dev/codemirror.next/codemirror.next.html
  2. Open the same demo address again with a new browser
  3. Type in the first line
  4. Observe cursor and username on other clients

Expected behavior
It is expected that the user name can be displayed normally

Screenshots
image

Environment Information
Yjs Demo

Additional context
Add any other context about the problem here.

Add types field in package.json exports

Is your feature request related to a problem? Please describe.
Could not find a declaration file for module 'y-codemirror.next'.
There are types at /dist/src/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'y-codemirror.next' library may need to update its package.json or typings.

Describe the solution you'd like
Add types field

Describe alternatives you've considered

Additional context

Undo/redo does not trigger scroll

Checklist

Describe the bug

Ctrl + z / ctrl + y does not scroll to the place where a change was applied

To Reproduce

  1. Set height or max-height on editor to make it scrollable
  2. Create a document with more lines than fits the viewport
  3. Scroll to the end type something
  4. Scroll to the beginning type press ctrl + z
  5. See no scrolling to the place where change happened

Expected behavior
The changes made by undo manager should result in scrolling the editor to relevant place

Screenshots

y.js bindings for CM6 (does not scroll):
does-not-scroll-on-undo-redo

Native CM6 (scrolls fine):
native-scrolls-ok

Environment Information

  • Chrome 121.0.6167.85
  • Whatever is running on the demo site

this.widgets.destroy is not a function

Please save me some time and use the following template. In 90% of all issues I can't reproduce the problem because I don't know what exactly you are doing, in which environment, or which y-* version is responsible. Just use the following template even if you think the problem is obvious.

Checklist

  • Are you reporting a bug?

I am not sure but it is happening to me when I try to use CodeMirror EditorView in nextjs React with y-codemirror.next, I recreated the demo.

Describe the bug
The error happens when as awarness of yColab triggers as a new client tries to make a transformation

Unhandled Runtime Error
TypeError: this.widget.destroy is not a function

Call Stack
WidgetView.destroy
node_modules/@codemirror/view/dist/index.js (830:0)
LineView.replaceChildren
node_modules/@codemirror/view/dist/index.js (444:0)
replaceRange
node_modules/@codemirror/view/dist/index.js (580:0)
mergeChildrenInto
node_modules/@codemirror/view/dist/index.js (590:0)
LineView.merge
node_modules/@codemirror/view/dist/index.js (1246:0)
replaceRange
node_modules/@codemirror/view/dist/index.js (511:0)
DocView.updateChildren
node_modules/@codemirror/view/dist/index.js (2447:0)
DocView.updateInner
node_modules/@codemirror/view/dist/index.js (2410:0)
DocView.update
node_modules/@codemirror/view/dist/index.js (2390:0)
EditorView.update
node_modules/@codemirror/view/dist/index.js (5821:0)
EditorView._dispatch
node_modules/@codemirror/view/dist/index.js (5713:0)
EditorView.dispatch
node_modules/@codemirror/view/dist/index.js (5769:0)
eval
node_modules/y-codemirror.next/src/y-remote-selections.js (124:0)
eval
node_modules/lib0/observable.js (73:62)
Array.forEach
<anonymous>
Awareness.emit
node_modules/lib0/observable.js (73:62)
Module.applyAwarenessUpdate
node_modules/y-protocols/awareness.js (286:0)
readMessage
node_modules/y-webrtc/src/y-webrtc.js (91:6)
eval
node_modules/y-webrtc/src/y-webrtc.js (330:0)
Room.eval [as mux]
node_modules/lib0/mutex.js (35:0)
eval
node_modules/y-webrtc/src/y-webrtc.js (329:0)

To Reproduce
Steps to reproduce the behavior:

Create this component in React, I am using Nextjs

import * as Y from 'yjs';
import { yCollab, yUndoManagerKeymap } from 'y-codemirror.next';
import { WebrtcProvider } from 'y-webrtc';
import { EditorState, EditorView, basicSetup } from '@codemirror/basic-setup';
import { markdown } from '@codemirror/lang-markdown';
import { defaultHighlightStyle } from '@codemirror/highlight';
import { keymap } from '@codemirror/view';
import { useEffect } from 'react';
import * as random from 'lib0/random';
export const usercolors = [
  { color: '#30bced', light: '#30bced33' },
  { color: '#6eeb83', light: '#6eeb8333' },
  { color: '#ffbc42', light: '#ffbc4233' },
  { color: '#ecd444', light: '#ecd44433' },
  { color: '#ee6352', light: '#ee635233' },
  { color: '#9ac2c9', light: '#9ac2c933' },
  { color: '#8acb88', light: '#8acb8833' },
  { color: '#1be7ff', light: '#1be7ff33' }
];
export const userColor = usercolors[random.uint32() % usercolors.length];
let editor, provider;
let state;
function loadCodemirror2(doc, onDocChange) {
  const ydoc = new Y.Doc();
  provider = new WebrtcProvider('codemirror-demo', ydoc);
  const ytext = ydoc.getText('codemirror');
  provider.awareness.setLocalStateField('user', {
    name: 'Anonymous ' + Math.floor(Math.random() * 100),
    color: userColor.color,
    colorLight: userColor.light,
    destroy(){
      alert('lol')
    }
  });
  state = EditorState.create({
    doc: ytext.toString(),
    extensions: [
      keymap.of([...yUndoManagerKeymap]),
      basicSetup,
      markdown(),
      yCollab(ytext, provider.awareness),
    ]
  });
  editor = new EditorView({
    state,
    parent: document.querySelector('#CMeditor')
  });
}
const CodeMirror = ({ }) => {

  useEffect(() => {
    loadCodemirror2('', ()=>{});

    return () => {
      editor.destroy();
    };
  }, []);
  return (
      <div id="CMeditor">
      </div>
  );
};
export default CodeMirror;
  • import the CodeMirror component, I am using @next/dynamic to import it.
  • Open 2 clients.
  • Write on both clients, error will pop up

Environment Information
Browser: Chrome / Node.js v17.1.0
React 17 / Nextjs

  • Yjs version and the versions of the y-* modules you are using [e.g. yjs v13.0.1, y-webrtc v1.2.1]. Use npm ls yjs to find out the exact version you are using.

├─┬ [email protected]
│ └── [email protected]
├─┬ [email protected]
│ └── [email protected] deduped
└─┬ [email protected]
├─┬ [email protected]
│ └── [email protected] deduped
└── [email protected] deduped

"@codemirror/basic-setup": "^0.19.0",
"@codemirror/lang-markdown": "^0.19.2",
"@codemirror/state": "^0.19.2",
"@codemirror/view": "^0.19.29",
"y-codemirror.next": "^0.1.0",
"y-webrtc": "^10.2.2",
"y-websocket": "^1.3.18"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.