@lexion-rte/extensions 0.1.0

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/dist/ai.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import type { JSONDocument, LexionEditor, LexionExtension } from "@lexion-rte/core";
2
+ export declare const aiCommandNames: {
3
+ readonly applySuggestion: "ai.applySuggestion";
4
+ };
5
+ export interface AIProviderRequest {
6
+ readonly prompt: string;
7
+ readonly selection: string;
8
+ readonly document: JSONDocument;
9
+ }
10
+ export interface AIProvider {
11
+ generate(request: AIProviderRequest): Promise<string>;
12
+ }
13
+ export declare class AIService {
14
+ private readonly provider;
15
+ constructor(provider: AIProvider);
16
+ generateForSelection(editor: LexionEditor, prompt: string): Promise<string>;
17
+ generateAndApply(editor: LexionEditor, prompt: string): Promise<boolean>;
18
+ }
19
+ export declare const createAIService: (provider: AIProvider) => AIService;
20
+ export declare const aiExtension: LexionExtension;
21
+ //# sourceMappingURL=ai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpF,eAAO,MAAM,cAAc;;CAEjB,CAAC;AAEX,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;gBAEnB,QAAQ,EAAE,UAAU;IAI1B,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW3E,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAOtF;AAED,eAAO,MAAM,eAAe,GAAI,UAAU,UAAU,KAAG,SAAoC,CAAC;AAE5F,eAAO,MAAM,WAAW,EAAE,eAazB,CAAC"}
package/dist/ai.js ADDED
@@ -0,0 +1,40 @@
1
+ export const aiCommandNames = {
2
+ applySuggestion: "ai.applySuggestion"
3
+ };
4
+ export class AIService {
5
+ provider;
6
+ constructor(provider) {
7
+ this.provider = provider;
8
+ }
9
+ async generateForSelection(editor, prompt) {
10
+ const { from, to } = editor.state.selection;
11
+ const selection = editor.state.doc.textBetween(from, to, "\n\n", "\n");
12
+ return this.provider.generate({
13
+ prompt,
14
+ selection,
15
+ document: editor.getJSON()
16
+ });
17
+ }
18
+ async generateAndApply(editor, prompt) {
19
+ const suggestion = await this.generateForSelection(editor, prompt);
20
+ if (suggestion.length === 0) {
21
+ return false;
22
+ }
23
+ return editor.execute(aiCommandNames.applySuggestion, suggestion);
24
+ }
25
+ }
26
+ export const createAIService = (provider) => new AIService(provider);
27
+ export const aiExtension = {
28
+ key: "ai",
29
+ commands: () => ({
30
+ [aiCommandNames.applySuggestion]: (context, suggestionValue) => {
31
+ if (typeof suggestionValue !== "string") {
32
+ return false;
33
+ }
34
+ const { from, to } = context.state.selection;
35
+ context.dispatch(context.state.tr.insertText(suggestionValue, from, to));
36
+ return true;
37
+ }
38
+ })
39
+ };
40
+ //# sourceMappingURL=ai.js.map
package/dist/ai.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe,EAAE,oBAAoB;CAC7B,CAAC;AAYX,MAAM,OAAO,SAAS;IACH,QAAQ,CAAa;IAEtC,YAAmB,QAAoB;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAAC,MAAoB,EAAE,MAAc;QACpE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAEvE,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC5B,MAAM;YACN,SAAS;YACT,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE;SAC3B,CAAC,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,MAAoB,EAAE,MAAc;QAChE,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;IACpE,CAAC;CACF;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAoB,EAAa,EAAE,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE5F,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC1C,GAAG,EAAE,IAAI;IACT,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACf,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE;YAC7D,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE,CAAC;gBACxC,OAAO,KAAK,CAAC;YACf,CAAC;YAED,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;YAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;CACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { LexionExtension } from "@lexion-rte/core";
2
+ import type { Awareness } from "y-protocols/awareness";
3
+ import type { XmlFragment } from "yjs";
4
+ export declare const collaborationCommandNames: {
5
+ readonly undo: "collaboration.undo";
6
+ readonly redo: "collaboration.redo";
7
+ };
8
+ export interface CollaborationExtensionOptions {
9
+ readonly fragment: XmlFragment;
10
+ readonly awareness: Awareness;
11
+ readonly withCursor?: boolean;
12
+ readonly withUndo?: boolean;
13
+ }
14
+ export declare const createCollaborationExtension: (options: CollaborationExtensionOptions) => LexionExtension;
15
+ //# sourceMappingURL=collaboration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaboration.d.ts","sourceRoot":"","sources":["../src/collaboration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAIvC,eAAO,MAAM,yBAAyB;;;CAG5B,CAAC;AAEX,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAKD,eAAO,MAAM,4BAA4B,GACvC,SAAS,6BAA6B,KACrC,eAwBF,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { yCursorPlugin, ySyncPlugin, yUndoPlugin, undo, redo } from "y-prosemirror";
2
+ export const collaborationCommandNames = {
3
+ undo: "collaboration.undo",
4
+ redo: "collaboration.redo"
5
+ };
6
+ const asCommand = (command) => (context) => command(context.state, context.dispatch);
7
+ export const createCollaborationExtension = (options) => {
8
+ const withCursor = options.withCursor ?? true;
9
+ const withUndo = options.withUndo ?? true;
10
+ return {
11
+ key: "collaboration",
12
+ prosemirrorPlugins: () => {
13
+ const plugins = [ySyncPlugin(options.fragment)];
14
+ if (withCursor) {
15
+ plugins.push(yCursorPlugin(options.awareness));
16
+ }
17
+ if (withUndo) {
18
+ plugins.push(yUndoPlugin());
19
+ }
20
+ return plugins;
21
+ },
22
+ commands: () => ({
23
+ [collaborationCommandNames.undo]: asCommand(undo),
24
+ [collaborationCommandNames.redo]: asCommand(redo)
25
+ })
26
+ };
27
+ };
28
+ //# sourceMappingURL=collaboration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collaboration.js","sourceRoot":"","sources":["../src/collaboration.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGpF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE,oBAAoB;CAClB,CAAC;AASX,MAAM,SAAS,GAAG,CAAC,OAAgB,EAAkB,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAClE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,OAAsC,EACrB,EAAE;IACnB,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAE1C,OAAO;QACL,GAAG,EAAE,eAAe;QACpB,kBAAkB,EAAE,GAAG,EAAE;YACvB,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAEhD,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;YACjD,CAAC;YAED,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9B,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACf,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC;YACjD,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC;SAClD,CAAC;KACH,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const starterKitCommandNames: {
2
+ readonly setParagraph: "setParagraph";
3
+ readonly toggleHeading: "toggleHeading";
4
+ readonly toggleBold: "toggleBold";
5
+ readonly toggleItalic: "toggleItalic";
6
+ readonly wrapBulletList: "wrapBulletList";
7
+ readonly wrapOrderedList: "wrapOrderedList";
8
+ readonly liftListItem: "liftListItem";
9
+ readonly sinkListItem: "sinkListItem";
10
+ readonly setLink: "setLink";
11
+ readonly unsetLink: "unsetLink";
12
+ readonly undo: "undo";
13
+ readonly redo: "redo";
14
+ };
15
+ //# sourceMappingURL=command-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-names.d.ts","sourceRoot":"","sources":["../src/command-names.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;CAazB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export const starterKitCommandNames = {
2
+ setParagraph: "setParagraph",
3
+ toggleHeading: "toggleHeading",
4
+ toggleBold: "toggleBold",
5
+ toggleItalic: "toggleItalic",
6
+ wrapBulletList: "wrapBulletList",
7
+ wrapOrderedList: "wrapOrderedList",
8
+ liftListItem: "liftListItem",
9
+ sinkListItem: "sinkListItem",
10
+ setLink: "setLink",
11
+ unsetLink: "unsetLink",
12
+ undo: "undo",
13
+ redo: "redo"
14
+ };
15
+ //# sourceMappingURL=command-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-names.js","sourceRoot":"","sources":["../src/command-names.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,YAAY,EAAE,cAAc;IAC5B,aAAa,EAAE,eAAe;IAC9B,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,cAAc;IAC5B,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;CACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { starterKitCommandNames } from "./command-names.js";
2
+ export { createStarterKitCommands, createStarterKitSchema, starterKitExtension, starterKitSchema } from "./starter-kit.js";
3
+ export { aiCommandNames, aiExtension, AIService, createAIService } from "./ai.js";
4
+ export { collaborationCommandNames, createCollaborationExtension } from "./collaboration.js";
5
+ export type { HeadingAttributes, LinkAttributes } from "./types.js";
6
+ export type { AIProvider, AIProviderRequest } from "./ai.js";
7
+ export type { CollaborationExtensionOptions } from "./collaboration.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC3H,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAC7F,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC7D,YAAY,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { starterKitCommandNames } from "./command-names.js";
2
+ export { createStarterKitCommands, createStarterKitSchema, starterKitExtension, starterKitSchema } from "./starter-kit.js";
3
+ export { aiCommandNames, aiExtension, AIService, createAIService } from "./ai.js";
4
+ export { collaborationCommandNames, createCollaborationExtension } from "./collaboration.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC3H,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Schema } from "prosemirror-model";
2
+ import type { CommandMap, LexionExtension } from "@lexion-rte/core";
3
+ export declare const createStarterKitSchema: () => Schema;
4
+ export declare const starterKitSchema: Schema<any, any>;
5
+ export declare const createStarterKitCommands: () => CommandMap;
6
+ export declare const starterKitExtension: LexionExtension;
7
+ //# sourceMappingURL=starter-kit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"starter-kit.d.ts","sourceRoot":"","sources":["../src/starter-kit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAgC,MAAM,mBAAmB,CAAC;AASzE,OAAO,KAAK,EAAkB,UAAU,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAOpF,eAAO,MAAM,sBAAsB,QAAO,MAItC,CAAC;AAEL,eAAO,MAAM,gBAAgB,kBAA2B,CAAC;AAmDzD,eAAO,MAAM,wBAAwB,QAAO,UAqE1C,CAAC;AAEH,eAAO,MAAM,mBAAmB,EAAE,eAKjC,CAAC"}
@@ -0,0 +1,119 @@
1
+ import { setBlockType, toggleMark, baseKeymap } from "prosemirror-commands";
2
+ import { history, redo, undo } from "prosemirror-history";
3
+ import { keymap } from "prosemirror-keymap";
4
+ import { Schema } from "prosemirror-model";
5
+ import { schema as basicSchema } from "prosemirror-schema-basic";
6
+ import { addListNodes, liftListItem as pmLiftListItem, sinkListItem as pmSinkListItem, wrapInList } from "prosemirror-schema-list";
7
+ import { starterKitCommandNames } from "./command-names.js";
8
+ const starterKitNodes = addListNodes(basicSchema.spec.nodes, "paragraph block*", "block");
9
+ export const createStarterKitSchema = () => new Schema({
10
+ nodes: starterKitNodes,
11
+ marks: basicSchema.spec.marks
12
+ });
13
+ export const starterKitSchema = createStarterKitSchema();
14
+ const asProseMirrorCommand = (command) => (context) => command(context.state, context.dispatch);
15
+ const getNodeType = (name, schema) => {
16
+ const nodeType = schema.nodes[name];
17
+ if (!nodeType) {
18
+ throw new Error(`Missing required node type: ${name}`);
19
+ }
20
+ return nodeType;
21
+ };
22
+ const getMarkType = (name, schema) => {
23
+ const markType = schema.marks[name];
24
+ if (!markType) {
25
+ throw new Error(`Missing required mark type: ${name}`);
26
+ }
27
+ return markType;
28
+ };
29
+ const asHeadingAttributes = (value) => {
30
+ if (typeof value !== "number") {
31
+ return null;
32
+ }
33
+ if (value < 1 || value > 6) {
34
+ return null;
35
+ }
36
+ return { level: value };
37
+ };
38
+ const asLinkAttributes = (value) => {
39
+ if (typeof value !== "object" || value === null) {
40
+ return null;
41
+ }
42
+ const candidate = value;
43
+ if (typeof candidate["href"] !== "string" || candidate["href"].length === 0) {
44
+ return null;
45
+ }
46
+ const titleValue = candidate["title"];
47
+ if (titleValue !== undefined && titleValue !== null && typeof titleValue !== "string") {
48
+ return null;
49
+ }
50
+ return {
51
+ href: candidate["href"],
52
+ title: titleValue ?? null
53
+ };
54
+ };
55
+ export const createStarterKitCommands = () => ({
56
+ [starterKitCommandNames.setParagraph]: (context) => {
57
+ const paragraph = getNodeType("paragraph", context.schema);
58
+ return setBlockType(paragraph)(context.state, context.dispatch);
59
+ },
60
+ [starterKitCommandNames.toggleHeading]: (context, levelValue) => {
61
+ const heading = getNodeType("heading", context.schema);
62
+ const headingAttributes = asHeadingAttributes(levelValue);
63
+ if (!headingAttributes) {
64
+ return false;
65
+ }
66
+ return setBlockType(heading, { level: headingAttributes.level })(context.state, context.dispatch);
67
+ },
68
+ [starterKitCommandNames.toggleBold]: (context) => {
69
+ const strong = getMarkType("strong", context.schema);
70
+ return toggleMark(strong)(context.state, context.dispatch);
71
+ },
72
+ [starterKitCommandNames.toggleItalic]: (context) => {
73
+ const em = getMarkType("em", context.schema);
74
+ return toggleMark(em)(context.state, context.dispatch);
75
+ },
76
+ [starterKitCommandNames.wrapBulletList]: (context) => {
77
+ const bulletList = getNodeType("bullet_list", context.schema);
78
+ return wrapInList(bulletList)(context.state, context.dispatch);
79
+ },
80
+ [starterKitCommandNames.wrapOrderedList]: (context) => {
81
+ const orderedList = getNodeType("ordered_list", context.schema);
82
+ return wrapInList(orderedList)(context.state, context.dispatch);
83
+ },
84
+ [starterKitCommandNames.liftListItem]: (context) => {
85
+ const listItem = getNodeType("list_item", context.schema);
86
+ return pmLiftListItem(listItem)(context.state, context.dispatch);
87
+ },
88
+ [starterKitCommandNames.sinkListItem]: (context) => {
89
+ const listItem = getNodeType("list_item", context.schema);
90
+ return pmSinkListItem(listItem)(context.state, context.dispatch);
91
+ },
92
+ [starterKitCommandNames.setLink]: (context, linkValue) => {
93
+ const link = getMarkType("link", context.schema);
94
+ const attributes = asLinkAttributes(linkValue);
95
+ if (!attributes || context.state.selection.empty) {
96
+ return false;
97
+ }
98
+ const { from, to } = context.state.selection;
99
+ const transaction = context.state.tr.removeMark(from, to, link).addMark(from, to, link.create(attributes));
100
+ context.dispatch(transaction.scrollIntoView());
101
+ return true;
102
+ },
103
+ [starterKitCommandNames.unsetLink]: (context) => {
104
+ const link = getMarkType("link", context.schema);
105
+ const { from, to } = context.state.selection;
106
+ const transaction = context.state.tr.removeMark(from, to, link);
107
+ context.dispatch(transaction.scrollIntoView());
108
+ return true;
109
+ },
110
+ [starterKitCommandNames.undo]: asProseMirrorCommand(undo),
111
+ [starterKitCommandNames.redo]: asProseMirrorCommand(redo)
112
+ });
113
+ export const starterKitExtension = {
114
+ key: "starter-kit",
115
+ schema: starterKitSchema,
116
+ commands: () => createStarterKitCommands(),
117
+ prosemirrorPlugins: () => [history(), keymap(baseKeymap)]
118
+ };
119
+ //# sourceMappingURL=starter-kit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"starter-kit.js","sourceRoot":"","sources":["../src/starter-kit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface LinkAttributes {
2
+ readonly href: string;
3
+ readonly title?: string | null;
4
+ }
5
+ export interface HeadingAttributes {
6
+ readonly level: 1 | 2 | 3 | 4 | 5 | 6;
7
+ }
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACvC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@lexion-rte/extensions",
3
+ "version": "0.1.0",
4
+ "description": "Feature extensions for the Lexion editor platform.",
5
+ "private": false,
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "license": "GPL-3.0-only",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/lexion-rte/lexion.git",
19
+ "directory": "packages/extensions"
20
+ },
21
+ "homepage": "https://github.com/lexion-rte/lexion/tree/main/packages/extensions",
22
+ "bugs": {
23
+ "url": "https://github.com/lexion-rte/lexion/issues"
24
+ },
25
+ "keywords": [
26
+ "lexion",
27
+ "editor",
28
+ "rich-text",
29
+ "prosemirror",
30
+ "extensions"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "dependencies": {
36
+ "prosemirror-commands": "^1.6.2",
37
+ "prosemirror-history": "^1.4.1",
38
+ "prosemirror-keymap": "^1.2.2",
39
+ "prosemirror-model": "^1.22.3",
40
+ "prosemirror-schema-basic": "^1.2.3",
41
+ "prosemirror-schema-list": "^1.4.1",
42
+ "prosemirror-state": "^1.4.3",
43
+ "y-prosemirror": "^1.2.12",
44
+ "y-protocols": "^1.0.6",
45
+ "yjs": "^13.6.23",
46
+ "@lexion-rte/core": "0.1.0"
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.json",
50
+ "lint": "eslint src --ext .ts"
51
+ }
52
+ }
package/src/ai.ts ADDED
@@ -0,0 +1,59 @@
1
+ import type { JSONDocument, LexionEditor, LexionExtension } from "@lexion-rte/core";
2
+
3
+ export const aiCommandNames = {
4
+ applySuggestion: "ai.applySuggestion"
5
+ } as const;
6
+
7
+ export interface AIProviderRequest {
8
+ readonly prompt: string;
9
+ readonly selection: string;
10
+ readonly document: JSONDocument;
11
+ }
12
+
13
+ export interface AIProvider {
14
+ generate(request: AIProviderRequest): Promise<string>;
15
+ }
16
+
17
+ export class AIService {
18
+ private readonly provider: AIProvider;
19
+
20
+ public constructor(provider: AIProvider) {
21
+ this.provider = provider;
22
+ }
23
+
24
+ public async generateForSelection(editor: LexionEditor, prompt: string): Promise<string> {
25
+ const { from, to } = editor.state.selection;
26
+ const selection = editor.state.doc.textBetween(from, to, "\n\n", "\n");
27
+
28
+ return this.provider.generate({
29
+ prompt,
30
+ selection,
31
+ document: editor.getJSON()
32
+ });
33
+ }
34
+
35
+ public async generateAndApply(editor: LexionEditor, prompt: string): Promise<boolean> {
36
+ const suggestion = await this.generateForSelection(editor, prompt);
37
+ if (suggestion.length === 0) {
38
+ return false;
39
+ }
40
+ return editor.execute(aiCommandNames.applySuggestion, suggestion);
41
+ }
42
+ }
43
+
44
+ export const createAIService = (provider: AIProvider): AIService => new AIService(provider);
45
+
46
+ export const aiExtension: LexionExtension = {
47
+ key: "ai",
48
+ commands: () => ({
49
+ [aiCommandNames.applySuggestion]: (context, suggestionValue) => {
50
+ if (typeof suggestionValue !== "string") {
51
+ return false;
52
+ }
53
+
54
+ const { from, to } = context.state.selection;
55
+ context.dispatch(context.state.tr.insertText(suggestionValue, from, to));
56
+ return true;
57
+ }
58
+ })
59
+ };
@@ -0,0 +1,48 @@
1
+ import type { LexionExtension, CommandHandler } from "@lexion-rte/core";
2
+ import type { Awareness } from "y-protocols/awareness";
3
+ import type { XmlFragment } from "yjs";
4
+ import { yCursorPlugin, ySyncPlugin, yUndoPlugin, undo, redo } from "y-prosemirror";
5
+ import type { Command } from "prosemirror-state";
6
+
7
+ export const collaborationCommandNames = {
8
+ undo: "collaboration.undo",
9
+ redo: "collaboration.redo"
10
+ } as const;
11
+
12
+ export interface CollaborationExtensionOptions {
13
+ readonly fragment: XmlFragment;
14
+ readonly awareness: Awareness;
15
+ readonly withCursor?: boolean;
16
+ readonly withUndo?: boolean;
17
+ }
18
+
19
+ const asCommand = (command: Command): CommandHandler => (context) =>
20
+ command(context.state, context.dispatch);
21
+
22
+ export const createCollaborationExtension = (
23
+ options: CollaborationExtensionOptions
24
+ ): LexionExtension => {
25
+ const withCursor = options.withCursor ?? true;
26
+ const withUndo = options.withUndo ?? true;
27
+
28
+ return {
29
+ key: "collaboration",
30
+ prosemirrorPlugins: () => {
31
+ const plugins = [ySyncPlugin(options.fragment)];
32
+
33
+ if (withCursor) {
34
+ plugins.push(yCursorPlugin(options.awareness));
35
+ }
36
+
37
+ if (withUndo) {
38
+ plugins.push(yUndoPlugin());
39
+ }
40
+
41
+ return plugins;
42
+ },
43
+ commands: () => ({
44
+ [collaborationCommandNames.undo]: asCommand(undo),
45
+ [collaborationCommandNames.redo]: asCommand(redo)
46
+ })
47
+ };
48
+ };
@@ -0,0 +1,14 @@
1
+ export const starterKitCommandNames = {
2
+ setParagraph: "setParagraph",
3
+ toggleHeading: "toggleHeading",
4
+ toggleBold: "toggleBold",
5
+ toggleItalic: "toggleItalic",
6
+ wrapBulletList: "wrapBulletList",
7
+ wrapOrderedList: "wrapOrderedList",
8
+ liftListItem: "liftListItem",
9
+ sinkListItem: "sinkListItem",
10
+ setLink: "setLink",
11
+ unsetLink: "unsetLink",
12
+ undo: "undo",
13
+ redo: "redo"
14
+ } as const;
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export { starterKitCommandNames } from "./command-names.js";
2
+ export { createStarterKitCommands, createStarterKitSchema, starterKitExtension, starterKitSchema } from "./starter-kit.js";
3
+ export { aiCommandNames, aiExtension, AIService, createAIService } from "./ai.js";
4
+ export { collaborationCommandNames, createCollaborationExtension } from "./collaboration.js";
5
+ export type { HeadingAttributes, LinkAttributes } from "./types.js";
6
+ export type { AIProvider, AIProviderRequest } from "./ai.js";
7
+ export type { CollaborationExtensionOptions } from "./collaboration.js";