transone 0.4.0 → 0.9.0

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 (39) hide show
  1. package/README.md +15 -0
  2. package/README.zh-CN.md +16 -0
  3. package/dist/core/app.d.ts +6 -4
  4. package/dist/core/cleanup.d.ts +7 -0
  5. package/dist/core/component/base-component.d.ts +5 -0
  6. package/dist/core/component/base.d.ts +19 -0
  7. package/dist/core/component/index.d.ts +3 -2
  8. package/dist/core/index.d.ts +1 -0
  9. package/dist/core/vnode.d.ts +4 -4
  10. package/dist/index-8qh91wft.js +12 -0
  11. package/dist/index-8qh91wft.js.map +27 -0
  12. package/dist/index-dse0chhf.js +5 -0
  13. package/dist/index-dse0chhf.js.map +10 -0
  14. package/dist/index-fxpn7qkh.js +4 -0
  15. package/dist/index-fxpn7qkh.js.map +11 -0
  16. package/dist/{index-qmpx307q.js → index-ryj080w6.js} +3 -3
  17. package/dist/{index-qmpx307q.js.map → index-ryj080w6.js.map} +1 -1
  18. package/dist/index-sg4er0f8.js +5 -0
  19. package/dist/{index-xp7y2crt.js.map → index-sg4er0f8.js.map} +5 -5
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.js +2 -2
  22. package/dist/index.js.map +3 -3
  23. package/dist/platform/bindings.d.ts +3 -0
  24. package/dist/platform/decorators.d.ts +15 -0
  25. package/dist/platform/definitions.d.ts +32 -0
  26. package/dist/platform/index.d.ts +3 -0
  27. package/dist/platform/index.js +4 -0
  28. package/dist/platform/index.js.map +9 -0
  29. package/dist/request/index.js +2 -2
  30. package/dist/request/index.js.map +1 -1
  31. package/dist/router/index.d.ts +2 -2
  32. package/dist/router/index.js +2 -2
  33. package/dist/router/index.js.map +1 -1
  34. package/dist/style/index.js +2 -2
  35. package/dist/style/index.js.map +1 -1
  36. package/package.json +5 -1
  37. package/dist/index-rmgr0qs2.js +0 -12
  38. package/dist/index-rmgr0qs2.js.map +0 -25
  39. package/dist/index-xp7y2crt.js +0 -5
package/README.md CHANGED
@@ -75,6 +75,14 @@ transone build --target mp-alipay # Alipay mini-program project (AXML/ACSS)
75
75
  transone build --target mp-bytedance # ByteDance mini-program project (TTML/TTSS)
76
76
  ```
77
77
 
78
+ ## Platform component implementations
79
+
80
+ From framework 0.5.0 and CLI 0.8.0, a business component can extend `BaseComponent<Props, State>` and share its state/methods with platform subclasses. Decorate an exported subclass with `@WebMobile()`, `@WebPc()`, `@MiniprogramWeixin()` or `@AppIos()`; the framework's `Platform` enum supplies the matching values such as `web-mobile` and `app-ios`.
81
+
82
+ Pages keep referencing the business base through `createComponent({ component: CardComponent })`. Run `transone dev --target web-mobile` or `transone build --target app-ios` to select the implementation. Exact matches take priority, followed by the matching family implementation (`@Web()`, `@Miniprogram()` or `@App()`) and then a concrete base; ambiguous implementations and missing implementations for consumed abstract bases fail with diagnostics. Existing `Component` users and legacy target names remain supported. Generic mini-program and App markers select component implementations; builds still require concrete targets.
83
+
84
+ `transone create` generates a runnable shared Card example. See the [component implementation guide](../../docs/platform-components.md) for all platforms, discovery configuration, inheritance, explicit references and the native compiler's static subset.
85
+
78
86
  ## Reactivity
79
87
 
80
88
  ```ts
@@ -227,6 +235,7 @@ Errors are normalized to `RequestError` (`code` / `config` / `response` / `cause
227
235
  | `transone/request` | `createRequest`, `request`, `Request`, `InterceptorManager`, `RequestError`, `detectPlatform` |
228
236
  | `transone/style` | `StyleManager`, style sheets and units |
229
237
  | `transone/dom` | DOM abstractions: `createDomWindow`, `installDomGlobals`, `parseHtmlFragment` |
238
+ | `transone/platform` | `Platform`, platform definitions and class decorators |
230
239
 
231
240
  ## Relationship with TSone
232
241
 
@@ -246,3 +255,9 @@ bun run lint
246
255
  ## License
247
256
 
248
257
  MIT
258
+
259
+ ## Resource cleanup
260
+
261
+ Web runtime components can register owned resources with `this.onDispose(cleanup)`, in registration order, and unregister using its return value. Teardown continues after throwing hooks, children or disposers; repeated unmounts do not repeat cleanup. Single errors retain their identity; multiple errors retain their `errors` collection.
262
+ Request completion releases external abort listeners and timers, including Mini Program hosts whose abort does not invoke a callback.
263
+ See the [cleanup guide and static compilation boundaries](../../docs/reliability.md).
package/README.zh-CN.md CHANGED
@@ -13,7 +13,23 @@ TransOne 核心框架包:一份 TypeScript 源码,跨端框架的核心运
13
13
  与 TSone 同源:核心公开 API 复用 TSone,Web 产物可直接复用 TSone 渲染策略。
14
14
  编译器见 [transone-cli](../transone-cli)。
15
15
 
16
+ 框架 0.5.0 / CLI 0.8.0 支持业务组件与端实现:`CardComponent extends BaseComponent`
17
+ 共享业务状态与方法,`@WebMobile()`、`@WebPc()`、`@MiniprogramWeixin()`、`@AppIos()`
18
+ 标注子类。框架导出的 `Platform.WebMobile` 值为 `web-mobile`;
19
+ 页面只引用 CardComponent,由 `dev/build --target web-mobile` 自动选择实现。
20
+ 已有直接继承 Component 的用法继续有效。
21
+
22
+ 默认精确端优先,再回退到所属平台族的通用实现(`@Web()` / `@Miniprogram()` / `@App()`),最后回退到可实例化业务基类;冲突或抽象基类缺少实现时报错。通用小程序与 App 装饰器仅用于组件选择,构建仍需指定具体端。
23
+ `transone create` 自带各端 Card 示例。完整 API、扫描配置和原生静态子集见
24
+ [业务组件与端实现](../../docs/platform-components.md)。
25
+
16
26
  ```bash
17
27
  bun test # 测试
18
28
  bun run build # 构建 dist(ESM + .d.ts)
19
29
  ```
30
+
31
+ ## 资源清理
32
+
33
+ Web 组件可通过 `this.onDispose(cleanup)` 按注册顺序登记资源释放,返回的函数可撤销登记。卸载期间即使钩子、子组件或某个清理函数抛错,也会继续处理其余资源;重复卸载不会重复执行清理。单个异常保留原对象,多个异常汇总并保留 `errors`。
34
+ 请求结束后自动释放外部取消监听与定时器;小程序宿主取消不回调时仍能正常结算。
35
+ 使用示例和静态编译边界见[诊断与清理](../../docs/reliability.md)。
@@ -1,4 +1,4 @@
1
- import { ComponentConstructor, ComponentProps, InjectionKey, InjectionResult } from './component';
1
+ import { ComponentReference, ComponentProps, InjectionKey, InjectionResult } from './component';
2
2
  import { type HtmlDocumentBody, type HtmlDocumentOptions } from './document';
3
3
  import type { Router } from '../router';
4
4
  export interface Plugin {
@@ -13,7 +13,7 @@ export type AppDocumentOptions = Partial<Omit<HtmlDocumentOptions, 'body'>> & {
13
13
  export type AppDocumentRenderOptions = AppDocumentOptions;
14
14
  export interface AppOptions<TState = Record<string, unknown>, TConfig = Record<string, unknown>, TRootProps extends ComponentProps = ComponentProps> {
15
15
  /** 根组件构造函数 */
16
- root?: ComponentConstructor<TRootProps>;
16
+ root?: ComponentReference<TRootProps>;
17
17
  /** 根组件 props */
18
18
  rootProps?: TRootProps;
19
19
  /** 应用挂载点,默认 #app */
@@ -36,6 +36,7 @@ export declare class OneApp<TState extends object = Record<string, unknown>, TCo
36
36
  private container;
37
37
  private rootInstance;
38
38
  private mounted;
39
+ private unmounting;
39
40
  private templateEngine;
40
41
  private readonly appContext;
41
42
  private readonly providers;
@@ -60,6 +61,8 @@ export declare class OneApp<TState extends object = Record<string, unknown>, TCo
60
61
  * 卸载应用
61
62
  */
62
63
  unmount(): void;
64
+ private teardown;
65
+ private releaseResources;
63
66
  /**
64
67
  * 应用是否正在运行
65
68
  */
@@ -67,7 +70,7 @@ export declare class OneApp<TState extends object = Record<string, unknown>, TCo
67
70
  /**
68
71
  * 更新根组件
69
72
  */
70
- updateRootComponent(component: ComponentConstructor<TRootProps>): void;
73
+ updateRootComponent(component: ComponentReference<TRootProps>): void;
71
74
  /**
72
75
  * 更新应用状态
73
76
  */
@@ -106,7 +109,6 @@ export declare class OneApp<TState extends object = Record<string, unknown>, TCo
106
109
  private mergeDocumentScripts;
107
110
  private onMounted;
108
111
  private onUpdated;
109
- private onBeforeUnmount;
110
112
  }
111
113
  /**
112
114
  * 创建应用实例
@@ -0,0 +1,7 @@
1
+ /** Collect independent teardown failures without skipping later resource releases. */
2
+ export declare class CleanupErrors {
3
+ private readonly errors;
4
+ attempt(cleanup: () => void): void;
5
+ add(error: unknown): void;
6
+ throwIfAny(message: string): void;
7
+ }
@@ -0,0 +1,5 @@
1
+ import { Component } from './base';
2
+ import type { ComponentProps, ComponentState } from './base';
3
+ /** Shared business component contract, with rendering supplied by target implementations. */
4
+ export declare abstract class BaseComponent<P extends ComponentProps = ComponentProps, S extends ComponentState = ComponentState> extends Component<P, S> {
5
+ }
@@ -12,6 +12,9 @@ export interface InjectionResult<T> {
12
12
  value: T | undefined;
13
13
  }
14
14
  export type ComponentConstructor<TProps extends ComponentProps = ComponentProps, TState extends ComponentState = ComponentState> = new (props?: TProps) => Component<TProps, TState>;
15
+ /** A logical component reference may be abstract and resolved by the application bundle. */
16
+ export type ComponentReference<TProps extends ComponentProps = ComponentProps, TState extends ComponentState = ComponentState> = abstract new (props?: TProps) => Component<TProps, TState>;
17
+ export type AnyComponentReference = abstract new (props?: never) => Component<ComponentProps, ComponentState>;
15
18
  export type AnyComponentConstructor = new (props?: never) => Component<ComponentProps, ComponentState>;
16
19
  export declare abstract class Component<TProps extends ComponentProps = ComponentProps, TState extends ComponentState = ComponentState> implements ComponentInstance {
17
20
  protected props: TProps;
@@ -24,6 +27,9 @@ export declare abstract class Component<TProps extends ComponentProps = Componen
24
27
  private readonly providers;
25
28
  private readonly updateEffect;
26
29
  private appContext;
30
+ private disposed;
31
+ private unmounting;
32
+ private readonly disposers;
27
33
  private parentComponent;
28
34
  private elementChangeListener;
29
35
  protected styleManager: StyleManager;
@@ -36,7 +42,20 @@ export declare abstract class Component<TProps extends ComponentProps = Componen
36
42
  mount(container: HTMLElement): void;
37
43
  mountToNode(): Node;
38
44
  update(): void;
45
+ /**
46
+ * Teardown order: beforeUnmount, descendants, FIFO disposers, framework
47
+ * bindings/styles/effect, DOM and references, then onUnmounted. Every stage
48
+ * runs even after failures; repeated/reentrant calls do nothing.
49
+ */
39
50
  unmount(): void;
51
+ /**
52
+ * Register instance-owned resources (timers, subscriptions, cancellation).
53
+ * Callbacks run once, in registration order, after descendants. The returned
54
+ * function unregisters without running the callback. Registrations during or
55
+ * after teardown run immediately; a later mount starts a fresh resource scope.
56
+ * An immediate callback's error is thrown to its caller.
57
+ */
58
+ protected onDispose(cleanup: () => void): () => void;
40
59
  setProps(props: Partial<TProps>): void;
41
60
  setState(state: Partial<TState>): void;
42
61
  setAppContext(context: unknown): void;
@@ -1,4 +1,5 @@
1
1
  import { Component } from './base';
2
- import type { AnyComponentConstructor, ComponentConstructor, ComponentEventListener, InjectionKey, InjectionResult, ComponentProps, ComponentState } from './base';
2
+ import type { AnyComponentConstructor, AnyComponentReference, ComponentReference, ComponentConstructor, ComponentEventListener, InjectionKey, InjectionResult, ComponentProps, ComponentState } from './base';
3
3
  export { Component };
4
- export type { AnyComponentConstructor, ComponentConstructor, ComponentEventListener, InjectionKey, InjectionResult, ComponentProps, ComponentState, };
4
+ export type { AnyComponentConstructor, AnyComponentReference, ComponentReference, ComponentConstructor, ComponentEventListener, InjectionKey, InjectionResult, ComponentProps, ComponentState, };
5
+ export { BaseComponent } from './base-component';
@@ -7,3 +7,4 @@ export * from './renderer';
7
7
  export * from './document';
8
8
  export * from './model';
9
9
  export * from './form';
10
+ export { createComponentInstance } from '../platform/bindings';
@@ -1,4 +1,4 @@
1
- import type { AnyComponentConstructor, ComponentConstructor, ComponentEventListener, ComponentProps } from './component';
1
+ import type { AnyComponentReference, ComponentReference, ComponentEventListener, ComponentProps } from './component';
2
2
  import type { ModelBinding } from './model';
3
3
  export interface ComponentType {
4
4
  mount(container: HTMLElement): void;
@@ -6,7 +6,7 @@ export interface ComponentType {
6
6
  on(eventName: string, listener: ComponentEventListener): () => void;
7
7
  }
8
8
  type VNodeComponentProps = ComponentProps;
9
- export type VNodeComponentConstructor<P extends VNodeComponentProps = VNodeComponentProps> = ComponentConstructor<P> | AnyComponentConstructor;
9
+ export type VNodeComponentConstructor<P extends VNodeComponentProps = VNodeComponentProps> = ComponentReference<P> | AnyComponentReference;
10
10
  export type HTMLPropValue = string | number | boolean | null | undefined | Record<string, string | number> | EventListener;
11
11
  export type Children = VNode | string | Array<VNode | string>;
12
12
  /** 归一化 children 为数组(运行时渲染使用;h() 允许直接传单个节点或数组)。 */
@@ -102,7 +102,7 @@ export declare const Tr: ElementShortcut;
102
102
  export declare const Th: ElementShortcut;
103
103
  export declare const Td: ElementShortcut;
104
104
  export interface ComponentDescriptor<P extends VNodeComponentProps> {
105
- component: ComponentConstructor<P>;
105
+ component: ComponentReference<P>;
106
106
  props?: P;
107
107
  children?: Children;
108
108
  key?: string | number;
@@ -110,7 +110,7 @@ export interface ComponentDescriptor<P extends VNodeComponentProps> {
110
110
  emitters?: Record<string, ComponentEventListener>;
111
111
  }
112
112
  export declare function createComponent<P extends VNodeComponentProps>(options: ComponentDescriptor<P>): ComponentNode<P>;
113
- export declare function createComponent<P extends VNodeComponentProps>(componentClass: ComponentConstructor<P>, props?: P, children?: Children, key?: string | number, directions?: Directions): ComponentNode<P>;
113
+ export declare function createComponent<P extends VNodeComponentProps>(componentClass: ComponentReference<P>, props?: P, children?: Children, key?: string | number, directions?: Directions): ComponentNode<P>;
114
114
  export declare function slot(name: string, key?: string | number, directions?: Directions): SlotProvider;
115
115
  export declare function each<T>(items: readonly T[], render: (item: T, index: number) => VNode | string, key?: (item: T, index: number) => string | number): VNode[];
116
116
  export {};
@@ -0,0 +1,12 @@
1
+ import{Da as re,Ea as fe,Fa as q}from"./index-ryj080w6.js";import{gb as j}from"./index-dse0chhf.js";class l{errors=[];attempt(e){try{e()}catch(t){this.errors.push(t)}}add(e){this.errors.push(e)}throwIfAny(e){if(this.errors.length===1)throw this.errors[0];if(this.errors.length>1){let t=globalThis.AggregateError;if(t)throw new t(this.errors,e);let n=Error(e);throw n.name="AggregateError",n.errors=this.errors,n}}}var E=Symbol("is_reactive"),h=Symbol("is_readonly"),B=Symbol("is_ref"),Y=["push","pop","shift","unshift","splice","sort","reverse"];function f(e,t){return Boolean(Reflect.get(e,t))}function m(e){return e!==null&&typeof e==="object"}class D{pending=new Set;flushing=!1;flushPromise=null;flushResolve=null;enqueue(e){if(this.pending.has(e))return;if(this.pending.add(e),!this.flushing)queueMicrotask(()=>this.flush())}flush(){if(this.flushing)return;this.flushing=!0;try{while(this.pending.size>0){let e=Array.from(this.pending);this.pending.clear();for(let t of e)if(t.active)t()}}finally{this.flushing=!1;let e=this.flushResolve;this.flushResolve=null,this.flushPromise=null,e?.()}}nextTick(){if(!this.flushing&&this.pending.size===0)return Promise.resolve();if(this.flushPromise)return this.flushPromise;return this.flushPromise=new Promise((e)=>{this.flushResolve=e}),this.flushPromise}}var be=0,w=new D;function Qe(){return w.nextTick()}function Ze(){w.flush()}class g{static instance;activeEffect=null;effectStack=[];targetMap=new WeakMap;reactiveMap=new WeakMap;readonlyMap=new WeakMap;proxyMap=new WeakMap;constructor(){}static getInstance(){if(!g.instance)g.instance=new g;return g.instance}reactive(e){if(!m(e))return console.warn("reactive: target must be an object"),e;if(Ee(e))return e;if(this.reactiveMap.has(e))return this.reactiveMap.get(e);if(Array.isArray(e))return this.createReactiveArray(e);let t=new Proxy(e,{get:(n,r)=>{if(r===E)return!0;if(r===h)return!1;this.track(n,r);let o=Reflect.get(n,r);if(m(o)&&!f(o,h))return this.reactive(o);return o},set:(n,r,o)=>{if(f(n,h))return console.warn(`Cannot set property ${String(r)} on readonly object`),!1;let i=Reflect.get(n,r);if(m(o)&&!f(o,E)&&!f(o,h))o=this.reactive(o);let s=Reflect.set(n,r,o);if(i!==o)this.trigger(n,r);return s},deleteProperty:(n,r)=>{if(f(n,h))return console.warn(`Cannot delete property ${String(r)} on readonly object`),!1;let o=r in n,i=Reflect.deleteProperty(n,r);if(o)this.trigger(n,r);return i}});return this.reactiveMap.set(e,t),this.proxyMap.set(t,e),t}toRawValue(e){if(m(e)&&this.proxyMap.has(e))return this.proxyMap.get(e);return e}createReactiveArray(e){if(this.reactiveMap.has(e))return this.reactiveMap.get(e);let t=new Proxy(e,{get:(n,r)=>{if(r===E)return!0;if(r===h)return!1;this.track(n,r);let o=Reflect.get(n,r);if(typeof r==="string"&&(r==="includes"||r==="indexOf"||r==="lastIndexOf")){this.track(n,"length");for(let s=0;s<n.length;s++)this.track(n,String(s));let i=o;return(...s)=>{let a=i.apply(n,s);if(a===!1||a===-1){let p=n.map((d)=>this.toRawValue(d));return p[r].apply(p,s.map((d)=>this.toRawValue(d)))}return a}}if(typeof r==="string"&&Y.includes(r))return(...i)=>{let a=o.apply(n,i);return this.trigger(n,"length"),this.trigger(n,r),a};if(m(o)&&!f(o,h))return this.reactive(o);return o},set:(n,r,o)=>{if(f(n,h))return console.warn(`Cannot set property ${String(r)} on readonly object`),!1;let i=Reflect.get(n,r);if(m(o)&&!f(o,E)&&!f(o,h))o=this.reactive(o);let s=Reflect.set(n,r,o);if(i!==o){if(this.trigger(n,r),typeof r==="string"&&!isNaN(Number(r)))this.trigger(n,"length")}return s},deleteProperty:(n,r)=>{if(f(n,h))return console.warn(`Cannot delete property ${String(r)} on readonly object`),!1;let o=r in n,i=Reflect.deleteProperty(n,r);if(o)this.trigger(n,r),this.trigger(n,"length");return i}});return this.reactiveMap.set(e,t),this.proxyMap.set(t,e),t}readonly(e){if(!m(e))return console.warn("readonly: target must be an object"),e;if(f(e,h))return e;if(this.readonlyMap.has(e))return this.readonlyMap.get(e);let t=new Proxy(e,{get:(n,r)=>{if(r===E)return!1;if(r===h)return!0;let o=Reflect.get(n,r);if(m(o))return this.readonly(o);return o},set:()=>(console.warn("Cannot set property on readonly object"),!1),deleteProperty:()=>(console.warn("Cannot delete property on readonly object"),!1)});return this.readonlyMap.set(e,t),t}effect(e,t){let{lazy:n=!1,scheduler:r,throwOnError:o=!1}=t||{},i=()=>{if(!i.active)return e();try{return this.cleanup(i),this.effectStack.push(i),this.activeEffect=i,e()}catch(s){if(o)throw s;console.error("Effect error:",s);return}finally{this.effectStack.pop(),this.activeEffect=this.effectStack[this.effectStack.length-1]??null}};if(i.id=be++,i.deps=[],i.active=!0,i.scheduler=r,!n)i();return i}runWithEffect(e,t){this.effectStack.push(e),this.activeEffect=e;try{return t()}finally{this.effectStack.pop(),this.activeEffect=this.effectStack[this.effectStack.length-1]??null}}computed(e){let t=!0,n,r={},o=()=>{this.track(r,"value")},i=this.effect(()=>{n=e(),t=!1},{lazy:!0,scheduler:()=>{if(!t)t=!0,this.trigger(r,"value")}});return{get value(){if(t)i();return o(),n}}}cleanup(e){e.deps.forEach((t)=>{t.delete(e)}),e.deps.length=0}track(e,t){if(!this.activeEffect||!this.activeEffect.active)return;let n=this.targetMap.get(e);if(!n)n=new Map,this.targetMap.set(e,n);let r=n.get(t);if(!r)r=new Set,n.set(t,r);if(!r.has(this.activeEffect))r.add(this.activeEffect),this.activeEffect.deps.push(r)}trigger(e,t){let n=this.targetMap.get(e);if(!n)return;let r=n.get(t);if(!r)return;new Set(r).forEach((i)=>{if(i.active)if(i.scheduler)i.scheduler(i);else i()})}stop(e){if(e.active)this.cleanup(e),e.active=!1}}function K(e){return g.getInstance().reactive(e)}function Je(e){return g.getInstance().readonly(e)}function y(e,t){return g.getInstance().effect(e,t)}function Xe(e){return g.getInstance().computed(e)}function et(e){let t={value:e};return Object.defineProperty(t,B,{configurable:!1,enumerable:!1,value:!0}),K(t)}function Q(e){return m(e)&&Boolean(Reflect.get(e,B))}function tt(e){return Q(e)?e.value:e}function C(e){g.getInstance().stop(e)}function U(e,t){if(!m(e)||t.has(e))return;if(t.add(e),Array.isArray(e)){e.forEach((n)=>U(n,t));return}Object.keys(e).forEach((n)=>{U(e[n],t)})}function nt(e,t,n={}){let r=g.getInstance(),o=Q(e)?()=>e.value:e,i,s=null,a=()=>{if(!u.active)return;s?.(),s=null;let d=p();t(d,i,(v)=>{s=v}),i=d},p=y(()=>{let d=o();if(n.deep&&m(d))U(d,new Set);return d},{lazy:!0,scheduler:()=>{if(n.sync)a();else w.enqueue(u)}}),u=y(()=>{a()},{lazy:!0});if(n.immediate)a();else i=p();return()=>{r.stop(p),r.stop(u)}}function Ee(e){return m(e)&&f(e,E)}function rt(e){return m(e)&&f(e,h)}function R(e){if(e===void 0||e===null)return[];return Array.isArray(e)?e:[e]}function Z(e){return typeof e==="object"&&e!==null&&"component"in e}function J(e){return typeof e==="object"&&e!==null&&"tag"in e&&e.tag!=="slot"}function X(e){return typeof e==="object"&&e!==null&&"tag"in e&&e.tag==="slot"}function it(e,t,n,r,o,i){return{tag:e,props:t,children:n,listeners:r,key:o,directions:i}}function xe(e,t={}){return{tag:e,...t}}function c(e){return(t={})=>xe(e,t)}var A=c("div"),st=c("span"),at=c("p"),pt=c("button"),ct=c("input"),ut=c("section"),lt=c("main"),dt=c("header"),ht=c("footer"),ft=c("nav"),mt=c("article"),gt=c("aside"),vt=c("h1"),yt=c("h2"),Rt=c("h3"),Ct=c("h4"),bt=c("h5"),Et=c("h6"),xt=c("strong"),Tt=c("em"),wt=c("small"),St=c("pre"),Pt=c("code"),At=c("blockquote"),Lt=c("ul"),Mt=c("ol"),Nt=c("li"),It=c("a"),kt=c("img"),Ht=c("form"),jt=c("label"),Ot=c("textarea"),_t=c("select"),Vt=c("option"),Bt=c("table"),Dt=c("thead"),$t=c("tbody"),Ut=c("tr"),Kt=c("th"),Wt=c("td");function Ft(e,t,n,r,o){if(typeof e==="function")return{component:e,props:t,children:n,key:r,directions:o};return{component:e.component,props:e.props,children:e.children,key:e.key,directions:e.directions,emitters:e.emitters}}function zt(e,t,n){return{tag:"slot",props:{name:e},key:t,directions:n}}function Gt(e,t,n){return e.map((r,o)=>{let i=t(r,o);if(typeof i==="string")throw Error("each render callback must return a VNode");if(!n)return i;return{...i,key:n(r,o)}})}function te(e){let t=e.split(".");if(e.length===0||t.some((n)=>n.length===0||n==="__proto__"||n==="prototype"||n==="constructor"))throw Error(`Invalid model path "${e}"`);return t}function F(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function ne(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function Te(e){return typeof e==="string"?e:e.path}function ee(e,t){let n=e;for(let r of te(t)){if(!F(n))throw Error(`Invalid model path "${t}"`);if(!ne(n,r)){if(r in n)throw Error(`Invalid model path "${t}"`);return}n=n[r]}return n}function we(e,t,n){let r=te(t),o=e;for(let s of r.slice(0,-1)){if(!ne(o,s)){if(s in o)throw Error(`Invalid model path "${t}"`);o[s]={}}else if(!F(o[s]))throw Error(`Invalid model path "${t}"`);let a=o[s];if(!F(a))throw Error(`Invalid model path "${t}"`);o=a}let i=r[r.length-1];o[i]=n}function W(e,t){if(typeof e!=="string"&&e.format)return e.format(t);return t===void 0||t===null?"":String(t)}function Se(e,t){if(typeof e!=="string"&&e.parse)return e.parse(t);return t}function Pe(e,t,n){if(e instanceof HTMLInputElement){if(e.type==="checkbox"){e.checked=Array.isArray(n)?n.some((r)=>String(r)===e.value):Boolean(n);return}if(e.type==="radio"){e.checked=n===e.value;return}e.value=W(t,n);return}if(e instanceof HTMLTextAreaElement){e.value=W(t,n);return}if(e instanceof HTMLSelectElement){if(e.multiple){let r=Array.isArray(n)?new Set(n.map(String)):new Set;for(let o=0;o<e.options.length;o+=1){let i=e.options.item(o);if(!i)continue;i.selected=r.has(i.value)}return}e.value=W(t,n)}}function Ae(e,t){if(e instanceof HTMLInputElement){if(e.type==="checkbox"){if(Array.isArray(t)){let n=t.filter((r)=>String(r)!==e.value);return e.checked?[...n,e.value]:n}return e.checked}if(e.type==="radio")return e.checked?e.value:t;return e.value}if(e instanceof HTMLTextAreaElement)return e.value;if(e instanceof HTMLSelectElement){if(!e.multiple)return e.value;let n=[];for(let r=0;r<e.selectedOptions.length;r+=1){let o=e.selectedOptions.item(r);if(o)n.push(o.value)}return n}return}class z{bindings=new WeakMap;bind(e,t,n){if(!this.isSupportedControl(e))return;let r=this.bindings.get(e);if(r&&this.sameBinding(r,t))return;this.cleanup(e);let o=Te(t),i=()=>Pe(e,t,ee(n,o)),s=e instanceof HTMLTextAreaElement||e instanceof HTMLInputElement&&!["checkbox","radio"].includes(e.type)?"input":"change",a=()=>{let u=ee(n,o);we(n,o,Se(t,Ae(e,u)))};e.addEventListener(s,a);let p=y(i);this.bindings.set(e,{binding:t,path:o,parse:typeof t==="string"?void 0:t.parse,format:typeof t==="string"?void 0:t.format,eventName:s,listener:a,effect:p})}cleanup(e){let t=this.bindings.get(e);if(!t)return;e.removeEventListener(t.eventName,t.listener),C(t.effect),this.bindings.delete(e)}isSupportedControl(e){return e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement}sameBinding(e,t){if(typeof e.binding==="string"||typeof t==="string")return e.binding===t;return e.path===t.path&&e.parse===t.parse&&e.format===t.format}}function M(e){return/^on[A-Z]/.test(e)||/^on[a-z]/.test(e)}function oe(e){return e.slice(2).toLowerCase()}function ie(e){let[t,...n]=e.split(".");return{eventName:t,modifiers:new Set(n)}}function se(e,t){let n=(r)=>{if(t.has("stop"))r.stopPropagation();if(t.has("prevent"))r.preventDefault();if(t.has("self")&&r.currentTarget!==r.target)return;if(t.has("once"))r.currentTarget.removeEventListener(r.type,n);e(r)};return n}function ae(e,t,n){let r=t.includes("-")?t:t.replace(/[A-Z]/g,(o)=>`-${o.toLowerCase()}`);e.setProperty(r,re(n))}var N=null;function pe(e){if(!e||!(e instanceof I))throw Error("Invalid router instance");N=e}function Le(){if(!N)throw Error("Router is not initialized. Please make sure you have installed the router plugin.");return N}function ce(){return N}var ue="http://www.w3.org/2000/svg",Me=new Set(["svg","g","defs","rect","circle","ellipse","line","polyline","polygon","path","text","tspan","textPath","use","symbol","marker","linearGradient","radialGradient","stop","pattern","mask","clipPath","foreignObject"]);class H{listeners=new WeakMap;effects=new WeakMap;modelBindings=new z;matches(e){return typeof e==="object"&&e!==null&&J(e)}mount(e,t){if(e.directions?.if===!1)return document.createComment("if");let n=e.tag==="navigator",r=n?document.createElement("a"):Me.has(e.tag)?document.createElementNS(ue,e.tag):document.createElement(e.tag);try{let o=e.props??{};if(n){let{url:i,openType:s,...a}=o,p=typeof i==="string"?i:"#";r.setAttribute("href",p);let u=(d)=>{let v=ce();if(v)d.preventDefault(),v.push(r.getAttribute("href")??"#")};r.addEventListener("click",u),this.listeners.set(r,new Map([["navigator",{eventName:"click",listener:u}]])),this.applyProps(r,{},a,t)}else this.applyProps(r,{},o,t);return this.updateListeners(r,{},this.collectListeners(e)),this.mountChildren(r,e,t),this.applyDirections(r,void 0,e.directions,t),r}catch(o){let i=new l;throw i.add(o),i.attempt(()=>this.unmount(e,r,t)),i.throwIfAny("Element initialization and cleanup failed"),o}}patch(e,t,n,r){if(e.tag!==t.tag||n.nodeType===Node.COMMENT_NODE){let i=this.mount(t,r);return n.parentNode?.replaceChild(i,n),this.unmount(e,n,r),i}if(!(n instanceof Element))return n;if(t.directions?.if===!1){let i=document.createComment("if");return n.parentNode?.replaceChild(i,n),this.unmount(e,n,r),i}if(t.tag==="navigator"||e.tag==="navigator"){let i=e.props??{},s=t.props??{},a=typeof i.url==="string"?i.url:"",p=typeof s.url==="string"?s.url:"";if(a!==p)n.setAttribute("href",p);let u={...s};delete u.url,delete u.openType,this.applyProps(n,i,u,r)}else this.applyProps(n,e.props??{},t.props??{},r);return this.updateListeners(n,this.collectListeners(e),this.collectListeners(t)),this.updateChildren(n,e,t,r),this.applyDirections(n,e.directions,t.directions,r),n}unmount(e,t,n){if(!(t instanceof Element))return;let r=new l;this.effects.get(t)?.forEach((o)=>r.attempt(()=>C(o))),this.effects.delete(t),this.listeners.get(t)?.forEach(({eventName:o,listener:i})=>{r.attempt(()=>t.removeEventListener(o,i))}),this.listeners.delete(t),r.attempt(()=>this.modelBindings.cleanup(t)),r.attempt(()=>this.unmountChildren(t,e,n)),r.throwIfAny("Element teardown failed")}mountChildren(e,t,n){R(t.children).forEach((r)=>{e.appendChild(n.renderer.mount(r,n))})}updateChildren(e,t,n,r){this.updateOrdinaryChildren(e,R(t.children),R(n.children),r)}unmountChildren(e,t,n){let r=Array.from(e.childNodes),o=new l;R(t.children).forEach((i,s)=>{let a=r[s];if(a)o.attempt(()=>n.renderer.unmount(i,a,n))}),o.throwIfAny("Element children teardown failed")}applyProps(e,t,n,r){Object.keys(t).forEach((o)=>{if(M(o)||o in n)return;if(o==="className"||o==="class")e.removeAttribute("class");else if(o==="style")e.removeAttribute("style");else if(o==="value"&&typeof e==="object"&&e!==null&&"value"in e)e.value="";else e.removeAttribute(k(o))}),Object.entries(n).forEach(([o,i])=>{if(M(o))return;if(t[o]===i)return;if(o==="className"||o==="class"){if(e.namespaceURI===ue)e.setAttribute("class",String(i??""));else e.className=String(i??"");return}if(o==="value"&&typeof e==="object"&&e!==null&&"value"in e){e.value=String(i??"");return}if(o==="style"&&typeof i==="object"&&i!==null){e.removeAttribute("style");let s=e.style;Object.entries(i).forEach(([a,p])=>{ae(s,a,p)});return}if(i===!1||i===void 0||i===null){e.removeAttribute(k(o));return}if(i===!0){e.setAttribute(k(o),"");return}if(typeof i==="string"&&r.templateEngine.hasExpressions(i)){this.setupReactiveAttribute(e,o,i,r);return}e.setAttribute(k(o),String(i))})}applyDirections(e,t,n,r){if(n&&"show"in n)e.style.display=n.show?"":"none";else if(t&&"show"in t)e.style.display="";if(!n?.model){this.modelBindings.cleanup(e);return}this.modelBindings.bind(e,n.model,r.templateEngine.state)}updateOrdinaryChildren(e,t,n,r){if(this.assertNoDuplicateKeys(t),this.assertNoDuplicateKeys(n),this.hasOnlyKeyedChildren(t,n)){this.updateKeyedChildren(e,t,n,r);return}let o=Math.min(t.length,n.length);for(let s=0;s<o;s+=1){let a=e.childNodes[s];if(!a){e.appendChild(r.renderer.mount(n[s],r));continue}r.renderer.patch(t[s],n[s],a,r)}for(let s=o;s<n.length;s+=1)e.appendChild(r.renderer.mount(n[s],r));let i=new l;for(let s=t.length-1;s>=n.length;s-=1){let a=e.childNodes[s];if(a)i.attempt(()=>r.renderer.unmount(t[s],a,r)),i.attempt(()=>{if(a.parentNode===e)e.removeChild(a)})}i.throwIfAny("Removed element children teardown failed")}updateKeyedChildren(e,t,n,r){let o=t.map((p,u)=>({vnode:p,node:e.childNodes[u],index:u})),i=new Map,s=new Set;o.forEach((p)=>{let u=this.getVNodeKey(p.vnode);if(u!==void 0&&p.node)i.set(u,{vnode:p.vnode,node:p.node,index:p.index})}),n.forEach((p,u)=>{let d=this.getVNodeKey(p),v=d===void 0?void 0:i.get(d),b;if(v)b=r.renderer.patch(v.vnode,p,v.node,r),s.add(v.index);else b=r.renderer.mount(p,r);let V=e.childNodes[u]??null;if(b!==V)e.insertBefore(b,V)});let a=new l;o.forEach((p)=>{if(!p.node||s.has(p.index))return;let u=p.node;a.attempt(()=>r.renderer.unmount(p.vnode,u,r)),a.attempt(()=>{if(u.parentNode===e)e.removeChild(u)})}),a.throwIfAny("Removed keyed children teardown failed")}hasOnlyKeyedChildren(e,t){return[...e,...t].every((n)=>this.getVNodeKey(n)!==void 0)}assertNoDuplicateKeys(e){let t=new Set;e.forEach((n)=>{let r=this.getVNodeKey(n);if(r===void 0)return;if(t.has(r))throw Error(`Duplicate key "${r}"`);t.add(r)})}getVNodeKey(e){if(typeof e==="string")return;return e.key}collectListeners(e){let t={};return Object.entries(e.props??{}).forEach(([n,r])=>{if(M(n)&&typeof r==="function")t[oe(n)]=r}),{...t,...e.listeners??{}}}updateListeners(e,t,n){let r=this.listeners.get(e)??new Map,o=new Set(Object.keys(t)),i=new Set(Object.keys(n));o.forEach((s)=>{if(!i.has(s)||t[s]!==n[s]){let a=r.get(s);if(a)e.removeEventListener(a.eventName,a.listener),r.delete(s)}}),i.forEach((s)=>{if(!o.has(s)||t[s]!==n[s]){let{eventName:a,modifiers:p}=ie(s),u=typeof e.tagName==="string"&&e.tagName.toLowerCase()==="textarea",d=a==="confirm"&&!u?"keydown":a,v=se((b)=>{if(d==="keydown"){if(b.key!=="Enter")return}n[s](b)},p);e.addEventListener(d,v),r.set(s,{eventName:d,listener:v})}}),this.listeners.set(e,r)}setupReactiveAttribute(e,t,n,r){let o=y(()=>{e.setAttribute(t,r.templateEngine.evaluateTemplateValue(n))});this.trackEffect(e,o)}trackEffect(e,t){let n=this.effects.get(e)??new Set;n.add(t),this.effects.set(e,n)}}function k(e){if(e.startsWith("data")&&e.length>4)return`data${e.slice(4).replace(/[A-Z]/g,(t)=>`-${t.toLowerCase()}`)}`;if(e==="tabIndex"||e==="colSpan"||e==="htmlFor")return e.toLowerCase();return e}class L{strategies;constructor(){this.strategies=[new le,new de,new he,new H]}mount(e,t){return this.findStrategy(e).mount(e,t)}patch(e,t,n,r){let o=this.findStrategy(e),i=this.findStrategy(t);if(o!==i){let s=i.mount(t,r);return n.parentNode?.replaceChild(s,n),o.unmount(e,n,r),s}return o.patch(e,t,n,r)}unmount(e,t,n){this.findStrategy(e).unmount(e,t,n)}findStrategy(e){let t=this.strategies.find((n)=>n.matches(e));if(!t)throw Error("No render strategy found for vnode");return t}}class le{matches(e){return typeof e==="string"}mount(e,t){return t.templateEngine.parseTemplate(e)}patch(e,t,n,r){if(e===t)return n;let o=this.mount(t,r);return n.parentNode?.replaceChild(o,n),o}unmount(){}}class de{instances=new WeakMap;instanceNodes=new Map;emitterUnsubscribers=new WeakMap;matches(e){return typeof e==="object"&&e!==null&&Z(e)}mount(e,t){if(e.directions?.if===!1)return document.createComment("if");let n=j(e.component,this.createProps(e));try{if(t.appContext&&n.setAppContext)n.setAppContext(t.appContext);this.syncEmitters(n,e.emitters??{}),t.registerChild(n);let r=n.mountToNode();return this.trackInstanceNode(n,r),n.setElementChangeListener?.((o,i)=>{this.trackInstanceNode(n,o),this.trackInstanceNode(n,i)}),r}catch(r){let o=new l;throw o.add(r),o.attempt(()=>this.clearEmitters(n)),o.attempt(()=>n.unmount()),this.clearInstanceNodes(n),o.attempt(()=>t.unregisterChild(n)),o.throwIfAny("Child initialization and cleanup failed"),r}}patch(e,t,n,r){if(n.nodeType===Node.COMMENT_NODE){let s=this.mount(t,r);return n.parentNode?.replaceChild(s,n),this.unmount(e,n,r),s}if(t.directions?.if===!1){let s=document.createComment("if");return n.parentNode?.replaceChild(s,n),this.unmount(e,n,r),s}let o=this.instances.get(n);if(o&&e.component===t.component){this.syncEmitters(o,t.emitters??{}),o.setProps(this.createProps(t));let s=o.getElement()??n;return this.trackInstanceNode(o,s),s}let i=this.mount(t,r);return n.parentNode?.replaceChild(i,n),this.unmount(e,n,r),i}unmount(e,t,n){let r=this.instances.get(t);if(r){let o=new l;o.attempt(()=>this.clearEmitters(r)),o.attempt(()=>r.unmount()),this.clearInstanceNodes(r),o.attempt(()=>n.unregisterChild(r)),o.throwIfAny("Child teardown failed")}}createProps(e){return{...e.props??{},children:R(e.children)}}syncEmitters(e,t){let n=this.emitterUnsubscribers.get(e)??new Map;n.forEach(({listener:r,unsubscribe:o},i)=>{let s=t[i];if(!s||s!==r)o(),n.delete(i)}),Object.entries(t).forEach(([r,o])=>{if(n.get(r)?.listener===o)return;n.set(r,{listener:o,unsubscribe:e.on(r,o)})}),this.emitterUnsubscribers.set(e,n)}clearEmitters(e){let t=new l;this.emitterUnsubscribers.get(e)?.forEach(({unsubscribe:n})=>{t.attempt(n)}),this.emitterUnsubscribers.delete(e),t.throwIfAny("Component emitter cleanup failed")}trackInstanceNode(e,t){this.instances.set(t,e);let n=this.instanceNodes.get(e)??new Set;n.add(t),this.instanceNodes.set(e,n)}clearInstanceNodes(e){this.instanceNodes.get(e)?.forEach((t)=>{this.instances.delete(t)}),this.instanceNodes.delete(e)}}class he{renderedChildren=new WeakMap;matches(e){return typeof e==="object"&&e!==null&&X(e)}mount(e,t){if(e.directions?.if===!1)return document.createComment("if");let n=document.createElement("div");n.setAttribute("data-slot",e.props.name);try{return this.mountSlotChildren(n,this.resolveChildren(e,t),t),n}catch(r){let o=new l;throw o.add(r),o.attempt(()=>this.unmount(e,n,t)),o.throwIfAny("Slot initialization and cleanup failed"),r}}patch(e,t,n,r){if(n.nodeType===Node.COMMENT_NODE){let o=this.mount(t,r);return n.parentNode?.replaceChild(o,n),o}if(t.directions?.if===!1){let o=document.createComment("if");return n.parentNode?.replaceChild(o,n),this.unmount(e,n,r),o}if(n instanceof HTMLElement)n.setAttribute("data-slot",t.props.name),this.replaceSlotChildren(n,e,t,r);return n}unmount(e,t,n){if(!(t instanceof HTMLElement))return;let r=new l;r.attempt(()=>this.unmountSlotChildren(t,n)),this.renderedChildren.delete(t),r.throwIfAny("Slot teardown failed")}resolveChildren(e,t){return t.slots[e.props.name]??R(e.children)}replaceSlotChildren(e,t,n,r){let o=this.renderedChildren.get(e)??[],i=this.resolveChildren(n,r),s=Math.min(o.length,i.length);for(let p=0;p<s;p+=1){let u=e.childNodes[p];if(!u){e.appendChild(r.renderer.mount(i[p],r));continue}r.renderer.patch(o[p],i[p],u,r)}for(let p=s;p<i.length;p+=1)e.appendChild(r.renderer.mount(i[p],r));let a=new l;for(let p=o.length-1;p>=i.length;p-=1){let u=e.childNodes[p];if(u)a.attempt(()=>r.renderer.unmount(o[p],u,r)),a.attempt(()=>{if(u.parentNode===e)e.removeChild(u)})}this.renderedChildren.set(e,i),a.throwIfAny("Removed slot children teardown failed")}mountSlotChildren(e,t,n){let r=[];this.renderedChildren.set(e,r),t.forEach((o)=>{e.appendChild(n.renderer.mount(o,n)),r.push(o)})}unmountSlotChildren(e,t){let n=this.renderedChildren.get(e)??[],r=Array.from(e.childNodes),o=new l;n.forEach((i,s)=>{let a=r[s];if(a)o.attempt(()=>t.renderer.unmount(i,a,t))}),o.throwIfAny("Slot children teardown failed")}}class x{state;bindings=[];templateRegex=/{{(.*?)}}/g;constructor(e){this.state=e;if(!e||typeof e!=="object")throw Error("TemplateEngine requires a valid state object")}parseTemplate(e){if(typeof e!=="string")e=String(e);let t=document.createTextNode("");this.templateRegex.lastIndex=0;let n=Array.from(e.matchAll(this.templateRegex));if(n&&n.length>0)this.setupReactiveBindings(t,e,n);else t.textContent=e;return t}setupReactiveBindings(e,t,n){let r=new Set,o=this.evaluateTemplate(t,n,r);e.textContent=o;let i=y(()=>{try{let s=this.evaluateTemplate(t,n,r);if(e.textContent!==s)e.textContent=s}catch(s){console.error("Template update error:",s),e.textContent=`Error: ${s instanceof Error?s.message:"Unknown error"}`}});this.bindings.push({node:e,originalText:t,effect:i})}evaluateTemplate(e,t,n){let r=e;return t.forEach((o)=>{let i=o[1]?.trim();if(i){n.add(i);let s=this.getValueFromState(i),a=s===void 0||s===null?"":String(s);r=r.replace(o[0],a)}}),r}getValueFromState(e){if(!e)return;let t=e.split("."),n=this.state;for(let r of t){if(!n||typeof n!=="object")return;n=n[r]}return n}clearBindings(){this.bindings.forEach((e)=>{C(e.effect)}),this.bindings=[]}getBindingCount(){return this.bindings.length}hasExpressions(e){return this.templateRegex.lastIndex=0,this.templateRegex.test(e)}extractKeys(e){let t=[],n,r=new RegExp(this.templateRegex,"g");while((n=r.exec(e))!==null){let o=n[1]?.trim();if(o)t.push(o)}return t}evaluateTemplateValue(e){this.templateRegex.lastIndex=0;let t=Array.from(e.matchAll(this.templateRegex));if(!t||t.length===0)return e;let n=new Set;return this.evaluateTemplate(e,t,n)}}class T{props;vnode=null;el=null;renderer=new L;templateEngine;childComponents=new Set;eventListeners={};providers=new Map;updateEffect;appContext=null;disposed=!1;unmounting=!1;disposers=new Set;parentComponent=null;elementChangeListener=null;styleManager;state;mounted=!1;constructor(e={}){this.props=e;this.styleManager=new fe,this.state=K(this.initState()??{}),this.templateEngine=new x(this.state),this.initStyles(),this.updateEffect=y(()=>{if(this.mounted)try{this.update()}catch(t){if(!this.dispatchError(t))throw t}},{throwOnError:!0,scheduler:(t)=>{w.enqueue(t)}})}mount(e){if(!e||!(e instanceof HTMLElement))throw Error("Invalid container element");try{e.appendChild(this.mountToNode())}catch(t){let n=new l;n.add(t),n.attempt(()=>this.unmount()),console.error("组件渲染错误:",t),n.throwIfAny("Component mount and cleanup failed")}}mountToNode(){if(this.mounted&&this.el)return this.el;if(this.unmounting)throw Error("Cannot mount a component during teardown");try{if(this.disposed)this.disposed=!1,this.updateEffect.active=!0,this.initStyles();return this.beforeMount(),this.el=g.getInstance().runWithEffect(this.updateEffect,()=>(this.vnode=this.render(),this.renderer.mount(this.vnode,this.createRenderContext()))),this.mounted=!0,this.onMounted(),this.el}catch(e){let t=new l,n=!1;if(t.attempt(()=>{n=this.dispatchError(e)}),!n)t.add(e);return t.attempt(()=>this.unmount()),t.throwIfAny("Component mount and cleanup failed"),document.createComment("error-boundary")}}update(){if(this.unmounting||this.disposed||!this.el||!this.vnode)return;this.beforeUpdate();let e=this.vnode,t=this.el;if(this.el=g.getInstance().runWithEffect(this.updateEffect,()=>{let n=this.render(),r=this.renderer.patch(e,n,t,this.createRenderContext());return this.vnode=n,r}),t!==this.el)this.elementChangeListener?.(t,this.el);this.onUpdated(),this.onPropsChange()}unmount(){if(this.disposed||this.unmounting)return;this.unmounting=!0,this.disposed=!0;let e=this.mounted,t=new l;if(e)t.attempt(()=>this.beforeUnmount());if(this.vnode&&this.el)t.attempt(()=>this.renderer.unmount(this.vnode,this.el,this.createRenderContext()));for(let n of Array.from(this.childComponents))t.attempt(()=>n.unmount()),t.attempt(()=>n.setParentComponent?.(null));this.childComponents.clear();for(let n of Array.from(this.disposers))if(this.disposers.delete(n))t.attempt(n);for(let n of Object.keys(this.eventListeners))this.eventListeners[n].clear(),delete this.eventListeners[n];if(this.providers.clear(),this.parentComponent=null,this.elementChangeListener=null,this.appContext=null,t.attempt(()=>this.templateEngine.clearBindings()),t.attempt(()=>this.styleManager.destroy()),t.attempt(()=>C(this.updateEffect)),t.attempt(()=>this.el?.parentNode?.removeChild(this.el)),this.el=null,this.vnode=null,this.mounted=!1,e)t.attempt(()=>this.onUnmounted());this.unmounting=!1,t.throwIfAny("Component teardown failed")}onDispose(e){if(this.disposed||this.unmounting)return e(),()=>{};let t=()=>e();return this.disposers.add(t),()=>{this.disposers.delete(t)}}setProps(e){if(this.props={...this.props,...e},this.mounted)w.enqueue(this.updateEffect)}setState(e){Object.assign(this.state,e)}setAppContext(e){this.appContext=e,this.childComponents.forEach((t)=>{t.setAppContext?.(e)})}setParentComponent(e){this.parentComponent=e}getParentComponent(){return this.parentComponent}setElementChangeListener(e){this.elementChangeListener=e}provide(e,t){this.providers.set(e,t)}inject(e,t){let n=this.resolveInjection(e);return n.found?n.value:t}resolveInjection(e){if(this.providers.has(e))return{found:!0,value:this.providers.get(e)};if(this.parentComponent?.resolveInjection)return this.parentComponent.resolveInjection(e);return this.resolveAppInjection(e)}getElement(){return this.el}beforeMount(){}onMounted(){}beforeUpdate(){}onUpdated(){}onPropsChange(){}beforeUnmount(){}onUnmounted(){}dispatchError(e){let t=this.getParentComponent();while(t){let n=t;if(typeof n.onErrorCaptured==="function"){if(n.onErrorCaptured(e,this)===!1)return!0}t=t.getParentComponent?.()??null}return!1}getContext(){return this.appContext}get router(){return this.getRouterFrom(this.appContext)??this.getRouterFromGlobalApp()}emit(e,...t){this.eventListeners[e]?.forEach((n)=>{n(...t)})}on(e,t){if(!this.eventListeners[e])this.eventListeners[e]=new Set;return this.eventListeners[e].add(t),()=>this.off(e,t)}off(e,t){this.eventListeners[e]?.delete(t)}createRenderContext(){return{appContext:this.appContext,templateEngine:this.templateEngine,renderer:this.renderer,slots:this.collectSlots(),registerChild:(e)=>{this.childComponents.add(e),e.setParentComponent?.(this),e.setAppContext?.(this.appContext)},unregisterChild:(e)=>{this.childComponents.delete(e),e.setParentComponent?.(null)}}}collectSlots(){let e={default:[]};return R(this.props.children).forEach((n)=>{let r=this.getSlotName(n);if(!e[r])e[r]=[];e[r].push(this.normalizeSlotChild(n))}),e}getSlotName(e){if(typeof e==="string")return"default";return"slot"in e&&typeof e.slot==="string"?e.slot:"default"}normalizeSlotChild(e){if(typeof e==="string"||!("slot"in e))return e;let t={...e};return delete t.slot,t}getRouterFrom(e){if(!e||typeof e!=="object"||!("router"in e))return;return e.router}getRouterFromGlobalApp(){let e=globalThis.__APP__;return this.getRouterFrom(e)}resolveAppInjection(e){if(!this.appContext||typeof this.appContext!=="object")return{found:!1,value:void 0};return this.appContext.app?.resolveInjection?.(e)??{found:!1,value:void 0}}}class me extends T{}function S(e){if(!e.startsWith("/"))return`/${e}`;return e||"/"}function O(e,t){let n=S(t.split("?")[0]);for(let i of e){if(i.path==="*")continue;let s=Ne(i.path,n);if(s)return{route:i,params:s}}let r=e.find((i)=>i.path==="*");if(r)return{route:r,params:{pathMatch:n}};let o=e.find((i)=>i.path==="/");return o?{route:o,params:{}}:null}function Ne(e,t){let n=ge(e),r=ge(t);if(n.length!==r.length)return null;let o={};for(let i=0;i<n.length;i+=1){let s=n[i],a=r[i];if(s.startsWith(":")){let p=s.slice(1);if(!p)return null;o[decodeURIComponent(p)]=decodeURIComponent(a);continue}if(s!==a)return null}return o}function ge(e){let t=S(e);if(t==="/")return[];return t.split("/").filter(Boolean)}function ve(e,t,n){let r=S(e),o=n==="/"?r:n+r;return t==="hash"?`#${o}`:o}function ye(e,t){let n,r,o;if(e==="history")r=window.location.pathname+window.location.search,n=window.location.pathname,o=window.location.search;else{r=window.location.hash||"#/",n=r.startsWith("#")?r.slice(1):r;let s=n.indexOf("?");o=s>=0?n.slice(s+1):"",n=s>=0?n.slice(0,s):n}if(n.startsWith(t)&&t!=="/"&&n!=="/")n=n.slice(t.length);return n=S(n),{path:n,fullPath:r,query:Ie(o),params:{}}}function G(e,t,n,r){let o=S(e),i=r==="/"?o:r+o;if(n==="history"){if(t)window.history.replaceState({},"",i);else window.history.pushState({},"",i);return}if(t){let s=window.location.href.split("#")[0];window.location.replace(`${s}#${i}`);return}window.location.hash=i}function Ie(e){let t={},n=e.startsWith("?")?e.slice(1):e;if(!n)return t;return n.split("&").forEach((r)=>{let[o,i]=r.split("=");if(o)t[decodeURIComponent(o)]=i?decodeURIComponent(i):""}),t}function ke(e){let t=e.indexOf("?");if(t<0)return{};let n=e.slice(t+1),r={};if(!n)return r;return n.split("&").forEach((o)=>{let[i,s]=o.split("=");if(i)r[decodeURIComponent(i)]=s?decodeURIComponent(s):""}),r}class I{currentRoute=null;currentLocation=null;routes=[];app=null;mode;base;routeChangeListeners=[];beforeGuards=[];afterHooks=[];removeWindowListener;constructor(e){let t=Array.isArray(e)?{routes:e}:e;this.routes=t.routes||[],this.mode=t.mode||"history",this.base=t.base||"/",this.validateRoutes(),this.initEvents(),this.resolveCurrentRoute()}install(e){this.app=e,e.router=this,pe(this);let t=e.getContext();t.router=this,this.resolveCurrentRoute()}push(e){this.navigate(e,!1)}replace(e){this.navigate(e,!0)}forward(){window.history.forward()}back(){window.history.back()}go(e){window.history.go(e)}getCurrentRoute(){if(!this.currentLocation)this.resolveCurrentRoute();return this.currentLocation}getCurrentRouteRecord(){if(!this.currentRoute)this.resolveCurrentRoute();return this.currentRoute}onRouteChange(e){return this.routeChangeListeners.push(e),()=>{let t=this.routeChangeListeners.indexOf(e);if(t>-1)this.routeChangeListeners.splice(t,1)}}beforeEach(e){return this.beforeGuards.push(e),()=>{let t=this.beforeGuards.indexOf(e);if(t>-1)this.beforeGuards.splice(t,1)}}afterEach(e){return this.afterHooks.push(e),()=>{let t=this.afterHooks.indexOf(e);if(t>-1)this.afterHooks.splice(t,1)}}getRoutes(){return[...this.routes]}addRoute(e){if(this.routes.some((n)=>n.path===e.path))throw Error(`Route already exists: ${e.path}`);if(this.routes.push(e),this.getCurrentLocation().path===e.path)this.handleRouteChange()}createHref(e){return ve(e,this.mode,this.base)}destroy(){if(this.removeWindowListener?.(),this.removeWindowListener=void 0,this.app?.router===this)this.app.router=void 0;this.app=null}navigate(e,t){if(!e||typeof e!=="string")throw Error("Path must be a non-empty string");let n=this.currentLocation,r=this.resolveTarget(e);if(!r)return;let o=r.location;for(let i of this.beforeGuards){let s=i(o,n);if(s===!1)return;if(typeof s==="string"&&s!==e){this.navigate(s,t);return}}if(n&&this.isSameLocation(n,o))return;G(r.path,t,this.mode,this.base),this.currentRoute=r.route,this.currentLocation=o,this.triggerRouteChangeListeners(o,n),this.afterHooks.forEach((i)=>{try{i(o,n)}catch(s){console.error("Route afterEach error:",s)}})}resolveTarget(e){let t=O(this.routes,e.split("?")[0]);if(!t)return null;let n=this.applyRedirect(t),r=n?.path??e,o=n?.route??t.route;return{path:r,route:o,location:{path:r.split("?")[0],query:ke(r),params:n?.params??t.params,fullPath:r,name:o?.name,meta:o?.meta}}}applyRedirect(e){let t=new Set,n=e,r="";while(n.route.redirect){if(t.has(n.route.path))throw Error(`Redirect loop detected for route: ${n.route.path}`);t.add(n.route.path),r=n.route.redirect;let o=O(this.routes,r.split("?")[0]);if(!o)return null;n=o}return r?{route:n.route,params:n.params,path:r}:null}validateRoutes(){if(!Array.isArray(this.routes))throw Error("Router routes must be an array");let e=new Set;this.routes.forEach((t)=>{if(!t.component&&!t.redirect)throw Error(`Route ${t.path} must define a component or redirect`);if(e.has(t.path))throw Error(`Duplicate route path: ${t.path}`);e.add(t.path)})}initEvents(){if(typeof window>"u")return;let e=this.mode==="history"?"popstate":"hashchange",t=()=>{this.handleRouteChange()};window.addEventListener(e,t),this.removeWindowListener=()=>{window.removeEventListener(e,t)}}handleRouteChange(){let e=this.currentLocation,t=this.resolveCurrentRoute();if(!this.isSameLocation(e,t))this.triggerRouteChangeListeners(t,e)}resolveCurrentRoute(){let e=this.getCurrentLocation(),t=O(this.routes,e.path),n=t?this.applyRedirect(t):null,r=n?.route??t?.route??null;if(n&&n.path!==e.path)G(n.path,!0,this.mode,this.base);if(this.currentRoute=r,this.currentLocation={...e,params:n?.params??t?.params??{},name:r?.name,meta:r?.meta},this.afterHooks.length>0){let o=this.currentLocation;this.afterHooks.forEach((i)=>{try{i(o,null)}catch(s){console.error("Route afterEach error:",s)}})}return this.currentLocation}getCurrentLocation(){return ye(this.mode,this.base)}isSameLocation(e,t){return e?.fullPath===t?.fullPath&&e?.name===t?.name}triggerRouteChangeListeners(e,t){this.routeChangeListeners.forEach((n)=>{try{n(e,t)}catch(r){console.error("Route change listener error:",r)}})}}class He extends T{unsubscribe;initState(){return{currentPath:this.router?.getCurrentRoute()?.path??window.location.pathname}}initStyles(){}onMounted(){let e=this.router;this.unsubscribe=e?.onRouteChange((t)=>{this.state.currentPath=t.path})}onUnmounted(){this.unsubscribe?.()}render(){let e=this.router,t=this.props.activeClass??"active",n=this.state.currentPath===this.props.to,r=[this.props.className,n?t:void 0].filter(Boolean).join(" ");return{tag:"a",props:{href:e?.createHref(this.props.to)??this.props.to,className:r},listeners:{click:(o)=>{if(o.preventDefault(),this.props.replace)e?.replace(this.props.to);else e?.push(this.props.to)}},children:this.props.children&&this.props.children.length>0?this.props.children:[this.props.to]}}}class je extends T{unsubscribe;initState(){let e=this.router;return{route:e?.getCurrentRoute()??null,record:e?.getCurrentRouteRecord()??null}}initStyles(){}onMounted(){let e=this.router;this.unsubscribe=e?.onRouteChange((t)=>{this.state.route=t,this.state.record=e.getCurrentRouteRecord()})}onUnmounted(){this.unsubscribe?.()}render(){let e=this.state.record??this.router?.getCurrentRouteRecord();return{tag:"div",props:{"data-router-view":""},children:e?.component?[{component:e.component}]:[]}}}function Jn(e){return new I(e)}var Oe=new Set(["base","link","meta"]);function Re(e){let t=e.lang??"en",n=e.charset??"utf-8",r=e.viewport??"width=device-width, initial-scale=1",o=_({lang:t,...e.htmlAttributes??{}}),i=_(e.bodyAttributes),s=_e(e.body);return["<!doctype html>",`<html${o}>`,"<head>",` <meta charset="${P(n)}">`,` <meta name="viewport" content="${P(r)}">`,` <title>${P(e.title)}</title>`,e.description?` <meta name="description" content="${P(e.description)}">`:"",...(e.head??[]).map((a)=>` ${Ve(a)}`),e.styles&&e.styles.length>0?` <style>${q(e.styles)}</style>`:"","</head>",`<body${i}>`,s,...(e.scripts??[]).map((a)=>` ${Be(a)}`),"</body>","</html>"].filter((a)=>a!=="").join(`
2
+ `)}function _e(e){if(typeof document>"u")throw Error("renderHtmlDocument requires a DOM-like document");let t=document.createElement("div"),n=new L,r=new Set,o=Array.isArray(e)?e:[e],i={templateEngine:new x({}),renderer:n,slots:{default:[]},registerChild:(a)=>{r.add(a)},unregisterChild:(a)=>{r.delete(a)}};o.forEach((a)=>{t.appendChild(n.mount(a,i))});let s=t.innerHTML;return r.forEach((a)=>{a.unmount()}),s}function Ve(e){let t=_(e.attributes);if(Oe.has(e.tag)&&!e.text)return`<${e.tag}${t}>`;return`<${e.tag}${t}>${P(e.text??"")}</${e.tag}>`}function Be(e){return`<script${_({type:e.type,src:e.src,async:e.async,defer:e.defer,...e.attributes??{}})}></script>`}function _(e={}){let t=Object.entries(e).flatMap(([n,r])=>{if(r===!1||r===null||r===void 0)return[];return r===!0?[n]:[`${n}="${P(String(r))}"`]}).join(" ");return t?` ${t}`:""}function P(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var Ce="#app";class De{options;container=null;rootInstance=null;mounted=!1;unmounting=!1;templateEngine=null;appContext;providers=new Map;plugins=[];unmountedCallback;router;constructor(e={}){this.options=e;this.appContext={app:this,version:"0.9.0",config:e.config||{}}}handleError(e){console.error("应用错误:",e),this.renderErrorUI(e)}renderErrorUI(e){if(!this.container)return;this.container.innerHTML=`
3
+ <div style="padding: 20px; background-color: #ffebee; color: #c62828; font-family: Arial, sans-serif;">
4
+ <h3>应用错误</h3>
5
+ <p>${e.message}</p>
6
+ <pre style="background-color: #fff; padding: 10px; border-radius: 4px; overflow: auto;">${e.stack}</pre>
7
+ </div>
8
+ `}use(e,...t){if(typeof e.install!=="function")throw Error("插件必须提供 install 方法");return e.install(this,...t),this.plugins.push({plugin:e,args:t}),this}mount(){if(this.unmounting||this.mounted){console.warn("应用已经处于运行状态");return}let e=this.resolveMountContainer();if(!e)return;try{if(this.container=e,globalThis.__APP__=this,this.options.root){if(this.rootInstance=j(this.options.root,this.options.rootProps),"setAppContext"in this.rootInstance)this.rootInstance.setAppContext(this.appContext);if(this.options.state&&"setState"in this.rootInstance)this.rootInstance.setState(this.options.state);this.rootInstance.mount(this.container),this.templateEngine=new x(this.options.state||{})}this.mounted=!0,this.onMounted()}catch(t){let n=new l;n.add(t),this.unmounting=!0,this.teardown(n),this.unmounting=!1;try{n.throwIfAny("App mount and cleanup failed")}catch(r){this.container=e;try{this.handleError(r)}finally{this.container=null}}}}unmount(){if(this.unmounting)return;if(!this.mounted&&!this.rootInstance&&!this.container&&!this.templateEngine){console.warn("应用未处于运行状态");return}this.unmounting=!0;let e=new l;this.teardown(e),this.unmounting=!1;try{e.throwIfAny("App teardown failed")}catch(t){console.error("Failed to unmount app:",t)}}teardown(e){for(let{plugin:t}of this.plugins)e.attempt(()=>t.onBeforeUnmount?.(this));if(this.releaseResources(e),this.unmountedCallback)e.attempt(this.unmountedCallback)}releaseResources(e){if(e.attempt(()=>this.rootInstance?.unmount()),this.rootInstance=null,e.attempt(()=>this.templateEngine?.clearBindings()),this.templateEngine=null,e.attempt(()=>{if(this.container)this.container.innerHTML=""}),this.container=null,this.mounted=!1,globalThis.__APP__===this)delete globalThis.__APP__}isRunning(){return this.mounted}updateRootComponent(e){if(this.mounted)this.unmount();this.options.root=e,this.mount()}update(e){if(!this.mounted)return console.warn("Cannot update unmounted app"),this;try{if(e&&this.options.state){if(this.options.state={...this.options.state,...e},this.rootInstance&&"setState"in this.rootInstance)this.rootInstance.setState(e);if(this.templateEngine)this.templateEngine.state=this.options.state}this.onUpdated()}catch(t){console.error("Failed to update app:",t)}return this}getContext(){return this.appContext}provide(e,t){return this.providers.set(e,t),this}inject(e,t){let n=this.resolveInjection(e);return n.found?n.value:t}resolveInjection(e){if(!this.providers.has(e))return{found:!1,value:void 0};return{found:!0,value:this.providers.get(e)}}getState(){return this.options.state}setState(e){if(this.options.state=e,this.mounted)this.update();return this}onUnmounted(e){return this.unmountedCallback=e,this}renderHtmlDocument(e={}){let t=this.options.document??{},n=this.mergeDocumentScripts(t.scripts,e.scripts);return Re({...t,...e,title:e.title??t.title??"TransOne App",body:e.body??t.body??this.createMountDocumentBody(),scripts:n})}resolveRootElement(e){if(!e)return null;if(typeof e==="string"){if(typeof document>"u")return null;return document.querySelector(e)}return typeof Element<"u"&&e instanceof Element?e:null}resolveMountContainer(){if(typeof document>"u")return null;let e=this.resolveRootElement(this.options.rootElement??Ce);return e instanceof HTMLElement?e:null}createMountDocumentBody(){let e=this.options.rootElement??Ce;if(typeof e==="string")return this.createMountElementFromSelector(e);if(typeof Element<"u"&&e instanceof Element){let t={};if(e.id)t.id=e.id;if(e.className)t.className=e.className;return{tag:e.tagName.toLowerCase(),props:t}}return A({props:{id:"app"}})}createMountElementFromSelector(e){if(e.startsWith("#")&&e.length>1)return A({props:{id:e.slice(1)}});if(e.startsWith(".")&&e.length>1)return A({props:{className:e.slice(1)}});return A({props:{"data-transone-root":e}})}mergeDocumentScripts(e,t){if(!e&&!t)return;return[...e??[],...t??[]]}onMounted(){this.plugins.forEach(({plugin:e})=>{if(e&&typeof e.onMounted==="function")e.onMounted(this)})}onUpdated(){this.plugins.forEach(({plugin:e})=>{if(e&&typeof e.onUpdated==="function")e.onUpdated(this)})}}
9
+ export{w as a,Qe as b,Ze as c,g as d,K as e,Je as f,y as g,Xe as h,et as i,Q as j,tt as k,C as l,nt as m,Ee as n,rt as o,R as p,Z as q,J as r,X as s,it as t,xe as u,A as v,st as w,at as x,pt as y,ct as z,ut as A,lt as B,dt as C,ht as D,ft as E,mt as F,gt as G,vt as H,yt as I,Rt as J,Ct as K,bt as L,Et as M,xt as N,Tt as O,wt as P,St as Q,Pt as R,At as S,Lt as T,Mt as U,Nt as V,It as W,kt as X,Ht as Y,jt as Z,Ot as _,_t as $,Vt as aa,Bt as ba,Dt as ca,$t as da,Ut as ea,Kt as fa,Wt as ga,Ft as ha,zt as ia,Gt as ja,Te as ka,ee as la,we as ma,z as na,I as oa,He as pa,je as qa,Jn as ra,Le as sa,H as ta,L as ua,le as va,de as wa,he as xa,x as ya,T as za,me as Aa,Re as Ba,De as Ca};
10
+
11
+ //# debugId=6A7DF95ED95FE4AF64756E2164756E21
12
+ //# sourceMappingURL=index-8qh91wft.js.map