dexin-content 0.2.1 → 0.3.1
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 +120 -112
- package/cli/build.ts +4 -4
- package/cli/main.ts +197 -207
- package/core/artifact/store.ts +2 -2
- package/docs/content-format.md +191 -0
- package/example/README.md +37 -0
- package/example/content-manifest.json +16 -0
- package/example/lessons/getting-started/hello-lesson/minimal.md +10 -0
- package/example/lessons/getting-started/hello-lesson/syntax-tour.md +74 -0
- package/index.ts +57 -61
- package/package.json +7 -3
- package/core/validator/integrity.ts +0 -199
- package/domains/document/identity.ts +0 -27
- package/domains/document/index.ts +0 -5
- package/domains/document/parser.ts +0 -105
package/README.md
CHANGED
|
@@ -1,112 +1,120 @@
|
|
|
1
|
-
# dexin-content
|
|
2
|
-
|
|
3
|
-
得心实验室的**结构化内容编译与运行时 package**。
|
|
4
|
-
|
|
5
|
-
负责与具体业务领域无关的通用内容管线:
|
|
6
|
-
|
|
7
|
-
- **Compile**:将带 frontmatter 的 Markdown 编译成中性 Content AST,再经宿主注入的 `DomainParser` 产出稳定的 PositiveArtifact
|
|
8
|
-
- **Store**:Artifact 与索引(ContentIndex)的 FS/Memory 抽象
|
|
9
|
-
- **Query**:按 id / URL path / collection / 条件过滤对 Artifact 做只读查询
|
|
10
|
-
- **Collection**:集合声明、发现、批量编译与增量变化检测
|
|
11
|
-
- **Diff**:Canonical JSON 序列化与对象级差异原语(Golden/Regress 管线使用)
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
|
|
43
|
-
|
|
|
44
|
-
| `./core/
|
|
45
|
-
| `./
|
|
46
|
-
| `./
|
|
47
|
-
| `./
|
|
48
|
-
| `./
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
1
|
+
# dexin-content
|
|
2
|
+
|
|
3
|
+
得心实验室的**结构化内容编译与运行时 package**。
|
|
4
|
+
|
|
5
|
+
负责与具体业务领域无关的通用内容管线:
|
|
6
|
+
|
|
7
|
+
- **Compile**:将带 frontmatter 的 Markdown 编译成中性 Content AST,再经宿主注入的 `DomainParser` 产出稳定的 PositiveArtifact
|
|
8
|
+
- **Store**:Artifact 与索引(ContentIndex)的 FS/Memory 抽象
|
|
9
|
+
- **Query**:按 id / URL path / collection / 条件过滤对 Artifact 做只读查询
|
|
10
|
+
- **Collection**:集合声明、发现、批量编译与增量变化检测
|
|
11
|
+
- **Diff**:Canonical JSON 序列化与对象级差异原语(Golden/Regress 管线使用)
|
|
12
|
+
|
|
13
|
+
## 为内容作者
|
|
14
|
+
|
|
15
|
+
- **格式规范**:[docs/content-format.md](./docs/content-format.md) —— 目录结构、front-matter、块/容器/数学语法、错误码、自检命令、投稿 SOP(§14)
|
|
16
|
+
- **示例课**:[example/](./example/README.md) —— 可直接编译通过的最小内容仓样例
|
|
17
|
+
- **社区投稿**:[proposals/](./proposals/README.md) —— 课程稿件投放区,PR + 门禁校验(`npm run validate:proposals`)+ 人审后迁入私有成品仓
|
|
18
|
+
|
|
19
|
+
## 目录范围
|
|
20
|
+
|
|
21
|
+
dexin-content 是**通用层**:
|
|
22
|
+
- `core/` 编译核心(types / compiler / parser / artifact)
|
|
23
|
+
- `domains/lesson/` 内置 lesson 域 parser(其余域由宿主自行注入)
|
|
24
|
+
- `cli/` flow 编排(`flowBuild` / `flowPackage` / `flowValidate` / `flowCheck` / `flowServe` 库 API;**CLI 子命令仅有 `build` 与 `help`**,其余 flow 经子路径作库消费)
|
|
25
|
+
- `scripts/` 仓内脚本(不在发布包 files 内,仅供本地开发/测试;也不作为公开 API)
|
|
26
|
+
|
|
27
|
+
宿主应用负责域扩展(DomainParser)、编排脚本与内容文件所有权,通过 `exports` 里的子路径消费本 package。
|
|
28
|
+
|
|
29
|
+
## 安装
|
|
30
|
+
|
|
31
|
+
> 需要 Node.js ≥ 20。Package 以 TypeScript 源码形式分发(`*.ts`),宿主应通过 `tsx`、Nuxt/Vite 等支持 TS 解析的工具链使用。
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install dexin-content
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 公开 API 边界
|
|
38
|
+
|
|
39
|
+
唯一公共 API 边界是 `package.json` 中 `exports` 字段。**只使用下列路径**:
|
|
40
|
+
|
|
41
|
+
| 子路径 | 暴露内容 |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `.` | 门面:核心类型 + `DomainParserRegistry` / `compile` + `ArtifactStore` / `ContentQuery` + `defineCollection / resolveCollections / discover / compileCollections` |
|
|
44
|
+
| `./core/types` | 类型:`Inline` 家族(`TextInline` / `BoldInline` / `ItalicInline` / `CodeInline` / `LinkInline` / `FormulaInline`) / `Identity` / `DocumentIdentity` / `StructuredIdentity` / `Meta` / `PositiveArtifact` / `Artifact` / `ParseError` / `ParseContext` / `Schema` / `DomainParser` / `DomainName`(LessonAST 块类型在 `./core/types/lessonAST`) |
|
|
45
|
+
| `./core/compiler` | `compile`、`CompileInput`、`CompileResult`、`DomainParserRegistry` |
|
|
46
|
+
| `./core/discovery` | `buildDocumentIdentity` / `buildStructuredIdentity` / `normaliseRel` / `readSourceFile` / `IdentityKind` / `CollectionConfig` / `SourceFile` |
|
|
47
|
+
| `./core/frontmatter` | `splitFrontmatter` / `parseFrontmatter` / `validateSchema` / `projectMeta` |
|
|
48
|
+
| `./store` | `ArtifactStore` 接口 + `createFsArtifactStore` / `createMemoryArtifactStore` + `ContentIndex` / `IndexEntry` |
|
|
49
|
+
| `./collection` | `defineCollection` / `resolveCollections` / `compileCollections` / `recompileChanged` / `createLocalSource` / `createMemorySource` / `SourceAdapter` / `ResolvedCollection` / `CollectionDefinition` |
|
|
50
|
+
| `./query` | `ContentQuery` (byId / byPath / list / collection) + `QueryOptions` |
|
|
51
|
+
| `./diff` | `toCanonicalJSON` / `sortKeysDeep` / `stripUnderscoreKeysGolden` / `underscorePrefixedPaths` / `firstDiff` / `shortStr` |
|
|
52
|
+
| `./core/markdown` | Markdown → 中性 AST 解析(`parseDocument` 等) |
|
|
53
|
+
| `./core/types/lessonAST` | LessonAST 类型与常量 |
|
|
54
|
+
| `./domains/lesson` | 内置 lesson 域:`lessonParser` / `buildLessonIdentity` / `mapBlocks` |
|
|
55
|
+
| `./cli/build` | `flowBuild`(目录发现 → compile → Artifact Store + index.json) |
|
|
56
|
+
| `./cli/package` | `flowPackage`(按 manifest 打包 ContentPackage) |
|
|
57
|
+
| `./cli/validate` | `flowValidate` |
|
|
58
|
+
| `./cli/check` | `flowCheck` |
|
|
59
|
+
| `./cli/serve` | `flowServe`(dev preview HTTP 服务) |
|
|
60
|
+
|
|
61
|
+
任何未列入上表的内部路径均不保证稳定。
|
|
62
|
+
|
|
63
|
+
## 快速示例
|
|
64
|
+
|
|
65
|
+
最简用法是走 CLI(仅编译内置 lesson 域):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 单文件:AST 打印到 stdout,失败非零退出
|
|
69
|
+
npx dexin-content build example/lessons/getting-started/hello-lesson/minimal.md --domain lesson
|
|
70
|
+
|
|
71
|
+
# 整树:编译 + 按 manifest 打包 ContentPackage
|
|
72
|
+
npx dexin-content build example --manifest example/content-manifest.json --out /tmp/dexin-out
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
库 API(宿主自行编排时)用内置 `lessonParser` 经 `DomainParserRegistry` 注入:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import { DomainParserRegistry, compile } from 'dexin-content/core/compiler'
|
|
79
|
+
import { lessonParser } from 'dexin-content/domains/lesson'
|
|
80
|
+
import { buildLessonIdentity } from 'dexin-content/domains/lesson'
|
|
81
|
+
|
|
82
|
+
const registry = new DomainParserRegistry()
|
|
83
|
+
registry.register(lessonParser)
|
|
84
|
+
|
|
85
|
+
const result = compile(
|
|
86
|
+
{
|
|
87
|
+
fixture: 'getting-started/hello-lesson/minimal',
|
|
88
|
+
domain: 'lesson',
|
|
89
|
+
identity: buildLessonIdentity('minimal', 'getting-started', 'hello-lesson', 'lessons/getting-started/hello-lesson/minimal.md'),
|
|
90
|
+
source: '---\ntitle: 最小的一节课\norder: 1\n---\n\n## 这就是全部了\n',
|
|
91
|
+
file: 'lessons/getting-started/hello-lesson/minimal.md',
|
|
92
|
+
},
|
|
93
|
+
registry,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
if (result.kind === 'error') throw result.error
|
|
97
|
+
else console.log(result.artifact.content.blocks)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`compile()` 永不抛异常,失败以 `{ kind: 'error', error }` 返回。域扩展由宿主注入其它 `DomainParser`。
|
|
101
|
+
|
|
102
|
+
## 开发
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 依赖
|
|
106
|
+
npm install
|
|
107
|
+
|
|
108
|
+
# 类型检查(唯一静态门禁)
|
|
109
|
+
npm run typecheck
|
|
110
|
+
|
|
111
|
+
# 仓内自检测(脚本自建临时 fixture,无需任何本地产物)
|
|
112
|
+
npm run runtime:check
|
|
113
|
+
|
|
114
|
+
# 预发布 tarball 内容检查
|
|
115
|
+
npm run pack
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
Apache-2.0 © 得心实验室。详见 [LICENSE](./LICENSE)。
|
package/cli/build.ts
CHANGED
|
@@ -157,7 +157,7 @@ async function discoverAndCompileDocuments(
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
async function writeArtifact(outDir: string, artifact: PositiveArtifact): Promise<void> {
|
|
160
|
-
const outFile = path.join(outDir, '
|
|
160
|
+
const outFile = path.join(outDir, 'content', artifact.fixture + '.json')
|
|
161
161
|
await mkdir(path.dirname(outFile), { recursive: true })
|
|
162
162
|
await writeFile(outFile, JSON.stringify(artifact, null, 2) + '\n', 'utf-8')
|
|
163
163
|
}
|
|
@@ -183,6 +183,6 @@ async function walkMdFiles(dir: string): Promise<string[]> {
|
|
|
183
183
|
}
|
|
184
184
|
return out.sort()
|
|
185
185
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|