@witchcraft/editor 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -106,6 +106,7 @@ src/
106
106
  # Dev Notes
107
107
 
108
108
  - Be very careful passing things from vue to tiptap/prosemirror. The reactive wrappings can break a lot of things.
109
+ - If making an editor it MUST use the import from `@tiptap/vue-3` and not `@tiptap/core` as the former will mark itself with vue's markRaw so it doesn't accidentally become reactive.
109
110
  - Be careful when applying steps/transactions across different editor instances. They do not share the same schema instance and are therefore considered incompatible for many operations. Likeliest cause of "invalid content" errors.
110
111
  - Invalid node content errors while testing are likely the result of using an invalid doc since the builder nodes are not created and filled. For example, items require some content (e.g. a paragraph).
111
112
 
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "witchcraftEditor",
3
3
  "configKey": "witchcraftEditor",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,8 +1,13 @@
1
1
  import { crop } from '@alanscodelog/utils';
2
- import { createResolver, defineNuxtModule, installModule, addComponentsDir, addImportsDir, addTemplate } from '@nuxt/kit';
2
+ import { createResolver, defineNuxtModule, addComponentsDir, addImportsDir, addTemplate } from '@nuxt/kit';
3
3
  import { defu } from 'defu';
4
4
  import fs from 'node:fs/promises';
5
5
 
6
+ const dependencies = {
7
+ "@witchcraft/ui": "^0.3.0"};
8
+ const pkg = {
9
+ dependencies: dependencies};
10
+
6
11
  const { resolve } = createResolver(import.meta.url);
7
12
  const module = defineNuxtModule({
8
13
  meta: {
@@ -12,12 +17,16 @@ const module = defineNuxtModule({
12
17
  defaults: {
13
18
  _playgroundWorkaround: false
14
19
  },
20
+ moduleDependencies: {
21
+ "@witchcraft/ui/nuxt": {
22
+ version: pkg.dependencies["@witchcraft/ui"]
23
+ }
24
+ },
15
25
  async setup(options, nuxt) {
16
26
  nuxt.options.runtimeConfig.public.witchcraftEditor = defu(
17
27
  nuxt.options.runtimeConfig.public.witchcraftEditor,
18
28
  {}
19
29
  );
20
- await installModule("@witchcraft/ui/nuxt", nuxt.options.witchcraftUi);
21
30
  addComponentsDir({ path: resolve("./runtime/components") });
22
31
  const pmFeatures = await fs.readdir(resolve("./runtime/pm/features"));
23
32
  for (const feature of pmFeatures) {
@@ -19,7 +19,7 @@ type __VLS_Props = {
19
19
  menus?: Record<string, MenuRenderInfo>;
20
20
  };
21
21
  declare const _default: import("vue").DefineComponent<__VLS_Props, {
22
- editor: import("vue").ShallowRef<import("@tiptap/core").Editor | undefined, import("@tiptap/core").Editor | undefined>;
22
+ editor: import("vue").ShallowRef<import("@tiptap/vue-3").Editor | undefined, import("@tiptap/vue-3").Editor | undefined>;
23
23
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
24
24
  load: () => any;
25
25
  unload: () => any;
@@ -19,7 +19,7 @@ type __VLS_Props = {
19
19
  menus?: Record<string, MenuRenderInfo>;
20
20
  };
21
21
  declare const _default: import("vue").DefineComponent<__VLS_Props, {
22
- editor: import("vue").ShallowRef<import("@tiptap/core").Editor | undefined, import("@tiptap/core").Editor | undefined>;
22
+ editor: import("vue").ShallowRef<import("@tiptap/vue-3").Editor | undefined, import("@tiptap/vue-3").Editor | undefined>;
23
23
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
24
24
  load: () => any;
25
25
  unload: () => any;
@@ -1,5 +1,5 @@
1
1
  import type { EditorOptions } from "@tiptap/core";
2
- import { Editor } from "@tiptap/core";
2
+ import { Editor } from "@tiptap/vue-3";
3
3
  /**
4
4
  * Unline tiptap's useEditor, this does not auto-mount the editor. Instead the returned `recreate` function must be called manually. This was built with the use of {@link useContentEditor} in mind.
5
5
  */
@@ -1,4 +1,4 @@
1
- import { Editor } from "@tiptap/core";
1
+ import { Editor } from "@tiptap/vue-3";
2
2
  import { onBeforeUnmount, shallowRef } from "vue";
3
3
  export const useEditor = (options = {}) => {
4
4
  const editor = shallowRef();
@@ -9,6 +9,10 @@ export const useEditor = (options = {}) => {
9
9
  }
10
10
  onBeforeUnmount(() => {
11
11
  const nodes = editor.value?.options.element;
12
+ if (nodes && !(nodes instanceof HTMLElement)) {
13
+ console.warn(`Expected editor element to be an HTMLElement, got ${nodes.constructor.name}: ${nodes}`);
14
+ return;
15
+ }
12
16
  const newEl = nodes?.cloneNode(true);
13
17
  nodes?.parentNode?.replaceChild(newEl, nodes);
14
18
  editor.value?.destroy();
@@ -5,7 +5,7 @@ export const useWindowDebugging = (editor) => {
5
5
  watch(editor, () => {
6
6
  if (!editor.value) return;
7
7
  if (typeof window === "undefined" || typeof process === "undefined") return;
8
- if (process.env.NODE_ENV === "development" && editor.value !== void 0) {
8
+ if (import.meta.dev && editor.value !== void 0) {
9
9
  const w = window;
10
10
  w.editor = editor.value;
11
11
  w.tr = () => editor.value.state.tr;
@@ -2,7 +2,7 @@ import type { Editor } from "@tiptap/core";
2
2
  import { Plugin, PluginKey } from "@tiptap/pm/state";
3
3
  export declare const debugSelectionPluginKey: PluginKey<any>;
4
4
  /**
5
- * Sets the window title to the current selection for debugging in development mode (by checking process.env.NODE_ENV).
5
+ * Sets the window title to the current selection for debugging in development mode (by checking import.meta.dev).
6
6
  *
7
7
  * For embedded editors, adds the selection as `[from - to]`.
8
8
  */
@@ -11,7 +11,7 @@ export const debugSelectionPlugin = (editor, log = false) => {
11
11
  init() {
12
12
  },
13
13
  apply(tr) {
14
- if (process.env.NODE_ENV === "production") {
14
+ if (!import.meta.dev) {
15
15
  return;
16
16
  }
17
17
  const sel = `${tr.selection.from} - ${tr.selection.to}`;
@@ -1,6 +1,7 @@
1
- import { type Content, Editor, type EditorOptions } from "@tiptap/core";
1
+ import type { Content, EditorOptions } from "@tiptap/core";
2
2
  import type { Schema } from "@tiptap/pm/model";
3
3
  import type { EditorState, Plugin, Transaction } from "@tiptap/pm/state";
4
+ import { Editor } from "@tiptap/vue-3";
4
5
  import type { DocId, DocumentApiInterface, EmbedId, OnSaveDocumentCallback, OnUpdateDocumentCallback } from "./types.js.js";
5
6
  /**
6
7
  * Configures the document api which tells the editor how to load/unload/save/cache documents, including embedded ones.
@@ -1,7 +1,7 @@
1
1
  import { debounce } from "@alanscodelog/utils/debounce";
2
2
  import { unreachable } from "@alanscodelog/utils/unreachable";
3
- import { Editor } from "@tiptap/core";
4
- import { toRaw } from "vue";
3
+ import { Editor } from "@tiptap/vue-3";
4
+ import { isProxy } from "vue";
5
5
  import { convertTransactionForFullState } from "./utils/convertTransactionForFullState.js";
6
6
  import { getEmbedJson } from "./utils/getEmbedJson.js";
7
7
  import { getEmbedNodeFromDoc } from "./utils/getEmbedNodeFromDoc.js";
@@ -87,7 +87,7 @@ export class DocumentApi {
87
87
  const newState = stateBefore.apply(modifiedTr);
88
88
  this._cache.set(embedId.docId, newState);
89
89
  for (const cb of this._callbacks.update) {
90
- cb(embedId, modifiedTr, toRaw(stateBefore), toRaw(newState), updaterSymbol);
90
+ cb(embedId, modifiedTr, stateBefore, newState, updaterSymbol);
91
91
  }
92
92
  }
93
93
  addEventListener(type, cb) {
@@ -110,11 +110,17 @@ export class DocumentApi {
110
110
  if (res === void 0) unreachable();
111
111
  this._loading[docId] = void 0;
112
112
  this._refCounter.load(docId, res);
113
+ if (isProxy(res.state)) {
114
+ throw new Error("State cannot be a reactive proxy. You can use toRaw as a temporary workaround but you should ideally not make it reactive");
115
+ }
113
116
  this._cache.set(docId, res.state);
114
117
  return res;
115
118
  }
116
119
  async _loadInternal({ docId }) {
117
120
  const cachedState = this.getFromCache({ docId }, { errorIfNotFound: false });
121
+ if (isProxy(cachedState)) {
122
+ throw new Error("State cannot be a reactive proxy. You can use toRaw as a temporary workaround but you should ideally not make it reactive");
123
+ }
118
124
  if (cachedState) {
119
125
  const res = { state: cachedState };
120
126
  this._refCounter.load(docId, res);
@@ -146,6 +152,9 @@ export class DocumentApi {
146
152
  if (options?.errorIfNotFound) {
147
153
  throw new Error(`Could not find cached state for document ${docId}. Expected document to be loaded.`);
148
154
  }
155
+ if (isProxy(cached)) {
156
+ throw new Error("State cannot be a reactive proxy. You can use toRaw as a temporary workaround but you should ideally not make it reactive");
157
+ }
149
158
  return void 0;
150
159
  }
151
160
  getEmbeddedContent(embedId) {
@@ -1,5 +1,5 @@
1
1
  import type { Content, Editor, EditorOptions } from "@tiptap/core";
2
- import { type Ref } from "vue";
2
+ import { type Ref, type ShallowRef } from "vue";
3
3
  import type { DocumentApiInterface } from "../types.js.js";
4
4
  /**
5
5
  * Provides two ways to load content into the editor.
@@ -10,4 +10,4 @@ import type { DocumentApiInterface } from "../types.js.js";
10
10
  *
11
11
  * The second option is usually the best, as multiple editors can load the same content and it's automatically kept in sync. See {@link DocumentApi} for more info.
12
12
  */
13
- export declare function useEditorContent(editor: Ref<Editor | undefined>, content: Ref<Content | undefined>, id: Ref<string | undefined>, documentApi: DocumentApiInterface | undefined, recreate: (modifyOptions?: (options: Partial<EditorOptions>) => Partial<EditorOptions>) => void): void;
13
+ export declare function useEditorContent(editor: ShallowRef<Editor | undefined>, content: Ref<Content | undefined>, id: Ref<string | undefined>, documentApi: DocumentApiInterface | undefined, recreate: (modifyOptions?: (options: Partial<EditorOptions>) => Partial<EditorOptions>) => void): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@witchcraft/editor",
3
3
  "description": "Block base prosemirror editor with partial/full editable document embeds, infinite embeds, and document uploads.",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "main": "./dist/runtime/main.lib.js",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -79,11 +79,11 @@
79
79
  "lint:types": "vue-tsc --noEmit",
80
80
  "test": "vitest",
81
81
  "test:watch": "vitest --watch",
82
- "doc": "typedoc --options typedoc.config.js",
83
- "doc:watch": "onchange -i \"src/**/*.ts\" \"typedoc.config.cjs\" -- pnpm doc",
82
+ "doc": "typedoc",
83
+ "doc:watch": "onchange -i \"src/**/*.ts\" \"typedoc.config.js\" -- pnpm doc",
84
84
  "doc:serve": "http-server docs --port=5001",
85
85
  "doc:dev": "concurrently \"pnpm doc:watch\" \"pnpm doc:serve\"",
86
- "doc:check-invalid": "typedoc --options typedoc.config.cjs --listInvalidSymbolLinks",
86
+ "doc:check-invalid": "typedoc --listInvalidSymbolLinks",
87
87
  "//actions:debug": "echo For debugging github build action locally with nektos/act. Requires act and docker. Note: Cache will never work locally because of https://github.com/nektos/act/issues/285",
88
88
  "actions:debug": "act -r -v -j release",
89
89
  "gen:highlightJsLangInfo": "node src/runtime/pm/features/CodeBlock/build/generateHighlightJsInfo.js"
@@ -123,7 +123,7 @@
123
123
  "@tiptap/extension-underline": "^3.4.2",
124
124
  "@tiptap/pm": "^3.4.2",
125
125
  "@tiptap/vue-3": "^3.4.2",
126
- "@witchcraft/ui": "^0.2.1",
126
+ "@witchcraft/ui": "^0.3.0",
127
127
  "tailwindcss": "^4.0.0",
128
128
  "vue": "^3.2.47"
129
129
  },
@@ -140,7 +140,7 @@
140
140
  },
141
141
  "dependencies": {
142
142
  "@alanscodelog/eslint-config": "^6.3.1",
143
- "@alanscodelog/utils": "^6.0.1",
143
+ "@alanscodelog/utils": "^6.0.2",
144
144
  "@commitlint/cli": "^19.8.1",
145
145
  "@fortawesome/fontawesome-svg-core": "^7.0.1",
146
146
  "@fortawesome/free-brands-svg-icons": "^7.0.1",
@@ -148,7 +148,7 @@
148
148
  "@fortawesome/free-solid-svg-icons": "^7.0.1",
149
149
  "@nuxt/eslint-config": "^1.9.0",
150
150
  "@witchcraft/nuxt-utils": "^0.3.2",
151
- "@witchcraft/ui": "^0.2.1",
151
+ "@witchcraft/ui": "^0.3.0",
152
152
  "colord": "^2.9.3",
153
153
  "defu": "^6.1.4",
154
154
  "highlight.js": "^11.11.1",
@@ -158,7 +158,7 @@
158
158
  "nanoid": "^5.1.5",
159
159
  "reka-ui": "^2.5.0",
160
160
  "tailwind-merge": "^3.3.1",
161
- "unplugin-vue-components": "^29.0.0",
161
+ "unplugin-vue-components": "^29.1.0",
162
162
  "uuid": "^13.0.0",
163
163
  "y-prosemirror": "^1.3.7",
164
164
  "yjs": "^13.6.27"
@@ -168,21 +168,21 @@
168
168
  "@alanscodelog/semantic-release-config": "^5.0.4",
169
169
  "@alanscodelog/tsconfigs": "^6.2.0",
170
170
  "@alanscodelog/vite-config": "^0.0.6",
171
- "@iconify/json": "^2.2.384",
171
+ "@iconify/json": "^2.2.385",
172
172
  "@nuxt/kit": "^4.1.2",
173
173
  "@nuxt/module-builder": "^1.0.2",
174
174
  "@nuxt/schema": "^4.1.2",
175
175
  "@nuxt/types": "^2.18.1",
176
- "@playwright/test": "=1.54.0",
176
+ "@playwright/test": "^1.54.0",
177
177
  "@rollup/plugin-dynamic-import-vars": "^2.1.5",
178
178
  "@tailwindcss/cli": "^4.1.13",
179
179
  "@tailwindcss/vite": "^4.1.13",
180
180
  "@testing-library/vue": "^8.1.0",
181
- "@types/node": "^24.4.0",
181
+ "@types/node": "^24.5.1",
182
182
  "@vitejs/plugin-vue": "^6.0.1",
183
- "@vitest/browser": "^3.0.0",
184
- "@vitest/coverage-v8": "^3.0.0",
185
- "@witchcraft/ui": "^0.2.1",
183
+ "@vitest/browser": "^3.2.4",
184
+ "@vitest/coverage-v8": "^3.2.4",
185
+ "@witchcraft/ui": "^0.3.0",
186
186
  "concurrently": "^9.2.1",
187
187
  "cross-env": "^10.0.0",
188
188
  "eslint": "^9.35.0",
@@ -192,8 +192,8 @@
192
192
  "madge": "^8.0.0",
193
193
  "nuxt": "^4.1.2",
194
194
  "onchange": "^7.1.0",
195
- "playwright": "=1.54.0",
196
- "playwright-core": "=1.54.0",
195
+ "playwright": "^1.54.0",
196
+ "playwright-core": "^1.54.0",
197
197
  "prosemirror-test-builder": "^1.1.1",
198
198
  "radix-vue": "^1.9.17",
199
199
  "semantic-release": "^24.2.8",
@@ -202,7 +202,7 @@
202
202
  "typescript": "~5.9.2",
203
203
  "unplugin-icons": "^22.3.0",
204
204
  "vite": "^7.1.5",
205
- "vitest": "^3.0.0",
205
+ "vitest": "^3.2.4",
206
206
  "vue": "^3.5.21",
207
207
  "vue-component-type-helpers": "^3.0.7",
208
208
  "vue-tsc": "^2.2.12"
package/src/module.ts CHANGED
@@ -4,11 +4,13 @@ import {
4
4
  addImportsDir,
5
5
  addTemplate,
6
6
  createResolver,
7
- defineNuxtModule,
8
- installModule } from "@nuxt/kit"
7
+ defineNuxtModule
8
+ } from "@nuxt/kit"
9
9
  import { defu } from "defu"
10
10
  import fs from "node:fs/promises"
11
11
 
12
+ import pkg from "../package.json" with { type: "json" }
13
+
12
14
  const { resolve } = createResolver(import.meta.url)
13
15
 
14
16
  declare module "@nuxt/schema" {
@@ -31,13 +33,17 @@ export default defineNuxtModule<ModuleOptions>({
31
33
  defaults: {
32
34
  _playgroundWorkaround: false
33
35
  },
36
+ moduleDependencies: {
37
+ "@witchcraft/ui/nuxt": {
38
+ version: pkg.dependencies["@witchcraft/ui"]
39
+ }
40
+ },
34
41
  async setup(options, nuxt) {
35
42
  nuxt.options.runtimeConfig.public.witchcraftEditor = defu(
36
43
  nuxt.options.runtimeConfig.public.witchcraftEditor,
37
44
  {
38
45
  }
39
46
  )
40
- await installModule("@witchcraft/ui/nuxt", (nuxt.options as any).witchcraftUi)
41
47
 
42
48
  addComponentsDir({ path: resolve("./runtime/components") })
43
49
 
@@ -1,5 +1,5 @@
1
1
  import type { EditorOptions } from "@tiptap/core"
2
- import { Editor } from "@tiptap/core"
2
+ import { Editor } from "@tiptap/vue-3"
3
3
  import { onBeforeUnmount, shallowRef } from "vue"
4
4
  /**
5
5
  * Unline tiptap's useEditor, this does not auto-mount the editor. Instead the returned `recreate` function must be called manually. This was built with the use of {@link useContentEditor} in mind.
@@ -18,6 +18,11 @@ export const useEditor = (options: Partial<EditorOptions> = {}) => {
18
18
  onBeforeUnmount(() => {
19
19
  // Cloning root node (and its children) to avoid content being lost by destroy
20
20
  const nodes = editor.value?.options.element
21
+ if (nodes && !(nodes instanceof HTMLElement)) {
22
+ // eslint-disable-next-line no-console
23
+ console.warn(`Expected editor element to be an HTMLElement, got ${nodes.constructor.name}: ${nodes}`)
24
+ return
25
+ }
21
26
  const newEl = nodes?.cloneNode(true) as HTMLElement
22
27
 
23
28
  nodes?.parentNode?.replaceChild(newEl, nodes)
@@ -9,7 +9,7 @@ export const useWindowDebugging = (editor: ShallowRef<Editor | undefined>): void
9
9
  watch(editor, () => {
10
10
  if (!editor.value) return
11
11
  if (typeof window === "undefined" || typeof process === "undefined") return
12
- if (process.env.NODE_ENV === "development" && editor.value !== undefined) {
12
+ if (import.meta.dev && editor.value !== undefined) {
13
13
  const w = window as any
14
14
  w.editor = editor.value
15
15
  w.tr = () => editor.value!.state.tr
@@ -9,7 +9,7 @@ const SUB_SELECTION_REGEX = /(\[[0-9 -]*\])/
9
9
 
10
10
  export const debugSelectionPluginKey = new PluginKey("debugSelection")
11
11
  /**
12
- * Sets the window title to the current selection for debugging in development mode (by checking process.env.NODE_ENV).
12
+ * Sets the window title to the current selection for debugging in development mode (by checking import.meta.dev).
13
13
  *
14
14
  * For embedded editors, adds the selection as `[from - to]`.
15
15
  */
@@ -20,7 +20,7 @@ export const debugSelectionPlugin = (editor: Editor, log: boolean = false): Plug
20
20
  state: {
21
21
  init(): void { /**/ },
22
22
  apply(tr: Transaction): void {
23
- if (process.env.NODE_ENV === "production") { return }
23
+ if (!import.meta.dev) { return }
24
24
  const sel = `${tr.selection.from} - ${tr.selection.to}`
25
25
  if (isEmbeddedBlock(editor.view)) {
26
26
  if (log) {
@@ -1,9 +1,10 @@
1
1
  import { debounce, type DebounceQueue } from "@alanscodelog/utils/debounce"
2
2
  import { unreachable } from "@alanscodelog/utils/unreachable"
3
- import { type Content, Editor, type EditorOptions } from "@tiptap/core"
3
+ import type { Content, EditorOptions } from "@tiptap/core"
4
4
  import type { Schema } from "@tiptap/pm/model"
5
5
  import type { EditorState, Plugin, Transaction } from "@tiptap/pm/state"
6
- import { toRaw } from "vue"
6
+ import { Editor } from "@tiptap/vue-3"
7
+ import { isProxy } from "vue"
7
8
 
8
9
  import type { DocId, DocumentApiInterface, EmbedId, OnSaveDocumentCallback, OnUpdateDocumentCallback } from "./types.js"
9
10
  import { convertTransactionForFullState } from "./utils/convertTransactionForFullState.js"
@@ -165,7 +166,7 @@ export class DocumentApi<
165
166
  const newState = stateBefore.apply(modifiedTr)
166
167
  this._cache.set(embedId.docId, newState)
167
168
  for (const cb of this._callbacks.update) {
168
- cb(embedId, modifiedTr, toRaw(stateBefore), toRaw(newState), updaterSymbol)
169
+ cb(embedId, modifiedTr, stateBefore, newState, updaterSymbol)
169
170
  }
170
171
  }
171
172
 
@@ -210,12 +211,18 @@ export class DocumentApi<
210
211
  if (res === undefined) unreachable()
211
212
  this._loading[docId] = undefined
212
213
  this._refCounter.load(docId, res)
214
+ if (isProxy(res.state)) {
215
+ throw new Error("State cannot be a reactive proxy. You can use toRaw as a temporary workaround but you should ideally not make it reactive")
216
+ }
213
217
  this._cache.set(docId, res.state)
214
218
  return res
215
219
  }
216
220
 
217
221
  private async _loadInternal({ docId }: DocId): Promise<{ state: EditorState, data?: T }> {
218
222
  const cachedState = this.getFromCache({ docId }, { errorIfNotFound: false })
223
+ if (isProxy(cachedState)) {
224
+ throw new Error("State cannot be a reactive proxy. You can use toRaw as a temporary workaround but you should ideally not make it reactive")
225
+ }
219
226
  if (cachedState) {
220
227
  const res = { state: cachedState }
221
228
  this._refCounter.load(docId, res)
@@ -256,6 +263,9 @@ export class DocumentApi<
256
263
  if (options?.errorIfNotFound) {
257
264
  throw new Error(`Could not find cached state for document ${docId}. Expected document to be loaded.`)
258
265
  }
266
+ if (isProxy(cached)) {
267
+ throw new Error("State cannot be a reactive proxy. You can use toRaw as a temporary workaround but you should ideally not make it reactive")
268
+ }
259
269
  return undefined
260
270
  }
261
271
 
@@ -1,6 +1,6 @@
1
1
  import type { Content, Editor, EditorOptions } from "@tiptap/core"
2
2
  import type { Transaction } from "@tiptap/pm/state"
3
- import { nextTick, onBeforeUnmount, type Ref, watch } from "vue"
3
+ import { nextTick, onBeforeUnmount, type Ref, type ShallowRef, watch } from "vue"
4
4
 
5
5
  import type { DocumentApiInterface, OnUpdateDocumentCallback } from "../types.js"
6
6
  import { convertTrForInstance } from "../utils/convertTrForInstance.js"
@@ -15,7 +15,7 @@ import { convertTrForInstance } from "../utils/convertTrForInstance.js"
15
15
  * The second option is usually the best, as multiple editors can load the same content and it's automatically kept in sync. See {@link DocumentApi} for more info.
16
16
  */
17
17
  export function useEditorContent(
18
- editor: Ref<Editor | undefined>,
18
+ editor: ShallowRef<Editor | undefined>,
19
19
  content: Ref<Content | undefined>,
20
20
  id: Ref<string | undefined>,
21
21
  documentApi: DocumentApiInterface | undefined,