@deepseek-ai/dsh-typert-generator 0.2.1-rc.4 → 0.2.2-alpha.2

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.i18n.yaml CHANGED
@@ -24,14 +24,14 @@
24
24
  en: 6bb456bb03fc6617
25
25
  zh: 029407c373b8e6a6
26
26
  /deepseek-ai-dsh-typert-generator/use-this-package/analyzing-a-workspace-statically:
27
- en: 8227097859169cdf
28
- zh: 249790ed62e8558a
27
+ en: 0a4f5896df9f2fab
28
+ zh: e7d0d6cddd7a59e7
29
29
  /deepseek-ai-dsh-typert-generator/use-this-package/running-generation-inside-a-tsdown-build:
30
- en: ebcb4850a5620d93
31
- zh: 55f6f54265830f28
30
+ en: 15ecce4f32b7a8c0
31
+ zh: c7d6b449d7b20338
32
32
  /deepseek-ai-dsh-typert-generator/use-this-package/generating-without-a-bundler:
33
- en: e1afb26aea87fe46
34
- zh: ed3cdfde78d87825
33
+ en: cf6893be24bdc495
34
+ zh: dafc23e2d2e8553e
35
35
  /deepseek-ai-dsh-typert-generator/understand-the-implementation:
36
36
  en: b90762df7a978580
37
37
  zh: 123ab225a2b5df2a
package/README.md CHANGED
@@ -60,19 +60,21 @@ Every generated parameter spec contains both `codec` and `strictCodec`, derived
60
60
 
61
61
  ### Analyzing a workspace statically
62
62
 
63
- Static consumers call `WorkspaceAnalyzer` directly against the workspace's `tsconfig.host.json` and `tsconfig.client.json` aggregates, select a face and package subset, and read the resulting `FaceModel` and type graph without emitting or loading runtime artifacts. `analyzeInBatches()` processes a large package selection through bounded compiler programs with the same model shape, and `discoverPackages()` finds contributing packages without building a type-checker program; its optional `package.json` predicate skips a package before its sources or project config are read. Typert parses only the tsconfigs of packages it analyzes; validating every referenced tsconfig belongs to the preceding `tsc -b`.
63
+ Static consumers call `WorkspaceAnalyzer` directly against the workspace's `tsconfig.host.json` and `tsconfig.client.json` aggregates, select a face and package subset, and read the resulting `FaceModel` and type graph without emitting or loading runtime artifacts. `analyzeInBatches()` processes a large package selection through bounded compiler programs with the same model shape, and `discoverPackages()` finds contributing packages without building a type-checker program; its optional `package.json` predicate skips a package before its sources or project config are read. Typert parses only the tsconfigs of packages it analyzes; validating every referenced tsconfig belongs to package compilation with `tsc -b`.
64
64
 
65
65
  JSON, YAML, SVG, PNG, JPEG, and WebP resource exports contribute no TypeScript declarations and are excluded from the API model. Missing JavaScript or TypeScript export sources remain errors.
66
66
 
67
67
  ### Running generation inside a tsdown build
68
68
 
69
- The package's `./tsdown` subpath provides `typertPlugin()` for the root tsdown config: it lowers standard decorators in TypeScript dependencies before bundling and emits the model-driven face artifacts at the package output root. A module-id filter on its `transform` hook keeps non-TypeScript modules out of JavaScript. The workspace root is the nearest ancestor of the bundle that contains both `tsconfig.host.json` and `packages/`, so a package's own face leaf config never qualifies. In `package` mode it generates synchronously in the bundled package's `writeBundle` and emits only that package.
69
+ The `./tsdown` subpath exports `decoratorPlugin()` and `typertPlugin()`. The `./tsdown` subpath exports `decoratorPlugin()` and `typertPlugin()`. `decoratorPlugin()` lowers standard TypeScript decorators without reading or writing metadata. The repository build uses it after source-only generation; consumers that generate metadata during bundling use `typertPlugin()`.
70
+
71
+ `typertPlugin()` serves builds that generate metadata during bundling: it lowers standard decorators in TypeScript dependencies before bundling and emits the model-driven face artifacts at the package output root. A module-id filter on its `transform` hook keeps non-TypeScript modules out of JavaScript. The workspace root is the nearest ancestor of the bundle that contains both `tsconfig.host.json` and `packages/`, so a package's own face leaf config never qualifies. In `package` mode it generates synchronously in the bundled package's `writeBundle` and emits only that package.
70
72
 
71
73
  In `workspace` mode it emits every explicit contributor once without blocking bundling: the first package build's `buildStart` starts generation in a Worker Thread, and the first `writeBundle` awaits the result and writes every artifact while later bundles return immediately. An analysis error, a worker crash or early exit, or a malformed worker response fails that bundle, and therefore the tsdown pass, with a `TypertWorkerError` naming the workspace and cause; the worker is terminated before the failure is reported.
72
74
 
73
75
  ### Generating without a bundler
74
76
 
75
- `writeWorkspaceArtifacts()` and `writePackageArtifacts()` are the plugin's file writers: each artifact becomes `lib/typert.<face>.{js,d.ts}`, plus `lib/typert.remote-client.{js,d.ts,d.ts.map}` when it carries Remote methods, and a Host artifact without Remote methods removes stale Remote client files. Writing the result of `WorkspaceTypertGenerator.generateContributors()` through them leaves the same bytes as the `workspace`-mode plugin, and `findWorkspaceRoot()` applies the plugin's workspace-root rule. The repository's bundle-free pass, [`scripts/generate-typert.ts`](../../../scripts/generate-typert.ts), generates the Host face this way for type checks that need no bundle.
77
+ `writeWorkspaceArtifacts()` and `writePackageArtifacts()` are the plugin's file writers: each artifact becomes `lib/typert.<face>.{js,d.ts}`, plus `lib/typert.remote-client.{js,d.ts,d.ts.map}` when it carries Remote methods, and a Host artifact without Remote methods removes stale Remote client files. Writing the result of `WorkspaceTypertGenerator.generateContributors()` through them leaves the same bytes as the `workspace`-mode plugin, and `findWorkspaceRoot()` applies the plugin's workspace-root rule. The repository's bundle-free pass, [`scripts/generate-typert.ts`](../../../scripts/generate-typert.ts), generates the Host face this way before package compilation for artifact and declaration-only builds.
76
78
 
77
79
  With `rejectBuildOutputs: true`, analysis fails with a `TypertAnalysisError` when a face program loads a file from a workspace package's `lib/` directory, or cannot resolve an import of a workspace package, as on a tree whose packages are not yet compiled. The error names each such import specifier and the source file a `paths` alias should map it to, so a passing generation depends only on workspace source and can run before or beside package compilation. Leave it off for a face whose sources import generated outputs, such as a Client face importing `/remote`.
78
80
 
package/README.zh.md CHANGED
@@ -60,19 +60,21 @@ factory 返回类实例,并保留 spec,直到 `descriptors` 或 `methods` ge
60
60
 
61
61
  ### 静态分析工作区
62
62
 
63
- 静态消费方直接针对工作区的 `tsconfig.host.json` 与 `tsconfig.client.json` 聚合配置调用 `WorkspaceAnalyzer`,选择 face 与包子集,并在不生成或加载运行时产物的前提下读取生成的 `FaceModel` 与类型图。`analyzeInBatches()` 通过有界的编译器程序处理大批量包选择,模型形态保持一致;`discoverPackages()` 无需构建类型检查程序即可找出参与贡献的包,其可选的 `package.json` 谓词会在读取某个包的源码或项目配置之前就跳过该包。Typert 只解析它所分析的包的 tsconfig;校验每个被引用的 tsconfig 由之前运行的 `tsc -b` 负责。
63
+ 静态消费方直接针对工作区的 `tsconfig.host.json` 与 `tsconfig.client.json` 聚合配置调用 `WorkspaceAnalyzer`,选择 face 与包子集,并在不生成或加载运行时产物的前提下读取生成的 `FaceModel` 与类型图。`analyzeInBatches()` 通过有界的编译器程序处理大批量包选择,模型形态保持一致;`discoverPackages()` 无需构建类型检查程序即可找出参与贡献的包,其可选的 `package.json` 谓词会在读取某个包的源码或项目配置之前就跳过该包。Typert 只解析它所分析的包的 tsconfig;校验每个被引用的 tsconfig 由包编译中的 `tsc -b` 负责。
64
64
 
65
65
  JSON、YAML、SVG、PNG、JPEG 和 WebP 资源导出不提供 TypeScript 声明,因此不进入 API 模型。JavaScript 或 TypeScript 导出源文件缺失时仍报错。
66
66
 
67
67
  ### 在 tsdown 构建中运行生成
68
68
 
69
- 包的 `./tsdown` 子路径为根 tsdown 配置提供 `typertPlugin()`:它在打包前转换 TypeScript 依赖中的标准装饰器,并在包输出根目录生成模型驱动的 face 产物。其 `transform` 钩子带有模块 id 过滤器,非 TypeScript 模块不会进入 JavaScript。工作区根目录是打包输出最近的、同时包含 `tsconfig.host.json` 与 `packages/` 的祖先目录,因此包自身的 face 叶子配置永远不会被当作根目录。`package` 模式在当前包的 `writeBundle` 中同步生成,并只生成该包。
69
+ `./tsdown` 子路径导出 `decoratorPlugin()` 与 `typertPlugin()`。`./tsdown` 子路径导出 `decoratorPlugin()` 与 `typertPlugin()`。`decoratorPlugin()` 转换标准 TypeScript 装饰器,不读取或写入元数据。仓库构建在仅源码生成完成后使用它;需要在打包时生成元数据的消费方使用 `typertPlugin()`。
70
+
71
+ `typertPlugin()` 用于需要在打包时生成元数据的构建:它在打包前转换 TypeScript 依赖中的标准装饰器,并在包输出根目录生成模型驱动的 face 产物。其 `transform` 钩子带有模块 id 过滤器,非 TypeScript 模块不会进入 JavaScript。工作区根目录是打包输出最近的、同时包含 `tsconfig.host.json` 与 `packages/` 的祖先目录,因此包自身的 face 叶子配置永远不会被当作根目录。`package` 模式在当前包的 `writeBundle` 中同步生成,并只生成该包。
70
72
 
71
73
  `workspace` 模式对每个显式贡献方各生成一次,且不阻塞打包:第一个包构建的 `buildStart` 在 Worker Thread 中启动生成,第一个 `writeBundle` 等待结果并写入全部产物,之后的打包立即返回。分析错误、worker 崩溃或提前退出、worker 响应格式错误,都会以指明工作区与原因的 `TypertWorkerError` 使该打包失败,从而使整个 tsdown 阶段失败;报告失败之前 worker 已被终止。
72
74
 
73
75
  ### 不经打包器生成
74
76
 
75
- `writeWorkspaceArtifacts()` 与 `writePackageArtifacts()` 是插件的写盘函数:每个产物写成 `lib/typert.<face>.{js,d.ts}`,带 Remote 方法时另写 `lib/typert.remote-client.{js,d.ts,d.ts.map}`,没有 Remote 方法的 Host 产物会删除残留的 Remote client 文件。把 `WorkspaceTypertGenerator.generateContributors()` 的结果交给它们写盘,得到的字节与 `workspace` 模式插件相同;`findWorkspaceRoot()` 采用插件的工作区根目录规则。仓库中不打包的生成 [`scripts/generate-typert.ts`](../../../scripts/generate-typert.ts) 就以这种方式为不需要 bundle 的类型检查生成 Host face。
77
+ `writeWorkspaceArtifacts()` 与 `writePackageArtifacts()` 是插件的写盘函数:每个产物写成 `lib/typert.<face>.{js,d.ts}`,带 Remote 方法时另写 `lib/typert.remote-client.{js,d.ts,d.ts.map}`,没有 Remote 方法的 Host 产物会删除残留的 Remote client 文件。把 `WorkspaceTypertGenerator.generateContributors()` 的结果交给它们写盘,得到的字节与 `workspace` 模式插件相同;`findWorkspaceRoot()` 采用插件的工作区根目录规则。仓库中不打包的生成 [`scripts/generate-typert.ts`](../../../scripts/generate-typert.ts) 就以这种方式为产物构建与仅生成声明的构建在包编译之前生成 Host face。
76
78
 
77
79
  设置 `rejectBuildOutputs: true` 后,若 face program 载入了工作区包 `lib/` 目录下的文件,或无法解析对工作区包的 import(例如包尚未编译的工作区),分析会以 `TypertAnalysisError` 失败。错误信息列出每个这样的 import 说明符,以及应由 `paths` 别名映射到的源文件;因此通过的生成只依赖工作区源码,可以在包编译之前或与之并行运行。若某个 face 的源码 import 生成产物(例如 Client face import `/remote`),则不要开启它。
78
80
 
@@ -40,7 +40,12 @@ export declare class TypertWorkerError extends Error {
40
40
  name: string;
41
41
  }
42
42
  /**
43
- * Create the decorator-lowering and typert-generation plugin for the root tsdown config.
43
+ * Lower standard TypeScript decorators without reading or writing metadata.
44
+ * @returns a rolldown-compatible transform without metadata generation or artifact writes.
45
+ */
46
+ export declare function decoratorPlugin(): Pick<TypertPlugin, 'name' | 'transform'>;
47
+ /**
48
+ * Create the decorator-lowering and Typert-generation plugin for generation during bundling.
44
49
  * @param pluginOptions - package/workspace emission mode and independent program faces.
45
50
  * @returns a rolldown-compatible plugin that lowers source decorators and emits local and Host-for-Client artifacts.
46
51
  */
@@ -26,7 +26,39 @@ export class TypertWorkerError extends Error {
26
26
  name = 'TypertWorkerError';
27
27
  }
28
28
  /**
29
- * Create the decorator-lowering and typert-generation plugin for the root tsdown config.
29
+ * Lower standard TypeScript decorators without reading or writing metadata.
30
+ * @returns a rolldown-compatible transform without metadata generation or artifact writes.
31
+ */
32
+ export function decoratorPlugin() {
33
+ return {
34
+ name: 'dsh-decorators',
35
+ transform: {
36
+ // Rolldown evaluates the id filter natively, so non-TypeScript modules
37
+ // never cross into this JavaScript hook.
38
+ filter: { id: TYPESCRIPT_MODULE },
39
+ handler(code, id) {
40
+ if (!TYPESCRIPT_MODULE.test(id) || !DECORATOR_SYNTAX.test(code))
41
+ return;
42
+ const file = id.replace(/\?.*$/su, '');
43
+ const result = ts.transpileModule(code, {
44
+ fileName: file,
45
+ compilerOptions: {
46
+ target: ts.ScriptTarget.ES2024,
47
+ module: ts.ModuleKind.ESNext,
48
+ ...(file.endsWith('x') ? { jsx: ts.JsxEmit.ReactJSX } : {}),
49
+ sourceMap: true,
50
+ },
51
+ });
52
+ return {
53
+ code: result.outputText.replace(/\n?\/\/# sourceMappingURL=.*$/u, '\n'),
54
+ map: result.sourceMapText,
55
+ };
56
+ },
57
+ },
58
+ };
59
+ }
60
+ /**
61
+ * Create the decorator-lowering and Typert-generation plugin for generation during bundling.
30
62
  * @param pluginOptions - package/workspace emission mode and independent program faces.
31
63
  * @returns a rolldown-compatible plugin that lowers source decorators and emits local and Host-for-Client artifacts.
32
64
  */
@@ -47,6 +79,7 @@ export function typertPlugin(pluginOptions = {}) {
47
79
  return generation;
48
80
  };
49
81
  return {
82
+ ...decoratorPlugin(),
50
83
  name: 'dsh-typert-generator',
51
84
  buildStart(inputOptions) {
52
85
  // tsdown builds every workspace package concurrently through this one
@@ -54,29 +87,6 @@ export function typertPlugin(pluginOptions = {}) {
54
87
  if (pluginOptions.mode === 'workspace')
55
88
  void workspaceGeneration(findWorkspaceRoot(inputOptions.cwd));
56
89
  },
57
- transform: {
58
- // Rolldown evaluates the id filter natively, so non-TypeScript modules
59
- // never cross into this JavaScript hook.
60
- filter: { id: TYPESCRIPT_MODULE },
61
- handler(code, id) {
62
- if (!TYPESCRIPT_MODULE.test(id) || !DECORATOR_SYNTAX.test(code))
63
- return;
64
- const file = id.replace(/\?.*$/su, '');
65
- const result = ts.transpileModule(code, {
66
- fileName: file,
67
- compilerOptions: {
68
- target: ts.ScriptTarget.ES2024,
69
- module: ts.ModuleKind.ESNext,
70
- ...(file.endsWith('x') ? { jsx: ts.JsxEmit.ReactJSX } : {}),
71
- sourceMap: true,
72
- },
73
- });
74
- return {
75
- code: result.outputText.replace(/\n?\/\/# sourceMappingURL=.*$/u, '\n'),
76
- map: result.sourceMapText,
77
- };
78
- },
79
- },
80
90
  async writeBundle(bundleOptions) {
81
91
  // options.dir is the package's absolute outDir (<package>/lib); its
82
92
  // nearest package.json owns the bundle even when a custom config writes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-typert-generator",
3
3
  "description": "TypeScript project analyzer and model-driven Typert artifact generator",
4
- "version": "0.2.1-rc.4",
4
+ "version": "0.2.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -36,13 +36,13 @@
36
36
  "typescript": "^6.0.3"
37
37
  },
38
38
  "peerDependencies": {
39
- "@deepseek-ai/cordis": "~4.0.5"
39
+ "@deepseek-ai/cordis": "~4.0.6-alpha.1"
40
40
  },
41
41
  "devDependencies": {
42
- "@deepseek-ai/dsh-tools": "0.2.1-rc.4",
43
- "@deepseek-ai/dsh-tool-cordis": "0.2.1-rc.4",
44
- "@deepseek-ai/dsh-typert-registry": "0.2.1-rc.4",
45
- "@deepseek-ai/cordis": "~4.0.5",
42
+ "@deepseek-ai/dsh-tools": "0.2.2-alpha.2",
43
+ "@deepseek-ai/dsh-tool-cordis": "0.2.2-alpha.2",
44
+ "@deepseek-ai/dsh-typert-registry": "0.2.2-alpha.2",
45
+ "@deepseek-ai/cordis": "~4.0.6-alpha.1",
46
46
  "zod": "4.4.3"
47
47
  }
48
48
  }