├── .gitignore ├── README.md ├── babel.config.json ├── package.json ├── packages ├── compiler-core │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── codegen.spec.ts.snap │ │ ├── codegen.spec.ts │ │ ├── parse.spec.ts │ │ └── transform.spec.ts │ ├── package.json │ └── src │ │ ├── ast.ts │ │ ├── codegen.ts │ │ ├── compile.ts │ │ ├── index.ts │ │ ├── parse.ts │ │ ├── runtimeHelpers.ts │ │ ├── transform.ts │ │ ├── transforms │ │ ├── transformElement.ts │ │ ├── transformExpression.ts │ │ └── transformText.ts │ │ └── utils.ts ├── reactivity │ ├── __tests__ │ │ ├── computed.spec.ts │ │ ├── effect.spec.ts │ │ ├── reactive.spec.ts │ │ ├── readonly.spec.ts │ │ ├── ref.spec.ts │ │ └── shallowReadonly.spec.ts │ ├── package.json │ └── src │ │ ├── baseHandlers.ts │ │ ├── computed.ts │ │ ├── effect.ts │ │ ├── index.ts │ │ ├── reactive.ts │ │ └── ref.ts ├── runtime-core │ ├── __tests__ │ │ └── apiWatch.spec.ts │ ├── package.json │ └── src │ │ ├── apiInject.ts │ │ ├── apiWatch.ts │ │ ├── component.ts │ │ ├── componentEmit.ts │ │ ├── componentProps.ts │ │ ├── componentPublicInstance.ts │ │ ├── componentSlots.ts │ │ ├── componentUpdateUtils.ts │ │ ├── createApp.ts │ │ ├── h.ts │ │ ├── helper │ │ └── renderSlots.ts │ │ ├── index.ts │ │ ├── renderer.ts │ │ ├── scheduler.ts │ │ └── vnode.ts ├── runtime-dom │ ├── package.json │ └── src │ │ └── index.ts ├── shared │ ├── package.json │ └── src │ │ ├── ShapeFlags.ts │ │ ├── getSequence.ts │ │ ├── index.ts │ │ └── toDisplayString.ts └── vue │ ├── examples │ ├── apiInject │ │ ├── App.js │ │ ├── index.html │ │ └── main.js │ ├── compilerBase │ │ ├── App.js │ │ └── index.html │ ├── componentSlot │ │ ├── App.js │ │ ├── Foo.js │ │ ├── index.html │ │ └── main.js │ ├── componentUpdate │ │ ├── App.js │ │ ├── Child.js │ │ ├── index.html │ │ └── main.js │ ├── currentInstance │ │ ├── App.js │ │ ├── Foo.js │ │ ├── index.html │ │ └── main.js │ ├── customRenderer │ │ ├── App.js │ │ ├── index.html │ │ └── main.js │ ├── helloworld │ │ ├── App.js │ │ ├── Foo.js │ │ ├── index.html │ │ └── main.js │ ├── nextTicker │ │ ├── App.js │ │ ├── index.html │ │ └── main.js │ ├── patchChildren │ │ ├── App.js │ │ ├── ArrayToArray.js │ │ ├── ArrayToText.js │ │ ├── TextToArray.js │ │ ├── TextToText.js │ │ ├── index.html │ │ └── main.js │ └── update │ │ ├── App.js │ │ ├── index.html │ │ └── main.js │ ├── package.json │ └── src │ └── index.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── rollup.config.js ├── tsconfig.json ├── vitest.config.ts └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | lib 4 | dist 5 | .DS_Store 6 | *.log 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # my-vue3 2 | Vue3 source code learning. 3 | 4 | From https://github.com/cuixiaorui/mini-vue.git 5 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "targets": { 7 | "node": "current" 8 | } 9 | } 10 | ], 11 | "@babel/preset-typescript" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-vue3-core", 3 | "version": "1.0.0", 4 | "main": "lib/my-vue3-core.cjs.js", 5 | "module": "lib/my-vue3-core.esm.js", 6 | "type": "module", 7 | "repository": "https://github.com/Seanxyc/my-vue3-core.git", 8 | "author": "Seanxyc ", 9 | "license": "MIT", 10 | "scripts": { 11 | "test": "vitest", 12 | "build": "rollup -c rollup.config.js" 13 | }, 14 | "devDependencies": { 15 | "@babel/core": "^7.17.4", 16 | "@babel/preset-env": "^7.16.11", 17 | "@babel/preset-typescript": "^7.16.7", 18 | "@rollup/plugin-typescript": "^10.0.1", 19 | "rollup": "^3.7.5", 20 | "tslib": "^2.4.1", 21 | "typescript": "^4.5.5", 22 | "vite": "^4.1.2", 23 | "vitest": "^0.28.4" 24 | } 25 | } -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`codegen > element 1`] = ` 4 | "const { toDisplayString: _toDisplayString, createElementVNode: _createElementVNode } = Vue 5 | return function render(_ctx, _cache){return _createElementVNode(\\"div\\", null, \\"hi,\\" + _toDisplayString(_ctx.message))}" 6 | `; 7 | 8 | exports[`codegen > interpolation 1`] = ` 9 | "const { toDisplayString: _toDisplayString } = Vue 10 | return function render(_ctx, _cache){return _toDisplayString(_ctx.message)}" 11 | `; 12 | 13 | exports[`codegen > string 1`] = `"return function render(_ctx, _cache){return \\"hi\\"}"`; 14 | -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/codegen.spec.ts: -------------------------------------------------------------------------------- 1 | import { generate } from "../src/codegen"; 2 | import { baseParse } from "../src/parse"; 3 | import { transform } from "../src/transform"; 4 | import { transformElement } from "../src/transforms/transformElement"; 5 | import { transformExpression } from "../src/transforms/transformExpression"; 6 | import { transformText } from "../src/transforms/transformText"; 7 | 8 | describe('codegen', () => { 9 | it('string', () => { 10 | const ast = baseParse('hi') 11 | 12 | transform(ast) 13 | const { code } = generate(ast) 14 | 15 | expect(code).toMatchSnapshot() 16 | }); 17 | 18 | it('interpolation', () => { 19 | const ast = baseParse('{{message}}') 20 | 21 | transform(ast, { 22 | nodeTransforms: [transformExpression] 23 | }) 24 | const { code } = generate(ast) 25 | 26 | expect(code).toMatchSnapshot() 27 | }); 28 | 29 | it('element', () => { 30 | const ast = baseParse("
hi,{{message}}
") 31 | 32 | transform(ast, { 33 | // TODO 理解顺序 34 | nodeTransforms: [transformExpression, transformElement, transformText] 35 | }) 36 | const { code } = generate(ast) 37 | 38 | expect(code).toMatchSnapshot() 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/parse.spec.ts: -------------------------------------------------------------------------------- 1 | import { NodeTypes } from "../src/ast" 2 | import { baseParse } from "../src/parse" 3 | 4 | describe('Parse', () => { 5 | describe('interpolation', () => { 6 | test('simple interpolation', () => { 7 | const ast = baseParse("{{ message }}") 8 | //root 9 | expect(ast.children[0]).toStrictEqual({ 10 | type: NodeTypes.INTERPOLATION, 11 | content: { 12 | type: NodeTypes.SIMPLE_EXPRESSTION, 13 | content: 'message' 14 | } 15 | }) 16 | }) 17 | }) 18 | }) 19 | 20 | describe('element', () => { 21 | it('simple element div', () => { 22 | const ast = baseParse('
') 23 | 24 | expect(ast.children[0]).toStrictEqual({ 25 | type: NodeTypes.ElEMEMT, 26 | tag: 'div', 27 | children: [] 28 | }) 29 | }) 30 | }) 31 | 32 | describe('text', () => { 33 | it('simple text', () => { 34 | const ast = baseParse('this is text') 35 | 36 | expect(ast.children[0]).toStrictEqual({ 37 | type: NodeTypes.TEXT, 38 | content: 'this is text', 39 | }) 40 | }) 41 | }) 42 | 43 | test('hello world', () => { 44 | const ast = baseParse('

hi,{{ message }}

') 45 | 46 | expect(ast.children[0]).toStrictEqual({ 47 | type: NodeTypes.ElEMEMT, 48 | tag: 'p', 49 | children: [ 50 | { 51 | type: NodeTypes.TEXT, 52 | content: 'hi,' 53 | }, 54 | { 55 | type: NodeTypes.INTERPOLATION, 56 | content: { 57 | type: NodeTypes.SIMPLE_EXPRESSTION, 58 | content: 'message' 59 | } 60 | } 61 | ] 62 | }) 63 | }); 64 | 65 | test('nested element', () => { 66 | const ast = baseParse('

hi,

{{ message }}
') 67 | 68 | expect(ast.children[0]).toStrictEqual({ 69 | type: NodeTypes.ElEMEMT, 70 | tag: 'div', 71 | children: [ 72 | { 73 | type: NodeTypes.ElEMEMT, 74 | tag: 'p', 75 | children: [ 76 | { 77 | type: NodeTypes.TEXT, 78 | content: 'hi,' 79 | }, 80 | ] 81 | }, 82 | { 83 | type: NodeTypes.INTERPOLATION, 84 | content: { 85 | type: NodeTypes.SIMPLE_EXPRESSTION, 86 | content: 'message' 87 | } 88 | } 89 | ] 90 | }) 91 | }); 92 | 93 | test('should throw error when there is no close tag', () => { 94 | expect(() => { 95 | baseParse("

") 96 | }).toThrow("no close tag: span") 97 | }); -------------------------------------------------------------------------------- /packages/compiler-core/__tests__/transform.spec.ts: -------------------------------------------------------------------------------- 1 | import { NodeTypes } from "../src/ast"; 2 | import { baseParse } from "../src/parse"; 3 | import { transform } from "../src/transform"; 4 | 5 | describe('transform', () => { 6 | it('happy path', () => { 7 | const ast = baseParse("
hi,{{message}}
") 8 | 9 | const plugin = (node) => { 10 | if (node.type === NodeTypes.TEXT) { 11 | node.content = node.content + " mini-vue" 12 | } 13 | } 14 | 15 | transform(ast, { 16 | nodeTransforms: [plugin], 17 | }) 18 | 19 | const nodeText = ast.children[0].children[0] 20 | expect(nodeText.content).toBe('hi, mini-vue') 21 | }); 22 | }) -------------------------------------------------------------------------------- /packages/compiler-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-vue/compiler-core", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@my-vue/shared": "workspace:^1.0.0" 14 | } 15 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/ast.ts: -------------------------------------------------------------------------------- 1 | import { CREATE_ELEMENT_VNODE } from "./runtimeHelpers" 2 | 3 | export const enum NodeTypes { 4 | INTERPOLATION, 5 | SIMPLE_EXPRESSTION, 6 | ElEMEMT, 7 | TEXT, 8 | ROOT, 9 | COMPOUND_EXPRESSION 10 | } 11 | 12 | export function createVNodeCall(context, tag, props, children) { 13 | if (context) { 14 | context.helper(CREATE_ELEMENT_VNODE) 15 | } 16 | 17 | return { 18 | // TODO vue3 里面这里的 type 是 VNODE_CALL 19 | // 是为了 block 而 mini-vue 里面没有实现 block 20 | // 所以创建的是 Element 类型就够用了 21 | type: NodeTypes.ElEMEMT, 22 | tag, 23 | props, 24 | children 25 | } 26 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/codegen.ts: -------------------------------------------------------------------------------- 1 | import { isString } from "@my-vue/shared" 2 | import { NodeTypes } from "./ast" 3 | import { CREATE_ELEMENT_VNODE, helperMapName, TO_DISPLAY_STRING } from "./runtimeHelpers" 4 | 5 | export function generate(ast: any) { 6 | const context = createCodegenContext() 7 | const { push } = context 8 | 9 | genFunctionPreamble(ast, context) 10 | 11 | const functionName = "render" 12 | const args = ['_ctx', "_cache"] 13 | const signature = args.join(", ") 14 | 15 | push(`function ${functionName}(${signature}){`) 16 | push('return ') 17 | genNode(ast.codegenNode, context) 18 | push('}') 19 | 20 | return { 21 | code: context.code 22 | } 23 | } 24 | 25 | /** 26 | * @description: 导入逻辑 27 | */ 28 | function genFunctionPreamble(ast: any, context: any) { 29 | const { push } = context 30 | const VueBinging = "Vue" 31 | const aliasHelper = s => `${helperMapName[s]}: _${helperMapName[s]}` 32 | if (ast.helpers.length > 0) { 33 | push(`const { ${ast.helpers.map(aliasHelper).join(", ")} } = ${VueBinging}`) 34 | push('\n') 35 | } 36 | push('return ') 37 | } 38 | 39 | function genNode(node: any, context: any) { 40 | switch (node.type) { 41 | case NodeTypes.TEXT: 42 | genText(context, node) 43 | break; 44 | 45 | case NodeTypes.INTERPOLATION: 46 | genInterpolation(node, context) 47 | break; 48 | 49 | case NodeTypes.SIMPLE_EXPRESSTION: 50 | genExpression(node, context) 51 | break; 52 | 53 | case NodeTypes.ElEMEMT: 54 | genElement(node, context) 55 | break; 56 | 57 | case NodeTypes.COMPOUND_EXPRESSION: 58 | genCompoundExpression(node, context) 59 | break; 60 | 61 | default: 62 | break; 63 | } 64 | } 65 | 66 | function createCodegenContext() { 67 | const context = { 68 | code: '', 69 | push(source) { 70 | context.code += source 71 | }, 72 | helper(key) { 73 | return `_${helperMapName[key]}` 74 | } 75 | } 76 | 77 | return context 78 | } 79 | 80 | function genText(context: any, node: any) { 81 | const { push } = context 82 | push(`"${node.content}"`) 83 | } 84 | 85 | function genInterpolation(node: any, context: any) { 86 | const { push, helper } = context 87 | push(`${helper(TO_DISPLAY_STRING)}(`) 88 | genNode(node.content, context) 89 | push(')') 90 | } 91 | 92 | function genExpression(node: any, context: any) { 93 | const { push } = context 94 | push(`${node.content}`) 95 | } 96 | 97 | function genElement(node: any, context: any) { 98 | const { push, helper } = context 99 | const { tag, children, props } = node 100 | push(`${helper(CREATE_ELEMENT_VNODE)}(`) 101 | // TODO ? 102 | genNodeList(genNullable([tag, props, children]), context) 103 | // for (let i = 0; i < children.length; i++) { 104 | // const child = children[i] 105 | // genNode(child, context) 106 | // } 107 | 108 | push(")") 109 | } 110 | 111 | function genCompoundExpression(node: any, context: any) { 112 | const { push } = context 113 | const { children } = node 114 | for (let i = 0; i < children.length; i++) { 115 | const child = children[i] 116 | if (isString(child)) { 117 | push(child) 118 | } else { 119 | genNode(child, context) 120 | } 121 | } 122 | } 123 | 124 | function genNodeList(nodes: any, context: any) { 125 | const { push } = context 126 | for (let i = 0; i < nodes.length; i++) { 127 | const node = nodes[i]; 128 | 129 | if (isString(node)) { 130 | push(node) 131 | } else { 132 | genNode(node, context) 133 | } 134 | 135 | if (i < nodes.length - 1) { 136 | push(', ') 137 | } 138 | } 139 | } 140 | 141 | function genNullable(args: any[]) { 142 | return args.map(arg => arg || 'null') 143 | } 144 | 145 | -------------------------------------------------------------------------------- /packages/compiler-core/src/compile.ts: -------------------------------------------------------------------------------- 1 | import { generate } from "./codegen"; 2 | import { baseParse } from "./parse"; 3 | import { transform } from "./transform"; 4 | import { transformElement } from "./transforms/transformElement"; 5 | import { transformExpression } from "./transforms/transformExpression"; 6 | import { transformText } from "./transforms/transformText"; 7 | 8 | export function baseCompile(template: any) { 9 | // 1. 先把 template 也就是字符串 parse 成 ast 10 | const ast: any = baseParse(template) 11 | // 2. 给 ast 加点料(- -#) 12 | transform(ast, { 13 | nodeTransforms: [transformExpression, transformElement, transformText] 14 | }) 15 | // 3. 生成 render 函数代码 16 | return generate(ast) 17 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./compile" 2 | 3 | -------------------------------------------------------------------------------- /packages/compiler-core/src/parse.ts: -------------------------------------------------------------------------------- 1 | import { NodeTypes } from "./ast" 2 | 3 | const enum TagType { 4 | Start, 5 | End 6 | } 7 | 8 | export function baseParse(content: string) { 9 | const context = createParseContext(content) 10 | return createRoot(parseChildren(context, [])) 11 | } 12 | 13 | function parseChildren(context, ancestors) { 14 | const nodes: any = [] 15 | 16 | while (!isEnd(context, ancestors)) { 17 | let node 18 | const s = context.source 19 | 20 | if (s.startsWith("{{")) { 21 | node = parseInterpolation(context) 22 | } else if (s.startsWith("<")) { 23 | if (/[a-z]/i.test(s[1])) { 24 | node = parseElement(context, ancestors) 25 | } 26 | } 27 | 28 | if (!node) { 29 | node = parseText(context) 30 | } 31 | 32 | nodes.push(node) 33 | } 34 | 35 | return nodes 36 | } 37 | 38 | function isEnd(context, ancestors) { 39 | const s = context.source 40 | // 1. 遇到close标签 41 | if (s.startsWith('= 0; i--) { 43 | const tag = ancestors[i].tag 44 | if (startsWithEndTagOpen(s, tag)) { 45 | return true 46 | } 47 | } 48 | } 49 | // 2. source有值 50 | return !s 51 | } 52 | 53 | /** 54 | * @description: 解析插值 55 | * @param {any} context 56 | */ 57 | function parseInterpolation(context) { 58 | // {{message}} 59 | const openDelimiter = "{{" 60 | const closeDelimiter = "}}" 61 | 62 | const closeIndex = context.source.indexOf(closeDelimiter, closeDelimiter.length) 63 | 64 | advanceBy(context, openDelimiter.length) 65 | 66 | const rawContentLength = closeIndex - openDelimiter.length 67 | 68 | const rawContent: any = parseTextData(context, rawContentLength) 69 | // const rawContent = context.source.slice(0, rawContentLength) 70 | const content = rawContent.trim() 71 | 72 | advanceBy(context, closeDelimiter.length) 73 | 74 | return { 75 | type: NodeTypes.INTERPOLATION, 76 | content: { 77 | type: NodeTypes.SIMPLE_EXPRESSTION, 78 | content: content 79 | } 80 | } 81 | } 82 | 83 | /** 84 | * @description: 解析element 85 | * @param {any} context 86 | */ 87 | function parseElement(context: any, ancestors: any) { 88 | const element: any = parseTag(context, TagType.Start) 89 | ancestors.push(element) 90 | element.children = parseChildren(context, ancestors) 91 | 92 | ancestors.pop() 93 | 94 | if (startsWithEndTagOpen(context.source, element.tag)) { 95 | parseTag(context, TagType.End) 96 | } else { 97 | throw new Error(`no close tag: ${element.tag}`); 98 | } 99 | 100 | return element 101 | } 102 | 103 | /** 104 | * @description: 解析tag 105 | * @param {any} context 106 | */ 107 | function parseTag(context: any, type: TagType) { 108 | // 1. 解析tag 109 | const match: any = /^<\/?([a-z]*)/i.exec(context.source) 110 | const tag = match[1] 111 | // 2. 删除处理完成的内容 112 | advanceBy(context, match[0].length) 113 | advanceBy(context, 1) 114 | 115 | if (type === TagType.End) return 116 | 117 | return { 118 | type: NodeTypes.ElEMEMT, 119 | tag 120 | } 121 | } 122 | 123 | /** 124 | * @description: 解析text 125 | * @param {any} context 126 | */ 127 | function parseText(context: any) { 128 | let endIndex = context.source.length 129 | const endTokens = ["<", "{{"] 130 | 131 | // 截取到 {{ 或 < 前 132 | for (let i = 0; i < endTokens.length; i++) { 133 | const index = context.source.indexOf(endTokens[i]) 134 | if (index !== -1 && endIndex > index) { 135 | endIndex = index 136 | } 137 | } 138 | 139 | const content = parseTextData(context, endIndex) 140 | 141 | return { 142 | type: NodeTypes.TEXT, 143 | content: content 144 | } 145 | } 146 | 147 | function parseTextData(context: any, length: number) { 148 | // 1. 获取content 149 | const content = context.source.slice(0, length) 150 | // 2. 删除处理完成的内容 151 | advanceBy(context, content.length) 152 | 153 | return content 154 | } 155 | 156 | function createRoot(children: any) { 157 | return { 158 | children, 159 | type: NodeTypes.ROOT 160 | } 161 | } 162 | 163 | function createParseContext(content: string): any { 164 | return { 165 | source: content 166 | } 167 | } 168 | 169 | function advanceBy(context: any, length: number) { 170 | context.source = context.source.slice(length) 171 | } 172 | 173 | function startsWithEndTagOpen(source, tag) { 174 | return source.startsWith(" { 7 | 8 | // tag 9 | const vnodeTag = `"${node.tag}"` 10 | 11 | // props 12 | let vnodeProps 13 | 14 | const { children } = node 15 | let vnodeChildren = children[0] 16 | 17 | node.codegenNode = createVNodeCall(context, vnodeTag, vnodeProps, vnodeChildren) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/transforms/transformExpression.ts: -------------------------------------------------------------------------------- 1 | import { NodeTypes } from "../ast"; 2 | 3 | export function transformExpression(node) { 4 | if (node.type === NodeTypes.INTERPOLATION) { 5 | const rawContent = node.content.content 6 | node.content.content = "_ctx." + rawContent 7 | } 8 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/transforms/transformText.ts: -------------------------------------------------------------------------------- 1 | import { NodeTypes } from "../ast"; 2 | import { isText } from "../utils"; 3 | 4 | export function transformText(node) { 5 | if (node.type === NodeTypes.ElEMEMT) { 6 | return () => { 7 | const { children } = node 8 | 9 | let currentContainer 10 | for (let i = 0; i < children.length; i++) { 11 | const child = children[i]; 12 | if (isText(child)) { 13 | for (let j = i + 1; j < children.length; j++) { 14 | const next = children[j]; 15 | if (isText(next)) { 16 | if (!currentContainer) { 17 | currentContainer = children[i] = { 18 | type: NodeTypes.COMPOUND_EXPRESSION, 19 | children: [child] 20 | } 21 | } 22 | 23 | currentContainer.children.push(" + ") 24 | currentContainer.children.push(next) 25 | 26 | children.splice(j--, 1) 27 | } else { 28 | // not text 29 | currentContainer = undefined 30 | break 31 | } 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /packages/compiler-core/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { NodeTypes } from "./ast"; 2 | 3 | export function isText(node) { 4 | return node.type === NodeTypes.TEXT || node.type === NodeTypes.INTERPOLATION 5 | } -------------------------------------------------------------------------------- /packages/reactivity/__tests__/computed.spec.ts: -------------------------------------------------------------------------------- 1 | import { computed } from '../src/computed' 2 | import { reactive } from '../src/reactive' 3 | import { vi } from 'vitest' 4 | import { effect } from '../src/effect' 5 | 6 | describe('computed', () => { 7 | it('happy path', () => { 8 | const user = reactive({ 9 | age: 1, 10 | }) 11 | 12 | const age = computed(() => { 13 | return user.age 14 | }) 15 | 16 | expect(age.value).toBe(1) 17 | }) 18 | 19 | it('should compute lazily', () => { 20 | const value = reactive({ 21 | foo: 1, 22 | }) 23 | const getter = vi.fn(() => { 24 | return value.foo 25 | }) 26 | const cValue = computed(getter) 27 | 28 | // lazy 29 | expect(getter).not.toHaveBeenCalled() 30 | 31 | expect(cValue.value).toBe(1) 32 | expect(getter).toHaveBeenCalledTimes(1) 33 | 34 | // should not compute again 35 | cValue.value 36 | expect(getter).toHaveBeenCalledTimes(1) 37 | 38 | // should not computed until needed 39 | value.foo = 2 40 | expect(getter).toHaveBeenCalledTimes(1) // 不再次调用getter 41 | 42 | // now it should compute 43 | expect(cValue.value).toBe(2) 44 | expect(getter).toHaveBeenCalledTimes(2) 45 | }) 46 | 47 | it('nested computed', () => { 48 | const obj = reactive({ foo: 1, bar: 2 }) 49 | let dummy = computed(() => obj.foo + obj.bar) 50 | 51 | const runner = vi.fn(() => { 52 | console.log(dummy.value) 53 | }) 54 | effect(runner) 55 | 56 | expect(runner).toHaveBeenCalledOnce() 57 | expect(dummy.value).toBe(3) 58 | 59 | obj.foo++ 60 | 61 | expect(runner).toHaveBeenCalledTimes(2) 62 | expect(dummy.value).toBe(4) 63 | }) 64 | }) 65 | -------------------------------------------------------------------------------- /packages/reactivity/__tests__/effect.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-04 22:11:41 4 | * @LastEditTime: 2023-02-19 22:15:09 5 | * @LastEditors: Seanxyc seanxyc41@gmail.com 6 | * @Description: 7 | */ 8 | import { reactive } from "../src/reactive"; 9 | import { effect, stop } from "../src/effect"; 10 | import { vi } from 'vitest' 11 | 12 | describe("effect", () => { 13 | it("happy path", () => { 14 | const user = reactive({ 15 | age: 10, 16 | }); 17 | 18 | let nextAge; 19 | effect(() => { 20 | nextAge = user.age + 1; 21 | }); 22 | 23 | expect(nextAge).toBe(11); 24 | 25 | // update 26 | user.age++; 27 | expect(nextAge).toBe(12); 28 | }); 29 | 30 | // runer 31 | it("should return runner when call effect", () => { 32 | // effect(fn) -> function(runner) -> fn -> return 33 | let foo = 10; 34 | const runner = effect(() => { 35 | foo++; 36 | return "foo"; 37 | }); 38 | 39 | expect(foo).toBe(11); 40 | const r = runner(); 41 | expect(foo).toBe(12); 42 | expect(r).toBe("foo"); 43 | }); 44 | 45 | // scheduler 46 | it("scheduler", () => { 47 | // 1. 通过effect的第二个参数给定一个scheduler的fn 48 | // 2. effect第一次执行的时候还会执行fn 49 | // 3. 当响应式对象set update 不会执行fn,而是执行scheduler 50 | // 4. 当执行runner的时候,会再次执行fn 51 | let dummy; 52 | let run: any; 53 | const scheduler = vi.fn(() => { 54 | run = runner; 55 | }); 56 | const obj = reactive({ foo: 1 }); 57 | const runner = effect( 58 | () => { 59 | dummy = obj.foo; 60 | }, 61 | { scheduler } 62 | ); 63 | 64 | expect(scheduler).not.toHaveBeenCalled(); 65 | expect(dummy).toBe(1); 66 | // should be callsed on first trigger 67 | obj.foo++; 68 | expect(scheduler).toHaveBeenCalledTimes(1); 69 | // should not run yet 70 | expect(dummy).toBe(1); 71 | // manually run 72 | run(); 73 | // should have run 74 | expect(dummy).toBe(2); 75 | }); 76 | 77 | // stop 78 | it("stop", () => { 79 | let dummy; 80 | const obj = reactive({ prop: 1 }); 81 | const runner = effect(() => { 82 | dummy = obj.prop; 83 | }); 84 | obj.prop = 2; 85 | expect(dummy).toBe(2); 86 | stop(runner); 87 | obj.prop = 3; // 仅触发set 88 | expect(dummy).toBe(2); 89 | obj.prop++; // obj.prop = obj.prop + 1 会触发get 90 | expect(dummy).toBe(2); 91 | 92 | // stopped effect should still be manually callable 93 | runner(); 94 | expect(dummy).toBe(4); 95 | }); 96 | 97 | // onStop 98 | it("onStop", () => { 99 | const obj = reactive({ 100 | foo: 1, 101 | }); 102 | const onStop = vi.fn(); 103 | let dummy; 104 | const runner = effect( 105 | () => { 106 | dummy = obj.foo; 107 | }, 108 | { onStop } 109 | ); 110 | stop(runner); 111 | expect(onStop).toBeCalledTimes(1); 112 | }); 113 | 114 | // clean up 115 | it('cleanUp', () => { 116 | let dummy 117 | const obj = reactive({ ok: true, text: 'hello world' }) 118 | const runner = vi.fn(() => { 119 | dummy = obj.ok ? obj.text : 'not' 120 | }) 121 | effect(runner) 122 | expect(runner).toHaveBeenCalledOnce() 123 | expect(dummy).toBe('hello world') 124 | obj.ok = false 125 | expect(dummy).toBe('not') 126 | expect(runner).toHaveBeenCalledTimes(2) 127 | obj.text = 'hi, vue' 128 | expect(runner).toHaveBeenCalledTimes(2) 129 | }) 130 | 131 | it('nested effect', () => { 132 | let dummy1, dummy2 133 | const obj = reactive({ foo: true, bar: true }) 134 | const effectFn1 = vi.fn(() => { 135 | effect(effectFn2) 136 | dummy1 = obj.foo 137 | }) 138 | const effectFn2 = vi.fn(() => { 139 | dummy2 = obj.bar 140 | }) 141 | effect(effectFn1) 142 | 143 | expect(effectFn1).toHaveBeenCalledTimes(1) 144 | obj.foo = false 145 | expect(dummy1).toBe(false) 146 | expect(effectFn1).toHaveBeenCalledTimes(2) 147 | expect(effectFn2).toHaveBeenCalledTimes(2) 148 | obj.bar = false 149 | expect(dummy2).toBe(false) 150 | expect(effectFn1).toHaveBeenCalledTimes(2) 151 | expect(effectFn2).toHaveBeenCalledTimes(4) 152 | }); 153 | 154 | it('self increment', () => { 155 | const obj = reactive({ foo: 1 }) 156 | effect(() => { obj.foo++ }) 157 | }) 158 | }); 159 | -------------------------------------------------------------------------------- /packages/reactivity/__tests__/reactive.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-04 21:29:16 4 | * @LastEditTime: 2022-05-22 17:06:37 5 | * @LastEditors: seanchen 6 | * @Description: 7 | */ 8 | import { reactive, isReactive, isProxy } from "../src/reactive"; 9 | 10 | describe("reactive", () => { 11 | it("happy path", () => { 12 | const original = { foo: 1 }; 13 | const observed = reactive(original); 14 | 15 | // 1. observered !== original 16 | expect(observed).not.toBe(original); 17 | // 2. 调用foo时返回值 18 | expect(observed.foo).toBe(1); 19 | 20 | expect(isReactive(observed)).toBe(true); 21 | 22 | // test isProxy 23 | expect(isProxy(observed)).toBe(true); 24 | }); 25 | 26 | test("nested reactive", () => { 27 | const original = { 28 | nested: { 29 | foo: 1, 30 | }, 31 | array: [{ bar: 2 }], 32 | }; 33 | const observed = reactive(original); 34 | expect(isReactive(observed.nested)).toBe(true); 35 | expect(isReactive(observed.array)).toBe(true); 36 | expect(isReactive(observed.array[0])).toBe(true); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/reactivity/__tests__/readonly.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-22 15:27:12 4 | * @LastEditTime: 2023-02-12 18:31:14 5 | * @LastEditors: Seanxyc seanxyc41@gmail.com 6 | * @Description: 7 | */ 8 | import { readonly, isReadonly, isProxy } from "../src/reactive"; 9 | import { vi } from 'vitest' 10 | 11 | describe("readonly", () => { 12 | it("happy path", () => { 13 | // not set 14 | const original = { foo: 1, bar: { baz: 2 } }; 15 | const wrapped = readonly(original); 16 | 17 | expect(wrapped).not.toBe(original); 18 | expect(wrapped.foo).toBe(1); 19 | 20 | expect(isReadonly(wrapped)).toBe(true); 21 | expect(isReadonly(original)).toBe(false); 22 | 23 | // readonly嵌套 24 | expect(isReadonly(wrapped.bar)).toBe(true); 25 | expect(isReadonly(original.bar)).toBe(false); 26 | 27 | // test isProxy 28 | expect(isProxy(wrapped)).toBe(true); 29 | }); 30 | 31 | it("warn when call set", () => { 32 | console.warn = vi.fn(); 33 | 34 | const user = readonly({ 35 | age: 10, 36 | }); 37 | 38 | user.age = 11; 39 | 40 | expect(console.warn).toBeCalled(); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /packages/reactivity/__tests__/ref.spec.ts: -------------------------------------------------------------------------------- 1 | import { effect } from "../src/effect"; 2 | import { reactive } from "../src/reactive"; 3 | import { ref, isRef, unRef, proxyRefs } from "../src/ref"; 4 | 5 | describe("ref", () => { 6 | it("happy path", () => { 7 | const a = ref(1); 8 | expect(a.value).toBe(1); 9 | }); 10 | 11 | it("should be reactive", () => { 12 | const a = ref(1); 13 | let dummy; 14 | let calls = 0; 15 | effect(() => { 16 | calls++; 17 | dummy = a.value; 18 | }); 19 | expect(calls).toBe(1); 20 | expect(dummy).toBe(1); 21 | a.value = 2; 22 | expect(calls).toBe(2); 23 | expect(dummy).toBe(2); 24 | // same value should not trigger 25 | a.value = 2; 26 | expect(calls).toBe(2); 27 | expect(dummy).toBe(2); 28 | }); 29 | 30 | it("should make nested propertites reactive", () => { 31 | const a = ref({ 32 | count: 1, 33 | }); 34 | let dummy; 35 | effect(() => { 36 | dummy = a.value.count; 37 | }); 38 | expect(dummy).toBe(1); 39 | a.value.count = 2; 40 | expect(dummy).toBe(2); 41 | }); 42 | 43 | 44 | it("isRef", () => { 45 | const a = ref(1) 46 | const user = reactive({ 47 | age: 1 48 | }) 49 | expect(isRef(a)).toBe(true) 50 | expect(isRef(1)).toBe(false) 51 | expect(isRef(user)).toBe(false) 52 | }) 53 | 54 | it("unRef", () => { 55 | const a = ref(1) 56 | expect(unRef(a)).toBe(1) 57 | expect(unRef(1)).toBe(1) 58 | }) 59 | 60 | 61 | it("proxyRefs", () => { 62 | const user = { 63 | age: ref(10), 64 | name: "ikeda" 65 | } 66 | 67 | const proxyUser = proxyRefs(user) 68 | expect(user.age.value).toBe(10) 69 | expect(proxyUser.age).toBe(10) 70 | expect(proxyUser.name).toBe("ikeda") 71 | 72 | proxyUser.age = 20 73 | expect(proxyUser.age).toBe(20) 74 | expect(user.age.value).toBe(20) 75 | 76 | proxyUser.age = ref(10) 77 | expect(proxyUser.age).toBe(10) 78 | expect(user.age.value).toBe(10) 79 | }) 80 | }); 81 | -------------------------------------------------------------------------------- /packages/reactivity/__tests__/shallowReadonly.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-22 15:21:21 4 | * @LastEditTime: 2022-05-22 17:06:36 5 | * @LastEditors: seanchen 6 | * @Description: 7 | */ 8 | import { isReadonly, shallowReadonly } from "../src/reactive"; 9 | 10 | describe("shallowReadonly", () => { 11 | test("should not make non-reactive properties reacctive", () => { 12 | const props = shallowReadonly({ n: { foo: 1 } }); 13 | expect(isReadonly(props)).toBe(true); 14 | expect(isReadonly(props.n)).toBe(false); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/reactivity/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-vue/reactivity", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@my-vue/shared": "workspace:^1.0.0" 14 | } 15 | } -------------------------------------------------------------------------------- /packages/reactivity/src/baseHandlers.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-22 15:17:51 4 | * @LastEditTime: 2023-02-12 17:36:43 5 | * @LastEditors: Seanxyc seanxyc41@gmail.com 6 | * @Description: 7 | */ 8 | import { extend, isObject } from "@my-vue/shared"; 9 | import { track, trigger } from "./effect"; 10 | import { reactive, ReactiveFlags, readonly } from "./reactive"; 11 | 12 | const get = createGetter(); 13 | const set = createSetter(); 14 | const readonlyGet = createGetter(true); 15 | const shallowReadonlyGet = createGetter(true, true); 16 | 17 | function createGetter(isReadonly = false, isShallow = false) { 18 | return (target, key) => { 19 | if (key === ReactiveFlags.IS_REACTIVE) { 20 | return !isReadonly; 21 | } else if (key === ReactiveFlags.IS_READONLY) { 22 | return isReadonly; 23 | } 24 | 25 | const res = Reflect.get(target, key); 26 | 27 | if (isShallow) { 28 | return res; 29 | } 30 | 31 | // reactive、readonly嵌套逻辑 32 | if (isObject(res)) { 33 | return isReadonly ? readonly(res) : reactive(res); 34 | } 35 | 36 | if (!isReadonly) { 37 | // 收集依赖 38 | track(target, key); 39 | } 40 | 41 | return res; 42 | }; 43 | } 44 | 45 | function createSetter() { 46 | return (target, key, value) => { 47 | const res = Reflect.set(target, key, value); 48 | // 触发依赖 49 | trigger(target, key); 50 | return res; 51 | }; 52 | } 53 | 54 | export const mutableHandler = { 55 | get, 56 | set, 57 | }; 58 | 59 | export const readonlyHandler = { 60 | get: readonlyGet, 61 | 62 | set(target, key) { 63 | console.warn("key: ${key} cannot set readonly value!"); 64 | return true; 65 | }, 66 | }; 67 | 68 | export const shallowReadonlyHandler = extend({}, readonlyHandler, { 69 | get: shallowReadonlyGet, 70 | }); 71 | -------------------------------------------------------------------------------- /packages/reactivity/src/computed.ts: -------------------------------------------------------------------------------- 1 | import { ReactiveEffect } from "./effect" 2 | import { trackRefValue, triggerRefValue } from "./ref" 3 | 4 | class ComputedRefImpl { 5 | public dep = new Set() 6 | private _getter: any 7 | private _dirty: boolean = true 8 | private _value: any 9 | private _effect: any 10 | constructor(getter) { 11 | this._getter = getter 12 | 13 | this._effect = new ReactiveEffect(getter, () => { 14 | // scheduler 控制getter重复调用,并且在触发fn.run()时将dirty改为true 15 | if (!this._dirty) { 16 | this._dirty = true 17 | triggerRefValue(this) 18 | } 19 | }) 20 | } 21 | 22 | get value() { 23 | trackRefValue(this) 24 | // 一开始执行getter 25 | if (this._dirty) { 26 | this._dirty = false 27 | this._value = this._effect.run() 28 | } 29 | 30 | // 当依赖的响应式对象发生改变时 31 | 32 | return this._value 33 | } 34 | } 35 | 36 | export function computed(getter) { 37 | return new ComputedRefImpl(getter) 38 | } 39 | -------------------------------------------------------------------------------- /packages/reactivity/src/effect.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-04 22:28:00 4 | * @LastEditTime: 2023-02-19 22:16:33 5 | * @LastEditors: Seanxyc seanxyc41@gmail.com 6 | * @Description: 7 | */ 8 | import { extend } from '@my-vue/shared' 9 | 10 | let activeEffect 11 | const effectStack: any[] = [] 12 | const trackStack: boolean[] = [] 13 | 14 | export class ReactiveEffect { 15 | private _fn: any 16 | public scheduler: Function | undefined 17 | onStop?: () => void 18 | deps = [] 19 | active = true 20 | 21 | constructor(fn, scheduler?: Function) { 22 | this._fn = fn 23 | this.scheduler = scheduler 24 | } 25 | 26 | run() { 27 | if (!this.active) { 28 | return this._fn() 29 | } 30 | 31 | cleanupEffect(this) 32 | 33 | trackStack.push(true) 34 | activeEffect = this 35 | effectStack.push(this) 36 | 37 | const result = this._fn() 38 | effectStack.pop() 39 | activeEffect = effectStack[effectStack.length - 1] 40 | 41 | return result 42 | } 43 | 44 | stop() { 45 | // 判断是否需要清空deps 46 | if (this.active) { 47 | cleanupEffect(this) 48 | if (this.onStop) { 49 | this.onStop() 50 | } 51 | this.active = false 52 | } 53 | } 54 | } 55 | 56 | let targetMap = new WeakMap() 57 | export function track(target, key) { 58 | if (!isTracking()) return 59 | 60 | // target -> key -> dep 61 | let depsMap = targetMap.get(target) 62 | if (!depsMap) targetMap.set(target, depsMap = new Map()) 63 | 64 | let deps = depsMap.get(key) 65 | if (!deps) depsMap.set(key, deps = new Set()) 66 | 67 | if (deps.has(activeEffect)) return // 已经在dep中,不需要重复收集 68 | 69 | trackEffects(deps) 70 | } 71 | 72 | export function trackEffects(dep) { 73 | dep.add(activeEffect) 74 | activeEffect.deps.push(dep) 75 | } 76 | 77 | export function isTracking() { 78 | return trackStack[trackStack.length - 1] && activeEffect !== undefined 79 | } 80 | 81 | export function trigger(target, key) { 82 | const depsMap = targetMap.get(target) 83 | if (!depsMap) return 84 | 85 | const deps = depsMap.get(key) 86 | const effectsToRun = new Set(deps) // 避免无限执行 87 | 88 | triggerEffects(effectsToRun) 89 | } 90 | 91 | export function triggerEffects(dep) { 92 | for (const effect of dep) { 93 | if (effect !== activeEffect) { 94 | if (effect.scheduler) { 95 | effect.scheduler() 96 | } else { 97 | effect.run() 98 | } 99 | } 100 | } 101 | } 102 | 103 | export function stop(runner) { 104 | runner.effect.stop() 105 | } 106 | 107 | // 清空deps 108 | function cleanupEffect(effect) { 109 | effect.deps.forEach((dep: any) => { 110 | dep.delete(effect) 111 | }) 112 | effect.deps.length = 0 113 | } 114 | 115 | export function effect(fn, options: any = {}) { 116 | const _effect = new ReactiveEffect(fn, options.scheduler) 117 | extend(_effect, options) 118 | 119 | _effect.run() 120 | 121 | const runner: any = _effect.run.bind(_effect) 122 | runner.effect = _effect 123 | 124 | // fn 返回值 125 | return runner 126 | } 127 | -------------------------------------------------------------------------------- /packages/reactivity/src/index.ts: -------------------------------------------------------------------------------- 1 | export { ref, isRef, unRef, proxyRefs } from './ref' 2 | export { reactive, shallowReadonly, readonly, isReactive, isReadonly, isProxy } from './reactive' 3 | export { effect, ReactiveEffect } from './effect' -------------------------------------------------------------------------------- /packages/reactivity/src/reactive.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-04 22:17:56 4 | * @LastEditTime: 2023-02-12 17:49:58 5 | * @LastEditors: Seanxyc seanxyc41@gmail.com 6 | * @Description: reactivity 7 | */ 8 | import { isObject } from "@my-vue/shared"; 9 | import { 10 | mutableHandler, 11 | readonlyHandler, 12 | shallowReadonlyHandler, 13 | } from "./baseHandlers"; 14 | 15 | export const enum ReactiveFlags { 16 | IS_REACTIVE = "__v_isReactive", 17 | IS_READONLY = "__v_isReadonly", 18 | } 19 | 20 | export function reactive(raw) { 21 | return createReactiveObject(raw, mutableHandler); 22 | } 23 | 24 | export function readonly(raw) { 25 | return createReactiveObject(raw, readonlyHandler); 26 | } 27 | 28 | export function shallowReadonly(raw) { 29 | return createReactiveObject(raw, shallowReadonlyHandler); 30 | } 31 | 32 | export function isReactive(value) { 33 | return !!value[ReactiveFlags.IS_REACTIVE]; 34 | } 35 | 36 | export function isReadonly(value) { 37 | return !!value[ReactiveFlags.IS_READONLY]; 38 | } 39 | 40 | export function isProxy(value) { 41 | return isReactive(value) || isReadonly(value); 42 | } 43 | 44 | function createReactiveObject(target, baseHandler) { 45 | if (!isObject(target)) { 46 | console.log("target ${target} has to be an object"); 47 | return 48 | } 49 | return new Proxy(target, baseHandler); 50 | } 51 | -------------------------------------------------------------------------------- /packages/reactivity/src/ref.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: seanchen 3 | * @Date: 2022-05-22 17:02:13 4 | * @LastEditTime: 2023-02-20 00:14:04 5 | * @LastEditors: Seanxyc seanxyc41@gmail.com 6 | * @Description: 7 | */ 8 | import { hasChanged, isObject } from "@my-vue/shared"; 9 | import { isTracking, trackEffects, triggerEffects } from "./effect"; 10 | import { reactive } from "./reactive"; 11 | 12 | class RefImpl { 13 | private _value: any; 14 | private _rawValue: any; 15 | public dep; 16 | public __v_isRef = true; 17 | 18 | constructor(value) { 19 | this._rawValue = value; 20 | this._value = convert(value); 21 | this.dep = new Set(); 22 | } 23 | 24 | get value() { 25 | trackRefValue(this); 26 | return this._value; 27 | } 28 | 29 | set value(newValue) { 30 | // same value should not trigger 31 | if (hasChanged(this._rawValue, newValue)) { 32 | this._rawValue = newValue; 33 | this._value = convert(newValue); 34 | const effectsToRun = new Set(this.dep) // 避免无限执行 35 | triggerEffects(effectsToRun); 36 | } 37 | } 38 | } 39 | 40 | export function trackRefValue(ref) { 41 | if (isTracking()) { 42 | trackEffects(ref.dep); 43 | } 44 | } 45 | 46 | export function triggerRefValue(ref, newVal?: any) { 47 | const dep = ref.dep 48 | if (dep) { 49 | const effectsToRun = new Set(dep) // 避免无限执行 50 | triggerEffects(effectsToRun) 51 | } 52 | } 53 | 54 | /** 55 | * description: value为Object时通过reactive转换 56 | */ 57 | function convert(val) { 58 | return isObject(val) ? reactive(val) : val; 59 | } 60 | 61 | export function ref(value) { 62 | return new RefImpl(value); 63 | } 64 | 65 | export function isRef(ref) { 66 | return !!ref.__v_isRef; 67 | } 68 | 69 | export function unRef(ref) { 70 | return isRef(ref) ? ref.value : ref; 71 | } 72 | 73 | export function proxyRefs(objectWithRefs) { 74 | return new Proxy(objectWithRefs, { 75 | // get -> 如果是ref类型,返回.value 76 | // 如果不是ref类型,返回本身 77 | get(target, key) { 78 | return unRef(Reflect.get(target, key)) 79 | }, 80 | 81 | // set -> 如果是当前是ref类型: 82 | // 如果newValue不是ref,修改;newValue是ref,替换 83 | set(target, key, value) { 84 | if (isRef(target[key]) && !isRef(value)) { 85 | return (target[key].value = value) 86 | } else { 87 | return Reflect.set(target, key, value) 88 | } 89 | } 90 | }) 91 | } 92 | -------------------------------------------------------------------------------- /packages/runtime-core/__tests__/apiWatch.spec.ts: -------------------------------------------------------------------------------- 1 | import { reactive } from "@my-vue/reactivity"; 2 | import { watchEffect } from "../src/apiWatch"; 3 | import { nextTick } from "../src/scheduler"; 4 | import { vi } from "vitest"; 5 | 6 | describe("api: watch", () => { 7 | it("effect", async () => { 8 | const state = reactive({ count: 0 }); 9 | let dummy; 10 | watchEffect(() => { 11 | dummy = state.count; 12 | }); 13 | expect(dummy).toBe(0); 14 | 15 | state.count++; 16 | expect(dummy).toBe(0); 17 | await nextTick(); 18 | expect(dummy).toBe(1); 19 | }); 20 | 21 | it("stopping the watcher (effect)", async () => { 22 | const state = reactive({ count: 0 }); 23 | let dummy; 24 | const stop: any = watchEffect(() => { 25 | dummy = state.count; 26 | }); 27 | expect(dummy).toBe(0); 28 | 29 | stop(); 30 | state.count++; 31 | await nextTick(); 32 | // should not update 33 | expect(dummy).toBe(0); 34 | }); 35 | 36 | it("cleanup registration (effect)", async () => { 37 | const state = reactive({ count: 0 }); 38 | const cleanup = vi.fn(); 39 | let dummy; 40 | const stop: any = watchEffect((onCleanup) => { 41 | onCleanup(cleanup); 42 | dummy = state.count; 43 | }); 44 | expect(dummy).toBe(0); 45 | 46 | state.count++; 47 | await nextTick(); 48 | expect(cleanup).toHaveBeenCalledTimes(1); 49 | expect(dummy).toBe(1); 50 | 51 | stop(); 52 | expect(cleanup).toHaveBeenCalledTimes(2); 53 | }); 54 | }); -------------------------------------------------------------------------------- /packages/runtime-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-vue/runtime-core", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@my-vue/reactivity": "workspace:^1.0.0", 14 | "@my-vue/shared": "workspace:^1.0.0" 15 | } 16 | } -------------------------------------------------------------------------------- /packages/runtime-core/src/apiInject.ts: -------------------------------------------------------------------------------- 1 | import { getCurrentInstance } from "./component"; 2 | 3 | export function provide(key: string, value: any) { 4 | const currentInstance: any = getCurrentInstance() 5 | 6 | if (currentInstance) { 7 | let { provides } = currentInstance 8 | const parentProvides = currentInstance.parent.provides 9 | 10 | if (provides === parentProvides) { // 只在初始化时执行一次 11 | // 当前provides的原型指向父级provides(原型链) 12 | provides = currentInstance.provides = Object.create(parentProvides) 13 | } 14 | 15 | provides[key] = value 16 | } 17 | } 18 | 19 | export function inject(key: string, defaultValue: any) { 20 | const currentInstance: any = getCurrentInstance() 21 | 22 | if (currentInstance) { 23 | const parentProvides = currentInstance.parent.provides 24 | 25 | if (key in parentProvides) { 26 | return parentProvides[key] 27 | } else if (defaultValue) { 28 | if (typeof defaultValue === 'function') return defaultValue() 29 | return defaultValue 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/runtime-core/src/apiWatch.ts: -------------------------------------------------------------------------------- 1 | import { ReactiveEffect } from "@my-vue/reactivity"; 2 | import { queuePreFlushCb } from "./scheduler"; 3 | 4 | // Simple effect. 5 | export function watchEffect(effect) { 6 | return doWatch(effect); 7 | } 8 | 9 | function doWatch(source) { 10 | // 把 job 添加到 pre flush 里面 11 | // 也就是在视图更新完成之前进行渲染(待确认?) 12 | // 当逻辑执行到这里的时候 就已经触发了 watchEffect 13 | const job = () => { 14 | effect.run(); 15 | }; 16 | 17 | // 当触发 trigger 的时候会调用 scheduler 18 | // 这里用 scheduler 的目的就是在更新的时候 19 | // 让回调可以在 render 前执行 变成一个异步的行为(这里也可以通过 flush 来改变) 20 | const scheduler = () => queuePreFlushCb(job); 21 | 22 | // cleanup 的作用是为了解决初始化的时候不调用 fn(用户传过来的 cleanup) 23 | // 第一次执行 watchEffect 的时候 onCleanup 会被调用 而这时候只需要把 fn 赋值给 cleanup 就可以 24 | // 当第二次执行 watchEffect 的时候就需要执行 fn 了 也就是 cleanup 25 | let cleanup; 26 | const onCleanup = (fn) => { 27 | // 当 effect stop 的时候也需要执行 cleanup 28 | // 所以可以在 onStop 中直接执行 fn 29 | cleanup = effect.onStop = () => { 30 | fn(); 31 | }; 32 | }; 33 | // 这里是在执行 effect.run 的时候就会调用的 34 | const getter = () => { 35 | // 这个的检测就是初始化不执行 cleanup 的关键点 36 | if (cleanup) { 37 | cleanup(); 38 | } 39 | 40 | source(onCleanup); 41 | }; 42 | 43 | const effect = new ReactiveEffect(getter, scheduler); 44 | 45 | // 这里执行的就是 getter 46 | effect.run(); 47 | 48 | // 返回值为 StopHandle 49 | // 只需要调用 stop 即可 50 | return () => { 51 | effect.stop(); 52 | }; 53 | } -------------------------------------------------------------------------------- /packages/runtime-core/src/component.ts: -------------------------------------------------------------------------------- 1 | import { shallowReadonly, proxyRefs } from "@my-vue/reactivity" 2 | import { emit } from "./componentEmit" 3 | import { initProps } from "./componentProps" 4 | import { PublicInstanceProxyHandlers } from "./componentPublicInstance" 5 | import { initSlots } from "./componentSlots" 6 | 7 | /** 8 | * @description 创建实例对象,存储组件的属性(props, slots...) 9 | */ 10 | export function createComponentInstance(vnode: any, parent: any) { 11 | const component = { 12 | vnode, 13 | type: vnode.type, 14 | setupState: {}, 15 | props: {}, 16 | emit: () => { }, 17 | slots: {}, 18 | provides: parent ? parent.provides : {}, 19 | parent, 20 | isMounted: false, 21 | subTree: {} 22 | } 23 | 24 | component.emit = emit.bind(null, component) as any 25 | 26 | return component 27 | } 28 | 29 | /** 30 | * @description setup 处理props, slots, 调用组件实例的setup(返回可能是Object或Function) 31 | */ 32 | export function setupComponent(instance: any) { 33 | initProps(instance, instance.vnode.props) 34 | 35 | initSlots(instance, instance.vnode.children) 36 | 37 | // 处理有状态的组件 38 | setupStatefulComponent(instance) 39 | } 40 | 41 | function setupStatefulComponent(instance: any) { 42 | const Component = instance.type 43 | 44 | // ctx 45 | instance.proxy = new Proxy({ _: instance }, PublicInstanceProxyHandlers) 46 | 47 | const { setup } = Component 48 | 49 | // 如果组件实例定义了setup 50 | if (setup) { 51 | 52 | // 赋值当前实例对象 53 | setCurrentInstance(instance) 54 | 55 | const setupResult = setup(shallowReadonly(instance.props), { 56 | emit: instance.emit 57 | }) // Function/Object 58 | 59 | currentInstance = null 60 | 61 | handleSetupResult(instance, setupResult) 62 | } 63 | } 64 | 65 | /** 66 | * @description 处理setup结果 67 | * @param {*} instance 68 | * @param {Function, Object} setupResult 69 | */ 70 | function handleSetupResult(instance: any, setupResult: any) { 71 | // Function Object 72 | // TODO: function 73 | 74 | if (typeof setupResult === 'object') { 75 | instance.setupState = proxyRefs(setupResult) 76 | } 77 | 78 | finishComponentSetup(instance) 79 | } 80 | 81 | function finishComponentSetup(instance: any) { 82 | const Component = instance.type 83 | 84 | if (compiler && !Component.render) { 85 | if (Component.template) { 86 | Component.render = compiler(Component.template) 87 | } 88 | } 89 | 90 | // 如果组件实例定义了render 91 | if (Component.render) { 92 | instance.render = Component.render 93 | } 94 | } 95 | 96 | 97 | let currentInstance = null 98 | export function getCurrentInstance() { 99 | return currentInstance 100 | } 101 | 102 | function setCurrentInstance(instance) { 103 | currentInstance = instance 104 | } 105 | 106 | let compiler 107 | 108 | export function registerRuntimeCompiler(_compiler) { 109 | compiler = _compiler 110 | } -------------------------------------------------------------------------------- /packages/runtime-core/src/componentEmit.ts: -------------------------------------------------------------------------------- 1 | import { camelize, toHandleKey } from "@my-vue/shared" 2 | 3 | export function emit(instance, event, ...args) { 4 | const { props } = instance 5 | 6 | 7 | const handlerName = toHandleKey(camelize(event)) 8 | const handler = props[handlerName] 9 | handler && handler(...args) 10 | } 11 | -------------------------------------------------------------------------------- /packages/runtime-core/src/componentProps.ts: -------------------------------------------------------------------------------- 1 | export function initProps(instance, rawProps) { 2 | instance.props = rawProps || {} 3 | // TODO: 4 | // attrs 5 | } 6 | -------------------------------------------------------------------------------- /packages/runtime-core/src/componentPublicInstance.ts: -------------------------------------------------------------------------------- 1 | import { hasOwn } from "@my-vue/shared" 2 | 3 | const publicPropertiesMap = { 4 | $el: i => i.vnode.el, 5 | $slots: i => i.slots, 6 | $props: i => i.props 7 | // $data: 8 | } 9 | 10 | 11 | export const PublicInstanceProxyHandlers = { 12 | get({ _: instance }, key) { 13 | // 1. key in setupState 14 | const { setupState, props } = instance 15 | if (hasOwn(setupState, key)) { 16 | return setupState[key] 17 | } else if (hasOwn(props, key)) { 18 | return props[key] 19 | } 20 | 21 | // 2. key = $el, $data ... 22 | // if (key === '$el') { 23 | // return instance.vnode.el 24 | // } 25 | const publicGetter = publicPropertiesMap[key] 26 | if (publicGetter) { 27 | return publicGetter(instance) 28 | } 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /packages/runtime-core/src/componentSlots.ts: -------------------------------------------------------------------------------- 1 | import { ShapeFlags } from "@my-vue/shared" 2 | 3 | export function initSlots(instance: any, children: any) { 4 | // slots? 5 | const { vnode } = instance 6 | if (vnode.shapeFlag = ShapeFlags.SLOT_CHILDREN) { 7 | normalizeObjectSlots(children, instance.slots) 8 | } 9 | } 10 | 11 | function normalizeObjectSlots(children: any, slots: any) { 12 | for (const key in children) { 13 | const value = children[key] 14 | // slot 15 | slots[key] = (props) => normalizeSlotValue(value(props)) 16 | } 17 | } 18 | 19 | function normalizeSlotValue(value) { 20 | return Array.isArray(value) ? value : [value] 21 | } 22 | 23 | -------------------------------------------------------------------------------- /packages/runtime-core/src/componentUpdateUtils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 是否需要更新props 3 | * @param prevVNode 4 | * @param nextVNode 5 | */ 6 | export function shouldUpdateComponent(prevVNode: any, nextVNode: any) { 7 | const { props: prevProps } = prevVNode 8 | const { props: nextProps } = nextVNode 9 | 10 | for (const key in nextProps) { 11 | if (nextProps[key] !== prevProps[key]) { 12 | return true 13 | } 14 | } 15 | return false 16 | } 17 | -------------------------------------------------------------------------------- /packages/runtime-core/src/createApp.ts: -------------------------------------------------------------------------------- 1 | import { createVNode } from "./vnode" 2 | 3 | export function createAppAPI(render) { 4 | return function createApp(rootComponent) { 5 | return { 6 | mount(rootContainer) { 7 | // 先转换成vnode 8 | // component -> vnode 9 | // 所有的逻辑操作都会基于vnode做处理 10 | 11 | const vnode = createVNode(rootComponent) 12 | 13 | render(vnode, rootContainer) 14 | } 15 | } 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /packages/runtime-core/src/h.ts: -------------------------------------------------------------------------------- 1 | import {createVNode} from './vnode' 2 | 3 | export function h(type, props?, children?) { 4 | return createVNode(type, props, children) 5 | } 6 | -------------------------------------------------------------------------------- /packages/runtime-core/src/helper/renderSlots.ts: -------------------------------------------------------------------------------- 1 | import { createVNode, Fragment } from '../vnode' 2 | 3 | export function renderSlots(slots, name, props) { 4 | const slot = slots[name] 5 | if (slot) { 6 | if (typeof slot === 'function') { 7 | // children 不可以有 array 8 | return createVNode(Fragment, {}, slot(props)) 9 | } 10 | // return createVNode('div', {}, slot) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/runtime-core/src/index.ts: -------------------------------------------------------------------------------- 1 | export { h } from './h' 2 | export { renderSlots } from './helper/renderSlots' 3 | export { createTextVNode, createElementVNode } from './vnode' 4 | export { getCurrentInstance, registerRuntimeCompiler } from './component' 5 | export { provide, inject } from './apiInject' 6 | export { createRenderer } from './renderer' 7 | export { nextTick } from './scheduler' 8 | export { toDisplayString } from '@my-vue/shared' 9 | export * from '@my-vue/reactivity' -------------------------------------------------------------------------------- /packages/runtime-core/src/renderer.ts: -------------------------------------------------------------------------------- 1 | import { effect } from "@my-vue/reactivity" 2 | import { ShapeFlags, getSequence, EMPTY_OBJ } from "@my-vue/shared" 3 | import { createComponentInstance, setupComponent } from "./component" 4 | import { shouldUpdateComponent } from "./componentUpdateUtils" 5 | import { createAppAPI } from "./createApp" 6 | import { queueJobs } from "./scheduler" 7 | import { Fragment, Text } from "./vnode" 8 | 9 | /** 10 | * @description 11 | * @param createElement 12 | * @param patchProp 13 | * @param insert 14 | */ 15 | export function createRenderer(options) { 16 | 17 | const { 18 | createElement: hostCreateElement, 19 | patchProp: hostPatchProp, 20 | insert: hostInsert, 21 | remove: hostRemove, 22 | setElementText: hostSetElementText 23 | } = options 24 | 25 | function render(vnode: any, container: any) { 26 | // patch 27 | patch(null, vnode, container, null, null) 28 | } 29 | 30 | /** 31 | * @description patch 32 | * @param n1 旧VNode 33 | * @param n2 新VNode 34 | * @param container 35 | * @param parentComponent 36 | */ 37 | function patch(n1: any, n2: any, container: any, parentComponent: any, anchor: any) { 38 | // ShapeFlags element | stateful component 39 | const { type, shapeFlag } = n2 40 | 41 | switch (type) { 42 | case Fragment: 43 | processFragment(n1, n2, container, parentComponent, anchor) 44 | break; 45 | 46 | case Text: 47 | processText(n1, n2, container) 48 | break; 49 | 50 | default: 51 | if (shapeFlag & ShapeFlags.ELEMENT) { // 与运算比较 52 | // 处理element类型 53 | processElement(n1, n2, container, parentComponent, anchor) 54 | } else if (shapeFlag & ShapeFlags.STATEFUL_COMPONENT) { 55 | // 处理组件类型 56 | processComponent(n1, n2, container, parentComponent, anchor) 57 | } 58 | break; 59 | } 60 | } 61 | 62 | function processFragment(n1: any, n2: any, container: any, parentComponent: any, anchor: any) { 63 | mountChildren(n2.children, container, parentComponent, anchor) 64 | } 65 | 66 | function processText(n1: any, n2: any, container: any) { 67 | const { children } = n2 68 | const textNode = document.createTextNode(children) 69 | container.append(textNode) 70 | } 71 | 72 | function processElement(n1: any, n2: any, container: any, parentComponent: any, anchor: any) { 73 | if (!n1) { 74 | // 初始化 75 | mountElement(n2, container, parentComponent, anchor) 76 | } else { 77 | patchElement(n1, n2, container, parentComponent, anchor) 78 | } 79 | } 80 | 81 | /** 82 | * @description 83 | * @param n1 oldVNode 84 | * @param n2 newVNode 85 | * @param container 86 | */ 87 | function patchElement(n1: any, n2: any, container: any, parentComponent: any, anchor: any) { 88 | const oldProps = n1.props || EMPTY_OBJ 89 | const newProps = n2.props || EMPTY_OBJ 90 | const el = (n2.el = n1.el) 91 | // children 92 | patchChildren(n1, n2, el, parentComponent, anchor) 93 | // props 94 | patchProps(el, oldProps, newProps) 95 | } 96 | 97 | 98 | /** 99 | * @description 100 | * @param n1 oldVNode 101 | * @param n2 newVNode 102 | */ 103 | function patchChildren(n1: any, n2: any, container: any, parentComponent: any, anchor: any) { 104 | const prevShapeFlag = n1.shapeFlag 105 | const shapeFlag = n2.shapeFlag 106 | const c1 = n1.children 107 | const c2 = n2.children 108 | 109 | if (shapeFlag & ShapeFlags.TEXT_CHILDREN) { 110 | if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) { 111 | // array to text 112 | // 1. 把旧的children清空 113 | unmountChildren(n1.children) 114 | // 2. 设置text 115 | // hostSetElementText(container, c2) 116 | } 117 | 118 | // text to text / array to text 119 | if (c1 !== c2) { 120 | hostSetElementText(container, c2) 121 | } 122 | } else { 123 | if (prevShapeFlag & ShapeFlags.TEXT_CHILDREN) { 124 | hostSetElementText(container, '') 125 | mountChildren(c2, container, parentComponent, anchor) 126 | } else { 127 | // array to array 128 | patchKeyedChildren(c1, c2, container, parentComponent, anchor) 129 | } 130 | } 131 | } 132 | 133 | /** 134 | * @description diff 135 | * @param c1 oldChildren 136 | * @param c2 newChildren 137 | * @param container 138 | * @param parentComponent 139 | */ 140 | function patchKeyedChildren( 141 | c1: any, 142 | c2: any, 143 | container: any, 144 | parentComponent: any, 145 | parentAnchor: any 146 | ) { 147 | const l2 = c2.length 148 | let i = 0 149 | let e1 = c1.length - 1 150 | let e2 = l2 - 1 151 | 152 | function isSameVNodeType(n1, n2) { 153 | return n1.type === n2.type && n1.key === n2.key 154 | } 155 | 156 | // left 157 | while (i <= e1 && i <= e2) { 158 | const n1 = c1[i] // old 159 | const n2 = c2[i] // new 160 | 161 | if (isSameVNodeType(n1, n2)) { 162 | patch(n1, n2, container, parentComponent, parentAnchor) 163 | } else { 164 | break 165 | } 166 | i++ 167 | } 168 | 169 | // right 170 | while (i <= e1 && i <= e2) { 171 | const n1 = c1[e1] 172 | const n2 = c2[e2] 173 | 174 | if (isSameVNodeType(n1, n2)) { 175 | patch(n1, n2, container, parentComponent, parentAnchor) 176 | } else { 177 | break 178 | } 179 | e1-- 180 | e2-- 181 | } 182 | 183 | // 3. 新的比旧的长----创建 184 | if (i > e1) { 185 | if (i <= e2) { 186 | const nextPos = e2 + 1 187 | const anchor = nextPos < l2 ? c2[nextPos].el : null // 在前面添加, 利用锚点 188 | while (i <= e2) { 189 | patch(null, c2[i], container, parentComponent, anchor) 190 | i++ 191 | } 192 | } 193 | } else if (i > e2) { // 4. 旧的比新的长----删除 194 | while (i <= e1) { 195 | hostRemove(c1[i].el) 196 | i++ 197 | } 198 | } else { 199 | // 4. 中间对比 200 | let s1 = i // 老节点起始位置 201 | let s2 = i 202 | 203 | const toBePatched = e2 - s2 + 1 // 新节点数量 204 | let patched = 0 // 已处理的节点数量 205 | const keyToNewIndexMap = new Map() // 映射表 206 | const newIndexToOldIndexMap = new Array(toBePatched) // 最长递增子序列映射表 207 | let moved = false // 是否需要移动位置 208 | let maxNewIndexSoFar = 0 209 | for (let j = 0; j < toBePatched; j++) newIndexToOldIndexMap[j] = 0 210 | 211 | // 建立映射关系 212 | for (let j = s2; j <= e2; j++) { 213 | const nextChild = c2[j] 214 | keyToNewIndexMap.set(nextChild.key, j) 215 | } 216 | 217 | for (let j = s1; j <= e1; j++) { 218 | const prevChild = c1[j] 219 | 220 | if (patched >= toBePatched) { 221 | // 所有新节点都已patch过,remove剩余旧节点 222 | hostRemove(prevChild.el) 223 | } 224 | 225 | let newIndex // 匹配节点的index 226 | if (prevChild.key !== null) { 227 | newIndex = keyToNewIndexMap.get(prevChild.key) // (1)根据映射查找 228 | } else { 229 | // (2)没有设置key,遍历查找 230 | for (let k = s2; k <= e2; k++) { 231 | if (isSameVNodeType(prevChild, c2[k])) { 232 | newIndex = k 233 | break 234 | } 235 | } 236 | } 237 | if (newIndex === undefined) { 238 | // 新中间节点没找到该旧节点----删除 239 | hostRemove(prevChild.el) 240 | } else { 241 | // 如果新节点大于旧 242 | if (newIndex >= maxNewIndexSoFar) { 243 | maxNewIndexSoFar = newIndex 244 | } else { 245 | // 否则移动位置 246 | moved = true 247 | } 248 | 249 | newIndexToOldIndexMap[newIndex - s2] = j + 1 250 | patch(prevChild, c2[newIndex], container, parentComponent, null) 251 | patched++ 252 | } 253 | } 254 | 255 | const increasingNewIndexSequence = moved ? getSequence(newIndexToOldIndexMap) : [] // 最长递增子序列 256 | // let p = 0 257 | // for (let j = 0; j < toBePatched; j++) { 258 | // if (j !== increasingNewIndexSequence[p]) { 259 | // // 移动位置 260 | // } else { 261 | // p++ 262 | // } 263 | // } 264 | // 倒序 265 | let p = increasingNewIndexSequence.length - 1 266 | for (let j = toBePatched - 1; j >= 0; j--) { 267 | const nextIndex = j + s2 268 | const nextChild = c2[nextIndex] 269 | const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : null 270 | 271 | if (newIndexToOldIndexMap[j] === 0) { 272 | // 创建新节点 273 | patch(null, nextChild, container, parentComponent, anchor) 274 | } else if (moved) { 275 | if (p < 0 || j !== increasingNewIndexSequence[p]) { 276 | // 移动位置 277 | hostInsert(nextChild.el, container, anchor) 278 | } else { 279 | p++ 280 | } 281 | } 282 | } 283 | } 284 | } 285 | 286 | /** 287 | * @description 288 | * @param children 289 | */ 290 | function unmountChildren(children: any) { 291 | for (let i = 0; i < children.length; i++) { 292 | const el = children[i].el; 293 | hostRemove(el) 294 | } 295 | } 296 | 297 | /** 298 | * @description 遍历新props和旧props对比 299 | * @param el 300 | * @param oldProps 301 | * @param newProps 302 | */ 303 | function patchProps(el: any, oldProps: any, newProps: any) { 304 | if (oldProps !== newProps) { 305 | for (const key in newProps) { 306 | const prevProp = oldProps[key] 307 | const nextProp = newProps[key] 308 | 309 | if (prevProp !== nextProp) { 310 | hostPatchProp(el, key, prevProp, nextProp) 311 | } 312 | } 313 | 314 | if (oldProps !== EMPTY_OBJ) { 315 | for (const key in oldProps) { 316 | if (!(key in newProps)) { 317 | hostPatchProp(el, key, oldProps[key], null) 318 | } 319 | } 320 | } 321 | } 322 | } 323 | 324 | function mountElement(vnode: any, container: any, parentComponent: any, anchor: any) { 325 | // vnode -> element 326 | 327 | // 基于DOM 328 | // const el = (vnode.el = document.createElement(vnode.type)) // string | array 329 | // 自定义渲染 330 | const el = (vnode.el = hostCreateElement(vnode.type)) // string | array 331 | const { children, props, shapeFlag } = vnode 332 | 333 | // text children | array children 334 | if (shapeFlag & ShapeFlags.TEXT_CHILDREN) { 335 | el.textContent = children 336 | } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { 337 | // 每个child调用patch 338 | mountChildren(vnode.children, el, parentComponent, anchor) 339 | } 340 | 341 | for (const key in props) { 342 | if (props.hasOwnProperty(key)) { 343 | const val = props[key]; 344 | // 基于DOM 345 | // if (isEvent(key)) { 346 | // const event = key.slice(2).toLowerCase() 347 | // el.addEventListener(event, val) 348 | // } else { 349 | // el.setAttribute(key, val) 350 | // } 351 | // 自定义渲染 352 | hostPatchProp(el, key, null, val) 353 | } 354 | } 355 | 356 | // 基于DOM 357 | // container.append(el) 358 | // 自定义渲染 359 | hostInsert(el, container, anchor) 360 | } 361 | 362 | /** 363 | * @description 处理数组类型children 364 | */ 365 | function mountChildren(children: any, container: any, parentComponent: any, anchor: any) { 366 | children.forEach(v => { 367 | patch(null, v, container, parentComponent, anchor) 368 | }); 369 | } 370 | 371 | /** 372 | * @description 处理组件类型 373 | */ 374 | function processComponent(n1: any, n2: any, container: any, parentComponent: any, anchor: any) { 375 | if (!n1) { 376 | 377 | mountComponent(n2, container, parentComponent, anchor) 378 | } else { 379 | updateComponent(n1, n2) 380 | } 381 | } 382 | 383 | /** 384 | * @description 组件初始化 385 | */ 386 | function mountComponent(initialVNode: any, container: any, parentComponent: any, anchor: any) { 387 | // 创建实例 388 | const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent)) 389 | 390 | // 执行setup 391 | setupComponent(instance) 392 | 393 | // 调用render 394 | setupRenderEffect(instance, initialVNode, container, anchor) 395 | } 396 | 397 | /** 398 | * @description 组件更新 399 | * @param n1 oldVNode 400 | * @param n2 newVNode 401 | */ 402 | function updateComponent(n1: any, n2: any) { 403 | const instance = (n2.component = n1.component) 404 | if (shouldUpdateComponent(n1, n2)) { 405 | 406 | instance.next = n2 // 下次要更新的虚拟节点 407 | instance.update() 408 | } else { // props未改变不需要更新 409 | n2.el = n1.el 410 | instance.vnode = n2 411 | } 412 | } 413 | 414 | /** 415 | * @description 生成虚拟节点 416 | */ 417 | function setupRenderEffect(instance: any, initialVNode: any, container: any, anchor: any) { 418 | instance.update = effect(() => { 419 | 420 | if (!instance.isMounted) { 421 | // init 422 | const { proxy } = instance 423 | const subTree = instance.subTree = instance.render.call(proxy, proxy) // 虚拟节点树 424 | 425 | patch(null, subTree, container, instance, anchor) 426 | 427 | initialVNode.el = subTree.el 428 | 429 | instance.isMounted = true 430 | } else { 431 | // update 432 | const { next, vnode } = instance // vnode: 更新之前的虚拟节点 next: 下次要更新的虚拟节点 433 | if (next) { 434 | next.el = vnode.el 435 | 436 | updateComponentPreRender(instance, next) 437 | } 438 | 439 | const { proxy } = instance 440 | const subTree = instance.render.call(proxy, proxy) // 虚拟节点树 441 | const prevSubTree = instance.subTree 442 | // 更新subTree 443 | instance.subTree = subTree 444 | 445 | patch(prevSubTree, subTree, container, instance, anchor) 446 | } 447 | }, 448 | { 449 | scheduler() { 450 | queueJobs(instance.update) 451 | } 452 | } 453 | ) 454 | } 455 | 456 | return { 457 | createApp: createAppAPI(render) 458 | } 459 | } 460 | 461 | function updateComponentPreRender(instance, nextVNode) { 462 | instance.vnode = nextVNode 463 | instance.next = null 464 | // update props 465 | instance.props = nextVNode.props 466 | } 467 | -------------------------------------------------------------------------------- /packages/runtime-core/src/scheduler.ts: -------------------------------------------------------------------------------- 1 | const queue: any[] = [] 2 | const activePreFlushCbs: any[] = [] 3 | 4 | let isFlushPending = false 5 | const p = Promise.resolve() 6 | 7 | /** 8 | * @description nextTick 9 | * @param fn 10 | */ 11 | export function nextTick(fn?) { 12 | // return fn ? Promise.resolve().then(fn()) : Promise.resolve() 13 | return fn ? p.then(fn) : p 14 | } 15 | 16 | export function queueJobs(job: any) { 17 | if (!queue.includes(job)) { 18 | queue.push(job) 19 | // 执行所有的 job 20 | queueFlush() 21 | } 22 | } 23 | 24 | function queueFlush() { 25 | // 如果同时触发了两个组件的更新的话 26 | // 这里就会触发两次 then (微任务逻辑) 27 | // 但是着是没有必要的 28 | // 只需要触发一次即可处理完所有的 job 调用 29 | // 所以需要判断一下 如果已经触发过 nextTick 了 30 | // 那么后面就不需要再次触发一次 nextTick 逻辑了 31 | if (isFlushPending) return 32 | isFlushPending = true 33 | // 微任务 34 | nextTick(flushJobs) 35 | // Promise.resolve().then(() => { 36 | // isFlushPending = false 37 | // let job 38 | // while (job = queue.shift()) { 39 | // job && job() 40 | // } 41 | // }) 42 | } 43 | 44 | export function queuePreFlushCb(cb) { 45 | queueCb(cb, activePreFlushCbs); 46 | } 47 | 48 | function queueCb(cb, activeQueue) { 49 | // 直接添加到对应的列表内就ok 50 | // todo 这里没有考虑 activeQueue 是否已经存在 cb 的情况 51 | // 然后在执行 flushJobs 的时候就可以调用 activeQueue 了 52 | activeQueue.push(cb); 53 | 54 | // 然后执行队列里面所有的 job 55 | queueFlush() 56 | } 57 | 58 | function flushJobs() { 59 | isFlushPending = false 60 | 61 | // 先执行 pre 类型的 job 62 | // 所以这里执行的job 是在渲染前的 63 | // 也就意味着执行这里的 job 的时候 页面还没有渲染 64 | flushPreFlushCbs() 65 | 66 | // component rende 67 | // 这里是执行 queueJob 的 68 | // 比如 render 渲染就是属于这个类型的 jobr 69 | let job 70 | while ((job = queue.shift())) { 71 | job && job() 72 | } 73 | } 74 | 75 | function flushPreFlushCbs() { 76 | // 执行所有的 pre 类型的 job 77 | for (let i = 0; i < activePreFlushCbs.length; i++) { 78 | activePreFlushCbs[i](); 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /packages/runtime-core/src/vnode.ts: -------------------------------------------------------------------------------- 1 | import { ShapeFlags } from "@my-vue/shared" 2 | 3 | export const Fragment = Symbol("Fragment") 4 | export const Text = Symbol("Text") 5 | 6 | export { 7 | createVNode as createElementVNode 8 | } 9 | 10 | export function createVNode(type, props?, children?) { 11 | const vnode = { 12 | type, 13 | props, 14 | children, 15 | shapeFlag: getShapeFlag(type), 16 | el: null, 17 | key: props && props.key, 18 | component: null, 19 | next: null // 下次要更新的虚拟节点 20 | } 21 | 22 | if (typeof children === "string") { 23 | vnode.shapeFlag |= ShapeFlags.TEXT_CHILDREN // 或运算 24 | } else if (Array.isArray(children)) { 25 | vnode.shapeFlag |= ShapeFlags.ARRAY_CHILDREN 26 | } 27 | 28 | // slots children 类型 29 | // 满足 自身时组件 + children = object 30 | if (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) { 31 | if (typeof children === 'object') { 32 | vnode.shapeFlag |= ShapeFlags.SLOT_CHILDREN 33 | } 34 | } 35 | 36 | return vnode 37 | } 38 | 39 | export function createTextVNode(text: string) { 40 | return createVNode(Text, {}, text) 41 | } 42 | 43 | function getShapeFlag(type) { 44 | return typeof type === "string" ? ShapeFlags.ELEMENT : ShapeFlags.STATEFUL_COMPONENT 45 | } 46 | -------------------------------------------------------------------------------- /packages/runtime-dom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-vue/runtime-dom", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@my-vue/runtime-core": "workspace:^1.0.0", 14 | "@my-vue/shared": "workspace:^1.0.0" 15 | } 16 | } -------------------------------------------------------------------------------- /packages/runtime-dom/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createRenderer } from '@my-vue/runtime-core' 2 | import { isEvent } from '@my-vue/shared' 3 | 4 | function createElement(type: any) { 5 | return document.createElement(type) 6 | } 7 | 8 | function patchProp(el, key, prevVal, nextVal) { 9 | if (isEvent(key)) { 10 | const event = key.slice(2).toLowerCase() 11 | el.addEventListener(event, nextVal) 12 | } else { 13 | if (nextVal === undefined || nextVal === null) { 14 | // 更新props为null或undefined时删除属性 15 | el.removeAttribute(key) 16 | } else { 17 | el.setAttribute(key, nextVal) 18 | } 19 | } 20 | } 21 | 22 | /** 23 | * @description 添加dom元素 24 | * @param child 25 | * @param parent 26 | * @param anchor 27 | */ 28 | function insert(child, parent, anchor) { 29 | // parent.append(el) 30 | parent.insertBefore(child, anchor || null) 31 | } 32 | 33 | function remove(child) { 34 | const parent = child.parentNode 35 | if (parent) { 36 | parent.removeChild(child) 37 | } 38 | } 39 | 40 | function setElementText(el, text) { 41 | el.textContent = text 42 | } 43 | 44 | const renderer: any = createRenderer({ 45 | createElement, 46 | patchProp, 47 | insert, 48 | remove, 49 | setElementText 50 | }) 51 | 52 | 53 | export function createApp(...args) { 54 | return renderer.createApp(...args) 55 | } 56 | 57 | export * from '@my-vue/runtime-core' 58 | -------------------------------------------------------------------------------- /packages/shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@my-vue/shared", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } -------------------------------------------------------------------------------- /packages/shared/src/ShapeFlags.ts: -------------------------------------------------------------------------------- 1 | export const enum ShapeFlags { 2 | ELEMENT = 1, // 0001 3 | STATEFUL_COMPONENT = 1 << 1, // 0010 4 | TEXT_CHILDREN = 1 << 2, // 0100 5 | ARRAY_CHILDREN = 1 << 3, // 1000 6 | SLOT_CHILDREN = 1 << 4, 7 | } 8 | -------------------------------------------------------------------------------- /packages/shared/src/getSequence.ts: -------------------------------------------------------------------------------- 1 | export function getSequence(arr: number[]): number[] { 2 | const p = arr.slice(); 3 | const result = [0]; 4 | let i, j, u, v, c; 5 | const len = arr.length; 6 | for (i = 0; i < len; i++) { 7 | const arrI = arr[i]; 8 | if (arrI !== 0) { 9 | j = result[result.length - 1]; 10 | if (arr[j] < arrI) { 11 | p[i] = j; 12 | result.push(i); 13 | continue; 14 | } 15 | u = 0; 16 | v = result.length - 1; 17 | while (u < v) { 18 | c = (u + v) >> 1; 19 | if (arr[result[c]] < arrI) { 20 | u = c + 1; 21 | } else { 22 | v = c; 23 | } 24 | } 25 | if (arrI < arr[result[u]]) { 26 | if (u > 0) { 27 | p[i] = result[u - 1]; 28 | } 29 | result[u] = i; 30 | } 31 | } 32 | } 33 | u = result.length; 34 | v = result[u - 1]; 35 | while (u-- > 0) { 36 | result[u] = v; 37 | v = p[v]; 38 | } 39 | return result; 40 | } 41 | -------------------------------------------------------------------------------- /packages/shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './toDisplayString' 2 | export * from './ShapeFlags' 3 | export * from './getSequence' 4 | 5 | export const extend = Object.assign; 6 | 7 | export const EMPTY_OBJ = {} 8 | 9 | export const isObject = val => { 10 | return val !== null && typeof val === "object"; 11 | }; 12 | 13 | export const isString = val => typeof val === 'string' 14 | 15 | export const hasChanged = (val, newVal) => { 16 | return !Object.is(val, newVal); 17 | }; 18 | 19 | export const isEvent = (key: string) => /^on[A-Z]/.test(key) 20 | 21 | export const hasOwn = (val, key) => Object.prototype.hasOwnProperty.call(val, key) 22 | 23 | /** 24 | * @description 首字母大写 25 | */ 26 | export const capitalize = (str: string) => { 27 | return str.charAt(0).toUpperCase() + str.slice(1) 28 | } 29 | 30 | /** 31 | * @description 字符串前加上'on' 32 | */ 33 | export const toHandleKey = (str: string) => { 34 | return str ? 'on' + capitalize(str) : '' 35 | } 36 | 37 | /** 38 | * @description keybabcase to camelcase 39 | */ 40 | export const camelize = (str: string) => { 41 | return str.replace(/-(\w)/g, (_, c: string) => c ? c.toUpperCase() : '') 42 | } 43 | -------------------------------------------------------------------------------- /packages/shared/src/toDisplayString.ts: -------------------------------------------------------------------------------- 1 | export function toDisplayString(value) { 2 | return String(value) 3 | } 4 | -------------------------------------------------------------------------------- /packages/vue/examples/apiInject/App.js: -------------------------------------------------------------------------------- 1 | // 组件provide,inject功能 2 | import { h, provide, inject } from '../../dist/my-vue.esm.js' 3 | 4 | const Provider = { 5 | name: "Provider", 6 | 7 | setup() { 8 | provide('foo', "fooVal") 9 | provide('bar', "barVal") 10 | }, 11 | 12 | render() { 13 | return h('div', {}, [h('p', {}, "Provider"), h(Provider2)]) 14 | } 15 | } 16 | 17 | const Provider2 = { 18 | name: "Provider2", 19 | 20 | setup() { 21 | provide('foo', 'fooVal2') 22 | provide('bar2', 'bar2Val') 23 | const foo = inject('foo') 24 | 25 | return { 26 | foo 27 | } 28 | }, 29 | 30 | render() { 31 | return h('div', {}, [h('p', {}, `Provider2: foo - ${this.foo}`), h(Consumer)]) 32 | } 33 | } 34 | 35 | const Consumer = { 36 | name: 'Consumer', 37 | 38 | setup() { 39 | const foo = inject('foo') 40 | const bar = inject('bar') 41 | const fooBar = inject('fooBar', 'defaultValue') 42 | 43 | return { 44 | foo, 45 | bar, 46 | fooBar 47 | } 48 | }, 49 | 50 | render() { 51 | return h('div', {}, `Consumer: - ${this.foo} - ${this.bar} - ${this.fooBar}`) 52 | } 53 | } 54 | 55 | export default { 56 | name: "App", 57 | setup() { }, 58 | render() { 59 | return h('div', {}, [h('p', {}, 'apiInject'), h(Provider)]) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/vue/examples/apiInject/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Document 11 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /packages/vue/examples/apiInject/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import App from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/compilerBase/App.js: -------------------------------------------------------------------------------- 1 | // 最简单的情况 2 | // template 只有一个 interpolation 3 | // export default { 4 | // name: "App", 5 | // template: `
hi,{{msg}}
`, 6 | // setup() { 7 | // return { 8 | // msg: "vue3 - compiler", 9 | // }; 10 | // }, 11 | // }; 12 | 13 | 14 | // 复杂一点 15 | // template 包含 element 和 interpolation 16 | import { ref } from '../../dist/my-vue.esm.js' 17 | export default { 18 | template: `
{{msg}}{{count}}
`, 19 | setup() { 20 | const count = window.count = ref(1) 21 | return { 22 | msg: "vue3 - compiler", 23 | count 24 | }; 25 | }, 26 | }; -------------------------------------------------------------------------------- /packages/vue/examples/compilerBase/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 |
12 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /packages/vue/examples/componentSlot/App.js: -------------------------------------------------------------------------------- 1 | import { createTextVNode, h } from '../../dist/my-vue.esm.js' 2 | import { Foo } from './Foo.js' 3 | 4 | export const App = { 5 | name: "App", 6 | 7 | setup() { 8 | return {} 9 | }, 10 | 11 | render() { 12 | const app = h('div', {}, 'App') 13 | const foo = h(Foo, {}, 14 | { 15 | header: ({ age }) => [ 16 | h('p', {}, 'header' + age), 17 | createTextVNode("this is header") 18 | ], 19 | footer: () => h('p', {}, 'footer') 20 | } 21 | ) 22 | 23 | return h('div', {}, [app, foo]) 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /packages/vue/examples/componentSlot/Foo.js: -------------------------------------------------------------------------------- 1 | import { h, renderSlots } from '../../dist/my-vue.esm.js' 2 | 3 | export const Foo = { 4 | name: "Foo", 5 | 6 | setup() { 7 | return {} 8 | }, 9 | 10 | render() { 11 | const foo = h('p', {}, 'foo') 12 | 13 | const age = 18 14 | return h('div', {}, [ 15 | renderSlots(this.$slots, "header", { 16 | age 17 | }), 18 | foo, 19 | renderSlots(this.$slots, "footer") 20 | ]) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/vue/examples/componentSlot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /packages/vue/examples/componentSlot/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import { App } from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/componentUpdate/App.js: -------------------------------------------------------------------------------- 1 | // 在 render 中使用 proxy 调用 emit 函数 2 | // 也可以直接使用 this 3 | // 验证 proxy 的实现逻辑 4 | import { h, ref } from '../../dist/my-vue.esm.js' 5 | import Child from "./Child.js"; 6 | 7 | export default { 8 | name: "App", 9 | setup() { 10 | const msg = ref("123"); 11 | const count = ref(1) 12 | 13 | window.msg = msg 14 | 15 | const changeChildProps = () => { 16 | msg.value = "456"; 17 | }; 18 | 19 | const changeCount = () => { 20 | count.value++ 21 | } 22 | 23 | return { msg, changeChildProps, count, changeCount }; 24 | }, 25 | 26 | render() { 27 | return h("div", {}, [ 28 | h("div", {}, "你好"), 29 | h( 30 | "button", 31 | { 32 | onClick: this.changeChildProps, 33 | }, 34 | "change child props" 35 | ), 36 | h(Child, { 37 | msg: this.msg, 38 | }), 39 | h( 40 | 'button', 41 | { 42 | onClick: this.changeCount, 43 | }, 44 | 'change self count' 45 | ), 46 | h('p', {}, 'count' + this.count) 47 | ]); 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /packages/vue/examples/componentUpdate/Child.js: -------------------------------------------------------------------------------- 1 | import { h, ref, reactive } from '../../dist/my-vue.esm.js' 2 | export default { 3 | name: "Child", 4 | setup(props, { emit }) { }, 5 | render(proxy) { 6 | return h("div", {}, [h("div", {}, "child" + this.$props.msg)]); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/vue/examples/componentUpdate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/vue/examples/componentUpdate/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import App from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/currentInstance/App.js: -------------------------------------------------------------------------------- 1 | import { h, getCurrentInstance } from '../../dist/my-vue.esm.js' 2 | import { Foo } from './Foo.js' 3 | 4 | export const App = { 5 | name: "App", 6 | render() { 7 | return h("div", {}, [h("p", {}, "currentInstance demo"), h(Foo)]) 8 | }, 9 | 10 | setup() { 11 | const instance = getCurrentInstance() 12 | console.log("App:", instance) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/vue/examples/currentInstance/Foo.js: -------------------------------------------------------------------------------- 1 | import { h, getCurrentInstance } from '../../dist/my-vue.esm.js' 2 | 3 | export const Foo = { 4 | name: "Foo", 5 | 6 | render() { 7 | return h('div', {}, 'Foo') 8 | }, 9 | 10 | setup() { 11 | const instance = getCurrentInstance() 12 | console.log("Foo:", instance) 13 | return {} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/vue/examples/currentInstance/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/vue/examples/currentInstance/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import { App } from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/customRenderer/App.js: -------------------------------------------------------------------------------- 1 | import { h } from '../../dist/my-vue.esm.js' 2 | 3 | export const App = { 4 | setup() { 5 | return { 6 | x: 100, 7 | y: 100 8 | } 9 | }, 10 | 11 | render() { 12 | return h('rect', { x: this.x, y: this.y }) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/vue/examples/customRenderer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/vue/examples/customRenderer/main.js: -------------------------------------------------------------------------------- 1 | import { createRenderer } from '../../dist/my-vue.esm.js' 2 | import { App } from './App.js' 3 | 4 | const game = new PIXI.Application({ 5 | width: 500, 6 | height: 500 7 | }) 8 | 9 | document.body.append(game.view) 10 | 11 | const renderer = createRenderer({ 12 | createElement(type) { 13 | if (type === 'rect') { 14 | const rect = new PIXI.Graphics() 15 | rect.beginFill(0xff0000) 16 | rect.drawRect(0, 0, 100, 100) 17 | rect.endFill() 18 | return rect 19 | } 20 | }, 21 | 22 | patchProp(el, key, val) { 23 | el[key] = val 24 | }, 25 | 26 | insert(el, parent) { 27 | parent.addChild(el) 28 | } 29 | }) 30 | 31 | renderer.createApp(App).mount(game.stage) 32 | -------------------------------------------------------------------------------- /packages/vue/examples/helloworld/App.js: -------------------------------------------------------------------------------- 1 | import { h } from '../../dist/my-vue.esm.js' 2 | import { Foo } from './Foo.js' 3 | 4 | window.self = null 5 | export const App = { 6 | // .vue 7 | // 8 | // render 9 | name: "App", 10 | 11 | render() { 12 | window.self = this 13 | return h('div', { 14 | id: "root", 15 | class: ["red", "hard"], 16 | // onClick: () => { 17 | // console.log('click') 18 | // }, 19 | // onMousedown: () => { 20 | // console.log('mousedown') 21 | // } 22 | }, 23 | // setupState 24 | // this.$el 25 | // 'hello, ' + this.msg 26 | // [ 27 | // h("p", { class: 'pink' }, "hi"), 28 | // h("p", { class: 'skyblue' }, "mini-vue") 29 | // ] 30 | [ 31 | h("div", {}, "hi," + this.msg), 32 | h(Foo, { 33 | count: 1, 34 | onEmit: (a, b) => { 35 | console.log(a, b) 36 | }, 37 | onEmitFoo: () => { 38 | console.log('emit foo') 39 | } 40 | }) 41 | ] 42 | ) 43 | }, 44 | 45 | setup() { 46 | return { 47 | msg: 'vue3-core', 48 | } 49 | }, 50 | } 51 | -------------------------------------------------------------------------------- /packages/vue/examples/helloworld/Foo.js: -------------------------------------------------------------------------------- 1 | import { h } from '../../dist/my-vue.esm.js' 2 | 3 | export const Foo = { 4 | setup(props, { emit }) { 5 | // props 6 | console.log(props) 7 | props.count++ 8 | console.log(props) 9 | 10 | 11 | // emit 12 | const emitAdd = () => { 13 | emit("emit", 1, 2) 14 | emit('emit-foo') 15 | } 16 | return { 17 | emitAdd 18 | } 19 | }, 20 | 21 | 22 | render() { 23 | const foo = h( 24 | "p", 25 | { 26 | onMousedown: () => { 27 | console.log('onMousedown') 28 | } 29 | }, 30 | "foo: " + this.count 31 | ) 32 | 33 | const btn = h( 34 | 'button', 35 | { 36 | onClick: this.emitAdd, 37 | }, 38 | 'emitAdd' 39 | ) 40 | 41 | return h('div', {}, [foo, btn]) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/vue/examples/helloworld/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /packages/vue/examples/helloworld/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import { App } from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/nextTicker/App.js: -------------------------------------------------------------------------------- 1 | import { h, ref, reactive, getCurrentInstance, nextTick } from '../../dist/my-vue.esm.js' 2 | 3 | export default { 4 | name: "App", 5 | setup() { 6 | const count = ref(1) 7 | const instance = getCurrentInstance() 8 | 9 | function onClick() { 10 | for (let i = 0; i < 100; i++) { 11 | console.log('update') 12 | count.value = i 13 | } 14 | 15 | nextTick(() => { 16 | console.log('nextTick', instance) 17 | }) 18 | } 19 | 20 | return { 21 | onClick, 22 | count 23 | } 24 | }, 25 | 26 | render() { 27 | const btn = h( 28 | 'button', 29 | { 30 | onClick: this.onClick 31 | }, 32 | 'update') 33 | 34 | const p = h('p', {}, 'count:' + this.count) 35 | 36 | return h('div', {}, [btn, p]) 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /packages/vue/examples/nextTicker/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Document 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/vue/examples/nextTicker/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import App from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/App.js: -------------------------------------------------------------------------------- 1 | import { h } from '../../dist/my-vue.esm.js' 2 | 3 | import ArrayToArray from './ArrayToArray.js' 4 | import ArrayToText from './ArrayToText.js' 5 | import TextToArray from './TextToArray.js' 6 | import TextToText from './TextToText.js' 7 | 8 | export default { 9 | name: 'App', 10 | 11 | setup() { 12 | 13 | }, 14 | 15 | render() { 16 | return h('div', { tId: 1 }, [ 17 | h('p', {}, "home"), 18 | h(ArrayToText), 19 | h(TextToText), 20 | h(TextToArray), 21 | h('p', {}, '-------------diff--------------'), 22 | h(ArrayToArray) 23 | ]) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/ArrayToArray.js: -------------------------------------------------------------------------------- 1 | import { h, ref } from '../../dist/my-vue.esm.js' 2 | 3 | // 1.1 左侧对比 4 | // (A B) C 5 | // (A B) D E 6 | /* const prevChildren = [ */ 7 | /* h('p', { key: 'A' }, 'A'), */ 8 | /* h('p', { key: 'B' }, 'B'), */ 9 | /* h('p', { key: 'C' }, 'C'), */ 10 | /* ] */ 11 | /* const nextChildren = [ */ 12 | /* h('p', { key: 'A' }, 'A'), */ 13 | /* h('p', { key: 'B' }, 'B'), */ 14 | /* h('p', { key: 'D' }, 'D'), */ 15 | /* h('p', { key: 'E' }, 'E'), */ 16 | /* ] */ 17 | 18 | // 1.2 右侧对比 19 | // A (B C) 20 | // D E (B C) 21 | /* const prevChildren = [ */ 22 | /* h('p', { key: 'A' }, 'A'), */ 23 | /* h('p', { key: 'B' }, 'B'), */ 24 | /* h('p', { key: 'C' }, 'C'), */ 25 | /* ] */ 26 | /* const nextChildren = [ */ 27 | /* h('p', { key: 'D' }, 'D'), */ 28 | /* h('p', { key: 'E' }, 'E'), */ 29 | /* h('p', { key: 'B' }, 'B'), */ 30 | /* h('p', { key: 'C' }, 'C'), */ 31 | /* ] */ 32 | 33 | // 2. 新的比旧的长 34 | // 2.1 左侧 35 | // (A B) 36 | // (A B) C D 37 | /* const prevChildren = [ */ 38 | /* h('p', { key: 'A' }, 'A'), */ 39 | /* h('p', { key: 'B' }, 'B'), */ 40 | /* ] */ 41 | /* const nextChildren = [ */ 42 | /* h('p', { key: 'A' }, 'A'), */ 43 | /* h('p', { key: 'B' }, 'B'), */ 44 | /* h('p', { key: 'C' }, 'C'), */ 45 | /* h('p', { key: 'D' }, 'D'), */ 46 | /* ] */ 47 | // 2.2 右侧 48 | // (A B) 49 | // C (A B) 50 | /* const prevChildren = [ */ 51 | /* h('p', { key: 'A' }, 'A'), */ 52 | /* h('p', { key: 'B' }, 'B'), */ 53 | /* ] */ 54 | /* const nextChildren = [ */ 55 | /* h('p', { key: 'D' }, 'D'), */ 56 | /* h('p', { key: 'C' }, 'C'), */ 57 | /* h('p', { key: 'A' }, 'A'), */ 58 | /* h('p', { key: 'B' }, 'B'), */ 59 | /* ] */ 60 | 61 | // 3. 旧的比新的长 62 | // 3.1 左侧 63 | // (A B) C 64 | // (A B) 65 | /* const prevChildren = [ */ 66 | /* h('p', { key: 'A' }, 'A'), */ 67 | /* h('p', { key: 'B' }, 'B'), */ 68 | /* h('p', { key: 'C' }, 'C'), */ 69 | /* h('p', { key: 'D' }, 'D'), */ 70 | /* ] */ 71 | /* const nextChildren = [ */ 72 | /* h('p', { key: 'A' }, 'A'), */ 73 | /* h('p', { key: 'B' }, 'B'), */ 74 | /* ] */ 75 | // 3.2 右侧 76 | /* const prevChildren = [ */ 77 | /* h('p', { key: 'A' }, 'A'), */ 78 | /* h('p', { key: 'B' }, 'B'), */ 79 | /* h('p', { key: 'C' }, 'C'), */ 80 | /* h('p', { key: 'D' }, 'D'), */ 81 | /* ] */ 82 | /* const nextChildren = [ */ 83 | /* h('p', { key: 'C' }, 'C'), */ 84 | /* h('p', { key: 'D' }, 'D'), */ 85 | /* ] */ 86 | 87 | // 4.1 中间对比 88 | // A B (C D) F G 89 | // A B (E C) F G 90 | /* const prevChildren = [ */ 91 | /* h('p', { key: 'A' }, 'A'), */ 92 | /* h('p', { key: 'B' }, 'B'), */ 93 | /* h('p', { key: 'C', id: 'c-prev' }, 'C'), */ 94 | /* h('p', { key: 'D' }, 'D'), */ 95 | /* h('p', { key: 'F' }, 'F'), */ 96 | /* h('p', { key: 'G' }, 'G'), */ 97 | /* ] */ 98 | /* const nextChildren = [ */ 99 | /* h('p', { key: 'A' }, 'A'), */ 100 | /* h('p', { key: 'B' }, 'B'), */ 101 | /* h('p', { key: 'E' }, 'E'), */ 102 | /* h('p', { key: 'C', id: 'c-next' }, 'C'), */ 103 | /* h('p', { key: 'F' }, 'F'), */ 104 | /* h('p', { key: 'G' }, 'G'), */ 105 | /* ] */ 106 | // 4.2 优化 107 | // A B (C E D) F G 108 | // A B (E C) F G 109 | /* const prevChildren = [ */ 110 | /* h('p', { key: 'A' }, 'A'), */ 111 | /* h('p', { key: 'B' }, 'B'), */ 112 | /* h('p', { key: 'C', id: 'c-prev' }, 'C'), */ 113 | /* h('p', { key: 'E' }, 'E'), */ 114 | /* h('p', { key: 'D' }, 'D'), */ 115 | /* h('p', { key: 'F' }, 'F'), */ 116 | /* h('p', { key: 'G' }, 'G'), */ 117 | /* ] */ 118 | /* const nextChildren = [ */ 119 | /* h('p', { key: 'A' }, 'A'), */ 120 | /* h('p', { key: 'B' }, 'B'), */ 121 | /* h('p', { key: 'E' }, 'E'), */ 122 | /* h('p', { key: 'C', id: 'c-next' }, 'C'), */ 123 | /* h('p', { key: 'F' }, 'F'), */ 124 | /* h('p', { key: 'G' }, 'G'), */ 125 | /* ] */ 126 | // 4.3. 127 | // A B (C D E) F G 128 | // A B (E C D) F G 129 | // 最长子序列 【1,2】 130 | /* const prevChildren = [ */ 131 | /* h('p', { key: 'A' }, 'A'), */ 132 | /* h('p', { key: 'B' }, 'B'), */ 133 | /* h('p', { key: 'C' }, 'C'), */ 134 | /* h('p', { key: 'D' }, 'D'), */ 135 | /* h('p', { key: 'E' }, 'E'), */ 136 | /* h('p', { key: 'F' }, 'F'), */ 137 | /* h('p', { key: 'G' }, 'G'), */ 138 | /* ] */ 139 | /* const nextChildren = [ */ 140 | /* h('p', { key: 'A' }, 'A'), */ 141 | /* h('p', { key: 'B' }, 'B'), */ 142 | /* h('p', { key: 'E' }, 'E'), */ 143 | /* h('p', { key: 'C' }, 'C'), */ 144 | /* h('p', { key: 'D' }, 'D'), */ 145 | /* h('p', { key: 'F' }, 'F'), */ 146 | /* ] */ 147 | /* h('p', { key: 'G' }, 'G'), */ 148 | 149 | // 4.4 包含新节点 150 | // A B (C E) F G 151 | // A B (E C D) F G 152 | /* const prevChildren = [ */ 153 | /* h('p', { key: 'A' }, 'A'), */ 154 | /* h('p', { key: 'B' }, 'B'), */ 155 | /* h('p', { key: 'C' }, 'C'), */ 156 | /* h('p', { key: 'E' }, 'E'), */ 157 | /* h('p', { key: 'F' }, 'F'), */ 158 | /* h('p', { key: 'G' }, 'G'), */ 159 | /* ] */ 160 | /* const nextChildren = [ */ 161 | /* h('p', { key: 'A' }, 'A'), */ 162 | /* h('p', { key: 'B' }, 'B'), */ 163 | /* h('p', { key: 'E' }, 'E'), */ 164 | /* h('p', { key: 'C' }, 'C'), */ 165 | /* h('p', { key: 'D' }, 'D'), */ 166 | /* h('p', { key: 'F' }, 'F'), */ 167 | /* h('p', { key: 'G' }, 'G'), */ 168 | /* ] */ 169 | 170 | 171 | // 4.4 综合例子 172 | // A B (C D E Z) F G 173 | // A B (D C Y E) F G 174 | /* const prevChildren = [ */ 175 | /* h('p', { key: 'A' }, 'A'), */ 176 | /* h('p', { key: 'B' }, 'B'), */ 177 | /* h('p', { key: 'C' }, 'C'), */ 178 | /* h('p', { key: 'D' }, 'D'), */ 179 | /* h('p', { key: 'E' }, 'E'), */ 180 | /* h('p', { key: 'Z' }, 'Z'), */ 181 | /* h('p', { key: 'F' }, 'F'), */ 182 | /* h('p', { key: 'G' }, 'G'), */ 183 | /* ] */ 184 | /* const nextChildren = [ */ 185 | /* h('p', { key: 'A' }, 'A'), */ 186 | /* h('p', { key: 'B' }, 'B'), */ 187 | /* h('p', { key: 'D' }, 'D'), */ 188 | /* h('p', { key: 'C' }, 'C'), */ 189 | /* h('p', { key: 'Y' }, 'Y'), */ 190 | /* h('p', { key: 'E' }, 'E'), */ 191 | /* h('p', { key: 'F' }, 'F'), */ 192 | /* h('p', { key: 'G' }, 'G'), */ 193 | /* ] */ 194 | 195 | // fix 196 | const prevChildren = [ 197 | h('p', { key: 'A' }, 'A'), 198 | h('p', {}, 'C'), 199 | h('p', { key: 'B' }, 'B'), 200 | h('p', { key: 'D' }, 'D'), 201 | ] 202 | const nextChildren = [ 203 | h('p', { key: 'A' }, 'A'), 204 | h('p', { key: 'B' }, 'B'), 205 | h('p', {}, 'C'), 206 | h('p', { key: 'D' }, 'D'), 207 | ] 208 | 209 | export default { 210 | name: "ArrayToArray", 211 | setup() { 212 | const array2array = ref(false) 213 | window.array2array = array2array 214 | 215 | return { 216 | isChange: array2array 217 | } 218 | }, 219 | 220 | render() { 221 | const self = this 222 | 223 | return self.isChange === true 224 | ? h('div', {}, nextChildren) 225 | : h('div', {}, prevChildren) 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/ArrayToText.js: -------------------------------------------------------------------------------- 1 | import { h, ref } from '../../dist/my-vue.esm.js' 2 | 3 | const nextChildren = 'array2text' 4 | const prevChildren = [h('div', {}, "A"), h('div', {}, 'B')] 5 | 6 | export default { 7 | name: "ArrayToText", 8 | setup() { 9 | const array2text = ref(false) 10 | window.array2text = array2text 11 | 12 | return { 13 | isChange: array2text 14 | } 15 | }, 16 | 17 | render() { 18 | const self = this 19 | 20 | return self.isChange === true 21 | ? h('div', {}, nextChildren) 22 | : h('div', {}, prevChildren) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/TextToArray.js: -------------------------------------------------------------------------------- 1 | import { h, ref } from '../../dist/my-vue.esm.js' 2 | 3 | const prevChildren = 'oldText' 4 | const nextChildren = [h('div', {}, "A"), h('div', {}, 'B')] 5 | 6 | export default { 7 | name: "ArrayToText", 8 | setup() { 9 | const text2array = ref(false) 10 | window.text2array = text2array 11 | 12 | return { 13 | isChange: text2array 14 | } 15 | }, 16 | 17 | render() { 18 | const self = this 19 | 20 | return self.isChange === true 21 | ? h('div', {}, nextChildren) 22 | : h('div', {}, prevChildren) 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/TextToText.js: -------------------------------------------------------------------------------- 1 | 2 | import { h, ref } from '../../dist/my-vue.esm.js' 3 | 4 | const nextChildren = 'newText' 5 | const prevChildren = 'oldText' 6 | 7 | export default { 8 | name: "TextToText", 9 | setup() { 10 | const text2text = ref(false) 11 | window.text2text = text2text 12 | 13 | return { 14 | isChange: text2text 15 | } 16 | }, 17 | 18 | render() { 19 | const self = this 20 | 21 | return self.isChange === true 22 | ? h('div', {}, nextChildren) 23 | : h('div', {}, prevChildren) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Document 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /packages/vue/examples/patchChildren/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import App from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/examples/update/App.js: -------------------------------------------------------------------------------- 1 | import { h, ref } from '../../dist/my-vue.esm.js' 2 | 3 | export const App = { 4 | name: "App", 5 | 6 | setup() { 7 | const count = ref(0) 8 | 9 | const onClick = () => { 10 | count.value++ 11 | } 12 | 13 | const props = ref({ 14 | foo: 'foo', 15 | bar: 'bar' 16 | }) 17 | 18 | const onChangePropsDemo1 = () => { 19 | props.value.foo = 'new-foo' 20 | } 21 | 22 | const onChangePropsDemo2 = () => { 23 | props.value.foo = undefined 24 | } 25 | 26 | const onChangePropsDemo3 = () => { 27 | props.value = { 28 | foo: 'foo' 29 | } 30 | } 31 | 32 | return { 33 | count, 34 | onClick, 35 | onChangePropsDemo1, 36 | onChangePropsDemo2, 37 | onChangePropsDemo3, 38 | props 39 | } 40 | }, 41 | 42 | render() { 43 | return h( 44 | 'div', 45 | { 46 | id: 'root', 47 | ...this.props 48 | }, 49 | [ 50 | h('div', {}, 'count' + this.count), 51 | h( 52 | 'button', 53 | { 54 | onClick: this.onClick 55 | }, 56 | 'click' 57 | ), 58 | h( 59 | 'button', 60 | { 61 | onClick: this.onChangePropsDemo1 62 | }, 63 | '1.值改变了 - 修改' 64 | ), 65 | h( 66 | 'button', 67 | { 68 | onClick: this.onChangePropsDemo2 69 | }, 70 | '2.值变成了undefined - 删除' 71 | ), 72 | h( 73 | 'button', 74 | { 75 | onClick: this.onChangePropsDemo3 76 | }, 77 | '3. 属性在新的里面没了 - 删除' 78 | ), 79 | ] 80 | ) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /packages/vue/examples/update/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Document 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /packages/vue/examples/update/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from '../../dist/my-vue.esm.js' 2 | import { App } from './App.js' 3 | 4 | const rootContainer = document.querySelector('#app') 5 | createApp(App).mount(rootContainer) 6 | -------------------------------------------------------------------------------- /packages/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-vue", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@my-vue/compiler-core": "workspace:^1.0.0", 14 | "@my-vue/runtime-dom": "workspace:^1.0.0" 15 | } 16 | } -------------------------------------------------------------------------------- /packages/vue/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@my-vue/runtime-dom' 2 | import { registerRuntimeCompiler } from '@my-vue/runtime-dom' 3 | 4 | import * as runtimeDom from '@my-vue/runtime-dom' 5 | import { baseCompile } from '@my-vue/compiler-core' 6 | 7 | function compileToFunction(template: any) { 8 | const { code } = baseCompile(template) 9 | // 调用 compile 得到的代码在给封装到函数内, 10 | // 这里会依赖 runtimeDom 的一些函数,所以在这里通过参数的形式注入进去 11 | const render = new Function("Vue", code)(runtimeDom) 12 | 13 | return render 14 | } 15 | 16 | registerRuntimeCompiler(compileToFunction) -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | importers: 4 | 5 | .: 6 | specifiers: 7 | '@babel/core': ^7.17.4 8 | '@babel/preset-env': ^7.16.11 9 | '@babel/preset-typescript': ^7.16.7 10 | '@rollup/plugin-typescript': ^10.0.1 11 | rollup: ^3.7.5 12 | tslib: ^2.4.1 13 | typescript: ^4.5.5 14 | vite: ^4.1.2 15 | vitest: ^0.28.4 16 | devDependencies: 17 | '@babel/core': 7.20.12 18 | '@babel/preset-env': 7.20.2_@babel+core@7.20.12 19 | '@babel/preset-typescript': 7.18.6_@babel+core@7.20.12 20 | '@rollup/plugin-typescript': 10.0.1_m3kxv4pqnmlodzidcpaglsppii 21 | rollup: 3.12.0 22 | tslib: 2.5.0 23 | typescript: 4.9.4 24 | vite: 4.1.2 25 | vitest: 0.28.4 26 | 27 | packages/compiler-core: 28 | specifiers: 29 | '@my-vue/shared': workspace:^1.0.0 30 | dependencies: 31 | '@my-vue/shared': link:../shared 32 | 33 | packages/reactivity: 34 | specifiers: 35 | '@my-vue/shared': workspace:^1.0.0 36 | dependencies: 37 | '@my-vue/shared': link:../shared 38 | 39 | packages/runtime-core: 40 | specifiers: 41 | '@my-vue/reactivity': workspace:^1.0.0 42 | '@my-vue/shared': workspace:^1.0.0 43 | dependencies: 44 | '@my-vue/reactivity': link:../reactivity 45 | '@my-vue/shared': link:../shared 46 | 47 | packages/runtime-dom: 48 | specifiers: 49 | '@my-vue/runtime-core': workspace:^1.0.0 50 | '@my-vue/shared': workspace:^1.0.0 51 | dependencies: 52 | '@my-vue/runtime-core': link:../runtime-core 53 | '@my-vue/shared': link:../shared 54 | 55 | packages/shared: 56 | specifiers: {} 57 | 58 | packages/vue: 59 | specifiers: 60 | '@my-vue/compiler-core': workspace:^1.0.0 61 | '@my-vue/runtime-dom': workspace:^1.0.0 62 | dependencies: 63 | '@my-vue/compiler-core': link:../compiler-core 64 | '@my-vue/runtime-dom': link:../runtime-dom 65 | 66 | packages: 67 | 68 | /@ampproject/remapping/2.2.0: 69 | resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} 70 | engines: {node: '>=6.0.0'} 71 | dependencies: 72 | '@jridgewell/gen-mapping': 0.1.1 73 | '@jridgewell/trace-mapping': 0.3.17 74 | dev: true 75 | 76 | /@babel/code-frame/7.18.6: 77 | resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} 78 | engines: {node: '>=6.9.0'} 79 | dependencies: 80 | '@babel/highlight': 7.18.6 81 | dev: true 82 | 83 | /@babel/compat-data/7.20.14: 84 | resolution: {integrity: sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==} 85 | engines: {node: '>=6.9.0'} 86 | dev: true 87 | 88 | /@babel/core/7.20.12: 89 | resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==} 90 | engines: {node: '>=6.9.0'} 91 | dependencies: 92 | '@ampproject/remapping': 2.2.0 93 | '@babel/code-frame': 7.18.6 94 | '@babel/generator': 7.20.14 95 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 96 | '@babel/helper-module-transforms': 7.20.11 97 | '@babel/helpers': 7.20.13 98 | '@babel/parser': 7.20.13 99 | '@babel/template': 7.20.7 100 | '@babel/traverse': 7.20.13 101 | '@babel/types': 7.20.7 102 | convert-source-map: 1.9.0 103 | debug: 4.3.4 104 | gensync: 1.0.0-beta.2 105 | json5: 2.2.3 106 | semver: 6.3.0 107 | transitivePeerDependencies: 108 | - supports-color 109 | dev: true 110 | 111 | /@babel/generator/7.20.14: 112 | resolution: {integrity: sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==} 113 | engines: {node: '>=6.9.0'} 114 | dependencies: 115 | '@babel/types': 7.20.7 116 | '@jridgewell/gen-mapping': 0.3.2 117 | jsesc: 2.5.2 118 | dev: true 119 | 120 | /@babel/helper-annotate-as-pure/7.18.6: 121 | resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} 122 | engines: {node: '>=6.9.0'} 123 | dependencies: 124 | '@babel/types': 7.20.7 125 | dev: true 126 | 127 | /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: 128 | resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} 129 | engines: {node: '>=6.9.0'} 130 | dependencies: 131 | '@babel/helper-explode-assignable-expression': 7.18.6 132 | '@babel/types': 7.20.7 133 | dev: true 134 | 135 | /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12: 136 | resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} 137 | engines: {node: '>=6.9.0'} 138 | peerDependencies: 139 | '@babel/core': ^7.0.0 140 | dependencies: 141 | '@babel/compat-data': 7.20.14 142 | '@babel/core': 7.20.12 143 | '@babel/helper-validator-option': 7.18.6 144 | browserslist: 4.21.4 145 | lru-cache: 5.1.1 146 | semver: 6.3.0 147 | dev: true 148 | 149 | /@babel/helper-create-class-features-plugin/7.20.12_@babel+core@7.20.12: 150 | resolution: {integrity: sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==} 151 | engines: {node: '>=6.9.0'} 152 | peerDependencies: 153 | '@babel/core': ^7.0.0 154 | dependencies: 155 | '@babel/core': 7.20.12 156 | '@babel/helper-annotate-as-pure': 7.18.6 157 | '@babel/helper-environment-visitor': 7.18.9 158 | '@babel/helper-function-name': 7.19.0 159 | '@babel/helper-member-expression-to-functions': 7.20.7 160 | '@babel/helper-optimise-call-expression': 7.18.6 161 | '@babel/helper-replace-supers': 7.20.7 162 | '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 163 | '@babel/helper-split-export-declaration': 7.18.6 164 | transitivePeerDependencies: 165 | - supports-color 166 | dev: true 167 | 168 | /@babel/helper-create-regexp-features-plugin/7.20.5_@babel+core@7.20.12: 169 | resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} 170 | engines: {node: '>=6.9.0'} 171 | peerDependencies: 172 | '@babel/core': ^7.0.0 173 | dependencies: 174 | '@babel/core': 7.20.12 175 | '@babel/helper-annotate-as-pure': 7.18.6 176 | regexpu-core: 5.2.2 177 | dev: true 178 | 179 | /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.12: 180 | resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} 181 | peerDependencies: 182 | '@babel/core': ^7.4.0-0 183 | dependencies: 184 | '@babel/core': 7.20.12 185 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 186 | '@babel/helper-plugin-utils': 7.20.2 187 | debug: 4.3.4 188 | lodash.debounce: 4.0.8 189 | resolve: 1.22.1 190 | semver: 6.3.0 191 | transitivePeerDependencies: 192 | - supports-color 193 | dev: true 194 | 195 | /@babel/helper-environment-visitor/7.18.9: 196 | resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} 197 | engines: {node: '>=6.9.0'} 198 | dev: true 199 | 200 | /@babel/helper-explode-assignable-expression/7.18.6: 201 | resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} 202 | engines: {node: '>=6.9.0'} 203 | dependencies: 204 | '@babel/types': 7.20.7 205 | dev: true 206 | 207 | /@babel/helper-function-name/7.19.0: 208 | resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} 209 | engines: {node: '>=6.9.0'} 210 | dependencies: 211 | '@babel/template': 7.20.7 212 | '@babel/types': 7.20.7 213 | dev: true 214 | 215 | /@babel/helper-hoist-variables/7.18.6: 216 | resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} 217 | engines: {node: '>=6.9.0'} 218 | dependencies: 219 | '@babel/types': 7.20.7 220 | dev: true 221 | 222 | /@babel/helper-member-expression-to-functions/7.20.7: 223 | resolution: {integrity: sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==} 224 | engines: {node: '>=6.9.0'} 225 | dependencies: 226 | '@babel/types': 7.20.7 227 | dev: true 228 | 229 | /@babel/helper-module-imports/7.18.6: 230 | resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} 231 | engines: {node: '>=6.9.0'} 232 | dependencies: 233 | '@babel/types': 7.20.7 234 | dev: true 235 | 236 | /@babel/helper-module-transforms/7.20.11: 237 | resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} 238 | engines: {node: '>=6.9.0'} 239 | dependencies: 240 | '@babel/helper-environment-visitor': 7.18.9 241 | '@babel/helper-module-imports': 7.18.6 242 | '@babel/helper-simple-access': 7.20.2 243 | '@babel/helper-split-export-declaration': 7.18.6 244 | '@babel/helper-validator-identifier': 7.19.1 245 | '@babel/template': 7.20.7 246 | '@babel/traverse': 7.20.13 247 | '@babel/types': 7.20.7 248 | transitivePeerDependencies: 249 | - supports-color 250 | dev: true 251 | 252 | /@babel/helper-optimise-call-expression/7.18.6: 253 | resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} 254 | engines: {node: '>=6.9.0'} 255 | dependencies: 256 | '@babel/types': 7.20.7 257 | dev: true 258 | 259 | /@babel/helper-plugin-utils/7.20.2: 260 | resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} 261 | engines: {node: '>=6.9.0'} 262 | dev: true 263 | 264 | /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.12: 265 | resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} 266 | engines: {node: '>=6.9.0'} 267 | peerDependencies: 268 | '@babel/core': ^7.0.0 269 | dependencies: 270 | '@babel/core': 7.20.12 271 | '@babel/helper-annotate-as-pure': 7.18.6 272 | '@babel/helper-environment-visitor': 7.18.9 273 | '@babel/helper-wrap-function': 7.20.5 274 | '@babel/types': 7.20.7 275 | transitivePeerDependencies: 276 | - supports-color 277 | dev: true 278 | 279 | /@babel/helper-replace-supers/7.20.7: 280 | resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} 281 | engines: {node: '>=6.9.0'} 282 | dependencies: 283 | '@babel/helper-environment-visitor': 7.18.9 284 | '@babel/helper-member-expression-to-functions': 7.20.7 285 | '@babel/helper-optimise-call-expression': 7.18.6 286 | '@babel/template': 7.20.7 287 | '@babel/traverse': 7.20.13 288 | '@babel/types': 7.20.7 289 | transitivePeerDependencies: 290 | - supports-color 291 | dev: true 292 | 293 | /@babel/helper-simple-access/7.20.2: 294 | resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} 295 | engines: {node: '>=6.9.0'} 296 | dependencies: 297 | '@babel/types': 7.20.7 298 | dev: true 299 | 300 | /@babel/helper-skip-transparent-expression-wrappers/7.20.0: 301 | resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} 302 | engines: {node: '>=6.9.0'} 303 | dependencies: 304 | '@babel/types': 7.20.7 305 | dev: true 306 | 307 | /@babel/helper-split-export-declaration/7.18.6: 308 | resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} 309 | engines: {node: '>=6.9.0'} 310 | dependencies: 311 | '@babel/types': 7.20.7 312 | dev: true 313 | 314 | /@babel/helper-string-parser/7.19.4: 315 | resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} 316 | engines: {node: '>=6.9.0'} 317 | dev: true 318 | 319 | /@babel/helper-validator-identifier/7.19.1: 320 | resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} 321 | engines: {node: '>=6.9.0'} 322 | dev: true 323 | 324 | /@babel/helper-validator-option/7.18.6: 325 | resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} 326 | engines: {node: '>=6.9.0'} 327 | dev: true 328 | 329 | /@babel/helper-wrap-function/7.20.5: 330 | resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} 331 | engines: {node: '>=6.9.0'} 332 | dependencies: 333 | '@babel/helper-function-name': 7.19.0 334 | '@babel/template': 7.20.7 335 | '@babel/traverse': 7.20.13 336 | '@babel/types': 7.20.7 337 | transitivePeerDependencies: 338 | - supports-color 339 | dev: true 340 | 341 | /@babel/helpers/7.20.13: 342 | resolution: {integrity: sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==} 343 | engines: {node: '>=6.9.0'} 344 | dependencies: 345 | '@babel/template': 7.20.7 346 | '@babel/traverse': 7.20.13 347 | '@babel/types': 7.20.7 348 | transitivePeerDependencies: 349 | - supports-color 350 | dev: true 351 | 352 | /@babel/highlight/7.18.6: 353 | resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} 354 | engines: {node: '>=6.9.0'} 355 | dependencies: 356 | '@babel/helper-validator-identifier': 7.19.1 357 | chalk: 2.4.2 358 | js-tokens: 4.0.0 359 | dev: true 360 | 361 | /@babel/parser/7.20.13: 362 | resolution: {integrity: sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==} 363 | engines: {node: '>=6.0.0'} 364 | hasBin: true 365 | dependencies: 366 | '@babel/types': 7.20.7 367 | dev: true 368 | 369 | /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.12: 370 | resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} 371 | engines: {node: '>=6.9.0'} 372 | peerDependencies: 373 | '@babel/core': ^7.0.0 374 | dependencies: 375 | '@babel/core': 7.20.12 376 | '@babel/helper-plugin-utils': 7.20.2 377 | dev: true 378 | 379 | /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.20.7_@babel+core@7.20.12: 380 | resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} 381 | engines: {node: '>=6.9.0'} 382 | peerDependencies: 383 | '@babel/core': ^7.13.0 384 | dependencies: 385 | '@babel/core': 7.20.12 386 | '@babel/helper-plugin-utils': 7.20.2 387 | '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 388 | '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.20.12 389 | dev: true 390 | 391 | /@babel/plugin-proposal-async-generator-functions/7.20.7_@babel+core@7.20.12: 392 | resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} 393 | engines: {node: '>=6.9.0'} 394 | peerDependencies: 395 | '@babel/core': ^7.0.0-0 396 | dependencies: 397 | '@babel/core': 7.20.12 398 | '@babel/helper-environment-visitor': 7.18.9 399 | '@babel/helper-plugin-utils': 7.20.2 400 | '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.12 401 | '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.12 402 | transitivePeerDependencies: 403 | - supports-color 404 | dev: true 405 | 406 | /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.12: 407 | resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} 408 | engines: {node: '>=6.9.0'} 409 | peerDependencies: 410 | '@babel/core': ^7.0.0-0 411 | dependencies: 412 | '@babel/core': 7.20.12 413 | '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.20.12 414 | '@babel/helper-plugin-utils': 7.20.2 415 | transitivePeerDependencies: 416 | - supports-color 417 | dev: true 418 | 419 | /@babel/plugin-proposal-class-static-block/7.20.7_@babel+core@7.20.12: 420 | resolution: {integrity: sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==} 421 | engines: {node: '>=6.9.0'} 422 | peerDependencies: 423 | '@babel/core': ^7.12.0 424 | dependencies: 425 | '@babel/core': 7.20.12 426 | '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.20.12 427 | '@babel/helper-plugin-utils': 7.20.2 428 | '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.12 429 | transitivePeerDependencies: 430 | - supports-color 431 | dev: true 432 | 433 | /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.12: 434 | resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} 435 | engines: {node: '>=6.9.0'} 436 | peerDependencies: 437 | '@babel/core': ^7.0.0-0 438 | dependencies: 439 | '@babel/core': 7.20.12 440 | '@babel/helper-plugin-utils': 7.20.2 441 | '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.12 442 | dev: true 443 | 444 | /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.12: 445 | resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} 446 | engines: {node: '>=6.9.0'} 447 | peerDependencies: 448 | '@babel/core': ^7.0.0-0 449 | dependencies: 450 | '@babel/core': 7.20.12 451 | '@babel/helper-plugin-utils': 7.20.2 452 | '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.12 453 | dev: true 454 | 455 | /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.12: 456 | resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} 457 | engines: {node: '>=6.9.0'} 458 | peerDependencies: 459 | '@babel/core': ^7.0.0-0 460 | dependencies: 461 | '@babel/core': 7.20.12 462 | '@babel/helper-plugin-utils': 7.20.2 463 | '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.12 464 | dev: true 465 | 466 | /@babel/plugin-proposal-logical-assignment-operators/7.20.7_@babel+core@7.20.12: 467 | resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} 468 | engines: {node: '>=6.9.0'} 469 | peerDependencies: 470 | '@babel/core': ^7.0.0-0 471 | dependencies: 472 | '@babel/core': 7.20.12 473 | '@babel/helper-plugin-utils': 7.20.2 474 | '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.12 475 | dev: true 476 | 477 | /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.12: 478 | resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} 479 | engines: {node: '>=6.9.0'} 480 | peerDependencies: 481 | '@babel/core': ^7.0.0-0 482 | dependencies: 483 | '@babel/core': 7.20.12 484 | '@babel/helper-plugin-utils': 7.20.2 485 | '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.12 486 | dev: true 487 | 488 | /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.12: 489 | resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} 490 | engines: {node: '>=6.9.0'} 491 | peerDependencies: 492 | '@babel/core': ^7.0.0-0 493 | dependencies: 494 | '@babel/core': 7.20.12 495 | '@babel/helper-plugin-utils': 7.20.2 496 | '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.12 497 | dev: true 498 | 499 | /@babel/plugin-proposal-object-rest-spread/7.20.7_@babel+core@7.20.12: 500 | resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} 501 | engines: {node: '>=6.9.0'} 502 | peerDependencies: 503 | '@babel/core': ^7.0.0-0 504 | dependencies: 505 | '@babel/compat-data': 7.20.14 506 | '@babel/core': 7.20.12 507 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 508 | '@babel/helper-plugin-utils': 7.20.2 509 | '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.12 510 | '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.20.12 511 | dev: true 512 | 513 | /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.12: 514 | resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} 515 | engines: {node: '>=6.9.0'} 516 | peerDependencies: 517 | '@babel/core': ^7.0.0-0 518 | dependencies: 519 | '@babel/core': 7.20.12 520 | '@babel/helper-plugin-utils': 7.20.2 521 | '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.12 522 | dev: true 523 | 524 | /@babel/plugin-proposal-optional-chaining/7.20.7_@babel+core@7.20.12: 525 | resolution: {integrity: sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==} 526 | engines: {node: '>=6.9.0'} 527 | peerDependencies: 528 | '@babel/core': ^7.0.0-0 529 | dependencies: 530 | '@babel/core': 7.20.12 531 | '@babel/helper-plugin-utils': 7.20.2 532 | '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 533 | '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.12 534 | dev: true 535 | 536 | /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.12: 537 | resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} 538 | engines: {node: '>=6.9.0'} 539 | peerDependencies: 540 | '@babel/core': ^7.0.0-0 541 | dependencies: 542 | '@babel/core': 7.20.12 543 | '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.20.12 544 | '@babel/helper-plugin-utils': 7.20.2 545 | transitivePeerDependencies: 546 | - supports-color 547 | dev: true 548 | 549 | /@babel/plugin-proposal-private-property-in-object/7.20.5_@babel+core@7.20.12: 550 | resolution: {integrity: sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==} 551 | engines: {node: '>=6.9.0'} 552 | peerDependencies: 553 | '@babel/core': ^7.0.0-0 554 | dependencies: 555 | '@babel/core': 7.20.12 556 | '@babel/helper-annotate-as-pure': 7.18.6 557 | '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.20.12 558 | '@babel/helper-plugin-utils': 7.20.2 559 | '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.12 560 | transitivePeerDependencies: 561 | - supports-color 562 | dev: true 563 | 564 | /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.12: 565 | resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} 566 | engines: {node: '>=4'} 567 | peerDependencies: 568 | '@babel/core': ^7.0.0-0 569 | dependencies: 570 | '@babel/core': 7.20.12 571 | '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.12 572 | '@babel/helper-plugin-utils': 7.20.2 573 | dev: true 574 | 575 | /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.12: 576 | resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} 577 | peerDependencies: 578 | '@babel/core': ^7.0.0-0 579 | dependencies: 580 | '@babel/core': 7.20.12 581 | '@babel/helper-plugin-utils': 7.20.2 582 | dev: true 583 | 584 | /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.12: 585 | resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} 586 | peerDependencies: 587 | '@babel/core': ^7.0.0-0 588 | dependencies: 589 | '@babel/core': 7.20.12 590 | '@babel/helper-plugin-utils': 7.20.2 591 | dev: true 592 | 593 | /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.12: 594 | resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} 595 | engines: {node: '>=6.9.0'} 596 | peerDependencies: 597 | '@babel/core': ^7.0.0-0 598 | dependencies: 599 | '@babel/core': 7.20.12 600 | '@babel/helper-plugin-utils': 7.20.2 601 | dev: true 602 | 603 | /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.12: 604 | resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} 605 | peerDependencies: 606 | '@babel/core': ^7.0.0-0 607 | dependencies: 608 | '@babel/core': 7.20.12 609 | '@babel/helper-plugin-utils': 7.20.2 610 | dev: true 611 | 612 | /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.12: 613 | resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} 614 | peerDependencies: 615 | '@babel/core': ^7.0.0-0 616 | dependencies: 617 | '@babel/core': 7.20.12 618 | '@babel/helper-plugin-utils': 7.20.2 619 | dev: true 620 | 621 | /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.20.12: 622 | resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} 623 | engines: {node: '>=6.9.0'} 624 | peerDependencies: 625 | '@babel/core': ^7.0.0-0 626 | dependencies: 627 | '@babel/core': 7.20.12 628 | '@babel/helper-plugin-utils': 7.20.2 629 | dev: true 630 | 631 | /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.12: 632 | resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} 633 | peerDependencies: 634 | '@babel/core': ^7.0.0-0 635 | dependencies: 636 | '@babel/core': 7.20.12 637 | '@babel/helper-plugin-utils': 7.20.2 638 | dev: true 639 | 640 | /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.12: 641 | resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} 642 | peerDependencies: 643 | '@babel/core': ^7.0.0-0 644 | dependencies: 645 | '@babel/core': 7.20.12 646 | '@babel/helper-plugin-utils': 7.20.2 647 | dev: true 648 | 649 | /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.12: 650 | resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} 651 | peerDependencies: 652 | '@babel/core': ^7.0.0-0 653 | dependencies: 654 | '@babel/core': 7.20.12 655 | '@babel/helper-plugin-utils': 7.20.2 656 | dev: true 657 | 658 | /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.12: 659 | resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} 660 | peerDependencies: 661 | '@babel/core': ^7.0.0-0 662 | dependencies: 663 | '@babel/core': 7.20.12 664 | '@babel/helper-plugin-utils': 7.20.2 665 | dev: true 666 | 667 | /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.12: 668 | resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} 669 | peerDependencies: 670 | '@babel/core': ^7.0.0-0 671 | dependencies: 672 | '@babel/core': 7.20.12 673 | '@babel/helper-plugin-utils': 7.20.2 674 | dev: true 675 | 676 | /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.12: 677 | resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} 678 | peerDependencies: 679 | '@babel/core': ^7.0.0-0 680 | dependencies: 681 | '@babel/core': 7.20.12 682 | '@babel/helper-plugin-utils': 7.20.2 683 | dev: true 684 | 685 | /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.12: 686 | resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} 687 | peerDependencies: 688 | '@babel/core': ^7.0.0-0 689 | dependencies: 690 | '@babel/core': 7.20.12 691 | '@babel/helper-plugin-utils': 7.20.2 692 | dev: true 693 | 694 | /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.12: 695 | resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} 696 | engines: {node: '>=6.9.0'} 697 | peerDependencies: 698 | '@babel/core': ^7.0.0-0 699 | dependencies: 700 | '@babel/core': 7.20.12 701 | '@babel/helper-plugin-utils': 7.20.2 702 | dev: true 703 | 704 | /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.12: 705 | resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} 706 | engines: {node: '>=6.9.0'} 707 | peerDependencies: 708 | '@babel/core': ^7.0.0-0 709 | dependencies: 710 | '@babel/core': 7.20.12 711 | '@babel/helper-plugin-utils': 7.20.2 712 | dev: true 713 | 714 | /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.12: 715 | resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} 716 | engines: {node: '>=6.9.0'} 717 | peerDependencies: 718 | '@babel/core': ^7.0.0-0 719 | dependencies: 720 | '@babel/core': 7.20.12 721 | '@babel/helper-plugin-utils': 7.20.2 722 | dev: true 723 | 724 | /@babel/plugin-transform-arrow-functions/7.20.7_@babel+core@7.20.12: 725 | resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} 726 | engines: {node: '>=6.9.0'} 727 | peerDependencies: 728 | '@babel/core': ^7.0.0-0 729 | dependencies: 730 | '@babel/core': 7.20.12 731 | '@babel/helper-plugin-utils': 7.20.2 732 | dev: true 733 | 734 | /@babel/plugin-transform-async-to-generator/7.20.7_@babel+core@7.20.12: 735 | resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} 736 | engines: {node: '>=6.9.0'} 737 | peerDependencies: 738 | '@babel/core': ^7.0.0-0 739 | dependencies: 740 | '@babel/core': 7.20.12 741 | '@babel/helper-module-imports': 7.18.6 742 | '@babel/helper-plugin-utils': 7.20.2 743 | '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.12 744 | transitivePeerDependencies: 745 | - supports-color 746 | dev: true 747 | 748 | /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.12: 749 | resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} 750 | engines: {node: '>=6.9.0'} 751 | peerDependencies: 752 | '@babel/core': ^7.0.0-0 753 | dependencies: 754 | '@babel/core': 7.20.12 755 | '@babel/helper-plugin-utils': 7.20.2 756 | dev: true 757 | 758 | /@babel/plugin-transform-block-scoping/7.20.14_@babel+core@7.20.12: 759 | resolution: {integrity: sha512-sMPepQtsOs5fM1bwNvuJJHvaCfOEQfmc01FGw0ELlTpTJj5Ql/zuNRRldYhAPys4ghXdBIQJbRVYi44/7QflQQ==} 760 | engines: {node: '>=6.9.0'} 761 | peerDependencies: 762 | '@babel/core': ^7.0.0-0 763 | dependencies: 764 | '@babel/core': 7.20.12 765 | '@babel/helper-plugin-utils': 7.20.2 766 | dev: true 767 | 768 | /@babel/plugin-transform-classes/7.20.7_@babel+core@7.20.12: 769 | resolution: {integrity: sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==} 770 | engines: {node: '>=6.9.0'} 771 | peerDependencies: 772 | '@babel/core': ^7.0.0-0 773 | dependencies: 774 | '@babel/core': 7.20.12 775 | '@babel/helper-annotate-as-pure': 7.18.6 776 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 777 | '@babel/helper-environment-visitor': 7.18.9 778 | '@babel/helper-function-name': 7.19.0 779 | '@babel/helper-optimise-call-expression': 7.18.6 780 | '@babel/helper-plugin-utils': 7.20.2 781 | '@babel/helper-replace-supers': 7.20.7 782 | '@babel/helper-split-export-declaration': 7.18.6 783 | globals: 11.12.0 784 | transitivePeerDependencies: 785 | - supports-color 786 | dev: true 787 | 788 | /@babel/plugin-transform-computed-properties/7.20.7_@babel+core@7.20.12: 789 | resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} 790 | engines: {node: '>=6.9.0'} 791 | peerDependencies: 792 | '@babel/core': ^7.0.0-0 793 | dependencies: 794 | '@babel/core': 7.20.12 795 | '@babel/helper-plugin-utils': 7.20.2 796 | '@babel/template': 7.20.7 797 | dev: true 798 | 799 | /@babel/plugin-transform-destructuring/7.20.7_@babel+core@7.20.12: 800 | resolution: {integrity: sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==} 801 | engines: {node: '>=6.9.0'} 802 | peerDependencies: 803 | '@babel/core': ^7.0.0-0 804 | dependencies: 805 | '@babel/core': 7.20.12 806 | '@babel/helper-plugin-utils': 7.20.2 807 | dev: true 808 | 809 | /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.12: 810 | resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} 811 | engines: {node: '>=6.9.0'} 812 | peerDependencies: 813 | '@babel/core': ^7.0.0-0 814 | dependencies: 815 | '@babel/core': 7.20.12 816 | '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.12 817 | '@babel/helper-plugin-utils': 7.20.2 818 | dev: true 819 | 820 | /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.12: 821 | resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} 822 | engines: {node: '>=6.9.0'} 823 | peerDependencies: 824 | '@babel/core': ^7.0.0-0 825 | dependencies: 826 | '@babel/core': 7.20.12 827 | '@babel/helper-plugin-utils': 7.20.2 828 | dev: true 829 | 830 | /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.12: 831 | resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} 832 | engines: {node: '>=6.9.0'} 833 | peerDependencies: 834 | '@babel/core': ^7.0.0-0 835 | dependencies: 836 | '@babel/core': 7.20.12 837 | '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 838 | '@babel/helper-plugin-utils': 7.20.2 839 | dev: true 840 | 841 | /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.12: 842 | resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} 843 | engines: {node: '>=6.9.0'} 844 | peerDependencies: 845 | '@babel/core': ^7.0.0-0 846 | dependencies: 847 | '@babel/core': 7.20.12 848 | '@babel/helper-plugin-utils': 7.20.2 849 | dev: true 850 | 851 | /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.12: 852 | resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} 853 | engines: {node: '>=6.9.0'} 854 | peerDependencies: 855 | '@babel/core': ^7.0.0-0 856 | dependencies: 857 | '@babel/core': 7.20.12 858 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 859 | '@babel/helper-function-name': 7.19.0 860 | '@babel/helper-plugin-utils': 7.20.2 861 | dev: true 862 | 863 | /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.12: 864 | resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} 865 | engines: {node: '>=6.9.0'} 866 | peerDependencies: 867 | '@babel/core': ^7.0.0-0 868 | dependencies: 869 | '@babel/core': 7.20.12 870 | '@babel/helper-plugin-utils': 7.20.2 871 | dev: true 872 | 873 | /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.12: 874 | resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} 875 | engines: {node: '>=6.9.0'} 876 | peerDependencies: 877 | '@babel/core': ^7.0.0-0 878 | dependencies: 879 | '@babel/core': 7.20.12 880 | '@babel/helper-plugin-utils': 7.20.2 881 | dev: true 882 | 883 | /@babel/plugin-transform-modules-amd/7.20.11_@babel+core@7.20.12: 884 | resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} 885 | engines: {node: '>=6.9.0'} 886 | peerDependencies: 887 | '@babel/core': ^7.0.0-0 888 | dependencies: 889 | '@babel/core': 7.20.12 890 | '@babel/helper-module-transforms': 7.20.11 891 | '@babel/helper-plugin-utils': 7.20.2 892 | transitivePeerDependencies: 893 | - supports-color 894 | dev: true 895 | 896 | /@babel/plugin-transform-modules-commonjs/7.20.11_@babel+core@7.20.12: 897 | resolution: {integrity: sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==} 898 | engines: {node: '>=6.9.0'} 899 | peerDependencies: 900 | '@babel/core': ^7.0.0-0 901 | dependencies: 902 | '@babel/core': 7.20.12 903 | '@babel/helper-module-transforms': 7.20.11 904 | '@babel/helper-plugin-utils': 7.20.2 905 | '@babel/helper-simple-access': 7.20.2 906 | transitivePeerDependencies: 907 | - supports-color 908 | dev: true 909 | 910 | /@babel/plugin-transform-modules-systemjs/7.20.11_@babel+core@7.20.12: 911 | resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} 912 | engines: {node: '>=6.9.0'} 913 | peerDependencies: 914 | '@babel/core': ^7.0.0-0 915 | dependencies: 916 | '@babel/core': 7.20.12 917 | '@babel/helper-hoist-variables': 7.18.6 918 | '@babel/helper-module-transforms': 7.20.11 919 | '@babel/helper-plugin-utils': 7.20.2 920 | '@babel/helper-validator-identifier': 7.19.1 921 | transitivePeerDependencies: 922 | - supports-color 923 | dev: true 924 | 925 | /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.12: 926 | resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} 927 | engines: {node: '>=6.9.0'} 928 | peerDependencies: 929 | '@babel/core': ^7.0.0-0 930 | dependencies: 931 | '@babel/core': 7.20.12 932 | '@babel/helper-module-transforms': 7.20.11 933 | '@babel/helper-plugin-utils': 7.20.2 934 | transitivePeerDependencies: 935 | - supports-color 936 | dev: true 937 | 938 | /@babel/plugin-transform-named-capturing-groups-regex/7.20.5_@babel+core@7.20.12: 939 | resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} 940 | engines: {node: '>=6.9.0'} 941 | peerDependencies: 942 | '@babel/core': ^7.0.0 943 | dependencies: 944 | '@babel/core': 7.20.12 945 | '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.12 946 | '@babel/helper-plugin-utils': 7.20.2 947 | dev: true 948 | 949 | /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.12: 950 | resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} 951 | engines: {node: '>=6.9.0'} 952 | peerDependencies: 953 | '@babel/core': ^7.0.0-0 954 | dependencies: 955 | '@babel/core': 7.20.12 956 | '@babel/helper-plugin-utils': 7.20.2 957 | dev: true 958 | 959 | /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.12: 960 | resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} 961 | engines: {node: '>=6.9.0'} 962 | peerDependencies: 963 | '@babel/core': ^7.0.0-0 964 | dependencies: 965 | '@babel/core': 7.20.12 966 | '@babel/helper-plugin-utils': 7.20.2 967 | '@babel/helper-replace-supers': 7.20.7 968 | transitivePeerDependencies: 969 | - supports-color 970 | dev: true 971 | 972 | /@babel/plugin-transform-parameters/7.20.7_@babel+core@7.20.12: 973 | resolution: {integrity: sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==} 974 | engines: {node: '>=6.9.0'} 975 | peerDependencies: 976 | '@babel/core': ^7.0.0-0 977 | dependencies: 978 | '@babel/core': 7.20.12 979 | '@babel/helper-plugin-utils': 7.20.2 980 | dev: true 981 | 982 | /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.12: 983 | resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} 984 | engines: {node: '>=6.9.0'} 985 | peerDependencies: 986 | '@babel/core': ^7.0.0-0 987 | dependencies: 988 | '@babel/core': 7.20.12 989 | '@babel/helper-plugin-utils': 7.20.2 990 | dev: true 991 | 992 | /@babel/plugin-transform-regenerator/7.20.5_@babel+core@7.20.12: 993 | resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} 994 | engines: {node: '>=6.9.0'} 995 | peerDependencies: 996 | '@babel/core': ^7.0.0-0 997 | dependencies: 998 | '@babel/core': 7.20.12 999 | '@babel/helper-plugin-utils': 7.20.2 1000 | regenerator-transform: 0.15.1 1001 | dev: true 1002 | 1003 | /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.12: 1004 | resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} 1005 | engines: {node: '>=6.9.0'} 1006 | peerDependencies: 1007 | '@babel/core': ^7.0.0-0 1008 | dependencies: 1009 | '@babel/core': 7.20.12 1010 | '@babel/helper-plugin-utils': 7.20.2 1011 | dev: true 1012 | 1013 | /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.12: 1014 | resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} 1015 | engines: {node: '>=6.9.0'} 1016 | peerDependencies: 1017 | '@babel/core': ^7.0.0-0 1018 | dependencies: 1019 | '@babel/core': 7.20.12 1020 | '@babel/helper-plugin-utils': 7.20.2 1021 | dev: true 1022 | 1023 | /@babel/plugin-transform-spread/7.20.7_@babel+core@7.20.12: 1024 | resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} 1025 | engines: {node: '>=6.9.0'} 1026 | peerDependencies: 1027 | '@babel/core': ^7.0.0-0 1028 | dependencies: 1029 | '@babel/core': 7.20.12 1030 | '@babel/helper-plugin-utils': 7.20.2 1031 | '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 1032 | dev: true 1033 | 1034 | /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.12: 1035 | resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} 1036 | engines: {node: '>=6.9.0'} 1037 | peerDependencies: 1038 | '@babel/core': ^7.0.0-0 1039 | dependencies: 1040 | '@babel/core': 7.20.12 1041 | '@babel/helper-plugin-utils': 7.20.2 1042 | dev: true 1043 | 1044 | /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.12: 1045 | resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} 1046 | engines: {node: '>=6.9.0'} 1047 | peerDependencies: 1048 | '@babel/core': ^7.0.0-0 1049 | dependencies: 1050 | '@babel/core': 7.20.12 1051 | '@babel/helper-plugin-utils': 7.20.2 1052 | dev: true 1053 | 1054 | /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.12: 1055 | resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} 1056 | engines: {node: '>=6.9.0'} 1057 | peerDependencies: 1058 | '@babel/core': ^7.0.0-0 1059 | dependencies: 1060 | '@babel/core': 7.20.12 1061 | '@babel/helper-plugin-utils': 7.20.2 1062 | dev: true 1063 | 1064 | /@babel/plugin-transform-typescript/7.20.13_@babel+core@7.20.12: 1065 | resolution: {integrity: sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==} 1066 | engines: {node: '>=6.9.0'} 1067 | peerDependencies: 1068 | '@babel/core': ^7.0.0-0 1069 | dependencies: 1070 | '@babel/core': 7.20.12 1071 | '@babel/helper-create-class-features-plugin': 7.20.12_@babel+core@7.20.12 1072 | '@babel/helper-plugin-utils': 7.20.2 1073 | '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.12 1074 | transitivePeerDependencies: 1075 | - supports-color 1076 | dev: true 1077 | 1078 | /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.12: 1079 | resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} 1080 | engines: {node: '>=6.9.0'} 1081 | peerDependencies: 1082 | '@babel/core': ^7.0.0-0 1083 | dependencies: 1084 | '@babel/core': 7.20.12 1085 | '@babel/helper-plugin-utils': 7.20.2 1086 | dev: true 1087 | 1088 | /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.12: 1089 | resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} 1090 | engines: {node: '>=6.9.0'} 1091 | peerDependencies: 1092 | '@babel/core': ^7.0.0-0 1093 | dependencies: 1094 | '@babel/core': 7.20.12 1095 | '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.12 1096 | '@babel/helper-plugin-utils': 7.20.2 1097 | dev: true 1098 | 1099 | /@babel/preset-env/7.20.2_@babel+core@7.20.12: 1100 | resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} 1101 | engines: {node: '>=6.9.0'} 1102 | peerDependencies: 1103 | '@babel/core': ^7.0.0-0 1104 | dependencies: 1105 | '@babel/compat-data': 7.20.14 1106 | '@babel/core': 7.20.12 1107 | '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 1108 | '@babel/helper-plugin-utils': 7.20.2 1109 | '@babel/helper-validator-option': 7.18.6 1110 | '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.12 1111 | '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7_@babel+core@7.20.12 1112 | '@babel/plugin-proposal-async-generator-functions': 7.20.7_@babel+core@7.20.12 1113 | '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.12 1114 | '@babel/plugin-proposal-class-static-block': 7.20.7_@babel+core@7.20.12 1115 | '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.12 1116 | '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.12 1117 | '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.12 1118 | '@babel/plugin-proposal-logical-assignment-operators': 7.20.7_@babel+core@7.20.12 1119 | '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.12 1120 | '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.12 1121 | '@babel/plugin-proposal-object-rest-spread': 7.20.7_@babel+core@7.20.12 1122 | '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.12 1123 | '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.20.12 1124 | '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.12 1125 | '@babel/plugin-proposal-private-property-in-object': 7.20.5_@babel+core@7.20.12 1126 | '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.12 1127 | '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.12 1128 | '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.12 1129 | '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.12 1130 | '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.12 1131 | '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.12 1132 | '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.20.12 1133 | '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.12 1134 | '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.12 1135 | '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.12 1136 | '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.12 1137 | '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.12 1138 | '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.12 1139 | '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.12 1140 | '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.12 1141 | '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.12 1142 | '@babel/plugin-transform-arrow-functions': 7.20.7_@babel+core@7.20.12 1143 | '@babel/plugin-transform-async-to-generator': 7.20.7_@babel+core@7.20.12 1144 | '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.12 1145 | '@babel/plugin-transform-block-scoping': 7.20.14_@babel+core@7.20.12 1146 | '@babel/plugin-transform-classes': 7.20.7_@babel+core@7.20.12 1147 | '@babel/plugin-transform-computed-properties': 7.20.7_@babel+core@7.20.12 1148 | '@babel/plugin-transform-destructuring': 7.20.7_@babel+core@7.20.12 1149 | '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.12 1150 | '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.12 1151 | '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.12 1152 | '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.12 1153 | '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.12 1154 | '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.12 1155 | '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.12 1156 | '@babel/plugin-transform-modules-amd': 7.20.11_@babel+core@7.20.12 1157 | '@babel/plugin-transform-modules-commonjs': 7.20.11_@babel+core@7.20.12 1158 | '@babel/plugin-transform-modules-systemjs': 7.20.11_@babel+core@7.20.12 1159 | '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.12 1160 | '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5_@babel+core@7.20.12 1161 | '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.12 1162 | '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.12 1163 | '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.20.12 1164 | '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.12 1165 | '@babel/plugin-transform-regenerator': 7.20.5_@babel+core@7.20.12 1166 | '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.12 1167 | '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.12 1168 | '@babel/plugin-transform-spread': 7.20.7_@babel+core@7.20.12 1169 | '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.12 1170 | '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.12 1171 | '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.12 1172 | '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.12 1173 | '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.12 1174 | '@babel/preset-modules': 0.1.5_@babel+core@7.20.12 1175 | '@babel/types': 7.20.7 1176 | babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.12 1177 | babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.12 1178 | babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.12 1179 | core-js-compat: 3.27.2 1180 | semver: 6.3.0 1181 | transitivePeerDependencies: 1182 | - supports-color 1183 | dev: true 1184 | 1185 | /@babel/preset-modules/0.1.5_@babel+core@7.20.12: 1186 | resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} 1187 | peerDependencies: 1188 | '@babel/core': ^7.0.0-0 1189 | dependencies: 1190 | '@babel/core': 7.20.12 1191 | '@babel/helper-plugin-utils': 7.20.2 1192 | '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.12 1193 | '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.12 1194 | '@babel/types': 7.20.7 1195 | esutils: 2.0.3 1196 | dev: true 1197 | 1198 | /@babel/preset-typescript/7.18.6_@babel+core@7.20.12: 1199 | resolution: {integrity: sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==} 1200 | engines: {node: '>=6.9.0'} 1201 | peerDependencies: 1202 | '@babel/core': ^7.0.0-0 1203 | dependencies: 1204 | '@babel/core': 7.20.12 1205 | '@babel/helper-plugin-utils': 7.20.2 1206 | '@babel/helper-validator-option': 7.18.6 1207 | '@babel/plugin-transform-typescript': 7.20.13_@babel+core@7.20.12 1208 | transitivePeerDependencies: 1209 | - supports-color 1210 | dev: true 1211 | 1212 | /@babel/runtime/7.20.13: 1213 | resolution: {integrity: sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==} 1214 | engines: {node: '>=6.9.0'} 1215 | dependencies: 1216 | regenerator-runtime: 0.13.11 1217 | dev: true 1218 | 1219 | /@babel/template/7.20.7: 1220 | resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} 1221 | engines: {node: '>=6.9.0'} 1222 | dependencies: 1223 | '@babel/code-frame': 7.18.6 1224 | '@babel/parser': 7.20.13 1225 | '@babel/types': 7.20.7 1226 | dev: true 1227 | 1228 | /@babel/traverse/7.20.13: 1229 | resolution: {integrity: sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==} 1230 | engines: {node: '>=6.9.0'} 1231 | dependencies: 1232 | '@babel/code-frame': 7.18.6 1233 | '@babel/generator': 7.20.14 1234 | '@babel/helper-environment-visitor': 7.18.9 1235 | '@babel/helper-function-name': 7.19.0 1236 | '@babel/helper-hoist-variables': 7.18.6 1237 | '@babel/helper-split-export-declaration': 7.18.6 1238 | '@babel/parser': 7.20.13 1239 | '@babel/types': 7.20.7 1240 | debug: 4.3.4 1241 | globals: 11.12.0 1242 | transitivePeerDependencies: 1243 | - supports-color 1244 | dev: true 1245 | 1246 | /@babel/types/7.20.7: 1247 | resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} 1248 | engines: {node: '>=6.9.0'} 1249 | dependencies: 1250 | '@babel/helper-string-parser': 7.19.4 1251 | '@babel/helper-validator-identifier': 7.19.1 1252 | to-fast-properties: 2.0.0 1253 | dev: true 1254 | 1255 | /@esbuild/android-arm/0.16.17: 1256 | resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} 1257 | engines: {node: '>=12'} 1258 | cpu: [arm] 1259 | os: [android] 1260 | requiresBuild: true 1261 | dev: true 1262 | optional: true 1263 | 1264 | /@esbuild/android-arm64/0.16.17: 1265 | resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} 1266 | engines: {node: '>=12'} 1267 | cpu: [arm64] 1268 | os: [android] 1269 | requiresBuild: true 1270 | dev: true 1271 | optional: true 1272 | 1273 | /@esbuild/android-x64/0.16.17: 1274 | resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} 1275 | engines: {node: '>=12'} 1276 | cpu: [x64] 1277 | os: [android] 1278 | requiresBuild: true 1279 | dev: true 1280 | optional: true 1281 | 1282 | /@esbuild/darwin-arm64/0.16.17: 1283 | resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} 1284 | engines: {node: '>=12'} 1285 | cpu: [arm64] 1286 | os: [darwin] 1287 | requiresBuild: true 1288 | dev: true 1289 | optional: true 1290 | 1291 | /@esbuild/darwin-x64/0.16.17: 1292 | resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} 1293 | engines: {node: '>=12'} 1294 | cpu: [x64] 1295 | os: [darwin] 1296 | requiresBuild: true 1297 | dev: true 1298 | optional: true 1299 | 1300 | /@esbuild/freebsd-arm64/0.16.17: 1301 | resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} 1302 | engines: {node: '>=12'} 1303 | cpu: [arm64] 1304 | os: [freebsd] 1305 | requiresBuild: true 1306 | dev: true 1307 | optional: true 1308 | 1309 | /@esbuild/freebsd-x64/0.16.17: 1310 | resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} 1311 | engines: {node: '>=12'} 1312 | cpu: [x64] 1313 | os: [freebsd] 1314 | requiresBuild: true 1315 | dev: true 1316 | optional: true 1317 | 1318 | /@esbuild/linux-arm/0.16.17: 1319 | resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} 1320 | engines: {node: '>=12'} 1321 | cpu: [arm] 1322 | os: [linux] 1323 | requiresBuild: true 1324 | dev: true 1325 | optional: true 1326 | 1327 | /@esbuild/linux-arm64/0.16.17: 1328 | resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} 1329 | engines: {node: '>=12'} 1330 | cpu: [arm64] 1331 | os: [linux] 1332 | requiresBuild: true 1333 | dev: true 1334 | optional: true 1335 | 1336 | /@esbuild/linux-ia32/0.16.17: 1337 | resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} 1338 | engines: {node: '>=12'} 1339 | cpu: [ia32] 1340 | os: [linux] 1341 | requiresBuild: true 1342 | dev: true 1343 | optional: true 1344 | 1345 | /@esbuild/linux-loong64/0.16.17: 1346 | resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} 1347 | engines: {node: '>=12'} 1348 | cpu: [loong64] 1349 | os: [linux] 1350 | requiresBuild: true 1351 | dev: true 1352 | optional: true 1353 | 1354 | /@esbuild/linux-mips64el/0.16.17: 1355 | resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} 1356 | engines: {node: '>=12'} 1357 | cpu: [mips64el] 1358 | os: [linux] 1359 | requiresBuild: true 1360 | dev: true 1361 | optional: true 1362 | 1363 | /@esbuild/linux-ppc64/0.16.17: 1364 | resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} 1365 | engines: {node: '>=12'} 1366 | cpu: [ppc64] 1367 | os: [linux] 1368 | requiresBuild: true 1369 | dev: true 1370 | optional: true 1371 | 1372 | /@esbuild/linux-riscv64/0.16.17: 1373 | resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} 1374 | engines: {node: '>=12'} 1375 | cpu: [riscv64] 1376 | os: [linux] 1377 | requiresBuild: true 1378 | dev: true 1379 | optional: true 1380 | 1381 | /@esbuild/linux-s390x/0.16.17: 1382 | resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} 1383 | engines: {node: '>=12'} 1384 | cpu: [s390x] 1385 | os: [linux] 1386 | requiresBuild: true 1387 | dev: true 1388 | optional: true 1389 | 1390 | /@esbuild/linux-x64/0.16.17: 1391 | resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} 1392 | engines: {node: '>=12'} 1393 | cpu: [x64] 1394 | os: [linux] 1395 | requiresBuild: true 1396 | dev: true 1397 | optional: true 1398 | 1399 | /@esbuild/netbsd-x64/0.16.17: 1400 | resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} 1401 | engines: {node: '>=12'} 1402 | cpu: [x64] 1403 | os: [netbsd] 1404 | requiresBuild: true 1405 | dev: true 1406 | optional: true 1407 | 1408 | /@esbuild/openbsd-x64/0.16.17: 1409 | resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} 1410 | engines: {node: '>=12'} 1411 | cpu: [x64] 1412 | os: [openbsd] 1413 | requiresBuild: true 1414 | dev: true 1415 | optional: true 1416 | 1417 | /@esbuild/sunos-x64/0.16.17: 1418 | resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} 1419 | engines: {node: '>=12'} 1420 | cpu: [x64] 1421 | os: [sunos] 1422 | requiresBuild: true 1423 | dev: true 1424 | optional: true 1425 | 1426 | /@esbuild/win32-arm64/0.16.17: 1427 | resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} 1428 | engines: {node: '>=12'} 1429 | cpu: [arm64] 1430 | os: [win32] 1431 | requiresBuild: true 1432 | dev: true 1433 | optional: true 1434 | 1435 | /@esbuild/win32-ia32/0.16.17: 1436 | resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} 1437 | engines: {node: '>=12'} 1438 | cpu: [ia32] 1439 | os: [win32] 1440 | requiresBuild: true 1441 | dev: true 1442 | optional: true 1443 | 1444 | /@esbuild/win32-x64/0.16.17: 1445 | resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} 1446 | engines: {node: '>=12'} 1447 | cpu: [x64] 1448 | os: [win32] 1449 | requiresBuild: true 1450 | dev: true 1451 | optional: true 1452 | 1453 | /@jridgewell/gen-mapping/0.1.1: 1454 | resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} 1455 | engines: {node: '>=6.0.0'} 1456 | dependencies: 1457 | '@jridgewell/set-array': 1.1.2 1458 | '@jridgewell/sourcemap-codec': 1.4.14 1459 | dev: true 1460 | 1461 | /@jridgewell/gen-mapping/0.3.2: 1462 | resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} 1463 | engines: {node: '>=6.0.0'} 1464 | dependencies: 1465 | '@jridgewell/set-array': 1.1.2 1466 | '@jridgewell/sourcemap-codec': 1.4.14 1467 | '@jridgewell/trace-mapping': 0.3.17 1468 | dev: true 1469 | 1470 | /@jridgewell/resolve-uri/3.1.0: 1471 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 1472 | engines: {node: '>=6.0.0'} 1473 | dev: true 1474 | 1475 | /@jridgewell/set-array/1.1.2: 1476 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 1477 | engines: {node: '>=6.0.0'} 1478 | dev: true 1479 | 1480 | /@jridgewell/sourcemap-codec/1.4.14: 1481 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 1482 | dev: true 1483 | 1484 | /@jridgewell/trace-mapping/0.3.17: 1485 | resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} 1486 | dependencies: 1487 | '@jridgewell/resolve-uri': 3.1.0 1488 | '@jridgewell/sourcemap-codec': 1.4.14 1489 | dev: true 1490 | 1491 | /@rollup/plugin-typescript/10.0.1_m3kxv4pqnmlodzidcpaglsppii: 1492 | resolution: {integrity: sha512-wBykxRLlX7EzL8BmUqMqk5zpx2onnmRMSw/l9M1sVfkJvdwfxogZQVNUM9gVMJbjRLDR5H6U0OMOrlDGmIV45A==} 1493 | engines: {node: '>=14.0.0'} 1494 | peerDependencies: 1495 | rollup: ^2.14.0||^3.0.0 1496 | tslib: '*' 1497 | typescript: '>=3.7.0' 1498 | peerDependenciesMeta: 1499 | rollup: 1500 | optional: true 1501 | tslib: 1502 | optional: true 1503 | dependencies: 1504 | '@rollup/pluginutils': 5.0.2_rollup@3.12.0 1505 | resolve: 1.22.1 1506 | rollup: 3.12.0 1507 | tslib: 2.5.0 1508 | typescript: 4.9.4 1509 | dev: true 1510 | 1511 | /@rollup/pluginutils/5.0.2_rollup@3.12.0: 1512 | resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} 1513 | engines: {node: '>=14.0.0'} 1514 | peerDependencies: 1515 | rollup: ^1.20.0||^2.0.0||^3.0.0 1516 | peerDependenciesMeta: 1517 | rollup: 1518 | optional: true 1519 | dependencies: 1520 | '@types/estree': 1.0.0 1521 | estree-walker: 2.0.2 1522 | picomatch: 2.3.1 1523 | rollup: 3.12.0 1524 | dev: true 1525 | 1526 | /@types/chai-subset/1.3.3: 1527 | resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} 1528 | dependencies: 1529 | '@types/chai': 4.3.4 1530 | dev: true 1531 | 1532 | /@types/chai/4.3.4: 1533 | resolution: {integrity: sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==} 1534 | dev: true 1535 | 1536 | /@types/estree/1.0.0: 1537 | resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} 1538 | dev: true 1539 | 1540 | /@types/node/18.11.18: 1541 | resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} 1542 | dev: true 1543 | 1544 | /@vitest/expect/0.28.4: 1545 | resolution: {integrity: sha512-JqK0NZ4brjvOSL8hXAnIsfi+jxDF7rH/ZWCGCt0FAqRnVFc1hXsfwXksQvEnKqD84avRt3gmeXoK4tNbmkoVsQ==} 1546 | dependencies: 1547 | '@vitest/spy': 0.28.4 1548 | '@vitest/utils': 0.28.4 1549 | chai: 4.3.7 1550 | dev: true 1551 | 1552 | /@vitest/runner/0.28.4: 1553 | resolution: {integrity: sha512-Q8UV6GjDvBSTfUoq0QXVCNpNOUrWu4P2qvRq7ssJWzn0+S0ojbVOxEjMt+8a32X6SdkhF8ak+2nkppsqV0JyNQ==} 1554 | dependencies: 1555 | '@vitest/utils': 0.28.4 1556 | p-limit: 4.0.0 1557 | pathe: 1.1.0 1558 | dev: true 1559 | 1560 | /@vitest/spy/0.28.4: 1561 | resolution: {integrity: sha512-8WuhfXLlvCXpNXEGJW6Gc+IKWI32435fQJLh43u70HnZ1otJOa2Cmg2Wy2Aym47ZnNCP4NolF+8cUPwd0MigKQ==} 1562 | dependencies: 1563 | tinyspy: 1.1.1 1564 | dev: true 1565 | 1566 | /@vitest/utils/0.28.4: 1567 | resolution: {integrity: sha512-l2QztOLdc2LkR+w/lP52RGh8hW+Ul4KESmCAgVE8q737I7e7bQoAfkARKpkPJ4JQtGpwW4deqlj1732VZD7TFw==} 1568 | dependencies: 1569 | cli-truncate: 3.1.0 1570 | diff: 5.1.0 1571 | loupe: 2.3.6 1572 | picocolors: 1.0.0 1573 | pretty-format: 27.5.1 1574 | dev: true 1575 | 1576 | /acorn-walk/8.2.0: 1577 | resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} 1578 | engines: {node: '>=0.4.0'} 1579 | dev: true 1580 | 1581 | /acorn/8.8.2: 1582 | resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} 1583 | engines: {node: '>=0.4.0'} 1584 | hasBin: true 1585 | dev: true 1586 | 1587 | /ansi-regex/5.0.1: 1588 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 1589 | engines: {node: '>=8'} 1590 | dev: true 1591 | 1592 | /ansi-regex/6.0.1: 1593 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 1594 | engines: {node: '>=12'} 1595 | dev: true 1596 | 1597 | /ansi-styles/3.2.1: 1598 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 1599 | engines: {node: '>=4'} 1600 | dependencies: 1601 | color-convert: 1.9.3 1602 | dev: true 1603 | 1604 | /ansi-styles/5.2.0: 1605 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} 1606 | engines: {node: '>=10'} 1607 | dev: true 1608 | 1609 | /ansi-styles/6.2.1: 1610 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 1611 | engines: {node: '>=12'} 1612 | dev: true 1613 | 1614 | /assertion-error/1.1.0: 1615 | resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} 1616 | dev: true 1617 | 1618 | /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.12: 1619 | resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} 1620 | peerDependencies: 1621 | '@babel/core': ^7.0.0-0 1622 | dependencies: 1623 | '@babel/compat-data': 7.20.14 1624 | '@babel/core': 7.20.12 1625 | '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.12 1626 | semver: 6.3.0 1627 | transitivePeerDependencies: 1628 | - supports-color 1629 | dev: true 1630 | 1631 | /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.12: 1632 | resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} 1633 | peerDependencies: 1634 | '@babel/core': ^7.0.0-0 1635 | dependencies: 1636 | '@babel/core': 7.20.12 1637 | '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.12 1638 | core-js-compat: 3.27.2 1639 | transitivePeerDependencies: 1640 | - supports-color 1641 | dev: true 1642 | 1643 | /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.12: 1644 | resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} 1645 | peerDependencies: 1646 | '@babel/core': ^7.0.0-0 1647 | dependencies: 1648 | '@babel/core': 7.20.12 1649 | '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.12 1650 | transitivePeerDependencies: 1651 | - supports-color 1652 | dev: true 1653 | 1654 | /browserslist/4.21.4: 1655 | resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} 1656 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 1657 | hasBin: true 1658 | dependencies: 1659 | caniuse-lite: 1.0.30001449 1660 | electron-to-chromium: 1.4.284 1661 | node-releases: 2.0.8 1662 | update-browserslist-db: 1.0.10_browserslist@4.21.4 1663 | dev: true 1664 | 1665 | /buffer-from/1.1.2: 1666 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 1667 | dev: true 1668 | 1669 | /cac/6.7.14: 1670 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 1671 | engines: {node: '>=8'} 1672 | dev: true 1673 | 1674 | /caniuse-lite/1.0.30001449: 1675 | resolution: {integrity: sha512-CPB+UL9XMT/Av+pJxCKGhdx+yg1hzplvFJQlJ2n68PyQGMz9L/E2zCyLdOL8uasbouTUgnPl+y0tccI/se+BEw==} 1676 | dev: true 1677 | 1678 | /chai/4.3.7: 1679 | resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} 1680 | engines: {node: '>=4'} 1681 | dependencies: 1682 | assertion-error: 1.1.0 1683 | check-error: 1.0.2 1684 | deep-eql: 4.1.3 1685 | get-func-name: 2.0.0 1686 | loupe: 2.3.6 1687 | pathval: 1.1.1 1688 | type-detect: 4.0.8 1689 | dev: true 1690 | 1691 | /chalk/2.4.2: 1692 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 1693 | engines: {node: '>=4'} 1694 | dependencies: 1695 | ansi-styles: 3.2.1 1696 | escape-string-regexp: 1.0.5 1697 | supports-color: 5.5.0 1698 | dev: true 1699 | 1700 | /check-error/1.0.2: 1701 | resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} 1702 | dev: true 1703 | 1704 | /cli-truncate/3.1.0: 1705 | resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} 1706 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1707 | dependencies: 1708 | slice-ansi: 5.0.0 1709 | string-width: 5.1.2 1710 | dev: true 1711 | 1712 | /color-convert/1.9.3: 1713 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 1714 | dependencies: 1715 | color-name: 1.1.3 1716 | dev: true 1717 | 1718 | /color-name/1.1.3: 1719 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 1720 | dev: true 1721 | 1722 | /convert-source-map/1.9.0: 1723 | resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} 1724 | dev: true 1725 | 1726 | /core-js-compat/3.27.2: 1727 | resolution: {integrity: sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==} 1728 | dependencies: 1729 | browserslist: 4.21.4 1730 | dev: true 1731 | 1732 | /debug/4.3.4: 1733 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 1734 | engines: {node: '>=6.0'} 1735 | peerDependencies: 1736 | supports-color: '*' 1737 | peerDependenciesMeta: 1738 | supports-color: 1739 | optional: true 1740 | dependencies: 1741 | ms: 2.1.2 1742 | dev: true 1743 | 1744 | /deep-eql/4.1.3: 1745 | resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} 1746 | engines: {node: '>=6'} 1747 | dependencies: 1748 | type-detect: 4.0.8 1749 | dev: true 1750 | 1751 | /diff/5.1.0: 1752 | resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} 1753 | engines: {node: '>=0.3.1'} 1754 | dev: true 1755 | 1756 | /eastasianwidth/0.2.0: 1757 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 1758 | dev: true 1759 | 1760 | /electron-to-chromium/1.4.284: 1761 | resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} 1762 | dev: true 1763 | 1764 | /emoji-regex/9.2.2: 1765 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 1766 | dev: true 1767 | 1768 | /esbuild/0.16.17: 1769 | resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} 1770 | engines: {node: '>=12'} 1771 | hasBin: true 1772 | requiresBuild: true 1773 | optionalDependencies: 1774 | '@esbuild/android-arm': 0.16.17 1775 | '@esbuild/android-arm64': 0.16.17 1776 | '@esbuild/android-x64': 0.16.17 1777 | '@esbuild/darwin-arm64': 0.16.17 1778 | '@esbuild/darwin-x64': 0.16.17 1779 | '@esbuild/freebsd-arm64': 0.16.17 1780 | '@esbuild/freebsd-x64': 0.16.17 1781 | '@esbuild/linux-arm': 0.16.17 1782 | '@esbuild/linux-arm64': 0.16.17 1783 | '@esbuild/linux-ia32': 0.16.17 1784 | '@esbuild/linux-loong64': 0.16.17 1785 | '@esbuild/linux-mips64el': 0.16.17 1786 | '@esbuild/linux-ppc64': 0.16.17 1787 | '@esbuild/linux-riscv64': 0.16.17 1788 | '@esbuild/linux-s390x': 0.16.17 1789 | '@esbuild/linux-x64': 0.16.17 1790 | '@esbuild/netbsd-x64': 0.16.17 1791 | '@esbuild/openbsd-x64': 0.16.17 1792 | '@esbuild/sunos-x64': 0.16.17 1793 | '@esbuild/win32-arm64': 0.16.17 1794 | '@esbuild/win32-ia32': 0.16.17 1795 | '@esbuild/win32-x64': 0.16.17 1796 | dev: true 1797 | 1798 | /escalade/3.1.1: 1799 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 1800 | engines: {node: '>=6'} 1801 | dev: true 1802 | 1803 | /escape-string-regexp/1.0.5: 1804 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 1805 | engines: {node: '>=0.8.0'} 1806 | dev: true 1807 | 1808 | /estree-walker/2.0.2: 1809 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 1810 | dev: true 1811 | 1812 | /esutils/2.0.3: 1813 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 1814 | engines: {node: '>=0.10.0'} 1815 | dev: true 1816 | 1817 | /fsevents/2.3.2: 1818 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 1819 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1820 | os: [darwin] 1821 | requiresBuild: true 1822 | dev: true 1823 | optional: true 1824 | 1825 | /function-bind/1.1.1: 1826 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 1827 | dev: true 1828 | 1829 | /gensync/1.0.0-beta.2: 1830 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 1831 | engines: {node: '>=6.9.0'} 1832 | dev: true 1833 | 1834 | /get-func-name/2.0.0: 1835 | resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} 1836 | dev: true 1837 | 1838 | /globals/11.12.0: 1839 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 1840 | engines: {node: '>=4'} 1841 | dev: true 1842 | 1843 | /has-flag/3.0.0: 1844 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 1845 | engines: {node: '>=4'} 1846 | dev: true 1847 | 1848 | /has/1.0.3: 1849 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 1850 | engines: {node: '>= 0.4.0'} 1851 | dependencies: 1852 | function-bind: 1.1.1 1853 | dev: true 1854 | 1855 | /is-core-module/2.11.0: 1856 | resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} 1857 | dependencies: 1858 | has: 1.0.3 1859 | dev: true 1860 | 1861 | /is-fullwidth-code-point/4.0.0: 1862 | resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} 1863 | engines: {node: '>=12'} 1864 | dev: true 1865 | 1866 | /js-tokens/4.0.0: 1867 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1868 | dev: true 1869 | 1870 | /jsesc/0.5.0: 1871 | resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} 1872 | hasBin: true 1873 | dev: true 1874 | 1875 | /jsesc/2.5.2: 1876 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 1877 | engines: {node: '>=4'} 1878 | hasBin: true 1879 | dev: true 1880 | 1881 | /json5/2.2.3: 1882 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 1883 | engines: {node: '>=6'} 1884 | hasBin: true 1885 | dev: true 1886 | 1887 | /jsonc-parser/3.2.0: 1888 | resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} 1889 | dev: true 1890 | 1891 | /local-pkg/0.4.3: 1892 | resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} 1893 | engines: {node: '>=14'} 1894 | dev: true 1895 | 1896 | /lodash.debounce/4.0.8: 1897 | resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} 1898 | dev: true 1899 | 1900 | /loupe/2.3.6: 1901 | resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} 1902 | dependencies: 1903 | get-func-name: 2.0.0 1904 | dev: true 1905 | 1906 | /lru-cache/5.1.1: 1907 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} 1908 | dependencies: 1909 | yallist: 3.1.1 1910 | dev: true 1911 | 1912 | /mlly/1.1.0: 1913 | resolution: {integrity: sha512-cwzBrBfwGC1gYJyfcy8TcZU1f+dbH/T+TuOhtYP2wLv/Fb51/uV7HJQfBPtEupZ2ORLRU1EKFS/QfS3eo9+kBQ==} 1914 | dependencies: 1915 | acorn: 8.8.2 1916 | pathe: 1.1.0 1917 | pkg-types: 1.0.1 1918 | ufo: 1.0.1 1919 | dev: true 1920 | 1921 | /ms/2.1.2: 1922 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1923 | dev: true 1924 | 1925 | /nanoid/3.3.4: 1926 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 1927 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1928 | hasBin: true 1929 | dev: true 1930 | 1931 | /node-releases/2.0.8: 1932 | resolution: {integrity: sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==} 1933 | dev: true 1934 | 1935 | /p-limit/4.0.0: 1936 | resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} 1937 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 1938 | dependencies: 1939 | yocto-queue: 1.0.0 1940 | dev: true 1941 | 1942 | /path-parse/1.0.7: 1943 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 1944 | dev: true 1945 | 1946 | /pathe/1.1.0: 1947 | resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} 1948 | dev: true 1949 | 1950 | /pathval/1.1.1: 1951 | resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} 1952 | dev: true 1953 | 1954 | /picocolors/1.0.0: 1955 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 1956 | dev: true 1957 | 1958 | /picomatch/2.3.1: 1959 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1960 | engines: {node: '>=8.6'} 1961 | dev: true 1962 | 1963 | /pkg-types/1.0.1: 1964 | resolution: {integrity: sha512-jHv9HB+Ho7dj6ItwppRDDl0iZRYBD0jsakHXtFgoLr+cHSF6xC+QL54sJmWxyGxOLYSHm0afhXhXcQDQqH9z8g==} 1965 | dependencies: 1966 | jsonc-parser: 3.2.0 1967 | mlly: 1.1.0 1968 | pathe: 1.1.0 1969 | dev: true 1970 | 1971 | /postcss/8.4.21: 1972 | resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} 1973 | engines: {node: ^10 || ^12 || >=14} 1974 | dependencies: 1975 | nanoid: 3.3.4 1976 | picocolors: 1.0.0 1977 | source-map-js: 1.0.2 1978 | dev: true 1979 | 1980 | /pretty-format/27.5.1: 1981 | resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} 1982 | engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} 1983 | dependencies: 1984 | ansi-regex: 5.0.1 1985 | ansi-styles: 5.2.0 1986 | react-is: 17.0.2 1987 | dev: true 1988 | 1989 | /react-is/17.0.2: 1990 | resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} 1991 | dev: true 1992 | 1993 | /regenerate-unicode-properties/10.1.0: 1994 | resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} 1995 | engines: {node: '>=4'} 1996 | dependencies: 1997 | regenerate: 1.4.2 1998 | dev: true 1999 | 2000 | /regenerate/1.4.2: 2001 | resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} 2002 | dev: true 2003 | 2004 | /regenerator-runtime/0.13.11: 2005 | resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} 2006 | dev: true 2007 | 2008 | /regenerator-transform/0.15.1: 2009 | resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} 2010 | dependencies: 2011 | '@babel/runtime': 7.20.13 2012 | dev: true 2013 | 2014 | /regexpu-core/5.2.2: 2015 | resolution: {integrity: sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==} 2016 | engines: {node: '>=4'} 2017 | dependencies: 2018 | regenerate: 1.4.2 2019 | regenerate-unicode-properties: 10.1.0 2020 | regjsgen: 0.7.1 2021 | regjsparser: 0.9.1 2022 | unicode-match-property-ecmascript: 2.0.0 2023 | unicode-match-property-value-ecmascript: 2.1.0 2024 | dev: true 2025 | 2026 | /regjsgen/0.7.1: 2027 | resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} 2028 | dev: true 2029 | 2030 | /regjsparser/0.9.1: 2031 | resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} 2032 | hasBin: true 2033 | dependencies: 2034 | jsesc: 0.5.0 2035 | dev: true 2036 | 2037 | /resolve/1.22.1: 2038 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 2039 | hasBin: true 2040 | dependencies: 2041 | is-core-module: 2.11.0 2042 | path-parse: 1.0.7 2043 | supports-preserve-symlinks-flag: 1.0.0 2044 | dev: true 2045 | 2046 | /rollup/3.12.0: 2047 | resolution: {integrity: sha512-4MZ8kA2HNYahIjz63rzrMMRvDqQDeS9LoriJvMuV0V6zIGysP36e9t4yObUfwdT9h/szXoHQideICftcdZklWg==} 2048 | engines: {node: '>=14.18.0', npm: '>=8.0.0'} 2049 | hasBin: true 2050 | optionalDependencies: 2051 | fsevents: 2.3.2 2052 | dev: true 2053 | 2054 | /semver/6.3.0: 2055 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 2056 | hasBin: true 2057 | dev: true 2058 | 2059 | /siginfo/2.0.0: 2060 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 2061 | dev: true 2062 | 2063 | /slice-ansi/5.0.0: 2064 | resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} 2065 | engines: {node: '>=12'} 2066 | dependencies: 2067 | ansi-styles: 6.2.1 2068 | is-fullwidth-code-point: 4.0.0 2069 | dev: true 2070 | 2071 | /source-map-js/1.0.2: 2072 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 2073 | engines: {node: '>=0.10.0'} 2074 | dev: true 2075 | 2076 | /source-map-support/0.5.21: 2077 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 2078 | dependencies: 2079 | buffer-from: 1.1.2 2080 | source-map: 0.6.1 2081 | dev: true 2082 | 2083 | /source-map/0.6.1: 2084 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 2085 | engines: {node: '>=0.10.0'} 2086 | dev: true 2087 | 2088 | /stackback/0.0.2: 2089 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 2090 | dev: true 2091 | 2092 | /std-env/3.3.2: 2093 | resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==} 2094 | dev: true 2095 | 2096 | /string-width/5.1.2: 2097 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 2098 | engines: {node: '>=12'} 2099 | dependencies: 2100 | eastasianwidth: 0.2.0 2101 | emoji-regex: 9.2.2 2102 | strip-ansi: 7.0.1 2103 | dev: true 2104 | 2105 | /strip-ansi/7.0.1: 2106 | resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} 2107 | engines: {node: '>=12'} 2108 | dependencies: 2109 | ansi-regex: 6.0.1 2110 | dev: true 2111 | 2112 | /strip-literal/1.0.1: 2113 | resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} 2114 | dependencies: 2115 | acorn: 8.8.2 2116 | dev: true 2117 | 2118 | /supports-color/5.5.0: 2119 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 2120 | engines: {node: '>=4'} 2121 | dependencies: 2122 | has-flag: 3.0.0 2123 | dev: true 2124 | 2125 | /supports-preserve-symlinks-flag/1.0.0: 2126 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 2127 | engines: {node: '>= 0.4'} 2128 | dev: true 2129 | 2130 | /tinybench/2.3.1: 2131 | resolution: {integrity: sha512-hGYWYBMPr7p4g5IarQE7XhlyWveh1EKhy4wUBS1LrHXCKYgvz+4/jCqgmJqZxxldesn05vccrtME2RLLZNW7iA==} 2132 | dev: true 2133 | 2134 | /tinypool/0.3.1: 2135 | resolution: {integrity: sha512-zLA1ZXlstbU2rlpA4CIeVaqvWq41MTWqLY3FfsAXgC8+f7Pk7zroaJQxDgxn1xNudKW6Kmj4808rPFShUlIRmQ==} 2136 | engines: {node: '>=14.0.0'} 2137 | dev: true 2138 | 2139 | /tinyspy/1.1.1: 2140 | resolution: {integrity: sha512-UVq5AXt/gQlti7oxoIg5oi/9r0WpF7DGEVwXgqWSMmyN16+e3tl5lIvTaOpJ3TAtu5xFzWccFRM4R5NaWHF+4g==} 2141 | engines: {node: '>=14.0.0'} 2142 | dev: true 2143 | 2144 | /to-fast-properties/2.0.0: 2145 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 2146 | engines: {node: '>=4'} 2147 | dev: true 2148 | 2149 | /tslib/2.5.0: 2150 | resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} 2151 | dev: true 2152 | 2153 | /type-detect/4.0.8: 2154 | resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} 2155 | engines: {node: '>=4'} 2156 | dev: true 2157 | 2158 | /typescript/4.9.4: 2159 | resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} 2160 | engines: {node: '>=4.2.0'} 2161 | hasBin: true 2162 | dev: true 2163 | 2164 | /ufo/1.0.1: 2165 | resolution: {integrity: sha512-boAm74ubXHY7KJQZLlXrtMz52qFvpsbOxDcZOnw/Wf+LS4Mmyu7JxmzD4tDLtUQtmZECypJ0FrCz4QIe6dvKRA==} 2166 | dev: true 2167 | 2168 | /unicode-canonical-property-names-ecmascript/2.0.0: 2169 | resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} 2170 | engines: {node: '>=4'} 2171 | dev: true 2172 | 2173 | /unicode-match-property-ecmascript/2.0.0: 2174 | resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} 2175 | engines: {node: '>=4'} 2176 | dependencies: 2177 | unicode-canonical-property-names-ecmascript: 2.0.0 2178 | unicode-property-aliases-ecmascript: 2.1.0 2179 | dev: true 2180 | 2181 | /unicode-match-property-value-ecmascript/2.1.0: 2182 | resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} 2183 | engines: {node: '>=4'} 2184 | dev: true 2185 | 2186 | /unicode-property-aliases-ecmascript/2.1.0: 2187 | resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} 2188 | engines: {node: '>=4'} 2189 | dev: true 2190 | 2191 | /update-browserslist-db/1.0.10_browserslist@4.21.4: 2192 | resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} 2193 | hasBin: true 2194 | peerDependencies: 2195 | browserslist: '>= 4.21.0' 2196 | dependencies: 2197 | browserslist: 4.21.4 2198 | escalade: 3.1.1 2199 | picocolors: 1.0.0 2200 | dev: true 2201 | 2202 | /vite-node/0.28.4_@types+node@18.11.18: 2203 | resolution: {integrity: sha512-KM0Q0uSG/xHHKOJvVHc5xDBabgt0l70y7/lWTR7Q0pR5/MrYxadT+y32cJOE65FfjGmJgxpVEEY+69btJgcXOQ==} 2204 | engines: {node: '>=v14.16.0'} 2205 | hasBin: true 2206 | dependencies: 2207 | cac: 6.7.14 2208 | debug: 4.3.4 2209 | mlly: 1.1.0 2210 | pathe: 1.1.0 2211 | picocolors: 1.0.0 2212 | source-map: 0.6.1 2213 | source-map-support: 0.5.21 2214 | vite: 4.1.2_@types+node@18.11.18 2215 | transitivePeerDependencies: 2216 | - '@types/node' 2217 | - less 2218 | - sass 2219 | - stylus 2220 | - sugarss 2221 | - supports-color 2222 | - terser 2223 | dev: true 2224 | 2225 | /vite/4.1.2: 2226 | resolution: {integrity: sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==} 2227 | engines: {node: ^14.18.0 || >=16.0.0} 2228 | hasBin: true 2229 | peerDependencies: 2230 | '@types/node': '>= 14' 2231 | less: '*' 2232 | sass: '*' 2233 | stylus: '*' 2234 | sugarss: '*' 2235 | terser: ^5.4.0 2236 | peerDependenciesMeta: 2237 | '@types/node': 2238 | optional: true 2239 | less: 2240 | optional: true 2241 | sass: 2242 | optional: true 2243 | stylus: 2244 | optional: true 2245 | sugarss: 2246 | optional: true 2247 | terser: 2248 | optional: true 2249 | dependencies: 2250 | esbuild: 0.16.17 2251 | postcss: 8.4.21 2252 | resolve: 1.22.1 2253 | rollup: 3.12.0 2254 | optionalDependencies: 2255 | fsevents: 2.3.2 2256 | dev: true 2257 | 2258 | /vite/4.1.2_@types+node@18.11.18: 2259 | resolution: {integrity: sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==} 2260 | engines: {node: ^14.18.0 || >=16.0.0} 2261 | hasBin: true 2262 | peerDependencies: 2263 | '@types/node': '>= 14' 2264 | less: '*' 2265 | sass: '*' 2266 | stylus: '*' 2267 | sugarss: '*' 2268 | terser: ^5.4.0 2269 | peerDependenciesMeta: 2270 | '@types/node': 2271 | optional: true 2272 | less: 2273 | optional: true 2274 | sass: 2275 | optional: true 2276 | stylus: 2277 | optional: true 2278 | sugarss: 2279 | optional: true 2280 | terser: 2281 | optional: true 2282 | dependencies: 2283 | '@types/node': 18.11.18 2284 | esbuild: 0.16.17 2285 | postcss: 8.4.21 2286 | resolve: 1.22.1 2287 | rollup: 3.12.0 2288 | optionalDependencies: 2289 | fsevents: 2.3.2 2290 | dev: true 2291 | 2292 | /vitest/0.28.4: 2293 | resolution: {integrity: sha512-sfWIy0AdlbyGRhunm+TLQEJrFH9XuRPdApfubsyLcDbCRrUX717BRQKInTgzEfyl2Ipi1HWoHB84Nqtcwxogcg==} 2294 | engines: {node: '>=v14.16.0'} 2295 | hasBin: true 2296 | peerDependencies: 2297 | '@edge-runtime/vm': '*' 2298 | '@vitest/browser': '*' 2299 | '@vitest/ui': '*' 2300 | happy-dom: '*' 2301 | jsdom: '*' 2302 | peerDependenciesMeta: 2303 | '@edge-runtime/vm': 2304 | optional: true 2305 | '@vitest/browser': 2306 | optional: true 2307 | '@vitest/ui': 2308 | optional: true 2309 | happy-dom: 2310 | optional: true 2311 | jsdom: 2312 | optional: true 2313 | dependencies: 2314 | '@types/chai': 4.3.4 2315 | '@types/chai-subset': 1.3.3 2316 | '@types/node': 18.11.18 2317 | '@vitest/expect': 0.28.4 2318 | '@vitest/runner': 0.28.4 2319 | '@vitest/spy': 0.28.4 2320 | '@vitest/utils': 0.28.4 2321 | acorn: 8.8.2 2322 | acorn-walk: 8.2.0 2323 | cac: 6.7.14 2324 | chai: 4.3.7 2325 | debug: 4.3.4 2326 | local-pkg: 0.4.3 2327 | pathe: 1.1.0 2328 | picocolors: 1.0.0 2329 | source-map: 0.6.1 2330 | std-env: 3.3.2 2331 | strip-literal: 1.0.1 2332 | tinybench: 2.3.1 2333 | tinypool: 0.3.1 2334 | tinyspy: 1.1.1 2335 | vite: 4.1.2_@types+node@18.11.18 2336 | vite-node: 0.28.4_@types+node@18.11.18 2337 | why-is-node-running: 2.2.2 2338 | transitivePeerDependencies: 2339 | - less 2340 | - sass 2341 | - stylus 2342 | - sugarss 2343 | - supports-color 2344 | - terser 2345 | dev: true 2346 | 2347 | /why-is-node-running/2.2.2: 2348 | resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} 2349 | engines: {node: '>=8'} 2350 | hasBin: true 2351 | dependencies: 2352 | siginfo: 2.0.0 2353 | stackback: 0.0.2 2354 | dev: true 2355 | 2356 | /yallist/3.1.1: 2357 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 2358 | dev: true 2359 | 2360 | /yocto-queue/1.0.0: 2361 | resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} 2362 | engines: {node: '>=12.20'} 2363 | dev: true 2364 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/*" 3 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript' 2 | export default { 3 | input: "./packages/vue/src/index.ts", 4 | output: [ 5 | // 1. cjs -> commonjs 6 | // 2. esm 7 | { 8 | format: 'cjs', 9 | file: "packages/vue/dist/my-vue.cjs.js", 10 | }, 11 | { 12 | format: 'es', 13 | file: "packages/vue/dist/my-vue.esm.js", 14 | }, 15 | ], 16 | plugins: [ 17 | typescript() 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | /* Projects */ 5 | // "incremental": true, /* Enable incremental compilation */ 6 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 7 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 8 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 9 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 10 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 11 | /* Language and Environment */ 12 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 13 | "lib": [ 14 | "DOM", 15 | "es6", 16 | "es2016" 17 | ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 18 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 19 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 20 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 21 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 22 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 23 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 24 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 25 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 26 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 27 | /* Modules */ 28 | "module": "esnext", /* Specify what module code is generated. */ 29 | // "rootDir": "./", /* Specify the root folder within your source files. */ 30 | "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 31 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 | "paths": { 33 | "@my-vue/*": [ 34 | "./packages/*/src" 35 | ] 36 | }, /* Specify a set of entries that re-map imports to additional lookup locations. */ 37 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 38 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 39 | "types": [ 40 | "vitest/globals" 41 | ], /* Specify type package names to be included without being referenced in a source file. */ 42 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 43 | // "resolveJsonModule": true, /* Enable importing .json files */ 44 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 45 | /* JavaScript Support */ 46 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 47 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 48 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 49 | /* Emit */ 50 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 51 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 52 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 53 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 54 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 55 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 56 | // "removeComments": true, /* Disable emitting comments. */ 57 | // "noEmit": true, /* Disable emitting files from a compilation. */ 58 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 59 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 60 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 61 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 62 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 63 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 64 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 65 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 66 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 67 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 68 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 69 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 70 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 71 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 72 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 73 | /* Interop Constraints */ 74 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 75 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 76 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 77 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 78 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 79 | /* Type Checking */ 80 | "strict": true, /* Enable all strict type-checking options. */ 81 | "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 82 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 83 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 84 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 85 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 86 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 87 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 88 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 89 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 90 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 91 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 92 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 93 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 94 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 95 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 96 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 97 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 98 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 99 | /* Completeness */ 100 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 101 | "skipLibCheck": true, /* Skip type checking all .d.ts files. */ 102 | }, 103 | "include": [ 104 | "packages/*/src", 105 | "packages/*/__tests__" 106 | ] 107 | } -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | import path from 'path' 3 | 4 | export default defineConfig({ 5 | test: { 6 | globals: true 7 | }, 8 | resolve: { 9 | alias: [ 10 | { 11 | // @my-vue/runtime-core/src 12 | find: /@my-vue\/(\w*)/, 13 | replacement: path.resolve(__dirname, "packages") + "/$1/src" 14 | } 15 | ] 16 | } 17 | }) --------------------------------------------------------------------------------