@lytjs/common-vnode 6.5.0 → 6.6.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.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +338 -338
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["ShapeFlags","PatchFlags"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * @lytjs/common-vnode\r\n * VNode 类型定义与常量\r\n */\r\n\r\n// ============================================================\r\n// VNode 类型 Symbol\r\n// ============================================================\r\n\r\nexport const Fragment = Symbol.for('Fragment');\r\nexport const Text = Symbol.for('Text');\r\nexport const Comment = Symbol.for('Comment');\r\n\r\n// ============================================================\r\n// ShapeFlags - VNode 形状标志\r\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\r\n// ============================================================\r\n\r\nexport enum ShapeFlags {\r\n /** HTML 元素或 SVG 元素 */\r\n ELEMENT = 1,\r\n /** 函数式组件 */\r\n FUNCTIONAL_COMPONENT = 1 << 1,\r\n /** 有状态组件 */\r\n STATEFUL_COMPONENT = 1 << 2,\r\n /** 子节点是文本 */\r\n TEXT_CHILDREN = 1 << 3,\r\n /** 子节点是数组 */\r\n ARRAY_CHILDREN = 1 << 4,\r\n /** 子节点是插槽 */\r\n SLOTS_CHILDREN = 1 << 5,\r\n /** Suspense 组件 */\r\n SUSPENSE = 1 << 6,\r\n /** Teleport 组件 */\r\n TELEPORT = 1 << 7,\r\n /** 组件应该被 keep-alive */\r\n COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,\r\n /** 组件已被 keep-alive */\r\n COMPONENT_KEPT_ALIVE = 1 << 9,\r\n}\r\n\r\n// ============================================================\r\n// PatchFlags - 补丁标志\r\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\r\n// ============================================================\r\n\r\nexport enum PatchFlags {\r\n /** 动态文本内容 */\r\n TEXT = 1,\r\n /** 动态 class */\r\n CLASS = 1 << 1,\r\n /** 动态 style */\r\n STYLE = 1 << 2,\r\n /** 动态 props(非 class 和 style) */\r\n PROPS = 1 << 3,\r\n /** 有动态的 key 的 props,需要完整 diff */\r\n FULL_PROPS = 1 << 4,\r\n /** 有事件监听器 */\r\n HYDRATE_EVENTS = 1 << 5,\r\n /** 子节点顺序不会改变,是稳定的 fragment */\r\n STABLE_FRAGMENT = 1 << 6,\r\n /** 子节点带有 key 的 fragment */\r\n KEYED_FRAGMENT = 1 << 7,\r\n /** 子节点没有 key 的 fragment */\r\n UNKEYED_FRAGMENT = 1 << 8,\r\n /** 非 props 的 patch,如 ref 或 directives */\r\n NEED_PATCH = 1 << 9,\r\n /** 动态插槽 */\r\n DYNAMIC_SLOTS = 1 << 10,\r\n /** Block 节点具有 dynamicChildren,patch 时应优先遍历 dynamicChildren */\r\n DYNAMIC_CHILDREN = 1 << 11,\r\n /** 静态节点,可提升 */\r\n HOISTED = -1,\r\n /** 指示 diff 算法应退出优化模式 */\r\n BAIL = -2,\r\n}\r\n\r\n// ============================================================\r\n// VNode 类型定义\r\n// ============================================================\r\n\r\nexport type VNodeTypes = string | typeof Fragment | typeof Text | typeof Comment | object; // Component\r\n\r\nexport type VNodeChildren =\r\n | string\r\n | number\r\n | boolean\r\n | null\r\n | undefined\r\n | VNode[]\r\n | { [key: string]: VNode[] };\r\n\r\nexport interface VNodeSourceLocation {\r\n start: { line: number; column: number; offset: number };\r\n end: { line: number; column: number; offset: number };\r\n source: string;\r\n}\r\n\r\nexport interface VNodeData {\r\n [key: string]: unknown;\r\n}\r\n\r\nexport interface VNode {\r\n /** VNode 类型 */\r\n type: VNodeTypes;\r\n /** VNode 的 key */\r\n key: string | number | symbol | null | undefined;\r\n /** ref 引用 */\r\n ref: ((ref: unknown) => void) | null;\r\n /** VNode 的 props(可选,直接存储在 VNode 上) */\r\n props: Record<string, unknown> | null;\r\n /** 是否为静态提升 */\r\n isStatic: boolean;\r\n /** 是否为静态根节点 */\r\n isStaticRoot: boolean;\r\n /** 是否为 once 渲染 */\r\n isOnce: boolean;\r\n /** 是否为异步占位 */\r\n isAsyncPlaceholder: boolean;\r\n /** 是否为注释节点 */\r\n isComment: boolean;\r\n /** 是否为克隆节点 */\r\n isCloned: boolean;\r\n /** 是否为块级元素 */\r\n isBlockTree: boolean;\r\n /** 形状标志 */\r\n shapeFlag: number;\r\n /** 补丁标志 */\r\n patchFlag: number;\r\n /** 动态 props */\r\n dynamicProps: string[] | null;\r\n /** 动态子节点 */\r\n dynamicChildren: VNode[] | null;\r\n /** 子节点 */\r\n children: VNodeChildren;\r\n /** 组件实例 */\r\n component: ComponentInternalInstance | null;\r\n /** 挂载的 DOM 元素 */\r\n el: Node | null;\r\n /** 锚点元素 */\r\n anchor: Node | null;\r\n /** 目标元素(Teleport) */\r\n target: Element | null;\r\n /** 目标锚点(Teleport) */\r\n targetAnchor: Node | null;\r\n /** 目标起始位置(Teleport) */\r\n targetStart: Node | null;\r\n /** Suspense 边界 */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n suspense?: any;\r\n /** 源码位置 */\r\n loc: VNodeSourceLocation | null;\r\n /** 内部标记 */\r\n __v_isVNode: true;\r\n}\r\n\r\n/**\r\n * 组件公共实例接口\r\n * @internal 此接口的权威来源为 @lytjs/shared-types/src/component.ts。\r\n * 此处保留仅为避免循环依赖,新代码请从 @lytjs/shared-types 导入。\r\n */\r\nexport interface ComponentPublicInstance {\r\n $props: Record<string, unknown>;\r\n $attrs: Record<string, unknown>;\r\n $refs: Record<string, unknown>;\r\n $slots: Record<string, unknown>;\r\n $emit: (event: string, ...args: unknown[]) => void;\r\n $el: Element | ComponentPublicInstance | null;\r\n $forceUpdate: () => void;\r\n $nextTick: (fn?: () => void) => Promise<void>;\r\n}\r\n\r\n/**\r\n * 组件内部实例接口\r\n * @internal 此接口的权威来源为 @lytjs/component/src/types.ts。\r\n * 此处保留简化版定义以避免循环依赖,新代码请从 @lytjs/component 导入。\r\n */\r\nexport interface ComponentInternalInstance {\r\n uid: number;\r\n type: VNodeTypes;\r\n parent: ComponentInternalInstance | null;\r\n root: ComponentInternalInstance;\r\n vnode: VNode;\r\n subTree: VNode;\r\n props: Record<string, unknown>;\r\n attrs: Record<string, unknown>;\r\n slots: Record<string, unknown>;\r\n refs: Record<string, unknown>;\r\n setupState: Record<string, unknown>;\r\n data: Record<string, unknown>;\r\n ctx: Record<string, unknown>;\r\n emit: (event: string, ...args: unknown[]) => void;\r\n isMounted: boolean;\r\n isUnmounted: boolean;\r\n isDeactivated: boolean;\r\n isKeepingAlive: boolean;\r\n bum?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n bm?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n m?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n bu?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n u?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n um?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n uc?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n effects?: Array<{ stop: () => void }>;\r\n update?: () => void;\r\n}\r\n\r\nexport interface BaseComponentOptions {\r\n props?: Record<string, unknown>;\r\n emits?: string[] | Record<string, unknown>;\r\n setup?: (...args: unknown[]) => Record<string, unknown>;\r\n render?: (...args: unknown[]) => unknown;\r\n computed?: Record<string, () => unknown>;\r\n methods?: Record<string, (...args: unknown[]) => unknown>;\r\n watch?: Record<string, unknown>;\r\n data?: () => Record<string, unknown>;\r\n}\r\n\r\n// ============================================================\r\n// VNode 默认值与工厂函数\r\n// ============================================================\r\n\r\n/**\r\n * VNode 默认值常量\r\n * 包含所有 VNode 字段的默认值,用于 createBaseVNode 工厂函数\r\n */\r\nexport const VNODE_DEFAULTS: VNode = {\r\n type: null as unknown as VNode['type'],\r\n key: null,\r\n ref: null,\r\n props: null,\r\n isStatic: false,\r\n isStaticRoot: false,\r\n isOnce: false,\r\n isAsyncPlaceholder: false,\r\n isComment: false,\r\n isCloned: false,\r\n isBlockTree: false,\r\n shapeFlag: 0,\r\n patchFlag: 0,\r\n dynamicProps: null,\r\n dynamicChildren: null,\r\n children: null,\r\n component: null,\r\n el: null,\r\n anchor: null,\r\n target: null,\r\n targetAnchor: null,\r\n targetStart: null,\r\n suspense: null,\r\n loc: null,\r\n __v_isVNode: true,\r\n};\r\n\r\n/**\r\n * 创建基础 VNode,使用默认值填充未指定的字段\r\n * @param overrides 需要覆盖的 VNode 字段\r\n * @returns 完整的 VNode 对象\r\n */\r\nexport function createBaseVNode(overrides: Partial<VNode>): VNode {\r\n return { ...VNODE_DEFAULTS, ...overrides } as VNode;\r\n}\r\n\r\n// ============================================================\r\n// VNode 工具函数\r\n// ============================================================\r\n\r\n/**\r\n * 检查是否为 Fragment VNode\r\n */\r\nexport function isVNode(value: unknown): value is VNode {\r\n return (\r\n value !== null &&\r\n typeof value === 'object' &&\r\n (value as Record<string, unknown>).__v_isVNode === true\r\n );\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否为 Fragment 类型\r\n */\r\nexport function isFragment(vnode: VNode): boolean {\r\n return vnode.type === Fragment;\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否为 Text 类型\r\n */\r\nexport function isTextVNode(vnode: VNode): boolean {\r\n return vnode.type === Text;\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否为 Comment 类型\r\n */\r\nexport function isCommentVNode(vnode: VNode): boolean {\r\n return vnode.type === Comment;\r\n}\r\n\r\n/**\r\n * 检查两个 VNode 是否类型相同\r\n */\r\nexport function isSameVNodeType(n1: VNode, n2: VNode): boolean {\r\n return n1.type === n2.type && n1.key === n2.key;\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否包含指定的 patch flag\r\n */\r\nexport function hasPatchFlag(vnode: VNode, flag: number): boolean {\r\n const pf = vnode.patchFlag;\r\n if (pf === -1 /* HOISTED */ || pf === -2 /* BAIL */) return true;\r\n return (pf & flag) !== 0;\r\n}\r\n\r\n/**\r\n * 描述 patch flag 的含义\r\n */\r\nexport function describePatchFlag(flag: number): string {\r\n const names: string[] = [];\r\n\r\n if (flag === PatchFlags.HOISTED) return 'HOISTED';\r\n if (flag === PatchFlags.BAIL) return 'BAIL';\r\n\r\n if (flag & PatchFlags.TEXT) names.push('TEXT');\r\n if (flag & PatchFlags.CLASS) names.push('CLASS');\r\n if (flag & PatchFlags.STYLE) names.push('STYLE');\r\n if (flag & PatchFlags.PROPS) names.push('PROPS');\r\n if (flag & PatchFlags.FULL_PROPS) names.push('FULL_PROPS');\r\n if (flag & PatchFlags.HYDRATE_EVENTS) names.push('HYDRATE_EVENTS');\r\n if (flag & PatchFlags.STABLE_FRAGMENT) names.push('STABLE_FRAGMENT');\r\n if (flag & PatchFlags.KEYED_FRAGMENT) names.push('KEYED_FRAGMENT');\r\n if (flag & PatchFlags.UNKEYED_FRAGMENT) names.push('UNKEYED_FRAGMENT');\r\n if (flag & PatchFlags.NEED_PATCH) names.push('NEED_PATCH');\r\n if (flag & PatchFlags.DYNAMIC_SLOTS) names.push('DYNAMIC_SLOTS');\r\n\r\n return names.join(' | ') || 'NO_FLAGS';\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["ShapeFlags","PatchFlags"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @lytjs/common-vnode\n * VNode 类型定义与常量\n */\n\n// ============================================================\n// VNode 类型 Symbol\n// ============================================================\n\nexport const Fragment = Symbol.for('Fragment');\nexport const Text = Symbol.for('Text');\nexport const Comment = Symbol.for('Comment');\n\n// ============================================================\n// ShapeFlags - VNode 形状标志\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\n// ============================================================\n\nexport enum ShapeFlags {\n /** HTML 元素或 SVG 元素 */\n ELEMENT = 1,\n /** 函数式组件 */\n FUNCTIONAL_COMPONENT = 1 << 1,\n /** 有状态组件 */\n STATEFUL_COMPONENT = 1 << 2,\n /** 子节点是文本 */\n TEXT_CHILDREN = 1 << 3,\n /** 子节点是数组 */\n ARRAY_CHILDREN = 1 << 4,\n /** 子节点是插槽 */\n SLOTS_CHILDREN = 1 << 5,\n /** Suspense 组件 */\n SUSPENSE = 1 << 6,\n /** Teleport 组件 */\n TELEPORT = 1 << 7,\n /** 组件应该被 keep-alive */\n COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,\n /** 组件已被 keep-alive */\n COMPONENT_KEPT_ALIVE = 1 << 9,\n}\n\n// ============================================================\n// PatchFlags - 补丁标志\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\n// ============================================================\n\nexport enum PatchFlags {\n /** 动态文本内容 */\n TEXT = 1,\n /** 动态 class */\n CLASS = 1 << 1,\n /** 动态 style */\n STYLE = 1 << 2,\n /** 动态 props(非 class 和 style) */\n PROPS = 1 << 3,\n /** 有动态的 key 的 props,需要完整 diff */\n FULL_PROPS = 1 << 4,\n /** 有事件监听器 */\n HYDRATE_EVENTS = 1 << 5,\n /** 子节点顺序不会改变,是稳定的 fragment */\n STABLE_FRAGMENT = 1 << 6,\n /** 子节点带有 key 的 fragment */\n KEYED_FRAGMENT = 1 << 7,\n /** 子节点没有 key 的 fragment */\n UNKEYED_FRAGMENT = 1 << 8,\n /** 非 props 的 patch,如 ref 或 directives */\n NEED_PATCH = 1 << 9,\n /** 动态插槽 */\n DYNAMIC_SLOTS = 1 << 10,\n /** Block 节点具有 dynamicChildren,patch 时应优先遍历 dynamicChildren */\n DYNAMIC_CHILDREN = 1 << 11,\n /** 静态节点,可提升 */\n HOISTED = -1,\n /** 指示 diff 算法应退出优化模式 */\n BAIL = -2,\n}\n\n// ============================================================\n// VNode 类型定义\n// ============================================================\n\nexport type VNodeTypes = string | typeof Fragment | typeof Text | typeof Comment | object; // Component\n\nexport type VNodeChildren =\n | string\n | number\n | boolean\n | null\n | undefined\n | VNode[]\n | { [key: string]: VNode[] };\n\nexport interface VNodeSourceLocation {\n start: { line: number; column: number; offset: number };\n end: { line: number; column: number; offset: number };\n source: string;\n}\n\nexport interface VNodeData {\n [key: string]: unknown;\n}\n\nexport interface VNode {\n /** VNode 类型 */\n type: VNodeTypes;\n /** VNode 的 key */\n key: string | number | symbol | null | undefined;\n /** ref 引用 */\n ref: ((ref: unknown) => void) | null;\n /** VNode 的 props(可选,直接存储在 VNode 上) */\n props: Record<string, unknown> | null;\n /** 是否为静态提升 */\n isStatic: boolean;\n /** 是否为静态根节点 */\n isStaticRoot: boolean;\n /** 是否为 once 渲染 */\n isOnce: boolean;\n /** 是否为异步占位 */\n isAsyncPlaceholder: boolean;\n /** 是否为注释节点 */\n isComment: boolean;\n /** 是否为克隆节点 */\n isCloned: boolean;\n /** 是否为块级元素 */\n isBlockTree: boolean;\n /** 形状标志 */\n shapeFlag: number;\n /** 补丁标志 */\n patchFlag: number;\n /** 动态 props */\n dynamicProps: string[] | null;\n /** 动态子节点 */\n dynamicChildren: VNode[] | null;\n /** 子节点 */\n children: VNodeChildren;\n /** 组件实例 */\n component: ComponentInternalInstance | null;\n /** 挂载的 DOM 元素 */\n el: Node | null;\n /** 锚点元素 */\n anchor: Node | null;\n /** 目标元素(Teleport) */\n target: Element | null;\n /** 目标锚点(Teleport) */\n targetAnchor: Node | null;\n /** 目标起始位置(Teleport) */\n targetStart: Node | null;\n /** Suspense 边界 */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n suspense?: any;\n /** 源码位置 */\n loc: VNodeSourceLocation | null;\n /** 内部标记 */\n __v_isVNode: true;\n}\n\n/**\n * 组件公共实例接口\n * @internal 此接口的权威来源为 @lytjs/shared-types/src/component.ts。\n * 此处保留仅为避免循环依赖,新代码请从 @lytjs/shared-types 导入。\n */\nexport interface ComponentPublicInstance {\n $props: Record<string, unknown>;\n $attrs: Record<string, unknown>;\n $refs: Record<string, unknown>;\n $slots: Record<string, unknown>;\n $emit: (event: string, ...args: unknown[]) => void;\n $el: Element | ComponentPublicInstance | null;\n $forceUpdate: () => void;\n $nextTick: (fn?: () => void) => Promise<void>;\n}\n\n/**\n * 组件内部实例接口\n * @internal 此接口的权威来源为 @lytjs/component/src/types.ts。\n * 此处保留简化版定义以避免循环依赖,新代码请从 @lytjs/component 导入。\n */\nexport interface ComponentInternalInstance {\n uid: number;\n type: VNodeTypes;\n parent: ComponentInternalInstance | null;\n root: ComponentInternalInstance;\n vnode: VNode;\n subTree: VNode;\n props: Record<string, unknown>;\n attrs: Record<string, unknown>;\n slots: Record<string, unknown>;\n refs: Record<string, unknown>;\n setupState: Record<string, unknown>;\n data: Record<string, unknown>;\n ctx: Record<string, unknown>;\n emit: (event: string, ...args: unknown[]) => void;\n isMounted: boolean;\n isUnmounted: boolean;\n isDeactivated: boolean;\n isKeepingAlive: boolean;\n bum?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n bm?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n m?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n bu?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n u?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n um?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n uc?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n effects?: Array<{ stop: () => void }>;\n update?: () => void;\n}\n\nexport interface BaseComponentOptions {\n props?: Record<string, unknown>;\n emits?: string[] | Record<string, unknown>;\n setup?: (...args: unknown[]) => Record<string, unknown>;\n render?: (...args: unknown[]) => unknown;\n computed?: Record<string, () => unknown>;\n methods?: Record<string, (...args: unknown[]) => unknown>;\n watch?: Record<string, unknown>;\n data?: () => Record<string, unknown>;\n}\n\n// ============================================================\n// VNode 默认值与工厂函数\n// ============================================================\n\n/**\n * VNode 默认值常量\n * 包含所有 VNode 字段的默认值,用于 createBaseVNode 工厂函数\n */\nexport const VNODE_DEFAULTS: VNode = {\n type: null as unknown as VNode['type'],\n key: null,\n ref: null,\n props: null,\n isStatic: false,\n isStaticRoot: false,\n isOnce: false,\n isAsyncPlaceholder: false,\n isComment: false,\n isCloned: false,\n isBlockTree: false,\n shapeFlag: 0,\n patchFlag: 0,\n dynamicProps: null,\n dynamicChildren: null,\n children: null,\n component: null,\n el: null,\n anchor: null,\n target: null,\n targetAnchor: null,\n targetStart: null,\n suspense: null,\n loc: null,\n __v_isVNode: true,\n};\n\n/**\n * 创建基础 VNode,使用默认值填充未指定的字段\n * @param overrides 需要覆盖的 VNode 字段\n * @returns 完整的 VNode 对象\n */\nexport function createBaseVNode(overrides: Partial<VNode>): VNode {\n return { ...VNODE_DEFAULTS, ...overrides } as VNode;\n}\n\n// ============================================================\n// VNode 工具函数\n// ============================================================\n\n/**\n * 检查是否为 Fragment VNode\n */\nexport function isVNode(value: unknown): value is VNode {\n return (\n value !== null &&\n typeof value === 'object' &&\n (value as Record<string, unknown>).__v_isVNode === true\n );\n}\n\n/**\n * 检查 VNode 是否为 Fragment 类型\n */\nexport function isFragment(vnode: VNode): boolean {\n return vnode.type === Fragment;\n}\n\n/**\n * 检查 VNode 是否为 Text 类型\n */\nexport function isTextVNode(vnode: VNode): boolean {\n return vnode.type === Text;\n}\n\n/**\n * 检查 VNode 是否为 Comment 类型\n */\nexport function isCommentVNode(vnode: VNode): boolean {\n return vnode.type === Comment;\n}\n\n/**\n * 检查两个 VNode 是否类型相同\n */\nexport function isSameVNodeType(n1: VNode, n2: VNode): boolean {\n return n1.type === n2.type && n1.key === n2.key;\n}\n\n/**\n * 检查 VNode 是否包含指定的 patch flag\n */\nexport function hasPatchFlag(vnode: VNode, flag: number): boolean {\n const pf = vnode.patchFlag;\n if (pf === -1 /* HOISTED */ || pf === -2 /* BAIL */) return true;\n return (pf & flag) !== 0;\n}\n\n/**\n * 描述 patch flag 的含义\n */\nexport function describePatchFlag(flag: number): string {\n const names: string[] = [];\n\n if (flag === PatchFlags.HOISTED) return 'HOISTED';\n if (flag === PatchFlags.BAIL) return 'BAIL';\n\n if (flag & PatchFlags.TEXT) names.push('TEXT');\n if (flag & PatchFlags.CLASS) names.push('CLASS');\n if (flag & PatchFlags.STYLE) names.push('STYLE');\n if (flag & PatchFlags.PROPS) names.push('PROPS');\n if (flag & PatchFlags.FULL_PROPS) names.push('FULL_PROPS');\n if (flag & PatchFlags.HYDRATE_EVENTS) names.push('HYDRATE_EVENTS');\n if (flag & PatchFlags.STABLE_FRAGMENT) names.push('STABLE_FRAGMENT');\n if (flag & PatchFlags.KEYED_FRAGMENT) names.push('KEYED_FRAGMENT');\n if (flag & PatchFlags.UNKEYED_FRAGMENT) names.push('UNKEYED_FRAGMENT');\n if (flag & PatchFlags.NEED_PATCH) names.push('NEED_PATCH');\n if (flag & PatchFlags.DYNAMIC_SLOTS) names.push('DYNAMIC_SLOTS');\n\n return names.join(' | ') || 'NO_FLAGS';\n}\n"]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["ShapeFlags","PatchFlags"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\r\n * @lytjs/common-vnode\r\n * VNode 类型定义与常量\r\n */\r\n\r\n// ============================================================\r\n// VNode 类型 Symbol\r\n// ============================================================\r\n\r\nexport const Fragment = Symbol.for('Fragment');\r\nexport const Text = Symbol.for('Text');\r\nexport const Comment = Symbol.for('Comment');\r\n\r\n// ============================================================\r\n// ShapeFlags - VNode 形状标志\r\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\r\n// ============================================================\r\n\r\nexport enum ShapeFlags {\r\n /** HTML 元素或 SVG 元素 */\r\n ELEMENT = 1,\r\n /** 函数式组件 */\r\n FUNCTIONAL_COMPONENT = 1 << 1,\r\n /** 有状态组件 */\r\n STATEFUL_COMPONENT = 1 << 2,\r\n /** 子节点是文本 */\r\n TEXT_CHILDREN = 1 << 3,\r\n /** 子节点是数组 */\r\n ARRAY_CHILDREN = 1 << 4,\r\n /** 子节点是插槽 */\r\n SLOTS_CHILDREN = 1 << 5,\r\n /** Suspense 组件 */\r\n SUSPENSE = 1 << 6,\r\n /** Teleport 组件 */\r\n TELEPORT = 1 << 7,\r\n /** 组件应该被 keep-alive */\r\n COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,\r\n /** 组件已被 keep-alive */\r\n COMPONENT_KEPT_ALIVE = 1 << 9,\r\n}\r\n\r\n// ============================================================\r\n// PatchFlags - 补丁标志\r\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\r\n// ============================================================\r\n\r\nexport enum PatchFlags {\r\n /** 动态文本内容 */\r\n TEXT = 1,\r\n /** 动态 class */\r\n CLASS = 1 << 1,\r\n /** 动态 style */\r\n STYLE = 1 << 2,\r\n /** 动态 props(非 class 和 style) */\r\n PROPS = 1 << 3,\r\n /** 有动态的 key 的 props,需要完整 diff */\r\n FULL_PROPS = 1 << 4,\r\n /** 有事件监听器 */\r\n HYDRATE_EVENTS = 1 << 5,\r\n /** 子节点顺序不会改变,是稳定的 fragment */\r\n STABLE_FRAGMENT = 1 << 6,\r\n /** 子节点带有 key 的 fragment */\r\n KEYED_FRAGMENT = 1 << 7,\r\n /** 子节点没有 key 的 fragment */\r\n UNKEYED_FRAGMENT = 1 << 8,\r\n /** 非 props 的 patch,如 ref 或 directives */\r\n NEED_PATCH = 1 << 9,\r\n /** 动态插槽 */\r\n DYNAMIC_SLOTS = 1 << 10,\r\n /** Block 节点具有 dynamicChildren,patch 时应优先遍历 dynamicChildren */\r\n DYNAMIC_CHILDREN = 1 << 11,\r\n /** 静态节点,可提升 */\r\n HOISTED = -1,\r\n /** 指示 diff 算法应退出优化模式 */\r\n BAIL = -2,\r\n}\r\n\r\n// ============================================================\r\n// VNode 类型定义\r\n// ============================================================\r\n\r\nexport type VNodeTypes = string | typeof Fragment | typeof Text | typeof Comment | object; // Component\r\n\r\nexport type VNodeChildren =\r\n | string\r\n | number\r\n | boolean\r\n | null\r\n | undefined\r\n | VNode[]\r\n | { [key: string]: VNode[] };\r\n\r\nexport interface VNodeSourceLocation {\r\n start: { line: number; column: number; offset: number };\r\n end: { line: number; column: number; offset: number };\r\n source: string;\r\n}\r\n\r\nexport interface VNodeData {\r\n [key: string]: unknown;\r\n}\r\n\r\nexport interface VNode {\r\n /** VNode 类型 */\r\n type: VNodeTypes;\r\n /** VNode 的 key */\r\n key: string | number | symbol | null | undefined;\r\n /** ref 引用 */\r\n ref: ((ref: unknown) => void) | null;\r\n /** VNode 的 props(可选,直接存储在 VNode 上) */\r\n props: Record<string, unknown> | null;\r\n /** 是否为静态提升 */\r\n isStatic: boolean;\r\n /** 是否为静态根节点 */\r\n isStaticRoot: boolean;\r\n /** 是否为 once 渲染 */\r\n isOnce: boolean;\r\n /** 是否为异步占位 */\r\n isAsyncPlaceholder: boolean;\r\n /** 是否为注释节点 */\r\n isComment: boolean;\r\n /** 是否为克隆节点 */\r\n isCloned: boolean;\r\n /** 是否为块级元素 */\r\n isBlockTree: boolean;\r\n /** 形状标志 */\r\n shapeFlag: number;\r\n /** 补丁标志 */\r\n patchFlag: number;\r\n /** 动态 props */\r\n dynamicProps: string[] | null;\r\n /** 动态子节点 */\r\n dynamicChildren: VNode[] | null;\r\n /** 子节点 */\r\n children: VNodeChildren;\r\n /** 组件实例 */\r\n component: ComponentInternalInstance | null;\r\n /** 挂载的 DOM 元素 */\r\n el: Node | null;\r\n /** 锚点元素 */\r\n anchor: Node | null;\r\n /** 目标元素(Teleport) */\r\n target: Element | null;\r\n /** 目标锚点(Teleport) */\r\n targetAnchor: Node | null;\r\n /** 目标起始位置(Teleport) */\r\n targetStart: Node | null;\r\n /** Suspense 边界 */\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n suspense?: any;\r\n /** 源码位置 */\r\n loc: VNodeSourceLocation | null;\r\n /** 内部标记 */\r\n __v_isVNode: true;\r\n}\r\n\r\n/**\r\n * 组件公共实例接口\r\n * @internal 此接口的权威来源为 @lytjs/shared-types/src/component.ts。\r\n * 此处保留仅为避免循环依赖,新代码请从 @lytjs/shared-types 导入。\r\n */\r\nexport interface ComponentPublicInstance {\r\n $props: Record<string, unknown>;\r\n $attrs: Record<string, unknown>;\r\n $refs: Record<string, unknown>;\r\n $slots: Record<string, unknown>;\r\n $emit: (event: string, ...args: unknown[]) => void;\r\n $el: Element | ComponentPublicInstance | null;\r\n $forceUpdate: () => void;\r\n $nextTick: (fn?: () => void) => Promise<void>;\r\n}\r\n\r\n/**\r\n * 组件内部实例接口\r\n * @internal 此接口的权威来源为 @lytjs/component/src/types.ts。\r\n * 此处保留简化版定义以避免循环依赖,新代码请从 @lytjs/component 导入。\r\n */\r\nexport interface ComponentInternalInstance {\r\n uid: number;\r\n type: VNodeTypes;\r\n parent: ComponentInternalInstance | null;\r\n root: ComponentInternalInstance;\r\n vnode: VNode;\r\n subTree: VNode;\r\n props: Record<string, unknown>;\r\n attrs: Record<string, unknown>;\r\n slots: Record<string, unknown>;\r\n refs: Record<string, unknown>;\r\n setupState: Record<string, unknown>;\r\n data: Record<string, unknown>;\r\n ctx: Record<string, unknown>;\r\n emit: (event: string, ...args: unknown[]) => void;\r\n isMounted: boolean;\r\n isUnmounted: boolean;\r\n isDeactivated: boolean;\r\n isKeepingAlive: boolean;\r\n bum?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n bm?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n m?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n bu?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n u?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n um?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n uc?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\r\n effects?: Array<{ stop: () => void }>;\r\n update?: () => void;\r\n}\r\n\r\nexport interface BaseComponentOptions {\r\n props?: Record<string, unknown>;\r\n emits?: string[] | Record<string, unknown>;\r\n setup?: (...args: unknown[]) => Record<string, unknown>;\r\n render?: (...args: unknown[]) => unknown;\r\n computed?: Record<string, () => unknown>;\r\n methods?: Record<string, (...args: unknown[]) => unknown>;\r\n watch?: Record<string, unknown>;\r\n data?: () => Record<string, unknown>;\r\n}\r\n\r\n// ============================================================\r\n// VNode 默认值与工厂函数\r\n// ============================================================\r\n\r\n/**\r\n * VNode 默认值常量\r\n * 包含所有 VNode 字段的默认值,用于 createBaseVNode 工厂函数\r\n */\r\nexport const VNODE_DEFAULTS: VNode = {\r\n type: null as unknown as VNode['type'],\r\n key: null,\r\n ref: null,\r\n props: null,\r\n isStatic: false,\r\n isStaticRoot: false,\r\n isOnce: false,\r\n isAsyncPlaceholder: false,\r\n isComment: false,\r\n isCloned: false,\r\n isBlockTree: false,\r\n shapeFlag: 0,\r\n patchFlag: 0,\r\n dynamicProps: null,\r\n dynamicChildren: null,\r\n children: null,\r\n component: null,\r\n el: null,\r\n anchor: null,\r\n target: null,\r\n targetAnchor: null,\r\n targetStart: null,\r\n suspense: null,\r\n loc: null,\r\n __v_isVNode: true,\r\n};\r\n\r\n/**\r\n * 创建基础 VNode,使用默认值填充未指定的字段\r\n * @param overrides 需要覆盖的 VNode 字段\r\n * @returns 完整的 VNode 对象\r\n */\r\nexport function createBaseVNode(overrides: Partial<VNode>): VNode {\r\n return { ...VNODE_DEFAULTS, ...overrides } as VNode;\r\n}\r\n\r\n// ============================================================\r\n// VNode 工具函数\r\n// ============================================================\r\n\r\n/**\r\n * 检查是否为 Fragment VNode\r\n */\r\nexport function isVNode(value: unknown): value is VNode {\r\n return (\r\n value !== null &&\r\n typeof value === 'object' &&\r\n (value as Record<string, unknown>).__v_isVNode === true\r\n );\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否为 Fragment 类型\r\n */\r\nexport function isFragment(vnode: VNode): boolean {\r\n return vnode.type === Fragment;\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否为 Text 类型\r\n */\r\nexport function isTextVNode(vnode: VNode): boolean {\r\n return vnode.type === Text;\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否为 Comment 类型\r\n */\r\nexport function isCommentVNode(vnode: VNode): boolean {\r\n return vnode.type === Comment;\r\n}\r\n\r\n/**\r\n * 检查两个 VNode 是否类型相同\r\n */\r\nexport function isSameVNodeType(n1: VNode, n2: VNode): boolean {\r\n return n1.type === n2.type && n1.key === n2.key;\r\n}\r\n\r\n/**\r\n * 检查 VNode 是否包含指定的 patch flag\r\n */\r\nexport function hasPatchFlag(vnode: VNode, flag: number): boolean {\r\n const pf = vnode.patchFlag;\r\n if (pf === -1 /* HOISTED */ || pf === -2 /* BAIL */) return true;\r\n return (pf & flag) !== 0;\r\n}\r\n\r\n/**\r\n * 描述 patch flag 的含义\r\n */\r\nexport function describePatchFlag(flag: number): string {\r\n const names: string[] = [];\r\n\r\n if (flag === PatchFlags.HOISTED) return 'HOISTED';\r\n if (flag === PatchFlags.BAIL) return 'BAIL';\r\n\r\n if (flag & PatchFlags.TEXT) names.push('TEXT');\r\n if (flag & PatchFlags.CLASS) names.push('CLASS');\r\n if (flag & PatchFlags.STYLE) names.push('STYLE');\r\n if (flag & PatchFlags.PROPS) names.push('PROPS');\r\n if (flag & PatchFlags.FULL_PROPS) names.push('FULL_PROPS');\r\n if (flag & PatchFlags.HYDRATE_EVENTS) names.push('HYDRATE_EVENTS');\r\n if (flag & PatchFlags.STABLE_FRAGMENT) names.push('STABLE_FRAGMENT');\r\n if (flag & PatchFlags.KEYED_FRAGMENT) names.push('KEYED_FRAGMENT');\r\n if (flag & PatchFlags.UNKEYED_FRAGMENT) names.push('UNKEYED_FRAGMENT');\r\n if (flag & PatchFlags.NEED_PATCH) names.push('NEED_PATCH');\r\n if (flag & PatchFlags.DYNAMIC_SLOTS) names.push('DYNAMIC_SLOTS');\r\n\r\n return names.join(' | ') || 'NO_FLAGS';\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["ShapeFlags","PatchFlags"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @lytjs/common-vnode\n * VNode 类型定义与常量\n */\n\n// ============================================================\n// VNode 类型 Symbol\n// ============================================================\n\nexport const Fragment = Symbol.for('Fragment');\nexport const Text = Symbol.for('Text');\nexport const Comment = Symbol.for('Comment');\n\n// ============================================================\n// ShapeFlags - VNode 形状标志\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\n// ============================================================\n\nexport enum ShapeFlags {\n /** HTML 元素或 SVG 元素 */\n ELEMENT = 1,\n /** 函数式组件 */\n FUNCTIONAL_COMPONENT = 1 << 1,\n /** 有状态组件 */\n STATEFUL_COMPONENT = 1 << 2,\n /** 子节点是文本 */\n TEXT_CHILDREN = 1 << 3,\n /** 子节点是数组 */\n ARRAY_CHILDREN = 1 << 4,\n /** 子节点是插槽 */\n SLOTS_CHILDREN = 1 << 5,\n /** Suspense 组件 */\n SUSPENSE = 1 << 6,\n /** Teleport 组件 */\n TELEPORT = 1 << 7,\n /** 组件应该被 keep-alive */\n COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,\n /** 组件已被 keep-alive */\n COMPONENT_KEPT_ALIVE = 1 << 9,\n}\n\n// ============================================================\n// PatchFlags - 补丁标志\n// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题\n// ============================================================\n\nexport enum PatchFlags {\n /** 动态文本内容 */\n TEXT = 1,\n /** 动态 class */\n CLASS = 1 << 1,\n /** 动态 style */\n STYLE = 1 << 2,\n /** 动态 props(非 class 和 style) */\n PROPS = 1 << 3,\n /** 有动态的 key 的 props,需要完整 diff */\n FULL_PROPS = 1 << 4,\n /** 有事件监听器 */\n HYDRATE_EVENTS = 1 << 5,\n /** 子节点顺序不会改变,是稳定的 fragment */\n STABLE_FRAGMENT = 1 << 6,\n /** 子节点带有 key 的 fragment */\n KEYED_FRAGMENT = 1 << 7,\n /** 子节点没有 key 的 fragment */\n UNKEYED_FRAGMENT = 1 << 8,\n /** 非 props 的 patch,如 ref 或 directives */\n NEED_PATCH = 1 << 9,\n /** 动态插槽 */\n DYNAMIC_SLOTS = 1 << 10,\n /** Block 节点具有 dynamicChildren,patch 时应优先遍历 dynamicChildren */\n DYNAMIC_CHILDREN = 1 << 11,\n /** 静态节点,可提升 */\n HOISTED = -1,\n /** 指示 diff 算法应退出优化模式 */\n BAIL = -2,\n}\n\n// ============================================================\n// VNode 类型定义\n// ============================================================\n\nexport type VNodeTypes = string | typeof Fragment | typeof Text | typeof Comment | object; // Component\n\nexport type VNodeChildren =\n | string\n | number\n | boolean\n | null\n | undefined\n | VNode[]\n | { [key: string]: VNode[] };\n\nexport interface VNodeSourceLocation {\n start: { line: number; column: number; offset: number };\n end: { line: number; column: number; offset: number };\n source: string;\n}\n\nexport interface VNodeData {\n [key: string]: unknown;\n}\n\nexport interface VNode {\n /** VNode 类型 */\n type: VNodeTypes;\n /** VNode 的 key */\n key: string | number | symbol | null | undefined;\n /** ref 引用 */\n ref: ((ref: unknown) => void) | null;\n /** VNode 的 props(可选,直接存储在 VNode 上) */\n props: Record<string, unknown> | null;\n /** 是否为静态提升 */\n isStatic: boolean;\n /** 是否为静态根节点 */\n isStaticRoot: boolean;\n /** 是否为 once 渲染 */\n isOnce: boolean;\n /** 是否为异步占位 */\n isAsyncPlaceholder: boolean;\n /** 是否为注释节点 */\n isComment: boolean;\n /** 是否为克隆节点 */\n isCloned: boolean;\n /** 是否为块级元素 */\n isBlockTree: boolean;\n /** 形状标志 */\n shapeFlag: number;\n /** 补丁标志 */\n patchFlag: number;\n /** 动态 props */\n dynamicProps: string[] | null;\n /** 动态子节点 */\n dynamicChildren: VNode[] | null;\n /** 子节点 */\n children: VNodeChildren;\n /** 组件实例 */\n component: ComponentInternalInstance | null;\n /** 挂载的 DOM 元素 */\n el: Node | null;\n /** 锚点元素 */\n anchor: Node | null;\n /** 目标元素(Teleport) */\n target: Element | null;\n /** 目标锚点(Teleport) */\n targetAnchor: Node | null;\n /** 目标起始位置(Teleport) */\n targetStart: Node | null;\n /** Suspense 边界 */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n suspense?: any;\n /** 源码位置 */\n loc: VNodeSourceLocation | null;\n /** 内部标记 */\n __v_isVNode: true;\n}\n\n/**\n * 组件公共实例接口\n * @internal 此接口的权威来源为 @lytjs/shared-types/src/component.ts。\n * 此处保留仅为避免循环依赖,新代码请从 @lytjs/shared-types 导入。\n */\nexport interface ComponentPublicInstance {\n $props: Record<string, unknown>;\n $attrs: Record<string, unknown>;\n $refs: Record<string, unknown>;\n $slots: Record<string, unknown>;\n $emit: (event: string, ...args: unknown[]) => void;\n $el: Element | ComponentPublicInstance | null;\n $forceUpdate: () => void;\n $nextTick: (fn?: () => void) => Promise<void>;\n}\n\n/**\n * 组件内部实例接口\n * @internal 此接口的权威来源为 @lytjs/component/src/types.ts。\n * 此处保留简化版定义以避免循环依赖,新代码请从 @lytjs/component 导入。\n */\nexport interface ComponentInternalInstance {\n uid: number;\n type: VNodeTypes;\n parent: ComponentInternalInstance | null;\n root: ComponentInternalInstance;\n vnode: VNode;\n subTree: VNode;\n props: Record<string, unknown>;\n attrs: Record<string, unknown>;\n slots: Record<string, unknown>;\n refs: Record<string, unknown>;\n setupState: Record<string, unknown>;\n data: Record<string, unknown>;\n ctx: Record<string, unknown>;\n emit: (event: string, ...args: unknown[]) => void;\n isMounted: boolean;\n isUnmounted: boolean;\n isDeactivated: boolean;\n isKeepingAlive: boolean;\n bum?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n bm?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n m?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n bu?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n u?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n um?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n uc?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;\n effects?: Array<{ stop: () => void }>;\n update?: () => void;\n}\n\nexport interface BaseComponentOptions {\n props?: Record<string, unknown>;\n emits?: string[] | Record<string, unknown>;\n setup?: (...args: unknown[]) => Record<string, unknown>;\n render?: (...args: unknown[]) => unknown;\n computed?: Record<string, () => unknown>;\n methods?: Record<string, (...args: unknown[]) => unknown>;\n watch?: Record<string, unknown>;\n data?: () => Record<string, unknown>;\n}\n\n// ============================================================\n// VNode 默认值与工厂函数\n// ============================================================\n\n/**\n * VNode 默认值常量\n * 包含所有 VNode 字段的默认值,用于 createBaseVNode 工厂函数\n */\nexport const VNODE_DEFAULTS: VNode = {\n type: null as unknown as VNode['type'],\n key: null,\n ref: null,\n props: null,\n isStatic: false,\n isStaticRoot: false,\n isOnce: false,\n isAsyncPlaceholder: false,\n isComment: false,\n isCloned: false,\n isBlockTree: false,\n shapeFlag: 0,\n patchFlag: 0,\n dynamicProps: null,\n dynamicChildren: null,\n children: null,\n component: null,\n el: null,\n anchor: null,\n target: null,\n targetAnchor: null,\n targetStart: null,\n suspense: null,\n loc: null,\n __v_isVNode: true,\n};\n\n/**\n * 创建基础 VNode,使用默认值填充未指定的字段\n * @param overrides 需要覆盖的 VNode 字段\n * @returns 完整的 VNode 对象\n */\nexport function createBaseVNode(overrides: Partial<VNode>): VNode {\n return { ...VNODE_DEFAULTS, ...overrides } as VNode;\n}\n\n// ============================================================\n// VNode 工具函数\n// ============================================================\n\n/**\n * 检查是否为 Fragment VNode\n */\nexport function isVNode(value: unknown): value is VNode {\n return (\n value !== null &&\n typeof value === 'object' &&\n (value as Record<string, unknown>).__v_isVNode === true\n );\n}\n\n/**\n * 检查 VNode 是否为 Fragment 类型\n */\nexport function isFragment(vnode: VNode): boolean {\n return vnode.type === Fragment;\n}\n\n/**\n * 检查 VNode 是否为 Text 类型\n */\nexport function isTextVNode(vnode: VNode): boolean {\n return vnode.type === Text;\n}\n\n/**\n * 检查 VNode 是否为 Comment 类型\n */\nexport function isCommentVNode(vnode: VNode): boolean {\n return vnode.type === Comment;\n}\n\n/**\n * 检查两个 VNode 是否类型相同\n */\nexport function isSameVNodeType(n1: VNode, n2: VNode): boolean {\n return n1.type === n2.type && n1.key === n2.key;\n}\n\n/**\n * 检查 VNode 是否包含指定的 patch flag\n */\nexport function hasPatchFlag(vnode: VNode, flag: number): boolean {\n const pf = vnode.patchFlag;\n if (pf === -1 /* HOISTED */ || pf === -2 /* BAIL */) return true;\n return (pf & flag) !== 0;\n}\n\n/**\n * 描述 patch flag 的含义\n */\nexport function describePatchFlag(flag: number): string {\n const names: string[] = [];\n\n if (flag === PatchFlags.HOISTED) return 'HOISTED';\n if (flag === PatchFlags.BAIL) return 'BAIL';\n\n if (flag & PatchFlags.TEXT) names.push('TEXT');\n if (flag & PatchFlags.CLASS) names.push('CLASS');\n if (flag & PatchFlags.STYLE) names.push('STYLE');\n if (flag & PatchFlags.PROPS) names.push('PROPS');\n if (flag & PatchFlags.FULL_PROPS) names.push('FULL_PROPS');\n if (flag & PatchFlags.HYDRATE_EVENTS) names.push('HYDRATE_EVENTS');\n if (flag & PatchFlags.STABLE_FRAGMENT) names.push('STABLE_FRAGMENT');\n if (flag & PatchFlags.KEYED_FRAGMENT) names.push('KEYED_FRAGMENT');\n if (flag & PatchFlags.UNKEYED_FRAGMENT) names.push('UNKEYED_FRAGMENT');\n if (flag & PatchFlags.NEED_PATCH) names.push('NEED_PATCH');\n if (flag & PatchFlags.DYNAMIC_SLOTS) names.push('DYNAMIC_SLOTS');\n\n return names.join(' | ') || 'NO_FLAGS';\n}\n"]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,338 +1,338 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @lytjs/common-vnode
|
|
3
|
-
* VNode 类型定义与常量
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// ============================================================
|
|
7
|
-
// VNode 类型 Symbol
|
|
8
|
-
// ============================================================
|
|
9
|
-
|
|
10
|
-
export const Fragment = Symbol.for('Fragment');
|
|
11
|
-
export const Text = Symbol.for('Text');
|
|
12
|
-
export const Comment = Symbol.for('Comment');
|
|
13
|
-
|
|
14
|
-
// ============================================================
|
|
15
|
-
// ShapeFlags - VNode 形状标志
|
|
16
|
-
// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题
|
|
17
|
-
// ============================================================
|
|
18
|
-
|
|
19
|
-
export enum ShapeFlags {
|
|
20
|
-
/** HTML 元素或 SVG 元素 */
|
|
21
|
-
ELEMENT = 1,
|
|
22
|
-
/** 函数式组件 */
|
|
23
|
-
FUNCTIONAL_COMPONENT = 1 << 1,
|
|
24
|
-
/** 有状态组件 */
|
|
25
|
-
STATEFUL_COMPONENT = 1 << 2,
|
|
26
|
-
/** 子节点是文本 */
|
|
27
|
-
TEXT_CHILDREN = 1 << 3,
|
|
28
|
-
/** 子节点是数组 */
|
|
29
|
-
ARRAY_CHILDREN = 1 << 4,
|
|
30
|
-
/** 子节点是插槽 */
|
|
31
|
-
SLOTS_CHILDREN = 1 << 5,
|
|
32
|
-
/** Suspense 组件 */
|
|
33
|
-
SUSPENSE = 1 << 6,
|
|
34
|
-
/** Teleport 组件 */
|
|
35
|
-
TELEPORT = 1 << 7,
|
|
36
|
-
/** 组件应该被 keep-alive */
|
|
37
|
-
COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,
|
|
38
|
-
/** 组件已被 keep-alive */
|
|
39
|
-
COMPONENT_KEPT_ALIVE = 1 << 9,
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// ============================================================
|
|
43
|
-
// PatchFlags - 补丁标志
|
|
44
|
-
// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题
|
|
45
|
-
// ============================================================
|
|
46
|
-
|
|
47
|
-
export enum PatchFlags {
|
|
48
|
-
/** 动态文本内容 */
|
|
49
|
-
TEXT = 1,
|
|
50
|
-
/** 动态 class */
|
|
51
|
-
CLASS = 1 << 1,
|
|
52
|
-
/** 动态 style */
|
|
53
|
-
STYLE = 1 << 2,
|
|
54
|
-
/** 动态 props(非 class 和 style) */
|
|
55
|
-
PROPS = 1 << 3,
|
|
56
|
-
/** 有动态的 key 的 props,需要完整 diff */
|
|
57
|
-
FULL_PROPS = 1 << 4,
|
|
58
|
-
/** 有事件监听器 */
|
|
59
|
-
HYDRATE_EVENTS = 1 << 5,
|
|
60
|
-
/** 子节点顺序不会改变,是稳定的 fragment */
|
|
61
|
-
STABLE_FRAGMENT = 1 << 6,
|
|
62
|
-
/** 子节点带有 key 的 fragment */
|
|
63
|
-
KEYED_FRAGMENT = 1 << 7,
|
|
64
|
-
/** 子节点没有 key 的 fragment */
|
|
65
|
-
UNKEYED_FRAGMENT = 1 << 8,
|
|
66
|
-
/** 非 props 的 patch,如 ref 或 directives */
|
|
67
|
-
NEED_PATCH = 1 << 9,
|
|
68
|
-
/** 动态插槽 */
|
|
69
|
-
DYNAMIC_SLOTS = 1 << 10,
|
|
70
|
-
/** Block 节点具有 dynamicChildren,patch 时应优先遍历 dynamicChildren */
|
|
71
|
-
DYNAMIC_CHILDREN = 1 << 11,
|
|
72
|
-
/** 静态节点,可提升 */
|
|
73
|
-
HOISTED = -1,
|
|
74
|
-
/** 指示 diff 算法应退出优化模式 */
|
|
75
|
-
BAIL = -2,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// ============================================================
|
|
79
|
-
// VNode 类型定义
|
|
80
|
-
// ============================================================
|
|
81
|
-
|
|
82
|
-
export type VNodeTypes = string | typeof Fragment | typeof Text | typeof Comment | object; // Component
|
|
83
|
-
|
|
84
|
-
export type VNodeChildren =
|
|
85
|
-
| string
|
|
86
|
-
| number
|
|
87
|
-
| boolean
|
|
88
|
-
| null
|
|
89
|
-
| undefined
|
|
90
|
-
| VNode[]
|
|
91
|
-
| { [key: string]: VNode[] };
|
|
92
|
-
|
|
93
|
-
export interface VNodeSourceLocation {
|
|
94
|
-
start: { line: number; column: number; offset: number };
|
|
95
|
-
end: { line: number; column: number; offset: number };
|
|
96
|
-
source: string;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface VNodeData {
|
|
100
|
-
[key: string]: unknown;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export interface VNode {
|
|
104
|
-
/** VNode 类型 */
|
|
105
|
-
type: VNodeTypes;
|
|
106
|
-
/** VNode 的 key */
|
|
107
|
-
key: string | number | symbol | null | undefined;
|
|
108
|
-
/** ref 引用 */
|
|
109
|
-
ref: ((ref: unknown) => void) | null;
|
|
110
|
-
/** VNode 的 props(可选,直接存储在 VNode 上) */
|
|
111
|
-
props: Record<string, unknown> | null;
|
|
112
|
-
/** 是否为静态提升 */
|
|
113
|
-
isStatic: boolean;
|
|
114
|
-
/** 是否为静态根节点 */
|
|
115
|
-
isStaticRoot: boolean;
|
|
116
|
-
/** 是否为 once 渲染 */
|
|
117
|
-
isOnce: boolean;
|
|
118
|
-
/** 是否为异步占位 */
|
|
119
|
-
isAsyncPlaceholder: boolean;
|
|
120
|
-
/** 是否为注释节点 */
|
|
121
|
-
isComment: boolean;
|
|
122
|
-
/** 是否为克隆节点 */
|
|
123
|
-
isCloned: boolean;
|
|
124
|
-
/** 是否为块级元素 */
|
|
125
|
-
isBlockTree: boolean;
|
|
126
|
-
/** 形状标志 */
|
|
127
|
-
shapeFlag: number;
|
|
128
|
-
/** 补丁标志 */
|
|
129
|
-
patchFlag: number;
|
|
130
|
-
/** 动态 props */
|
|
131
|
-
dynamicProps: string[] | null;
|
|
132
|
-
/** 动态子节点 */
|
|
133
|
-
dynamicChildren: VNode[] | null;
|
|
134
|
-
/** 子节点 */
|
|
135
|
-
children: VNodeChildren;
|
|
136
|
-
/** 组件实例 */
|
|
137
|
-
component: ComponentInternalInstance | null;
|
|
138
|
-
/** 挂载的 DOM 元素 */
|
|
139
|
-
el: Node | null;
|
|
140
|
-
/** 锚点元素 */
|
|
141
|
-
anchor: Node | null;
|
|
142
|
-
/** 目标元素(Teleport) */
|
|
143
|
-
target: Element | null;
|
|
144
|
-
/** 目标锚点(Teleport) */
|
|
145
|
-
targetAnchor: Node | null;
|
|
146
|
-
/** 目标起始位置(Teleport) */
|
|
147
|
-
targetStart: Node | null;
|
|
148
|
-
/** Suspense 边界 */
|
|
149
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
-
suspense?: any;
|
|
151
|
-
/** 源码位置 */
|
|
152
|
-
loc: VNodeSourceLocation | null;
|
|
153
|
-
/** 内部标记 */
|
|
154
|
-
__v_isVNode: true;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* 组件公共实例接口
|
|
159
|
-
* @internal 此接口的权威来源为 @lytjs/shared-types/src/component.ts。
|
|
160
|
-
* 此处保留仅为避免循环依赖,新代码请从 @lytjs/shared-types 导入。
|
|
161
|
-
*/
|
|
162
|
-
export interface ComponentPublicInstance {
|
|
163
|
-
$props: Record<string, unknown>;
|
|
164
|
-
$attrs: Record<string, unknown>;
|
|
165
|
-
$refs: Record<string, unknown>;
|
|
166
|
-
$slots: Record<string, unknown>;
|
|
167
|
-
$emit: (event: string, ...args: unknown[]) => void;
|
|
168
|
-
$el: Element | ComponentPublicInstance | null;
|
|
169
|
-
$forceUpdate: () => void;
|
|
170
|
-
$nextTick: (fn?: () => void) => Promise<void>;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* 组件内部实例接口
|
|
175
|
-
* @internal 此接口的权威来源为 @lytjs/component/src/types.ts。
|
|
176
|
-
* 此处保留简化版定义以避免循环依赖,新代码请从 @lytjs/component 导入。
|
|
177
|
-
*/
|
|
178
|
-
export interface ComponentInternalInstance {
|
|
179
|
-
uid: number;
|
|
180
|
-
type: VNodeTypes;
|
|
181
|
-
parent: ComponentInternalInstance | null;
|
|
182
|
-
root: ComponentInternalInstance;
|
|
183
|
-
vnode: VNode;
|
|
184
|
-
subTree: VNode;
|
|
185
|
-
props: Record<string, unknown>;
|
|
186
|
-
attrs: Record<string, unknown>;
|
|
187
|
-
slots: Record<string, unknown>;
|
|
188
|
-
refs: Record<string, unknown>;
|
|
189
|
-
setupState: Record<string, unknown>;
|
|
190
|
-
data: Record<string, unknown>;
|
|
191
|
-
ctx: Record<string, unknown>;
|
|
192
|
-
emit: (event: string, ...args: unknown[]) => void;
|
|
193
|
-
isMounted: boolean;
|
|
194
|
-
isUnmounted: boolean;
|
|
195
|
-
isDeactivated: boolean;
|
|
196
|
-
isKeepingAlive: boolean;
|
|
197
|
-
bum?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
198
|
-
bm?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
199
|
-
m?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
200
|
-
bu?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
201
|
-
u?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
202
|
-
um?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
203
|
-
uc?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
204
|
-
effects?: Array<{ stop: () => void }>;
|
|
205
|
-
update?: () => void;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export interface BaseComponentOptions {
|
|
209
|
-
props?: Record<string, unknown>;
|
|
210
|
-
emits?: string[] | Record<string, unknown>;
|
|
211
|
-
setup?: (...args: unknown[]) => Record<string, unknown>;
|
|
212
|
-
render?: (...args: unknown[]) => unknown;
|
|
213
|
-
computed?: Record<string, () => unknown>;
|
|
214
|
-
methods?: Record<string, (...args: unknown[]) => unknown>;
|
|
215
|
-
watch?: Record<string, unknown>;
|
|
216
|
-
data?: () => Record<string, unknown>;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ============================================================
|
|
220
|
-
// VNode 默认值与工厂函数
|
|
221
|
-
// ============================================================
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* VNode 默认值常量
|
|
225
|
-
* 包含所有 VNode 字段的默认值,用于 createBaseVNode 工厂函数
|
|
226
|
-
*/
|
|
227
|
-
export const VNODE_DEFAULTS: VNode = {
|
|
228
|
-
type: null as unknown as VNode['type'],
|
|
229
|
-
key: null,
|
|
230
|
-
ref: null,
|
|
231
|
-
props: null,
|
|
232
|
-
isStatic: false,
|
|
233
|
-
isStaticRoot: false,
|
|
234
|
-
isOnce: false,
|
|
235
|
-
isAsyncPlaceholder: false,
|
|
236
|
-
isComment: false,
|
|
237
|
-
isCloned: false,
|
|
238
|
-
isBlockTree: false,
|
|
239
|
-
shapeFlag: 0,
|
|
240
|
-
patchFlag: 0,
|
|
241
|
-
dynamicProps: null,
|
|
242
|
-
dynamicChildren: null,
|
|
243
|
-
children: null,
|
|
244
|
-
component: null,
|
|
245
|
-
el: null,
|
|
246
|
-
anchor: null,
|
|
247
|
-
target: null,
|
|
248
|
-
targetAnchor: null,
|
|
249
|
-
targetStart: null,
|
|
250
|
-
suspense: null,
|
|
251
|
-
loc: null,
|
|
252
|
-
__v_isVNode: true,
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* 创建基础 VNode,使用默认值填充未指定的字段
|
|
257
|
-
* @param overrides 需要覆盖的 VNode 字段
|
|
258
|
-
* @returns 完整的 VNode 对象
|
|
259
|
-
*/
|
|
260
|
-
export function createBaseVNode(overrides: Partial<VNode>): VNode {
|
|
261
|
-
return { ...VNODE_DEFAULTS, ...overrides } as VNode;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// ============================================================
|
|
265
|
-
// VNode 工具函数
|
|
266
|
-
// ============================================================
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* 检查是否为 Fragment VNode
|
|
270
|
-
*/
|
|
271
|
-
export function isVNode(value: unknown): value is VNode {
|
|
272
|
-
return (
|
|
273
|
-
value !== null &&
|
|
274
|
-
typeof value === 'object' &&
|
|
275
|
-
(value as Record<string, unknown>).__v_isVNode === true
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* 检查 VNode 是否为 Fragment 类型
|
|
281
|
-
*/
|
|
282
|
-
export function isFragment(vnode: VNode): boolean {
|
|
283
|
-
return vnode.type === Fragment;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* 检查 VNode 是否为 Text 类型
|
|
288
|
-
*/
|
|
289
|
-
export function isTextVNode(vnode: VNode): boolean {
|
|
290
|
-
return vnode.type === Text;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* 检查 VNode 是否为 Comment 类型
|
|
295
|
-
*/
|
|
296
|
-
export function isCommentVNode(vnode: VNode): boolean {
|
|
297
|
-
return vnode.type === Comment;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* 检查两个 VNode 是否类型相同
|
|
302
|
-
*/
|
|
303
|
-
export function isSameVNodeType(n1: VNode, n2: VNode): boolean {
|
|
304
|
-
return n1.type === n2.type && n1.key === n2.key;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* 检查 VNode 是否包含指定的 patch flag
|
|
309
|
-
*/
|
|
310
|
-
export function hasPatchFlag(vnode: VNode, flag: number): boolean {
|
|
311
|
-
const pf = vnode.patchFlag;
|
|
312
|
-
if (pf === -1 /* HOISTED */ || pf === -2 /* BAIL */) return true;
|
|
313
|
-
return (pf & flag) !== 0;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* 描述 patch flag 的含义
|
|
318
|
-
*/
|
|
319
|
-
export function describePatchFlag(flag: number): string {
|
|
320
|
-
const names: string[] = [];
|
|
321
|
-
|
|
322
|
-
if (flag === PatchFlags.HOISTED) return 'HOISTED';
|
|
323
|
-
if (flag === PatchFlags.BAIL) return 'BAIL';
|
|
324
|
-
|
|
325
|
-
if (flag & PatchFlags.TEXT) names.push('TEXT');
|
|
326
|
-
if (flag & PatchFlags.CLASS) names.push('CLASS');
|
|
327
|
-
if (flag & PatchFlags.STYLE) names.push('STYLE');
|
|
328
|
-
if (flag & PatchFlags.PROPS) names.push('PROPS');
|
|
329
|
-
if (flag & PatchFlags.FULL_PROPS) names.push('FULL_PROPS');
|
|
330
|
-
if (flag & PatchFlags.HYDRATE_EVENTS) names.push('HYDRATE_EVENTS');
|
|
331
|
-
if (flag & PatchFlags.STABLE_FRAGMENT) names.push('STABLE_FRAGMENT');
|
|
332
|
-
if (flag & PatchFlags.KEYED_FRAGMENT) names.push('KEYED_FRAGMENT');
|
|
333
|
-
if (flag & PatchFlags.UNKEYED_FRAGMENT) names.push('UNKEYED_FRAGMENT');
|
|
334
|
-
if (flag & PatchFlags.NEED_PATCH) names.push('NEED_PATCH');
|
|
335
|
-
if (flag & PatchFlags.DYNAMIC_SLOTS) names.push('DYNAMIC_SLOTS');
|
|
336
|
-
|
|
337
|
-
return names.join(' | ') || 'NO_FLAGS';
|
|
338
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @lytjs/common-vnode
|
|
3
|
+
* VNode 类型定义与常量
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================
|
|
7
|
+
// VNode 类型 Symbol
|
|
8
|
+
// ============================================================
|
|
9
|
+
|
|
10
|
+
export const Fragment = Symbol.for('Fragment');
|
|
11
|
+
export const Text = Symbol.for('Text');
|
|
12
|
+
export const Comment = Symbol.for('Comment');
|
|
13
|
+
|
|
14
|
+
// ============================================================
|
|
15
|
+
// ShapeFlags - VNode 形状标志
|
|
16
|
+
// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题
|
|
17
|
+
// ============================================================
|
|
18
|
+
|
|
19
|
+
export enum ShapeFlags {
|
|
20
|
+
/** HTML 元素或 SVG 元素 */
|
|
21
|
+
ELEMENT = 1,
|
|
22
|
+
/** 函数式组件 */
|
|
23
|
+
FUNCTIONAL_COMPONENT = 1 << 1,
|
|
24
|
+
/** 有状态组件 */
|
|
25
|
+
STATEFUL_COMPONENT = 1 << 2,
|
|
26
|
+
/** 子节点是文本 */
|
|
27
|
+
TEXT_CHILDREN = 1 << 3,
|
|
28
|
+
/** 子节点是数组 */
|
|
29
|
+
ARRAY_CHILDREN = 1 << 4,
|
|
30
|
+
/** 子节点是插槽 */
|
|
31
|
+
SLOTS_CHILDREN = 1 << 5,
|
|
32
|
+
/** Suspense 组件 */
|
|
33
|
+
SUSPENSE = 1 << 6,
|
|
34
|
+
/** Teleport 组件 */
|
|
35
|
+
TELEPORT = 1 << 7,
|
|
36
|
+
/** 组件应该被 keep-alive */
|
|
37
|
+
COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,
|
|
38
|
+
/** 组件已被 keep-alive */
|
|
39
|
+
COMPONENT_KEPT_ALIVE = 1 << 9,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ============================================================
|
|
43
|
+
// PatchFlags - 补丁标志
|
|
44
|
+
// FIX: 将 const enum 改为普通 enum,解决 verbatimModuleSyntax 问题
|
|
45
|
+
// ============================================================
|
|
46
|
+
|
|
47
|
+
export enum PatchFlags {
|
|
48
|
+
/** 动态文本内容 */
|
|
49
|
+
TEXT = 1,
|
|
50
|
+
/** 动态 class */
|
|
51
|
+
CLASS = 1 << 1,
|
|
52
|
+
/** 动态 style */
|
|
53
|
+
STYLE = 1 << 2,
|
|
54
|
+
/** 动态 props(非 class 和 style) */
|
|
55
|
+
PROPS = 1 << 3,
|
|
56
|
+
/** 有动态的 key 的 props,需要完整 diff */
|
|
57
|
+
FULL_PROPS = 1 << 4,
|
|
58
|
+
/** 有事件监听器 */
|
|
59
|
+
HYDRATE_EVENTS = 1 << 5,
|
|
60
|
+
/** 子节点顺序不会改变,是稳定的 fragment */
|
|
61
|
+
STABLE_FRAGMENT = 1 << 6,
|
|
62
|
+
/** 子节点带有 key 的 fragment */
|
|
63
|
+
KEYED_FRAGMENT = 1 << 7,
|
|
64
|
+
/** 子节点没有 key 的 fragment */
|
|
65
|
+
UNKEYED_FRAGMENT = 1 << 8,
|
|
66
|
+
/** 非 props 的 patch,如 ref 或 directives */
|
|
67
|
+
NEED_PATCH = 1 << 9,
|
|
68
|
+
/** 动态插槽 */
|
|
69
|
+
DYNAMIC_SLOTS = 1 << 10,
|
|
70
|
+
/** Block 节点具有 dynamicChildren,patch 时应优先遍历 dynamicChildren */
|
|
71
|
+
DYNAMIC_CHILDREN = 1 << 11,
|
|
72
|
+
/** 静态节点,可提升 */
|
|
73
|
+
HOISTED = -1,
|
|
74
|
+
/** 指示 diff 算法应退出优化模式 */
|
|
75
|
+
BAIL = -2,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ============================================================
|
|
79
|
+
// VNode 类型定义
|
|
80
|
+
// ============================================================
|
|
81
|
+
|
|
82
|
+
export type VNodeTypes = string | typeof Fragment | typeof Text | typeof Comment | object; // Component
|
|
83
|
+
|
|
84
|
+
export type VNodeChildren =
|
|
85
|
+
| string
|
|
86
|
+
| number
|
|
87
|
+
| boolean
|
|
88
|
+
| null
|
|
89
|
+
| undefined
|
|
90
|
+
| VNode[]
|
|
91
|
+
| { [key: string]: VNode[] };
|
|
92
|
+
|
|
93
|
+
export interface VNodeSourceLocation {
|
|
94
|
+
start: { line: number; column: number; offset: number };
|
|
95
|
+
end: { line: number; column: number; offset: number };
|
|
96
|
+
source: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface VNodeData {
|
|
100
|
+
[key: string]: unknown;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface VNode {
|
|
104
|
+
/** VNode 类型 */
|
|
105
|
+
type: VNodeTypes;
|
|
106
|
+
/** VNode 的 key */
|
|
107
|
+
key: string | number | symbol | null | undefined;
|
|
108
|
+
/** ref 引用 */
|
|
109
|
+
ref: ((ref: unknown) => void) | null;
|
|
110
|
+
/** VNode 的 props(可选,直接存储在 VNode 上) */
|
|
111
|
+
props: Record<string, unknown> | null;
|
|
112
|
+
/** 是否为静态提升 */
|
|
113
|
+
isStatic: boolean;
|
|
114
|
+
/** 是否为静态根节点 */
|
|
115
|
+
isStaticRoot: boolean;
|
|
116
|
+
/** 是否为 once 渲染 */
|
|
117
|
+
isOnce: boolean;
|
|
118
|
+
/** 是否为异步占位 */
|
|
119
|
+
isAsyncPlaceholder: boolean;
|
|
120
|
+
/** 是否为注释节点 */
|
|
121
|
+
isComment: boolean;
|
|
122
|
+
/** 是否为克隆节点 */
|
|
123
|
+
isCloned: boolean;
|
|
124
|
+
/** 是否为块级元素 */
|
|
125
|
+
isBlockTree: boolean;
|
|
126
|
+
/** 形状标志 */
|
|
127
|
+
shapeFlag: number;
|
|
128
|
+
/** 补丁标志 */
|
|
129
|
+
patchFlag: number;
|
|
130
|
+
/** 动态 props */
|
|
131
|
+
dynamicProps: string[] | null;
|
|
132
|
+
/** 动态子节点 */
|
|
133
|
+
dynamicChildren: VNode[] | null;
|
|
134
|
+
/** 子节点 */
|
|
135
|
+
children: VNodeChildren;
|
|
136
|
+
/** 组件实例 */
|
|
137
|
+
component: ComponentInternalInstance | null;
|
|
138
|
+
/** 挂载的 DOM 元素 */
|
|
139
|
+
el: Node | null;
|
|
140
|
+
/** 锚点元素 */
|
|
141
|
+
anchor: Node | null;
|
|
142
|
+
/** 目标元素(Teleport) */
|
|
143
|
+
target: Element | null;
|
|
144
|
+
/** 目标锚点(Teleport) */
|
|
145
|
+
targetAnchor: Node | null;
|
|
146
|
+
/** 目标起始位置(Teleport) */
|
|
147
|
+
targetStart: Node | null;
|
|
148
|
+
/** Suspense 边界 */
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
150
|
+
suspense?: any;
|
|
151
|
+
/** 源码位置 */
|
|
152
|
+
loc: VNodeSourceLocation | null;
|
|
153
|
+
/** 内部标记 */
|
|
154
|
+
__v_isVNode: true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* 组件公共实例接口
|
|
159
|
+
* @internal 此接口的权威来源为 @lytjs/shared-types/src/component.ts。
|
|
160
|
+
* 此处保留仅为避免循环依赖,新代码请从 @lytjs/shared-types 导入。
|
|
161
|
+
*/
|
|
162
|
+
export interface ComponentPublicInstance {
|
|
163
|
+
$props: Record<string, unknown>;
|
|
164
|
+
$attrs: Record<string, unknown>;
|
|
165
|
+
$refs: Record<string, unknown>;
|
|
166
|
+
$slots: Record<string, unknown>;
|
|
167
|
+
$emit: (event: string, ...args: unknown[]) => void;
|
|
168
|
+
$el: Element | ComponentPublicInstance | null;
|
|
169
|
+
$forceUpdate: () => void;
|
|
170
|
+
$nextTick: (fn?: () => void) => Promise<void>;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 组件内部实例接口
|
|
175
|
+
* @internal 此接口的权威来源为 @lytjs/component/src/types.ts。
|
|
176
|
+
* 此处保留简化版定义以避免循环依赖,新代码请从 @lytjs/component 导入。
|
|
177
|
+
*/
|
|
178
|
+
export interface ComponentInternalInstance {
|
|
179
|
+
uid: number;
|
|
180
|
+
type: VNodeTypes;
|
|
181
|
+
parent: ComponentInternalInstance | null;
|
|
182
|
+
root: ComponentInternalInstance;
|
|
183
|
+
vnode: VNode;
|
|
184
|
+
subTree: VNode;
|
|
185
|
+
props: Record<string, unknown>;
|
|
186
|
+
attrs: Record<string, unknown>;
|
|
187
|
+
slots: Record<string, unknown>;
|
|
188
|
+
refs: Record<string, unknown>;
|
|
189
|
+
setupState: Record<string, unknown>;
|
|
190
|
+
data: Record<string, unknown>;
|
|
191
|
+
ctx: Record<string, unknown>;
|
|
192
|
+
emit: (event: string, ...args: unknown[]) => void;
|
|
193
|
+
isMounted: boolean;
|
|
194
|
+
isUnmounted: boolean;
|
|
195
|
+
isDeactivated: boolean;
|
|
196
|
+
isKeepingAlive: boolean;
|
|
197
|
+
bum?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
198
|
+
bm?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
199
|
+
m?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
200
|
+
bu?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
201
|
+
u?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
202
|
+
um?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
203
|
+
uc?: ((...args: unknown[]) => void) | Array<(...args: unknown[]) => void> | null;
|
|
204
|
+
effects?: Array<{ stop: () => void }>;
|
|
205
|
+
update?: () => void;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface BaseComponentOptions {
|
|
209
|
+
props?: Record<string, unknown>;
|
|
210
|
+
emits?: string[] | Record<string, unknown>;
|
|
211
|
+
setup?: (...args: unknown[]) => Record<string, unknown>;
|
|
212
|
+
render?: (...args: unknown[]) => unknown;
|
|
213
|
+
computed?: Record<string, () => unknown>;
|
|
214
|
+
methods?: Record<string, (...args: unknown[]) => unknown>;
|
|
215
|
+
watch?: Record<string, unknown>;
|
|
216
|
+
data?: () => Record<string, unknown>;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// ============================================================
|
|
220
|
+
// VNode 默认值与工厂函数
|
|
221
|
+
// ============================================================
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* VNode 默认值常量
|
|
225
|
+
* 包含所有 VNode 字段的默认值,用于 createBaseVNode 工厂函数
|
|
226
|
+
*/
|
|
227
|
+
export const VNODE_DEFAULTS: VNode = {
|
|
228
|
+
type: null as unknown as VNode['type'],
|
|
229
|
+
key: null,
|
|
230
|
+
ref: null,
|
|
231
|
+
props: null,
|
|
232
|
+
isStatic: false,
|
|
233
|
+
isStaticRoot: false,
|
|
234
|
+
isOnce: false,
|
|
235
|
+
isAsyncPlaceholder: false,
|
|
236
|
+
isComment: false,
|
|
237
|
+
isCloned: false,
|
|
238
|
+
isBlockTree: false,
|
|
239
|
+
shapeFlag: 0,
|
|
240
|
+
patchFlag: 0,
|
|
241
|
+
dynamicProps: null,
|
|
242
|
+
dynamicChildren: null,
|
|
243
|
+
children: null,
|
|
244
|
+
component: null,
|
|
245
|
+
el: null,
|
|
246
|
+
anchor: null,
|
|
247
|
+
target: null,
|
|
248
|
+
targetAnchor: null,
|
|
249
|
+
targetStart: null,
|
|
250
|
+
suspense: null,
|
|
251
|
+
loc: null,
|
|
252
|
+
__v_isVNode: true,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* 创建基础 VNode,使用默认值填充未指定的字段
|
|
257
|
+
* @param overrides 需要覆盖的 VNode 字段
|
|
258
|
+
* @returns 完整的 VNode 对象
|
|
259
|
+
*/
|
|
260
|
+
export function createBaseVNode(overrides: Partial<VNode>): VNode {
|
|
261
|
+
return { ...VNODE_DEFAULTS, ...overrides } as VNode;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ============================================================
|
|
265
|
+
// VNode 工具函数
|
|
266
|
+
// ============================================================
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 检查是否为 Fragment VNode
|
|
270
|
+
*/
|
|
271
|
+
export function isVNode(value: unknown): value is VNode {
|
|
272
|
+
return (
|
|
273
|
+
value !== null &&
|
|
274
|
+
typeof value === 'object' &&
|
|
275
|
+
(value as Record<string, unknown>).__v_isVNode === true
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* 检查 VNode 是否为 Fragment 类型
|
|
281
|
+
*/
|
|
282
|
+
export function isFragment(vnode: VNode): boolean {
|
|
283
|
+
return vnode.type === Fragment;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* 检查 VNode 是否为 Text 类型
|
|
288
|
+
*/
|
|
289
|
+
export function isTextVNode(vnode: VNode): boolean {
|
|
290
|
+
return vnode.type === Text;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* 检查 VNode 是否为 Comment 类型
|
|
295
|
+
*/
|
|
296
|
+
export function isCommentVNode(vnode: VNode): boolean {
|
|
297
|
+
return vnode.type === Comment;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* 检查两个 VNode 是否类型相同
|
|
302
|
+
*/
|
|
303
|
+
export function isSameVNodeType(n1: VNode, n2: VNode): boolean {
|
|
304
|
+
return n1.type === n2.type && n1.key === n2.key;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* 检查 VNode 是否包含指定的 patch flag
|
|
309
|
+
*/
|
|
310
|
+
export function hasPatchFlag(vnode: VNode, flag: number): boolean {
|
|
311
|
+
const pf = vnode.patchFlag;
|
|
312
|
+
if (pf === -1 /* HOISTED */ || pf === -2 /* BAIL */) return true;
|
|
313
|
+
return (pf & flag) !== 0;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* 描述 patch flag 的含义
|
|
318
|
+
*/
|
|
319
|
+
export function describePatchFlag(flag: number): string {
|
|
320
|
+
const names: string[] = [];
|
|
321
|
+
|
|
322
|
+
if (flag === PatchFlags.HOISTED) return 'HOISTED';
|
|
323
|
+
if (flag === PatchFlags.BAIL) return 'BAIL';
|
|
324
|
+
|
|
325
|
+
if (flag & PatchFlags.TEXT) names.push('TEXT');
|
|
326
|
+
if (flag & PatchFlags.CLASS) names.push('CLASS');
|
|
327
|
+
if (flag & PatchFlags.STYLE) names.push('STYLE');
|
|
328
|
+
if (flag & PatchFlags.PROPS) names.push('PROPS');
|
|
329
|
+
if (flag & PatchFlags.FULL_PROPS) names.push('FULL_PROPS');
|
|
330
|
+
if (flag & PatchFlags.HYDRATE_EVENTS) names.push('HYDRATE_EVENTS');
|
|
331
|
+
if (flag & PatchFlags.STABLE_FRAGMENT) names.push('STABLE_FRAGMENT');
|
|
332
|
+
if (flag & PatchFlags.KEYED_FRAGMENT) names.push('KEYED_FRAGMENT');
|
|
333
|
+
if (flag & PatchFlags.UNKEYED_FRAGMENT) names.push('UNKEYED_FRAGMENT');
|
|
334
|
+
if (flag & PatchFlags.NEED_PATCH) names.push('NEED_PATCH');
|
|
335
|
+
if (flag & PatchFlags.DYNAMIC_SLOTS) names.push('DYNAMIC_SLOTS');
|
|
336
|
+
|
|
337
|
+
return names.join(' | ') || 'NO_FLAGS';
|
|
338
|
+
}
|