@vobs/i18n 1.1.0 → 1.2.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/dist/index.cjs +685 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +60 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +679 -0
- package/dist/index.js.map +1 -0
- package/package.json +21 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../reactivity/src/debug.ts","../../reactivity/src/owner.ts","../../reactivity/src/signal.ts","../../reactivity/src/scheduler.ts","../../runtime/src/debug.ts","../../runtime/src/hmr.ts","../../runtime/src/ops.ts","../../runtime/src/fragment.ts","../../vobs/src/context.ts","../../vobs/src/app.ts","../src/index.ts"],"names":["effect"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Effect } from './effect'\nimport type { Owner } from './owner'\nimport type { Dependency, ReadableSignal, Subscriber } from './signal'\n\nexport interface ReactivityDebugHooks {\n ownerCreated?(owner: Owner): void\n ownerNamed?(owner: Owner, name: string): void\n ownerDisposed?(owner: Owner): void\n signalCreated?(signal: ReadableSignal<unknown>, owner: Owner | null): void\n signalNamed?(signal: ReadableSignal<unknown>, name: string): void\n signalRead?(signal: ReadableSignal<unknown>, subscriber: Subscriber): void\n signalChanged?(signal: ReadableSignal<unknown>, previousValue: unknown, nextValue: unknown): void\n signalDisposed?(signal: ReadableSignal<unknown>): void\n dependencyTracked?(dependency: Dependency, subscriber: Subscriber): void\n dependencyUntracked?(dependency: Dependency, subscriber: Subscriber): void\n effectCreated?(effect: Effect, owner: Owner | null): void\n effectInvalidated?(effect: Effect): void\n effectRunStart?(effect: Effect): void\n effectRunEnd?(effect: Effect, error?: unknown, handled?: boolean): void\n effectDisposed?(effect: Effect): void\n memoCreated?(signal: ReadableSignal<unknown>, subscriber: Subscriber, owner: Owner | null): void\n memoInvalidated?(signal: ReadableSignal<unknown>): void\n flushStart?(): void\n flushEnd?(): void\n}\n\nlet activeDebugHooks: ReactivityDebugHooks | null = null\nconst signalNames = new WeakMap<object, string>()\n\nexport function setDebugHooks(hooks: ReactivityDebugHooks | null): ReactivityDebugHooks | null {\n const previous = activeDebugHooks\n activeDebugHooks = hooks\n return previous\n}\n\nexport function getDebugHooks(): ReactivityDebugHooks | null {\n return activeDebugHooks\n}\n\n/** 热路径守卫:无 hooks 时跳过 invokeDebug 调用,避免 rest 参数数组分配。 */\nexport function hasDebugHooks(): boolean {\n return activeDebugHooks !== null\n}\n\nexport function setSignalDebugName(signal: ReadableSignal<unknown>, name: string): void {\n signalNames.set(signal, name)\n invokeDebug('signalNamed', signal, name)\n}\n\nexport function getSignalDebugName(signal: ReadableSignal<unknown>): string | undefined {\n return signalNames.get(signal)\n}\n\nexport function invokeDebug<K extends keyof ReactivityDebugHooks>(\n name: K,\n ...args: Parameters<NonNullable<ReactivityDebugHooks[K]>>\n): void {\n const callback = activeDebugHooks?.[name] as ((...values: unknown[]) => void) | undefined\n if (!callback) return\n try {\n callback(...args)\n } catch {\n // Debug tooling must never change application behavior.\n }\n}\n","import { invokeDebug, hasDebugHooks } from './debug'\n\nexport interface Owner {\n readonly id: string\n readonly parent: Owner | null\n readonly children: readonly Owner[]\n readonly depth: number\n readonly disposed: boolean\n run<T>(fn: () => T): T\n addCleanup(cleanup: () => void): void\n onDispose(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n handleError(error: unknown): boolean\n dispose(): void\n}\n\nlet currentOwner: Owner | null = null\nlet nextOwnerId = 1\nconst ownerNames = new WeakMap<Owner, string>()\n\nexport function createOwner(): Owner {\n const parent = currentOwner\n let disposed = parent?.disposed ?? false\n const children: Owner[] = []\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n\n const owner: Owner = {\n id: `owner-${nextOwnerId++}`,\n parent,\n children,\n depth: (parent?.depth ?? -1) + 1,\n\n get disposed(): boolean {\n return disposed\n },\n\n run<T>(fn: () => T): T {\n if (disposed) throw new Error('Vobs: 已销毁的 Owner 不能继续运行')\n const previous = currentOwner\n currentOwner = owner\n try {\n return fn()\n } finally {\n currentOwner = previous\n }\n },\n\n addCleanup(cleanup: () => void): void {\n if (disposed) {\n cleanup()\n return\n }\n cleanups.push(cleanup)\n },\n\n onDispose(cleanup: () => void): void {\n owner.addCleanup(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n owner.addCleanup(remove)\n return remove\n },\n\n handleError(error: unknown): boolean {\n for (const handler of [...errorHandlers].reverse()) {\n try {\n handler(error)\n return true\n } catch (handlerError) {\n return parent?.handleError(handlerError) ?? false\n }\n }\n return parent?.handleError(error) ?? false\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const child of [...children]) child.dispose()\n children.length = 0\n\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n if (parent) {\n const index = parent.children.indexOf(owner)\n if (index >= 0) (parent.children as Owner[]).splice(index, 1)\n }\n if (hasDebugHooks()) invokeDebug('ownerDisposed', owner)\n if (firstError) throw firstError\n }\n }\n\n if (parent && !parent.disposed) (parent.children as Owner[]).push(owner)\n if (hasDebugHooks()) invokeDebug('ownerCreated', owner)\n return owner\n}\n\nexport function setOwnerDebugName(owner: Owner, name: string): void {\n ownerNames.set(owner, name)\n if (hasDebugHooks()) invokeDebug('ownerNamed', owner, name)\n}\n\nexport function getOwnerDebugName(owner: Owner): string | undefined {\n return ownerNames.get(owner)\n}\n\nexport function getCurrentOwner(): Owner | null {\n return currentOwner\n}\n\n/** Re-enter an Owner for an explicitly captured asynchronous continuation. */\nexport function runWithOwner<T>(owner: Owner, fn: () => T): T {\n return owner.run(fn)\n}\n\nexport function onDispose(cleanup: () => void): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: onDispose 必须在 Owner 作用域内调用')\n owner.onDispose(cleanup)\n}\n","import { getCurrentOwner } from './owner'\nimport { invokeDebug, hasDebugHooks, setSignalDebugName } from './debug'\n\nexport interface Dependency {\n unsubscribe(subscriber: Subscriber): void\n}\n\nexport interface Subscriber {\n readonly dependencies: Set<Dependency>\n readonly disposed: boolean\n notify(): void\n}\n\n/** 只读信号:派生值(memo)与只读上下文的最小契约,只能订阅与读取。 */\nexport interface ReadableSignal<T> extends Dependency {\n readonly value: T\n dispose(): void\n}\n\n/** 可写信号:state() 的返回类型。`set` 与 `.value =` 赋值语义完全一致。 */\nexport interface Signal<T> extends ReadableSignal<T> {\n value: T\n set(next: T): void\n}\n\nlet currentSubscriber: Subscriber | null = null\n\nexport function getCurrentSubscriber(): Subscriber | null {\n return currentSubscriber\n}\n\nexport function setCurrentSubscriber(subscriber: Subscriber | null): void {\n currentSubscriber = subscriber\n}\n\nexport function untrack<T>(fn: () => T): T {\n const previous = currentSubscriber\n currentSubscriber = null\n try {\n return fn()\n } finally {\n currentSubscriber = previous\n }\n}\n\nexport function trackDependency(dependency: Dependency): void {\n if (!currentSubscriber || currentSubscriber.disposed) return\n const added = !currentSubscriber.dependencies.has(dependency)\n currentSubscriber.dependencies.add(dependency)\n if (added && hasDebugHooks()) invokeDebug('dependencyTracked', dependency, currentSubscriber)\n}\n\n/**\n * Create a reactive state signal.\n *\n * State uses identity (`Object.is`) change detection. Objects and arrays are\n * intentionally shallow: mutating a nested property in place does not notify\n * subscribers; assign a new object/array to `value` to publish the change.\n *\n * The optional debug name is metadata for inspection tools only. It does not\n * affect subscriptions, scheduling, serialization, or the signal contract.\n */\nexport function state<T>(initialValue: T, debugName?: string): Signal<T> {\n let value = initialValue\n let disposed = false\n const subscribers = new Set<Subscriber>()\n\n const signalInstance: Signal<T> = {\n get value(): T {\n const subscriber = getCurrentSubscriber()\n if (subscriber && !subscriber.disposed) {\n subscribers.add(subscriber)\n if (hasDebugHooks()) invokeDebug('signalRead', signalInstance as Signal<unknown>, subscriber)\n trackDependency(signalInstance)\n }\n return value\n },\n\n set value(nextValue: T) {\n if (disposed || Object.is(value, nextValue)) return\n const previousValue = value\n value = nextValue\n if (hasDebugHooks()) invokeDebug('signalChanged', signalInstance as Signal<unknown>, previousValue, nextValue)\n for (const subscriber of [...subscribers]) subscriber.notify()\n },\n\n unsubscribe(subscriber: Subscriber): void {\n subscribers.delete(subscriber)\n },\n\n // 与 `.value =` 赋值同一条路径:判等短路、debug hook、notify 全部一致。\n // 以闭包实现,可安全地作为回调直接传递(无 this 绑定问题)。\n set(next: T): void {\n signalInstance.value = next\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n subscribers.clear()\n if (hasDebugHooks()) invokeDebug('signalDisposed', signalInstance as Signal<unknown>)\n }\n }\n\n const owner = getCurrentOwner()\n owner?.addCleanup(signalInstance.dispose)\n if (hasDebugHooks()) invokeDebug('signalCreated', signalInstance as Signal<unknown>, owner)\n if (debugName?.trim()) setSignalDebugName(signalInstance as Signal<unknown>, debugName.trim())\n return signalInstance\n}\n","import type { Effect } from './effect'\nimport { hasDebugHooks, invokeDebug } from './debug'\n\nexport class Scheduler {\n private readonly dirtyEffects = new Set<Effect>()\n private readonly lowPriorityEffects = new Set<Effect>()\n // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。\n private readonly normalBuffer: Effect[] = []\n private readonly lowBuffer: Effect[] = []\n private flushing = false\n private scheduled = false\n private batchDepth = 0\n\n schedule(effect: Effect): void {\n if (effect.disposed) return\n this.dirtyEffects.add(effect)\n this.lowPriorityEffects.delete(effect)\n this.ensureScheduled()\n }\n\n /** Queue an effect behind normal updates while preserving deterministic order. */\n scheduleLow(effect: Effect): void {\n if (effect.disposed) return\n if (!this.dirtyEffects.has(effect)) this.lowPriorityEffects.add(effect)\n this.ensureScheduled()\n }\n\n private ensureScheduled(): void {\n if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {\n this.scheduled = true\n queueMicrotask(() => {\n this.scheduled = false\n this.flush()\n })\n }\n }\n\n remove(effect: Effect): void {\n this.dirtyEffects.delete(effect)\n this.lowPriorityEffects.delete(effect)\n }\n\n batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) this.flush()\n }\n }\n\n flush(): void {\n if (this.flushing || this.batchDepth > 0) return\n this.flushing = true\n const debugEnabled = hasDebugHooks()\n if (debugEnabled) invokeDebug('flushStart')\n let rounds = 0\n let firstError: unknown\n let hasError = false\n try {\n while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {\n if (++rounds > 100) {\n this.dirtyEffects.clear()\n this.lowPriorityEffects.clear()\n throw new Error('Vobs: 响应式更新超过 100 轮,可能存在循环依赖')\n }\n\n // normal 先、low 后,两组分别排序:与旧的合并排序语义一致\n // (旧比较器里 low 优先级本就高于 depth),但消除了比较器内的 Set 查找。\n this.collectRunnable(this.dirtyEffects, this.normalBuffer)\n this.collectRunnable(this.lowPriorityEffects, this.lowBuffer)\n sortEffects(this.normalBuffer)\n sortEffects(this.lowBuffer)\n for (const effect of this.normalBuffer) {\n try {\n effect.run()\n } catch (error) {\n // Isolate one failed effect from the rest of the flush. Re-throw\n // the first error after all runnable effects have had a chance.\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n for (const effect of this.lowBuffer) {\n try {\n effect.run()\n } catch (error) {\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n }\n } finally {\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n this.flushing = false\n if (debugEnabled) invokeDebug('flushEnd')\n }\n if (hasError) throw firstError\n }\n\n /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */\n private collectRunnable(source: Set<Effect>, target: Effect[]): void {\n for (const effect of source) {\n if (!effect.disposed) target.push(effect)\n }\n source.clear()\n }\n}\n\n/** depth 深的先跑(子 effect 先于父),同深度按创建顺序。 */\nfunction sortEffects(effects: Effect[]): void {\n if (effects.length > 1) {\n effects.sort((a, b) => b.depth - a.depth || a.order - b.order)\n }\n}\n\nexport const scheduler = new Scheduler()\n\nexport function batch<T>(fn: () => T): T {\n return scheduler.batch(fn)\n}\n\n/** Schedule a low-priority effect explicitly. */\nexport function scheduleLow(effect: Effect): void {\n effect.scheduleLow()\n}\n","import type { Owner } from '@vobs/reactivity'\n\nexport type RuntimeDebugEnvironment = 'client' | 'server'\n\n/**\n * Lightweight context copied onto debug events created synchronously inside a\n * Router loader, Effect or SSR render. It is intentionally optional so the\n * runtime remains useful without DevTools.\n */\nexport interface RuntimeDebugContext {\n readonly environment?: RuntimeDebugEnvironment\n readonly sessionId?: string\n readonly route?: string\n readonly navigationId?: number\n readonly dataRequestId?: number\n readonly updateId?: string\n readonly effectId?: string\n readonly source?: string\n}\n\nexport interface RuntimeHydrationMismatch {\n readonly kind: 'missing-node' | 'extra-node' | 'position' | 'content'\n readonly expected: string\n readonly actual: string\n readonly path: string\n readonly message: string\n}\n\nexport type RuntimeDomMutationOperation = 'text' | 'property' | 'attribute' | 'insert' | 'remove'\n\nexport interface RuntimeDomMutation {\n readonly operation: RuntimeDomMutationOperation\n readonly target: string\n readonly parent?: string\n readonly key?: string\n readonly previousValue?: unknown\n readonly nextValue?: unknown\n}\n\nexport interface RuntimeErrorEvent {\n readonly error: unknown\n readonly owner: Owner\n readonly phase: 'event' | 'boundary'\n readonly handled: boolean\n readonly recovery: 'propagated' | 'handled' | 'fallback' | 'retrying' | 'recovered'\n}\n\nexport interface RuntimeDebugHooks {\n domMutation?(mutation: RuntimeDomMutation): void\n error?(event: RuntimeErrorEvent): void\n hydrationMismatch?(event: RuntimeHydrationMismatch): void\n}\n\nlet activeRuntimeDebugHooks: RuntimeDebugHooks | null = null\nlet activeRuntimeDebugContext: RuntimeDebugContext | null = null\n\nexport function setRuntimeDebugHooks(hooks: RuntimeDebugHooks | null): RuntimeDebugHooks | null {\n const previous = activeRuntimeDebugHooks\n activeRuntimeDebugHooks = hooks\n return previous\n}\n\nexport function getRuntimeDebugHooks(): RuntimeDebugHooks | null {\n return activeRuntimeDebugHooks\n}\n\nexport function getRuntimeDebugContext(): RuntimeDebugContext | null {\n return activeRuntimeDebugContext\n}\n\n/** Run a synchronous operation with trace context, preserving async renders. */\nexport function runWithRuntimeDebugContext<T>(context: RuntimeDebugContext, task: () => T): T {\n const previous = activeRuntimeDebugContext\n const next = { ...previous, ...context }\n activeRuntimeDebugContext = next\n let result: T\n try {\n result = task()\n } catch (error) {\n activeRuntimeDebugContext = previous\n throw error\n }\n if (isPromiseLike(result)) {\n return Promise.resolve(result).finally(() => {\n if (activeRuntimeDebugContext === next) activeRuntimeDebugContext = previous\n }) as T\n }\n activeRuntimeDebugContext = previous\n return result\n}\n\n/** Keep a context active across callback boundaries such as Effect execution. */\nexport function pushRuntimeDebugContext(context: RuntimeDebugContext): () => void {\n const previous = activeRuntimeDebugContext\n activeRuntimeDebugContext = { ...previous, ...context }\n let restored = false\n return () => {\n if (restored) return\n restored = true\n activeRuntimeDebugContext = previous\n }\n}\n\nexport function invokeRuntimeDebug<K extends keyof RuntimeDebugHooks>(\n name: K,\n ...args: Parameters<NonNullable<RuntimeDebugHooks[K]>>\n): void {\n const callback = activeRuntimeDebugHooks?.[name] as ((...values: unknown[]) => void) | undefined\n if (!callback) return\n try {\n callback(...args)\n } catch {\n // Debug tooling must never change runtime behavior.\n }\n}\n\nexport function readDebugValue(read: () => unknown): unknown {\n try {\n return read()\n } catch {\n return '[Uninspectable]'\n }\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return Boolean(value) && (typeof value === 'object' || typeof value === 'function')\n && typeof (value as { then?: unknown }).then === 'function'\n}\n\nexport function describeDebugNode(node: unknown): string {\n if (!node || typeof node !== 'object') return 'node'\n const value = node as {\n readonly nodeName?: unknown\n readonly tagName?: unknown\n readonly id?: unknown\n readonly className?: unknown\n }\n const name = typeof value.tagName === 'string'\n ? value.tagName.toLowerCase()\n : typeof value.nodeName === 'string' ? value.nodeName.toLowerCase() : 'node'\n const id = typeof value.id === 'string' && value.id ? `#${value.id}` : ''\n const className = typeof value.className === 'string' && value.className\n ? `.${value.className.trim().split(/\\s+/).filter(Boolean).join('.')}`\n : ''\n return `${name}${id}${className}`\n}\n","import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(_moduleId: string, nextModule: Record<string, unknown>): void {\n const modules = [...hmrGlobal.modules.values()]\n for (const module of modules) {\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) continue\n for (const instance of module.instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n","// 编译产物调用的基础操作\n\nimport { createOwner, getCurrentOwner, setOwnerDebugName, type Owner } from '@vobs/reactivity'\nimport { isVobsFragment, type VobsNode } from './fragment'\nimport { describeDebugNode, getRuntimeDebugHooks, invokeRuntimeDebug, readDebugValue } from './debug'\nimport {\n associateHmrInstance,\n markHmrInstanceMounted,\n registerHmrInstance,\n type HmrInstance\n} from './hmr'\nimport type { VobsRenderer } from './renderer'\nimport { setRef } from './ref'\n\ntype RuntimeRenderer = VobsRenderer<Node, Text, Element, Comment>\n\nlet currentRenderer: RuntimeRenderer | null = null\nconst nodeOwners = new WeakMap<object, Owner>()\ninterface EventBinding {\n readonly handler: EventListener\n readonly owner: Owner | null\n readonly original: EventListener\n}\nconst eventBindings = new WeakMap<object, Map<string, EventBinding>>()\n\nexport function setRenderer<\n NodeType,\n TextNode extends NodeType,\n ElementNode extends NodeType,\n CommentNode extends NodeType\n>(renderer: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>): void {\n // 编译产物仍使用 DOM 节点声明;实际宿主类型由应用提供的渲染器决定。\n currentRenderer = renderer as unknown as RuntimeRenderer\n}\n\nexport function getRenderer(): RuntimeRenderer {\n if (!currentRenderer) {\n throw new Error('渲染器未初始化')\n }\n return currentRenderer\n}\n\nexport function createText(content: string): Text {\n return getRenderer().createText(content)\n}\n\nexport function createElement(tag: string): Element {\n return getRenderer().createElement(tag)\n}\n\nexport function createComment(content: string): Comment {\n return getRenderer().createComment(content)\n}\n\nexport function insertBefore(\n parent: Node,\n child: VobsNode,\n anchor: VobsNode | null\n): void {\n if (isVobsFragment(child)) {\n child.mount(parent, isVobsFragment(anchor) ? anchor.start : anchor)\n return\n }\n getRenderer().insertBefore(parent, child, isVobsFragment(anchor) ? anchor.start : anchor)\n markHmrInstanceMounted(child, parent)\n if (getRuntimeDebugHooks()) {\n invokeRuntimeDebug('domMutation', {\n operation: 'insert',\n target: describeDebugNode(child),\n parent: describeDebugNode(parent)\n })\n }\n}\n\nexport function removeChild(\n parent: Node,\n child: VobsNode\n): void {\n disposeNodeOwner(child)\n if (isVobsFragment(child)) {\n child.unmount(parent)\n return\n }\n getRenderer().removeChild(parent, child)\n if (getRuntimeDebugHooks()) {\n invokeRuntimeDebug('domMutation', {\n operation: 'remove',\n target: describeDebugNode(child),\n parent: describeDebugNode(parent)\n })\n }\n}\n\nexport function setTextContent(\n node: Text,\n content: string\n): void {\n const previousValue = getRuntimeDebugHooks()\n ? readDebugValue(() => node.textContent)\n : undefined\n getRenderer().setTextContent(node, content)\n if (getRuntimeDebugHooks()) {\n invokeRuntimeDebug('domMutation', {\n operation: 'text',\n target: describeDebugNode(node),\n previousValue,\n nextValue: content\n })\n }\n}\n\nexport function setProperty(\n node: Element,\n key: string,\n value: unknown\n): void {\n const previousValue = getRuntimeDebugHooks()\n ? readDebugValue(() => Reflect.get(node, key))\n : undefined\n getRenderer().setProperty(node, key, value)\n if (getRuntimeDebugHooks()) {\n invokeRuntimeDebug('domMutation', {\n operation: 'property',\n target: describeDebugNode(node),\n key,\n previousValue,\n nextValue: value\n })\n }\n}\n\nexport function setAttribute(\n node: Element,\n key: string,\n value: string\n): void {\n const previousValue = getRuntimeDebugHooks()\n ? readDebugValue(() => typeof node.getAttribute === 'function' ? node.getAttribute(key) : undefined)\n : undefined\n getRenderer().setAttribute(node, key, value)\n if (getRuntimeDebugHooks()) {\n invokeRuntimeDebug('domMutation', {\n operation: 'attribute',\n target: describeDebugNode(node),\n key,\n previousValue,\n nextValue: value\n })\n }\n}\n\nexport function spreadProps(node: Element, props: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(props)) {\n if (key === 'key' || value === null || value === undefined) continue\n if (key === 'ref') {\n setRef(node, value)\n continue\n }\n if (key.startsWith('on') && typeof value === 'function') addEventListener(node, key.slice(2).toLowerCase(), value as EventListener)\n // property 键的 false 有语义(如 disabled={false} 必须清除),不能跳过;\n // attribute 键的 false 表示“不设置”,与 HTML 语义一致。\n else if (isPropertyKey(key)) setProperty(node, key, value)\n else if (value === false) continue\n else setAttribute(node, key === 'className' ? 'class' : key, key === 'style' && isStyleObject(value) ? formatStyle(value) : String(value))\n }\n}\n\n/** Apply compile-time host properties in one renderer pass. */\nexport function setStaticProps(node: Element, props: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(props)) {\n if (key === 'key' || key === 'ref' || key.startsWith('on')) continue\n if (value === null || value === undefined) continue\n if (isPropertyKey(key)) setProperty(node, key, value)\n else if (value === false) continue\n else setAttribute(node, key === 'className' ? 'class' : key, key === 'style' && isStyleObject(value) ? formatStyle(value) : String(value))\n }\n}\n\nfunction isPropertyKey(key: string): boolean {\n return key === 'value' || key === 'checked' || key === 'selected' || key === 'disabled'\n || key === 'multiple' || key === 'readOnly' || key === 'required'\n || key === 'autofocus' || key === 'hidden' || key === 'tabIndex'\n}\n\nfunction isStyleObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction formatStyle(value: Record<string, unknown>): string {\n return Object.entries(value).filter(([, entry]) => entry !== null && entry !== undefined && entry !== false)\n .map(([key, entry]) => `${key.replace(/[A-Z]/gu, match => `-${match.toLowerCase()}`)}:${String(entry)}`).join(';')\n}\n\nexport function addEventListener(\n node: Element,\n event: string,\n handler: EventListener\n): void {\n const renderer = getRenderer()\n const owner = getCurrentOwner()\n let bindings = eventBindings.get(node)\n if (!bindings) {\n bindings = new Map()\n eventBindings.set(node, bindings)\n }\n const previous = bindings.get(event)\n if (previous && previous.original === handler && previous.owner === owner) return\n if (previous) renderer.removeEventListener(node, event, previous.handler)\n const listener = owner ? (reason: Event) => {\n try {\n owner.run(() => handler(reason))\n } catch (error) {\n const handled = owner.handleError(error)\n invokeRuntimeDebug('error', {\n error,\n owner,\n phase: 'event',\n handled,\n recovery: handled ? 'handled' : 'propagated'\n })\n if (!handled) throw error\n }\n } : handler\n const binding: EventBinding = { handler: listener, owner, original: handler }\n bindings.set(event, binding)\n renderer.addEventListener(node, event, listener)\n owner?.onDispose(() => {\n if (bindings?.get(event) !== binding) return\n bindings.delete(event)\n renderer.removeEventListener(node, event, listener)\n })\n}\n\nexport function removeEventListener(\n node: Element,\n event: string,\n handler: EventListener\n): void {\n const renderer = getRenderer()\n const binding = eventBindings.get(node)?.get(event)\n renderer.removeEventListener(node, event, binding?.handler ?? handler)\n eventBindings.get(node)?.delete(event)\n}\n\nexport function clear(container: Node): void {\n getRenderer().clear(container)\n}\n\ntype VobsComponent = (...args: any[]) => VobsNode\n\ntype ComponentProps<Component extends VobsComponent> = Component extends (\n props: infer Props\n) => VobsNode\n ? NonNullable<Props> extends object ? NonNullable<Props> : Record<string, never>\n : Record<string, never>\n\nexport function createComponent<Component extends VobsComponent>(\n component: Component,\n props: ComponentProps<Component>,\n source?: VobsSourceLocation\n): VobsNode {\n const owner = createOwner()\n const componentName = (component as typeof component & { displayName?: string }).displayName\n || component.name\n || 'anonymous'\n setOwnerDebugName(owner, source\n ? `${componentName} (${source.file}:${source.line}:${source.column})`\n : componentName)\n owner.onError(reason => {\n attachSourceLocation(reason, source)\n attachComponentContext(reason, componentName, owner.id)\n throw reason\n })\n let node: VobsNode\n try {\n node = owner.run(() => component(props))\n } catch (error) {\n owner.dispose()\n attachSourceLocation(error, source)\n attachComponentContext(error, componentName, owner.id)\n throw error\n }\n associateNodeOwner(node, owner)\n const hmrKey = (component as typeof component & { hmrKey?: string }).hmrKey\n if (hmrKey) {\n const instance: HmrInstance = {\n node,\n parent: null,\n refresh(): void {\n const previous = instance.node\n const next = owner.run(() => component(props))\n if (instance.parent && !isVobsFragment(previous) && !isVobsFragment(next)) {\n getRenderer().insertBefore(instance.parent, next, previous)\n getRenderer().removeChild(instance.parent, previous)\n }\n nodeOwners.delete(previous as object)\n nodeOwners.set(next as object, owner)\n associateHmrInstance(next, instance)\n instance.node = next\n }\n }\n associateHmrInstance(node, instance)\n const separator = hmrKey.lastIndexOf(':')\n const moduleId = separator < 0 ? hmrKey : hmrKey.slice(0, separator)\n const cleanup = registerHmrInstance(moduleId, instance)\n owner.onDispose(cleanup)\n }\n return node\n}\n\nexport interface VobsSourceLocation {\n readonly file: string\n readonly line: number\n readonly column: number\n}\n\nexport interface VobsLocatedError extends Error {\n readonly vobsSource?: VobsSourceLocation\n readonly vobsComponent?: string\n readonly vobsOwnerId?: string\n}\n\nfunction attachSourceLocation(reason: unknown, source: VobsSourceLocation | undefined): void {\n if (!source || (!reason || (typeof reason !== 'object' && typeof reason !== 'function'))) return\n const error = reason as VobsLocatedError\n if (error.vobsSource) return\n try {\n Object.defineProperty(error, 'vobsSource', {\n configurable: true,\n enumerable: false,\n value: source,\n writable: false\n })\n } catch {\n // Frozen third-party errors still propagate with their original details.\n }\n}\n\nfunction attachComponentContext(reason: unknown, component: string, ownerId: string): void {\n if (!reason || (typeof reason !== 'object' && typeof reason !== 'function')) return\n const error = reason as VobsLocatedError\n try {\n if (!error.vobsComponent) Object.defineProperty(error, 'vobsComponent', { configurable: true, enumerable: false, value: component, writable: false })\n if (!error.vobsOwnerId) Object.defineProperty(error, 'vobsOwnerId', { configurable: true, enumerable: false, value: ownerId, writable: false })\n } catch {\n // Frozen third-party errors still propagate with their original details.\n }\n}\n\nexport function createBlock(factory: () => VobsNode | null | undefined | false): VobsNode | null {\n const owner = createOwner()\n setOwnerDebugName(owner, 'dynamic')\n let node: VobsNode | null | undefined | false\n try {\n node = owner.run(factory)\n } catch (error) {\n owner.dispose()\n throw error\n }\n if (!node) {\n owner.dispose()\n return null\n }\n associateNodeOwner(node, owner)\n return node\n}\n\nexport function associateNodeOwner(node: VobsNode, owner: Owner): void {\n nodeOwners.set(node, owner)\n}\n\nexport function disposeNodeOwner(node: VobsNode): void {\n const owner = nodeOwners.get(node)\n if (!owner) return\n nodeOwners.delete(node)\n owner.dispose()\n}\n","import { getCurrentOwner } from '@vobs/reactivity'\nimport { createComment, getRenderer } from './ops'\n\nexport interface VobsFragment {\n readonly kind: 'vobs-fragment'\n readonly start: Node\n readonly end: Node\n readonly mount: (parent: Node, anchor: Node | null) => void\n readonly unmount: (parent: Node) => void\n}\n\nexport type VobsNode = Node | VobsFragment\nexport type FragmentFactory = (parent: Node, anchor: Node) => void\n\nexport function createFragment(factory: FragmentFactory): VobsFragment {\n const start = createComment('vobs:fragment:start')\n const end = createComment('vobs:fragment:end')\n let parent: Node | null = null\n let initialized = false\n const owner = getCurrentOwner()\n\n const fragment: VobsFragment = {\n kind: 'vobs-fragment',\n start,\n end,\n mount(nextParent, anchor): void {\n if (parent && parent !== nextParent) {\n throw new Error('Vobs Fragment: 不能跨父节点移动 Fragment')\n }\n\n if (initialized) {\n moveRange(nextParent, start, end, anchor)\n return\n }\n\n const renderer = getRenderer()\n renderer.insertBefore(nextParent, start, anchor)\n renderer.insertBefore(nextParent, end, anchor)\n parent = nextParent\n initialized = true\n if (owner) owner.run(() => factory(nextParent, end))\n else factory(nextParent, end)\n },\n unmount(nextParent): void {\n if (!initialized || parent !== nextParent) {\n throw new Error('Vobs Fragment: Fragment 不属于指定父节点')\n }\n const renderer = getRenderer()\n let current = renderer.nextSibling(start)\n while (current && current !== end) {\n const next = renderer.nextSibling(current)\n renderer.removeChild(nextParent, current)\n current = next\n }\n renderer.removeChild(nextParent, start)\n renderer.removeChild(nextParent, end)\n parent = null\n initialized = false\n }\n }\n return fragment\n}\n\nexport function isVobsFragment(value: unknown): value is VobsFragment {\n return Boolean(value) && typeof value === 'object' && (value as VobsFragment).kind === 'vobs-fragment'\n}\n\nfunction moveRange(parent: Node, start: Node, end: Node, anchor: Node | null): void {\n const renderer = getRenderer()\n const nodes: Node[] = [start]\n let current = renderer.nextSibling(start)\n while (current) {\n nodes.push(current)\n if (current === end) break\n current = renderer.nextSibling(current)\n }\n if (nodes[nodes.length - 1] !== end) {\n throw new Error('Vobs Fragment: 找不到结束锚点')\n }\n for (const node of nodes) renderer.insertBefore(parent, node, anchor)\n}\n","import { getCurrentOwner, type Owner } from '@vobs/reactivity'\nimport type { InjectionKey, ProvideOptions } from './app'\n\nconst ownerProviders = new WeakMap<Owner, Map<InjectionKey<unknown>, unknown>>()\n\nexport function provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: provide 必须在组件或 Owner 作用域内调用')\n provideToOwner(owner, key, value, options)\n}\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T\nexport function inject<T>(key: InjectionKey<T>, fallback?: T): T | undefined {\n const owner = getCurrentOwner()\n const value = owner ? injectFromOwner(owner, key) : undefined\n return value === undefined ? fallback : value\n}\n\nexport function injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = inject(key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n}\n\nexport function provideToOwner<T>(\n owner: Owner,\n key: InjectionKey<T>,\n value: T,\n options: ProvideOptions = {}\n): void {\n let providers = ownerProviders.get(owner)\n if (!providers) {\n providers = new Map<InjectionKey<unknown>, unknown>()\n ownerProviders.set(owner, providers)\n owner.onDispose(() => ownerProviders.delete(owner))\n }\n if (providers.has(key) && !options.override) {\n throw new Error(`Vobs: 注入项 ${String(key)} 已存在;如需覆盖请传入 override: true`)\n }\n providers.set(key, value)\n}\n\nexport function injectFromOwner<T>(owner: Owner, key: InjectionKey<T>): T | undefined {\n let current: Owner | null = owner\n while (current) {\n const providers = ownerProviders.get(current)\n if (providers?.has(key)) return providers.get(key) as T\n current = current.parent\n }\n return undefined\n}\n","import { createOwner, scheduler, setOwnerDebugName, type Owner } from '@vobs/reactivity'\nimport { createDOMRenderer } from '@vobs/dom'\nimport { insertBefore as insertRuntimeNode, setRenderer, type VobsFragment, type VobsRenderer } from '@vobs/runtime'\nimport { injectFromOwner, provideToOwner } from './context'\n\nexport type InjectionKey<T> = symbol & {\n readonly __vobsType?: T\n}\n\nexport interface ProvideOptions {\n override?: boolean\n}\n\nexport interface VobsPlugin {\n name: string\n version?: string\n requires?: readonly VobsPlugin[]\n optional?: readonly VobsPlugin[]\n install?: (ctx: VobsContext) => void | (() => void)\n}\n\nexport interface VobsContext {\n readonly app: VobsApp\n provide<T>(key: InjectionKey<T>, value: T, options?: ProvideOptions): void\n inject<T>(key: InjectionKey<T>): T | undefined\n injectRequired<T>(key: InjectionKey<T>, description?: string): T\n onDestroy(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n}\n\nexport interface VobsConfig<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n> {\n render: () => NodeType | VobsFragment | Node | null | undefined\n renderer?: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n plugins?: VobsPlugin[]\n /** Optional application-level error observer. Observers are isolated from the app. */\n onError?: (error: unknown) => void\n}\n\nexport interface VobsApp<NodeType = Node> {\n readonly mounted: boolean\n readonly destroyed: boolean\n use(plugin: VobsPlugin): VobsApp<NodeType>\n mount(target: string | NodeType): void\n hydrate(target: string | NodeType): void\n update(): void\n destroy(): void\n}\n\nexport function createInjectionKey<T>(description: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>\n}\n\nexport function createVobs(\n config: VobsConfig<Node, Text, Element, Comment>\n): VobsApp<Node>\nexport function createVobs<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n>(\n config: VobsConfig<NodeType, TextNode, ElementNode, CommentNode> & {\n renderer: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n }\n): VobsApp<NodeType>\nexport function createVobs(\n config: VobsConfig<any, any, any, any>\n): VobsApp<any> {\n if (!config.render) throw new Error('createVobs: render 不能为空')\n\n const renderer = config.renderer ?? createDOMRenderer()\n const rootOwner: Owner = createOwner()\n setOwnerDebugName(rootOwner, 'App')\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n const installed = new Set<string>()\n const installing = new Set<string>()\n let mounted = false\n let destroyed = false\n let container: any = null\n let app!: VobsApp<any>\n\n if (config.onError) {\n errorHandlers.add(config.onError)\n cleanups.push(() => errorHandlers.delete(config.onError!))\n }\n\n const context: VobsContext = {\n get app(): VobsApp<any> {\n return app\n },\n\n provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n provideToOwner(rootOwner, key, value, options)\n },\n\n inject<T>(key: InjectionKey<T>): T | undefined {\n return injectFromOwner(rootOwner, key)\n },\n\n injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = injectFromOwner(rootOwner, key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n },\n\n onDestroy(cleanup: () => void): void {\n cleanups.push(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n cleanups.push(remove)\n return remove\n }\n }\n\n function notifyError(error: unknown): void {\n for (const handler of [...errorHandlers]) {\n try {\n handler(error)\n } catch {\n // 错误处理器不能覆盖触发它的原始错误。\n }\n }\n }\n\n function installPlugin(plugin: VobsPlugin): void {\n if (installed.has(plugin.name)) return\n if (installing.has(plugin.name)) {\n throw new Error(`Vobs: 插件依赖存在循环:${plugin.name}`)\n }\n\n installing.add(plugin.name)\n try {\n for (const dependency of plugin.requires ?? []) installPlugin(dependency)\n const cleanup = plugin.install?.(context)\n if (cleanup) cleanups.push(cleanup)\n installed.add(plugin.name)\n } finally {\n installing.delete(plugin.name)\n }\n }\n\n function cleanup(clearContainer = true): unknown {\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n try {\n rootOwner.dispose()\n } catch (error) {\n firstError ??= error\n }\n\n if (container && clearContainer) {\n try {\n renderer.clear(container)\n } catch (error) {\n firstError ??= error\n }\n }\n return firstError\n }\n\n function start(target: string | any, hydrating: boolean): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能挂载')\n if (mounted) return\n\n container = typeof target === 'string' ? document.querySelector(target) : target\n if (!container) throw new Error(`mount: 目标不存在: ${target}`)\n if (hydrating && !renderer.beginHydration) {\n throw new Error('Vobs: 当前渲染器不支持 Hydration')\n }\n\n setRenderer(renderer)\n try {\n if (hydrating) renderer.beginHydration?.()\n const rootNode = rootOwner.run(config.render)\n if (!hydrating) renderer.clear(container)\n if (rootNode) insertRuntimeNode(container, rootNode as any, null)\n if (hydrating) renderer.completeHydration?.()\n mounted = true\n } catch (error) {\n notifyError(error)\n const cleanupError = cleanup(!hydrating)\n destroyed = true\n throw cleanupError ?? error\n }\n }\n\n app = {\n get mounted(): boolean {\n return mounted\n },\n\n get destroyed(): boolean {\n return destroyed\n },\n\n use(plugin: VobsPlugin): VobsApp<any> {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能安装插件')\n installPlugin(plugin)\n return app\n },\n\n mount(target: string | any): void {\n start(target, false)\n },\n\n hydrate(target: string | any): void {\n start(target, true)\n },\n\n update(): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能更新')\n try {\n scheduler.flush()\n } catch (error) {\n notifyError(error)\n throw error\n }\n },\n\n destroy(): void {\n if (destroyed) return\n try {\n const cleanupError = cleanup()\n if (cleanupError) {\n notifyError(cleanupError)\n throw cleanupError\n }\n } finally {\n mounted = false\n destroyed = true\n }\n }\n }\n\n try {\n for (const plugin of config.plugins ?? []) app.use(plugin)\n } catch (error) {\n notifyError(error)\n cleanup()\n destroyed = true\n throw error\n }\n\n return app\n}\n","import { getCurrentOwner, onDispose, state, type Signal } from '@vobs/reactivity'\nimport {\n createFragment,\n createInjectionKey,\n inject,\n insertBefore,\n provide,\n type InjectionKey,\n type VobsNode,\n type VobsPlugin\n} from '@vobs/vobs'\n\nexport type Locale = string\nexport type MessageValue = string | Messages\n\nexport interface Messages {\n readonly [key: string]: MessageValue\n}\n\nexport type LocaleMessages = Readonly<Record<Locale, Messages>>\nexport type DatePreset = 'short' | 'medium' | 'long' | 'full' | 'custom'\nexport type NumberPreset = 'decimal' | 'percent'\nexport type I18nLocaleLoader = () => Promise<Messages>\n\nexport interface I18nDehydratedState {\n readonly version: 1\n readonly locale: Locale\n readonly messages: LocaleMessages\n}\n\nexport type I18nFormatter = (\n value: unknown,\n locale: Locale,\n argument?: string\n) => string\n\nexport interface I18nOptions {\n readonly defaultLocale: Locale\n readonly messages?: LocaleMessages\n readonly localeLoaders?: Readonly<Record<Locale, I18nLocaleLoader>>\n readonly fallbackLocale?: Locale\n readonly timeZone?: string\n readonly formatters?: Record<string, I18nFormatter>\n}\n\nexport interface I18nContext {\n readonly locale: Signal<Locale>\n readonly messages: Signal<LocaleMessages>\n readonly fallbackLocale: Locale | undefined\n readonly timeZone: string | undefined\n dehydrate(): I18nDehydratedState\n hydrate(snapshot: unknown): void\n setLocale(locale: Locale): void\n setMessages(locale: Locale, messages: Messages): void\n loadLocale(locale: Locale, loader?: I18nLocaleLoader): Promise<void>\n isLocaleLoaded(locale: Locale): boolean\n t(key: string, params?: Record<string, unknown>): string\n formatDate(\n value: Date | number,\n presetOrOptions?: DatePreset | Intl.DateTimeFormatOptions,\n options?: Intl.DateTimeFormatOptions\n ): string\n formatNumber(value: number, presetOrOptions?: NumberPreset | Intl.NumberFormatOptions): string\n formatCurrency(\n value: number,\n currency: string,\n options?: Omit<Intl.NumberFormatOptions, 'currency' | 'style'>\n ): string\n formatRelativeTime(value: Date | number, now?: Date | number): string\n registerFormatter(name: string, formatter: I18nFormatter): () => void\n dispose(): void\n}\n\nexport const I18N_KEY: InjectionKey<I18nContext> = createInjectionKey<I18nContext>('vobs.i18n')\n\nexport interface I18nPluginOptions extends Omit<I18nOptions, 'defaultLocale'> {\n readonly defaultLocale?: Locale\n readonly i18n?: I18nContext\n}\n\nexport interface I18nBoundaryProps {\n readonly locale?: Locale\n readonly children?: VobsNode | (() => VobsNode | null | undefined)\n}\n\nconst DATE_PRESETS: Record<Exclude<DatePreset, 'custom'>, Intl.DateTimeFormatOptions> = {\n short: {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit'\n },\n medium: {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n },\n long: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n weekday: 'long'\n },\n full: {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n weekday: 'long',\n hour: '2-digit',\n minute: '2-digit'\n }\n}\n\nexport function createI18n(options: I18nOptions): I18nContext {\n const defaultLocale = validateLocale(options.defaultLocale)\n const fallbackLocale = options.fallbackLocale === undefined\n ? defaultLocale\n : validateLocale(options.fallbackLocale)\n const initialMessages = validateLocaleMessages(options.messages ?? {})\n const locale = state(defaultLocale)\n const messages = state<LocaleMessages>({ ...initialMessages })\n const formatters = new Map<string, I18nFormatter>(Object.entries(options.formatters ?? {}))\n const loadedLocales = new Set(Object.keys(initialMessages))\n const pendingLoads = new Map<string, Promise<void>>()\n let disposed = false\n\n const context: I18nContext = {\n locale,\n messages,\n fallbackLocale,\n timeZone: options.timeZone,\n\n dehydrate(): I18nDehydratedState {\n ensureActive()\n return { version: 1, locale: locale.value, messages: messages.value }\n },\n\n hydrate(snapshot: unknown): void {\n ensureActive()\n const restored = parseDehydratedState(snapshot)\n locale.value = restored.locale\n messages.value = restored.messages\n loadedLocales.clear()\n for (const loadedLocale of Object.keys(restored.messages)) loadedLocales.add(loadedLocale)\n },\n\n setLocale(nextLocale: Locale): void {\n ensureActive()\n locale.value = validateLocale(nextLocale)\n },\n\n setMessages(nextLocale: Locale, nextMessages: Messages): void {\n ensureActive()\n const normalizedLocale = validateLocale(nextLocale)\n const normalizedMessages = validateMessages(nextMessages)\n messages.value = {\n ...messages.value,\n [normalizedLocale]: mergeMessages(messages.value[normalizedLocale], normalizedMessages)\n }\n loadedLocales.add(normalizedLocale)\n },\n\n loadLocale(nextLocale: Locale, loader?: I18nLocaleLoader): Promise<void> {\n ensureActive()\n const normalizedLocale = validateLocale(nextLocale)\n if (loadedLocales.has(normalizedLocale)) return Promise.resolve()\n const pending = pendingLoads.get(normalizedLocale)\n if (pending) return pending\n const source = loader ?? options.localeLoaders?.[normalizedLocale]\n if (!source) return Promise.reject(new Error(`Vobs I18n: locale ${normalizedLocale} 没有可用的 loader`))\n const task = Promise.resolve()\n .then(() => source())\n .then(nextMessages => {\n context.setMessages(normalizedLocale, nextMessages)\n })\n .finally(() => {\n pendingLoads.delete(normalizedLocale)\n })\n pendingLoads.set(normalizedLocale, task)\n return task\n },\n\n isLocaleLoaded(nextLocale: Locale): boolean {\n ensureActive()\n return loadedLocales.has(validateLocale(nextLocale))\n },\n\n t(key: string, params?: Record<string, unknown>): string {\n ensureActive()\n if (!key) return ''\n const allMessages = messages.value\n const template = findMessage(allMessages, locale.value, fallbackLocale, key)\n if (template === undefined) return key\n return interpolate(template, params, context, formatters)\n },\n\n formatDate(value, presetOrOptions, dateOptions): string {\n ensureActive()\n const date = toDate(value)\n if (!date) return ''\n const resolvedOptions = resolveDateOptions(presetOrOptions, dateOptions)\n return new Intl.DateTimeFormat(locale.value, withTimeZone(resolvedOptions, options.timeZone)).format(date)\n },\n\n formatNumber(value, presetOrOptions): string {\n ensureActive()\n if (!Number.isFinite(value)) return ''\n const numberOptions = typeof presetOrOptions === 'string'\n ? presetOrOptions === 'percent' ? { style: 'percent' as const } : {}\n : presetOrOptions\n return new Intl.NumberFormat(locale.value, numberOptions).format(value)\n },\n\n formatCurrency(value, currency, currencyOptions): string {\n ensureActive()\n if (!Number.isFinite(value)) return ''\n if (!currency) throw new Error('Vobs I18n: currency 不能为空')\n return new Intl.NumberFormat(locale.value, {\n ...currencyOptions,\n style: 'currency',\n currency\n }).format(value)\n },\n\n formatRelativeTime(value, now = Date.now()): string {\n ensureActive()\n const target = toDate(value)?.getTime()\n const current = toDate(now)?.getTime()\n if (target === undefined || current === undefined) return ''\n const difference = current - target\n const units = [\n ['year', 365 * 24 * 60 * 60 * 1000],\n ['month', 30 * 24 * 60 * 60 * 1000],\n ['day', 24 * 60 * 60 * 1000],\n ['hour', 60 * 60 * 1000],\n ['minute', 60 * 1000],\n ['second', 1000]\n ] as const\n for (const [unit, milliseconds] of units) {\n const amount = Math.round(difference / milliseconds)\n if (Math.abs(amount) >= 1) {\n return new Intl.RelativeTimeFormat(locale.value, { numeric: 'auto' })\n .format(-amount, unit)\n }\n }\n return new Intl.RelativeTimeFormat(locale.value, { numeric: 'auto' }).format(0, 'second')\n },\n\n registerFormatter(name: string, formatter: I18nFormatter): () => void {\n ensureActive()\n if (!name) throw new Error('Vobs I18n: formatter 名称不能为空')\n const previous = formatters.get(name)\n formatters.set(name, formatter)\n return () => {\n if (previous) formatters.set(name, previous)\n else formatters.delete(name)\n }\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n locale.dispose()\n messages.dispose()\n formatters.clear()\n pendingLoads.clear()\n }\n }\n\n if (getCurrentOwner()) onDispose(context.dispose)\n return context\n\n function ensureActive(): void {\n if (disposed) throw new Error('Vobs I18n: 已销毁的上下文不能继续使用')\n }\n}\n\nfunction parseDehydratedState(snapshot: unknown): I18nDehydratedState {\n let value: unknown = snapshot\n if (typeof snapshot === 'string') {\n try {\n value = JSON.parse(snapshot)\n } catch {\n throw new Error('Vobs I18n: 初始状态不是有效 JSON')\n }\n }\n if (!value || typeof value !== 'object') throw new Error('Vobs I18n: 初始状态格式无效')\n const candidate = value as Partial<I18nDehydratedState>\n if (candidate.version !== 1 || typeof candidate.locale !== 'string'\n || !candidate.messages || typeof candidate.messages !== 'object') {\n throw new Error('Vobs I18n: 初始状态版本或字段无效')\n }\n return {\n version: 1,\n locale: validateLocale(candidate.locale),\n messages: validateLocaleMessages(candidate.messages)\n }\n}\n\nexport function i18nPlugin(options: I18nPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/i18n',\n version: '0.1.0',\n install(context) {\n const ownedI18n = options.i18n ? undefined : createI18n({\n defaultLocale: options.defaultLocale ?? 'en-US',\n messages: options.messages,\n localeLoaders: options.localeLoaders,\n fallbackLocale: options.fallbackLocale,\n timeZone: options.timeZone,\n formatters: options.formatters\n })\n const i18n = options.i18n ?? ownedI18n!\n context.provide(I18N_KEY, i18n)\n return () => ownedI18n?.dispose()\n }\n }\n}\n\nexport function useI18n(): I18nContext {\n const i18n = inject(I18N_KEY)\n if (!i18n) throw new Error('Vobs I18n: 找不到上下文,请安装 i18nPlugin')\n return i18n\n}\n\nexport function I18nBoundary(props: I18nBoundaryProps = {}): VobsNode {\n const parent = useI18n()\n const local = createI18n({\n defaultLocale: props.locale ?? parent.locale.value,\n messages: parent.messages.value,\n fallbackLocale: parent.fallbackLocale,\n timeZone: parent.timeZone\n })\n provide(I18N_KEY, local)\n\n return createFragment((parentNode, anchor) => {\n const child = typeof props.children === 'function' ? props.children() : props.children\n if (child) insertBefore(parentNode, child, anchor)\n })\n}\n\nfunction findMessage(\n allMessages: LocaleMessages,\n locale: Locale,\n fallbackLocale: Locale | undefined,\n key: string\n): string | undefined {\n const locales = unique([\n locale,\n locale.split('-')[0],\n fallbackLocale,\n fallbackLocale?.split('-')[0]\n ])\n for (const candidate of locales) {\n const message = getMessage(allMessages[candidate], key)\n if (message !== undefined) return message\n }\n return undefined\n}\n\nfunction getMessage(messages: Messages | undefined, key: string): string | undefined {\n if (!messages) return undefined\n const direct = messages[key]\n if (typeof direct === 'string') return direct\n\n let current: MessageValue | undefined = messages\n for (const segment of key.split('.')) {\n if (!isMessages(current)) return undefined\n current = current[segment]\n }\n return typeof current === 'string' ? current : undefined\n}\n\nfunction interpolate(\n template: string,\n params: Record<string, unknown> | undefined,\n context: I18nContext,\n formatters: Map<string, I18nFormatter>\n): string {\n if (!params) return template\n return template.replace(/\\{([\\w.-]+)(?:,\\s*([\\w-]+)(?:,\\s*([^}]+))?)?\\}/g,\n (match, key: string, formatter?: string, argument?: string) => {\n if (!(key in params)) return match\n const value = params[key]\n if (!formatter) return String(value)\n if (formatter === 'date') return context.formatDate(toDate(value) ?? Number.NaN, argument as DatePreset | undefined)\n if (formatter === 'number') return context.formatNumber(Number(value))\n if (formatter === 'currency') return context.formatCurrency(Number(value), argument ?? 'USD')\n if (formatter === 'relativeTime') return context.formatRelativeTime(toDate(value) ?? Number.NaN)\n const custom = formatters.get(formatter)\n return custom ? custom(value, context.locale.value, argument) : String(value)\n })\n}\n\nfunction toDate(value: Date | number | unknown): Date | undefined {\n const date = value instanceof Date ? new Date(value.getTime()) : typeof value === 'number' ? new Date(value) : undefined\n return date && Number.isFinite(date.getTime()) ? date : undefined\n}\n\nfunction resolveDateOptions(\n presetOrOptions: DatePreset | Intl.DateTimeFormatOptions | undefined,\n options: Intl.DateTimeFormatOptions | undefined\n): Intl.DateTimeFormatOptions {\n if (presetOrOptions === undefined) return DATE_PRESETS.medium\n if (typeof presetOrOptions === 'object') return presetOrOptions\n if (presetOrOptions === 'custom') return options ?? {}\n return { ...DATE_PRESETS[presetOrOptions], ...options }\n}\n\nfunction withTimeZone(options: Intl.DateTimeFormatOptions, timeZone: string | undefined): Intl.DateTimeFormatOptions {\n return timeZone && options.timeZone === undefined ? { ...options, timeZone } : options\n}\n\nfunction validateLocale(locale: Locale): Locale {\n if (typeof locale !== 'string' || !locale.trim()) throw new Error('Vobs I18n: locale 不能为空')\n return locale\n}\n\nfunction validateMessages(value: Messages): Messages {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('Vobs I18n: messages 必须是对象')\n }\n for (const [key, message] of Object.entries(value)) {\n if (typeof message === 'string') continue\n if (!message || typeof message !== 'object' || Array.isArray(message)) {\n throw new Error(`Vobs I18n: 翻译字段 ${key} 的值无效`)\n }\n validateMessages(message)\n }\n return value\n}\n\nfunction validateLocaleMessages(value: LocaleMessages): LocaleMessages {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('Vobs I18n: locale messages 必须是对象')\n }\n for (const [locale, messages] of Object.entries(value)) {\n validateLocale(locale)\n validateMessages(messages)\n }\n return value\n}\n\nfunction mergeMessages(parent: Messages | undefined, next: Messages): Messages {\n const merged: Record<string, MessageValue> = { ...(parent ?? {}) }\n for (const [key, value] of Object.entries(next)) {\n const previous = merged[key]\n merged[key] = typeof value === 'object' && typeof previous === 'object'\n ? mergeMessages(previous, value)\n : value\n }\n return merged\n}\n\nfunction isMessages(value: MessageValue | undefined): value is Messages {\n return Boolean(value) && typeof value === 'object'\n}\n\nfunction unique(values: Array<string | undefined>): string[] {\n return [...new Set(values.filter((value): value is string => value !== undefined))]\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Signal } from '@vobs/reactivity';
|
|
2
|
+
import { InjectionKey, VobsNode, VobsPlugin } from '@vobs/vobs';
|
|
3
|
+
|
|
4
|
+
type Locale = string;
|
|
5
|
+
type MessageValue = string | Messages;
|
|
6
|
+
interface Messages {
|
|
7
|
+
readonly [key: string]: MessageValue;
|
|
8
|
+
}
|
|
9
|
+
type LocaleMessages = Readonly<Record<Locale, Messages>>;
|
|
10
|
+
type DatePreset = 'short' | 'medium' | 'long' | 'full' | 'custom';
|
|
11
|
+
type NumberPreset = 'decimal' | 'percent';
|
|
12
|
+
type I18nLocaleLoader = () => Promise<Messages>;
|
|
13
|
+
interface I18nDehydratedState {
|
|
14
|
+
readonly version: 1;
|
|
15
|
+
readonly locale: Locale;
|
|
16
|
+
readonly messages: LocaleMessages;
|
|
17
|
+
}
|
|
18
|
+
type I18nFormatter = (value: unknown, locale: Locale, argument?: string) => string;
|
|
19
|
+
interface I18nOptions {
|
|
20
|
+
readonly defaultLocale: Locale;
|
|
21
|
+
readonly messages?: LocaleMessages;
|
|
22
|
+
readonly localeLoaders?: Readonly<Record<Locale, I18nLocaleLoader>>;
|
|
23
|
+
readonly fallbackLocale?: Locale;
|
|
24
|
+
readonly timeZone?: string;
|
|
25
|
+
readonly formatters?: Record<string, I18nFormatter>;
|
|
26
|
+
}
|
|
27
|
+
interface I18nContext {
|
|
28
|
+
readonly locale: Signal<Locale>;
|
|
29
|
+
readonly messages: Signal<LocaleMessages>;
|
|
30
|
+
readonly fallbackLocale: Locale | undefined;
|
|
31
|
+
readonly timeZone: string | undefined;
|
|
32
|
+
dehydrate(): I18nDehydratedState;
|
|
33
|
+
hydrate(snapshot: unknown): void;
|
|
34
|
+
setLocale(locale: Locale): void;
|
|
35
|
+
setMessages(locale: Locale, messages: Messages): void;
|
|
36
|
+
loadLocale(locale: Locale, loader?: I18nLocaleLoader): Promise<void>;
|
|
37
|
+
isLocaleLoaded(locale: Locale): boolean;
|
|
38
|
+
t(key: string, params?: Record<string, unknown>): string;
|
|
39
|
+
formatDate(value: Date | number, presetOrOptions?: DatePreset | Intl.DateTimeFormatOptions, options?: Intl.DateTimeFormatOptions): string;
|
|
40
|
+
formatNumber(value: number, presetOrOptions?: NumberPreset | Intl.NumberFormatOptions): string;
|
|
41
|
+
formatCurrency(value: number, currency: string, options?: Omit<Intl.NumberFormatOptions, 'currency' | 'style'>): string;
|
|
42
|
+
formatRelativeTime(value: Date | number, now?: Date | number): string;
|
|
43
|
+
registerFormatter(name: string, formatter: I18nFormatter): () => void;
|
|
44
|
+
dispose(): void;
|
|
45
|
+
}
|
|
46
|
+
declare const I18N_KEY: InjectionKey<I18nContext>;
|
|
47
|
+
interface I18nPluginOptions extends Omit<I18nOptions, 'defaultLocale'> {
|
|
48
|
+
readonly defaultLocale?: Locale;
|
|
49
|
+
readonly i18n?: I18nContext;
|
|
50
|
+
}
|
|
51
|
+
interface I18nBoundaryProps {
|
|
52
|
+
readonly locale?: Locale;
|
|
53
|
+
readonly children?: VobsNode | (() => VobsNode | null | undefined);
|
|
54
|
+
}
|
|
55
|
+
declare function createI18n(options: I18nOptions): I18nContext;
|
|
56
|
+
declare function i18nPlugin(options?: I18nPluginOptions): VobsPlugin;
|
|
57
|
+
declare function useI18n(): I18nContext;
|
|
58
|
+
declare function I18nBoundary(props?: I18nBoundaryProps): VobsNode;
|
|
59
|
+
|
|
60
|
+
export { type DatePreset, I18N_KEY, I18nBoundary, type I18nBoundaryProps, type I18nContext, type I18nDehydratedState, type I18nFormatter, type I18nLocaleLoader, type I18nOptions, type I18nPluginOptions, type Locale, type LocaleMessages, type MessageValue, type Messages, type NumberPreset, createI18n, i18nPlugin, useI18n };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Signal } from '@vobs/reactivity';
|
|
2
|
+
import { InjectionKey, VobsNode, VobsPlugin } from '@vobs/vobs';
|
|
3
|
+
|
|
4
|
+
type Locale = string;
|
|
5
|
+
type MessageValue = string | Messages;
|
|
6
|
+
interface Messages {
|
|
7
|
+
readonly [key: string]: MessageValue;
|
|
8
|
+
}
|
|
9
|
+
type LocaleMessages = Readonly<Record<Locale, Messages>>;
|
|
10
|
+
type DatePreset = 'short' | 'medium' | 'long' | 'full' | 'custom';
|
|
11
|
+
type NumberPreset = 'decimal' | 'percent';
|
|
12
|
+
type I18nLocaleLoader = () => Promise<Messages>;
|
|
13
|
+
interface I18nDehydratedState {
|
|
14
|
+
readonly version: 1;
|
|
15
|
+
readonly locale: Locale;
|
|
16
|
+
readonly messages: LocaleMessages;
|
|
17
|
+
}
|
|
18
|
+
type I18nFormatter = (value: unknown, locale: Locale, argument?: string) => string;
|
|
19
|
+
interface I18nOptions {
|
|
20
|
+
readonly defaultLocale: Locale;
|
|
21
|
+
readonly messages?: LocaleMessages;
|
|
22
|
+
readonly localeLoaders?: Readonly<Record<Locale, I18nLocaleLoader>>;
|
|
23
|
+
readonly fallbackLocale?: Locale;
|
|
24
|
+
readonly timeZone?: string;
|
|
25
|
+
readonly formatters?: Record<string, I18nFormatter>;
|
|
26
|
+
}
|
|
27
|
+
interface I18nContext {
|
|
28
|
+
readonly locale: Signal<Locale>;
|
|
29
|
+
readonly messages: Signal<LocaleMessages>;
|
|
30
|
+
readonly fallbackLocale: Locale | undefined;
|
|
31
|
+
readonly timeZone: string | undefined;
|
|
32
|
+
dehydrate(): I18nDehydratedState;
|
|
33
|
+
hydrate(snapshot: unknown): void;
|
|
34
|
+
setLocale(locale: Locale): void;
|
|
35
|
+
setMessages(locale: Locale, messages: Messages): void;
|
|
36
|
+
loadLocale(locale: Locale, loader?: I18nLocaleLoader): Promise<void>;
|
|
37
|
+
isLocaleLoaded(locale: Locale): boolean;
|
|
38
|
+
t(key: string, params?: Record<string, unknown>): string;
|
|
39
|
+
formatDate(value: Date | number, presetOrOptions?: DatePreset | Intl.DateTimeFormatOptions, options?: Intl.DateTimeFormatOptions): string;
|
|
40
|
+
formatNumber(value: number, presetOrOptions?: NumberPreset | Intl.NumberFormatOptions): string;
|
|
41
|
+
formatCurrency(value: number, currency: string, options?: Omit<Intl.NumberFormatOptions, 'currency' | 'style'>): string;
|
|
42
|
+
formatRelativeTime(value: Date | number, now?: Date | number): string;
|
|
43
|
+
registerFormatter(name: string, formatter: I18nFormatter): () => void;
|
|
44
|
+
dispose(): void;
|
|
45
|
+
}
|
|
46
|
+
declare const I18N_KEY: InjectionKey<I18nContext>;
|
|
47
|
+
interface I18nPluginOptions extends Omit<I18nOptions, 'defaultLocale'> {
|
|
48
|
+
readonly defaultLocale?: Locale;
|
|
49
|
+
readonly i18n?: I18nContext;
|
|
50
|
+
}
|
|
51
|
+
interface I18nBoundaryProps {
|
|
52
|
+
readonly locale?: Locale;
|
|
53
|
+
readonly children?: VobsNode | (() => VobsNode | null | undefined);
|
|
54
|
+
}
|
|
55
|
+
declare function createI18n(options: I18nOptions): I18nContext;
|
|
56
|
+
declare function i18nPlugin(options?: I18nPluginOptions): VobsPlugin;
|
|
57
|
+
declare function useI18n(): I18nContext;
|
|
58
|
+
declare function I18nBoundary(props?: I18nBoundaryProps): VobsNode;
|
|
59
|
+
|
|
60
|
+
export { type DatePreset, I18N_KEY, I18nBoundary, type I18nBoundaryProps, type I18nContext, type I18nDehydratedState, type I18nFormatter, type I18nLocaleLoader, type I18nOptions, type I18nPluginOptions, type Locale, type LocaleMessages, type MessageValue, type Messages, type NumberPreset, createI18n, i18nPlugin, useI18n };
|