astrobit 0.1.0 → 0.1.2

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 (2) hide show
  1. package/README.md +146 -0
  2. package/package.json +9 -3
package/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # astrobit
2
+
3
+ A thin framework for running [MoonBit](https://www.moonbitlang.com/) components as [Astro](https://astro.build/) islands.
4
+
5
+ Write your UI logic in MoonBit, use it directly in `.astro` files — SSR and client-side hydration included.
6
+
7
+ ## Requirements
8
+
9
+ - [Astro](https://astro.build/) 6+
10
+ - [MoonBit toolchain](https://www.moonbitlang.com/download/) (`moon` CLI)
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ npm install astrobit
16
+ ```
17
+
18
+ Add the integration to your `astro.config.mjs`:
19
+
20
+ ```js
21
+ import { defineConfig } from 'astro/config'
22
+ import astrobit from 'astrobit'
23
+
24
+ export default defineConfig({
25
+ integrations: [astrobit()],
26
+ })
27
+ ```
28
+
29
+ ## Project Setup
30
+
31
+ Place a `moon.mod.json` at the root of your Astro project:
32
+
33
+ ```json
34
+ {
35
+ "name": "yourname/your-project",
36
+ "deps": {
37
+ "SouichiroTsujimoto/astrobit": "0.1.1",
38
+ "mizchi/signals": "0.6.4"
39
+ },
40
+ "preferred-target": "js"
41
+ }
42
+ ```
43
+
44
+ Then install the MoonBit dependencies:
45
+
46
+ ```sh
47
+ moon install
48
+ ```
49
+
50
+ ## Writing a Component
51
+
52
+ Each component lives in its own directory with a `moon.pkg` file.
53
+
54
+ **`src/components/counter/moon.pkg`**
55
+ ```json
56
+ {
57
+ "import": [
58
+ "SouichiroTsujimoto/astrobit" @a,
59
+ "SouichiroTsujimoto/astrobit/dom",
60
+ "mizchi/signals"
61
+ ],
62
+ "options": {
63
+ "link": { "js": { "exports": ["mount", "render", "hydrate"], "format": "esm" } }
64
+ }
65
+ }
66
+ ```
67
+
68
+ **`src/components/counter/counter.mbt`**
69
+ ```moonbit
70
+ fn counter(props : @dom.Props) -> @a.Node {
71
+ let initial = props.get_int("initial")
72
+ let count = @signals.signal(initial)
73
+ @a.div([
74
+ @a.p(@a.dyn_text(fn() { "Count: " + count.get().to_string() })),
75
+ @a.button("-") |> @a.on_click(fn(_) { count.update(fn(n) { n - 1 }) }),
76
+ @a.button("+") |> @a.on_click(fn(_) { count.update(fn(n) { n + 1 }) }),
77
+ ])
78
+ }
79
+
80
+ pub fn mount(element : @dom.Element, props : @dom.Props) -> Unit {
81
+ @a.mount_dom(element, counter(props))
82
+ }
83
+
84
+ pub fn render(props : @dom.Props) -> String {
85
+ @a.render_to_html(counter(props))
86
+ }
87
+
88
+ pub fn hydrate(element : @dom.Element, props : @dom.Props) -> Unit {
89
+ @a.hydrate_dom(element, counter(props))
90
+ }
91
+ ```
92
+
93
+ Props are received as `@dom.Props` and extracted with typed accessors:
94
+
95
+ ```moonbit
96
+ props.get_int("key") // Int (default: 0)
97
+ props.get_string("key") // String (default: "")
98
+ props.get_bool("key") // Bool (default: false)
99
+
100
+ props.get_int("key", default=10) // with explicit default
101
+ ```
102
+
103
+ ## Using in Astro
104
+
105
+ Import the `.mbt` file directly. The Vite plugin handles the rest.
106
+
107
+ ```astro
108
+ ---
109
+ import Counter from '../components/counter/counter.mbt'
110
+ ---
111
+
112
+ <!-- client:only — mount on the client, no SSR -->
113
+ <Counter client:only="astrobit" initial={0} />
114
+
115
+ <!-- client:load — SSR + hydration -->
116
+ <Counter client:load initial={0} />
117
+ ```
118
+
119
+ TypeScript types for `*.mbt` imports are injected automatically — no manual `env.d.ts` setup required.
120
+
121
+ ## Build
122
+
123
+ Before running the dev server, build the MoonBit sources:
124
+
125
+ ```sh
126
+ moon build
127
+ ```
128
+
129
+ Then start Astro:
130
+
131
+ ```sh
132
+ npm run dev
133
+ ```
134
+
135
+ HMR is supported — saving a `.mbt` file triggers an automatic rebuild and page reload.
136
+
137
+ ## How It Works
138
+
139
+ - **SSR**: `render(props)` returns an HTML string, rendered server-side by Astro.
140
+ - **Hydration** (`client:load`): `hydrate(element, props)` attaches signals and event listeners to the existing DOM without re-rendering.
141
+ - **Mount** (`client:only`): `mount(element, props)` builds the DOM from scratch on the client.
142
+ - **Reactivity**: Powered by [`mizchi/signals`](https://mooncakes.io/docs/#/mizchi/signals/).
143
+
144
+ ## License
145
+
146
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astrobit",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "main": "./dist/integration.js",
6
6
  "types": "./dist/integration.d.ts",
@@ -31,10 +31,16 @@
31
31
  "typescript": "^5.9.3"
32
32
  },
33
33
  "description": "A thin framework for running MoonBit components as Astro islands",
34
- "keywords": ["astro", "moonbit", "island", "framework", "astro-integration"],
34
+ "keywords": [
35
+ "astro",
36
+ "moonbit",
37
+ "island",
38
+ "framework",
39
+ "astro-integration"
40
+ ],
35
41
  "repository": {
36
42
  "type": "git",
37
43
  "url": "https://github.com/SouichiroTsujimoto/astrobit"
38
44
  },
39
45
  "license": "MIT"
40
- }
46
+ }