mikuru 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +142 -0
  3. package/dist/compiler/analyzeTemplate.d.ts +7 -0
  4. package/dist/compiler/analyzeTemplate.js +161 -0
  5. package/dist/compiler/analyzeTemplate.js.map +1 -0
  6. package/dist/compiler/compile.d.ts +2 -0
  7. package/dist/compiler/compile.js +24 -0
  8. package/dist/compiler/compile.js.map +1 -0
  9. package/dist/compiler/errors.d.ts +17 -0
  10. package/dist/compiler/errors.js +51 -0
  11. package/dist/compiler/errors.js.map +1 -0
  12. package/dist/compiler/generate.d.ts +2 -0
  13. package/dist/compiler/generate.js +982 -0
  14. package/dist/compiler/generate.js.map +1 -0
  15. package/dist/compiler/index.d.ts +9 -0
  16. package/dist/compiler/index.js +8 -0
  17. package/dist/compiler/index.js.map +1 -0
  18. package/dist/compiler/parseExpression.d.ts +14 -0
  19. package/dist/compiler/parseExpression.js +273 -0
  20. package/dist/compiler/parseExpression.js.map +1 -0
  21. package/dist/compiler/parseSfc.d.ts +2 -0
  22. package/dist/compiler/parseSfc.js +38 -0
  23. package/dist/compiler/parseSfc.js.map +1 -0
  24. package/dist/compiler/parseTemplate.d.ts +8 -0
  25. package/dist/compiler/parseTemplate.js +266 -0
  26. package/dist/compiler/parseTemplate.js.map +1 -0
  27. package/dist/compiler/sourceMap.d.ts +2 -0
  28. package/dist/compiler/sourceMap.js +66 -0
  29. package/dist/compiler/sourceMap.js.map +1 -0
  30. package/dist/compiler/types.d.ts +89 -0
  31. package/dist/compiler/types.js +2 -0
  32. package/dist/compiler/types.js.map +1 -0
  33. package/dist/index.d.ts +4 -0
  34. package/dist/index.js +3 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/runtime/dom.d.ts +3 -0
  37. package/dist/runtime/dom.js +46 -0
  38. package/dist/runtime/dom.js.map +1 -0
  39. package/dist/runtime/index.d.ts +6 -0
  40. package/dist/runtime/index.js +4 -0
  41. package/dist/runtime/index.js.map +1 -0
  42. package/dist/runtime/lifecycle.d.ts +10 -0
  43. package/dist/runtime/lifecycle.js +79 -0
  44. package/dist/runtime/lifecycle.js.map +1 -0
  45. package/dist/runtime/reactivity.d.ts +11 -0
  46. package/dist/runtime/reactivity.js +84 -0
  47. package/dist/runtime/reactivity.js.map +1 -0
  48. package/dist/vite.d.ts +7 -0
  49. package/dist/vite.js +39 -0
  50. package/dist/vite.js.map +1 -0
  51. package/package.json +80 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ - Stabilized the v1 SFC compiler surface for `.mikuru` files.
6
+ - Added Vite integration, generated DOM cleanup, component props/events/slots, `defineProps`, and `defineEmits`.
7
+ - Added `v-if` / `v-else-if` / `v-else`, `v-show`, `v-for`, `v-model`, DOM event modifiers, style injection, and basic scoped CSS support.
8
+ - Added CI, library build checks, basic example build checks, and browser E2E coverage.
9
+ - Added a realworld example, public package smoke test, parser-limit coverage, debug sourceURL support, and performance smoke coverage.
10
+ - Added v3 source maps, keyed `v-for` reuse, npm pack smoke coverage, and a v1 API contract.
11
+ - Added a dogfood notes app written in Mikuru to exercise daily authoring flows.
12
+ - Added generated DOM coverage for keyed insert/remove/reorder behavior, component cleanup, and slot cleanup.
13
+ - Added explicit unsupported-syntax errors with source frames, Vite error forwarding coverage, and debug `sourceURL` path normalization coverage.
14
+ - Documented runtime helpers including `nextTick`, `watch`, lifecycle callbacks, `provide`, and `inject`.
package/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # Mikuru
2
+
3
+ Mikuruは、Vueの書き心地を残しながら、Svelte寄りにDOM更新コードを生成するコンパイル型JavaScriptフレームワークです。
4
+
5
+ Vueのように単一ファイルコンポーネントと宣言的なテンプレートで書き、Svelteのようにビルド時にテンプレートを解析して、仮想DOMに依存しない小さなJavaScriptへ変換することを目指します。
6
+
7
+ ## 目標
8
+
9
+ - `.mikuru` ファイルでコンポーネントを書く。
10
+ - `<template>` / `<script>` / `<style>` のSFC構造を使う。
11
+ - `ref`、`computed`、`effect` 風の小さなリアクティビティを提供する。
12
+ - `{{ value }}`、`@click` / `v-on:click`、`:class` / `v-bind:class`、`v-if`、`v-for` のようなVue風テンプレート構文を使う。
13
+ - コンパイラが更新箇所を静的に把握し、直接DOMを更新するコードを生成する。
14
+
15
+ ## 最小サンプル
16
+
17
+ ```mikuru
18
+ <template>
19
+ <button @click="increment">count: {{ count }}</button>
20
+ </template>
21
+
22
+ <script>
23
+ import { ref } from "mikuru";
24
+
25
+ const count = ref(0);
26
+
27
+ function increment() {
28
+ count.value += 1;
29
+ }
30
+ </script>
31
+
32
+ <style>
33
+ button {
34
+ font: inherit;
35
+ }
36
+ </style>
37
+ ```
38
+
39
+ このコンポーネントは、概念的に次のようなJavaScript moduleへ変換されます。
40
+
41
+ ```js
42
+ import { ref, effect } from "mikuru/runtime";
43
+
44
+ export function mount(target) {
45
+ const count = ref(0);
46
+ const button = document.createElement("button");
47
+
48
+ function increment() {
49
+ count.value += 1;
50
+ }
51
+
52
+ button.addEventListener("click", increment);
53
+
54
+ effect(() => {
55
+ button.textContent = `count: ${count.value}`;
56
+ });
57
+
58
+ target.appendChild(button);
59
+ }
60
+ ```
61
+
62
+ ## v1範囲
63
+
64
+ v1の成功条件は、Vue風の小さなSFC体験をVite上で実用的に書け、ブラウザで安定して動かせることです。最初のカウンターMVPは土台として維持し、v1では親子コンポーネント、フォーム入力、条件分岐、リスト表示、style注入までを公開対象として固定します。
65
+
66
+ v1では次の機能を対象にします。
67
+
68
+ - SFC分割: `<template>`、`<script>`、`<style>`
69
+ - Vite plugin: `.mikuru` importをJavaScript moduleへ変換
70
+ - テキスト補間: `{{ count }}`
71
+ - イベント: `@click="increment"`、`v-on:click="increment"`、DOMイベントの `.prevent` / `.stop`
72
+ - 属性バインド: `:class="className"`、`v-bind:class="className"`
73
+ - class正規化: `:class="['base', { active }]"` の配列・オブジェクト形式
74
+ - フォーム同期: `input` / `textarea` / `checkbox` / `select` の `v-model`
75
+ - 条件分岐: `v-if` / `v-else-if` / `v-else`
76
+ - 表示切り替え: `v-show="visible"`
77
+ - 繰り返し: `v-for="item in items"`、`v-for="(item, index) in items"`、`of` エイリアス
78
+ - コンポーネント合成: `<Child :count="count" @select="select" />` のprops/event受け渡し、`v-model`
79
+ - default slot: `<Panel>content</Panel>` と子側の `<slot />`
80
+ - props宣言: `const { title } = defineProps()` のコンパイル専用API
81
+ - emits宣言: `const emit = defineEmits()` で親の `@event` ハンドラを呼び出し
82
+ - style注入: `<style>` をmount時に一度だけdocumentへ追加し、`<style scoped>` の基本セレクタを書き換える
83
+ - unmount: 生成コンポーネントがイベント、effect、子コンポーネントを破棄する
84
+ - パーサ強化: コメント、シングルクォート属性、属性値内の `>`、void要素に対応
85
+ - 式検証: テンプレート式をExpressionとして検証し、文や代入など危険な構文を拒否
86
+ - エラー表示: コンパイルエラーにファイル名、行、列、コードフレームを付与
87
+ - 小さなランタイム: `ref`、`computed`、`effect`
88
+
89
+ ## v1の非目標
90
+
91
+ MikuruはVue完全互換を目指しません。SSR、hydration、transition、devtools、完全なテンプレート型チェック、Vue互換を名乗るための広範な仕様追従はv1後に検討します。scoped CSSはv1では基本セレクタのみを対象にし、`:global()`、深いセレクタ、複雑なネスト規則は後続課題です。
92
+
93
+ ## 開発
94
+
95
+ ```sh
96
+ npm install
97
+ npm run ci
98
+ ```
99
+
100
+ 個別に確認する場合は次を使います。
101
+
102
+ ```sh
103
+ npm run typecheck
104
+ npm test
105
+ npm run build
106
+ npm run build:basic
107
+ npm run build:realworld
108
+ npm run build:dogfood
109
+ npm run test:package
110
+ npm run test:pack
111
+ npm run test:e2e
112
+ npm run test:e2e:dogfood
113
+ ```
114
+
115
+ 公式exampleはViteで起動できます。
116
+
117
+ ```sh
118
+ npm run dev:basic
119
+ npm run dev:realworld
120
+ npm run dev:dogfood
121
+ ```
122
+
123
+ 用途は次の通りです。
124
+
125
+ - `examples/basic`: カウンター、props/events、component `v-model`、default slot の最小確認
126
+ - `examples/realworld`: 検索、フォーム、keyed list を含むアプリ風の検証
127
+ - `examples/dogfood`: Mikuru自身で書いた notes app による日常的な書き心地の検証
128
+ - `examples/mikuru-sample` / `examples/mikuru-vue-like`: 追加の手書きDOM/runtimeサンプル
129
+
130
+ 表示するときは、ブラウザで example の `index.html` を直接開かず、Viteが表示するローカルURLを開いてください。`.ts` と `.mikuru` はVite pluginで変換されます。
131
+
132
+ exampleを本番ビルドする場合は次を使います。
133
+
134
+ ```sh
135
+ npm run build:basic
136
+ npm run build:realworld
137
+ npm run build:dogfood
138
+ ```
139
+
140
+ ## 補足
141
+
142
+ Mikuru v1は、Vue完全互換ではなく小さなVue風SFCサブセットです。設計文書、対応構文、非対応構文、リリース前チェック項目などの詳細文書は内部資料として扱います。
@@ -0,0 +1,7 @@
1
+ import type { Binding, ElementNode } from "./types.js";
2
+ type AnalyzeTemplateOptions = {
3
+ source?: string;
4
+ filename?: string;
5
+ };
6
+ export declare function analyzeTemplate(root: ElementNode, options?: AnalyzeTemplateOptions): Binding[];
7
+ export {};
@@ -0,0 +1,161 @@
1
+ import { createCompileError } from "./errors.js";
2
+ import { parseForExpression, validateAssignableExpression, validateTemplateExpression } from "./parseExpression.js";
3
+ export function analyzeTemplate(root, options = {}) {
4
+ const bindings = [];
5
+ visitNode(root, bindings, options);
6
+ return bindings;
7
+ }
8
+ function visitNode(node, bindings, options) {
9
+ if (node.type === "text") {
10
+ for (const part of node.parts) {
11
+ if (part.type === "expression") {
12
+ bindings.push({ type: "text", expression: part.value });
13
+ }
14
+ }
15
+ return;
16
+ }
17
+ rejectUnsupportedNodeFeatures(node, options);
18
+ for (const attr of node.attrs) {
19
+ rejectUnsupportedAttribute(node, attr, options);
20
+ if (attr.name === "v-model") {
21
+ bindings.push({
22
+ type: "model",
23
+ expression: validateAssignableExpression(requireStringValue(attr.name, attr.value), attr.name, toExpressionContext(attr.valueLoc, options))
24
+ });
25
+ continue;
26
+ }
27
+ const event = parseEventDirective(attr.name);
28
+ if (event) {
29
+ bindings.push({
30
+ type: "event",
31
+ event: event.name,
32
+ handler: validateTemplateExpression(requireStringValue(attr.name, attr.value), attr.name, toExpressionContext(attr.valueLoc, options)),
33
+ modifiers: event.modifiers.length ? event.modifiers : undefined
34
+ });
35
+ continue;
36
+ }
37
+ const bindingName = getBindingName(attr.name);
38
+ if (bindingName) {
39
+ bindings.push({
40
+ type: "attribute",
41
+ name: bindingName,
42
+ expression: validateTemplateExpression(requireStringValue(attr.name, attr.value), attr.name, toExpressionContext(attr.valueLoc, options))
43
+ });
44
+ continue;
45
+ }
46
+ if (attr.name === "v-if") {
47
+ bindings.push({
48
+ type: "if",
49
+ expression: validateTemplateExpression(requireStringValue(attr.name, attr.value), attr.name, toExpressionContext(attr.valueLoc, options))
50
+ });
51
+ continue;
52
+ }
53
+ if (attr.name === "v-else-if") {
54
+ bindings.push({
55
+ type: "else-if",
56
+ expression: validateTemplateExpression(requireStringValue(attr.name, attr.value), attr.name, toExpressionContext(attr.valueLoc, options))
57
+ });
58
+ continue;
59
+ }
60
+ if (attr.name === "v-else") {
61
+ if (attr.value !== true) {
62
+ requireStringValue(attr.name, attr.value);
63
+ }
64
+ bindings.push({ type: "else" });
65
+ continue;
66
+ }
67
+ if (attr.name === "v-show") {
68
+ bindings.push({
69
+ type: "show",
70
+ expression: validateTemplateExpression(requireStringValue(attr.name, attr.value), attr.name, toExpressionContext(attr.valueLoc, options))
71
+ });
72
+ continue;
73
+ }
74
+ if (attr.name === "v-for") {
75
+ bindings.push(parseForBinding(requireStringValue(attr.name, attr.value), toExpressionContext(attr.valueLoc, options)));
76
+ }
77
+ }
78
+ for (const child of node.children) {
79
+ visitNode(child, bindings, options);
80
+ }
81
+ }
82
+ function rejectUnsupportedNodeFeatures(node, options) {
83
+ if (node.tag === "component") {
84
+ throwTemplateError("Dynamic components are not supported in v1", node.loc, options);
85
+ }
86
+ if (node.tag === "slot" && node.attrs.length > 0) {
87
+ throwTemplateError("Named slots and slot props are not supported in v1", node.attrs[0]?.loc ?? node.loc, options);
88
+ }
89
+ }
90
+ function rejectUnsupportedAttribute(node, attr, options) {
91
+ if (attr.name === "v-html") {
92
+ throwTemplateError("v-html is not supported in v1", attr.loc, options);
93
+ }
94
+ if (attr.name === "v-bind" || attr.name === "v-on") {
95
+ throwTemplateError(`Object-form ${attr.name} is not supported in v1`, attr.loc, options);
96
+ }
97
+ if (attr.name === "v-slot" || attr.name.startsWith("v-slot:") || attr.name.startsWith("#")) {
98
+ throwTemplateError("Named slots and slot props are not supported in v1", attr.loc, options);
99
+ }
100
+ if (node.tag === "template" && attr.name === "slot") {
101
+ throwTemplateError("Named slots and slot props are not supported in v1", attr.loc, options);
102
+ }
103
+ }
104
+ function parseForBinding(expression, context) {
105
+ const parsed = parseForExpression(expression, context);
106
+ return {
107
+ type: "for",
108
+ item: parsed.item,
109
+ index: parsed.index,
110
+ source: parsed.source
111
+ };
112
+ }
113
+ function toExpressionContext(location, options) {
114
+ if (!location || !options.source) {
115
+ return undefined;
116
+ }
117
+ return {
118
+ source: options.source,
119
+ offset: location.offset,
120
+ filename: options.filename
121
+ };
122
+ }
123
+ function requireStringValue(name, value) {
124
+ if (value === true) {
125
+ throw new Error(`Directive ${name} requires a value`);
126
+ }
127
+ return value;
128
+ }
129
+ function throwTemplateError(message, location, options) {
130
+ if (options.source && location) {
131
+ throw createCompileError(message, options.source, location.offset, options.filename);
132
+ }
133
+ throw new Error(message);
134
+ }
135
+ function parseEventDirective(name) {
136
+ const rawName = getEventName(name);
137
+ if (!rawName) {
138
+ return undefined;
139
+ }
140
+ const [eventName, ...modifiers] = rawName.split(".");
141
+ return { name: eventName, modifiers };
142
+ }
143
+ function getEventName(name) {
144
+ if (name.startsWith("@")) {
145
+ return name.slice(1);
146
+ }
147
+ if (name.startsWith("v-on:")) {
148
+ return name.slice("v-on:".length);
149
+ }
150
+ return undefined;
151
+ }
152
+ function getBindingName(name) {
153
+ if (name.startsWith(":")) {
154
+ return name.slice(1);
155
+ }
156
+ if (name.startsWith("v-bind:")) {
157
+ return name.slice("v-bind:".length);
158
+ }
159
+ return undefined;
160
+ }
161
+ //# sourceMappingURL=analyzeTemplate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzeTemplate.js","sourceRoot":"","sources":["../../src/compiler/analyzeTemplate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAOpH,MAAM,UAAU,eAAe,CAAC,IAAiB,EAAE,UAAkC,EAAE;IACrF,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,IAAkB,EAAE,QAAmB,EAAE,OAA+B;IACzF,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAED,OAAO;IACT,CAAC;IAED,6BAA6B,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,0BAA0B,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAEhD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,OAAO;gBACb,UAAU,EAAE,4BAA4B,CACtC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,IAAI,EACT,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,EAAE,CAAC;YACV,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,KAAK,CAAC,IAAI;gBACjB,OAAO,EAAE,0BAA0B,CACjC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,IAAI,EACT,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C;gBACD,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;aAChE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE9C,IAAI,WAAW,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,WAAW;gBACjB,UAAU,EAAE,0BAA0B,CACpC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,IAAI,EACT,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,0BAA0B,CACpC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,IAAI,EACT,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,SAAS;gBACf,UAAU,EAAE,0BAA0B,CACpC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,IAAI,EACT,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBACxB,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5C,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAChC,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,MAAM;gBACZ,UAAU,EAAE,0BAA0B,CACpC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EACzC,IAAI,CAAC,IAAI,EACT,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAC5C;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QACzH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClC,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAS,6BAA6B,CAAC,IAAiB,EAAE,OAA+B;IACvF,IAAI,IAAI,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;QAC7B,kBAAkB,CAAC,4CAA4C,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,kBAAkB,CAAC,oDAAoD,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpH,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAiB,EAAE,IAAuB,EAAE,OAA+B;IAC7G,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,kBAAkB,CAAC,+BAA+B,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACnD,kBAAkB,CAAC,eAAe,IAAI,CAAC,IAAI,yBAAyB,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3F,kBAAkB,CAAC,oDAAoD,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,KAAK,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACpD,kBAAkB,CAAC,oDAAoD,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB,EAAE,OAAmC;IAC9E,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO;QACL,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAC1B,QAAoC,EACpC,OAA+B;IAE/B,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY,EAAE,KAAoB;IAC5D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,mBAAmB,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe,EAAE,QAAoC,EAAE,OAA+B;IAChH,IAAI,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { CompileOptions, CompileResult } from "./types.js";
2
+ export declare function compile(source: string, options?: CompileOptions): CompileResult;
@@ -0,0 +1,24 @@
1
+ import { analyzeTemplate } from "./analyzeTemplate.js";
2
+ import { generate } from "./generate.js";
3
+ import { parseSfc } from "./parseSfc.js";
4
+ import { parseTemplate } from "./parseTemplate.js";
5
+ import { createSourceMap } from "./sourceMap.js";
6
+ export function compile(source, options = {}) {
7
+ const descriptor = parseSfc(source, options.filename);
8
+ const ast = parseTemplate(descriptor.template, {
9
+ filename: options.filename,
10
+ source,
11
+ offset: descriptor.templateOffset
12
+ });
13
+ const bindings = analyzeTemplate(ast, { source, filename: options.filename });
14
+ const code = generate(descriptor, ast);
15
+ const map = createSourceMap(code, descriptor);
16
+ return {
17
+ code,
18
+ map,
19
+ descriptor,
20
+ ast,
21
+ bindings
22
+ };
23
+ }
24
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/compiler/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,UAA0B,EAAE;IAClE,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,QAAQ,EAAE;QAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM;QACN,MAAM,EAAE,UAAU,CAAC,cAAc;KAClC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAE9C,OAAO;QACL,IAAI;QACJ,GAAG;QACH,UAAU;QACV,GAAG;QACH,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type SourceLocation = {
2
+ filename?: string;
3
+ offset: number;
4
+ line: number;
5
+ column: number;
6
+ };
7
+ export declare class MikuruCompileError extends Error {
8
+ readonly filename?: string;
9
+ readonly offset: number;
10
+ readonly line: number;
11
+ readonly column: number;
12
+ readonly frame?: string;
13
+ constructor(message: string, location: SourceLocation, frame?: string);
14
+ }
15
+ export declare function createCompileError(message: string, source: string, offset: number, filename?: string): MikuruCompileError;
16
+ export declare function getSourceLocation(source: string, offset: number, filename?: string): SourceLocation;
17
+ export declare function createCodeFrame(source: string, location: SourceLocation): string;
@@ -0,0 +1,51 @@
1
+ export class MikuruCompileError extends Error {
2
+ filename;
3
+ offset;
4
+ line;
5
+ column;
6
+ frame;
7
+ constructor(message, location, frame) {
8
+ super(formatMessage(message, location));
9
+ this.name = "MikuruCompileError";
10
+ this.filename = location.filename;
11
+ this.offset = location.offset;
12
+ this.line = location.line;
13
+ this.column = location.column;
14
+ this.frame = frame;
15
+ }
16
+ }
17
+ export function createCompileError(message, source, offset, filename) {
18
+ const location = getSourceLocation(source, offset, filename);
19
+ return new MikuruCompileError(message, location, createCodeFrame(source, location));
20
+ }
21
+ export function getSourceLocation(source, offset, filename) {
22
+ const safeOffset = Math.max(0, Math.min(offset, source.length));
23
+ let line = 1;
24
+ let column = 1;
25
+ for (let index = 0; index < safeOffset; index += 1) {
26
+ if (source[index] === "\n") {
27
+ line += 1;
28
+ column = 1;
29
+ }
30
+ else {
31
+ column += 1;
32
+ }
33
+ }
34
+ return {
35
+ filename,
36
+ offset: safeOffset,
37
+ line,
38
+ column
39
+ };
40
+ }
41
+ export function createCodeFrame(source, location) {
42
+ const lines = source.split(/\r?\n/);
43
+ const lineText = lines[location.line - 1] ?? "";
44
+ const gutter = String(location.line).padStart(4, " ");
45
+ return `${gutter} | ${lineText}\n | ${" ".repeat(Math.max(0, location.column - 1))}^`;
46
+ }
47
+ function formatMessage(message, location) {
48
+ const filePart = location.filename ? `${location.filename}:` : "";
49
+ return `${message} (${filePart}${location.line}:${location.column})`;
50
+ }
51
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/compiler/errors.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAClC,QAAQ,CAAU;IAClB,MAAM,CAAS;IACf,IAAI,CAAS;IACb,MAAM,CAAS;IACf,KAAK,CAAU;IAExB,YAAY,OAAe,EAAE,QAAwB,EAAE,KAAc;QACnE,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,MAAc,EAAE,MAAc,EAAE,QAAiB;IACnG,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7D,OAAO,IAAI,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAAc,EAAE,QAAiB;IACjF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACnD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,CAAC;YACV,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,UAAU;QAClB,IAAI;QACJ,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,QAAwB;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEtD,OAAO,GAAG,MAAM,MAAM,QAAQ,YAAY,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5F,CAAC;AAED,SAAS,aAAa,CAAC,OAAe,EAAE,QAAwB;IAC9D,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,OAAO,GAAG,OAAO,KAAK,QAAQ,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;AACvE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ElementNode, SfcDescriptor } from "./types.js";
2
+ export declare function generate(descriptor: SfcDescriptor, root: ElementNode): string;