xote 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +2 -0
- package/.github/workflows/release.yml +44 -0
- package/LICENSE +21 -0
- package/README.md +317 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +9 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/docs/CHANGELOG.md +20 -0
- package/index.html +28 -0
- package/package.json +57 -0
- package/rescript.json +18 -0
- package/src/Xote.res +5 -0
- package/src/Xote.res.mjs +21 -0
- package/src/Xote__Component.res +151 -0
- package/src/Xote__Component.res.mjs +202 -0
- package/src/Xote__Computed.res +43 -0
- package/src/Xote__Computed.res.mjs +61 -0
- package/src/Xote__Core.res +105 -0
- package/src/Xote__Core.res.mjs +148 -0
- package/src/Xote__Effect.res +36 -0
- package/src/Xote__Effect.res.mjs +57 -0
- package/src/Xote__Example.res +266 -0
- package/src/Xote__Example.res.mjs +303 -0
- package/src/Xote__Id.res +5 -0
- package/src/Xote__Id.res.mjs +17 -0
- package/src/Xote__Observer.res +12 -0
- package/src/Xote__Observer.res.mjs +12 -0
- package/src/Xote__Signal.res +31 -0
- package/src/Xote__Signal.res.mjs +64 -0
- package/vite.config.js +45 -0
package/.gitattributes
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
workflow_dispatch: {}
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write # create releases, push changelog commits
|
|
10
|
+
issues: write # (optional) if plugins comment on issues
|
|
11
|
+
pull-requests: write # (optional) if plugins post to PRs
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: release-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
release:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0 # semantic-release needs full history & tags
|
|
27
|
+
|
|
28
|
+
- name: Use Node.js 24
|
|
29
|
+
uses: actions/setup-node@v4
|
|
30
|
+
with:
|
|
31
|
+
node-version: 24.10.0
|
|
32
|
+
cache: npm
|
|
33
|
+
registry-url: https://registry.npmjs.org
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: npm install
|
|
37
|
+
|
|
38
|
+
- name: Build
|
|
39
|
+
run: npm run build
|
|
40
|
+
- name: Release
|
|
41
|
+
env:
|
|
42
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
43
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
44
|
+
run: npx semantic-release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Bernardo Gurgel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# xote (pronounced [ˈʃɔtʃi])
|
|
2
|
+
|
|
3
|
+
A lightweight, zero-dependency UI library for ReScript with fine-grained reactivity powered by signals. Build reactive web applications with automatic dependency tracking and efficient updates.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Zero dependencies** - No runtime dependencies, pure ReScript implementation
|
|
8
|
+
- **Reactive primitives** - Signals, computed values, and effects
|
|
9
|
+
- **Component system** - Declarative UI components with automatic reactive updates
|
|
10
|
+
- **Automatic dependency tracking** - No manual subscription management
|
|
11
|
+
- **Batching and control** - Support for untracked reads and batched updates
|
|
12
|
+
- **Lightweight** - Small bundle size, minimal overhead
|
|
13
|
+
|
|
14
|
+
## Getting Started
|
|
15
|
+
|
|
16
|
+
Comming soon.
|
|
17
|
+
|
|
18
|
+
### Installation
|
|
19
|
+
|
|
20
|
+
Comming soon.
|
|
21
|
+
|
|
22
|
+
### Quick Example
|
|
23
|
+
|
|
24
|
+
```rescript
|
|
25
|
+
open Xote
|
|
26
|
+
|
|
27
|
+
// Create reactive state
|
|
28
|
+
let count = Signal.make(0)
|
|
29
|
+
|
|
30
|
+
// Create computed values
|
|
31
|
+
let doubled = Computed.make(() => Signal.get(count) * 2)
|
|
32
|
+
|
|
33
|
+
// Define event handlers
|
|
34
|
+
let increment = (_evt: Dom.event) => Signal.update(count, n => n + 1)
|
|
35
|
+
|
|
36
|
+
// Build your UI
|
|
37
|
+
let app = Component.div(
|
|
38
|
+
~children=[
|
|
39
|
+
Component.h1(~children=[Component.text("Counter")], ()),
|
|
40
|
+
Component.p(~children=[
|
|
41
|
+
Component.textSignal(
|
|
42
|
+
Computed.make(() => "Count: " ++ Int.toString(Signal.get(count)))
|
|
43
|
+
)
|
|
44
|
+
], ()),
|
|
45
|
+
Component.button(
|
|
46
|
+
~events=[("click", increment)],
|
|
47
|
+
~children=[Component.text("Increment")],
|
|
48
|
+
()
|
|
49
|
+
)
|
|
50
|
+
],
|
|
51
|
+
()
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// Mount to DOM
|
|
55
|
+
Component.mountById(app, "app")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## API Reference
|
|
59
|
+
|
|
60
|
+
### Signals - Reactive State
|
|
61
|
+
|
|
62
|
+
Signals are the foundation of reactive state management in Xote.
|
|
63
|
+
|
|
64
|
+
```rescript
|
|
65
|
+
// Create a signal with initial value
|
|
66
|
+
let count = Signal.make(0)
|
|
67
|
+
|
|
68
|
+
// Read signal value (tracks dependencies)
|
|
69
|
+
let value = Signal.get(count) // => 0
|
|
70
|
+
|
|
71
|
+
// Read without tracking
|
|
72
|
+
let value = Signal.peek(count) // => 0
|
|
73
|
+
|
|
74
|
+
// Update signal value
|
|
75
|
+
Signal.set(count, 1)
|
|
76
|
+
|
|
77
|
+
// Update with a function
|
|
78
|
+
Signal.update(count, n => n + 1)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Computed - Derived State
|
|
82
|
+
|
|
83
|
+
Computed values automatically update when their dependencies change.
|
|
84
|
+
|
|
85
|
+
```rescript
|
|
86
|
+
let count = Signal.make(5)
|
|
87
|
+
|
|
88
|
+
// Computed values are signals that derive from other signals
|
|
89
|
+
let doubled = Computed.make(() => Signal.get(count) * 2)
|
|
90
|
+
|
|
91
|
+
Signal.get(doubled) // => 10
|
|
92
|
+
|
|
93
|
+
Signal.set(count, 10)
|
|
94
|
+
Signal.get(doubled) // => 20
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Effects - Side Effects
|
|
98
|
+
|
|
99
|
+
Effects run automatically when their dependencies change.
|
|
100
|
+
|
|
101
|
+
```rescript
|
|
102
|
+
let count = Signal.make(0)
|
|
103
|
+
|
|
104
|
+
// Effect runs immediately and re-runs when count changes
|
|
105
|
+
let disposer = Effect.run(() => {
|
|
106
|
+
Console.log("Count is now: " ++ Int.toString(Signal.get(count)))
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
Signal.set(count, 1) // Logs: "Count is now: 1"
|
|
110
|
+
|
|
111
|
+
// Clean up effect
|
|
112
|
+
disposer.dispose()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Components - Building UI
|
|
116
|
+
|
|
117
|
+
#### Basic Elements
|
|
118
|
+
|
|
119
|
+
```rescript
|
|
120
|
+
// Text nodes
|
|
121
|
+
Component.text("Hello, world!")
|
|
122
|
+
|
|
123
|
+
// Reactive text from signals
|
|
124
|
+
let name = Signal.make("Alice")
|
|
125
|
+
Component.textSignal(
|
|
126
|
+
Computed.make(() => "Hello, " ++ Signal.get(name))
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
// HTML elements
|
|
130
|
+
Component.div(
|
|
131
|
+
~attrs=[("class", "container"), ("id", "main")],
|
|
132
|
+
~events=[("click", handleClick)],
|
|
133
|
+
~children=[
|
|
134
|
+
Component.h1(~children=[Component.text("Title")], ()),
|
|
135
|
+
Component.p(~children=[Component.text("Content")], ())
|
|
136
|
+
],
|
|
137
|
+
()
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Reactive Lists
|
|
142
|
+
|
|
143
|
+
Render lists that automatically update when data changes:
|
|
144
|
+
|
|
145
|
+
```rescript
|
|
146
|
+
let todos = Signal.make([
|
|
147
|
+
{id: 1, text: "Learn Xote"},
|
|
148
|
+
{id: 2, text: "Build an app"}
|
|
149
|
+
])
|
|
150
|
+
|
|
151
|
+
let todoItem = (todo) => {
|
|
152
|
+
Component.li(~children=[Component.text(todo.text)], ())
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
Component.ul(
|
|
156
|
+
~children=[Component.list(todos, todoItem)],
|
|
157
|
+
()
|
|
158
|
+
)
|
|
159
|
+
// List updates automatically when todos signal changes!
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Event Handling
|
|
163
|
+
|
|
164
|
+
```rescript
|
|
165
|
+
let handleClick = (evt: Dom.event) => {
|
|
166
|
+
Console.log("Clicked!")
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
Component.button(
|
|
170
|
+
~events=[("click", handleClick), ("mouseenter", handleHover)],
|
|
171
|
+
~children=[Component.text("Click me")],
|
|
172
|
+
()
|
|
173
|
+
)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Utilities
|
|
177
|
+
|
|
178
|
+
#### Untracked Reads
|
|
179
|
+
|
|
180
|
+
Read signals without creating dependencies.
|
|
181
|
+
|
|
182
|
+
```rescript
|
|
183
|
+
Core.untrack(() => {
|
|
184
|
+
let value = Signal.get(count) // Won't track this read
|
|
185
|
+
Console.log(value)
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Batching Updates
|
|
190
|
+
|
|
191
|
+
Group multiple updates to run effects only once.
|
|
192
|
+
|
|
193
|
+
```rescript
|
|
194
|
+
Core.batch(() => {
|
|
195
|
+
Signal.set(count1, 10)
|
|
196
|
+
Signal.set(count2, 20)
|
|
197
|
+
Signal.set(count3, 30)
|
|
198
|
+
})
|
|
199
|
+
// Effects run once after all updates
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Complete Example
|
|
203
|
+
|
|
204
|
+
### Counter Application
|
|
205
|
+
|
|
206
|
+
```rescript
|
|
207
|
+
open Xote
|
|
208
|
+
|
|
209
|
+
// State management
|
|
210
|
+
let counterValue = Signal.make(0)
|
|
211
|
+
|
|
212
|
+
// Derived state
|
|
213
|
+
let counterDisplay = Computed.make(() =>
|
|
214
|
+
"Count: " ++ Int.toString(Signal.get(counterValue))
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
let isEven = Computed.make(() =>
|
|
218
|
+
mod(Signal.get(counterValue), 2) == 0
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
// Event handlers
|
|
222
|
+
let increment = (_evt: Dom.event) => {
|
|
223
|
+
Signal.update(counterValue, n => n + 1)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
let decrement = (_evt: Dom.event) => {
|
|
227
|
+
Signal.update(counterValue, n => n - 1)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
let reset = (_evt: Dom.event) => {
|
|
231
|
+
Signal.set(counterValue, 0)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Side effects
|
|
235
|
+
let _ = Effect.run(() => {
|
|
236
|
+
Console.log("Counter changed: " ++ Int.toString(Signal.get(counterValue)))
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
// UI Component
|
|
240
|
+
let app = Component.div(
|
|
241
|
+
~attrs=[("class", "app")],
|
|
242
|
+
~children=[
|
|
243
|
+
Component.h1(~children=[Component.text("Xote Counter")], ()),
|
|
244
|
+
|
|
245
|
+
Component.div(
|
|
246
|
+
~attrs=[("class", "counter-display")],
|
|
247
|
+
~children=[
|
|
248
|
+
Component.h2(~children=[Component.textSignal(counterDisplay)], ()),
|
|
249
|
+
Component.p(~children=[
|
|
250
|
+
Component.textSignal(
|
|
251
|
+
Computed.make(() =>
|
|
252
|
+
Signal.get(isEven) ? "Even" : "Odd"
|
|
253
|
+
)
|
|
254
|
+
)
|
|
255
|
+
], ())
|
|
256
|
+
],
|
|
257
|
+
()
|
|
258
|
+
),
|
|
259
|
+
|
|
260
|
+
Component.div(
|
|
261
|
+
~attrs=[("class", "controls")],
|
|
262
|
+
~children=[
|
|
263
|
+
Component.button(
|
|
264
|
+
~events=[("click", decrement)],
|
|
265
|
+
~children=[Component.text("-")],
|
|
266
|
+
()
|
|
267
|
+
),
|
|
268
|
+
Component.button(
|
|
269
|
+
~events=[("click", reset)],
|
|
270
|
+
~children=[Component.text("Reset")],
|
|
271
|
+
()
|
|
272
|
+
),
|
|
273
|
+
Component.button(
|
|
274
|
+
~events=[("click", increment)],
|
|
275
|
+
~children=[Component.text("+")],
|
|
276
|
+
()
|
|
277
|
+
)
|
|
278
|
+
],
|
|
279
|
+
()
|
|
280
|
+
)
|
|
281
|
+
],
|
|
282
|
+
()
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
// Mount to DOM
|
|
286
|
+
Component.mountById(app, "app")
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## How It Works
|
|
290
|
+
|
|
291
|
+
### Reactive System
|
|
292
|
+
|
|
293
|
+
- **Automatic dependency tracking** - When you read a signal with `Signal.get()` inside a computed or effect, it automatically tracks that dependency
|
|
294
|
+
- **Fine-grained updates** - Only the specific computeds and effects that depend on changed signals are re-executed
|
|
295
|
+
- **Synchronous by default** - Updates happen immediately and synchronously for predictable behavior
|
|
296
|
+
- **Batching support** - Group multiple updates to minimize re-computation
|
|
297
|
+
|
|
298
|
+
### Component Rendering
|
|
299
|
+
|
|
300
|
+
- **Initial render** - Components are rendered to real DOM elements on mount
|
|
301
|
+
- **Reactive text** - `textSignal()` creates text nodes that automatically update when their signal changes
|
|
302
|
+
- **Reactive lists** - `Component.list()` creates lists that automatically update when data changes
|
|
303
|
+
- **Direct DOM manipulation** - No virtual DOM diffing, updates are precise and efficient
|
|
304
|
+
- **Effect-based** - Signal changes trigger effects that update specific DOM nodes automatically
|
|
305
|
+
|
|
306
|
+
## Best Practices
|
|
307
|
+
|
|
308
|
+
1. **Keep signals at the top level** - Define signals outside component definitions for proper reactivity
|
|
309
|
+
2. **Use computed for derived state** - Don't repeat calculations, use `Computed.make()`
|
|
310
|
+
3. **Use `Component.list()` for reactive arrays** - Let the framework handle list updates automatically
|
|
311
|
+
4. **Batch related updates** - Use `Core.batch()` when updating multiple signals together
|
|
312
|
+
5. **Dispose effects when done** - Call `disposer.dispose()` for effects you no longer need
|
|
313
|
+
6. **Use `peek()` when you don't want tracking** - Read signal values without creating dependencies
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT © 2025
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/Xote.res.mjs"],"sourcesContent":["// Generated by ReScript, PLEASE EDIT WITH CARE\n\n\nvar Component;\n\nvar Computed;\n\nvar Core;\n\nvar Effect;\n\nvar Signal;\n\nexport {\n Component ,\n Computed ,\n Core ,\n Effect ,\n Signal ,\n}\n/* No side effect */\n"],"names":["Component","Computed","Core","Effect","Signal"],"mappings":"gFAGG,IAACA,EAEAC,EAEAC,EAEAC,EAEAC"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/Xote.res.mjs"],"sourcesContent":["// Generated by ReScript, PLEASE EDIT WITH CARE\n\n\nvar Component;\n\nvar Computed;\n\nvar Core;\n\nvar Effect;\n\nvar Signal;\n\nexport {\n Component ,\n Computed ,\n Core ,\n Effect ,\n Signal ,\n}\n/* No side effect */\n"],"names":["Component","Computed","Core","Effect","Signal"],"mappings":"AAGG,IAACA,GAEAC,GAEAC,GAEAC,GAEAC;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(e,n){typeof exports=="object"&&typeof module!="undefined"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(e=typeof globalThis!="undefined"?globalThis:e||self,n(e.xote={}))})(this,(function(e){"use strict";var n,o,t,f,i;e.Component=n,e.Computed=o,e.Core=t,e.Effect=f,e.Signal=i,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/Xote.res.mjs"],"sourcesContent":["// Generated by ReScript, PLEASE EDIT WITH CARE\n\n\nvar Component;\n\nvar Computed;\n\nvar Core;\n\nvar Effect;\n\nvar Signal;\n\nexport {\n Component ,\n Computed ,\n Core ,\n Effect ,\n Signal ,\n}\n/* No side effect */\n"],"names":["Component","Computed","Core","Effect","Signal"],"mappings":"+OAGG,IAACA,EAEAC,EAEAC,EAEAC,EAEAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## [1.0.1](https://github.com/brnrdog/xote/compare/v1.0.0...v1.0.1) (2025-10-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* version bump for release ([72fb74f](https://github.com/brnrdog/xote/commit/72fb74f2cf3d4a2389daf5363457d5d7ad4eaed1))
|
|
7
|
+
|
|
8
|
+
# 1.0.0 (2025-10-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* improve signal reactivity and add todo styling ([495f0bb](https://github.com/brnrdog/xote/commit/495f0bb52eaa8de89214f957f30b078f07029569))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* add Component system with automatic reactivity ([38815ed](https://github.com/brnrdog/xote/commit/38815ed3d1400c5511b790011d60081b317a69ac))
|
|
19
|
+
* add demo ([cf3faf3](https://github.com/brnrdog/xote/commit/cf3faf34c07d85a60d78d5f9539d2e2132f3b85a))
|
|
20
|
+
* minimal signal implementation based on the TC39 proposal ([9b78d0b](https://github.com/brnrdog/xote/commit/9b78d0b62ba21c953d909459036246f334b6613e))
|
package/index.html
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Xote Demo</title>
|
|
7
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
8
|
+
<script>
|
|
9
|
+
tailwind.config = {
|
|
10
|
+
darkMode: 'class',
|
|
11
|
+
theme: {
|
|
12
|
+
extend: {}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
</script>
|
|
16
|
+
<style>
|
|
17
|
+
.todo-list li.completed span {
|
|
18
|
+
text-decoration: line-through;
|
|
19
|
+
@apply text-gray-500 dark:text-gray-400;
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body class="bg-gray-50 dark:bg-gray-900 min-h-screen">
|
|
24
|
+
<div id="app"></div>
|
|
25
|
+
<script type="module" src="./src/demo/TodoApp.res.mjs">
|
|
26
|
+
</script>
|
|
27
|
+
</body>
|
|
28
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xote",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"url": "https://github.com/brnrdog/xote"
|
|
6
|
+
},
|
|
7
|
+
"scripts": {
|
|
8
|
+
"res:build": "rescript",
|
|
9
|
+
"res:clean": "rescript clean",
|
|
10
|
+
"res:dev": "rescript -w",
|
|
11
|
+
"dev": "vite",
|
|
12
|
+
"build": "vite build",
|
|
13
|
+
"preview": "vite preview"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"rescript",
|
|
17
|
+
"signals"
|
|
18
|
+
],
|
|
19
|
+
"release": {
|
|
20
|
+
"branches": [
|
|
21
|
+
"main"
|
|
22
|
+
],
|
|
23
|
+
"plugins": [
|
|
24
|
+
"@semantic-release/commit-analyzer",
|
|
25
|
+
"@semantic-release/release-notes-generator",
|
|
26
|
+
[
|
|
27
|
+
"@semantic-release/changelog",
|
|
28
|
+
{
|
|
29
|
+
"changelogFile": "docs/CHANGELOG.md"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
"@semantic-release/git",
|
|
34
|
+
{
|
|
35
|
+
"assets": [
|
|
36
|
+
"docs/CHANGELOG.md"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"@semantic-release/npm"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"author": "Bernardo Gurgel <brnrdog@hey.com>",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@rescript/core": "^1.6.1",
|
|
47
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
48
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
49
|
+
"@semantic-release/git": "^10.0.1",
|
|
50
|
+
"@semantic-release/github": "^12.0.0",
|
|
51
|
+
"@semantic-release/npm": "^13.1.1",
|
|
52
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
53
|
+
"rescript": "^11.1.4",
|
|
54
|
+
"semantic-release": "^25.0.1",
|
|
55
|
+
"vite": "^7.1.12"
|
|
56
|
+
}
|
|
57
|
+
}
|
package/rescript.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xote",
|
|
3
|
+
"sources": {
|
|
4
|
+
"dir": "src",
|
|
5
|
+
"subdirs": true
|
|
6
|
+
},
|
|
7
|
+
"package-specs": {
|
|
8
|
+
"module": "esmodule",
|
|
9
|
+
"in-source": true
|
|
10
|
+
},
|
|
11
|
+
"suffix": ".res.mjs",
|
|
12
|
+
"bs-dependencies": [
|
|
13
|
+
"@rescript/core"
|
|
14
|
+
],
|
|
15
|
+
"bsc-flags": [
|
|
16
|
+
"-open RescriptCore"
|
|
17
|
+
]
|
|
18
|
+
}
|
package/src/Xote.res
ADDED
package/src/Xote.res.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var Component;
|
|
5
|
+
|
|
6
|
+
var Computed;
|
|
7
|
+
|
|
8
|
+
var Core;
|
|
9
|
+
|
|
10
|
+
var Effect;
|
|
11
|
+
|
|
12
|
+
var Signal;
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
Component ,
|
|
16
|
+
Computed ,
|
|
17
|
+
Core ,
|
|
18
|
+
Effect ,
|
|
19
|
+
Signal ,
|
|
20
|
+
}
|
|
21
|
+
/* No side effect */
|