@difizen/libro-code-editor 0.0.0-snapshot-20241017072317

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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/es/code-editor-info-manager.d.ts +8 -0
  4. package/es/code-editor-info-manager.d.ts.map +1 -0
  5. package/es/code-editor-info-manager.js +32 -0
  6. package/es/code-editor-manager.d.ts +60 -0
  7. package/es/code-editor-manager.d.ts.map +1 -0
  8. package/es/code-editor-manager.js +126 -0
  9. package/es/code-editor-model.d.ts +80 -0
  10. package/es/code-editor-model.d.ts.map +1 -0
  11. package/es/code-editor-model.js +108 -0
  12. package/es/code-editor-protocol.d.ts +475 -0
  13. package/es/code-editor-protocol.d.ts.map +1 -0
  14. package/es/code-editor-protocol.js +113 -0
  15. package/es/code-editor-settings.d.ts +34 -0
  16. package/es/code-editor-settings.d.ts.map +1 -0
  17. package/es/code-editor-settings.js +225 -0
  18. package/es/code-editor-state-manager.d.ts +14 -0
  19. package/es/code-editor-state-manager.d.ts.map +1 -0
  20. package/es/code-editor-state-manager.js +82 -0
  21. package/es/code-editor-view.d.ts +123 -0
  22. package/es/code-editor-view.d.ts.map +1 -0
  23. package/es/code-editor-view.js +420 -0
  24. package/es/index.d.ts +9 -0
  25. package/es/index.d.ts.map +1 -0
  26. package/es/index.js +8 -0
  27. package/es/language-specs.d.ts +38 -0
  28. package/es/language-specs.d.ts.map +1 -0
  29. package/es/language-specs.js +58 -0
  30. package/es/mimetype.d.ts +33 -0
  31. package/es/mimetype.d.ts.map +1 -0
  32. package/es/mimetype.js +11 -0
  33. package/es/module.d.ts +3 -0
  34. package/es/module.d.ts.map +1 -0
  35. package/es/module.js +10 -0
  36. package/package.json +60 -0
  37. package/src/code-editor-info-manager.ts +25 -0
  38. package/src/code-editor-manager.ts +71 -0
  39. package/src/code-editor-model.ts +120 -0
  40. package/src/code-editor-protocol.ts +681 -0
  41. package/src/code-editor-settings.ts +214 -0
  42. package/src/code-editor-state-manager.ts +54 -0
  43. package/src/code-editor-view.tsx +434 -0
  44. package/src/index.spec.ts +10 -0
  45. package/src/index.ts +8 -0
  46. package/src/language-specs.ts +69 -0
  47. package/src/mimetype.ts +37 -0
  48. package/src/module.ts +22 -0
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@difizen/libro-code-editor",
3
+ "version": "0.0.0-snapshot-20241017072317",
4
+ "description": "",
5
+ "keywords": [
6
+ "libro",
7
+ "notebook"
8
+ ],
9
+ "repository": "git@github.com:difizen/libro.git",
10
+ "license": "MIT",
11
+ "type": "module",
12
+ "exports": {
13
+ ".": {
14
+ "typings": "./es/index.d.ts",
15
+ "default": "./es/index.js"
16
+ },
17
+ "./mock": {
18
+ "typings": "./es/mock/index.d.ts",
19
+ "default": "./es/mock/index.js"
20
+ },
21
+ "./es/mock": {
22
+ "typings": "./es/mock/index.d.ts",
23
+ "default": "./es/mock/index.js"
24
+ },
25
+ "./package.json": "./package.json"
26
+ },
27
+ "main": "es/index.js",
28
+ "module": "es/index.js",
29
+ "typings": "es/index.d.ts",
30
+ "files": [
31
+ "es",
32
+ "src"
33
+ ],
34
+ "dependencies": {
35
+ "@difizen/mana-app": "latest",
36
+ "@difizen/mana-l10n": "latest",
37
+ "@difizen/libro-common": "0.0.0-snapshot-20241017072317",
38
+ "uuid": "^9.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "react": ">=16"
42
+ },
43
+ "devDependencies": {
44
+ "@types/react": "^18.2.25",
45
+ "@types/uuid": "^9.0.2"
46
+ },
47
+ "scripts": {
48
+ "setup": "father build",
49
+ "build": "father build",
50
+ "test": ": Note: lint task is delegated to test:* scripts",
51
+ "test:vitest": "vitest run",
52
+ "test:jest": "jest",
53
+ "coverage": ": Note: lint task is delegated to coverage:* scripts",
54
+ "coverage:vitest": "vitest run --coverage",
55
+ "coverage:jest": "jest --coverage",
56
+ "lint": ": Note: lint task is delegated to lint:* scripts",
57
+ "lint:eslint": "eslint src",
58
+ "typecheck:tsc": "tsc --noEmit"
59
+ }
60
+ }
@@ -0,0 +1,25 @@
1
+ import { singleton } from '@difizen/mana-app';
2
+
3
+ @singleton()
4
+ export class CodeEditorInfoManager {
5
+ editorHostRefMap: Map<string, React.RefObject<HTMLDivElement>>;
6
+
7
+ constructor() {
8
+ this.editorHostRefMap = new Map();
9
+ }
10
+
11
+ setEditorHostRef(id: string, ref: React.RefObject<HTMLDivElement>) {
12
+ if (!this.editorHostRefMap) {
13
+ this.editorHostRefMap = new Map();
14
+ }
15
+
16
+ this.editorHostRefMap.set(id, ref);
17
+ }
18
+
19
+ getEditorHostRef(id: string) {
20
+ if (!this.editorHostRefMap) {
21
+ return undefined;
22
+ }
23
+ return this.editorHostRefMap.get(id);
24
+ }
25
+ }
@@ -0,0 +1,71 @@
1
+ import type { Contribution } from '@difizen/mana-app';
2
+ import { Priority, ViewManager, contrib, inject, singleton } from '@difizen/mana-app';
3
+
4
+ import { CodeEditorInfoManager } from './code-editor-info-manager.js';
5
+ import type { IModel } from './code-editor-model.js';
6
+ import { CodeEditorContribution } from './code-editor-protocol.js';
7
+ import type { EditorState } from './code-editor-protocol.js';
8
+ import { CodeEditorSettings } from './code-editor-settings.js';
9
+ import type { CodeEditorViewOptions } from './code-editor-view.js';
10
+ import { CodeEditorView } from './code-editor-view.js';
11
+
12
+ @singleton()
13
+ export class CodeEditorManager {
14
+ @contrib(CodeEditorContribution)
15
+ protected readonly codeEditorProvider: Contribution.Provider<CodeEditorContribution>;
16
+ @inject(ViewManager) protected readonly viewManager: ViewManager;
17
+ @inject(CodeEditorInfoManager) protected codeEditorInfoManager: CodeEditorInfoManager;
18
+ @inject(CodeEditorSettings) protected readonly codeEditorSettings: CodeEditorSettings;
19
+ protected stateCache: Map<string, EditorState> = new Map();
20
+
21
+ setEditorHostRef(id: string, ref: React.RefObject<HTMLDivElement>) {
22
+ this.codeEditorInfoManager.setEditorHostRef(id, ref);
23
+ }
24
+
25
+ protected findCodeEditorProvider(model: IModel) {
26
+ const prioritized = Priority.sortSync(
27
+ this.codeEditorProvider.getContributions(),
28
+ (contribution) => contribution.canHandle(model.mimeType),
29
+ );
30
+ const sorted = prioritized.map((c) => c.value);
31
+ return sorted[0];
32
+ }
33
+
34
+ /**
35
+ * 获取默认配置
36
+ * @param model
37
+ * @returns
38
+ */
39
+ getEditorDefaultConfig(model: IModel) {
40
+ return this.findCodeEditorProvider(model)?.defaultConfig;
41
+ }
42
+
43
+ /**
44
+ * 用户配置+默认配置(还有一部分配置在cell中指定)
45
+ * @param model
46
+ * @returns
47
+ */
48
+ getUserEditorConfig(model: IModel) {
49
+ return {
50
+ ...this.getEditorDefaultConfig(model),
51
+ ...this.codeEditorSettings.getUserEditorSettings(),
52
+ };
53
+ }
54
+
55
+ async getOrCreateEditorView(option: CodeEditorViewOptions): Promise<CodeEditorView> {
56
+ const factory = this.findCodeEditorProvider(option.model)?.factory;
57
+ if (!factory) {
58
+ throw new Error(
59
+ `no code editor factory registered for mimetype: ${option.model.mimeType}`,
60
+ );
61
+ }
62
+ const editorView = await this.viewManager.getOrCreateView<
63
+ CodeEditorView,
64
+ CodeEditorViewOptions
65
+ >(CodeEditorView, {
66
+ factory,
67
+ ...option,
68
+ });
69
+ return editorView;
70
+ }
71
+ }
@@ -0,0 +1,120 @@
1
+ import type { CellType } from '@difizen/libro-common';
2
+ import type { Disposable, Event } from '@difizen/mana-app';
3
+ import { prop, transient, Emitter } from '@difizen/mana-app';
4
+ import { v4 } from 'uuid';
5
+
6
+ import type { ITextSelection } from './code-editor-protocol.js';
7
+
8
+ export interface IModelOptions {
9
+ /**
10
+ * A unique identifier for the model.
11
+ */
12
+ id?: string;
13
+
14
+ /**
15
+ * The initial value of the model.
16
+ */
17
+ value?: string;
18
+
19
+ /**
20
+ * The mimetype of the model.
21
+ */
22
+ mimeType?: string;
23
+ }
24
+
25
+ /**
26
+ * An editor model.
27
+ */
28
+ export interface IModel extends Disposable {
29
+ /**
30
+ * The text stored in the model.
31
+ */
32
+ value: string;
33
+
34
+ /**
35
+ * A mime type of the model.
36
+ *
37
+ * #### Notes
38
+ * It is never `null`, the default mime type is `text/plain`.
39
+ */
40
+ mimeType: string;
41
+
42
+ /**
43
+ * The currently selected code.
44
+ */
45
+ selections: ITextSelection[];
46
+ }
47
+
48
+ /**
49
+ * The default implementation of the editor model.
50
+ */
51
+ @transient()
52
+ export class Model implements IModel {
53
+ id: string;
54
+
55
+ /**
56
+ * The text stored in the model.
57
+ */
58
+ @prop()
59
+ value: string;
60
+
61
+ /**
62
+ * A mime type of the model.
63
+ *
64
+ * #### Notes
65
+ * It is never `null`, the default mime type is `text/plain`.
66
+ */
67
+ @prop()
68
+ mimeType: string;
69
+
70
+ @prop()
71
+ type: CellType = 'code';
72
+
73
+ /**
74
+ * The currently selected code.
75
+ */
76
+ @prop()
77
+ selections: ITextSelection[];
78
+
79
+ /**
80
+ * Construct a new Model.
81
+ */
82
+ constructor(options?: IModelOptions) {
83
+ // this.sharedModel = models.createStandaloneCell(this.type, options.id) as models.ISharedText;
84
+ // this.sharedModel.changed.connect(this._onSharedModelChanged, this);
85
+ this.id = options?.id ?? v4();
86
+
87
+ this.value = options?.value ?? '';
88
+ this.mimeType = options?.mimeType ?? 'text/plain';
89
+ this.selections = [];
90
+ }
91
+
92
+ /**
93
+ * A signal emitted when the shared model was switched.
94
+ */
95
+ get sharedModelSwitched(): Event<boolean> {
96
+ return this._sharedModelSwitched;
97
+ }
98
+
99
+ /**
100
+ * Whether the model is disposed.
101
+ */
102
+ get isDisposed(): boolean {
103
+ return this._isDisposed;
104
+ }
105
+
106
+ /**
107
+ * Dispose of the resources used by the model.
108
+ */
109
+ dispose(): void {
110
+ if (this._isDisposed) {
111
+ return;
112
+ }
113
+ this._isDisposed = true;
114
+ }
115
+
116
+ protected _isDisposed = false;
117
+
118
+ protected _sharedModelSwitchedEmitter = new Emitter<boolean>();
119
+ protected _sharedModelSwitched = this._sharedModelSwitchedEmitter.event;
120
+ }