Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 0 additions & 69 deletions .github/workflows/cypress-component.yml

This file was deleted.

110 changes: 0 additions & 110 deletions cypress/component/editor/search.cy.js

This file was deleted.

9 changes: 9 additions & 0 deletions src/declarations.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

declare module '*?raw' {
const content: string
export default content
}
2 changes: 1 addition & 1 deletion src/extensions/RichText.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import LinkBubble from './../extensions/LinkBubble.js'
import LinkPicker from './../extensions/LinkPicker.js'
import Markdown from './../extensions/Markdown.js'
import Mention from './../extensions/Mention.js'
import Search from './../extensions/Search.js'
import Search from './../extensions/Search.ts'
import TextDirection from './../extensions/TextDirection.ts'
import Typography from './../extensions/Typography.ts'
import BulletList from './../nodes/BulletList.js'
Expand Down
19 changes: 19 additions & 0 deletions src/extensions/Search.js → src/extensions/Search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,22 @@ export default Extension.create({
return [searchQuery(), searchDecorations()]
},
})

declare module '@tiptap/core' {
interface Commands<ReturnType> {
Search: {
/**
* Set the text direction attribute
*/
setSearchQuery: (query: string, matchAll?: boolean) => ReturnType
/**
* Unset the text direction attribute
*/
nextMatch: () => ReturnType
/**
* Unset the text direction attribute
*/
previousMatch: () => ReturnType
}
}
}
2 changes: 1 addition & 1 deletion src/helpers/base64.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { fromBase64, toBase64 } from 'lib0/buffer'
*
* @param {ArrayBuffer} data - binary data to encode
*/
export function encodeArrayBuffer(data: ArrayBuffer): string {
export function encodeArrayBuffer(data: Uint8Array<ArrayBufferLike>): string {
const view = new Uint8Array(data)
return toBase64(view)
}
Expand Down
47 changes: 26 additions & 21 deletions src/helpers/yjs.js → src/helpers/yjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,31 @@ import * as decoding from 'lib0/decoding.js'
import * as encoding from 'lib0/encoding.js'
import * as syncProtocol from 'y-protocols/sync'
import * as Y from 'yjs'
import { decodeArrayBuffer, encodeArrayBuffer } from '../helpers/base64.ts'
import { messageSync } from '../services/y-websocket.js'
import { decodeArrayBuffer, encodeArrayBuffer } from './base64'

/**
* Get Document state encode as base64.
*
* Used to store yjs state on the server.
* @param {Y.Doc} ydoc - encode state of this doc
* @return {string}
* @param ydoc - encode state of this doc
*/
export function getDocumentState(ydoc) {
export function getDocumentState(ydoc: Y.Doc): string {
const update = Y.encodeStateAsUpdate(ydoc)
return encodeArrayBuffer(update)
}

/**
*
* @param {Y.Doc} ydoc - apply state to this doc
* @param {string} documentState - base64 encoded doc state
* @param {object} origin - initiator object e.g. WebsocketProvider
* @param ydoc - apply state to this doc
* @param documentState - base64 encoded doc state
* @param origin - initiator object e.g. WebsocketProvider
*/
export function applyDocumentState(ydoc, documentState, origin) {
export function applyDocumentState(
ydoc: Y.Doc,
documentState: string,
origin: object,
) {
const update = decodeArrayBuffer(documentState)
Y.applyUpdate(ydoc, update, origin)
}
Expand All @@ -38,23 +41,24 @@ export function applyDocumentState(ydoc, documentState, origin) {
* i.e. create a sync protocol update message from it
* and encode it and wrap it in a step data structure.
*
* @param {string} documentState - base64 encoded doc state
* @return {{step: string}} base64 encoded yjs sync protocol update message
* @param documentState - base64 encoded doc state
* @return base64 encoded yjs sync protocol update message
*/
export function documentStateToStep(documentState) {
export function documentStateToStep(documentState: string): {
step: string
} {
const message = documentStateToUpdateMessage(documentState)
return { step: encodeArrayBuffer(message) }
}

/**
* Create an update message from a document state
* Create a message from a document state
* i.e. decode the base64 encoded yjs update
* and create a sync protocol update message from it
*
* @param {string} documentState - base64 encoded doc state
* @return {Uint8Array}
* @param documentState - base64 encoded doc state
*/
function documentStateToUpdateMessage(documentState) {
function documentStateToUpdateMessage(documentState: string): Uint8Array {
const update = decodeArrayBuffer(documentState)
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, messageSync)
Expand All @@ -66,11 +70,12 @@ function documentStateToUpdateMessage(documentState) {
* Apply a step to the ydoc.
*
* Only used in tests right now.
* @param {Y.Doc} ydoc - encode state of this doc
* @param {string} step - base64 encoded yjs sync update message
* @param {object} origin - initiator object e.g. WebsocketProvider
* @param ydoc - encode state of this doc
* @param step - step data
* @param step.step - base64 encoded yjs sync update message
* @param origin - initiator object e.g. WebsocketProvider
*/
export function applyStep(ydoc, step, origin = 'origin') {
export function applyStep(ydoc: Y.Doc, step: { step: string }, origin = 'origin') {
const updateMessage = decodeArrayBuffer(step.step)
const decoder = decoding.createDecoder(updateMessage)
const messageType = decoding.readVarUint(decoder)
Expand All @@ -86,9 +91,9 @@ export function applyStep(ydoc, step, origin = 'origin') {
/**
* Log y.js messages with their type and initiator call stack
*
* @param {string} step - Y.js message
* @param step - Y.js message
*/
export function logStep(step) {
export function logStep(step: Uint8Array<ArrayBufferLike>) {
// Create error for stack trace
const err = new Error()

Expand Down
4 changes: 3 additions & 1 deletion src/plugins/searchDecorations.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Plugin, PluginKey } from '@tiptap/pm/state'
import { Decoration, DecorationSet } from '@tiptap/pm/view'
import { searchQueryPluginKey } from './searchQuery.js'

export const searchDecorationsPluginKey = new PluginKey('searchDecorations')

/**
* Search decorations ProseMirror plugin
* Handles highlighting search matches for the search TipTap extension
Expand All @@ -16,7 +18,7 @@ import { searchQueryPluginKey } from './searchQuery.js'
*/
export default function searchDecorations() {
return new Plugin({
key: new PluginKey('searchDecorations'),
key: searchDecorationsPluginKey,
state: {
init(_, { doc }) {
const search = runSearch(doc, '')
Expand Down
2 changes: 1 addition & 1 deletion src/services/Outbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class Outbox {
#syncUpdate = ''
#syncQuery = ''

storeStep(step: ArrayBuffer) {
storeStep(step: Uint8Array<ArrayBufferLike>) {
const encoded = encodeArrayBuffer(step)
if (encoded < 'AAA' || encoded > 'Ag') {
logger.warn('Unexpected step type:', { step, encoded })
Expand Down
2 changes: 1 addition & 1 deletion src/services/SyncService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class SyncService {
}
}

sendStep(step: ArrayBuffer) {
sendStep(step: Uint8Array<ArrayBufferLike>) {
this.#outbox.storeStep(step)
this.sendSteps()
}
Expand Down
Loading
Loading