@proteus-vue/render-backend 0.3.0-beta.11 → 0.3.0-beta.21
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/index.js +65 -4
- package/dist/spi.d.ts +4 -0
- package/dist/vue-dom.d.ts +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -80,6 +80,7 @@ var SEMANTIC_HEADLESS_MAP = {
|
|
|
80
80
|
"layout.split": "split",
|
|
81
81
|
"layout.safe": "safe",
|
|
82
82
|
"layout.sidebar": "sidebar",
|
|
83
|
+
"layout.formfactor": "formfactor",
|
|
83
84
|
"ui.text": "text",
|
|
84
85
|
"ui.button": "button",
|
|
85
86
|
"ui.image": "image",
|
|
@@ -175,6 +176,18 @@ function createHeadlessBackend() {
|
|
|
175
176
|
nodes.set(n.id, n);
|
|
176
177
|
return n;
|
|
177
178
|
},
|
|
179
|
+
// ★2026-09-26 文本保留:'#text' → 文本节点(内存树)
|
|
180
|
+
createText(text) {
|
|
181
|
+
const n = {
|
|
182
|
+
id: nextId++,
|
|
183
|
+
type: "#text",
|
|
184
|
+
props: {},
|
|
185
|
+
children: [],
|
|
186
|
+
parent: null,
|
|
187
|
+
text
|
|
188
|
+
};
|
|
189
|
+
return n;
|
|
190
|
+
},
|
|
178
191
|
insert(child, parent, anchor) {
|
|
179
192
|
const c = ensureNode(child);
|
|
180
193
|
const p = ensureNode(parent);
|
|
@@ -247,6 +260,8 @@ var SEMANTIC_WEB_MAP = {
|
|
|
247
260
|
"layout.split": { tag: "div", className: "proteus-split" },
|
|
248
261
|
"layout.safe": { tag: "div", className: "proteus-safe" },
|
|
249
262
|
"layout.sidebar": { tag: "div", className: "proteus-sidebar" },
|
|
263
|
+
// ★★Fluid System v2:柔性形态容器
|
|
264
|
+
"layout.formfactor": { tag: "div", className: "proteus-formfactor" },
|
|
250
265
|
"ui.text": { tag: "span" },
|
|
251
266
|
"ui.button": { tag: "button" },
|
|
252
267
|
"ui.image": { tag: "img" },
|
|
@@ -313,7 +328,9 @@ function createVueDomBackend(doc) {
|
|
|
313
328
|
const documentLike = doc ?? defaultDocument();
|
|
314
329
|
function ensureEl(handle) {
|
|
315
330
|
const el = handle;
|
|
316
|
-
if (!el || typeof el.tagName !== "string"
|
|
331
|
+
if (!el || typeof el.tagName !== "string" && el.nodeType !== 3) {
|
|
332
|
+
throw new Error("VueDomBackend: \u975E\u6CD5\u53E5\u67C4");
|
|
333
|
+
}
|
|
317
334
|
return el;
|
|
318
335
|
}
|
|
319
336
|
return {
|
|
@@ -331,6 +348,10 @@ function createVueDomBackend(doc) {
|
|
|
331
348
|
}
|
|
332
349
|
return documentLike.createElement(node.type);
|
|
333
350
|
},
|
|
351
|
+
// ★2026-09-26 文本保留:IR '#text' 节点 → 真实文本节点(此前 createText 无实现——IR 无文本节点)
|
|
352
|
+
createText(text) {
|
|
353
|
+
return documentLike.createTextNode(text);
|
|
354
|
+
},
|
|
334
355
|
insert(child, parent, anchor) {
|
|
335
356
|
const c = ensureEl(child);
|
|
336
357
|
const p = ensureEl(parent);
|
|
@@ -432,6 +453,7 @@ var SEMANTIC_NATIVE_MAPS = {
|
|
|
432
453
|
"layout.split": "UISplitViewController",
|
|
433
454
|
"layout.safe": "safeAreaLayoutGuide",
|
|
434
455
|
"layout.sidebar": "UISplitViewController.side",
|
|
456
|
+
"layout.formfactor": "UIViewController.formFactor",
|
|
435
457
|
"ui.text": "UILabel",
|
|
436
458
|
"ui.button": "UIButton",
|
|
437
459
|
"ui.image": "UIImageView",
|
|
@@ -501,6 +523,7 @@ var SEMANTIC_NATIVE_MAPS = {
|
|
|
501
523
|
"layout.split": "SlidingPaneLayout",
|
|
502
524
|
"layout.safe": "WindowInsets",
|
|
503
525
|
"layout.sidebar": "NavigationRail",
|
|
526
|
+
"layout.formfactor": "FormFactorLayout",
|
|
504
527
|
"ui.text": "TextView",
|
|
505
528
|
"ui.button": "Button",
|
|
506
529
|
"ui.image": "ImageView",
|
|
@@ -570,6 +593,7 @@ var SEMANTIC_NATIVE_MAPS = {
|
|
|
570
593
|
"layout.split": "SideBarContainer",
|
|
571
594
|
"layout.safe": "getAvoidArea",
|
|
572
595
|
"layout.sidebar": "SideBarContainer",
|
|
596
|
+
"layout.formfactor": "GridRow.formFactor",
|
|
573
597
|
"ui.text": "Text",
|
|
574
598
|
"ui.button": "Button",
|
|
575
599
|
"ui.image": "Image",
|
|
@@ -660,6 +684,21 @@ function createNativeBackend(adapter, platform = "ios") {
|
|
|
660
684
|
nodes.set(descriptor.id, descriptor);
|
|
661
685
|
return descriptor;
|
|
662
686
|
},
|
|
687
|
+
// ★2026-09-26 文本保留:'#text' → 文本描述符(type 'text',text 字段承载内容——
|
|
688
|
+
// readback/控件树即见真实文案;真机渲染通道接线时映射 Text/Label 内容)
|
|
689
|
+
createText(text) {
|
|
690
|
+
const descriptor = {
|
|
691
|
+
id: nextId++,
|
|
692
|
+
type: "text",
|
|
693
|
+
props: {},
|
|
694
|
+
children: [],
|
|
695
|
+
parent: null,
|
|
696
|
+
text,
|
|
697
|
+
handle: null
|
|
698
|
+
};
|
|
699
|
+
descriptor.handle = descriptor;
|
|
700
|
+
return descriptor;
|
|
701
|
+
},
|
|
663
702
|
insert(child, parent, anchor) {
|
|
664
703
|
const c = ensureNode(child);
|
|
665
704
|
const p = ensureNode(parent);
|
|
@@ -735,6 +774,7 @@ var SEMANTIC_FLUTTER_MAP = {
|
|
|
735
774
|
"layout.split": "Row",
|
|
736
775
|
"layout.safe": "SafeArea",
|
|
737
776
|
"layout.sidebar": "NavigationRail",
|
|
777
|
+
"layout.formfactor": "LayoutBuilder.formFactor",
|
|
738
778
|
"ui.text": "Text",
|
|
739
779
|
"ui.button": "FilledButton",
|
|
740
780
|
"ui.image": "Image",
|
|
@@ -846,6 +886,18 @@ function createFlutterBackend() {
|
|
|
846
886
|
nodes.set(descriptor.id, descriptor);
|
|
847
887
|
return descriptor;
|
|
848
888
|
},
|
|
889
|
+
// ★2026-09-26 文本保留:'#text' → Text widget 描述符
|
|
890
|
+
createText(text) {
|
|
891
|
+
const descriptor = {
|
|
892
|
+
id: nextId++,
|
|
893
|
+
widget: "Text",
|
|
894
|
+
props: {},
|
|
895
|
+
children: [],
|
|
896
|
+
parent: null,
|
|
897
|
+
text
|
|
898
|
+
};
|
|
899
|
+
return descriptor;
|
|
900
|
+
},
|
|
849
901
|
insert(child, parent, anchor) {
|
|
850
902
|
const c = ensureNode(child);
|
|
851
903
|
const p = ensureNode(parent);
|
|
@@ -990,6 +1042,10 @@ function createHybridRenderer(options) {
|
|
|
990
1042
|
}
|
|
991
1043
|
return handle;
|
|
992
1044
|
},
|
|
1045
|
+
// ★2026-09-26 文本保留:'#text' → 委托默认后端(文本无 semantic 不可路由——区域语义由父元素决定)
|
|
1046
|
+
createText(text) {
|
|
1047
|
+
return defaultBackend.createText(text);
|
|
1048
|
+
},
|
|
993
1049
|
insert(child, parent, anchor) {
|
|
994
1050
|
const b = backendOf(child);
|
|
995
1051
|
if (!b) return;
|
|
@@ -1168,6 +1224,8 @@ var TAG_SEMANTIC_MAP = {
|
|
|
1168
1224
|
// ——同一语义由两个标签提供;本条与 p-view 是并列的别名情形,非「先例」关系)
|
|
1169
1225
|
"p-aspect": "layout.aspect",
|
|
1170
1226
|
"p-zone": "layout.zone",
|
|
1227
|
+
"p-formfactor": "layout.formfactor",
|
|
1228
|
+
// ★★Fluid System v2:柔性形态容器
|
|
1171
1229
|
"p-loading": "ui.loading",
|
|
1172
1230
|
"p-scale": "ui.scale",
|
|
1173
1231
|
"p-skeleton": "ui.skeleton",
|
|
@@ -1219,6 +1277,8 @@ var LAYOUT = [
|
|
|
1219
1277
|
// ★#405 语义登记批:Fluid 体系剩余组件(语义层待多端映射 → planned L2——G-31.4 不足 3 端降级)
|
|
1220
1278
|
{ id: "L13", kind: "layout", semantic: "layout.aspect", tag: "p-aspect", props: ["ratio", "maxWidth"], mpEquiv: "\u65E0\uFF08\u7EB5\u6A2A\u6BD4\u5BB9\u5668\uFF09", tier: "L2", status: "planned" },
|
|
1221
1279
|
{ id: "L14", kind: "layout", semantic: "layout.zone", tag: "p-zone", props: ["designWidth"], mpEquiv: "\u65E0\uFF08\u5BB9\u5668\u65AD\u70B9\u5206\u533A\uFF09", tier: "L2", status: "planned" },
|
|
1280
|
+
// ★★Fluid System v2(2026-09-26):柔性形态容器——按设备形态自动编排布局拓扑/能力/密度/缩放
|
|
1281
|
+
{ id: "L26", kind: "layout", semantic: "layout.formfactor", tag: "p-formfactor", props: ["declared", "width", "height"], mpEquiv: "\u65E0\uFF08\u5F62\u6001\u7F16\u6392\u5BB9\u5668\uFF1Aglance/stack/duo/rail-split/rail-grid/dashboard/hero-focus-row\uFF09", tier: "L2", status: "implemented" },
|
|
1222
1282
|
// ★批次 7(2026-09-18)未登记组件补登记:安全区(刘海/折叠屏/降级)+ 侧边导航容器
|
|
1223
1283
|
{ id: "L15", kind: "layout", semantic: "layout.safe", tag: "p-safe", props: ["area", "fold", "fallback"], mpEquiv: "\u65E0\uFF08\u5B89\u5168\u533A\u8BED\u4E49\u5BB9\u5668\uFF09", tier: "L1", status: "implemented" },
|
|
1224
1284
|
{ id: "L16", kind: "layout", semantic: "layout.sidebar", tag: "p-sidebar", props: ["minSidebarWidth", "navWidth", "designWidth", "toggleLabel"], mpEquiv: "\u65E0\uFF08\u5BB9\u5668\u65AD\u70B9\u4FA7\u680F\uFF09", tier: "L1", status: "implemented" }
|
|
@@ -1782,6 +1842,7 @@ function createNodeOpsDispatcher(initialBackend) {
|
|
|
1782
1842
|
};
|
|
1783
1843
|
}
|
|
1784
1844
|
function renderIRTree(backend, ir, insertInto) {
|
|
1845
|
+
if (ir.type === "#text") return backend.createText(ir.text ?? "");
|
|
1785
1846
|
const root = backend.createElement(ir);
|
|
1786
1847
|
for (const child of ir.children) {
|
|
1787
1848
|
const c = renderIRTree(backend, child);
|
|
@@ -3521,7 +3582,7 @@ function createSinglePageContainer(opts = {}) {
|
|
|
3521
3582
|
const emit = (event, payload) => {
|
|
3522
3583
|
for (const fn of events[event] ?? []) fn(payload);
|
|
3523
3584
|
};
|
|
3524
|
-
function
|
|
3585
|
+
function createSlot2(config) {
|
|
3525
3586
|
const ownership = opts.ownership ? createPageOwnership(config.pageId ?? `page-${++seq}`, { graph: opts.ownership.graph, quotaBytes: opts.ownership.quotaBytes }) : null;
|
|
3526
3587
|
const page = makeSlotPage(seq, config, ownership);
|
|
3527
3588
|
if (!config.pageId) seq++;
|
|
@@ -3530,7 +3591,7 @@ function createSinglePageContainer(opts = {}) {
|
|
|
3530
3591
|
return page;
|
|
3531
3592
|
}
|
|
3532
3593
|
function createPage(config) {
|
|
3533
|
-
return
|
|
3594
|
+
return createSlot2(config);
|
|
3534
3595
|
}
|
|
3535
3596
|
async function destroyPage(handle) {
|
|
3536
3597
|
const page = pages.get(handle.pageId);
|
|
@@ -3568,7 +3629,7 @@ function createSinglePageContainer(opts = {}) {
|
|
|
3568
3629
|
destroyPage,
|
|
3569
3630
|
async push(config) {
|
|
3570
3631
|
for (const p of [...pages.values()]) await destroyPage(p);
|
|
3571
|
-
const page =
|
|
3632
|
+
const page = createSlot2(config);
|
|
3572
3633
|
await mountPage(page);
|
|
3573
3634
|
current = page;
|
|
3574
3635
|
return page;
|
package/dist/spi.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export interface IRNode {
|
|
|
10
10
|
props: Record<string, unknown>;
|
|
11
11
|
children: IRNode[];
|
|
12
12
|
ref?: unknown;
|
|
13
|
+
/** ★2026-09-26 文本保留:type='#text' 节点的字面内容(additive——既有消费者零影响) */
|
|
14
|
+
text?: string;
|
|
13
15
|
}
|
|
14
16
|
/** 布局约束(后端可自带布局器,否则走框架 IR 求解) */
|
|
15
17
|
export interface LayoutConstraints {
|
|
@@ -57,6 +59,8 @@ export interface ProteusRenderBackend {
|
|
|
57
59
|
readonly version: string;
|
|
58
60
|
readonly capabilities: BackendCapabilities;
|
|
59
61
|
createElement(node: IRNode): NodeHandle;
|
|
62
|
+
/** ★2026-09-26 文本保留:'#text' 节点 → 文本句柄(此前 IR 无文本节点,SPI 未列——现必选) */
|
|
63
|
+
createText(text: string): NodeHandle;
|
|
60
64
|
insert(child: NodeHandle, parent: NodeHandle, anchor?: NodeHandle): void;
|
|
61
65
|
remove(child: NodeHandle): void;
|
|
62
66
|
patchProp(el: NodeHandle, key: string, prev: unknown, next: unknown): void;
|
package/dist/vue-dom.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteus-vue/render-backend",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.21",
|
|
4
4
|
"description": "G-27 ProteusRenderBackend SPI:可插拔渲染后端接口 + conformance test + 官方后端原型(Headless/VueDom) + G-41 nodeOps Dispatcher——Render anywhere, on any engine(M1.4)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@proteus-vue/component-ir": "0.3.0-beta.
|
|
8
|
+
"@proteus-vue/component-ir": "0.3.0-beta.21",
|
|
9
9
|
"@proteus-vue/contracts": "0.3.0-beta.11"
|
|
10
10
|
},
|
|
11
11
|
"peerDependencies": {
|