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