@analogjs/content 3.0.0-alpha.3 → 3.0.0-alpha.30
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/devtools/package.json +4 -0
- package/fesm2022/analogjs-content-devtools.mjs +162 -0
- package/fesm2022/analogjs-content-devtools.mjs.map +1 -0
- package/fesm2022/analogjs-content-md4x.mjs +291 -0
- package/fesm2022/analogjs-content-md4x.mjs.map +1 -0
- package/fesm2022/analogjs-content-mdc.mjs +170 -0
- package/fesm2022/analogjs-content-mdc.mjs.map +1 -0
- package/fesm2022/analogjs-content-og.mjs.map +1 -0
- package/fesm2022/analogjs-content-prism-highlighter.mjs +5 -4
- package/fesm2022/analogjs-content-prism-highlighter.mjs.map +1 -0
- package/fesm2022/analogjs-content-resources.mjs +30 -24
- package/fesm2022/analogjs-content-resources.mjs.map +1 -0
- package/fesm2022/analogjs-content-shiki-highlighter.mjs +1 -1
- package/fesm2022/analogjs-content-shiki-highlighter.mjs.map +1 -0
- package/fesm2022/analogjs-content.mjs +25 -350
- package/fesm2022/analogjs-content.mjs.map +1 -0
- package/fesm2022/content-list-loader.mjs +161 -0
- package/fesm2022/content-list-loader.mjs.map +1 -0
- package/fesm2022/content-renderer.mjs +128 -0
- package/fesm2022/content-renderer.mjs.map +1 -0
- package/fesm2022/marked-content-highlighter.mjs +40 -0
- package/fesm2022/marked-content-highlighter.mjs.map +1 -0
- package/fesm2022/parse-raw-content-file.mjs +45 -0
- package/fesm2022/parse-raw-content-file.mjs.map +1 -0
- package/md4x/package.json +4 -0
- package/mdc/package.json +4 -0
- package/package.json +71 -36
- package/plugin/migrations.json +1 -1
- package/plugin/package.json +2 -22
- package/plugin/src/index.d.ts +3 -1
- package/plugin/src/index.d.ts.map +1 -0
- package/plugin/src/index.js +5 -4
- package/plugin/src/index.js.map +1 -0
- package/plugin/src/migrations/update-markdown-version/compat.d.ts +5 -2
- package/plugin/src/migrations/update-markdown-version/compat.d.ts.map +1 -0
- package/plugin/src/migrations/update-markdown-version/compat.js +8 -7
- package/plugin/src/migrations/update-markdown-version/compat.js.map +1 -0
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.d.ts +6 -2
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.d.ts.map +1 -0
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.js +18 -20
- package/plugin/src/migrations/update-markdown-version/update-markdown-version.js.map +1 -0
- package/src/lib/devtools/content-devtools-client.ts +215 -0
- package/src/lib/devtools/content-devtools.styles.css +194 -0
- package/types/devtools/src/index.d.ts +1 -0
- package/types/md4x/src/index.d.ts +5 -0
- package/types/md4x/src/lib/md4x-content-renderer.service.d.ts +33 -0
- package/types/md4x/src/lib/md4x-wasm-content-renderer.service.d.ts +16 -0
- package/types/md4x/src/lib/provide-md4x.d.ts +26 -0
- package/types/md4x/src/lib/streaming-markdown-renderer.d.ts +21 -0
- package/types/mdc/src/index.d.ts +2 -0
- package/types/mdc/src/lib/mdc-component-registry.d.ts +25 -0
- package/types/mdc/src/lib/mdc-renderer.directive.d.ts +33 -0
- package/types/prism-highlighter/src/lib/prism-highlighter.d.ts +1 -1
- package/types/resources/src/content-file-resource.d.ts +32 -7
- package/types/resources/src/content-files-resource.d.ts +2 -1
- package/types/src/index.d.ts +5 -3
- package/types/src/lib/devtools/content-devtools-plugin.d.ts +23 -0
- package/types/src/lib/devtools/content-devtools-renderer.d.ts +23 -0
- package/types/src/lib/devtools/index.d.ts +23 -0
- package/types/src/lib/parse-raw-content-file.d.ts +15 -1
- package/plugin/README.md +0 -11
- package/plugin/src/migrations/update-markdown-renderer-feature/compat.d.ts +0 -3
- package/plugin/src/migrations/update-markdown-renderer-feature/compat.js +0 -8
- package/plugin/src/migrations/update-markdown-renderer-feature/update-markdown-renderer-feature.d.ts +0 -2
- package/plugin/src/migrations/update-markdown-renderer-feature/update-markdown-renderer-feature.js +0 -48
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../content-plugin/src/index.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nconst _default: undefined = void 0;\nexport default _default;\n"],"mappings":";;AACA,MAAM,WAAsB,KAAK"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import { convertNxGenerator } from
|
|
1
|
+
import { convertNxGenerator } from "@nx/devkit";
|
|
2
|
+
|
|
3
|
+
//#region src/migrations/update-markdown-version/compat.d.ts
|
|
2
4
|
declare const _default: ReturnType<typeof convertNxGenerator>;
|
|
3
|
-
export
|
|
5
|
+
export = _default;
|
|
6
|
+
//# sourceMappingURL=compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.d.ts","names":[],"sources":["../../../../../../content-plugin/src/migrations/update-markdown-version/compat.ts"],"mappings":";;;cAGM,QAAA,EAAU,UAAA,QAAkB,kBAAA;AAAA"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
const require_src_migrations_update_markdown_version_update_markdown_version = require('./update-markdown-version.js');
|
|
2
|
+
let _nx_devkit = require("@nx/devkit");
|
|
3
|
+
|
|
4
|
+
//#region src/migrations/update-markdown-version/compat.ts
|
|
5
|
+
const _default = (0, _nx_devkit.convertNxGenerator)(require_src_migrations_update_markdown_version_update_markdown_version);
|
|
6
|
+
|
|
7
|
+
//#endregion
|
|
8
|
+
module.exports = _default;
|
|
8
9
|
//# sourceMappingURL=compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.js","names":["updateMarkdownVersion"],"sources":["../../../../../../content-plugin/src/migrations/update-markdown-version/compat.ts"],"sourcesContent":["import { convertNxGenerator } from '@nx/devkit';\nimport updateMarkdownVersion from './update-markdown-version';\n\nconst _default: ReturnType<typeof convertNxGenerator> = convertNxGenerator(\n updateMarkdownVersion,\n);\nexport default _default;\n"],"mappings":";;;;AAGA,MAAM,8CACJA,uEACD"}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
import { Tree } from
|
|
2
|
-
|
|
1
|
+
import { Tree } from "@nx/devkit";
|
|
2
|
+
|
|
3
|
+
//#region src/migrations/update-markdown-version/update-markdown-version.d.ts
|
|
4
|
+
declare function update(host: Tree): Promise<(() => void) | undefined>;
|
|
5
|
+
export = update;
|
|
6
|
+
//# sourceMappingURL=update-markdown-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-markdown-version.d.ts","names":[],"sources":["../../../../../../content-plugin/src/migrations/update-markdown-version/update-markdown-version.ts"],"mappings":";;;iBAO8B,MAAA,CAC5B,IAAA,EAAM,IAAA,GACL,OAAA;AAAA"}
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
1
|
+
let _nx_devkit = require("@nx/devkit");
|
|
2
|
+
|
|
3
|
+
//#region src/migrations/update-markdown-version/update-markdown-version.ts
|
|
5
4
|
async function update(host) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
await (0, devkit_1.formatFiles)(host);
|
|
19
|
-
if (dependencyAdded) {
|
|
20
|
-
return () => (0, devkit_1.installPackagesTask)(host);
|
|
21
|
-
}
|
|
5
|
+
let dependencyAdded = false;
|
|
6
|
+
if (host.exists("/angular.json")) {
|
|
7
|
+
(0, _nx_devkit.addDependenciesToPackageJson)(host, {
|
|
8
|
+
marked: "^18.0.0",
|
|
9
|
+
"marked-mangle": "^1.1.10",
|
|
10
|
+
"marked-highlight": "^2.2.1",
|
|
11
|
+
"marked-gfm-heading-id": "^4.1.1"
|
|
12
|
+
}, {});
|
|
13
|
+
dependencyAdded = true;
|
|
14
|
+
}
|
|
15
|
+
await (0, _nx_devkit.formatFiles)(host);
|
|
16
|
+
if (dependencyAdded) return () => (0, _nx_devkit.installPackagesTask)(host);
|
|
22
17
|
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
module.exports = update;
|
|
23
21
|
//# sourceMappingURL=update-markdown-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-markdown-version.js","names":[],"sources":["../../../../../../content-plugin/src/migrations/update-markdown-version/update-markdown-version.ts"],"sourcesContent":["import {\n addDependenciesToPackageJson,\n type Tree,\n formatFiles,\n installPackagesTask,\n} from '@nx/devkit';\n\nexport default async function update(\n host: Tree,\n): Promise<(() => void) | undefined> {\n // NOTE: we only add the dependency if the project is an Angular project\n // Nx projects can add the dependency from migrations.json\n let dependencyAdded = false;\n if (host.exists('/angular.json')) {\n addDependenciesToPackageJson(\n host,\n {\n marked: '^18.0.0',\n 'marked-mangle': '^1.1.10',\n 'marked-highlight': '^2.2.1',\n 'marked-gfm-heading-id': '^4.1.1',\n },\n {},\n );\n dependencyAdded = true;\n }\n\n await formatFiles(host);\n\n if (dependencyAdded) {\n return () => installPackagesTask(host);\n }\n}\n"],"mappings":";;;AAOA,eAA8B,OAC5B,MACmC;CAGnC,IAAI,kBAAkB;AACtB,KAAI,KAAK,OAAO,gBAAgB,EAAE;AAChC,+CACE,MACA;GACE,QAAQ;GACR,iBAAiB;GACjB,oBAAoB;GACpB,yBAAyB;GAC1B,EACD,EAAE,CACH;AACD,oBAAkB;;AAGpB,mCAAkB,KAAK;AAEvB,KAAI,gBACF,kDAAiC,KAAK"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side script for the Analog Content DevTools panel.
|
|
3
|
+
* Injected by the Vite plugin in dev mode only.
|
|
4
|
+
*
|
|
5
|
+
* @experimental Content DevTools is experimental and may change in future releases.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
interface DevToolsData {
|
|
9
|
+
renderer: string;
|
|
10
|
+
renderTimeMs: number;
|
|
11
|
+
frontmatter: Record<string, unknown>;
|
|
12
|
+
toc: Array<{ id: string; level: number; text: string }>;
|
|
13
|
+
contentLength: number;
|
|
14
|
+
headingCount: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const STORAGE_KEY = 'analog-content-devtools-open';
|
|
18
|
+
|
|
19
|
+
// Cache the latest devtools payload at module level so events fired
|
|
20
|
+
// during initial bootstrap (before the panel is created) are not lost.
|
|
21
|
+
let latestDevToolsData: DevToolsData | null = null;
|
|
22
|
+
let panelUpdateCallback: ((data: DevToolsData) => void) | null = null;
|
|
23
|
+
|
|
24
|
+
window.addEventListener('analog-content-devtools-data', ((
|
|
25
|
+
e: CustomEvent<DevToolsData>,
|
|
26
|
+
) => {
|
|
27
|
+
latestDevToolsData = e.detail;
|
|
28
|
+
if (panelUpdateCallback) {
|
|
29
|
+
panelUpdateCallback(e.detail);
|
|
30
|
+
}
|
|
31
|
+
}) as EventListener);
|
|
32
|
+
|
|
33
|
+
function createPanel(): HTMLElement {
|
|
34
|
+
const root = document.createElement('div');
|
|
35
|
+
root.id = 'analog-content-devtools';
|
|
36
|
+
root.innerHTML = `
|
|
37
|
+
<button class="acd-toggle" title="Analog Content DevTools">
|
|
38
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
39
|
+
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zm-1 2l5 5h-5V4zM6 20V4h5v7h7v9H6z"/>
|
|
40
|
+
<path d="M8 13h8v1H8zm0 3h6v1H8z" opacity=".6"/>
|
|
41
|
+
</svg>
|
|
42
|
+
</button>
|
|
43
|
+
<div class="acd-panel" style="display:none">
|
|
44
|
+
<div class="acd-header">
|
|
45
|
+
<span>Analog Content DevTools <span class="acd-badge acd-badge-experimental">experimental</span></span>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="acd-tabs">
|
|
48
|
+
<button class="acd-tab" data-tab="overview" data-active="true">Overview</button>
|
|
49
|
+
<button class="acd-tab" data-tab="frontmatter">Frontmatter</button>
|
|
50
|
+
<button class="acd-tab" data-tab="toc">TOC</button>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="acd-body">
|
|
53
|
+
<div class="acd-empty">No content data available. Navigate to a content page.</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
`;
|
|
57
|
+
return root;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function renderOverview(data: DevToolsData): string {
|
|
61
|
+
const speedClass =
|
|
62
|
+
data.renderTimeMs < 5
|
|
63
|
+
? 'acd-fast'
|
|
64
|
+
: data.renderTimeMs > 50
|
|
65
|
+
? 'acd-slow'
|
|
66
|
+
: '';
|
|
67
|
+
return `
|
|
68
|
+
<div class="acd-section">
|
|
69
|
+
<div class="acd-section-title">Renderer</div>
|
|
70
|
+
<div class="acd-kv">
|
|
71
|
+
<span class="acd-key">Active</span>
|
|
72
|
+
<span class="acd-value"><span class="acd-badge acd-badge-renderer">${data.renderer}</span></span>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="acd-kv">
|
|
75
|
+
<span class="acd-key">Render time</span>
|
|
76
|
+
<span class="acd-value ${speedClass}">${data.renderTimeMs.toFixed(2)}ms</span>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="acd-section">
|
|
80
|
+
<div class="acd-section-title">Content</div>
|
|
81
|
+
<div class="acd-kv">
|
|
82
|
+
<span class="acd-key">Length</span>
|
|
83
|
+
<span class="acd-value">${data.contentLength.toLocaleString()} chars</span>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="acd-kv">
|
|
86
|
+
<span class="acd-key">Headings</span>
|
|
87
|
+
<span class="acd-value">${data.headingCount}</span>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="acd-kv">
|
|
90
|
+
<span class="acd-key">Frontmatter keys</span>
|
|
91
|
+
<span class="acd-value">${Object.keys(data.frontmatter).length}</span>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function renderFrontmatter(data: DevToolsData): string {
|
|
98
|
+
const keys = Object.keys(data.frontmatter);
|
|
99
|
+
if (keys.length === 0) {
|
|
100
|
+
return '<div class="acd-empty">No frontmatter found.</div>';
|
|
101
|
+
}
|
|
102
|
+
return `
|
|
103
|
+
<div class="acd-section">
|
|
104
|
+
<div class="acd-section-title">Frontmatter attributes</div>
|
|
105
|
+
<div class="acd-pre">${escapeHtml(JSON.stringify(data.frontmatter, null, 2))}</div>
|
|
106
|
+
</div>
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function renderToc(data: DevToolsData): HTMLElement {
|
|
111
|
+
if (data.toc.length === 0) {
|
|
112
|
+
const empty = document.createElement('div');
|
|
113
|
+
empty.className = 'acd-empty';
|
|
114
|
+
empty.textContent = 'No headings found.';
|
|
115
|
+
return empty;
|
|
116
|
+
}
|
|
117
|
+
const section = document.createElement('div');
|
|
118
|
+
section.className = 'acd-section';
|
|
119
|
+
const title = document.createElement('div');
|
|
120
|
+
title.className = 'acd-section-title';
|
|
121
|
+
title.textContent = `Table of Contents (${data.toc.length} headings)`;
|
|
122
|
+
section.appendChild(title);
|
|
123
|
+
|
|
124
|
+
for (const h of data.toc) {
|
|
125
|
+
const item = document.createElement('div');
|
|
126
|
+
item.className = 'acd-toc-item';
|
|
127
|
+
item.style.paddingLeft = `${(h.level - 1) * 12}px`;
|
|
128
|
+
const anchor = document.createElement('a');
|
|
129
|
+
anchor.setAttribute('href', `#${encodeURIComponent(h.id)}`);
|
|
130
|
+
anchor.textContent = `${'#'.repeat(h.level)} ${h.text}`;
|
|
131
|
+
item.appendChild(anchor);
|
|
132
|
+
section.appendChild(item);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return section;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function escapeHtml(str: string): string {
|
|
139
|
+
return str
|
|
140
|
+
.replace(/&/g, '&')
|
|
141
|
+
.replace(/</g, '<')
|
|
142
|
+
.replace(/>/g, '>')
|
|
143
|
+
.replace(/"/g, '"');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function initDevTools() {
|
|
147
|
+
if (document.getElementById('analog-content-devtools')) return;
|
|
148
|
+
|
|
149
|
+
const panel = createPanel();
|
|
150
|
+
document.body.appendChild(panel);
|
|
151
|
+
|
|
152
|
+
const toggle = panel.querySelector('.acd-toggle') as HTMLElement;
|
|
153
|
+
const panelEl = panel.querySelector('.acd-panel') as HTMLElement;
|
|
154
|
+
const body = panel.querySelector('.acd-body') as HTMLElement;
|
|
155
|
+
const tabs = panel.querySelectorAll('.acd-tab');
|
|
156
|
+
|
|
157
|
+
let isOpen = localStorage.getItem(STORAGE_KEY) === 'true';
|
|
158
|
+
let activeTab = 'overview';
|
|
159
|
+
let currentData: DevToolsData | null = latestDevToolsData;
|
|
160
|
+
|
|
161
|
+
function updateVisibility() {
|
|
162
|
+
panelEl.style.display = isOpen ? 'flex' : 'none';
|
|
163
|
+
localStorage.setItem(STORAGE_KEY, String(isOpen));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function updateBody() {
|
|
167
|
+
if (!currentData) {
|
|
168
|
+
body.innerHTML =
|
|
169
|
+
'<div class="acd-empty">No content data available. Navigate to a content page.</div>';
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
switch (activeTab) {
|
|
173
|
+
case 'overview':
|
|
174
|
+
body.innerHTML = renderOverview(currentData);
|
|
175
|
+
break;
|
|
176
|
+
case 'frontmatter':
|
|
177
|
+
body.innerHTML = renderFrontmatter(currentData);
|
|
178
|
+
break;
|
|
179
|
+
case 'toc':
|
|
180
|
+
body.replaceChildren(renderToc(currentData));
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
toggle.addEventListener('click', () => {
|
|
186
|
+
isOpen = !isOpen;
|
|
187
|
+
updateVisibility();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
tabs.forEach((tab) => {
|
|
191
|
+
tab.addEventListener('click', () => {
|
|
192
|
+
activeTab = (tab as HTMLElement).dataset['tab'] || 'overview';
|
|
193
|
+
tabs.forEach((t) =>
|
|
194
|
+
(t as HTMLElement).setAttribute('data-active', String(t === tab)),
|
|
195
|
+
);
|
|
196
|
+
updateBody();
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Wire the module-level listener to update the panel
|
|
201
|
+
panelUpdateCallback = (data: DevToolsData) => {
|
|
202
|
+
currentData = data;
|
|
203
|
+
updateBody();
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
updateVisibility();
|
|
207
|
+
updateBody();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Init when DOM is ready
|
|
211
|
+
if (document.readyState === 'loading') {
|
|
212
|
+
document.addEventListener('DOMContentLoaded', initDevTools);
|
|
213
|
+
} else {
|
|
214
|
+
initDevTools();
|
|
215
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#analog-content-devtools {
|
|
2
|
+
position: fixed;
|
|
3
|
+
bottom: 0;
|
|
4
|
+
right: 0;
|
|
5
|
+
z-index: 99999;
|
|
6
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
7
|
+
font-size: 12px;
|
|
8
|
+
color: #e4e4e7;
|
|
9
|
+
pointer-events: none;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
#analog-content-devtools * {
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#analog-content-devtools .acd-toggle {
|
|
17
|
+
position: fixed;
|
|
18
|
+
bottom: 12px;
|
|
19
|
+
right: 12px;
|
|
20
|
+
width: 36px;
|
|
21
|
+
height: 36px;
|
|
22
|
+
border-radius: 8px;
|
|
23
|
+
background: #18181b;
|
|
24
|
+
border: 1px solid #3f3f46;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
pointer-events: auto;
|
|
30
|
+
opacity: 0.7;
|
|
31
|
+
transition: opacity 0.15s;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#analog-content-devtools .acd-toggle:hover {
|
|
35
|
+
opacity: 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#analog-content-devtools .acd-toggle svg {
|
|
39
|
+
width: 20px;
|
|
40
|
+
height: 20px;
|
|
41
|
+
fill: #a1a1aa;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#analog-content-devtools .acd-panel {
|
|
45
|
+
position: fixed;
|
|
46
|
+
bottom: 56px;
|
|
47
|
+
right: 12px;
|
|
48
|
+
width: 420px;
|
|
49
|
+
max-height: 70vh;
|
|
50
|
+
background: #18181b;
|
|
51
|
+
border: 1px solid #3f3f46;
|
|
52
|
+
border-radius: 10px;
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
pointer-events: auto;
|
|
57
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#analog-content-devtools .acd-header {
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: space-between;
|
|
64
|
+
padding: 8px 12px;
|
|
65
|
+
background: #27272a;
|
|
66
|
+
border-bottom: 1px solid #3f3f46;
|
|
67
|
+
font-weight: 600;
|
|
68
|
+
font-size: 11px;
|
|
69
|
+
text-transform: uppercase;
|
|
70
|
+
letter-spacing: 0.05em;
|
|
71
|
+
color: #a1a1aa;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
#analog-content-devtools .acd-tabs {
|
|
75
|
+
display: flex;
|
|
76
|
+
gap: 2px;
|
|
77
|
+
padding: 4px 8px;
|
|
78
|
+
background: #27272a;
|
|
79
|
+
border-bottom: 1px solid #3f3f46;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#analog-content-devtools .acd-tab {
|
|
83
|
+
padding: 4px 10px;
|
|
84
|
+
border-radius: 4px;
|
|
85
|
+
background: transparent;
|
|
86
|
+
border: none;
|
|
87
|
+
color: #71717a;
|
|
88
|
+
cursor: pointer;
|
|
89
|
+
font-size: 11px;
|
|
90
|
+
font-family: inherit;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
#analog-content-devtools .acd-tab:hover {
|
|
94
|
+
color: #a1a1aa;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#analog-content-devtools .acd-tab[data-active='true'] {
|
|
98
|
+
background: #3f3f46;
|
|
99
|
+
color: #e4e4e7;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#analog-content-devtools .acd-body {
|
|
103
|
+
overflow-y: auto;
|
|
104
|
+
padding: 12px;
|
|
105
|
+
flex: 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
#analog-content-devtools .acd-section {
|
|
109
|
+
margin-bottom: 12px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#analog-content-devtools .acd-section-title {
|
|
113
|
+
font-size: 10px;
|
|
114
|
+
font-weight: 600;
|
|
115
|
+
text-transform: uppercase;
|
|
116
|
+
letter-spacing: 0.05em;
|
|
117
|
+
color: #71717a;
|
|
118
|
+
margin-bottom: 6px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
#analog-content-devtools .acd-kv {
|
|
122
|
+
display: flex;
|
|
123
|
+
justify-content: space-between;
|
|
124
|
+
padding: 2px 0;
|
|
125
|
+
border-bottom: 1px solid #27272a;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#analog-content-devtools .acd-key {
|
|
129
|
+
color: #a1a1aa;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
#analog-content-devtools .acd-value {
|
|
133
|
+
color: #22d3ee;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
#analog-content-devtools .acd-value.acd-fast {
|
|
137
|
+
color: #4ade80;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#analog-content-devtools .acd-value.acd-slow {
|
|
141
|
+
color: #fb923c;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#analog-content-devtools .acd-toc-item {
|
|
145
|
+
padding: 2px 0;
|
|
146
|
+
cursor: pointer;
|
|
147
|
+
color: #a1a1aa;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#analog-content-devtools .acd-toc-item:hover {
|
|
151
|
+
color: #e4e4e7;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
#analog-content-devtools .acd-toc-item a {
|
|
155
|
+
color: inherit;
|
|
156
|
+
text-decoration: none;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
#analog-content-devtools .acd-pre {
|
|
160
|
+
background: #09090b;
|
|
161
|
+
border: 1px solid #27272a;
|
|
162
|
+
border-radius: 6px;
|
|
163
|
+
padding: 8px;
|
|
164
|
+
overflow-x: auto;
|
|
165
|
+
white-space: pre-wrap;
|
|
166
|
+
overflow-wrap: anywhere;
|
|
167
|
+
font-size: 11px;
|
|
168
|
+
line-height: 1.5;
|
|
169
|
+
max-height: 300px;
|
|
170
|
+
overflow-y: auto;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
#analog-content-devtools .acd-empty {
|
|
174
|
+
color: #52525b;
|
|
175
|
+
font-style: italic;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#analog-content-devtools .acd-badge {
|
|
179
|
+
display: inline-block;
|
|
180
|
+
padding: 1px 6px;
|
|
181
|
+
border-radius: 4px;
|
|
182
|
+
font-size: 10px;
|
|
183
|
+
font-weight: 600;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
#analog-content-devtools .acd-badge-experimental {
|
|
187
|
+
background: #422006;
|
|
188
|
+
color: #fb923c;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#analog-content-devtools .acd-badge-renderer {
|
|
192
|
+
background: #042f2e;
|
|
193
|
+
color: #2dd4bf;
|
|
194
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { contentDevToolsPlugin, DevToolsContentRenderer, withContentDevTools, } from '../../src/lib/devtools/index';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { withMd4xRenderer, withMd4xWasmRenderer } from './lib/provide-md4x';
|
|
2
|
+
export { Md4xContentRendererService, MD4X_RENDERER_OPTIONS, } from './lib/md4x-content-renderer.service';
|
|
3
|
+
export type { Md4xRendererOptions } from './lib/md4x-content-renderer.service';
|
|
4
|
+
export { Md4xWasmContentRendererService } from './lib/md4x-wasm-content-renderer.service';
|
|
5
|
+
export { streamMarkdown } from './lib/streaming-markdown-renderer';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import { ContentRenderer, RenderedContent, TableOfContentItem } from '../../../src/lib/content-renderer';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Options for the experimental md4x-based content renderer.
|
|
6
|
+
*
|
|
7
|
+
* @experimental md4x integration is experimental and may change in future releases.
|
|
8
|
+
*/
|
|
9
|
+
export interface Md4xRendererOptions {
|
|
10
|
+
/** Heal incomplete markdown (useful for streaming/LLM content). */
|
|
11
|
+
heal?: boolean;
|
|
12
|
+
/** Custom code block highlighter. Receives raw code and block metadata,
|
|
13
|
+
* returns highlighted HTML or undefined to keep default rendering. */
|
|
14
|
+
highlighter?: (code: string, block: {
|
|
15
|
+
lang: string;
|
|
16
|
+
filename?: string;
|
|
17
|
+
highlights?: number[];
|
|
18
|
+
}) => string | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare const MD4X_RENDERER_OPTIONS: InjectionToken<Md4xRendererOptions>;
|
|
21
|
+
/**
|
|
22
|
+
* Content renderer backed by md4x (C-based CommonMark parser compiled with Zig).
|
|
23
|
+
* 50-70x faster than marked for complex documents.
|
|
24
|
+
*
|
|
25
|
+
* @experimental md4x integration is experimental and may change in future releases.
|
|
26
|
+
*/
|
|
27
|
+
export declare class Md4xContentRendererService extends ContentRenderer {
|
|
28
|
+
private options;
|
|
29
|
+
render(content: string): Promise<RenderedContent>;
|
|
30
|
+
getContentHeadings(content: string): TableOfContentItem[];
|
|
31
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<Md4xContentRendererService, never>;
|
|
32
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<Md4xContentRendererService>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ContentRenderer, RenderedContent, TableOfContentItem } from '../../../src/lib/content-renderer';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Content renderer backed by md4x/wasm for client-side (browser) rendering.
|
|
5
|
+
* ~100KB gzip, 3-6x faster than marked in the browser.
|
|
6
|
+
*
|
|
7
|
+
* @experimental md4x integration is experimental and may change in future releases.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Md4xWasmContentRendererService extends ContentRenderer {
|
|
10
|
+
private options;
|
|
11
|
+
private initPromise;
|
|
12
|
+
render(content: string): Promise<RenderedContent>;
|
|
13
|
+
getContentHeadings(content: string): TableOfContentItem[];
|
|
14
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<Md4xWasmContentRendererService, never>;
|
|
15
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<Md4xWasmContentRendererService>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Provider } from '@angular/core';
|
|
2
|
+
import type { Md4xRendererOptions } from './md4x-content-renderer.service';
|
|
3
|
+
/**
|
|
4
|
+
* Provides the experimental md4x-based content renderer (NAPI, server/build-time).
|
|
5
|
+
*
|
|
6
|
+
* @experimental md4x integration is experimental and may change in future releases.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* provideContent(withMd4xRenderer());
|
|
11
|
+
* provideContent(withMd4xRenderer({ heal: true }));
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function withMd4xRenderer(options?: Md4xRendererOptions): Provider;
|
|
15
|
+
/**
|
|
16
|
+
* Provides the experimental md4x WASM content renderer (browser/CSR).
|
|
17
|
+
* ~100KB gzip, 3-6x faster than marked in the browser.
|
|
18
|
+
*
|
|
19
|
+
* @experimental md4x integration is experimental and may change in future releases.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* provideContent(withMd4xWasmRenderer());
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function withMd4xWasmRenderer(options?: Md4xRendererOptions): Provider;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms a stream of markdown chunks into a stream of rendered HTML.
|
|
3
|
+
* Uses md4x's `heal()` to fix incomplete markdown from streaming sources
|
|
4
|
+
* (LLMs, collaborative editing) so each emitted HTML chunk is valid.
|
|
5
|
+
*
|
|
6
|
+
* @experimental Streaming markdown support is experimental and may change in future releases.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // In a Nitro API route
|
|
11
|
+
* import { streamMarkdown } from '@analogjs/content';
|
|
12
|
+
*
|
|
13
|
+
* export default defineEventHandler(async (event) => {
|
|
14
|
+
* const llmStream = getAIStream(prompt);
|
|
15
|
+
* return streamMarkdown(llmStream, { heal: true });
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function streamMarkdown(input: ReadableStream<string>, options?: {
|
|
20
|
+
heal?: boolean;
|
|
21
|
+
}): Promise<ReadableStream<string>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { InjectionToken, Type, Provider } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Registry mapping MDC component names to lazy-loaded Angular components.
|
|
4
|
+
*
|
|
5
|
+
* @experimental MDC component support is experimental and may change in future releases.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MDC_COMPONENTS: InjectionToken<Map<string, () => Promise<Type<unknown>>>>;
|
|
8
|
+
/**
|
|
9
|
+
* Provides a registry of Angular components that can be used in MDC
|
|
10
|
+
* (Markdown Components) syntax within markdown content.
|
|
11
|
+
*
|
|
12
|
+
* @experimental MDC component support is experimental and may change in future releases.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* provideContent(
|
|
17
|
+
* withMd4xRenderer(),
|
|
18
|
+
* withMdcComponents({
|
|
19
|
+
* alert: () => import('./components/alert.component').then(m => m.AlertComponent),
|
|
20
|
+
* card: () => import('./components/card.component').then(m => m.CardComponent),
|
|
21
|
+
* }),
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function withMdcComponents(components: Record<string, () => Promise<Type<unknown>>>): Provider;
|