@proteus-vue/component-ir 0.1.0 → 0.2.0-beta.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/dist/map.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BackendId } from '@proteus-vue/render-backend';
1
+ import type { BackendId } from '@proteus-vue/contracts';
2
2
  /** 语义类型 → 各端 Backend 控件(布局原语 + UI 原语 + 能力入口——G-31 §3 组件清单)
3
3
  * ★G-31 B5:vue-dom 列与 render-backend SEMANTIC_WEB_MAP 实际产出一致(div.proteus-* 语义类)——
4
4
  * 参考表即门禁标准,component-conformance 机器校验「快照 control == 参考表」 */
@@ -0,0 +1,106 @@
1
+ export type MpSpecStatus = 'covered' | 'planned' | 'private' | 'na' | 'gap';
2
+ export interface MpSpecClass {
3
+ status: MpSpecStatus;
4
+ /** covered/planned 时的 Proteus 承接(Hook/语义/组件) */
5
+ proteus?: string;
6
+ }
7
+ /** spec 快照(与 docs/generated/miniprogram-official-spec.json 同构) */
8
+ export interface MpOfficialSpec {
9
+ components: string[];
10
+ apis: string[];
11
+ }
12
+ export declare const SPEC_COVERED: Record<string, string>;
13
+ export declare const SPEC_PRIVATE: ReadonlySet<string>;
14
+ export declare const SPEC_NA: ReadonlySet<string>;
15
+ export declare const SPEC_PLANNED: Record<string, string>;
16
+ /** 单条分类(规则序:显式 covered → private → na → planned → 事件基名 → gap) */
17
+ export declare function classifySpecApi(name: string): MpSpecClass;
18
+ /** 组件分类:由 MP_MAPPING_MATRIX 的显式登记驱动(tag 命中即 covered/private/...) */
19
+ export declare function classifySpecComponent(tag: string, matrix: ReadonlyArray<{
20
+ mp: string;
21
+ status: string;
22
+ planned?: boolean;
23
+ }>): MpSpecClass;
24
+ /** 组件级显式分类(名不对齐/语义消灭/Skyline 专属——矩阵未逐条登记时的权威声明) */
25
+ export declare const SPEC_COMPONENT_OVERRIDE: Record<string, MpSpecClass>;
26
+ /**
27
+ * ★2026-09-18 补门禁:`SPEC_COMPONENT_OVERRIDE` 的引用一致性。
28
+ *
29
+ * 背景(本轮实测发现):`auditMatrixReferences` 只遍历 `MP_MAPPING_MATRIX`,
30
+ * override 表**完全不在引用校验范围内** → 表里长期存在两类未被发现的缺陷:
31
+ * ① **虚高覆盖**:5 个手势处理器标 `covered`,但指向的 `gesture.tap/pan/pinch/press`
32
+ * 在 PRIMITIVE_CATALOG 中是 `planned`(`covered` 的定义是「有可运行等价」);
33
+ * ② **悬空引用**:`gesture.long-press` 拼写错误(实际名为 `gesture.longpress`)。
34
+ * 两者都让「真·落地率」虚高且无人察觉。本函数把 override 表纳入同一校验。
35
+ *
36
+ * @param catalog 原语清单(SSOT,判定 covered 的引用是否真已落地)
37
+ * @param overrideTable 可选注入(测试用;缺省 = SPEC_COMPONENT_OVERRIDE)
38
+ * @returns issues 结构同矩阵引用检查;`dangling` 为未登记原语,`unimplemented` 为指向 planned 原语。
39
+ */
40
+ /**
41
+ * ★gesture-handler 组件 → **期望承载语义**(2026-09-19)。
42
+ *
43
+ * 背景(本轮实测发现):`double-tap-gesture-handler` 长期标 `covered` 并引用
44
+ * `gesture.draggable`(拖拽)——语义完全对不上,却因 `auditSpecOverrideRefs` 当时只校验
45
+ * 「引用存在且**已落地**」而无人发现(draggable 确实存在且已落地)。
46
+ * 「引用存在」≠「引用对得上」——本表把后者机器化:**covered 声明的引用必须包含期望语义**。
47
+ *
48
+ * 维护:新增 *-gesture-handler 类组件时同步本表;covered 行若换了承载语义须同步此处(否则 FAIL)。
49
+ */
50
+ export declare const GESTURE_HANDLER_EXPECTED: Record<string, string>;
51
+ export declare function auditSpecOverrideRefs(catalog: ReadonlyArray<{
52
+ semantic: string;
53
+ tag?: string;
54
+ status: string;
55
+ }>, overrideTable?: Record<string, MpSpecClass>): {
56
+ issues: Array<{
57
+ mp: string;
58
+ ref: string;
59
+ kind: 'semantic' | 'component' | 'unimplemented' | 'mismatched';
60
+ }>;
61
+ coveredRefs: number;
62
+ };
63
+ export interface SpecCoverageReport {
64
+ total: number;
65
+ covered: number;
66
+ planned: number;
67
+ private: number;
68
+ na: number;
69
+ gap: number;
70
+ /** 已归类项(total − gap)——分类完整性分母(防「漏登记」)。 */
71
+ accounted: number;
72
+ /** 分类完整率 = accounted/total(恒 100 表示「全部官方项都进了某个箱子」——不是「全实现」!) */
73
+ classifiedPercent: number;
74
+ /** ★可落地项 = covered + planned(排除 private/na——非目标或废弃) */
75
+ actionable: number;
76
+ /** ★真·落地率 = covered / actionable(诚实指标——「可用比例」,非「已归类比例」) */
77
+ landedPercent: number;
78
+ gaps: Array<{
79
+ kind: 'component' | 'api';
80
+ name: string;
81
+ }>;
82
+ /** 规划待落地清单(planned——可见待办) */
83
+ plannedItems: Array<{
84
+ kind: 'component' | 'api';
85
+ name: string;
86
+ proteus?: string;
87
+ }>;
88
+ }
89
+ /**
90
+ * ★spec 覆盖度审计:官方清单逐项分类 → 报告(gap 列出全部缺口名)。
91
+ * @param spec 官方清单快照
92
+ * @param matrix 组件显式登记(MP_MAPPING_MATRIX)
93
+ */
94
+ export declare function auditSpecCoverage(spec: MpOfficialSpec, matrix: ReadonlyArray<{
95
+ mp: string;
96
+ status: string;
97
+ planned?: boolean;
98
+ }>): SpecCoverageReport;
99
+ /**
100
+ * ★棘轮预算:covered 的硬下限 + gap 硬上限——只能向好的方向变。
101
+ * covered 下降 或 gap 上升 → CI 红(防「悄悄丢覆盖」);改善后应手动调高 covered 锁定成果。
102
+ */
103
+ export declare const SPEC_RATCHET: {
104
+ coveredMin: number;
105
+ gapMax: number;
106
+ };
@@ -2,7 +2,7 @@ export type PrimitiveKind = 'layout' | 'ui' | 'shell' | 'gesture' | 'capability'
2
2
  /** 状态:implemented = 已在 SEMANTIC_BACKEND_MAP 登记 ≥3 端(G-31.4/G-32.3 门禁适用);planned = 已冻结待实现(L2 生态) */
3
3
  export type PrimitiveStatus = 'implemented' | 'planned';
4
4
  export interface PrimitiveDef {
5
- /** 清单编号(L1..L12 / U1..U18 / S1..S10 / G1..G10 / C1..C50 / E1..E28) */
5
+ /** 清单编号(L1..L16 / U1..U29 / S1..S17 / G1..G10 / C1..C81 / E1..E29) */
6
6
  id: string;
7
7
  kind: PrimitiveKind;
8
8
  /** 语义标识(<domain>.<kind>——C-IR semantic / 能力属性) */
@@ -31,5 +31,5 @@ export declare function primitiveById(id: string): PrimitiveDef | undefined;
31
31
  export declare function primitiveBySemantic(semantic: string): PrimitiveDef | undefined;
32
32
  /** 按 p-* 标签查原语 */
33
33
  export declare function primitiveByTag(tag: string): PrimitiveDef | undefined;
34
- /** 清单自检:128 项 / id 唯一 / semantic 唯一 / 编号连续 */
34
+ /** 清单自检:长度/id 唯一/semantic 唯一/tag 唯一(长度按 SSOT 常量动态——新增项同步本行注释) */
35
35
  export declare function checkPrimitiveCatalog(): string[];
package/dist/schema.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface ComponentIR {
15
15
  degradation?: Record<string, 'supported' | 'fallback' | 'unsupported'>;
16
16
  }
17
17
  /** 语义枚举(与 plan component-ir.schema.json 一致)——<domain>.<kind> */
18
- export declare const SEMANTIC_ENUM: readonly ["layout.box", "layout.inline", "layout.stack", "layout.grid", "layout.fluid", "layout.adaptive", "layout.fit", "layout.spacer", "layout.divider", "layout.scroll", "layout.virtual-list", "layout.masonry", "layout.split", "layout.safe", "layout.sidebar", "ui.text", "ui.heading", "ui.rich-text", "ui.icon", "ui.image", "ui.avatar", "ui.media", "ui.canvas", "ui.svg", "ui.input", "ui.textarea", "ui.select", "ui.checkbox", "ui.radio", "ui.switch", "ui.slider", "ui.picker", "ui.form", "ui.button", "ui.list", "ui.nav", "shell.page", "shell.nav", "shell.tabbar", "shell.segment", "shell.drawer", "shell.modal", "shell.popover", "shell.toast", "shell.action-sheet", "gesture.draggable", "gesture.scrollable", "engineering.router-link", "engineering.transition", "engineering.animate", "capability.scan-qr", "capability.pick-photo", "capability.location"];
18
+ export declare const SEMANTIC_ENUM: readonly ["layout.box", "layout.inline", "layout.stack", "layout.grid", "layout.fluid", "layout.adaptive", "layout.fit", "layout.spacer", "layout.divider", "layout.scroll", "layout.virtual-list", "layout.masonry", "layout.split", "layout.safe", "layout.sidebar", "layout.aspect", "layout.zone", "ui.text", "ui.heading", "ui.rich-text", "ui.icon", "ui.image", "ui.avatar", "ui.media", "ui.canvas", "ui.svg", "ui.input", "ui.textarea", "ui.select", "ui.checkbox", "ui.radio", "ui.switch", "ui.slider", "ui.picker", "ui.form", "ui.button", "ui.list", "ui.nav", "ui.loading", "ui.scale", "ui.skeleton", "ui.progress", "ui.label", "ui.selection", "ui.camera", "shell.page", "shell.nav", "shell.tabbar", "shell.segment", "shell.drawer", "shell.modal", "shell.popover", "shell.toast", "shell.action-sheet", "shell.mask", "shell.popup", "shell.toolbar", "shell.page-container", "shell.keyboard-accessory", "shell.webview", "shell.ad", "ui.map", "gesture.draggable", "gesture.scrollable", "engineering.router-link", "engineering.transition", "engineering.animate", "engineering.error-boundary", "engineering.share-element", "capability.location", "capability.qr-code", "capability.camera"];
19
19
  /** C-IR JSON Schema(等价于 plan component-ir.schema.json——TS 内嵌供校验/工具消费) */
20
20
  export declare const COMPONENT_IR_SCHEMA: {
21
21
  readonly $schema: "https://json-schema.org/draft/2020-12/schema";
@@ -30,7 +30,7 @@ export declare const COMPONENT_IR_SCHEMA: {
30
30
  };
31
31
  readonly semantic: {
32
32
  readonly type: "string";
33
- readonly enum: readonly ["layout.box", "layout.inline", "layout.stack", "layout.grid", "layout.fluid", "layout.adaptive", "layout.fit", "layout.spacer", "layout.divider", "layout.scroll", "layout.virtual-list", "layout.masonry", "layout.split", "layout.safe", "layout.sidebar", "ui.text", "ui.heading", "ui.rich-text", "ui.icon", "ui.image", "ui.avatar", "ui.media", "ui.canvas", "ui.svg", "ui.input", "ui.textarea", "ui.select", "ui.checkbox", "ui.radio", "ui.switch", "ui.slider", "ui.picker", "ui.form", "ui.button", "ui.list", "ui.nav", "shell.page", "shell.nav", "shell.tabbar", "shell.segment", "shell.drawer", "shell.modal", "shell.popover", "shell.toast", "shell.action-sheet", "gesture.draggable", "gesture.scrollable", "engineering.router-link", "engineering.transition", "engineering.animate", "capability.scan-qr", "capability.pick-photo", "capability.location"];
33
+ readonly enum: readonly ["layout.box", "layout.inline", "layout.stack", "layout.grid", "layout.fluid", "layout.adaptive", "layout.fit", "layout.spacer", "layout.divider", "layout.scroll", "layout.virtual-list", "layout.masonry", "layout.split", "layout.safe", "layout.sidebar", "layout.aspect", "layout.zone", "ui.text", "ui.heading", "ui.rich-text", "ui.icon", "ui.image", "ui.avatar", "ui.media", "ui.canvas", "ui.svg", "ui.input", "ui.textarea", "ui.select", "ui.checkbox", "ui.radio", "ui.switch", "ui.slider", "ui.picker", "ui.form", "ui.button", "ui.list", "ui.nav", "ui.loading", "ui.scale", "ui.skeleton", "ui.progress", "ui.label", "ui.selection", "ui.camera", "shell.page", "shell.nav", "shell.tabbar", "shell.segment", "shell.drawer", "shell.modal", "shell.popover", "shell.toast", "shell.action-sheet", "shell.mask", "shell.popup", "shell.toolbar", "shell.page-container", "shell.keyboard-accessory", "shell.webview", "shell.ad", "ui.map", "gesture.draggable", "gesture.scrollable", "engineering.router-link", "engineering.transition", "engineering.animate", "engineering.error-boundary", "engineering.share-element", "capability.location", "capability.qr-code", "capability.camera"];
34
34
  };
35
35
  readonly props: {
36
36
  readonly type: "object";
@@ -60,3 +60,44 @@ export declare const COMPONENT_IR_SCHEMA: {
60
60
  };
61
61
  /** C-IR 组件标签 → 语义类型(组件清单映射——G-32 ①-③ 组件原语 + G-31 L1 布局/UI 原语 + ★B4 现有组件对齐) */
62
62
  export declare const TAG_SEMANTIC_MAP: Record<string, string>;
63
+ /**
64
+ * ★框架**内部运行时标签**(2026-09-18 批次 7):由编译器产出或仅供内部运行的组件标签——
65
+ * 它们**刻意不获得跨端语义**(不登记进 TAG_SEMANTIC_MAP / PRIMITIVE_CATALOG),
66
+ * 但必须在「未登记 p-*」反黑盒检查中被识别,否则产生**错误告警**。
67
+ *
68
+ * 判定依据(与 G-31 一致:不把平台私有的实现载体上升为框架语义):
69
+ * - `p-svg-canvas`:G-62 SVG 动画降级的 **MP 运行时载体**(`template/svg-canvas` 规则从 `<svg>`
70
+ * 形状变化动画产出,见 packages/compiler/src/template.ts)。组件自身文档写明
71
+ * 「MP-only 运行时组件——离屏 canvas 逐帧绘制依赖 wx.createOffscreenCanvas;Web 端不走此组件,
72
+ * 故无 L2 等价物」→ 它是 `ui.svg` 语义在 MP 端的**实现形态**,不是独立跨端语义。
73
+ * ★修复背景:此前它被 `tag/unknown-p-star` 检查命中,编译期报
74
+ * 「未入库组件?产物将按未注册自定义组件输出(MP 端不渲染)」——**该断言是错的**
75
+ * (组件确实在库中、产物亦由 gen-routes 正确注册),属误导告警(实测 155 个文件受影响面)。
76
+ *
77
+ * 新增条目须给理由;**不得**用它绕过「新组件必须登记语义」的要求——仅限「实现载体」类。
78
+ */
79
+ export declare const FRAMEWORK_INTERNAL_TAGS: ReadonlySet<string>;
80
+ /**
81
+ * ★多标签共享语义的**显式别名登记**(2026-09-18)。
82
+ *
83
+ * 背景:`checkPrimitiveCatalog` 只校验 **catalog** 的 semantic 唯一,不校验 `TAG_SEMANTIC_MAP`
84
+ * 的**值**唯一——于是「两个标签指向同一语义」这一情形长期**无人校验**,实测存在 3 处:
85
+ * `layout.box`(p-box / p-view)、`layout.scroll`(p-scroll / p-scroll-view)、
86
+ * `engineering.router-link`(p-router-link / router-link)。
87
+ *
88
+ * 语义:这些**不是缺陷**(同一语义可由多个标签提供,如 `router-link` 是 Vue Router 风格兼容别名),
89
+ * 但**必须显式登记 + 给理由 + 指明规范标签**,否则属「悄悄重复」(新增重复值不再可能漏检——
90
+ * 由 auditCatalogConsistency 的 **C6** 强制)。
91
+ *
92
+ * ★规范标签(canonical)判定依据:**端对齐产物且实际被源码引用者**为规范;
93
+ * 另一者为 G-32 血统的兼容别名(历史组件,保留不删——删除属更大决策)。
94
+ * ★实测源码引用(排除构建产物/缓存):p-view 22 · p-scroll-view 2 · p-box 0 · p-scroll 1。
95
+ */
96
+ export interface TagAliasDecl {
97
+ /** 规范标签(端对齐产物 + 实际使用;catalog 应登记此 tag) */
98
+ canonical: string;
99
+ /** 兼容别名标签 */
100
+ aliases: string[];
101
+ reason: string;
102
+ }
103
+ export declare const TAG_SEMANTIC_ALIASES: Record<string, TagAliasDecl>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteus-vue/component-ir",
3
- "version": "0.1.0",
3
+ "version": "0.2.0-beta.1",
4
4
  "description": "G-31 组件与 API 语义化(component-semantics-plan B1):Component IR(C-IR)schema + 属性约束校验 + semantic 映射——组件=语义、属性=约束、Backend 消费 semantic 而非 tag(零依赖纯逻辑)",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -18,10 +18,10 @@
18
18
  "dist",
19
19
  "README.md"
20
20
  ],
21
+ "dependencies": {
22
+ "@proteus-vue/contracts": "0.1.1-beta.0"
23
+ },
21
24
  "scripts": {
22
25
  "build": "tsc -p tsconfig.build.json --emitDeclarationOnly && esbuild src/index.ts --bundle --format=esm --platform=neutral --outfile=dist/index.js"
23
- },
24
- "devDependencies": {
25
- "@proteus-vue/render-backend": "0.1.0"
26
26
  }
27
- }
27
+ }