create-buntui 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (40) hide show
  1. package/dist/buntui.so +0 -0
  2. package/dist/index.js +7 -0
  3. package/package.json +12 -5
  4. package/templates/basic/README.md +17 -0
  5. package/templates/basic/package.json +12 -2
  6. package/templates/basic/scripts/build.ts +65 -0
  7. package/templates/basic/src/App.vue +29 -0
  8. package/templates/basic/src/dev.ts +27 -0
  9. package/templates/basic/src/main.ts +15 -0
  10. package/templates/basic/tsconfig.json +28 -0
  11. package/templates/full/README.md +39 -0
  12. package/templates/full/package.json +21 -0
  13. package/templates/full/scripts/build.ts +66 -0
  14. package/templates/full/src/App.vue +49 -0
  15. package/templates/full/src/components/BoxDemo.vue +80 -0
  16. package/templates/full/src/components/ButtonDemo.vue +32 -0
  17. package/templates/full/src/components/CheckboxDemo.vue +19 -0
  18. package/templates/full/src/components/InputDemo.vue +34 -0
  19. package/templates/full/src/components/ProgressDemo.vue +25 -0
  20. package/templates/full/src/components/RadioDemo.vue +23 -0
  21. package/templates/full/src/components/ScrollBoxDemo.vue +50 -0
  22. package/templates/full/src/components/SelectDemo.vue +41 -0
  23. package/templates/full/src/components/SwitchDemo.vue +19 -0
  24. package/templates/full/src/components/TableDemo.vue +33 -0
  25. package/templates/full/src/components/TextDemo.vue +66 -0
  26. package/templates/full/src/components/TextareaDemo.vue +38 -0
  27. package/templates/full/src/dev.ts +40 -0
  28. package/templates/full/src/main.ts +21 -0
  29. package/templates/full/tsconfig.json +28 -0
  30. package/templates/sfc/README.md +28 -0
  31. package/templates/sfc/package.json +21 -0
  32. package/templates/sfc/scripts/build.ts +66 -0
  33. package/templates/sfc/src/App.vue +42 -0
  34. package/templates/sfc/src/dev.ts +40 -0
  35. package/templates/sfc/src/main.ts +21 -0
  36. package/templates/sfc/tsconfig.json +28 -0
  37. package/src/index.ts +0 -10
  38. package/src/scaffold.ts +0 -25
  39. package/src/setup-ui.ts +0 -145
  40. package/templates/basic/index.ts +0 -30
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "{{name}}",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "bun --preload @buntui/compiler/vue-plugin src/dev.ts",
7
+ "build": "bun run ./scripts/build.ts"
8
+ },
9
+ "dependencies": {
10
+ "@buntui/core": "{{version}}",
11
+ "@buntui/compiler": "{{version}}",
12
+ "@buntui/native": "{{version}}",
13
+ "@buntui/extensions": "{{version}}",
14
+ "@vue/reactivity": "^3.5.34"
15
+ },
16
+ "devDependencies": {
17
+ "@types/bun": "latest",
18
+ "vue": "^3.5.34",
19
+ "vue-tsc": "^3.2.8"
20
+ }
21
+ }
@@ -0,0 +1,66 @@
1
+ import process from 'node:process';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import {compile, CORE_REGISTRY} from '@buntui/compiler';
5
+ import {getBinaryPath} from '@buntui/native';
6
+
7
+ const result = await Bun.build({
8
+ entrypoints: ['src/main.ts'],
9
+ outdir: 'dist',
10
+ target: 'bun',
11
+ minify: true,
12
+ plugins: [
13
+ {
14
+ name: 'buntui-vue',
15
+ setup(build) {
16
+ build.onLoad({filter: /\.vue$/v}, async args => {
17
+ const source = await Bun.file(args.path).text();
18
+ const compiled = compile(source, {
19
+ filename: args.path,
20
+ registry: CORE_REGISTRY,
21
+ codegen: {
22
+ coreModuleId: '@buntui/core',
23
+ reactivityModuleId: '@vue/reactivity',
24
+ },
25
+ });
26
+ return {contents: compiled.code, loader: 'ts'};
27
+ });
28
+ },
29
+ },
30
+ ],
31
+ });
32
+
33
+ if (!result.success) {
34
+ for (const error of result.logs) {
35
+ console.error(error);
36
+ }
37
+
38
+ process.exit(1);
39
+ }
40
+
41
+ for (const output of result.outputs) {
42
+ console.log(`Built: ${output.path} (${(output.size / 1024).toFixed(1)} KB)`);
43
+ }
44
+
45
+ function getBinaryExt(): string {
46
+ if (process.platform === 'win32') return 'dll';
47
+ if (process.platform === 'darwin') return 'dylib';
48
+ return 'so';
49
+ }
50
+
51
+ const binaryName = `buntui.${getBinaryExt()}`;
52
+ const nativePath = getBinaryPath();
53
+ const dllSearchPaths = [
54
+ ...(nativePath ? [nativePath] : []),
55
+ path.resolve(import.meta.dir, '..', 'node_modules', '@buntui', 'core', binaryName),
56
+ path.resolve(import.meta.dir, '..', binaryName),
57
+ ];
58
+
59
+ for (const candidate of dllSearchPaths) {
60
+ if (fs.existsSync(candidate)) {
61
+ const dest = path.resolve(import.meta.dir, '..', 'dist', binaryName);
62
+ fs.copyFileSync(candidate, dest);
63
+ console.log(`Copied: ${binaryName} -> dist/`);
64
+ break;
65
+ }
66
+ }
@@ -0,0 +1,49 @@
1
+ <template>
2
+ <SelectButton :x="1" :y="2" :height="1" :options="tabOptions" v-model="currentTab" />
3
+
4
+ <BoxDemo v-if="currentTab === 'Box'" />
5
+ <ButtonDemo v-if="currentTab === 'Button'" />
6
+ <InputDemo v-if="currentTab === 'Input'" />
7
+ <TextDemo v-if="currentTab === 'Text'" />
8
+ <ProgressDemo v-if="currentTab === 'Progress'" />
9
+ <CheckboxDemo v-if="currentTab === 'Checkbox'" />
10
+ <SwitchDemo v-if="currentTab === 'Switch'" />
11
+ <RadioDemo v-if="currentTab === 'Radio'" />
12
+ <ScrollBoxDemo v-if="currentTab === 'ScrollBox'" />
13
+ <TextareaDemo v-if="currentTab === 'Textarea'" />
14
+ <TableDemo v-if="currentTab === 'Table'" />
15
+ <SelectDemo v-if="currentTab === 'Select'" />
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { ref } from '@vue/reactivity'
20
+
21
+ import BoxDemo from './components/BoxDemo.vue'
22
+ import ButtonDemo from './components/ButtonDemo.vue'
23
+ import InputDemo from './components/InputDemo.vue'
24
+ import TextDemo from './components/TextDemo.vue'
25
+ import ProgressDemo from './components/ProgressDemo.vue'
26
+ import CheckboxDemo from './components/CheckboxDemo.vue'
27
+ import SwitchDemo from './components/SwitchDemo.vue'
28
+ import RadioDemo from './components/RadioDemo.vue'
29
+ import ScrollBoxDemo from './components/ScrollBoxDemo.vue'
30
+ import TextareaDemo from './components/TextareaDemo.vue'
31
+ import TableDemo from './components/TableDemo.vue'
32
+ import SelectDemo from './components/SelectDemo.vue'
33
+
34
+ const tabOptions = ref([
35
+ 'Box',
36
+ 'Button',
37
+ 'Input',
38
+ 'Text',
39
+ 'Progress',
40
+ 'Checkbox',
41
+ 'Switch',
42
+ 'Radio',
43
+ 'ScrollBox',
44
+ 'Textarea',
45
+ 'Table',
46
+ 'Select',
47
+ ])
48
+ const currentTab = ref(tabOptions.value[0]!)
49
+ </script>
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Box widget — layout container with borders, padding, alignment" />
3
+
4
+ <Box
5
+ :x="1"
6
+ :y="4"
7
+ :width="30"
8
+ :height="6"
9
+ borderColor="rgba(137,180,250,1)"
10
+ borderStyle="rounded"
11
+ direction="vertical"
12
+ :gap="1"
13
+ :paddingTop="1"
14
+ :paddingLeft="1"
15
+ >
16
+ <Text value="Rounded border" />
17
+ <Text value="With padding and gap" />
18
+ </Box>
19
+
20
+ <Box
21
+ :x="33"
22
+ :y="4"
23
+ :width="30"
24
+ :height="6"
25
+ borderColor="rgba(166,227,161,1)"
26
+ borderStyle="double"
27
+ direction="vertical"
28
+ :gap="1"
29
+ :paddingTop="1"
30
+ :paddingLeft="1"
31
+ >
32
+ <Text value="Double border" />
33
+ <Text value="Vertical layout" />
34
+ </Box>
35
+
36
+ <Box
37
+ :x="1"
38
+ :y="11"
39
+ :width="30"
40
+ :height="3"
41
+ borderColor="rgba(250,179,135,1)"
42
+ borderStyle="solid"
43
+ direction="horizontal"
44
+ :gap="2"
45
+ align="center"
46
+ >
47
+ <Text value="Horizontal" />
48
+ <Text value="center aligned" />
49
+ </Box>
50
+
51
+ <Box
52
+ :x="33"
53
+ :y="11"
54
+ :width="30"
55
+ :height="3"
56
+ borderColor="rgba(243,139,168,1)"
57
+ borderStyle="dashed"
58
+ direction="horizontal"
59
+ :gap="2"
60
+ align="center"
61
+ >
62
+ <Text value="Dashed border" />
63
+ <Text value="gap=2" />
64
+ </Box>
65
+
66
+ <Box
67
+ :draggable="true"
68
+ :x="1"
69
+ :y="15"
70
+ :width="20"
71
+ :height="3"
72
+ borderColor="rgba(203,166,245,1)"
73
+ borderStyle="rounded"
74
+ >
75
+ <Text value="Drag me!" />
76
+ </Box>
77
+ </template>
78
+
79
+ <script setup lang="ts">
80
+ </script>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Button widget — interactive clickable element" />
3
+
4
+ <Button :x="1" :y="4" :width="18" :height="3" value="Click me" @click="handleClick" />
5
+ <Text :x="21" :y="5" :value="log" />
6
+
7
+ <Text :x="1" :y="8" value="Border variants:" />
8
+ <Button :x="1" :y="9" :width="12" :height="3" value="Solid" borderStyleNormal="solid" @click="handleClick" />
9
+ <Button :x="15" :y="9" :width="12" :height="3" value="Rounded" borderStyleNormal="rounded" @click="handleClick" />
10
+ <Button :x="29" :y="9" :width="12" :height="3" value="Bold" borderStyleNormal="bold" @click="handleClick" />
11
+ <Button :x="43" :y="9" :width="12" :height="3" value="Double" borderStyleNormal="double" @click="handleClick" />
12
+
13
+ <Text :x="1" :y="13" value="States:" />
14
+ <Button :x="1" :y="14" :width="18" :height="3" value="Disabled" :disabled="disabled" />
15
+ <Button :x="21" :y="14" :width="18" :height="3" value="Toggle me" @click="toggleDisabled" />
16
+ </template>
17
+
18
+ <script setup lang="ts">
19
+ import { ref } from '@vue/reactivity'
20
+
21
+ const log = ref('Click a button above')
22
+ const disabled = ref(false)
23
+
24
+ function handleClick() {
25
+ const now = new Date()
26
+ log.value = `Clicked at ${now.toLocaleTimeString()}`
27
+ }
28
+
29
+ function toggleDisabled() {
30
+ disabled.value = !disabled.value
31
+ }
32
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Checkbox widget — boolean toggle" />
3
+
4
+ <Checkbox :x="1" :y="4" label="Enable feature A" @change="handleChange('A', $event)" />
5
+ <Checkbox :x="1" :y="5" label="Enable feature B" @change="handleChange('B', $event)" />
6
+ <Checkbox :x="1" :y="6" label="Disabled option" :disabled="true" />
7
+
8
+ <Text :x="1" :y="8" :value="log" />
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { ref } from '@vue/reactivity'
13
+
14
+ const log = ref('Toggle a checkbox above')
15
+
16
+ function handleChange(name: string, event: TuiCheckboxChangeEvent) {
17
+ log.value = `${name}: ${event.checked ? 'checked' : 'unchecked'}`
18
+ }
19
+ </script>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Input widget — text field with editing support" />
3
+
4
+ <Box
5
+ :x="1"
6
+ :y="4"
7
+ :width="50"
8
+ :height="8"
9
+ borderStyle="rounded"
10
+ direction="vertical"
11
+ :gap="1"
12
+ :paddingTop="1"
13
+ :paddingLeft="1"
14
+ >
15
+ <Text value="Type something and press Enter:" />
16
+ <Input
17
+ :width="46"
18
+ placeholder="Enter text here..."
19
+ @submit="handleSubmit"
20
+ />
21
+ </Box>
22
+
23
+ <Text :x="1" :y="13" :value="submittedValue" />
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { ref } from '@vue/reactivity'
28
+
29
+ const submittedValue = ref('Submit result appears here')
30
+
31
+ function handleSubmit(event: TuiSubmitEvent) {
32
+ submittedValue.value = `Submitted: "${event.value}"`
33
+ }
34
+ </script>
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Progress widget — bar indicator" />
3
+
4
+ <Text :x="1" :y="4" value="Determinate:" />
5
+ <Progress :x="1" :y="5" :width="40" :height="1" :value="progress" />
6
+
7
+ <Text :x="1" :y="7" :value="`${Math.round(progress * 100)}%`" />
8
+
9
+ <Button :x="1" :y="9" :width="20" :height="3" value="Reset" @click="reset" />
10
+ <Button :x="23" :y="9" :width="20" :height="3" value="Set 75%" @click="set75" />
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { ref } from '@vue/reactivity'
15
+
16
+ const progress = ref(0.5)
17
+
18
+ function reset() {
19
+ progress.value = 0
20
+ }
21
+
22
+ function set75() {
23
+ progress.value = 0.75
24
+ }
25
+ </script>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="RadioGroup widget — single selection from options" />
3
+
4
+ <RadioGroup
5
+ :x="1"
6
+ :y="4"
7
+ :width="30"
8
+ :options="['Red', 'Green', 'Blue']"
9
+ @change="handleChange"
10
+ />
11
+
12
+ <Text :x="1" :y="8" :value="log" />
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { ref } from '@vue/reactivity'
17
+
18
+ const log = ref('Select a color above')
19
+
20
+ function handleChange(event: TuiRadioGroupChangeEvent) {
21
+ log.value = `Selected: ${event.label} (index ${event.value})`
22
+ }
23
+ </script>
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="ScrollBox widget — scrollable container" />
3
+
4
+ <ScrollBox
5
+ :x="1"
6
+ :y="4"
7
+ :width="40"
8
+ :height="8"
9
+ borderStyle="rounded"
10
+ :gap="1"
11
+ :paddingTop="1"
12
+ :paddingLeft="1"
13
+ :alwaysShowScrollbar="true"
14
+ >
15
+ <Text v-for="item in items" :key="item" :value="item" />
16
+ </ScrollBox>
17
+
18
+ <Box
19
+ :x="44"
20
+ :y="4"
21
+ :width="30"
22
+ :height="8"
23
+ borderStyle="rounded"
24
+ direction="vertical"
25
+ :gap="1"
26
+ :paddingTop="1"
27
+ :paddingLeft="1"
28
+ >
29
+ <Text value="Scroll with arrow keys" />
30
+ <Text value="Content overflows the visible area" />
31
+ <Text value="Scrollbar appears automatically" />
32
+ </Box>
33
+ </template>
34
+
35
+ <script setup lang="ts">
36
+ import { ref } from '@vue/reactivity'
37
+
38
+ const items = ref([
39
+ 'Item 1 — Apple',
40
+ 'Item 2 — Banana',
41
+ 'Item 3 — Cherry',
42
+ 'Item 4 — Date',
43
+ 'Item 5 — Elderberry',
44
+ 'Item 6 — Fig',
45
+ 'Item 7 — Grape',
46
+ 'Item 8 — Honeydew',
47
+ 'Item 9 — Kiwi',
48
+ 'Item 10 — Lemon',
49
+ ])
50
+ </script>
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Select widget — dropdown selection" />
3
+
4
+ <Box
5
+ :x="1"
6
+ :y="4"
7
+ :width="50"
8
+ :height="8"
9
+ borderStyle="rounded"
10
+ direction="vertical"
11
+ :gap="1"
12
+ :paddingTop="1"
13
+ :paddingLeft="1"
14
+ >
15
+ <Text value="Choose a framework:" />
16
+ <Select
17
+ :width="46"
18
+ :options="frameworks"
19
+ placeholder="Select a framework..."
20
+ @change="handleChange"
21
+ />
22
+ </Box>
23
+
24
+ <Text :x="1" :y="13" :value="selected" />
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { ref } from '@vue/reactivity'
29
+
30
+ const frameworks = ref([
31
+ {value: 'bun', label: 'Bun'},
32
+ {value: 'node', label: 'Node.js'},
33
+ {value: 'deno', label: 'Deno'},
34
+ ])
35
+
36
+ const selected = ref('Select an option above')
37
+
38
+ function handleChange(event: TuiChangeEventData) {
39
+ selected.value = `Selected: ${String(event.value)}`
40
+ }
41
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Switch widget — on/off toggle" />
3
+
4
+ <Switch :x="1" :y="4" label="Dark mode" @change="handleChange('Dark mode', $event)" />
5
+ <Switch :x="1" :y="5" label="Notifications" @change="handleChange('Notifications', $event)" />
6
+ <Switch :x="1" :y="6" label="Disabled" :disabled="true" />
7
+
8
+ <Text :x="1" :y="8" :value="log" />
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { ref } from '@vue/reactivity'
13
+
14
+ const log = ref('Toggle a switch above')
15
+
16
+ function handleChange(name: string, event: TuiSwitchChangeEvent) {
17
+ log.value = `${name}: ${event.checked ? 'on' : 'off'}`
18
+ }
19
+ </script>
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Table widget — structured data display with selection" />
3
+
4
+ <Table
5
+ :x="1"
6
+ :y="4"
7
+ :width="60"
8
+ :height="8"
9
+ borderStyle="rounded"
10
+ :columns="columns"
11
+ :rows="rows"
12
+ />
13
+
14
+ <Text :x="1" :y="13" value="Use arrow keys to navigate rows" />
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ import { ref } from '@vue/reactivity'
19
+
20
+ const columns = ref([
21
+ {key: 'name', label: 'Name', width: 20},
22
+ {key: 'role', label: 'Role', width: 16},
23
+ {key: 'status', label: 'Status', width: 10},
24
+ ])
25
+
26
+ const rows = ref([
27
+ {name: 'Alice', role: 'Engineer', status: 'Active'},
28
+ {name: 'Bob', role: 'Designer', status: 'Away'},
29
+ {name: 'Charlie', role: 'Manager', status: 'Active'},
30
+ {name: 'Diana', role: 'Engineer', status: 'Busy'},
31
+ {name: 'Eve', role: 'Analyst', status: 'Active'},
32
+ ])
33
+ </script>
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Text widget — display styled text" />
3
+
4
+ <Box
5
+ :x="1"
6
+ :y="4"
7
+ width="45%"
8
+ :height="8"
9
+ borderStyle="rounded"
10
+ direction="vertical"
11
+ :gap="1"
12
+ :paddingTop="1"
13
+ :paddingLeft="1"
14
+ >
15
+ <Text value="Font styles" />
16
+ <Text styleModifier="bold" value="Bold text" />
17
+ <Text styleModifier="italic" value="Italic text" />
18
+ </Box>
19
+
20
+ <Box
21
+ x="50%"
22
+ :y="4"
23
+ width="45%"
24
+ :height="10"
25
+ borderStyle="rounded"
26
+ direction="vertical"
27
+ :gap="1"
28
+ :paddingTop="1"
29
+ :paddingLeft="1"
30
+ >
31
+ <Text value="Colors" />
32
+ <Text colorFg="rgba(243,139,168,1)" value="Red " />
33
+ <Text colorFg="rgba(137,180,250,1)" value="Blue " />
34
+ <Text colorFg="rgba(166,227,161,1)" value="Green" />
35
+ </Box>
36
+
37
+ <Box
38
+ :x="1"
39
+ :y="15"
40
+ width="95%"
41
+ :height="6"
42
+ borderStyle="rounded"
43
+ direction="vertical"
44
+ :gap="1"
45
+ :paddingTop="1"
46
+ :paddingLeft="1"
47
+ >
48
+ <Text value="Dynamic clock:" />
49
+ <Text :value="clock" />
50
+ </Box>
51
+ </template>
52
+
53
+ <script setup lang="ts">
54
+ import { ref, computed } from '@vue/reactivity'
55
+
56
+ const elapsed = ref(0)
57
+ setInterval(() => {
58
+ elapsed.value += 1
59
+ }, 1000)
60
+
61
+ const clock = computed(() => {
62
+ elapsed.value
63
+ const now = new Date()
64
+ return now.toLocaleTimeString()
65
+ })
66
+ </script>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <Text :x="1" :y="3" value="Textarea widget — multi-line text editor" />
3
+
4
+ <Box
5
+ :x="1"
6
+ :y="4"
7
+ :width="50"
8
+ :height="8"
9
+ borderStyle="rounded"
10
+ direction="vertical"
11
+ :gap="1"
12
+ :paddingTop="1"
13
+ :paddingLeft="1"
14
+ >
15
+ <Text :value="label" />
16
+ <Textarea
17
+ :width="46"
18
+ :height="3"
19
+ placeholder="Enter multi-line text..."
20
+ v-model="text"
21
+ />
22
+ </Box>
23
+
24
+ <Text :x="1" :y="13" :value="preview" />
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { ref, computed } from '@vue/reactivity'
29
+
30
+ const text = ref('')
31
+
32
+ const label = computed(() => text.value.length > 0 ? `Characters: ${text.value.length}` : 'Type something below:')
33
+
34
+ const preview = computed(() => {
35
+ const lines = text.value.split('\n')
36
+ return text.value.length > 0 ? `${lines.length} lines, ${text.value.length} chars` : 'Preview appears here'
37
+ })
38
+ </script>
@@ -0,0 +1,40 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import {createDevServer, CORE_REGISTRY, type DevServerOptions} from '@buntui/compiler';
4
+ import {mountHmrErrorOverlay, type HmrErrorOverlayHandle} from '@buntui/extensions/hmr-error-overlay';
5
+ import {ENTRY, run} from './main';
6
+
7
+ const DEV_DIR = path.join(import.meta.dir, '.dev');
8
+ fs.mkdirSync(DEV_DIR, {recursive: true});
9
+
10
+ const {scene} = run({logFilePath: DEV_DIR});
11
+
12
+ const VUE_FILE = path.join(import.meta.dir, ENTRY);
13
+
14
+ let errorOverlay: HmrErrorOverlayHandle | undefined;
15
+
16
+ createDevServer({
17
+ file: VUE_FILE,
18
+ tempDir: DEV_DIR,
19
+ compileOptions: {
20
+ registry: CORE_REGISTRY,
21
+ codegen: {
22
+ coreModuleId: '@buntui/core',
23
+ reactivityModuleId: '@vue/reactivity',
24
+ },
25
+ },
26
+ onClear() {
27
+ errorOverlay?.dismiss();
28
+ errorOverlay = undefined;
29
+ scene.clearWidgets();
30
+ },
31
+ onReload(setupFn: (scene: unknown) => void) {
32
+ errorOverlay?.dismiss();
33
+ errorOverlay = undefined;
34
+ setupFn(scene);
35
+ },
36
+ onError(error: Error) {
37
+ errorOverlay?.dismiss();
38
+ errorOverlay = mountHmrErrorOverlay(scene, error);
39
+ },
40
+ } satisfies DevServerOptions);
@@ -0,0 +1,21 @@
1
+ import {createApp} from '@buntui/core';
2
+ import App from './App.vue';
3
+
4
+ export const ENTRY = 'App.vue';
5
+
6
+ export function run(devOptions: {logFilePath?: string} = {}) {
7
+ const app = createApp({
8
+ logLevel: 'info',
9
+ clearLog: true,
10
+ tickRate: 60,
11
+ renderRate: 24,
12
+ ...devOptions,
13
+ });
14
+ const scene = app.createScene(App, {bgHexRgb: 0x1A_1B_26, visible: true});
15
+ app.start();
16
+ return {app, scene};
17
+ }
18
+
19
+ if (import.meta.main) {
20
+ run();
21
+ }