diff --git a/docs/guide/bundling.md b/docs/guide/bundling.md index 9b912ce3..a2482968 100644 --- a/docs/guide/bundling.md +++ b/docs/guide/bundling.md @@ -26,12 +26,80 @@ Flags: Currently there are 3 builtin plugins. - css: import `.css` will be inlined as a string -- sass: importing `.scss` files will go through the sass transpiler and be inlined as a string that contains valid css - - uses the `sass` executable found on $PATH -- blp: importing `.blp` files will go through [blueprint](https://jwestman.pages.gitlab.gnome.org/blueprint-compiler/) and be inlined as a string that contains valid xml template definitions +- sass: importing `.scss` files will go through the sass transpiler and be inlined as a string that contains valid css using the `sass` executable found on `$PATH` + :::code-group + + ```scss [style.scss] + $color: white; + + selector { + color: $color; + } + ``` + + ::: + :::code-group + + ```ts [ app.ts] + import style from "./style.scss" + + print(style) + // selector { + // color: white; + // } + ``` + + ::: + +- blp: importing `.blp` files will go through [blueprint](https://jwestman.pages.gitlab.gnome.org/blueprint-compiler/) and be inlined as a string that contains xml template definitions + :::code-group + + ```blp [ ui.blp] + using Gtk 4.0; + + Label { + label: _("hello"); + } + ``` + + ::: + :::code-group + + ```ts [ app.ts] + import ui from "./ui.blp" + + print(ui) + // + // + // + // + // hello + // + // + ``` + + ::: + - inline: importing with `inline:/path/to/file` will inline the contents of the file as a string + :::code-group + + ```txt [data.txt] + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do. + ``` -AGS defines `SRC` by default which by default will point to the directory of `entryfile`. + ::: + :::code-group + + ```ts [ app.ts] + import data from "inline:./data.txt" + + print(ui) + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do. + ``` + + ::: + +AGS defines `SRC` which by default will point to the directory of `entryfile`. It can be overriden with `-d "SRC='/path/to/source'"` ```js @@ -118,14 +186,94 @@ and distribute its output JS file as an executable. Optionally use a build tool like meson to also declare its runtime dependencies. When you have data files that you cannot inline as a string, for example icons, -a good practice would be to. +a good practice would be to: 1. Install data files to a directory, usually `/usr/share/your-project` 2. Define it as `DATADIR` in `env.d.ts` and at bundle time with `--define` 3. In code you can refer to data files through this `DATADIR` variable -Optionally you should use a build tool like meson or a makefile -to let users decide where to install to. + :::code-group -> [!NOTE] -> On Nix you can use the [lib.bundle](./nix#bundle-and-devshell) function. + ```meson [meson.build] + prefix = get_option('prefix') + pkgdatadir = prefix / get_option('datadir') / meson.project_name() + bindir = prefix / get_option('bindir') + + install_data( + files('data/data.txt'), + install_dir: pkgdatadir, + ) + + custom_target( + command: [ + find_program('ags'), + 'bundle', + '--define', 'DATADIR="' + pkgdatadir + '"', + meson.project_source_root() / 'app.ts', + meson.project_name(), + ], + output: [meson.project_name()], + input: files('app.ts'), + install: true, + install_dir: bindir, + ) + ``` + + ```ts [env.d.ts] + declare const DATADIR: string + ``` + + ```ts [app.ts] + const data = `${DATADIR}/data.txt` + ``` + + ::: + +> [!TIP] +> On Nix you can use the [lib.bundle](./nix#bundle-and-devshell) function as well as meson. + +## Notice for Gtk4 + +[`gtk4-layer-shell` needs to be linked before wayland.](https://github.com/wmww/gtk4-layer-shell/issues/3#issuecomment-1502339477) +When bundling a Gtk4 application you will have to use a wrapper to make it work. + +:::code-group + +```bash [wrapper.sh] +#!/bin/bash +LD_PRELOAD="@LAYER_SHELL_LIBDIR@/libgtk4-layer-shell.so" @MAIN_PROGRAM@ $@ +``` + +::: +:::code-group + +```meson [meson.build] +pkgdatadir = get_option('prefix') / get_option('datadir') / meson.project_name() +main = meson.project_name() + '.wrapped' + +custom_target( + command: [ + find_program('ags'), + 'bundle', + meson.project_source_root() / 'app.ts', + main, + ], + output: [meson.project_name()], + input: files('app.ts'), + install: true, + install_dir: pkgdatadir, +) + +configure_file( + input: files('wrapper.sh'), + output: meson.project_name(), + configuration: { + 'MAIN_PROGRAM': pkgdatadir / main, + 'LAYER_SHELL_LIBDIR': dependency('gtk4-layer-shell-0').get_variable('libdir'), + }, + install: true, + install_dir: get_option('prefix') / get_option('bindir'), +) +``` + +::: diff --git a/docs/guide/example.md b/docs/guide/example.md index 47805e16..ef46e9b2 100644 --- a/docs/guide/example.md +++ b/docs/guide/example.md @@ -106,5 +106,6 @@ fi ``` > [!TIP] -> If you are happy with the script and don't plan to change it anymore [bundle](./bundling.md) it, +> If you are happy with the script and don't +> plan to change it anymore [bundle](./bundling.md) it, > which will remove the dependency on AGS. diff --git a/docs/guide/init.md b/docs/guide/init.md index e96a7d7b..a817d018 100644 --- a/docs/guide/init.md +++ b/docs/guide/init.md @@ -26,43 +26,42 @@ It will generate the following files: ```txt . -├── .gitignore -├── @girs/ # generated types +├── @girs/ +├── node_modules/ +│ └── astal ├── widget/ │ └── Bar.tsx -├── app.ts # entry proint -├── env.d.ts # additional types +├── app.ts +├── env.d.ts ├── style.scss -└── tsconfig.json # needed by LSPs +├── package.json +└── tsconfig.json ``` The `@girs` directory contains the generated types, which are created when running the `init` command or the `types` command. -Assuming this directory will be tracked with git, -it generates a `.gitignore` file which is set to ignore `@girs` and `node_modules`. -Initially `node_modules` doesn't exist, but if you decide to install any `npm` -package it is not needed to track them with git. You can also add `tsconfig.json` -and `env.d.ts` to this list, as they are only used for developing and can be -regenerated with the `types` command. Only track `tsconfig.json` if you add -anything additional to `compilerOptions.paths`. - -> [!NOTE] -> Since the runtime is `gjs`, very few packages will run from `npm`. +:::details Details on TypeScript. +While `gjs` does not currently support Node.js project structures and its ecosystem +the JavaScript tooling we are using relies on it. The `node_modules` directory +contains the `astal` package, but its purpose is only to provide type information. +The `package.json` is a file describing the project and `tsconfig.json` is a file +containing settings for TypeScript. +::: -The `env.d.ts` will tell the LSP that `.css`, `.scss` and `.blp` files can be -imported and will be inlined as a string. It also tells it that imports -prefixed with `inline:` will be inlined as well as that a global `SRC` variable -is available. +> [!WARNING] +> Since the runtime is `gjs`, very few packages will run from `npm`, +since most depends on `node` features. -The `tsconfig.json` file tells information to the LSP so that -intellisense can do its thing and provide great DX. +The `env.d.ts` let's the type checker in your editor know about additional +[features](./bundling) the `ags` bundler provides, for example the ability to inline files. +This can be also be expanded for variables defined with the `--define` flag at bundling. -`app.ts` is the entry point of the project which usually contains only -an `App.start` call where you define [main](https://aylur.github.io/astal/guide/typescript/cli-app#entry-point) and [requestHandler](https://aylur.github.io/astal/guide/typescript/cli-app#messaging-from-cli), +`app.ts` is the entry point of the project which usually +contains only an `App.start` call where you define [main](https://aylur.github.io/astal/guide/typescript/cli-app#entry-point) and [requestHandler](https://aylur.github.io/astal/guide/typescript/cli-app#messaging-from-cli), but can contain any other code. -> [!NOTE] +> [!TIP] > You could also name the entry file `app.tsx` and write any JSX there. > [!TIP] @@ -70,15 +69,14 @@ but can contain any other code. > in `tsconfig.json` and optionally `"checkJs": true` will allow > JavaScript, although it is very much recommended to TypeScript. -You are not forced into a project structure. You can put -`style.scss` and `widget/Bar.ts` anywhere you like, only the entry file matters. - ## Running projects `tsconfig.json`, `env.d.ts` and `@girs` are only significant for the LSP, they are not needed to run the project. -:::tip -You can also use `ags run` as a shebang line for simple scripts. -See an [simple dialog example](./example.md) -::: +> [!TIP] +> You can also use `ags run` as a shebang line for simple scripts. +> See an [simple dialog example](./example.md). + +> [!IMPORTANT] +> When using Gtk4 you have to use `--gtk4` flag for [gtk4-layer-shell](https://github.com/wmww/gtk4-layer-shell/issues/3#issuecomment-1502339477). diff --git a/docs/guide/nix.md b/docs/guide/nix.md index 68936ee4..69ddff6c 100644 --- a/docs/guide/nix.md +++ b/docs/guide/nix.md @@ -29,6 +29,7 @@ Using nix, you'll technically never have to use the `ags` cli. src = ./.; name = "my-shell"; # name of executable entry = "app.ts"; + gtk4 = false; # additional libraries and executables to add to gjs' runtime extraPackages = [ diff --git a/docs/guide/quick-start.md b/docs/guide/quick-start.md index 902ce779..eef6594d 100644 --- a/docs/guide/quick-start.md +++ b/docs/guide/quick-start.md @@ -16,16 +16,32 @@ nix shell github:aylur/ags # ags in a temporary shell 2. Initialize a project -```sh -ags init +:::code-group + +```sh [Gtk3] +ags init --gtk 3 +``` + +```sh [Gtk4] +ags init --gtk 3 ``` +::: + 3. Run the project -```sh +:::code-group + +```sh [Gtk3] ags run ``` +```sh [Gtk4] +ags run --gtk4 +``` + +::: + 4. Learn [TypeScript in Y minutes](https://learnxinyminutes.com/docs/typescript/) 5. Read the [Astal Documentation](https://aylur.github.io/astal/guide/typescript/first-widgets) to start developing diff --git a/docs/vitepress.config.ts b/docs/vitepress.config.ts index cd6bfea6..19a0296c 100644 --- a/docs/vitepress.config.ts +++ b/docs/vitepress.config.ts @@ -12,6 +12,13 @@ export default defineConfig({ ["link", { rel: "icon", href: "https://aylur.github.io/astal/icon.svg" }], ], + markdown: { + languageAlias: { + meson: "ruby", + blp: "c", // TODO: find a better alternative + }, + }, + themeConfig: { outline: "deep", diff --git a/flake.nix b/flake.nix index b518444d..5ba30ef1 100644 --- a/flake.nix +++ b/flake.nix @@ -55,7 +55,16 @@ }; devShells.${system}.default = pkgs.mkShell { - packages = with pkgs; [go gopls gotools go-tools]; + packages = with pkgs; [ + markdownlint-cli2 + marksman + vtsls + vscode-langservers-extracted + go + gopls + gotools + go-tools + ]; }; }; } diff --git a/lib/esbuild.go b/lib/esbuild.go index 7d89f8c0..af5bb5da 100644 --- a/lib/esbuild.go +++ b/lib/esbuild.go @@ -161,6 +161,11 @@ func Bundle(opts BundleOpts) { Platform: api.PlatformNeutral, TsconfigRaw: tsconfig, Define: defines, + Target: api.ES2022, + Sourcemap: api.SourceMapInline, + Engines: []api.Engine{ + {Name: api.EngineFirefox, Version: "115"}, + }, Loader: map[string]api.Loader{ ".js": api.LoaderJSX, ".css": api.LoaderText, diff --git a/nix/bundle.nix b/nix/bundle.nix index 75c96106..8896605e 100644 --- a/nix/bundle.nix +++ b/nix/bundle.nix @@ -7,6 +7,7 @@ src, name, extraPackages ? [], + gtk4 ? false, }: pkgs.stdenvNoCC.mkDerivation { inherit src name; @@ -29,6 +30,7 @@ pkgs.stdenvNoCC.mkDerivation { preFixup = '' gappsWrapperArgs+=( + --set LD_PRELOAD "${pkgs.gtk4-layer-shell}/lib/libgtk4-layer-shell.so" --prefix PATH : ${with pkgs; lib.makeBinPath (extraPackages ++ [