@proteus-vue/render-backend 0.3.0-beta.28 → 0.3.0-beta.31
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.d.ts +2 -0
- package/dist/index.js +117 -14
- package/dist/runtime-profiler.d.ts +34 -0
- package/dist/screen-runtime.d.ts +36 -0
- package/dist/superapp-runtime.d.ts +28 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export type { ScreenCommandLike, ScreenTreeHost, ScreenAnimHost, RouteTransition
|
|
|
56
56
|
export { createHostScreenPorts, SCREEN_ANIM_DONE_KEY } from './screen-executor-host';
|
|
57
57
|
export { createScreenRuntime } from './screen-runtime';
|
|
58
58
|
export type { ScreenRuntime, ScreenRuntimeInstance, ScreenRuntimeArtifact, CreateScreenRuntimeOptions } from './screen-runtime';
|
|
59
|
+
export { createRuntimeProfiler, NULL_PROFILER } from './runtime-profiler';
|
|
60
|
+
export type { RuntimeProfiler, ProfEntry } from './runtime-profiler';
|
|
59
61
|
export { HOST_INVOKE_METHODS, HOST_SCREEN_METHODS, HOST_CAPABILITY_METHODS, HOST_METHOD_OPTIONAL } from './host-invoke-contract';
|
|
60
62
|
export { TAB_BAR_SPEC } from './tab-bar-spec';
|
|
61
63
|
export type { TabBarSpec } from './tab-bar-spec';
|
package/dist/index.js
CHANGED
|
@@ -3434,6 +3434,7 @@ function instantiateTemplate(tpl, opts) {
|
|
|
3434
3434
|
}
|
|
3435
3435
|
if (n.tag) out.tag = n.tag;
|
|
3436
3436
|
if (n.component) out.component = n.component;
|
|
3437
|
+
if (n.loc) out.loc = n.loc;
|
|
3437
3438
|
if (n.slotOutlet) out.slotOutlet = n.slotOutlet;
|
|
3438
3439
|
if (n.slotFor) out.slotFor = n.slotFor;
|
|
3439
3440
|
out.id = id + idOffset;
|
|
@@ -7277,6 +7278,46 @@ function createHostScreenPorts(opts) {
|
|
|
7277
7278
|
};
|
|
7278
7279
|
}
|
|
7279
7280
|
|
|
7281
|
+
// src/runtime-profiler.ts
|
|
7282
|
+
var NULL_PROFILER = {
|
|
7283
|
+
time: (_label, fn) => fn(),
|
|
7284
|
+
drain: () => []
|
|
7285
|
+
};
|
|
7286
|
+
var round1 = (v) => Math.round(v * 10) / 10;
|
|
7287
|
+
function createRuntimeProfiler() {
|
|
7288
|
+
const perf = globalThis.performance;
|
|
7289
|
+
const now = perf && typeof perf.now === "function" ? () => perf.now() : () => Date.now();
|
|
7290
|
+
const acc = /* @__PURE__ */ new Map();
|
|
7291
|
+
return {
|
|
7292
|
+
time(label, fn, loc) {
|
|
7293
|
+
const t0 = now();
|
|
7294
|
+
try {
|
|
7295
|
+
return fn();
|
|
7296
|
+
} finally {
|
|
7297
|
+
const ms = now() - t0;
|
|
7298
|
+
let e = acc.get(label);
|
|
7299
|
+
if (!e) {
|
|
7300
|
+
e = { count: 0, totalMs: 0, maxMs: 0 };
|
|
7301
|
+
acc.set(label, e);
|
|
7302
|
+
}
|
|
7303
|
+
e.count += 1;
|
|
7304
|
+
e.totalMs += ms;
|
|
7305
|
+
if (ms > e.maxMs) e.maxMs = ms;
|
|
7306
|
+
if (loc && !e.loc) e.loc = loc;
|
|
7307
|
+
}
|
|
7308
|
+
},
|
|
7309
|
+
drain() {
|
|
7310
|
+
const out = [];
|
|
7311
|
+
for (const [label, e] of acc) {
|
|
7312
|
+
out.push({ label, count: e.count, totalMs: round1(e.totalMs), maxMs: round1(e.maxMs), ...e.loc ? { loc: e.loc } : {} });
|
|
7313
|
+
}
|
|
7314
|
+
acc.clear();
|
|
7315
|
+
out.sort((a, b) => b.totalMs - a.totalMs);
|
|
7316
|
+
return out;
|
|
7317
|
+
}
|
|
7318
|
+
};
|
|
7319
|
+
}
|
|
7320
|
+
|
|
7280
7321
|
// src/screen-runtime.ts
|
|
7281
7322
|
function createScreenRuntime(opts) {
|
|
7282
7323
|
const base = opts.contentIdBase;
|
|
@@ -7286,12 +7327,13 @@ function createScreenRuntime(opts) {
|
|
|
7286
7327
|
function make(name) {
|
|
7287
7328
|
const art = opts.artifacts[name];
|
|
7288
7329
|
if (!art) throw new Error(`[screen-runtime] \u65E0\u8BE5\u5C4F\u4EA7\u7269\uFF1A${name}`);
|
|
7330
|
+
const prof = opts.profile ? createRuntimeProfiler() : NULL_PROFILER;
|
|
7289
7331
|
const data = { ...art.data, ...opts.seedData?.[name] ?? {} };
|
|
7290
7332
|
const read = (n) => data[n];
|
|
7291
|
-
let inst = instantiateTemplate(art.tpl, { viewport: opts.viewport, read, table: art.table, registry: new ListRegistry() });
|
|
7333
|
+
let inst = prof.time("instantiate", () => instantiateTemplate(art.tpl, { viewport: opts.viewport, read, table: art.table, registry: new ListRegistry() }));
|
|
7292
7334
|
let localIdsOrdered = inst.nodes.map((n) => n.id);
|
|
7293
7335
|
function rebuild() {
|
|
7294
|
-
inst = instantiateTemplate(art.tpl, { viewport: opts.viewport, read, table: art.table, registry: new ListRegistry() });
|
|
7336
|
+
inst = prof.time("instantiate", () => instantiateTemplate(art.tpl, { viewport: opts.viewport, read, table: art.table, registry: new ListRegistry() }));
|
|
7295
7337
|
localIdsOrdered = inst.nodes.map((n) => n.id);
|
|
7296
7338
|
}
|
|
7297
7339
|
if (inst.stats.componentNodes === 0 && inst.nodes.some((n) => n.component)) {
|
|
@@ -7306,10 +7348,16 @@ function createScreenRuntime(opts) {
|
|
|
7306
7348
|
const evalCtx = { read };
|
|
7307
7349
|
vapor.load(evalCtx, () => {
|
|
7308
7350
|
});
|
|
7309
|
-
vapor.relink(evalCtx);
|
|
7310
|
-
slotRt.flush();
|
|
7351
|
+
prof.time("relink", () => vapor.relink(evalCtx));
|
|
7352
|
+
prof.time("flush", () => slotRt.flush());
|
|
7311
7353
|
const byNodeEvent = indexEventBindings(art.events);
|
|
7312
7354
|
const dispatchState = createDispatchState();
|
|
7355
|
+
const locByHandler = /* @__PURE__ */ new Map();
|
|
7356
|
+
for (const e of art.events ?? []) {
|
|
7357
|
+
const b = e;
|
|
7358
|
+
if (b.handler && b.loc) locByHandler.set(b.handler, b.loc);
|
|
7359
|
+
}
|
|
7360
|
+
const handlerErrors = [];
|
|
7313
7361
|
function runHandler(handlerName, _nodeId, payload) {
|
|
7314
7362
|
const acts = art.handlers[handlerName];
|
|
7315
7363
|
if (!acts) return false;
|
|
@@ -7325,7 +7373,20 @@ function createScreenRuntime(opts) {
|
|
|
7325
7373
|
continue;
|
|
7326
7374
|
}
|
|
7327
7375
|
const ctx2 = { read: (n) => n === "$event" ? payload : data[n] };
|
|
7328
|
-
|
|
7376
|
+
let v;
|
|
7377
|
+
try {
|
|
7378
|
+
v = prof.time(`handler\u300C${handlerName}\u300D`, () => evalExpr(a.program, ctx2), locByHandler.get(handlerName));
|
|
7379
|
+
} catch (e) {
|
|
7380
|
+
const msg = String(e?.message ?? e);
|
|
7381
|
+
const loc = locByHandler.get(handlerName);
|
|
7382
|
+
const at = loc ? `\uFF08\u6A21\u677F ${name}.vue:${loc.line}:${loc.column}\uFF09` : "";
|
|
7383
|
+
const detail = `[screen-runtime] ${name}: handler\u300C${handlerName}\u300D\u8282\u70B9 #${_nodeId}${at} \u8868\u8FBE\u5F0F \`${a.source ?? "(?)"}\` \u6C42\u503C\u5931\u8D25\uFF1A${msg}`;
|
|
7384
|
+
handlerErrors.push(detail);
|
|
7385
|
+
if (handlerErrors.length > 50) handlerErrors.shift();
|
|
7386
|
+
note(detail);
|
|
7387
|
+
opts.onError?.(detail);
|
|
7388
|
+
continue;
|
|
7389
|
+
}
|
|
7329
7390
|
if (!a.source) continue;
|
|
7330
7391
|
if (a.op === "add") {
|
|
7331
7392
|
const cur = data[a.source];
|
|
@@ -7343,8 +7404,8 @@ function createScreenRuntime(opts) {
|
|
|
7343
7404
|
}
|
|
7344
7405
|
function refreshData() {
|
|
7345
7406
|
rebuild();
|
|
7346
|
-
vapor.relink(evalCtx);
|
|
7347
|
-
slotRt.flush();
|
|
7407
|
+
prof.time("relink", () => vapor.relink(evalCtx));
|
|
7408
|
+
prof.time("flush", () => slotRt.flush());
|
|
7348
7409
|
}
|
|
7349
7410
|
return {
|
|
7350
7411
|
content() {
|
|
@@ -7352,12 +7413,17 @@ function createScreenRuntime(opts) {
|
|
|
7352
7413
|
},
|
|
7353
7414
|
dispatch(type, chain) {
|
|
7354
7415
|
const localChain = chain.map(localIdOf);
|
|
7355
|
-
const
|
|
7416
|
+
const fired = [];
|
|
7417
|
+
const r = prof.time("dispatch", () => dispatchGesture(localChain, type, byNodeEvent, dispatchState, (h, id) => {
|
|
7418
|
+
const ok = runHandler(h, id);
|
|
7419
|
+
if (ok) fired.push({ handler: h, nodeId: id, ...locByHandler.has(h) ? { loc: locByHandler.get(h) } : {} });
|
|
7420
|
+
return ok;
|
|
7421
|
+
}));
|
|
7356
7422
|
if (r.fired.length > 0) refreshData();
|
|
7357
|
-
return { handled: r.fired.length > 0, fired: r.fired };
|
|
7423
|
+
return { handled: r.fired.length > 0, fired: r.fired, firedHandlers: fired };
|
|
7358
7424
|
},
|
|
7359
7425
|
flush() {
|
|
7360
|
-
slotRt.flush();
|
|
7426
|
+
prof.time("flush", () => slotRt.flush());
|
|
7361
7427
|
},
|
|
7362
7428
|
refresh() {
|
|
7363
7429
|
refreshData();
|
|
@@ -7367,6 +7433,14 @@ function createScreenRuntime(opts) {
|
|
|
7367
7433
|
},
|
|
7368
7434
|
snapshot() {
|
|
7369
7435
|
return { ...data };
|
|
7436
|
+
},
|
|
7437
|
+
handlerErrors() {
|
|
7438
|
+
const out = handlerErrors.slice();
|
|
7439
|
+
handlerErrors.length = 0;
|
|
7440
|
+
return out;
|
|
7441
|
+
},
|
|
7442
|
+
profileStats() {
|
|
7443
|
+
return prof.drain();
|
|
7370
7444
|
}
|
|
7371
7445
|
};
|
|
7372
7446
|
}
|
|
@@ -7385,6 +7459,15 @@ function createScreenRuntime(opts) {
|
|
|
7385
7459
|
const out = {};
|
|
7386
7460
|
for (const [name, it] of instances) out[name] = it.snapshot();
|
|
7387
7461
|
return out;
|
|
7462
|
+
},
|
|
7463
|
+
/** ★★★排空各屏阶段耗时(CPU Profiler · 决策 #715)——按屏归并(每屏只在其有数据时出现)。 */
|
|
7464
|
+
profileStats() {
|
|
7465
|
+
const out = {};
|
|
7466
|
+
for (const [name, it] of instances) {
|
|
7467
|
+
const entries = it.profileStats();
|
|
7468
|
+
if (entries.length > 0) out[name] = entries;
|
|
7469
|
+
}
|
|
7470
|
+
return out;
|
|
7388
7471
|
}
|
|
7389
7472
|
};
|
|
7390
7473
|
}
|
|
@@ -7459,7 +7542,10 @@ function createSuperappRuntime(opts) {
|
|
|
7459
7542
|
viewport: opts.viewport,
|
|
7460
7543
|
...opts.navigate ? { navigate: opts.navigate } : {},
|
|
7461
7544
|
...opts.seedData ? { seedData: opts.seedData } : {},
|
|
7462
|
-
onNote: note
|
|
7545
|
+
onNote: note,
|
|
7546
|
+
...opts.onError ? { onError: opts.onError } : {},
|
|
7547
|
+
...opts.profile ? { profile: true } : {}
|
|
7548
|
+
// ★CPU Profiler(决策 #715)
|
|
7463
7549
|
});
|
|
7464
7550
|
let cur = "";
|
|
7465
7551
|
let lastHostReply = null;
|
|
@@ -7476,9 +7562,18 @@ function createSuperappRuntime(opts) {
|
|
|
7476
7562
|
note(`[superapp-runtime] \u624B\u52BF\u94FE JSON \u89E3\u6790\u5931\u8D25\uFF1A${String(chainJson).slice(0, 40)}`);
|
|
7477
7563
|
}
|
|
7478
7564
|
const r = dispatch(type, chain);
|
|
7479
|
-
|
|
7565
|
+
const srcLoc = r.firedHandlers?.find((h) => h.loc)?.loc;
|
|
7566
|
+
devEvents.push({
|
|
7567
|
+
type,
|
|
7568
|
+
id: kernelId,
|
|
7569
|
+
chain,
|
|
7570
|
+
handled: r.handled,
|
|
7571
|
+
fired: r.fired,
|
|
7572
|
+
time: Date.now(),
|
|
7573
|
+
...srcLoc ? { src: `${cur}.vue:${srcLoc.line}:${srcLoc.column}` } : {}
|
|
7574
|
+
});
|
|
7480
7575
|
if (devEvents.length > 200) devEvents.shift();
|
|
7481
|
-
return JSON.stringify(r);
|
|
7576
|
+
return JSON.stringify({ ...r, screen: cur });
|
|
7482
7577
|
};
|
|
7483
7578
|
function hostOk(reply) {
|
|
7484
7579
|
try {
|
|
@@ -7550,7 +7645,9 @@ function createSuperappRuntime(opts) {
|
|
|
7550
7645
|
currentContent: () => {
|
|
7551
7646
|
if (!cur) return null;
|
|
7552
7647
|
try {
|
|
7553
|
-
|
|
7648
|
+
const c = rt.instance(cur).content();
|
|
7649
|
+
const file = opts.artifacts[cur]?.file;
|
|
7650
|
+
return { ...c, screen: cur, ...file ? { file } : {} };
|
|
7554
7651
|
} catch {
|
|
7555
7652
|
return null;
|
|
7556
7653
|
}
|
|
@@ -7561,6 +7658,10 @@ function createSuperappRuntime(opts) {
|
|
|
7561
7658
|
devEvents.length = 0;
|
|
7562
7659
|
return out;
|
|
7563
7660
|
},
|
|
7661
|
+
// ★排空式:当前屏页面处理器运行期错误(带模板源位置)——宿主 dev-watch 转发面板 Console。
|
|
7662
|
+
handlerErrors: () => cur ? rt.instance(cur).handlerErrors() : [],
|
|
7663
|
+
// ★排空式:运行期阶段耗时(CPU Profiler · 决策 #715)——宿主 dev-watch 取走随 /ping?perf= 上报。
|
|
7664
|
+
profileStats: () => rt.profileStats(),
|
|
7564
7665
|
snapshot: () => rt.snapshot(),
|
|
7565
7666
|
lastHostReply: () => lastHostReply
|
|
7566
7667
|
};
|
|
@@ -7581,6 +7682,7 @@ export {
|
|
|
7581
7682
|
HOST_SCREEN_METHODS,
|
|
7582
7683
|
Managed,
|
|
7583
7684
|
ManagedRegistry,
|
|
7685
|
+
NULL_PROFILER,
|
|
7584
7686
|
OWNERSHIP_ERRORS,
|
|
7585
7687
|
Owned,
|
|
7586
7688
|
OwnershipError,
|
|
@@ -7621,6 +7723,7 @@ export {
|
|
|
7621
7723
|
createQuotaManager,
|
|
7622
7724
|
createQuotaTracker,
|
|
7623
7725
|
createResourcePool,
|
|
7726
|
+
createRuntimeProfiler,
|
|
7624
7727
|
createScreenExecutor,
|
|
7625
7728
|
createScreenRuntime,
|
|
7626
7729
|
createSelfDrawBatchAdapter,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** 一条阶段采样(窗口内累加) */
|
|
2
|
+
export interface ProfEntry {
|
|
3
|
+
/** 标签(`instantiate` / `flush` / `dispatch` / `handler「h0」`…) */
|
|
4
|
+
label: string;
|
|
5
|
+
/** 调用次数 */
|
|
6
|
+
count: number;
|
|
7
|
+
/** 累计耗时(ms;窗口内) */
|
|
8
|
+
totalMs: number;
|
|
9
|
+
/** 单次最长(ms) */
|
|
10
|
+
maxMs: number;
|
|
11
|
+
/** 模板源位置(handler 类才有;1 基,整份 `.vue` 行) */
|
|
12
|
+
loc?: {
|
|
13
|
+
line: number;
|
|
14
|
+
column: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** 阶段采样出口(宿主/dev server 取走即清——排空式) */
|
|
18
|
+
export interface RuntimeProfiler {
|
|
19
|
+
/** 包一层计时:跑 `fn` 并把它耗时累加到 `label`(`loc` 仅首见记录)。 */
|
|
20
|
+
time<T>(label: string, fn: () => T, loc?: {
|
|
21
|
+
line: number;
|
|
22
|
+
column: number;
|
|
23
|
+
}): T;
|
|
24
|
+
/** 读并**清零**本窗口(按累计耗时降序)。 */
|
|
25
|
+
drain(): ProfEntry[];
|
|
26
|
+
}
|
|
27
|
+
/** 空实现(未启用 profiling 时用——`time` 直接透传,零开销)。 */
|
|
28
|
+
export declare const NULL_PROFILER: RuntimeProfiler;
|
|
29
|
+
/**
|
|
30
|
+
* 建一个阶段采样器。`now()` 优先用 `performance.now()`(亚毫秒),无则回落 `Date.now()`(ms)。
|
|
31
|
+
* ★诚实边界:`Date.now()` 的毫秒分辨率会把"微秒级 handler"记成 0ms——**不影响找热点**
|
|
32
|
+
* (热点本就是 ms 级),但别把 0 读成"绝对没花时间"。
|
|
33
|
+
*/
|
|
34
|
+
export declare function createRuntimeProfiler(): RuntimeProfiler;
|
package/dist/screen-runtime.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LayoutTemplate, SubscriptionTable, EventBinding, DispatchState } from '@proteus-vue/slot-runtime';
|
|
2
|
+
import { type ProfEntry } from './runtime-profiler';
|
|
2
3
|
/** 一屏的运行期产物(与 `packages/cli/src/app-runtime-content.ts` 的 `ScreenRuntimeArtifact` 同形) */
|
|
3
4
|
export interface ScreenRuntimeArtifact {
|
|
4
5
|
tpl: LayoutTemplate;
|
|
@@ -40,11 +41,24 @@ export interface CreateScreenRuntimeOptions {
|
|
|
40
41
|
seedData?: Record<string, Record<string, unknown>>;
|
|
41
42
|
/** 诊断出口(不静默) */
|
|
42
43
|
onNote?: (note: string) => void;
|
|
44
|
+
/**
|
|
45
|
+
* ★★★**页面处理器运行期错误出口**(决策 #712)——handler 表达式求值失败时逐条调用(带**模板源位置**)。
|
|
46
|
+
* 与 `onNote` 分开:note 是"诊断信息"(console.log 级),本出口是**用户代码出错**
|
|
47
|
+
* (宿主/桥应转发到面板 Console 的 `error` 级 + 如实回传,不得静默吞掉)。
|
|
48
|
+
* 缺省 ⇒ 仅落进 `handlerErrors()` 排空缓冲(仍可读,不静默)。
|
|
49
|
+
*/
|
|
50
|
+
onError?: (error: string) => void;
|
|
43
51
|
/**
|
|
44
52
|
* ★导航出口(B1):handler 里的 `$nav('目标')` 动作 → 交给宿主/装配层执行导航
|
|
45
53
|
* (App 壳 = `router.push(target)`;与 `<navigator>` 同语义)。缺省 ⇒ 只记 note(不静默)。
|
|
46
54
|
*/
|
|
47
55
|
navigate?: (target: string) => void;
|
|
56
|
+
/**
|
|
57
|
+
* ★★★**运行期阶段耗时自采样**(CPU Profiler · 决策 #715)——dev 构建开启:给 `instantiate` /
|
|
58
|
+
* `flush` / `dispatch` / 每个 handler 计时,归因"卡在哪一段"。缺省 false ⇒ **零开销**(空实现)。
|
|
59
|
+
* 采样经 `profileStats()` 排空 ⇒ 宿主每 tick 取走(随 `/ping?perf=` 上报面板)。
|
|
60
|
+
*/
|
|
61
|
+
profile?: boolean;
|
|
48
62
|
}
|
|
49
63
|
/** 一屏的运行期实例(挂载 + 事件 + 增量) */
|
|
50
64
|
export interface ScreenRuntimeInstance {
|
|
@@ -60,6 +74,15 @@ export interface ScreenRuntimeInstance {
|
|
|
60
74
|
dispatch(type: string, chain: readonly number[], state?: DispatchState): {
|
|
61
75
|
handled: boolean;
|
|
62
76
|
fired: number[];
|
|
77
|
+
/** ★跑了哪些 handler + 各自**模板源位置**(决策 #712·source map)——面板 Events 锚回 `.vue:line:col` */
|
|
78
|
+
firedHandlers?: Array<{
|
|
79
|
+
handler: string;
|
|
80
|
+
nodeId: number;
|
|
81
|
+
loc?: {
|
|
82
|
+
line: number;
|
|
83
|
+
column: number;
|
|
84
|
+
};
|
|
85
|
+
}>;
|
|
63
86
|
};
|
|
64
87
|
/** 立即把脏槽位编成指令并交给 `applyOps`(确定性驱动入口) */
|
|
65
88
|
flush(): void;
|
|
@@ -73,6 +96,17 @@ export interface ScreenRuntimeInstance {
|
|
|
73
96
|
data(): Record<string, unknown>;
|
|
74
97
|
/** ★跨调用状态导出(浅拷贝)——供宿主(一次性 VM)在下次调用回灌为 `seedData`(见 CreateScreenRuntimeOptions.seedData) */
|
|
75
98
|
snapshot(): Record<string, unknown>;
|
|
99
|
+
/**
|
|
100
|
+
* ★★★**排空本屏页面处理器错误**(决策 #712)——自上次调用以来的 handler 求值失败(带模板源位置)。
|
|
101
|
+
* 排空式(取走即清):供宿主 dev-watch / 面板 Console 消费(与 `SuperappRuntime.devEvents` 同形态)。
|
|
102
|
+
*/
|
|
103
|
+
handlerErrors(): string[];
|
|
104
|
+
/**
|
|
105
|
+
* ★★★**排空本屏运行期阶段耗时**(CPU Profiler · 决策 #715)——自上次调用以来的阶段采样
|
|
106
|
+
* (`instantiate` / `relink` / `flush` / `dispatch` / `handler「hN」`,按累计耗时降序)。
|
|
107
|
+
* 排空式;未启用 profiling(`profile` 未开)⇒ 恒空数组。
|
|
108
|
+
*/
|
|
109
|
+
profileStats(): ProfEntry[];
|
|
76
110
|
}
|
|
77
111
|
export interface ScreenRuntime {
|
|
78
112
|
/** 取(或按需创建)某屏的运行期实例 */
|
|
@@ -81,6 +115,8 @@ export interface ScreenRuntime {
|
|
|
81
115
|
has(name: string): boolean;
|
|
82
116
|
/** ★跨调用状态导出(`{屏名: 数据}`)——一次性 VM 宿主回灌用 */
|
|
83
117
|
snapshot(): Record<string, Record<string, unknown>>;
|
|
118
|
+
/** ★★★排空**当前所有已建实例**的运行期阶段耗时(CPU Profiler · 决策 #715)——排空式、按屏归并。 */
|
|
119
|
+
profileStats(): Record<string, ProfEntry[]>;
|
|
84
120
|
}
|
|
85
121
|
/**
|
|
86
122
|
* 创建 App 壳的统一运行期。
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ScreenRuntimeArtifact } from './screen-runtime';
|
|
2
|
+
import type { ProfEntry } from './runtime-profiler';
|
|
2
3
|
/** 宿主原语(App 壳各端 `proteusHost` 的**子集**;平台无关形状) */
|
|
3
4
|
export interface SuperappHostPorts {
|
|
4
5
|
/** 建树 + 上屏(内核排版 + 宿主自绘);返回宿主回执 JSON 串 */
|
|
@@ -40,6 +41,10 @@ export interface SuperappRuntimeOptions {
|
|
|
40
41
|
seedData?: Record<string, Record<string, unknown>>;
|
|
41
42
|
/** 诊断(不静默) */
|
|
42
43
|
onNote?: (note: string) => void;
|
|
44
|
+
/** ★页面处理器运行期错误出口(决策 #712·source map)——转发给 `createScreenRuntime.onError`。 */
|
|
45
|
+
onError?: (error: string) => void;
|
|
46
|
+
/** ★★★**运行期阶段耗时自采样**(CPU Profiler · 决策 #715)——dev 构建开启;缺省零开销。 */
|
|
47
|
+
profile?: boolean;
|
|
43
48
|
}
|
|
44
49
|
export interface SuperappRuntime {
|
|
45
50
|
/** 挂载(或重挂载)某屏:实例化 → `host.mount`;并记忆为"当前屏"(手势派发用) */
|
|
@@ -54,16 +59,27 @@ export interface SuperappRuntime {
|
|
|
54
59
|
dispatchGesture(type: string, chain: readonly number[]): {
|
|
55
60
|
handled: boolean;
|
|
56
61
|
fired: number[];
|
|
62
|
+
firedHandlers?: Array<{
|
|
63
|
+
handler: string;
|
|
64
|
+
nodeId: number;
|
|
65
|
+
loc?: {
|
|
66
|
+
line: number;
|
|
67
|
+
column: number;
|
|
68
|
+
};
|
|
69
|
+
}>;
|
|
57
70
|
};
|
|
58
71
|
/** 当前屏名 */
|
|
59
72
|
current(): string;
|
|
60
|
-
/** ★DevTools 元素内省(决策 #674):当前屏**已实例化节点**(Template 实例化产物:id/parentId/tag/style/text)——供面板"元素"树。
|
|
73
|
+
/** ★DevTools 元素内省(决策 #674):当前屏**已实例化节点**(Template 实例化产物:id/parentId/tag/style/text)——供面板"元素"树。
|
|
74
|
+
* ★(决策 #713)`:file` = 当前屏源文件(dev 构建;面板据节点 `loc` 拼 `file:line:col`)。 */
|
|
61
75
|
currentContent(): {
|
|
62
76
|
viewport?: {
|
|
63
77
|
width: number;
|
|
64
78
|
height: number;
|
|
65
79
|
};
|
|
66
80
|
nodes: readonly unknown[];
|
|
81
|
+
screen?: string;
|
|
82
|
+
file?: string;
|
|
67
83
|
} | null;
|
|
68
84
|
/** ★DevTools 事件 trace(决策 #675):自上次调用以来发生的手势派发(type/命中 id/冒泡链/handled/fired)——排空式。 */
|
|
69
85
|
devEvents(): ReadonlyArray<{
|
|
@@ -72,8 +88,19 @@ export interface SuperappRuntime {
|
|
|
72
88
|
chain: readonly number[];
|
|
73
89
|
handled: boolean;
|
|
74
90
|
fired: readonly number[];
|
|
91
|
+
src?: string;
|
|
75
92
|
time: number;
|
|
76
93
|
}>;
|
|
94
|
+
/**
|
|
95
|
+
* ★★★**排空当前屏页面处理器运行期错误**(决策 #712 · source map 生态链)——自上次调用以来的
|
|
96
|
+
* handler 求值失败(带**模板源位置** `.vue:line:col`)。排空式,供宿主 dev-watch 转发面板 Console。
|
|
97
|
+
*/
|
|
98
|
+
handlerErrors(): string[];
|
|
99
|
+
/**
|
|
100
|
+
* ★★★**排空运行期阶段耗时**(CPU Profiler · 决策 #715)——自上次调用以来的各屏阶段采样
|
|
101
|
+
* (`{屏名: [{label,count,totalMs,maxMs,loc?}]}`,按累计耗时降序)。排空式;未开 profiling ⇒ 空。
|
|
102
|
+
*/
|
|
103
|
+
profileStats(): Record<string, ProfEntry[]>;
|
|
77
104
|
/** ★跨调用状态导出(`{屏名: 数据}`)——一次性 VM 宿主持有、下次回灌 `seedData` */
|
|
78
105
|
snapshot(): Record<string, Record<string, unknown>>;
|
|
79
106
|
/**
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteus-vue/render-backend",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.31",
|
|
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
8
|
"@proteus-vue/animation": "0.3.0-beta.28",
|
|
9
|
-
"@proteus-vue/component-ir": "0.3.0-beta.
|
|
9
|
+
"@proteus-vue/component-ir": "0.3.0-beta.31",
|
|
10
10
|
"@proteus-vue/contracts": "0.3.0-beta.28",
|
|
11
11
|
"@proteus-vue/router": "0.3.0-beta.28",
|
|
12
|
-
"@proteus-vue/slot-runtime": "0.3.0-beta.
|
|
12
|
+
"@proteus-vue/slot-runtime": "0.3.0-beta.31"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
15
|
"@vue/runtime-core": "^3.4.0"
|