summaryrefslogtreecommitdiff
path: root/docs/ags/cli-app.md
blob: 0f17d55b0d8a51d347c187829c6d0ed018033160 (plain)
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
# CLI and App

`App` is a singleton **instance** of [Astal.Application](/astal/reference/class.Application.html).

```tsx
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.

```tsx
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")
    },
})
```

```bash
# ags cli
$ ags -m "say hi"
hi cli

# astal cli
$ 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.

```bash
$ ags -m "'hello'"
hello
```

If the string contains a semicolon, you have to return explicitly

```bash
$ 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")
    },
})
```

:::