galath 1.0.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.
- package/AGENTS.md +1 -0
- package/README.md +206 -0
- package/TODO.md +140 -0
- package/index.html +188 -0
- package/logo.jpg +0 -0
- package/logo.svg +96 -0
- package/package.json +32 -0
- package/packages/galath/package.json +28 -0
- package/packages/galath/src/behavior.js +193 -0
- package/packages/galath/src/binding.js +247 -0
- package/packages/galath/src/boot.js +52 -0
- package/packages/galath/src/command.js +117 -0
- package/packages/galath/src/component.js +505 -0
- package/packages/galath/src/controller.js +181 -0
- package/packages/galath/src/core.js +190 -0
- package/packages/galath/src/imports.js +132 -0
- package/packages/galath/src/index.js +38 -0
- package/packages/galath/src/instance-model.js +343 -0
- package/packages/galath/src/morph.js +237 -0
- package/packages/galath/src/rendering.js +556 -0
- package/packages/galath/src/signals.js +215 -0
- package/packages/galath/src/templates.js +24 -0
- package/packages/galath/src/xml-events.js +53 -0
- package/packages/galath-css/css/bootstrap-icons.min.css +5 -0
- package/packages/galath-css/css/bootstrap.min.css +6 -0
- package/packages/galath-css/css/fonts/bootstrap-icons.json +2077 -0
- package/packages/galath-css/css/fonts/bootstrap-icons.woff +0 -0
- package/packages/galath-css/css/fonts/bootstrap-icons.woff2 +0 -0
- package/packages/galath-css/js/bootstrap.bundle.min.js +7 -0
- package/packages/galath-css/package.json +13 -0
- package/playground/app.xml +214 -0
- package/playground/chapters/01-welcome.xml +94 -0
- package/playground/chapters/02-signals.xml +166 -0
- package/playground/chapters/03-instance.xml +130 -0
- package/playground/chapters/04-bindings.xml +156 -0
- package/playground/chapters/05-lists.xml +138 -0
- package/playground/chapters/06-commands.xml +144 -0
- package/playground/chapters/07-controller.xml +115 -0
- package/playground/chapters/08-events.xml +126 -0
- package/playground/chapters/09-behaviors.xml +210 -0
- package/playground/chapters/10-components.xml +152 -0
- package/playground/chapters/11-imports.xml +108 -0
- package/playground/chapters/12-expressions.xml +161 -0
- package/playground/chapters/13-paths.xml +197 -0
- package/playground/components/chapter-shell.xml +29 -0
- package/playground/components/highlighter.js +111 -0
- package/playground/components/run-snippet.js +120 -0
- package/public/basic/bootstrap-icons.min.css +5 -0
- package/public/basic/bootstrap.bundle.min.js +7 -0
- package/public/basic/bootstrap.min.css +6 -0
- package/public/basic/fonts/bootstrap-icons.json +2077 -0
- package/public/basic/fonts/bootstrap-icons.woff +0 -0
- package/public/basic/fonts/bootstrap-icons.woff2 +0 -0
- package/public/basic/theme.css +209 -0
- package/seed.html +321 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- External npm dependencies are forbidden due to possibley supply chain attacks
|
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Galath Strong Core
|
|
2
|
+
|
|
3
|
+
An XML manifesto for the age of AI.
|
|
4
|
+
|
|
5
|
+
Galath is a small language for web applications. It treats UI, state, events,
|
|
6
|
+
commands, components, imports, and instance data as explicit XML structure.
|
|
7
|
+
The goal is not nostalgia. The goal is a stronger substrate for humans and
|
|
8
|
+
machines to read, edit, verify, and extend.
|
|
9
|
+
|
|
10
|
+
```xml
|
|
11
|
+
<component name="counter" tag="x-counter">
|
|
12
|
+
<model>
|
|
13
|
+
<signal name="count" value="0" />
|
|
14
|
+
<signal name="step" value="1" />
|
|
15
|
+
</model>
|
|
16
|
+
|
|
17
|
+
<view>
|
|
18
|
+
<button on:click="set('count', count + step)">+</button>
|
|
19
|
+
<span>Count: {count}</span>
|
|
20
|
+
<input type="number" bind:value="step" />
|
|
21
|
+
</view>
|
|
22
|
+
</component>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## The Claim
|
|
26
|
+
|
|
27
|
+
AI does not need less structure. It needs better structure.
|
|
28
|
+
|
|
29
|
+
The web became powerful by accepting strings everywhere: HTML strings, CSS
|
|
30
|
+
strings, JavaScript strings, JSON strings, template strings, build config
|
|
31
|
+
strings. That freedom made software easy to start and hard to reason about.
|
|
32
|
+
Every agent, editor, linter, compiler, and reviewer must infer the shape of
|
|
33
|
+
the program from conventions.
|
|
34
|
+
|
|
35
|
+
Galath makes the shape visible.
|
|
36
|
+
|
|
37
|
+
```xml
|
|
38
|
+
<model> declares state.</model>
|
|
39
|
+
<view> declares the interface.</view>
|
|
40
|
+
<controller> names behavior.</controller>
|
|
41
|
+
<commandset> names intent.</commandset>
|
|
42
|
+
<instance> carries structured data.</instance>
|
|
43
|
+
<import> composes documents.</import>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
This is the strong core: a small number of explicit concepts, each with a
|
|
47
|
+
clear place in the document.
|
|
48
|
+
|
|
49
|
+
## Principles
|
|
50
|
+
|
|
51
|
+
**Structure before cleverness.** A Galath document should be inspectable by a
|
|
52
|
+
person, a browser, a test, or an AI agent without first reverse-engineering a
|
|
53
|
+
framework's private conventions.
|
|
54
|
+
|
|
55
|
+
**State is named.** Dynamic values live in signals or in the XML instance tree.
|
|
56
|
+
When something changes, the path to that change is visible.
|
|
57
|
+
|
|
58
|
+
**Behavior is addressable.** Inline event code exists, but durable behavior can
|
|
59
|
+
be named in controllers and commands.
|
|
60
|
+
|
|
61
|
+
**Composition is document-level.** Features can live in separate XML files and
|
|
62
|
+
arrive through `<import>`, not through a bundler ceremony.
|
|
63
|
+
|
|
64
|
+
**The runtime stays small.** Galath has no external npm dependencies. The
|
|
65
|
+
project favors readable platform code over supply-chain reach.
|
|
66
|
+
|
|
67
|
+
**Escapes are explicit.** Expressions are JavaScript expressions in a scoped
|
|
68
|
+
context. Paths are a strict XPath-like subset. When the language crosses into
|
|
69
|
+
JavaScript, it does so plainly.
|
|
70
|
+
|
|
71
|
+
## Why XML Now
|
|
72
|
+
|
|
73
|
+
XML is not just angle brackets. XML is a contract:
|
|
74
|
+
|
|
75
|
+
- elements have names;
|
|
76
|
+
- attributes have names;
|
|
77
|
+
- nesting is explicit;
|
|
78
|
+
- documents are parseable before execution;
|
|
79
|
+
- namespaces let languages grow without guessing;
|
|
80
|
+
- source can be transformed without pretending it is text.
|
|
81
|
+
|
|
82
|
+
That matters in the age of AI because agents are better collaborators when the
|
|
83
|
+
program has visible grammar. A model can add a chapter, inspect a component,
|
|
84
|
+
trace a signal, or rewrite a command without guessing which string is code,
|
|
85
|
+
which string is markup, and which string is data.
|
|
86
|
+
|
|
87
|
+
```xml
|
|
88
|
+
<repeat ref="/todos/todo" as="todo">
|
|
89
|
+
<button on:click="deleteNode($todo)">Delete</button>
|
|
90
|
+
<text value="$todo/@text" />
|
|
91
|
+
</repeat>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The data path is visible. The local variable is visible. The event boundary is
|
|
95
|
+
visible. This is what strong markup buys back.
|
|
96
|
+
|
|
97
|
+
## What Galath Includes
|
|
98
|
+
|
|
99
|
+
- Custom elements from `<component>`.
|
|
100
|
+
- Reactive `<signal>` values.
|
|
101
|
+
- Derived `<computed>` values.
|
|
102
|
+
- XML instance trees with path selection.
|
|
103
|
+
- Interpolation with `{expr}`.
|
|
104
|
+
- Two-way bindings with `bind:value` and `bind:checked`.
|
|
105
|
+
- Event handlers with `on:*`.
|
|
106
|
+
- Named controller actions.
|
|
107
|
+
- Command sets.
|
|
108
|
+
- Reusable data templates.
|
|
109
|
+
- XML imports.
|
|
110
|
+
- Attached behaviors.
|
|
111
|
+
- Lifecycle hooks with `<on:mount>` and `<on:unmount>`.
|
|
112
|
+
- DOM morphing to preserve focus and form state.
|
|
113
|
+
|
|
114
|
+
## Run The Playground
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
npm run serve
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then open the served URL. The playground is the main documentation surface and
|
|
121
|
+
is itself written in Galath.
|
|
122
|
+
|
|
123
|
+
No build step is required for the playground. The browser loads local modules
|
|
124
|
+
through an import map.
|
|
125
|
+
|
|
126
|
+
## Minimal Boot
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<div id="mount"></div>
|
|
130
|
+
|
|
131
|
+
<script type="application/xml" id="galath-source">
|
|
132
|
+
<galath version="1.0">
|
|
133
|
+
<component name="hello" tag="x-hello">
|
|
134
|
+
<model>
|
|
135
|
+
<signal name="name" value="World" />
|
|
136
|
+
</model>
|
|
137
|
+
<view>
|
|
138
|
+
<h1>Hello, {name}.</h1>
|
|
139
|
+
</view>
|
|
140
|
+
</component>
|
|
141
|
+
|
|
142
|
+
<application name="app">
|
|
143
|
+
<x-hello />
|
|
144
|
+
</application>
|
|
145
|
+
</galath>
|
|
146
|
+
</script>
|
|
147
|
+
|
|
148
|
+
<script type="module">
|
|
149
|
+
import { boot } from 'galath/boot';
|
|
150
|
+
|
|
151
|
+
await boot({
|
|
152
|
+
source: document.getElementById('galath-source').textContent,
|
|
153
|
+
mount: document.getElementById('mount'),
|
|
154
|
+
});
|
|
155
|
+
</script>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## The Strong Core Contract
|
|
159
|
+
|
|
160
|
+
Galath should remain small enough to understand and structured enough to grow.
|
|
161
|
+
|
|
162
|
+
It should be possible to answer these questions by reading the document:
|
|
163
|
+
|
|
164
|
+
- What state exists?
|
|
165
|
+
- What data tree exists?
|
|
166
|
+
- What renders?
|
|
167
|
+
- What changes state?
|
|
168
|
+
- What paths are read or written?
|
|
169
|
+
- What components are imported?
|
|
170
|
+
- What behavior is named?
|
|
171
|
+
|
|
172
|
+
If a language can answer those questions directly, AI tools can help without
|
|
173
|
+
turning the codebase into mud.
|
|
174
|
+
|
|
175
|
+
## Not A Framework Fashion
|
|
176
|
+
|
|
177
|
+
Galath is not trying to hide the platform. It uses the platform:
|
|
178
|
+
|
|
179
|
+
- Custom Elements for component boundaries.
|
|
180
|
+
- DOMParser and XMLSerializer for documents.
|
|
181
|
+
- `fetch()` for imports.
|
|
182
|
+
- native events for interaction.
|
|
183
|
+
- import maps for local modules.
|
|
184
|
+
|
|
185
|
+
The language is a thin, explicit layer over the browser. Its job is to preserve
|
|
186
|
+
the structure that ordinary web code too often throws away.
|
|
187
|
+
|
|
188
|
+
## The Manifesto
|
|
189
|
+
|
|
190
|
+
We choose documents over blobs.
|
|
191
|
+
|
|
192
|
+
We choose named state over ambient mutation.
|
|
193
|
+
|
|
194
|
+
We choose paths over guesswork.
|
|
195
|
+
|
|
196
|
+
We choose explicit imports over invisible build magic.
|
|
197
|
+
|
|
198
|
+
We choose small runtimes over dependency gravity.
|
|
199
|
+
|
|
200
|
+
We choose a language an AI can inspect without hallucinating the shape of the
|
|
201
|
+
program.
|
|
202
|
+
|
|
203
|
+
We choose XML not because it is old, but because it is still one of the few
|
|
204
|
+
formats honest enough to say what a program is made of.
|
|
205
|
+
|
|
206
|
+
That is Galath Strong Core.
|
package/TODO.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Galath - TODO
|
|
2
|
+
|
|
3
|
+
Items left for follow-up. None are blocking; the runtime, the playground, and
|
|
4
|
+
the reference demo all work as shipped. These are improvements that would make
|
|
5
|
+
Galath more capable, more polished, or more productive for authors.
|
|
6
|
+
|
|
7
|
+
The list is grouped by who can pick it up. The "Sonnet-friendly" pile is
|
|
8
|
+
deliberately scoped: clear inputs, clear outputs, low ambiguity.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Sonnet-friendly (good first tasks)
|
|
13
|
+
|
|
14
|
+
### Documentation
|
|
15
|
+
|
|
16
|
+
- [ ] **Write `packages/galath/README.md`.** Cover: install (none), import
|
|
17
|
+
map setup, two-line boot, link to playground, link to seed.html, list of
|
|
18
|
+
features. Keep under 300 lines.
|
|
19
|
+
- [ ] **Write `docs/PATHS.md`** documenting the path grammar. Include a
|
|
20
|
+
cheat-sheet for `/foo/bar`, `/foo/bar[@id=x]`, `$todo/@text`, `/text()`,
|
|
21
|
+
wildcard `*`. Show what's unsupported (descendant `//`, function calls
|
|
22
|
+
beyond `text()`, multi-step predicates).
|
|
23
|
+
- [ ] **Write `docs/EXPRESSIONS.md`** documenting which helpers are in
|
|
24
|
+
scope (`uid`, `select`, `valueOf`, `set`, `attr`, `deleteNode`,
|
|
25
|
+
`setNode`, `$event`, all signal names, all locals). Note the JS escape
|
|
26
|
+
hatch for anything else.
|
|
27
|
+
|
|
28
|
+
### Playground polish
|
|
29
|
+
|
|
30
|
+
- [ ] **Add a "Run" button** to each chapter's source listing that opens
|
|
31
|
+
the snippet in a new tab as a complete HTML file. Implementation: a
|
|
32
|
+
command that copies the snippet into a Blob and `URL.createObjectURL`,
|
|
33
|
+
with the standard import map / boot wrapper.
|
|
34
|
+
- [ ] **Add basic syntax highlighting** to `<pre class="xes-code">`
|
|
35
|
+
blocks. Either ship a tiny tokenizer in `playground/components/` or
|
|
36
|
+
add a `use:highlight` behavior. Keep it under 150 lines; we don't
|
|
37
|
+
want a full Prism dependency.
|
|
38
|
+
- [ ] **Add a toggle** to switch between the "narrated" chapter view
|
|
39
|
+
(current) and a "code-only" view that hides the docs card. Useful for
|
|
40
|
+
experienced readers.
|
|
41
|
+
- [ ] **Keyboard navigation**: left/right arrows move between chapters.
|
|
42
|
+
Implement as a `keydown` listener in the playground's `<on:mount>`.
|
|
43
|
+
|
|
44
|
+
### Chapter improvements
|
|
45
|
+
|
|
46
|
+
- [ ] **02-signals**: add a "computed chain" demo - `a -> b -> c` where
|
|
47
|
+
each is computed from the previous. Explain dependency tracking is
|
|
48
|
+
explicit (via `from=`).
|
|
49
|
+
- [ ] **04-bindings**: add `bind:` examples for `<select>` and date
|
|
50
|
+
inputs.
|
|
51
|
+
- [ ] **05-lists**: add an `index`-based example using the implicit
|
|
52
|
+
`index` local that `<repeat>` provides.
|
|
53
|
+
- [ ] **06-commands**: add a `<command shortcut="ctrl+s">` example. (See
|
|
54
|
+
language work below - shortcuts are not yet implemented.)
|
|
55
|
+
- [ ] **09-behaviors**: write a "build your own behavior" subsection
|
|
56
|
+
showing how to register a new behavior via
|
|
57
|
+
`language.behaviors.set(...)` from a feature plugin.
|
|
58
|
+
|
|
59
|
+
### Tests
|
|
60
|
+
|
|
61
|
+
- [ ] **Add a Playwright smoke test** that boots `index.html`, clicks
|
|
62
|
+
through each chapter, and asserts there's no console error.
|
|
63
|
+
- [ ] **Add unit tests for path parsing** in `packages/galath/test/`
|
|
64
|
+
covering the cases listed in `docs/PATHS.md`.
|
|
65
|
+
- [ ] **Add unit tests for `morph.js`** covering: focus preservation,
|
|
66
|
+
child swap by tag, attribute removal, custom-element child skip.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Larger pieces (Opus-y, but not urgent)
|
|
71
|
+
|
|
72
|
+
### Language features
|
|
73
|
+
|
|
74
|
+
- [x] **`<slot>` support** so components can accept inline children. This
|
|
75
|
+
removes the "pass code in a signal name" workaround in `code-card`.
|
|
76
|
+
Touches `component.js` (capture inline children before stamping
|
|
77
|
+
xesRoot) and `rendering.js` (resolve `<slot>` against the captured
|
|
78
|
+
fragment, fall back to default content).
|
|
79
|
+
- [x] **Cross-component scope reads.** Add a directive like
|
|
80
|
+
`bind:from-parent="signalName"` that lets a child read a signal in its
|
|
81
|
+
parent component. Walk up via `closest('[data-xes-root]')`.
|
|
82
|
+
- [x] **Keyed `<repeat>` / `<items>`**. Today the renderer relies on
|
|
83
|
+
positional matching plus `morph.js`. With reorders this is fine but
|
|
84
|
+
slower than necessary. Add `key="@id"` and a simple keyed reconciler.
|
|
85
|
+
- [x] **`<switch on="expr"><case value="...">...</case><default>...</default></switch>`**.
|
|
86
|
+
Cleaner than chained `<if>`. Lower in `rendering.js`.
|
|
87
|
+
- [x] **Async operations**: `<fetch url="..." into="signal">` and
|
|
88
|
+
`<command async>`. Useful for real-world data loading without dropping
|
|
89
|
+
into `<eval>`.
|
|
90
|
+
- [x] **Form validation**: re-introduce XForms `<bind constraint="..."
|
|
91
|
+
required="..." type="...">` and surface validation state to inputs.
|
|
92
|
+
|
|
93
|
+
### Tooling
|
|
94
|
+
|
|
95
|
+
- [ ] **VS Code extension** for `.xml` syntax in the Galath dialect
|
|
96
|
+
(color the directives, autocomplete bindings, hover docs).
|
|
97
|
+
- [ ] **A static linter** that walks Galath sources and reports common
|
|
98
|
+
mistakes: unknown component tags, dead `<command name>` (never
|
|
99
|
+
referenced), unbound `bind:` paths against the declared instance tree.
|
|
100
|
+
- [ ] **Source map** from rendered HTML elements back to the source
|
|
101
|
+
XML line. Useful for in-browser DevTools-like inspection.
|
|
102
|
+
|
|
103
|
+
### Performance
|
|
104
|
+
|
|
105
|
+
- [x] **Granular signal -> render mapping**. Today any signal change
|
|
106
|
+
re-renders the whole component view. Track which bindings depend on
|
|
107
|
+
which signals (we already collect bindings during render); re-run only
|
|
108
|
+
the affected expressions on update.
|
|
109
|
+
|
|
110
|
+
### Ecosystem
|
|
111
|
+
|
|
112
|
+
- [ ] **A few real apps** built on Galath - a markdown editor, a kanban
|
|
113
|
+
board, a small SPA that talks to an HTTP API. They will surface holes
|
|
114
|
+
in the language we don't see from the playground.
|
|
115
|
+
- [ ] **Standard component library** in `packages/galath-ui/` -
|
|
116
|
+
consistent buttons, modal, table, form. Optional; depends only on the
|
|
117
|
+
base runtime.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Open questions
|
|
122
|
+
|
|
123
|
+
- Should component instances persist across `<if>` toggles, or always
|
|
124
|
+
re-mount? Today they re-mount. Persisting would need a "keep alive"
|
|
125
|
+
directive and a place to stash detached instances.
|
|
126
|
+
answer: follow the web-component approach, remount
|
|
127
|
+
- Should `<text value="...">` accept template syntax like `{count}` or
|
|
128
|
+
always be a single path? Right now it's a single path; mixing would
|
|
129
|
+
collide with the path grammar.
|
|
130
|
+
answer: no collisions, keep it simple.
|
|
131
|
+
- What do we do about CSS-in-Galath? Today `<style>` is a global
|
|
132
|
+
scoped sheet. Should we accept `<style scoped="false">` or
|
|
133
|
+
`<style :where>` for opt-in scope rules?
|
|
134
|
+
answer: CSS must be external to Galath, provided by a powerful build system like CSS.
|
|
135
|
+
|
|
136
|
+
## Not Interested / Cancelled
|
|
137
|
+
|
|
138
|
+
- [-] **Compile views**. Pre-compile `<view>` to a JS function at
|
|
139
|
+
registerComponent time so renders skip the XML walk. Big change; only
|
|
140
|
+
worth it if profiling shows the renderer is a bottleneck.
|
package/index.html
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<!--
|
|
3
|
+
index.html
|
|
4
|
+
==========
|
|
5
|
+
|
|
6
|
+
The Galath playground entry point. A small shell:
|
|
7
|
+
|
|
8
|
+
1. Pulls in local Bootstrap CSS + Bootstrap Icons (see node_modules/galath-css).
|
|
9
|
+
2. Declares a native browser <importmap> so `import 'galath'` resolves to
|
|
10
|
+
packages/galath via a symlink in node_modules.
|
|
11
|
+
3. Declares one Galath source document. The document is mostly
|
|
12
|
+
<import src="..."/> lines that pull in chapter components and the
|
|
13
|
+
playground shell.
|
|
14
|
+
4. Boots Galath with two lines of JavaScript.
|
|
15
|
+
|
|
16
|
+
The whole tutorial is written in Galath itself - dogfooding the language.
|
|
17
|
+
Every chapter is a separate XML file under ./playground/chapters/, kept
|
|
18
|
+
small and focused. To add another chapter:
|
|
19
|
+
|
|
20
|
+
a. Create ./playground/chapters/12-my-feature.xml that defines a
|
|
21
|
+
<component name="chapter-myFeature" tag="x-chapter-myFeature">.
|
|
22
|
+
b. Add an <import src="./playground/chapters/12-my-feature.xml"/> below.
|
|
23
|
+
c. Add a <chapter id="myFeature" .../> entry in app.xml.
|
|
24
|
+
d. Add an <if test="activeChapter === 'myFeature'"> branch in app.xml.
|
|
25
|
+
|
|
26
|
+
To run:
|
|
27
|
+
npx serve . (or `python3 -m http.server 8080`)
|
|
28
|
+
open http://localhost:8080/
|
|
29
|
+
|
|
30
|
+
No build step. No bundler. No transpiler. Just the browser.
|
|
31
|
+
-->
|
|
32
|
+
<html lang="en" data-bs-theme="dark">
|
|
33
|
+
<head>
|
|
34
|
+
<meta charset="utf-8">
|
|
35
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
36
|
+
<title>Galath Playground</title>
|
|
37
|
+
|
|
38
|
+
<!-- Local stylesheets - works offline. -->
|
|
39
|
+
<link href="./node_modules/galath-css/css/bootstrap.min.css" rel="stylesheet">
|
|
40
|
+
<link href="./node_modules/galath-css/css/bootstrap-icons.min.css" rel="stylesheet">
|
|
41
|
+
|
|
42
|
+
<!--
|
|
43
|
+
Native browser import map. `galath/boot` is the convenience entry that
|
|
44
|
+
plugs every standard feature in and starts the language. The mapping
|
|
45
|
+
goes through ./node_modules/galath -> packages/galath, set up as a
|
|
46
|
+
symlink so we don't have to publish to a registry to develop locally.
|
|
47
|
+
-->
|
|
48
|
+
<script type="importmap">
|
|
49
|
+
{
|
|
50
|
+
"imports": {
|
|
51
|
+
"galath": "./node_modules/galath/src/index.js",
|
|
52
|
+
"galath/boot": "./node_modules/galath/src/boot.js"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style>
|
|
58
|
+
/*
|
|
59
|
+
Page chrome. Component-internal styles live inside their components'
|
|
60
|
+
<style> blocks where they get auto-scoped to the component root.
|
|
61
|
+
*/
|
|
62
|
+
:root {
|
|
63
|
+
--xes-shell: #06101f;
|
|
64
|
+
--xes-line: rgba(255, 255, 255, .12);
|
|
65
|
+
--xes-card: rgba(255, 255, 255, .045);
|
|
66
|
+
--xes-card-2: rgba(255, 255, 255, .022);
|
|
67
|
+
}
|
|
68
|
+
body {
|
|
69
|
+
min-height: 100vh;
|
|
70
|
+
background:
|
|
71
|
+
radial-gradient(circle at top left, rgba(13, 202, 240, .14), transparent 34rem),
|
|
72
|
+
radial-gradient(circle at top right, rgba(255, 193, 7, .08), transparent 28rem),
|
|
73
|
+
linear-gradient(180deg, #040812, var(--xes-shell));
|
|
74
|
+
}
|
|
75
|
+
.xes-card { background: linear-gradient(180deg, var(--xes-card), var(--xes-card-2)); border: 1px solid var(--xes-line); box-shadow: 0 1rem 3rem rgba(0,0,0,.22); }
|
|
76
|
+
.xes-code { max-height: 26rem; overflow: auto; font-size: .8rem; background: rgba(0,0,0,.34); border: 1px solid var(--xes-line); }
|
|
77
|
+
.xes-nav-link { width: 100%; text-align: left; color: var(--bs-body-color); background: transparent; border: 0; }
|
|
78
|
+
.xes-nav-link:hover { background-color: rgba(255,255,255,.07); }
|
|
79
|
+
.xes-nav-link.active { background-color: rgba(13,202,240,.16); box-shadow: inset 3px 0 0 var(--bs-info); color: var(--bs-info-text-emphasis); }
|
|
80
|
+
.xes-pill { border: 1px solid var(--xes-line); background-color: rgba(255,255,255,.045); }
|
|
81
|
+
.xes-tiny { font-size: .78rem; }
|
|
82
|
+
.xes-drop-hint { outline: 1px dashed rgba(13, 202, 240, .35); outline-offset: .35rem; }
|
|
83
|
+
.xes-dragging { opacity: .5; }
|
|
84
|
+
.xes-sidebar { background: rgba(0,0,0,.18); }
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
Syntax highlighting for the source listings. Tokens come from the
|
|
88
|
+
tiny tokenizer in playground/components/highlighter.js.
|
|
89
|
+
*/
|
|
90
|
+
.xes-code .hl-cm { color: #6c757d; font-style: italic; }
|
|
91
|
+
.xes-code .hl-cd { color: #c792ea; }
|
|
92
|
+
.xes-code .hl-pn { color: #6c757d; }
|
|
93
|
+
.xes-code .hl-tn { color: #6cb4ee; font-weight: 600; }
|
|
94
|
+
.xes-code .hl-an { color: #f0c674; }
|
|
95
|
+
.xes-code .hl-av { color: #98c379; }
|
|
96
|
+
.xes-code .hl-itp { color: #ffb454; font-weight: 600; }
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
Code-only view. The sidebar toggle flips a `xes-code-only` class on
|
|
100
|
+
the playground container. Every chapter follows the same docs/source
|
|
101
|
+
layout - a `.row.g-4` whose first `.col-lg-6` is the "How it works"
|
|
102
|
+
narration and second is the source listing - so a structural rule
|
|
103
|
+
hides docs and widens the source listing without touching each chapter.
|
|
104
|
+
*/
|
|
105
|
+
.xes-code-only .row.g-4 > .col-lg-6:first-child { display: none; }
|
|
106
|
+
.xes-code-only .row.g-4 > .col-lg-6:last-child { flex: 0 0 100%; max-width: 100%; }
|
|
107
|
+
|
|
108
|
+
/* Loading state until galath finishes booting. */
|
|
109
|
+
#mount:empty::before {
|
|
110
|
+
content: "Loading Galath playground...";
|
|
111
|
+
display: block;
|
|
112
|
+
padding: 2rem;
|
|
113
|
+
color: rgba(255,255,255,.6);
|
|
114
|
+
}
|
|
115
|
+
</style>
|
|
116
|
+
</head>
|
|
117
|
+
<body>
|
|
118
|
+
<div id="mount"></div>
|
|
119
|
+
|
|
120
|
+
<!--
|
|
121
|
+
The Galath source document. Almost everything is in imports. Adding
|
|
122
|
+
a chapter is one line here + one line in playground/app.xml + the
|
|
123
|
+
actual chapter file.
|
|
124
|
+
-->
|
|
125
|
+
<script type="application/xml" id="galath-source">
|
|
126
|
+
<galath version="1.0">
|
|
127
|
+
<!-- shared building blocks first so chapters can reference them -->
|
|
128
|
+
<import src="./playground/components/chapter-shell.xml" />
|
|
129
|
+
|
|
130
|
+
<!-- one chapter file each, in tutorial order -->
|
|
131
|
+
<import src="./playground/chapters/01-welcome.xml" />
|
|
132
|
+
<import src="./playground/chapters/02-signals.xml" />
|
|
133
|
+
<import src="./playground/chapters/03-instance.xml" />
|
|
134
|
+
<import src="./playground/chapters/04-bindings.xml" />
|
|
135
|
+
<import src="./playground/chapters/12-expressions.xml" />
|
|
136
|
+
<import src="./playground/chapters/13-paths.xml" />
|
|
137
|
+
<import src="./playground/chapters/05-lists.xml" />
|
|
138
|
+
<import src="./playground/chapters/06-commands.xml" />
|
|
139
|
+
<import src="./playground/chapters/07-controller.xml" />
|
|
140
|
+
<import src="./playground/chapters/08-events.xml" />
|
|
141
|
+
<import src="./playground/chapters/09-behaviors.xml" />
|
|
142
|
+
<import src="./playground/chapters/10-components.xml" />
|
|
143
|
+
<import src="./playground/chapters/11-imports.xml" />
|
|
144
|
+
|
|
145
|
+
<!-- the shell that ties chapters together -->
|
|
146
|
+
<import src="./playground/app.xml" />
|
|
147
|
+
|
|
148
|
+
<!-- entry point: just instantiate the shell -->
|
|
149
|
+
<application name="playground">
|
|
150
|
+
<x-playground />
|
|
151
|
+
</application>
|
|
152
|
+
</galath>
|
|
153
|
+
</script>
|
|
154
|
+
|
|
155
|
+
<!--
|
|
156
|
+
Boot. Two lines: read the source from the script tag, hand it to
|
|
157
|
+
galath, watch the page light up. `boot` returns the language object
|
|
158
|
+
so we expose it on `window.galath` for console exploration.
|
|
159
|
+
-->
|
|
160
|
+
<script type="module">
|
|
161
|
+
import { boot } from 'galath/boot';
|
|
162
|
+
import { attachHighlighter } from './playground/components/highlighter.js';
|
|
163
|
+
import { attachRunSnippet } from './playground/components/run-snippet.js';
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
attachRunSnippet();
|
|
167
|
+
window.galath = await boot({
|
|
168
|
+
source: document.getElementById('galath-source').textContent,
|
|
169
|
+
mount: document.getElementById('mount'),
|
|
170
|
+
});
|
|
171
|
+
attachHighlighter(document.getElementById('mount'));
|
|
172
|
+
} catch (error) {
|
|
173
|
+
// If the boot itself crashed, the error never reaches the user
|
|
174
|
+
// through the normal rendering path. Surface it loudly.
|
|
175
|
+
const mount = document.getElementById('mount');
|
|
176
|
+
mount.innerHTML = `
|
|
177
|
+
<div class="container-xxl py-5">
|
|
178
|
+
<div class="alert alert-danger">
|
|
179
|
+
<h2 class="h5"><i class="bi bi-exclamation-triangle me-2"></i>Galath failed to boot</h2>
|
|
180
|
+
<pre class="mb-0">${String(error?.stack || error)}</pre>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
`;
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
</script>
|
|
187
|
+
</body>
|
|
188
|
+
</html>
|
package/logo.jpg
ADDED
|
Binary file
|