1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# CLI and App
`App` is a singleton **instance** of [Astal.Application](https://aylur.github.io/libastal/class.Application.html).
```ts
import { App } from "astal"
```
## Entry point
:::code-group
```ts [app.ts]
App.start({
main() {
// setup anything
// instantiate widgets
},
})
```
:::
:::warning
You can not instantiate widgets outside of the main function.
:::
## Instance identifier
You can run multiple instance by defining a unique instance name.
```ts
App.start({
instanceName: "my-instance", // defaults to "astal"
main() {},
})
```
## Messaging from CLI
If you want to interact with an instance from the cli, you can do so by sending a message.
```ts
App.start({
main() {},
requestHandler(request: string, res: (response: any) => void) {
if (request == "say hi") {
res("hi cli")
}
res("unknown command")
},
})
```
:::code-group
```sh [ags]
ags -m "say hi"
# hi cli
```
```sh [astal]
astal say hi
# hi cli
```
:::
If you want to run arbitrary JavaScript from cli, you can use `App.eval`.
It will evaluate the passed string as the body of an `async` function.
```ts
App.start({
main() {},
requestHandler(js: string, res) {
App.eval(js).then(res).catch(res)
},
})
```
If the string does not contain a semicolon, a single expression is assumed and returned implicity.
```sh
ags -m "'hello'"
# hello
```
If the string contains a semicolon, you have to return explicitly
```sh
ags -m "'hello';"
# undefined
ags -m "return 'hello';"
# hello
```
## App without AGS
As mentioned before AGS is only a scaffolding tool. You can setup
a dev environment and a bundler yourself. In which case you won't be using
the ags cli to run the bundled scripts. The produced script can run as the main instance
and a "client" instance.
The first time you run your bundled script the `main` function gets executed.
While that instance is running any subsequent execution of the script will call
the `client` function.
:::code-group
```ts [main.ts]
App.start({
// main instance
main(...args: Array<string>) {
print(...args)
},
// every subsequent calls
client(message: (msg: string) => string, ...args: Array<string>) {
const res = message("you can message the main instance")
console.log(res)
},
// this runs in the main instance
requestHandler(request: string, res: (response: any) => void) {
res("response from main")
},
})
```
:::
|