transone 0.4.0 → 0.8.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.
- package/README.md +9 -0
- package/README.zh-CN.md +10 -0
- package/dist/core/app.d.ts +3 -3
- package/dist/core/component/base-component.d.ts +5 -0
- package/dist/core/component/base.d.ts +3 -0
- package/dist/core/component/index.d.ts +3 -2
- package/dist/core/index.d.ts +1 -0
- package/dist/core/vnode.d.ts +4 -4
- package/dist/index-5dxcnfw6.js +12 -0
- package/dist/{index-rmgr0qs2.js.map → index-5dxcnfw6.js.map} +9 -8
- package/dist/index-dse0chhf.js +5 -0
- package/dist/index-dse0chhf.js.map +10 -0
- package/dist/index-fxpn7qkh.js +4 -0
- package/dist/index-fxpn7qkh.js.map +11 -0
- package/dist/{index-xp7y2crt.js → index-jq6fv0br.js} +4 -4
- package/dist/{index-xp7y2crt.js.map → index-jq6fv0br.js.map} +3 -3
- package/dist/{index-qmpx307q.js → index-ryj080w6.js} +3 -3
- package/dist/{index-qmpx307q.js.map → index-ryj080w6.js.map} +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/dist/platform/bindings.d.ts +3 -0
- package/dist/platform/decorators.d.ts +15 -0
- package/dist/platform/definitions.d.ts +32 -0
- package/dist/platform/index.d.ts +3 -0
- package/dist/platform/index.js +4 -0
- package/dist/platform/index.js.map +9 -0
- package/dist/request/index.js +2 -2
- package/dist/request/index.js.map +1 -1
- package/dist/router/index.d.ts +2 -2
- package/dist/router/index.js +2 -2
- package/dist/router/index.js.map +1 -1
- package/dist/style/index.js +2 -2
- package/dist/style/index.js.map +1 -1
- package/package.json +5 -1
- package/dist/index-rmgr0qs2.js +0 -12
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
|
|
package/README.zh-CN.md
CHANGED
|
@@ -13,6 +13,16 @@ 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)
|
package/dist/core/app.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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?:
|
|
16
|
+
root?: ComponentReference<TRootProps>;
|
|
17
17
|
/** 根组件 props */
|
|
18
18
|
rootProps?: TRootProps;
|
|
19
19
|
/** 应用挂载点,默认 #app */
|
|
@@ -67,7 +67,7 @@ export declare class OneApp<TState extends object = Record<string, unknown>, TCo
|
|
|
67
67
|
/**
|
|
68
68
|
* 更新根组件
|
|
69
69
|
*/
|
|
70
|
-
updateRootComponent(component:
|
|
70
|
+
updateRootComponent(component: ComponentReference<TRootProps>): void;
|
|
71
71
|
/**
|
|
72
72
|
* 更新应用状态
|
|
73
73
|
*/
|
|
@@ -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;
|
|
@@ -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';
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/vnode.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
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> =
|
|
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:
|
|
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:
|
|
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 te,Ea as de,Fa as G}from"./index-ryj080w6.js";import{gb as H}from"./index-dse0chhf.js";var C=Symbol("is_reactive"),d=Symbol("is_readonly"),V=Symbol("is_ref"),q=["push","pop","shift","unshift","splice","sort","reverse"];function f(e,t){return Boolean(Reflect.get(e,t))}function h(e){return e!==null&&typeof e==="object"}class B{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 Re=0,x=new B;function ze(){return x.nextTick()}function Ye(){x.flush()}class m{static instance;activeEffect=null;effectStack=[];targetMap=new WeakMap;reactiveMap=new WeakMap;readonlyMap=new WeakMap;proxyMap=new WeakMap;constructor(){}static getInstance(){if(!m.instance)m.instance=new m;return m.instance}reactive(e){if(!h(e))return console.warn("reactive: target must be an object"),e;if(Ce(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===C)return!0;if(r===d)return!1;this.track(n,r);let o=Reflect.get(n,r);if(h(o)&&!f(o,d))return this.reactive(o);return o},set:(n,r,o)=>{if(f(n,d))return console.warn(`Cannot set property ${String(r)} on readonly object`),!1;let i=Reflect.get(n,r);if(h(o)&&!f(o,C)&&!f(o,d))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,d))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(h(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===C)return!0;if(r===d)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 c=n.map((u)=>this.toRawValue(u));return c[r].apply(c,s.map((u)=>this.toRawValue(u)))}return a}}if(typeof r==="string"&&q.includes(r))return(...i)=>{let a=o.apply(n,i);return this.trigger(n,"length"),this.trigger(n,r),a};if(h(o)&&!f(o,d))return this.reactive(o);return o},set:(n,r,o)=>{if(f(n,d))return console.warn(`Cannot set property ${String(r)} on readonly object`),!1;let i=Reflect.get(n,r);if(h(o)&&!f(o,C)&&!f(o,d))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,d))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(!h(e))return console.warn("readonly: target must be an object"),e;if(f(e,d))return e;if(this.readonlyMap.has(e))return this.readonlyMap.get(e);let t=new Proxy(e,{get:(n,r)=>{if(r===C)return!1;if(r===d)return!0;let o=Reflect.get(n,r);if(h(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=Re++,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 D(e){return m.getInstance().reactive(e)}function Qe(e){return m.getInstance().readonly(e)}function g(e,t){return m.getInstance().effect(e,t)}function Ze(e){return m.getInstance().computed(e)}function Je(e){let t={value:e};return Object.defineProperty(t,V,{configurable:!1,enumerable:!1,value:!0}),D(t)}function z(e){return h(e)&&Boolean(Reflect.get(e,V))}function Xe(e){return z(e)?e.value:e}function R(e){m.getInstance().stop(e)}function _(e,t){if(!h(e)||t.has(e))return;if(t.add(e),Array.isArray(e)){e.forEach((n)=>_(n,t));return}Object.keys(e).forEach((n)=>{_(e[n],t)})}function et(e,t,n={}){let r=m.getInstance(),o=z(e)?()=>e.value:e,i,s=null,a=()=>{if(!l.active)return;s?.(),s=null;let u=c();t(u,i,(y)=>{s=y}),i=u},c=g(()=>{let u=o();if(n.deep&&h(u))_(u,new Set);return u},{lazy:!0,scheduler:()=>{if(n.sync)a();else x.enqueue(l)}}),l=g(()=>{a()},{lazy:!0});if(n.immediate)a();else i=c();return()=>{r.stop(c),r.stop(l)}}function Ce(e){return h(e)&&f(e,C)}function tt(e){return h(e)&&f(e,d)}function v(e){if(e===void 0||e===null)return[];return Array.isArray(e)?e:[e]}function Y(e){return typeof e==="object"&&e!==null&&"component"in e}function Q(e){return typeof e==="object"&&e!==null&&"tag"in e&&e.tag!=="slot"}function Z(e){return typeof e==="object"&&e!==null&&"tag"in e&&e.tag==="slot"}function rt(e,t,n,r,o,i){return{tag:e,props:t,children:n,listeners:r,key:o,directions:i}}function be(e,t={}){return{tag:e,...t}}function p(e){return(t={})=>be(e,t)}var P=p("div"),ot=p("span"),it=p("p"),st=p("button"),at=p("input"),pt=p("section"),ct=p("main"),ut=p("header"),lt=p("footer"),dt=p("nav"),ft=p("article"),ht=p("aside"),mt=p("h1"),gt=p("h2"),vt=p("h3"),yt=p("h4"),Rt=p("h5"),Ct=p("h6"),bt=p("strong"),Et=p("em"),xt=p("small"),Tt=p("pre"),wt=p("code"),St=p("blockquote"),Pt=p("ul"),Lt=p("ol"),Mt=p("li"),Nt=p("a"),At=p("img"),kt=p("form"),It=p("label"),Ht=p("textarea"),jt=p("select"),Ot=p("option"),Vt=p("table"),Bt=p("thead"),_t=p("tbody"),Dt=p("tr"),Ut=p("th"),$t=p("td");function Kt(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 Wt(e,t,n){return{tag:"slot",props:{name:e},key:t,directions:n}}function Ft(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 X(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 K(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function ee(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function Ee(e){return typeof e==="string"?e:e.path}function J(e,t){let n=e;for(let r of X(t)){if(!K(n))throw Error(`Invalid model path "${t}"`);if(!ee(n,r)){if(r in n)throw Error(`Invalid model path "${t}"`);return}n=n[r]}return n}function xe(e,t,n){let r=X(t),o=e;for(let s of r.slice(0,-1)){if(!ee(o,s)){if(s in o)throw Error(`Invalid model path "${t}"`);o[s]={}}else if(!K(o[s]))throw Error(`Invalid model path "${t}"`);let a=o[s];if(!K(a))throw Error(`Invalid model path "${t}"`);o=a}let i=r[r.length-1];o[i]=n}function U(e,t){if(typeof e!=="string"&&e.format)return e.format(t);return t===void 0||t===null?"":String(t)}function Te(e,t){if(typeof e!=="string"&&e.parse)return e.parse(t);return t}function we(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=U(t,n);return}if(e instanceof HTMLTextAreaElement){e.value=U(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=U(t,n)}}function Se(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 W{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=Ee(t),i=()=>we(e,t,J(n,o)),s=e instanceof HTMLTextAreaElement||e instanceof HTMLInputElement&&!["checkbox","radio"].includes(e.type)?"input":"change",a=()=>{let l=J(n,o);xe(n,o,Te(t,Se(e,l)))};e.addEventListener(s,a);let c=g(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:c})}cleanup(e){let t=this.bindings.get(e);if(!t)return;e.removeEventListener(t.eventName,t.listener),R(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 ne(e){return e.slice(2).toLowerCase()}function re(e){let[t,...n]=e.split(".");return{eventName:t,modifiers:new Set(n)}}function oe(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 ie(e,t,n){let r=t.includes("-")?t:t.replace(/[A-Z]/g,(o)=>`-${o.toLowerCase()}`);e.setProperty(r,te(n))}var N=null;function se(e){if(!e||!(e instanceof A))throw Error("Invalid router instance");N=e}function Pe(){if(!N)throw Error("Router is not initialized. Please make sure you have installed the router plugin.");return N}function ae(){return N}var pe="http://www.w3.org/2000/svg",Le=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 I{listeners=new WeakMap;effects=new WeakMap;modelBindings=new W;matches(e){return typeof e==="object"&&e!==null&&Q(e)}mount(e,t){if(e.directions?.if===!1)return document.createComment("if");let n=e.tag==="navigator",r=n?document.createElement("a"):Le.has(e.tag)?document.createElementNS(pe,e.tag):document.createElement(e.tag),o=e.props??{};if(n){let{url:i,openType:s,...a}=o,c=typeof i==="string"?i:"#";r.setAttribute("href",c),r.addEventListener("click",(l)=>{let u=ae();if(u)l.preventDefault(),u.push(r.getAttribute("href")??"#")}),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}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:"",c=typeof s.url==="string"?s.url:"";if(a!==c)n.setAttribute("href",c);let l={...s};delete l.url,delete l.openType,this.applyProps(n,i,l,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;this.effects.get(t)?.forEach((r)=>R(r)),this.effects.delete(t),this.listeners.get(t)?.forEach(({eventName:r,listener:o})=>{t.removeEventListener(r,o)}),this.listeners.delete(t),this.modelBindings.cleanup(t),this.unmountChildren(t,e,n)}mountChildren(e,t,n){v(t.children).forEach((r)=>{e.appendChild(n.renderer.mount(r,n))})}updateChildren(e,t,n,r){this.updateOrdinaryChildren(e,v(t.children),v(n.children),r)}unmountChildren(e,t,n){v(t.children).forEach((r,o)=>{let i=e.childNodes[o];if(i)n.renderer.unmount(r,i,n)})}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===pe)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,c])=>{ie(s,a,c)});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 i=0;i<o;i+=1){let s=e.childNodes[i];if(!s){e.appendChild(r.renderer.mount(n[i],r));continue}r.renderer.patch(t[i],n[i],s,r)}for(let i=o;i<n.length;i+=1)e.appendChild(r.renderer.mount(n[i],r));for(let i=t.length-1;i>=n.length;i-=1){let s=e.childNodes[i];if(s){if(r.renderer.unmount(t[i],s,r),s.parentNode===e)e.removeChild(s)}}}updateKeyedChildren(e,t,n,r){let o=t.map((a,c)=>({vnode:a,node:e.childNodes[c],index:c})),i=new Map,s=new Set;o.forEach((a)=>{let c=this.getVNodeKey(a.vnode);if(c!==void 0&&a.node)i.set(c,{vnode:a.vnode,node:a.node,index:a.index})}),n.forEach((a,c)=>{let l=this.getVNodeKey(a),u=l===void 0?void 0:i.get(l),y;if(u)y=r.renderer.patch(u.vnode,a,u.node,r),s.add(u.index);else y=r.renderer.mount(a,r);let S=e.childNodes[c]??null;if(y!==S)e.insertBefore(y,S)}),o.forEach((a)=>{if(!a.node||s.has(a.index))return;if(r.renderer.unmount(a.vnode,a.node,r),a.node.parentNode===e)e.removeChild(a.node)})}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[ne(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:c}=re(s),l=typeof e.tagName==="string"&&e.tagName.toLowerCase()==="textarea",u=a==="confirm"&&!l?"keydown":a,y=oe((S)=>{if(u==="keydown"){if(S.key!=="Enter")return}n[s](S)},c);e.addEventListener(u,y),r.set(s,{eventName:u,listener:y})}}),this.listeners.set(e,r)}setupReactiveAttribute(e,t,n,r){let o=g(()=>{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 ce,new ue,new le,new I]}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 ce{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 ue{instances=new WeakMap;instanceNodes=new Map;emitterUnsubscribers=new WeakMap;matches(e){return typeof e==="object"&&e!==null&&Y(e)}mount(e,t){if(e.directions?.if===!1)return document.createComment("if");let n=H(e.component,this.createProps(e));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}patch(e,t,n,r){if(n.nodeType===Node.COMMENT_NODE){let s=this.mount(t,r);return n.parentNode?.replaceChild(s,n),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)this.clearEmitters(r),r.unmount(),this.clearInstanceNodes(r),n.unregisterChild(r)}createProps(e){return{...e.props??{},children:v(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){this.emitterUnsubscribers.get(e)?.forEach(({unsubscribe:t})=>{t()}),this.emitterUnsubscribers.delete(e)}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 le{renderedChildren=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=document.createElement("div");return n.setAttribute("data-slot",e.props.name),this.mountSlotChildren(n,this.resolveChildren(e,t),t),n}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;this.unmountSlotChildren(t,n),this.renderedChildren.delete(t)}resolveChildren(e,t){return t.slots[e.props.name]??v(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 a=0;a<s;a+=1){let c=e.childNodes[a];if(!c){e.appendChild(r.renderer.mount(i[a],r));continue}r.renderer.patch(o[a],i[a],c,r)}for(let a=s;a<i.length;a+=1)e.appendChild(r.renderer.mount(i[a],r));for(let a=o.length-1;a>=i.length;a-=1){let c=e.childNodes[a];if(c){if(r.renderer.unmount(o[a],c,r),c.parentNode===e)e.removeChild(c)}}this.renderedChildren.set(e,i)}mountSlotChildren(e,t,n){t.forEach((r)=>{e.appendChild(n.renderer.mount(r,n))}),this.renderedChildren.set(e,t)}unmountSlotChildren(e,t){(this.renderedChildren.get(e)??[]).forEach((r,o)=>{let i=e.childNodes[o];if(i)t.renderer.unmount(r,i,t)})}}class b{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=g(()=>{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)=>{R(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 E{props;vnode=null;el=null;renderer=new L;templateEngine;childComponents=new Set;eventListeners={};providers=new Map;updateEffect;appContext=null;parentComponent=null;elementChangeListener=null;styleManager;state;mounted=!1;constructor(e={}){this.props=e;this.styleManager=new de,this.state=D(this.initState()??{}),this.templateEngine=new b(this.state),this.initStyles(),this.updateEffect=g(()=>{if(this.mounted)try{this.update()}catch(t){if(!this.dispatchError(t))throw t}},{throwOnError:!0,scheduler:(t)=>{x.enqueue(t)}})}mount(e){if(!e||!(e instanceof HTMLElement))throw Error("Invalid container element");try{e.appendChild(this.mountToNode())}catch(t){throw console.error("组件渲染错误:",t),t}}mountToNode(){if(this.mounted&&this.el)return this.el;return this.beforeMount(),this.el=m.getInstance().runWithEffect(this.updateEffect,()=>{try{return this.vnode=this.render(),this.renderer.mount(this.vnode,this.createRenderContext())}catch(e){if(this.dispatchError(e))return document.createComment("error-boundary");throw e}}),this.mounted=!0,this.onMounted(),this.el}update(){if(!this.el||!this.vnode)return;this.beforeUpdate();let e=this.vnode,t=this.el;if(this.el=m.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.mounted)return;if(this.beforeUnmount(),this.vnode&&this.el)this.renderer.unmount(this.vnode,this.el,this.createRenderContext());if(this.childComponents.clear(),Object.keys(this.eventListeners).forEach((e)=>{this.eventListeners[e].clear(),delete this.eventListeners[e]}),this.providers.clear(),this.parentComponent=null,this.elementChangeListener=null,this.templateEngine.clearBindings(),this.styleManager.destroy(),R(this.updateEffect),this.el?.parentNode)this.el.parentNode.removeChild(this.el);this.el=null,this.vnode=null,this.mounted=!1,this.onUnmounted()}setProps(e){if(this.props={...this.props,...e},this.mounted)x.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 v(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 fe extends E{}function T(e){if(!e.startsWith("/"))return`/${e}`;return e||"/"}function j(e,t){let n=T(t.split("?")[0]);for(let i of e){if(i.path==="*")continue;let s=Me(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 Me(e,t){let n=he(e),r=he(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 c=s.slice(1);if(!c)return null;o[decodeURIComponent(c)]=decodeURIComponent(a);continue}if(s!==a)return null}return o}function he(e){let t=T(e);if(t==="/")return[];return t.split("/").filter(Boolean)}function me(e,t,n){let r=T(e),o=n==="/"?r:n+r;return t==="hash"?`#${o}`:o}function ge(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=T(n),{path:n,fullPath:r,query:Ne(o),params:{}}}function F(e,t,n,r){let o=T(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 Ne(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 Ae(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 A{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,se(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 me(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;F(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=j(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:Ae(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=j(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=j(this.routes,e.path),n=t?this.applyRedirect(t):null,r=n?.route??t?.route??null;if(n&&n.path!==e.path)F(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 ge(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 ke extends E{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 Ie extends E{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 qn(e){return new A(e)}var He=new Set(["base","link","meta"]);function ve(e){let t=e.lang??"en",n=e.charset??"utf-8",r=e.viewport??"width=device-width, initial-scale=1",o=O({lang:t,...e.htmlAttributes??{}}),i=O(e.bodyAttributes),s=je(e.body);return["<!doctype html>",`<html${o}>`,"<head>",` <meta charset="${w(n)}">`,` <meta name="viewport" content="${w(r)}">`,` <title>${w(e.title)}</title>`,e.description?` <meta name="description" content="${w(e.description)}">`:"",...(e.head??[]).map((a)=>` ${Oe(a)}`),e.styles&&e.styles.length>0?` <style>${G(e.styles)}</style>`:"","</head>",`<body${i}>`,s,...(e.scripts??[]).map((a)=>` ${Ve(a)}`),"</body>","</html>"].filter((a)=>a!=="").join(`
|
|
2
|
+
`)}function je(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 b({}),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 Oe(e){let t=O(e.attributes);if(He.has(e.tag)&&!e.text)return`<${e.tag}${t}>`;return`<${e.tag}${t}>${w(e.text??"")}</${e.tag}>`}function Ve(e){return`<script${O({type:e.type,src:e.src,async:e.async,defer:e.defer,...e.attributes??{}})}></script>`}function O(e={}){let t=Object.entries(e).flatMap(([n,r])=>{if(r===!1||r===null||r===void 0)return[];return r===!0?[n]:[`${n}="${w(String(r))}"`]}).join(" ");return t?` ${t}`:""}function w(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var ye="#app";class Be{options;container=null;rootInstance=null;mounted=!1;templateEngine=null;appContext;providers=new Map;plugins=[];unmountedCallback;router;constructor(e={}){this.options=e;this.appContext={app:this,version:"0.8.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.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=H(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 b(this.options.state||{})}this.mounted=!0,this.onMounted()}catch(t){this.handleError(t)}}unmount(){if(!this.mounted){console.warn("应用未处于运行状态");return}try{if(this.onBeforeUnmount(),this.rootInstance){if("unmount"in this.rootInstance)this.rootInstance.unmount();this.rootInstance=null,this.mounted=!1,delete globalThis.__APP__}if(this.templateEngine)this.templateEngine.clearBindings(),this.templateEngine=null;if(this.container)this.container.innerHTML="";if(this.unmountedCallback)this.unmountedCallback()}catch(e){console.error("Failed to unmount app:",e)}}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 ve({...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??ye);return e instanceof HTMLElement?e:null}createMountDocumentBody(){let e=this.options.rootElement??ye;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 P({props:{id:"app"}})}createMountElementFromSelector(e){if(e.startsWith("#")&&e.length>1)return P({props:{id:e.slice(1)}});if(e.startsWith(".")&&e.length>1)return P({props:{className:e.slice(1)}});return P({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)})}onBeforeUnmount(){this.plugins.forEach(({plugin:e})=>{if(e&&typeof e.onBeforeUnmount==="function")e.onBeforeUnmount(this)})}}
|
|
9
|
+
export{x as a,ze as b,Ye as c,m as d,D as e,Qe as f,g,Ze as h,Je as i,z as j,Xe as k,R as l,et as m,Ce as n,tt as o,v as p,Y as q,Q as r,Z as s,rt as t,be as u,P as v,ot as w,it as x,st as y,at as z,pt as A,ct as B,ut as C,lt as D,dt as E,ft as F,ht as G,mt as H,gt as I,vt as J,yt as K,Rt as L,Ct as M,bt as N,Et as O,xt as P,Tt as Q,wt as R,St as S,Pt as T,Lt as U,Mt as V,Nt as W,At as X,kt as Y,It as Z,Ht as _,jt as $,Ot as aa,Vt as ba,Bt as ca,_t as da,Dt as ea,Ut as fa,$t as ga,Kt as ha,Wt as ia,Ft as ja,Ee as ka,J as la,xe as ma,W as na,A as oa,ke as pa,Ie as qa,qn as ra,Pe as sa,I as ta,L as ua,ce as va,ue as wa,le as xa,b as ya,E as za,fe as Aa,ve as Ba,Be as Ca};
|
|
10
|
+
|
|
11
|
+
//# debugId=9766D61D79EA1A8864756E2164756E21
|
|
12
|
+
//# sourceMappingURL=index-5dxcnfw6.js.map
|