@vobs/runtime 1.7.8 → 1.8.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.
Files changed (127) hide show
  1. package/README.md +1 -1
  2. package/dist/async-boundary.cjs +14 -4
  3. package/dist/async-boundary.cjs.map +1 -1
  4. package/dist/async-boundary.js +17 -7
  5. package/dist/async-boundary.js.map +1 -1
  6. package/dist/bind.cjs +43 -3
  7. package/dist/bind.cjs.map +1 -1
  8. package/dist/bind.js +48 -8
  9. package/dist/bind.js.map +1 -1
  10. package/dist/boundary.cjs +159 -84
  11. package/dist/boundary.cjs.map +1 -1
  12. package/dist/boundary.js +162 -87
  13. package/dist/boundary.js.map +1 -1
  14. package/dist/client-only.cjs +323 -0
  15. package/dist/client-only.cjs.map +1 -0
  16. package/dist/client-only.d.cts +42 -0
  17. package/dist/client-only.d.ts +42 -0
  18. package/dist/client-only.js +299 -0
  19. package/dist/client-only.js.map +1 -0
  20. package/dist/debug.cjs.map +1 -1
  21. package/dist/debug.d.cts +12 -2
  22. package/dist/debug.d.ts +12 -2
  23. package/dist/debug.js.map +1 -1
  24. package/dist/dom-events.cjs +46 -0
  25. package/dist/dom-events.cjs.map +1 -0
  26. package/dist/dom-events.d.cts +23 -0
  27. package/dist/dom-events.d.ts +23 -0
  28. package/dist/dom-events.js +21 -0
  29. package/dist/dom-events.js.map +1 -0
  30. package/dist/dom-props.cjs +154 -0
  31. package/dist/dom-props.cjs.map +1 -0
  32. package/dist/dom-props.d.cts +21 -0
  33. package/dist/dom-props.d.ts +21 -0
  34. package/dist/dom-props.js +128 -0
  35. package/dist/dom-props.js.map +1 -0
  36. package/dist/dynamic.cjs +68 -14
  37. package/dist/dynamic.cjs.map +1 -1
  38. package/dist/dynamic.js +73 -19
  39. package/dist/dynamic.js.map +1 -1
  40. package/dist/error-boundary.cjs +159 -84
  41. package/dist/error-boundary.cjs.map +1 -1
  42. package/dist/error-boundary.js +162 -87
  43. package/dist/error-boundary.js.map +1 -1
  44. package/dist/error.cjs +52 -20
  45. package/dist/error.cjs.map +1 -1
  46. package/dist/error.d.cts +8 -0
  47. package/dist/error.d.ts +8 -0
  48. package/dist/error.js +52 -20
  49. package/dist/error.js.map +1 -1
  50. package/dist/fragment.cjs.map +1 -1
  51. package/dist/fragment.js +1 -1
  52. package/dist/fragment.js.map +1 -1
  53. package/dist/hmr.cjs +137 -1
  54. package/dist/hmr.cjs.map +1 -1
  55. package/dist/hmr.js +135 -1
  56. package/dist/hmr.js.map +1 -1
  57. package/dist/index.cjs +713 -236
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.d.cts +5 -2
  60. package/dist/index.d.ts +5 -2
  61. package/dist/index.js +715 -245
  62. package/dist/index.js.map +1 -1
  63. package/dist/ops.cjs +561 -107
  64. package/dist/ops.cjs.map +1 -1
  65. package/dist/ops.d.cts +49 -4
  66. package/dist/ops.d.ts +49 -4
  67. package/dist/ops.js +557 -108
  68. package/dist/ops.js.map +1 -1
  69. package/dist/profiler.cjs +14 -4
  70. package/dist/profiler.cjs.map +1 -1
  71. package/dist/profiler.js +17 -7
  72. package/dist/profiler.js.map +1 -1
  73. package/dist/ref.cjs +160 -5
  74. package/dist/ref.cjs.map +1 -1
  75. package/dist/ref.js +160 -5
  76. package/dist/ref.js.map +1 -1
  77. package/dist/renderer.cjs.map +1 -1
  78. package/dist/renderer.d.cts +2 -0
  79. package/dist/renderer.d.ts +2 -0
  80. package/dist/show.cjs +196 -0
  81. package/dist/show.cjs.map +1 -0
  82. package/dist/show.d.cts +54 -0
  83. package/dist/show.d.ts +54 -0
  84. package/dist/show.js +171 -0
  85. package/dist/show.js.map +1 -0
  86. package/dist/svg.cjs +102 -0
  87. package/dist/svg.cjs.map +1 -0
  88. package/dist/svg.d.cts +21 -0
  89. package/dist/svg.d.ts +21 -0
  90. package/dist/svg.js +76 -0
  91. package/dist/svg.js.map +1 -0
  92. package/package.json +20 -2
  93. package/src/bind.ts +30 -2
  94. package/src/boundaries.test.ts +54 -1
  95. package/src/boundary.ts +24 -8
  96. package/src/clear-remove.test.ts +85 -0
  97. package/src/client-only.test.ts +140 -0
  98. package/src/client-only.ts +65 -0
  99. package/src/component-empty-return.test.ts +123 -0
  100. package/src/debug.ts +12 -1
  101. package/src/dom-events.ts +32 -0
  102. package/src/dom-props-consistency.test.ts +149 -0
  103. package/src/dom-props.test.ts +70 -0
  104. package/src/dom-props.ts +107 -0
  105. package/src/dynamic.ts +91 -14
  106. package/src/error.test.ts +76 -1
  107. package/src/error.ts +87 -22
  108. package/src/event-cleanup-growth.test.ts +128 -0
  109. package/src/events.test.ts +16 -3
  110. package/src/hmr.ts +8 -2
  111. package/src/index.ts +13 -1
  112. package/src/invariants.test.ts +252 -0
  113. package/src/list-fast-path.test.ts +83 -0
  114. package/src/list-reactive-item.test.ts +77 -0
  115. package/src/ops.ts +419 -60
  116. package/src/props.test.ts +61 -1
  117. package/src/ref-cleanup.test.ts +144 -0
  118. package/src/ref.ts +57 -8
  119. package/src/remove-listener-identity.test.ts +97 -0
  120. package/src/renderer.ts +3 -1
  121. package/src/select-hidden-subscription.test.ts +104 -0
  122. package/src/show-classlist.test.ts +205 -0
  123. package/src/show.ts +107 -0
  124. package/src/spread-stable-shape.test.ts +109 -0
  125. package/src/spread.test.ts +86 -0
  126. package/src/svg.test.ts +28 -1
  127. package/src/svg.ts +34 -0
package/dist/hmr.cjs CHANGED
@@ -32,6 +32,141 @@ __export(hmr_exports, {
32
32
  updateHmrModule: () => updateHmrModule
33
33
  });
34
34
  module.exports = __toCommonJS(hmr_exports);
35
+
36
+ // packages/runtime/src/error.ts
37
+ var _VobsError = class _VobsError extends Error {
38
+ constructor(options) {
39
+ super(options.message);
40
+ this.name = "VobsError";
41
+ this.code = options.code;
42
+ this.severity = options.severity ?? "error";
43
+ this.layer = options.layer ?? "runtime";
44
+ this.cause = options.cause;
45
+ this.fix = options.fix;
46
+ this.location = options.location;
47
+ this.trace = options.trace;
48
+ this.example = options.example;
49
+ this.docs = options.docs;
50
+ this.codeFrame = options.codeFrame;
51
+ }
52
+ };
53
+ __name(_VobsError, "VobsError");
54
+ var VobsError = _VobsError;
55
+ function isVobsError(value) {
56
+ return value instanceof VobsError || Boolean(value && typeof value === "object" && typeof value.code === "string" && typeof value.message === "string");
57
+ }
58
+ __name(isVobsError, "isVobsError");
59
+ function isForeignVobsError(value) {
60
+ return value instanceof Error && value.name === "VobsError" && typeof value.code === "string";
61
+ }
62
+ __name(isForeignVobsError, "isForeignVobsError");
63
+ function describeUnknown(value) {
64
+ if (value === null || value === void 0) return String(value);
65
+ if (typeof value === "string") return value;
66
+ if (typeof value === "object") {
67
+ const message = value.message;
68
+ if (typeof message === "string" && message !== "") return message;
69
+ try {
70
+ return JSON.stringify(value) ?? String(value);
71
+ } catch {
72
+ return String(value);
73
+ }
74
+ }
75
+ return String(value);
76
+ }
77
+ __name(describeUnknown, "describeUnknown");
78
+ function adoptVobsError(value, defaults) {
79
+ return new VobsError({
80
+ code: value.code,
81
+ message: value.message,
82
+ severity: value.severity ?? defaults.severity,
83
+ layer: value.layer ?? defaults.layer,
84
+ cause: value.cause ?? (value instanceof Error ? value : void 0),
85
+ fix: value.fix ?? defaults.fix,
86
+ location: value.location,
87
+ trace: value.trace,
88
+ example: value.example,
89
+ docs: value.docs,
90
+ codeFrame: value.codeFrame
91
+ });
92
+ }
93
+ __name(adoptVobsError, "adoptVobsError");
94
+ function normalizeVobsError(value, defaults = {}) {
95
+ if (value instanceof VobsError) return value;
96
+ if (isForeignVobsError(value)) return adoptVobsError(value, defaults);
97
+ if (value instanceof Error) {
98
+ const metadata = value;
99
+ const code = defaults.code ?? (typeof metadata.vobsCode === "string" ? metadata.vobsCode : void 0);
100
+ if (code) {
101
+ defineErrorMetadata(value, "code", code);
102
+ if (value.code !== code) {
103
+ return new VobsError({
104
+ code,
105
+ message: value.message,
106
+ severity: defaults.severity ?? "error",
107
+ layer: defaults.layer ?? "runtime",
108
+ cause: value,
109
+ fix: defaults.fix ?? (typeof metadata.vobsHint === "string" ? metadata.vobsHint : void 0)
110
+ });
111
+ }
112
+ }
113
+ defineErrorMetadata(value, "severity", defaults.severity ?? "error");
114
+ defineErrorMetadata(value, "layer", defaults.layer ?? "runtime");
115
+ const fix = defaults.fix ?? (typeof metadata.vobsHint === "string" ? metadata.vobsHint : void 0);
116
+ if (fix) defineErrorMetadata(value, "fix", fix);
117
+ const source = metadata.vobsSource;
118
+ if (source && typeof source === "object" && typeof source.file === "string" && typeof source.line === "number" && typeof source.column === "number") {
119
+ defineErrorMetadata(value, "location", source);
120
+ }
121
+ return value;
122
+ }
123
+ if (isVobsError(value)) return adoptVobsError(value, defaults);
124
+ return new VobsError({
125
+ code: defaults.code ?? "VOBS_UNKNOWN",
126
+ message: describeUnknown(value),
127
+ severity: defaults.severity ?? "error",
128
+ layer: defaults.layer ?? "runtime",
129
+ cause: void 0,
130
+ fix: defaults.fix
131
+ });
132
+ }
133
+ __name(normalizeVobsError, "normalizeVobsError");
134
+ function defineErrorMetadata(target, key, value) {
135
+ if (key in target) return;
136
+ try {
137
+ Object.defineProperty(target, key, { configurable: true, enumerable: false, value, writable: true });
138
+ } catch {
139
+ }
140
+ }
141
+ __name(defineErrorMetadata, "defineErrorMetadata");
142
+ function formatVobsError(value, options = {}) {
143
+ const error = normalizeVobsError(value);
144
+ const code = error.code || "VOBS_UNKNOWN";
145
+ const severity = error.severity || "error";
146
+ if (options.environment === "production") return `[Vobs ${code}] ${error.message}`;
147
+ const lines = [`[Vobs ${capitalize(severity)}] ${error.message}`, `Code: ${code}`];
148
+ if (error.location) lines.push(`Location: ${error.location.file}:${error.location.line}:${error.location.column}`);
149
+ if (error.codeFrame) lines.push("", error.codeFrame);
150
+ if (error.cause !== void 0) lines.push(`Cause: ${formatCause(error.cause)}`);
151
+ if (error.trace?.length) lines.push("", `Trace: ${error.trace.join(" \u2192 ")}`);
152
+ if (error.fix) lines.push("", `Fix: ${error.fix}`);
153
+ if (error.example) lines.push("", `Example:
154
+ ${error.example}`);
155
+ if (error.docs) lines.push(`Docs: ${error.docs}`);
156
+ if (options.includeStack && error.stack) lines.push("", error.stack);
157
+ return lines.join("\n");
158
+ }
159
+ __name(formatVobsError, "formatVobsError");
160
+ function formatCause(value) {
161
+ return value instanceof Error ? `${value.name}: ${value.message}` : String(value);
162
+ }
163
+ __name(formatCause, "formatCause");
164
+ function capitalize(value) {
165
+ return value.slice(0, 1).toUpperCase() + value.slice(1);
166
+ }
167
+ __name(capitalize, "capitalize");
168
+
169
+ // packages/runtime/src/hmr.ts
35
170
  var globalTarget = globalThis;
36
171
  var hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: /* @__PURE__ */ new Map(), states: /* @__PURE__ */ new Map() };
37
172
  globalTarget.__VOBS_HMR__ = hmrGlobal;
@@ -69,7 +204,8 @@ function updateHmrModule(moduleId, nextModule) {
69
204
  for (const instance of instances) {
70
205
  try {
71
206
  instance.refresh();
72
- } catch {
207
+ } catch (error) {
208
+ console.error(formatVobsError(error, { includeStack: true }));
73
209
  }
74
210
  }
75
211
  }
package/dist/hmr.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hmr.ts"],"sourcesContent":["import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n /** 编译器生成的 hmrStateRef 注册表:键为 `${moduleId}#${声明名}`,值跨模块重执行保活。 */\n states: Map<string, unknown>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>(), states: new Map<string, unknown>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(moduleId: string, nextModule: Record<string, unknown>): void {\n const module = hmrGlobal.modules.get(moduleId)\n if (!module) return\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) return\n // 快照后正序遍历:实例在自身渲染开始前注册,祖先必然先于后代入列——\n // 祖先先刷新会 dispose 上一轮渲染作用域,其树内旧后代实例的 refresh\n // 命中已销毁守卫被跳过,避免同一组件在一次热更新中重渲染两次。\n // 同时 refresh 重渲染以新代码创建的全新实例不在快照中,天然不会再刷新。\n const instances = [...module.instances]\n for (const instance of instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\n/**\n * 编译器为模块顶层 state() 声明生成的取值入口。键为 `${moduleId}#${声明名}`,\n * 与手动 store 键空间隔离。模块热更新重执行时复用既有信号实例:旧导入方持有的\n * 实例与新模块实例共享同一份状态,消除\"两份模块、两份状态\"导致的编辑不生效/页面半边失灵。\n */\nexport function hmrStateRef<T>(key: string, create: () => T): T {\n const states = hmrGlobal.states\n if (states.has(key)) return states.get(key) as T\n const value = create()\n states.set(key, value)\n return value\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n"],"mappings":"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","names":["module"]}
1
+ {"version":3,"sources":["../src/hmr.ts","../src/error.ts"],"sourcesContent":["import type { VobsNode } from './fragment'\nimport { formatVobsError } from './error'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n /** 编译器生成的 hmrStateRef 注册表:键为 `${moduleId}#${声明名}`,值跨模块重执行保活。 */\n states: Map<string, unknown>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>(), states: new Map<string, unknown>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(moduleId: string, nextModule: Record<string, unknown>): void {\n const module = hmrGlobal.modules.get(moduleId)\n if (!module) return\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) return\n // 快照后正序遍历:实例在自身渲染开始前注册,祖先必然先于后代入列——\n // 祖先先刷新会 dispose 上一轮渲染作用域,其树内旧后代实例的 refresh\n // 命中已销毁守卫被跳过,避免同一组件在一次热更新中重渲染两次。\n // 同时 refresh 重渲染以新代码创建的全新实例不在快照中,天然不会再刷新。\n const instances = [...module.instances]\n for (const instance of instances) {\n try {\n instance.refresh()\n } catch (error) {\n /*\n * 静默吞掉会让开发者以为热更新成功了,而屏幕上是旧的 —— 最容易被当成\n * 「改了没生效」查半天。刷新失败本身不冒泡(下一次正常渲染会再抛),\n * 但必须留下记录。\n */\n console.error(formatVobsError(error, { includeStack: true }))\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\n/**\n * 编译器为模块顶层 state() 声明生成的取值入口。键为 `${moduleId}#${声明名}`,\n * 与手动 store 键空间隔离。模块热更新重执行时复用既有信号实例:旧导入方持有的\n * 实例与新模块实例共享同一份状态,消除\"两份模块、两份状态\"导致的编辑不生效/页面半边失灵。\n */\nexport function hmrStateRef<T>(key: string, create: () => T): T {\n const states = hmrGlobal.states\n if (states.has(key)) return states.get(key) as T\n const value = create()\n states.set(key, value)\n return value\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n","/** Shared error protocol used by the runtime, compiler and DevTools. */\nexport type VobsErrorSeverity = 'error' | 'warning' | 'info'\nexport type VobsErrorLayer =\n | 'compiler'\n | 'runtime'\n | 'constraint'\n | 'permission'\n | 'ssr'\n | 'http'\n | 'resource'\n\nexport interface VobsErrorLocation {\n readonly file: string\n readonly line: number\n readonly column: number\n}\n\nexport interface VobsErrorOptions {\n readonly code: string\n readonly message: string\n readonly severity?: VobsErrorSeverity\n readonly layer?: VobsErrorLayer\n readonly cause?: unknown\n readonly fix?: string\n readonly location?: VobsErrorLocation\n readonly trace?: readonly string[]\n readonly example?: string\n readonly docs?: string\n readonly codeFrame?: string\n}\n\nexport interface VobsErrorDefaults {\n readonly code?: string\n readonly severity?: VobsErrorSeverity\n readonly layer?: VobsErrorLayer\n readonly fix?: string\n}\n\n/** A framework error with stable machine-readable metadata. */\nexport class VobsError extends Error {\n readonly code: string\n readonly severity: VobsErrorSeverity\n readonly layer: VobsErrorLayer\n readonly cause?: unknown\n readonly fix?: string\n readonly location?: VobsErrorLocation\n readonly trace?: readonly string[]\n readonly example?: string\n readonly docs?: string\n readonly codeFrame?: string\n\n constructor(options: VobsErrorOptions) {\n super(options.message)\n this.name = 'VobsError'\n this.code = options.code\n this.severity = options.severity ?? 'error'\n this.layer = options.layer ?? 'runtime'\n this.cause = options.cause\n this.fix = options.fix\n this.location = options.location\n this.trace = options.trace\n this.example = options.example\n this.docs = options.docs\n this.codeFrame = options.codeFrame\n }\n}\n\nexport function createVobsError(options: VobsErrorOptions): VobsError {\n return new VobsError(options)\n}\n\n/**\n * 结构化识别(不依赖 `instanceof`)。\n *\n * **不能要求 `layer` 也齐全** —— 原来要求 code + message + layer 三者都是字符串,\n * 于是调用方递一个 `{ code, message }` 就会被判为「不是 VobsError」,掉进最后的\n * `String(value)` 兜底,输出 `[object Object]`:诊断系统自己把诊断丢了。\n * layer 缺失在下面构造时会补上默认值,没有理由在识别阶段就否掉。\n */\nexport function isVobsError(value: unknown): value is VobsError {\n return value instanceof VobsError\n || Boolean(value && typeof value === 'object'\n && typeof (value as { code?: unknown }).code === 'string'\n && typeof (value as { message?: unknown }).message === 'string')\n}\n\n/**\n * 别的打包副本造的 VobsError。\n *\n * tsup `splitting: false` 让 error.ts 同时进 `dist/index.js` 与 `dist/error.js`,\n * 两份类互不 `instanceof`。字段齐全,只是身份不同 —— 识别出来复制成本地实例。\n */\nfunction isForeignVobsError(value: unknown): value is Error & VobsErrorOptions {\n return value instanceof Error\n && value.name === 'VobsError'\n && typeof (value as { code?: unknown }).code === 'string'\n}\n\n/** 兜底取消息:至少要能读出对象上的 message,别再输出 `[object Object]`。 */\nfunction describeUnknown(value: unknown): string {\n if (value === null || value === undefined) return String(value)\n if (typeof value === 'string') return value\n if (typeof value === 'object') {\n const message = (value as { message?: unknown }).message\n if (typeof message === 'string' && message !== '') return message\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n }\n return String(value)\n}\n\n/** 把任意来源的「类 VobsError」字段复制成本地实例。 */\nfunction adoptVobsError(\n value: VobsErrorOptions & { cause?: unknown },\n defaults: VobsErrorDefaults\n): VobsError {\n return new VobsError({\n code: value.code,\n message: value.message,\n severity: value.severity ?? defaults.severity,\n layer: value.layer ?? defaults.layer,\n cause: value.cause ?? (value instanceof Error ? value : undefined),\n fix: value.fix ?? defaults.fix,\n location: value.location,\n trace: value.trace,\n example: value.example,\n docs: value.docs,\n codeFrame: value.codeFrame\n })\n}\n\n/** Convert thrown strings and third-party errors without losing their message. */\nexport function normalizeVobsError(value: unknown, defaults: VobsErrorDefaults = {}): VobsError {\n // 本地实例:原样返回,保持同一性与已有 stack\n if (value instanceof VobsError) return value\n\n // 别的副本造的:复制成本地实例,下游 instanceof 才成立\n if (isForeignVobsError(value)) return adoptVobsError(value, defaults)\n\n if (value instanceof Error) {\n // Preserve the original Error identity so boundaries and DevTools can\n // correlate event/effect phases without creating duplicate diagnostics.\n const metadata = value as Error & {\n readonly vobsCode?: unknown\n readonly vobsHint?: unknown\n readonly vobsSource?: unknown\n }\n const code = defaults.code ?? (typeof metadata.vobsCode === 'string' ? metadata.vobsCode : undefined)\n if (code) {\n defineErrorMetadata(value, 'code', code)\n /*\n * 冻结 / 不可扩展的第三方 Error 上挂不上元数据。原来这里静默吞掉,\n * 于是 normalize 的结果 code 是 undefined(打印成 VOBS_UNKNOWN)。\n * 挂不上就复制成本地实例,别把 code 丢了。\n */\n if ((value as { code?: unknown }).code !== code) {\n return new VobsError({\n code,\n message: value.message,\n severity: defaults.severity ?? 'error',\n layer: defaults.layer ?? 'runtime',\n cause: value,\n fix: defaults.fix ?? (typeof metadata.vobsHint === 'string' ? metadata.vobsHint : undefined)\n })\n }\n }\n defineErrorMetadata(value, 'severity', defaults.severity ?? 'error')\n defineErrorMetadata(value, 'layer', defaults.layer ?? 'runtime')\n const fix = defaults.fix ?? (typeof metadata.vobsHint === 'string' ? metadata.vobsHint : undefined)\n if (fix) defineErrorMetadata(value, 'fix', fix)\n const source = metadata.vobsSource\n if (source && typeof source === 'object'\n && typeof (source as { file?: unknown }).file === 'string'\n && typeof (source as { line?: unknown }).line === 'number'\n && typeof (source as { column?: unknown }).column === 'number') {\n defineErrorMetadata(value, 'location', source)\n }\n return value as VobsError\n }\n\n // 结构化对象(可能缺 layer,甚至缺 severity):补齐后构造成本地 VobsError\n if (isVobsError(value)) return adoptVobsError(value as VobsErrorOptions, defaults)\n\n return new VobsError({\n code: defaults.code ?? 'VOBS_UNKNOWN',\n message: describeUnknown(value),\n severity: defaults.severity ?? 'error',\n layer: defaults.layer ?? 'runtime',\n cause: undefined,\n fix: defaults.fix\n })\n}\n\nfunction defineErrorMetadata(target: Error, key: string, value: unknown): void {\n if (key in target) return\n try {\n Object.defineProperty(target, key, { configurable: true, enumerable: false, value, writable: true })\n } catch {\n // 冻结 / 不可扩展的第三方 Error:元数据挂不上。调用方会用「写完再读回」判断\n // 是否成功,失败时改成复制成本地实例,而不是静默丢掉 code。\n }\n}\n\nexport interface FormatVobsErrorOptions {\n readonly environment?: 'development' | 'production'\n readonly includeStack?: boolean\n}\n\n/** Format a concise, actionable message for terminals and dev overlays. */\nexport function formatVobsError(\n value: unknown,\n options: FormatVobsErrorOptions = {}\n): string {\n const error = normalizeVobsError(value)\n const code = error.code || 'VOBS_UNKNOWN'\n const severity = error.severity || 'error'\n if (options.environment === 'production') return `[Vobs ${code}] ${error.message}`\n\n const lines = [`[Vobs ${capitalize(severity)}] ${error.message}`, `Code: ${code}`]\n if (error.location) lines.push(`Location: ${error.location.file}:${error.location.line}:${error.location.column}`)\n if (error.codeFrame) lines.push('', error.codeFrame)\n if (error.cause !== undefined) lines.push(`Cause: ${formatCause(error.cause)}`)\n if (error.trace?.length) lines.push('', `Trace: ${error.trace.join(' → ')}`)\n if (error.fix) lines.push('', `Fix: ${error.fix}`)\n if (error.example) lines.push('', `Example:\\n${error.example}`)\n if (error.docs) lines.push(`Docs: ${error.docs}`)\n if (options.includeStack && error.stack) lines.push('', error.stack)\n return lines.join('\\n')\n}\n\nfunction formatCause(value: unknown): string {\n return value instanceof Error ? `${value.name}: ${value.message}` : String(value)\n}\n\nfunction capitalize(value: string): string {\n return value.slice(0, 1).toUpperCase() + value.slice(1)\n}\n"],"mappings":"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","names":["module"]}
package/dist/hmr.js CHANGED
@@ -1,6 +1,139 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
+ // packages/runtime/src/error.ts
5
+ var _VobsError = class _VobsError extends Error {
6
+ constructor(options) {
7
+ super(options.message);
8
+ this.name = "VobsError";
9
+ this.code = options.code;
10
+ this.severity = options.severity ?? "error";
11
+ this.layer = options.layer ?? "runtime";
12
+ this.cause = options.cause;
13
+ this.fix = options.fix;
14
+ this.location = options.location;
15
+ this.trace = options.trace;
16
+ this.example = options.example;
17
+ this.docs = options.docs;
18
+ this.codeFrame = options.codeFrame;
19
+ }
20
+ };
21
+ __name(_VobsError, "VobsError");
22
+ var VobsError = _VobsError;
23
+ function isVobsError(value) {
24
+ return value instanceof VobsError || Boolean(value && typeof value === "object" && typeof value.code === "string" && typeof value.message === "string");
25
+ }
26
+ __name(isVobsError, "isVobsError");
27
+ function isForeignVobsError(value) {
28
+ return value instanceof Error && value.name === "VobsError" && typeof value.code === "string";
29
+ }
30
+ __name(isForeignVobsError, "isForeignVobsError");
31
+ function describeUnknown(value) {
32
+ if (value === null || value === void 0) return String(value);
33
+ if (typeof value === "string") return value;
34
+ if (typeof value === "object") {
35
+ const message = value.message;
36
+ if (typeof message === "string" && message !== "") return message;
37
+ try {
38
+ return JSON.stringify(value) ?? String(value);
39
+ } catch {
40
+ return String(value);
41
+ }
42
+ }
43
+ return String(value);
44
+ }
45
+ __name(describeUnknown, "describeUnknown");
46
+ function adoptVobsError(value, defaults) {
47
+ return new VobsError({
48
+ code: value.code,
49
+ message: value.message,
50
+ severity: value.severity ?? defaults.severity,
51
+ layer: value.layer ?? defaults.layer,
52
+ cause: value.cause ?? (value instanceof Error ? value : void 0),
53
+ fix: value.fix ?? defaults.fix,
54
+ location: value.location,
55
+ trace: value.trace,
56
+ example: value.example,
57
+ docs: value.docs,
58
+ codeFrame: value.codeFrame
59
+ });
60
+ }
61
+ __name(adoptVobsError, "adoptVobsError");
62
+ function normalizeVobsError(value, defaults = {}) {
63
+ if (value instanceof VobsError) return value;
64
+ if (isForeignVobsError(value)) return adoptVobsError(value, defaults);
65
+ if (value instanceof Error) {
66
+ const metadata = value;
67
+ const code = defaults.code ?? (typeof metadata.vobsCode === "string" ? metadata.vobsCode : void 0);
68
+ if (code) {
69
+ defineErrorMetadata(value, "code", code);
70
+ if (value.code !== code) {
71
+ return new VobsError({
72
+ code,
73
+ message: value.message,
74
+ severity: defaults.severity ?? "error",
75
+ layer: defaults.layer ?? "runtime",
76
+ cause: value,
77
+ fix: defaults.fix ?? (typeof metadata.vobsHint === "string" ? metadata.vobsHint : void 0)
78
+ });
79
+ }
80
+ }
81
+ defineErrorMetadata(value, "severity", defaults.severity ?? "error");
82
+ defineErrorMetadata(value, "layer", defaults.layer ?? "runtime");
83
+ const fix = defaults.fix ?? (typeof metadata.vobsHint === "string" ? metadata.vobsHint : void 0);
84
+ if (fix) defineErrorMetadata(value, "fix", fix);
85
+ const source = metadata.vobsSource;
86
+ if (source && typeof source === "object" && typeof source.file === "string" && typeof source.line === "number" && typeof source.column === "number") {
87
+ defineErrorMetadata(value, "location", source);
88
+ }
89
+ return value;
90
+ }
91
+ if (isVobsError(value)) return adoptVobsError(value, defaults);
92
+ return new VobsError({
93
+ code: defaults.code ?? "VOBS_UNKNOWN",
94
+ message: describeUnknown(value),
95
+ severity: defaults.severity ?? "error",
96
+ layer: defaults.layer ?? "runtime",
97
+ cause: void 0,
98
+ fix: defaults.fix
99
+ });
100
+ }
101
+ __name(normalizeVobsError, "normalizeVobsError");
102
+ function defineErrorMetadata(target, key, value) {
103
+ if (key in target) return;
104
+ try {
105
+ Object.defineProperty(target, key, { configurable: true, enumerable: false, value, writable: true });
106
+ } catch {
107
+ }
108
+ }
109
+ __name(defineErrorMetadata, "defineErrorMetadata");
110
+ function formatVobsError(value, options = {}) {
111
+ const error = normalizeVobsError(value);
112
+ const code = error.code || "VOBS_UNKNOWN";
113
+ const severity = error.severity || "error";
114
+ if (options.environment === "production") return `[Vobs ${code}] ${error.message}`;
115
+ const lines = [`[Vobs ${capitalize(severity)}] ${error.message}`, `Code: ${code}`];
116
+ if (error.location) lines.push(`Location: ${error.location.file}:${error.location.line}:${error.location.column}`);
117
+ if (error.codeFrame) lines.push("", error.codeFrame);
118
+ if (error.cause !== void 0) lines.push(`Cause: ${formatCause(error.cause)}`);
119
+ if (error.trace?.length) lines.push("", `Trace: ${error.trace.join(" \u2192 ")}`);
120
+ if (error.fix) lines.push("", `Fix: ${error.fix}`);
121
+ if (error.example) lines.push("", `Example:
122
+ ${error.example}`);
123
+ if (error.docs) lines.push(`Docs: ${error.docs}`);
124
+ if (options.includeStack && error.stack) lines.push("", error.stack);
125
+ return lines.join("\n");
126
+ }
127
+ __name(formatVobsError, "formatVobsError");
128
+ function formatCause(value) {
129
+ return value instanceof Error ? `${value.name}: ${value.message}` : String(value);
130
+ }
131
+ __name(formatCause, "formatCause");
132
+ function capitalize(value) {
133
+ return value.slice(0, 1).toUpperCase() + value.slice(1);
134
+ }
135
+ __name(capitalize, "capitalize");
136
+
4
137
  // packages/runtime/src/hmr.ts
5
138
  var globalTarget = globalThis;
6
139
  var hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: /* @__PURE__ */ new Map(), states: /* @__PURE__ */ new Map() };
@@ -39,7 +172,8 @@ function updateHmrModule(moduleId, nextModule) {
39
172
  for (const instance of instances) {
40
173
  try {
41
174
  instance.refresh();
42
- } catch {
175
+ } catch (error) {
176
+ console.error(formatVobsError(error, { includeStack: true }));
43
177
  }
44
178
  }
45
179
  }
package/dist/hmr.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hmr.ts"],"sourcesContent":["import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n /** 编译器生成的 hmrStateRef 注册表:键为 `${moduleId}#${声明名}`,值跨模块重执行保活。 */\n states: Map<string, unknown>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>(), states: new Map<string, unknown>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(moduleId: string, nextModule: Record<string, unknown>): void {\n const module = hmrGlobal.modules.get(moduleId)\n if (!module) return\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) return\n // 快照后正序遍历:实例在自身渲染开始前注册,祖先必然先于后代入列——\n // 祖先先刷新会 dispose 上一轮渲染作用域,其树内旧后代实例的 refresh\n // 命中已销毁守卫被跳过,避免同一组件在一次热更新中重渲染两次。\n // 同时 refresh 重渲染以新代码创建的全新实例不在快照中,天然不会再刷新。\n const instances = [...module.instances]\n for (const instance of instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\n/**\n * 编译器为模块顶层 state() 声明生成的取值入口。键为 `${moduleId}#${声明名}`,\n * 与手动 store 键空间隔离。模块热更新重执行时复用既有信号实例:旧导入方持有的\n * 实例与新模块实例共享同一份状态,消除\"两份模块、两份状态\"导致的编辑不生效/页面半边失灵。\n */\nexport function hmrStateRef<T>(key: string, create: () => T): T {\n const states = hmrGlobal.states\n if (states.has(key)) return states.get(key) as T\n const value = create()\n states.set(key, value)\n return value\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/error.ts","../src/hmr.ts"],"sourcesContent":["/** Shared error protocol used by the runtime, compiler and DevTools. */\nexport type VobsErrorSeverity = 'error' | 'warning' | 'info'\nexport type VobsErrorLayer =\n | 'compiler'\n | 'runtime'\n | 'constraint'\n | 'permission'\n | 'ssr'\n | 'http'\n | 'resource'\n\nexport interface VobsErrorLocation {\n readonly file: string\n readonly line: number\n readonly column: number\n}\n\nexport interface VobsErrorOptions {\n readonly code: string\n readonly message: string\n readonly severity?: VobsErrorSeverity\n readonly layer?: VobsErrorLayer\n readonly cause?: unknown\n readonly fix?: string\n readonly location?: VobsErrorLocation\n readonly trace?: readonly string[]\n readonly example?: string\n readonly docs?: string\n readonly codeFrame?: string\n}\n\nexport interface VobsErrorDefaults {\n readonly code?: string\n readonly severity?: VobsErrorSeverity\n readonly layer?: VobsErrorLayer\n readonly fix?: string\n}\n\n/** A framework error with stable machine-readable metadata. */\nexport class VobsError extends Error {\n readonly code: string\n readonly severity: VobsErrorSeverity\n readonly layer: VobsErrorLayer\n readonly cause?: unknown\n readonly fix?: string\n readonly location?: VobsErrorLocation\n readonly trace?: readonly string[]\n readonly example?: string\n readonly docs?: string\n readonly codeFrame?: string\n\n constructor(options: VobsErrorOptions) {\n super(options.message)\n this.name = 'VobsError'\n this.code = options.code\n this.severity = options.severity ?? 'error'\n this.layer = options.layer ?? 'runtime'\n this.cause = options.cause\n this.fix = options.fix\n this.location = options.location\n this.trace = options.trace\n this.example = options.example\n this.docs = options.docs\n this.codeFrame = options.codeFrame\n }\n}\n\nexport function createVobsError(options: VobsErrorOptions): VobsError {\n return new VobsError(options)\n}\n\n/**\n * 结构化识别(不依赖 `instanceof`)。\n *\n * **不能要求 `layer` 也齐全** —— 原来要求 code + message + layer 三者都是字符串,\n * 于是调用方递一个 `{ code, message }` 就会被判为「不是 VobsError」,掉进最后的\n * `String(value)` 兜底,输出 `[object Object]`:诊断系统自己把诊断丢了。\n * layer 缺失在下面构造时会补上默认值,没有理由在识别阶段就否掉。\n */\nexport function isVobsError(value: unknown): value is VobsError {\n return value instanceof VobsError\n || Boolean(value && typeof value === 'object'\n && typeof (value as { code?: unknown }).code === 'string'\n && typeof (value as { message?: unknown }).message === 'string')\n}\n\n/**\n * 别的打包副本造的 VobsError。\n *\n * tsup `splitting: false` 让 error.ts 同时进 `dist/index.js` 与 `dist/error.js`,\n * 两份类互不 `instanceof`。字段齐全,只是身份不同 —— 识别出来复制成本地实例。\n */\nfunction isForeignVobsError(value: unknown): value is Error & VobsErrorOptions {\n return value instanceof Error\n && value.name === 'VobsError'\n && typeof (value as { code?: unknown }).code === 'string'\n}\n\n/** 兜底取消息:至少要能读出对象上的 message,别再输出 `[object Object]`。 */\nfunction describeUnknown(value: unknown): string {\n if (value === null || value === undefined) return String(value)\n if (typeof value === 'string') return value\n if (typeof value === 'object') {\n const message = (value as { message?: unknown }).message\n if (typeof message === 'string' && message !== '') return message\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n }\n return String(value)\n}\n\n/** 把任意来源的「类 VobsError」字段复制成本地实例。 */\nfunction adoptVobsError(\n value: VobsErrorOptions & { cause?: unknown },\n defaults: VobsErrorDefaults\n): VobsError {\n return new VobsError({\n code: value.code,\n message: value.message,\n severity: value.severity ?? defaults.severity,\n layer: value.layer ?? defaults.layer,\n cause: value.cause ?? (value instanceof Error ? value : undefined),\n fix: value.fix ?? defaults.fix,\n location: value.location,\n trace: value.trace,\n example: value.example,\n docs: value.docs,\n codeFrame: value.codeFrame\n })\n}\n\n/** Convert thrown strings and third-party errors without losing their message. */\nexport function normalizeVobsError(value: unknown, defaults: VobsErrorDefaults = {}): VobsError {\n // 本地实例:原样返回,保持同一性与已有 stack\n if (value instanceof VobsError) return value\n\n // 别的副本造的:复制成本地实例,下游 instanceof 才成立\n if (isForeignVobsError(value)) return adoptVobsError(value, defaults)\n\n if (value instanceof Error) {\n // Preserve the original Error identity so boundaries and DevTools can\n // correlate event/effect phases without creating duplicate diagnostics.\n const metadata = value as Error & {\n readonly vobsCode?: unknown\n readonly vobsHint?: unknown\n readonly vobsSource?: unknown\n }\n const code = defaults.code ?? (typeof metadata.vobsCode === 'string' ? metadata.vobsCode : undefined)\n if (code) {\n defineErrorMetadata(value, 'code', code)\n /*\n * 冻结 / 不可扩展的第三方 Error 上挂不上元数据。原来这里静默吞掉,\n * 于是 normalize 的结果 code 是 undefined(打印成 VOBS_UNKNOWN)。\n * 挂不上就复制成本地实例,别把 code 丢了。\n */\n if ((value as { code?: unknown }).code !== code) {\n return new VobsError({\n code,\n message: value.message,\n severity: defaults.severity ?? 'error',\n layer: defaults.layer ?? 'runtime',\n cause: value,\n fix: defaults.fix ?? (typeof metadata.vobsHint === 'string' ? metadata.vobsHint : undefined)\n })\n }\n }\n defineErrorMetadata(value, 'severity', defaults.severity ?? 'error')\n defineErrorMetadata(value, 'layer', defaults.layer ?? 'runtime')\n const fix = defaults.fix ?? (typeof metadata.vobsHint === 'string' ? metadata.vobsHint : undefined)\n if (fix) defineErrorMetadata(value, 'fix', fix)\n const source = metadata.vobsSource\n if (source && typeof source === 'object'\n && typeof (source as { file?: unknown }).file === 'string'\n && typeof (source as { line?: unknown }).line === 'number'\n && typeof (source as { column?: unknown }).column === 'number') {\n defineErrorMetadata(value, 'location', source)\n }\n return value as VobsError\n }\n\n // 结构化对象(可能缺 layer,甚至缺 severity):补齐后构造成本地 VobsError\n if (isVobsError(value)) return adoptVobsError(value as VobsErrorOptions, defaults)\n\n return new VobsError({\n code: defaults.code ?? 'VOBS_UNKNOWN',\n message: describeUnknown(value),\n severity: defaults.severity ?? 'error',\n layer: defaults.layer ?? 'runtime',\n cause: undefined,\n fix: defaults.fix\n })\n}\n\nfunction defineErrorMetadata(target: Error, key: string, value: unknown): void {\n if (key in target) return\n try {\n Object.defineProperty(target, key, { configurable: true, enumerable: false, value, writable: true })\n } catch {\n // 冻结 / 不可扩展的第三方 Error:元数据挂不上。调用方会用「写完再读回」判断\n // 是否成功,失败时改成复制成本地实例,而不是静默丢掉 code。\n }\n}\n\nexport interface FormatVobsErrorOptions {\n readonly environment?: 'development' | 'production'\n readonly includeStack?: boolean\n}\n\n/** Format a concise, actionable message for terminals and dev overlays. */\nexport function formatVobsError(\n value: unknown,\n options: FormatVobsErrorOptions = {}\n): string {\n const error = normalizeVobsError(value)\n const code = error.code || 'VOBS_UNKNOWN'\n const severity = error.severity || 'error'\n if (options.environment === 'production') return `[Vobs ${code}] ${error.message}`\n\n const lines = [`[Vobs ${capitalize(severity)}] ${error.message}`, `Code: ${code}`]\n if (error.location) lines.push(`Location: ${error.location.file}:${error.location.line}:${error.location.column}`)\n if (error.codeFrame) lines.push('', error.codeFrame)\n if (error.cause !== undefined) lines.push(`Cause: ${formatCause(error.cause)}`)\n if (error.trace?.length) lines.push('', `Trace: ${error.trace.join(' → ')}`)\n if (error.fix) lines.push('', `Fix: ${error.fix}`)\n if (error.example) lines.push('', `Example:\\n${error.example}`)\n if (error.docs) lines.push(`Docs: ${error.docs}`)\n if (options.includeStack && error.stack) lines.push('', error.stack)\n return lines.join('\\n')\n}\n\nfunction formatCause(value: unknown): string {\n return value instanceof Error ? `${value.name}: ${value.message}` : String(value)\n}\n\nfunction capitalize(value: string): string {\n return value.slice(0, 1).toUpperCase() + value.slice(1)\n}\n","import type { VobsNode } from './fragment'\nimport { formatVobsError } from './error'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n /** 编译器生成的 hmrStateRef 注册表:键为 `${moduleId}#${声明名}`,值跨模块重执行保活。 */\n states: Map<string, unknown>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>(), states: new Map<string, unknown>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(moduleId: string, nextModule: Record<string, unknown>): void {\n const module = hmrGlobal.modules.get(moduleId)\n if (!module) return\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) return\n // 快照后正序遍历:实例在自身渲染开始前注册,祖先必然先于后代入列——\n // 祖先先刷新会 dispose 上一轮渲染作用域,其树内旧后代实例的 refresh\n // 命中已销毁守卫被跳过,避免同一组件在一次热更新中重渲染两次。\n // 同时 refresh 重渲染以新代码创建的全新实例不在快照中,天然不会再刷新。\n const instances = [...module.instances]\n for (const instance of instances) {\n try {\n instance.refresh()\n } catch (error) {\n /*\n * 静默吞掉会让开发者以为热更新成功了,而屏幕上是旧的 —— 最容易被当成\n * 「改了没生效」查半天。刷新失败本身不冒泡(下一次正常渲染会再抛),\n * 但必须留下记录。\n */\n console.error(formatVobsError(error, { includeStack: true }))\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\n/**\n * 编译器为模块顶层 state() 声明生成的取值入口。键为 `${moduleId}#${声明名}`,\n * 与手动 store 键空间隔离。模块热更新重执行时复用既有信号实例:旧导入方持有的\n * 实例与新模块实例共享同一份状态,消除\"两份模块、两份状态\"导致的编辑不生效/页面半边失灵。\n */\nexport function hmrStateRef<T>(key: string, create: () => T): T {\n const states = hmrGlobal.states\n if (states.has(key)) return states.get(key) as T\n const value = create()\n states.set(key, value)\n return value\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n"],"mappings":"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","names":[]}