@witchcraft/editor 0.0.1 → 0.0.2
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 +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +11 -2
- package/dist/runtime/components/Editor.d.vue.ts +1 -1
- package/dist/runtime/components/Editor.vue.d.ts +1 -1
- package/dist/runtime/composables/useEditor.d.ts +1 -1
- package/dist/runtime/composables/useEditor.js +1 -1
- package/dist/runtime/pm/features/DocumentApi/DocumentApi.d.ts +2 -1
- package/dist/runtime/pm/features/DocumentApi/DocumentApi.js +12 -3
- package/dist/runtime/pm/features/DocumentApi/composables/useEditorContent.d.ts +2 -2
- package/package.json +16 -16
- package/src/module.ts +9 -3
- package/src/runtime/composables/useEditor.ts +1 -1
- package/src/runtime/pm/features/DocumentApi/DocumentApi.ts +13 -3
- package/src/runtime/pm/features/DocumentApi/composables/useEditorContent.ts +2 -2
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
package/dist/module.mjs
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { crop } from '@alanscodelog/utils';
|
|
2
|
-
import { createResolver, defineNuxtModule,
|
|
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.2.4"};
|
|
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/
|
|
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/
|
|
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/
|
|
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,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
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/
|
|
4
|
-
import {
|
|
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,
|
|
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:
|
|
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.
|
|
4
|
+
"version": "0.0.2",
|
|
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
|
|
83
|
-
"doc:watch": "onchange -i \"src/**/*.ts\" \"typedoc.config.
|
|
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 --
|
|
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.
|
|
126
|
+
"@witchcraft/ui": "^0.2.3",
|
|
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.
|
|
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.
|
|
151
|
+
"@witchcraft/ui": "^0.2.4",
|
|
152
152
|
"colord": "^2.9.3",
|
|
153
153
|
"defu": "^6.1.4",
|
|
154
154
|
"highlight.js": "^11.11.1",
|
|
@@ -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.
|
|
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": "
|
|
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.
|
|
181
|
+
"@types/node": "^24.5.1",
|
|
182
182
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
183
|
-
"@vitest/browser": "^3.
|
|
184
|
-
"@vitest/coverage-v8": "^3.
|
|
185
|
-
"@witchcraft/ui": "^0.2.
|
|
183
|
+
"@vitest/browser": "^3.2.4",
|
|
184
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
185
|
+
"@witchcraft/ui": "^0.2.3",
|
|
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": "
|
|
196
|
-
"playwright-core": "
|
|
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.
|
|
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
|
-
|
|
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/
|
|
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.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { debounce, type DebounceQueue } from "@alanscodelog/utils/debounce"
|
|
2
2
|
import { unreachable } from "@alanscodelog/utils/unreachable"
|
|
3
|
-
import {
|
|
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 {
|
|
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,
|
|
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:
|
|
18
|
+
editor: ShallowRef<Editor | undefined>,
|
|
19
19
|
content: Ref<Content | undefined>,
|
|
20
20
|
id: Ref<string | undefined>,
|
|
21
21
|
documentApi: DocumentApiInterface | undefined,
|