dexin-content 0.2.0 → 0.3.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/README.md +121 -112
- package/cli/build.ts +4 -4
- package/cli/main.ts +197 -207
- package/core/artifact/store.ts +2 -2
- package/core/parser/markdown.ts +343 -327
- package/index.ts +57 -61
- package/package.json +2 -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,121 @@
|
|
|
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
|
-
dexin-content 是**通用层**:
|
|
16
|
-
- `core/` 编译核心(types / compiler /
|
|
17
|
-
-
|
|
18
|
-
- `
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
npm
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
| `./core/
|
|
43
|
-
| `./core/
|
|
44
|
-
| `./core/
|
|
45
|
-
| `./
|
|
46
|
-
| `./
|
|
47
|
-
| `./
|
|
48
|
-
| `./
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
import
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
#
|
|
107
|
-
npm
|
|
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
|
+
dexin-content 是**通用层**:
|
|
16
|
+
- `core/` 编译核心(types / compiler / parser / artifact)
|
|
17
|
+
- `domains/lesson/` 内置 lesson 域 parser(其余域由宿主自行注入)
|
|
18
|
+
- `cli/` flow 编排(build / package / validate / check / serve)
|
|
19
|
+
- `scripts/` 仓内脚本(不在发布包 files 内,仅供本地开发/测试;也不作为公开 API)
|
|
20
|
+
|
|
21
|
+
宿主应用负责域扩展(DomainParser)、编排脚本与内容文件所有权,通过 `exports` 里的子路径消费本 package。
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
> 需要 Node.js ≥ 20。Package 以 TypeScript 源码形式分发(`*.ts`),宿主应通过 `tsx`、Nuxt/Vite 等支持 TS 解析的工具链使用。
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Gitee 源(当前发布前)
|
|
29
|
+
npm install git+https://gitee.com/cuizhn/dexin-content.git
|
|
30
|
+
|
|
31
|
+
# 发布到 npm 后
|
|
32
|
+
npm install dexin-content
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 公开 API 边界
|
|
36
|
+
|
|
37
|
+
唯一公共 API 边界是 `package.json` 中 `exports` 字段。**只使用下列路径**:
|
|
38
|
+
|
|
39
|
+
| 子路径 | 暴露内容 |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `.` | 门面:核心类型 + `DomainParserRegistry` / `compile` + `ArtifactStore` / `ContentQuery` + `defineCollection / resolveCollections / discover / compileCollections` |
|
|
42
|
+
| `./core/types` | 类型:`Inline` / `DocumentBlock` / `DocumentContent` / `DocumentIdentity` / `PositiveArtifact` / `Artifact` / `Meta` / `ParseError` / `DomainParser` / `Schema` / `ParseContext` |
|
|
43
|
+
| `./core/compiler` | `compile`、`CompileInput`、`CompileResult`、`DomainParserRegistry` |
|
|
44
|
+
| `./core/discovery` | `buildDocumentIdentity` / `normaliseRel` / `readSourceFile` / `sanitizeSourceText` / `mkLineEndingError` |
|
|
45
|
+
| `./core/frontmatter` | `splitFrontmatter` / `parseFrontmatter` / `validateSchema` / `projectMeta` |
|
|
46
|
+
| `./store` | `ArtifactStore` 接口 + `createFsArtifactStore` / `createMemoryArtifactStore` + `ContentIndex` / `IndexEntry` |
|
|
47
|
+
| `./collection` | `defineCollection` / `resolveCollections` / `compileCollections` / `recompileChanged` / `createLocalSource` / `createMemorySource` / `SourceAdapter` / `ResolvedCollection` / `CollectionDefinition` |
|
|
48
|
+
| `./query` | `ContentQuery` (byId / byPath / list / collection) + `QueryOptions` |
|
|
49
|
+
| `./diff` | `toCanonicalJSON` / `sortKeysDeep` / `stripUnderscoreKeysGolden` / `underscorePrefixedPaths` / `firstDiff` / `shortStr` |
|
|
50
|
+
| `./core/markdown` | Markdown → 中性 AST 解析(`parseDocument` 等) |
|
|
51
|
+
| `./core/types/lessonAST` | LessonAST 类型与常量 |
|
|
52
|
+
| `./domains/lesson` | 内置 lesson 域:`lessonParser` / `buildLessonIdentity` / `mapBlocks` |
|
|
53
|
+
| `./cli/build` | `flowBuild`(目录发现 → compile → Artifact Store + index.json) |
|
|
54
|
+
| `./cli/package` | `flowPackage`(按 manifest 打包 ContentPackage) |
|
|
55
|
+
| `./cli/validate` | `flowValidate` |
|
|
56
|
+
| `./cli/check` | `flowCheck` |
|
|
57
|
+
| `./cli/serve` | `flowServe`(dev preview HTTP 服务) |
|
|
58
|
+
|
|
59
|
+
任何未列入上表的内部路径均不保证稳定。
|
|
60
|
+
|
|
61
|
+
## 快速示例
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import {
|
|
65
|
+
defineCollection,
|
|
66
|
+
resolveCollections,
|
|
67
|
+
createLocalSource,
|
|
68
|
+
compileCollections,
|
|
69
|
+
} from 'dexin-content/collection'
|
|
70
|
+
import { createFsArtifactStore } from 'dexin-content/store'
|
|
71
|
+
import { ContentQuery } from 'dexin-content/query'
|
|
72
|
+
import { DomainParserRegistry } from 'dexin-content/core/compiler'
|
|
73
|
+
import type {
|
|
74
|
+
DomainParser,
|
|
75
|
+
DocumentContent,
|
|
76
|
+
ParseContext,
|
|
77
|
+
} from 'dexin-content/core/types'
|
|
78
|
+
|
|
79
|
+
// 1) 注入你的域 parser;parser 决定中性 AST 如何映射到目标 Artifact 内容结构
|
|
80
|
+
const documentParser: DomainParser = {
|
|
81
|
+
domain: 'document',
|
|
82
|
+
parse(content: DocumentContent, _ctx: ParseContext) {
|
|
83
|
+
return { version: 1, blocks: content.blocks as unknown[] }
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
const registry = new DomainParserRegistry()
|
|
87
|
+
registry.register(documentParser)
|
|
88
|
+
|
|
89
|
+
// 2) 声明集合 + 编译
|
|
90
|
+
const collections = resolveCollections(
|
|
91
|
+
[defineCollection({ name: 'legal', source: 'legal', domain: 'document' })],
|
|
92
|
+
'/path/to/content/root',
|
|
93
|
+
)
|
|
94
|
+
const source = createLocalSource('/path/to/content/root')
|
|
95
|
+
const store = createFsArtifactStore('/path/to/artifact-store')
|
|
96
|
+
await compileCollections(source, collections, registry, store)
|
|
97
|
+
|
|
98
|
+
// 3) 运行时只读查询(不解析任何 Markdown)
|
|
99
|
+
const query = new ContentQuery(store)
|
|
100
|
+
const entry = await query.byPath('/legal/privacy')
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 开发
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# 依赖
|
|
107
|
+
npm install
|
|
108
|
+
|
|
109
|
+
# 类型检查(唯一静态门禁)
|
|
110
|
+
npm run typecheck
|
|
111
|
+
|
|
112
|
+
# 仓内自检测(脚本自建临时 fixture,无需任何本地产物)
|
|
113
|
+
npm run runtime:check
|
|
114
|
+
|
|
115
|
+
# 预发布 tarball 内容检查
|
|
116
|
+
npm run pack
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
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
|
+
|