@moraya/core 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/CHANGELOG.md +344 -0
- package/LICENSE +85 -0
- package/README.md +82 -0
- package/dist/adapters/browser-media-resolver.d.ts +21 -0
- package/dist/adapters/browser-media-resolver.js +24 -0
- package/dist/adapters/browser-media-resolver.js.map +1 -0
- package/dist/commands.d.ts +35 -0
- package/dist/commands.js +976 -0
- package/dist/commands.js.map +1 -0
- package/dist/doc-cache.d.ts +29 -0
- package/dist/doc-cache.js +50 -0
- package/dist/doc-cache.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +4534 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +46 -0
- package/dist/markdown.js +1553 -0
- package/dist/markdown.js.map +1 -0
- package/dist/plugins/code-block-view.d.ts +52 -0
- package/dist/plugins/code-block-view.js +686 -0
- package/dist/plugins/code-block-view.js.map +1 -0
- package/dist/plugins/cursor-syntax.d.ts +27 -0
- package/dist/plugins/cursor-syntax.js +122 -0
- package/dist/plugins/cursor-syntax.js.map +1 -0
- package/dist/plugins/definition-list.d.ts +23 -0
- package/dist/plugins/definition-list.js +12 -0
- package/dist/plugins/definition-list.js.map +1 -0
- package/dist/plugins/editor-props-plugin.d.ts +36 -0
- package/dist/plugins/editor-props-plugin.js +1963 -0
- package/dist/plugins/editor-props-plugin.js.map +1 -0
- package/dist/plugins/emoji.d.ts +21 -0
- package/dist/plugins/emoji.js +42 -0
- package/dist/plugins/emoji.js.map +1 -0
- package/dist/plugins/enter-handler.d.ts +26 -0
- package/dist/plugins/enter-handler.js +193 -0
- package/dist/plugins/enter-handler.js.map +1 -0
- package/dist/plugins/highlight.d.ts +39 -0
- package/dist/plugins/highlight.js +283 -0
- package/dist/plugins/highlight.js.map +1 -0
- package/dist/plugins/inline-code-convert.d.ts +32 -0
- package/dist/plugins/inline-code-convert.js +173 -0
- package/dist/plugins/inline-code-convert.js.map +1 -0
- package/dist/plugins/link-text-plugin.d.ts +22 -0
- package/dist/plugins/link-text-plugin.js +194 -0
- package/dist/plugins/link-text-plugin.js.map +1 -0
- package/dist/plugins/mermaid-renderer.d.ts +24 -0
- package/dist/plugins/mermaid-renderer.js +80 -0
- package/dist/plugins/mermaid-renderer.js.map +1 -0
- package/dist/schema.d.ts +48 -0
- package/dist/schema.js +847 -0
- package/dist/schema.js.map +1 -0
- package/dist/setup.d.ts +104 -0
- package/dist/setup.js +4393 -0
- package/dist/setup.js.map +1 -0
- package/dist/types.d.ts +107 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +121 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency-injection interfaces for `@moraya/core`.
|
|
3
|
+
*
|
|
4
|
+
* These 4 interfaces are the **only** boundary between the core package
|
|
5
|
+
* (host-agnostic, pure ESM) and the consumer environment (Tauri / browser /
|
|
6
|
+
* mobile WebView). All Tauri / DOM-specific APIs that previously lived inside
|
|
7
|
+
* the editor source are now accessed through these injected implementations.
|
|
8
|
+
*
|
|
9
|
+
* See iteration spec: `moraya/docs/iterations/v0.60.0-pre-shared-markdown-core.md` §3.3.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Loads local / remote media as a URL usable in `img.src` / `video.src` / etc.
|
|
13
|
+
* Typically returns blob: URLs for local files (cached by the implementation).
|
|
14
|
+
*/
|
|
15
|
+
interface MediaResolver {
|
|
16
|
+
/** Read a local image file by absolute path; return a blob: URL (implementation caches internally). */
|
|
17
|
+
loadLocalImage(absolutePath: string): Promise<string>;
|
|
18
|
+
/** Read a local audio/video file by absolute path; return a blob: URL. */
|
|
19
|
+
loadLocalMedia(absolutePath: string): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Fetch a remote media URL.
|
|
22
|
+
* Browser implementations may return the original URL directly.
|
|
23
|
+
* Tauri implementations proxy through plugin-http to bypass WKWebView mixed-content.
|
|
24
|
+
*/
|
|
25
|
+
loadRemoteMedia(url: string): Promise<string>;
|
|
26
|
+
}
|
|
27
|
+
/** Opens an external link (browser = `window.open`; Tauri = plugin-opener; mobile = bridge). */
|
|
28
|
+
interface LinkOpener {
|
|
29
|
+
open(url: string): void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Custom code-block renderer plugin (WaveDrom / D2 / Excalidraw, etc.).
|
|
33
|
+
* Loaded dynamically via {@link RendererRegistry}.
|
|
34
|
+
*/
|
|
35
|
+
interface RendererPluginModule {
|
|
36
|
+
/**
|
|
37
|
+
* Render `source` into `container` (async supported).
|
|
38
|
+
* The caller guarantees `container` is already mounted in the DOM.
|
|
39
|
+
* The implementation must clear any old content of `container` before rendering.
|
|
40
|
+
*
|
|
41
|
+
* Error propagation: if this method throws or rejects, the core captures the error
|
|
42
|
+
* inside the NodeView (no rethrow) and inserts a fallback DOM:
|
|
43
|
+
* `<div class="renderer-error" data-language="${lang}" data-error="${msg}">[Renderer ${lang} failed]</div>`
|
|
44
|
+
* Roundtrip preservation: the serializer reads the original fenced source from
|
|
45
|
+
* `node.attrs.source` (NOT from the fallback DOM), so the fenced code block
|
|
46
|
+
* round-trips byte-stably even if rendering fails.
|
|
47
|
+
*/
|
|
48
|
+
render(source: string, container: HTMLElement, options?: {
|
|
49
|
+
theme?: string;
|
|
50
|
+
baseUrl?: string;
|
|
51
|
+
}): void | Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Destroy the rendered content within `container` (optional).
|
|
54
|
+
* Called from NodeView.destroy() to free canvas / SVG / event listeners.
|
|
55
|
+
*
|
|
56
|
+
* Error propagation: if this method throws, the core catches and `console.warn`s
|
|
57
|
+
* (does not report to Sentry, does not rethrow). This is a cleanup path; throwing
|
|
58
|
+
* here would block NodeView destruction and cause memory leaks.
|
|
59
|
+
*/
|
|
60
|
+
destroy?(container: HTMLElement): void;
|
|
61
|
+
}
|
|
62
|
+
/** Code-block custom renderer registry. Implemented by consumers (Moraya desktop / Web). */
|
|
63
|
+
interface RendererRegistry {
|
|
64
|
+
/** Whether a renderer is registered for the given language identifier. */
|
|
65
|
+
has(language: string): boolean;
|
|
66
|
+
/** Asynchronously load the renderer module (consumer handles CDN / local import). */
|
|
67
|
+
load(language: string): Promise<RendererPluginModule>;
|
|
68
|
+
/**
|
|
69
|
+
* Snapshot of currently registered renderer versions (language → version string).
|
|
70
|
+
* Used by code-block-view to invalidate cached renders when versions change.
|
|
71
|
+
*/
|
|
72
|
+
readonly versions: Readonly<Record<string, string>>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Platform behavior parameters (carries the editor-props-plugin DI from §F2.6).
|
|
76
|
+
* Desktop injects Tauri / OS truth; Web uses browser detection; mobile bridges fill.
|
|
77
|
+
*/
|
|
78
|
+
interface Platform {
|
|
79
|
+
/**
|
|
80
|
+
* Absolute path of the currently open document (used for relative-image-path
|
|
81
|
+
* resolution). Returns `null` when no document is open.
|
|
82
|
+
*/
|
|
83
|
+
getCurrentFilePath: () => string | null;
|
|
84
|
+
/**
|
|
85
|
+
* Whether the user is on macOS. Affects Option-key handling, Cmd vs Ctrl,
|
|
86
|
+
* emoji popup behavior, etc.
|
|
87
|
+
*/
|
|
88
|
+
isMacOS: boolean;
|
|
89
|
+
}
|
|
90
|
+
/** SchemaConfig (re-exported from schema.ts for convenience). */
|
|
91
|
+
interface SchemaConfig {
|
|
92
|
+
mediaResolver: MediaResolver;
|
|
93
|
+
rendererRegistry?: RendererRegistry;
|
|
94
|
+
linkOpener?: LinkOpener;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Internal symbol-tagged null MediaResolver used by core for parseMarkdown /
|
|
98
|
+
* serializeMarkdown internal fallback. Consumers must NOT pass this to
|
|
99
|
+
* createSchema(); doing so throws with a descriptive error.
|
|
100
|
+
*/
|
|
101
|
+
declare const NULL_MEDIA_RESOLVER_SENTINEL: unique symbol;
|
|
102
|
+
interface NullMediaResolver extends MediaResolver {
|
|
103
|
+
readonly [NULL_MEDIA_RESOLVER_SENTINEL]: true;
|
|
104
|
+
}
|
|
105
|
+
declare function isNullMediaResolver(r: MediaResolver): r is NullMediaResolver;
|
|
106
|
+
|
|
107
|
+
export { type LinkOpener, type MediaResolver, NULL_MEDIA_RESOLVER_SENTINEL, type NullMediaResolver, type Platform, type RendererPluginModule, type RendererRegistry, type SchemaConfig, isNullMediaResolver };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var NULL_MEDIA_RESOLVER_SENTINEL = /* @__PURE__ */ Symbol("@moraya/core:null-media-resolver");
|
|
3
|
+
function isNullMediaResolver(r) {
|
|
4
|
+
return r[NULL_MEDIA_RESOLVER_SENTINEL] === true;
|
|
5
|
+
}
|
|
6
|
+
export {
|
|
7
|
+
NULL_MEDIA_RESOLVER_SENTINEL,
|
|
8
|
+
isNullMediaResolver
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * Dependency-injection interfaces for `@moraya/core`.\n *\n * These 4 interfaces are the **only** boundary between the core package\n * (host-agnostic, pure ESM) and the consumer environment (Tauri / browser /\n * mobile WebView). All Tauri / DOM-specific APIs that previously lived inside\n * the editor source are now accessed through these injected implementations.\n *\n * See iteration spec: `moraya/docs/iterations/v0.60.0-pre-shared-markdown-core.md` §3.3.\n */\n\n/**\n * Loads local / remote media as a URL usable in `img.src` / `video.src` / etc.\n * Typically returns blob: URLs for local files (cached by the implementation).\n */\nexport interface MediaResolver {\n /** Read a local image file by absolute path; return a blob: URL (implementation caches internally). */\n loadLocalImage(absolutePath: string): Promise<string>\n\n /** Read a local audio/video file by absolute path; return a blob: URL. */\n loadLocalMedia(absolutePath: string): Promise<string>\n\n /**\n * Fetch a remote media URL.\n * Browser implementations may return the original URL directly.\n * Tauri implementations proxy through plugin-http to bypass WKWebView mixed-content.\n */\n loadRemoteMedia(url: string): Promise<string>\n}\n\n/** Opens an external link (browser = `window.open`; Tauri = plugin-opener; mobile = bridge). */\nexport interface LinkOpener {\n open(url: string): void\n}\n\n/**\n * Custom code-block renderer plugin (WaveDrom / D2 / Excalidraw, etc.).\n * Loaded dynamically via {@link RendererRegistry}.\n */\nexport interface RendererPluginModule {\n /**\n * Render `source` into `container` (async supported).\n * The caller guarantees `container` is already mounted in the DOM.\n * The implementation must clear any old content of `container` before rendering.\n *\n * Error propagation: if this method throws or rejects, the core captures the error\n * inside the NodeView (no rethrow) and inserts a fallback DOM:\n * `<div class=\"renderer-error\" data-language=\"${lang}\" data-error=\"${msg}\">[Renderer ${lang} failed]</div>`\n * Roundtrip preservation: the serializer reads the original fenced source from\n * `node.attrs.source` (NOT from the fallback DOM), so the fenced code block\n * round-trips byte-stably even if rendering fails.\n */\n render(\n source: string,\n container: HTMLElement,\n options?: { theme?: string; baseUrl?: string }\n ): void | Promise<void>\n\n /**\n * Destroy the rendered content within `container` (optional).\n * Called from NodeView.destroy() to free canvas / SVG / event listeners.\n *\n * Error propagation: if this method throws, the core catches and `console.warn`s\n * (does not report to Sentry, does not rethrow). This is a cleanup path; throwing\n * here would block NodeView destruction and cause memory leaks.\n */\n destroy?(container: HTMLElement): void\n}\n\n/** Code-block custom renderer registry. Implemented by consumers (Moraya desktop / Web). */\nexport interface RendererRegistry {\n /** Whether a renderer is registered for the given language identifier. */\n has(language: string): boolean\n\n /** Asynchronously load the renderer module (consumer handles CDN / local import). */\n load(language: string): Promise<RendererPluginModule>\n\n /**\n * Snapshot of currently registered renderer versions (language → version string).\n * Used by code-block-view to invalidate cached renders when versions change.\n */\n readonly versions: Readonly<Record<string, string>>\n}\n\n/**\n * Platform behavior parameters (carries the editor-props-plugin DI from §F2.6).\n * Desktop injects Tauri / OS truth; Web uses browser detection; mobile bridges fill.\n */\nexport interface Platform {\n /**\n * Absolute path of the currently open document (used for relative-image-path\n * resolution). Returns `null` when no document is open.\n */\n getCurrentFilePath: () => string | null\n\n /**\n * Whether the user is on macOS. Affects Option-key handling, Cmd vs Ctrl,\n * emoji popup behavior, etc.\n */\n isMacOS: boolean\n}\n\n/** SchemaConfig (re-exported from schema.ts for convenience). */\nexport interface SchemaConfig {\n mediaResolver: MediaResolver\n rendererRegistry?: RendererRegistry\n linkOpener?: LinkOpener\n}\n\n// ===== Internal sentinel for misuse detection (v0.60.0-pre §6.1.1) =====\n\n/**\n * Internal symbol-tagged null MediaResolver used by core for parseMarkdown /\n * serializeMarkdown internal fallback. Consumers must NOT pass this to\n * createSchema(); doing so throws with a descriptive error.\n */\nexport const NULL_MEDIA_RESOLVER_SENTINEL = Symbol('@moraya/core:null-media-resolver')\n\nexport interface NullMediaResolver extends MediaResolver {\n readonly [NULL_MEDIA_RESOLVER_SENTINEL]: true\n}\n\nexport function isNullMediaResolver(r: MediaResolver): r is NullMediaResolver {\n return (r as NullMediaResolver)[NULL_MEDIA_RESOLVER_SENTINEL] === true\n}\n"],"mappings":";AAoHO,IAAM,+BAA+B,uBAAO,kCAAkC;AAM9E,SAAS,oBAAoB,GAA0C;AAC5E,SAAQ,EAAwB,4BAA4B,MAAM;AACpE;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@moraya/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared markdown editor core for Moraya desktop and Moraya Web. ProseMirror schema, markdown-it parser, prosemirror-markdown serializer, plugins, and editor lifecycle factories. Pure ESM, host-agnostic, dependency-injected.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./schema": {
|
|
14
|
+
"import": "./dist/schema.js",
|
|
15
|
+
"types": "./dist/schema.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./markdown": {
|
|
18
|
+
"import": "./dist/markdown.js",
|
|
19
|
+
"types": "./dist/markdown.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./commands": {
|
|
22
|
+
"import": "./dist/commands.js",
|
|
23
|
+
"types": "./dist/commands.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./doc-cache": {
|
|
26
|
+
"import": "./dist/doc-cache.js",
|
|
27
|
+
"types": "./dist/doc-cache.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./types": {
|
|
30
|
+
"import": "./dist/types.js",
|
|
31
|
+
"types": "./dist/types.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./style": "./dist/style.css",
|
|
34
|
+
"./plugins/*": {
|
|
35
|
+
"import": "./dist/plugins/*.js",
|
|
36
|
+
"types": "./dist/plugins/*.d.ts"
|
|
37
|
+
},
|
|
38
|
+
"./adapters/*": {
|
|
39
|
+
"import": "./dist/adapters/*.js",
|
|
40
|
+
"types": "./dist/adapters/*.d.ts"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"README.md",
|
|
46
|
+
"CHANGELOG.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/zouwei/moraya-core.git"
|
|
55
|
+
},
|
|
56
|
+
"license": "PolyForm-Internal-Use-1.0.0",
|
|
57
|
+
"sideEffects": [
|
|
58
|
+
"./dist/style.css"
|
|
59
|
+
],
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"highlight.js": "^11.11.0",
|
|
62
|
+
"katex": "^0.16.28",
|
|
63
|
+
"markdown-it": "^14.0.0",
|
|
64
|
+
"markdown-it-deflist": "^3.0.0",
|
|
65
|
+
"markdown-it-texmath": "^1.0.0",
|
|
66
|
+
"mermaid": "^11.0.0",
|
|
67
|
+
"node-emoji": "^2.0.0",
|
|
68
|
+
"prosemirror-commands": "^1.7.0",
|
|
69
|
+
"prosemirror-dropcursor": "^1.8.0",
|
|
70
|
+
"prosemirror-history": "^1.5.0",
|
|
71
|
+
"prosemirror-inputrules": "^1.5.0",
|
|
72
|
+
"prosemirror-keymap": "^1.2.0",
|
|
73
|
+
"prosemirror-markdown": "^1.13.0",
|
|
74
|
+
"prosemirror-model": "^1.20.0",
|
|
75
|
+
"prosemirror-schema-list": "^1.5.0",
|
|
76
|
+
"prosemirror-state": "^1.4.0",
|
|
77
|
+
"prosemirror-tables": "^1.8.0",
|
|
78
|
+
"prosemirror-view": "^1.33.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"mermaid": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@types/markdown-it": "^14.1.2",
|
|
87
|
+
"@types/node": "^20.0.0",
|
|
88
|
+
"happy-dom": "^20.9.0",
|
|
89
|
+
"highlight.js": "^11.11.1",
|
|
90
|
+
"katex": "^0.16.28",
|
|
91
|
+
"markdown-it": "^14.1.1",
|
|
92
|
+
"markdown-it-deflist": "^3.0.0",
|
|
93
|
+
"markdown-it-texmath": "^1.0.0",
|
|
94
|
+
"node-emoji": "^2.2.0",
|
|
95
|
+
"prosemirror-commands": "^1.7.1",
|
|
96
|
+
"prosemirror-dropcursor": "^1.8.2",
|
|
97
|
+
"prosemirror-history": "^1.5.0",
|
|
98
|
+
"prosemirror-inputrules": "^1.5.1",
|
|
99
|
+
"prosemirror-keymap": "^1.2.3",
|
|
100
|
+
"prosemirror-markdown": "^1.13.4",
|
|
101
|
+
"prosemirror-model": "^1.25.4",
|
|
102
|
+
"prosemirror-schema-list": "^1.5.1",
|
|
103
|
+
"prosemirror-state": "^1.4.4",
|
|
104
|
+
"prosemirror-tables": "^1.8.5",
|
|
105
|
+
"prosemirror-view": "^1.41.6",
|
|
106
|
+
"tsup": "^8.3.0",
|
|
107
|
+
"typescript": "~5.6.2",
|
|
108
|
+
"vitest": "^2.1.0"
|
|
109
|
+
},
|
|
110
|
+
"engines": {
|
|
111
|
+
"node": ">=20.0.0"
|
|
112
|
+
},
|
|
113
|
+
"scripts": {
|
|
114
|
+
"build": "tsup",
|
|
115
|
+
"dev": "tsup --watch",
|
|
116
|
+
"typecheck": "tsc --noEmit",
|
|
117
|
+
"test": "vitest run",
|
|
118
|
+
"test:watch": "vitest",
|
|
119
|
+
"lint": "eslint src --ext .ts"
|
|
120
|
+
}
|
|
121
|
+
}
|