@astrale-os/adapter-cloudflare 0.4.4 → 0.4.6
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/dist/codegen/wrangler.js +1 -1
- package/package.json +4 -3
- package/src/codegen/wrangler.ts +1 -1
- package/template/CLAUDE.md +8 -21
- package/template/README.md +30 -107
- package/template/client/__tests__/app.test.tsx +6 -57
- package/template/client/components.json +25 -0
- package/template/client/index.html +1 -1
- package/template/client/package.json +10 -2
- package/template/client/src/app.tsx +42 -33
- package/template/client/src/components/ui/cn.ts +6 -0
- package/template/client/src/styles.css +71 -502
- package/template/client/vite.config.ts +2 -18
- package/template/client/vitest.config.ts +0 -6
- package/template/core/README.md +5 -21
- package/template/deps.ts +2 -20
- package/template/domain.ts +0 -26
- package/template/env.ts +1 -17
- package/template/icons.ts +4 -25
- package/template/integrations/README.md +5 -20
- package/template/package.json +7 -5
- package/template/pnpm-workspace.yaml +2 -0
- package/template/runtime/index.ts +0 -27
- package/template/schema/index.ts +0 -20
- package/template/simulation/README.md +12 -0
- package/template/tsconfig.json +2 -3
- package/template/vitest.config.ts +7 -0
- package/template/.domain-studio/comments.json +0 -4
- package/template/client/README.md +0 -104
- package/template/client/__tests__/harness.ts +0 -230
- package/template/client/__tests__/shell.test.ts +0 -46
- package/template/client/src/shell/client.ts +0 -67
- package/template/client/src/shell/index.ts +0 -21
- package/template/client/src/shell/invoke.ts +0 -35
- package/template/client/src/shell/transformers.ts +0 -75
- package/template/client/src/shell/use-async.ts +0 -59
- package/template/client/src/shell/use-capability.ts +0 -59
- package/template/client/src/shell/use-node.ts +0 -81
- package/template/client/src/shell/use-shell.ts +0 -91
- package/template/client/src/shell/view-router.tsx +0 -97
- package/template/client/src/ui/format.ts +0 -24
- package/template/client/src/ui/index.ts +0 -10
- package/template/client/src/ui/surface.tsx +0 -56
- package/template/client/src/ui/value.tsx +0 -32
- package/template/functions/index.ts +0 -22
- package/template/views/index.ts +0 -19
package/dist/codegen/wrangler.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { CLIENT_DIST_DIR } from '../client';
|
|
15
15
|
import { deepMergeConfig } from './merge';
|
|
16
|
-
const COMPATIBILITY_DATE = '
|
|
16
|
+
const COMPATIBILITY_DATE = '2026-07-12';
|
|
17
17
|
export function generateWranglerConfig(opts) {
|
|
18
18
|
const config = {
|
|
19
19
|
name: opts.workerName,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/adapter-cloudflare",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "Deploy an Astrale domain as a standalone Cloudflare Worker",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adapter",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
16
|
"src",
|
|
17
|
-
"template"
|
|
17
|
+
"template",
|
|
18
|
+
"!template/pnpm-lock.yaml"
|
|
18
19
|
],
|
|
19
20
|
"type": "module",
|
|
20
21
|
"main": "./src/index.ts",
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
34
35
|
"jose": "^6.1.3",
|
|
35
|
-
"@astrale-os/sdk": "^0.4.
|
|
36
|
+
"@astrale-os/sdk": "^0.4.10"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@astrale-os/ox": ">=0.1.0 <1.0.0",
|
package/src/codegen/wrangler.ts
CHANGED
|
@@ -41,7 +41,7 @@ export interface WranglerCodegenOptions {
|
|
|
41
41
|
wrangler?: Record<string, unknown>
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const COMPATIBILITY_DATE = '
|
|
44
|
+
const COMPATIBILITY_DATE = '2026-07-12'
|
|
45
45
|
|
|
46
46
|
export function generateWranglerConfig(opts: WranglerCodegenOptions): string {
|
|
47
47
|
const config: Record<string, unknown> = {
|
package/template/CLAUDE.md
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Astrale domain
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
this repo — it's the `astrale-domain` agent skill. Load it before changing the
|
|
6
|
-
schema or handlers.
|
|
7
|
-
|
|
8
|
-
## Agent skills
|
|
9
|
-
|
|
10
|
-
If the `astrale-domain` / `astrale-cli` skills aren't already available in your
|
|
11
|
-
harness, install them once (user-level):
|
|
3
|
+
Load the `astrale-domain` skill before changing schema, runtime, views, integrations, security, or
|
|
4
|
+
simulation code. Install it user-level if needed:
|
|
12
5
|
|
|
13
6
|
```bash
|
|
14
|
-
npx skills add astrale-os/cli -g
|
|
7
|
+
npx skills add astrale-os/cli -g
|
|
15
8
|
```
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
and
|
|
20
|
-
|
|
21
|
-
## Orientation
|
|
22
|
-
|
|
23
|
-
See `README.md` for the project layout (`schema/`, `icons.ts`, `core/`,
|
|
24
|
-
`integrations/`, `runtime/`, `views/`, `functions/`, `client/`), the dev/deploy
|
|
25
|
-
loop, and the signing-identity note. `domain.ts` is the one place the domain
|
|
26
|
-
contract is declared.
|
|
10
|
+
This scaffold is intentionally empty. Organize schema, runtime, core, simulation, and client code by
|
|
11
|
+
real bounded contexts. Keep I/O out of `core/`, use one explicit file per method or standalone function,
|
|
12
|
+
wrap nondeterministic handler work in `step`, derive graph keys and paths from the compiled schema, and
|
|
13
|
+
batch graph reads or mutations where possible.
|
package/template/README.md
CHANGED
|
@@ -1,120 +1,43 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Astrale domain
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
service (default) or as a worker on your own Cloudflare account.
|
|
5
|
-
|
|
6
|
-
This is a **blank skeleton** — every folder is wired up and ready, but the domain
|
|
7
|
-
ships with no classes, interfaces, views, or integrations. Fill in the terrain;
|
|
8
|
-
nothing here is a demo you have to delete.
|
|
9
|
-
|
|
10
|
-
## For AI agents
|
|
11
|
-
|
|
12
|
-
The complete domain-authoring guide is the `astrale-domain` skill (schema
|
|
13
|
-
modeling, handlers, kernel calls, external-API patterns — DI, secrets,
|
|
14
|
-
idempotency — views, webhooks, deploys); CLI operations (auth, instances, calls)
|
|
15
|
-
are the `astrale-cli` skill. Install both once, user-level:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npx skills add astrale-os/cli -g # both skills · or run `astrale setup`
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Then load `astrale-domain` before making changes. (Skills are installed into your
|
|
22
|
-
agent harness, not committed to this project — `astrale update` keeps them, the
|
|
23
|
-
CLI, and your `@astrale-os/*` deps current.)
|
|
24
|
-
|
|
25
|
-
> **Requires [Bun](https://bun.sh)** — the `astrale-domain` CLI behind `pnpm dev`
|
|
26
|
-
> / `pnpm prod` imports `astrale.config.ts` and your ★ files directly, so it
|
|
27
|
-
> needs a TypeScript-native runtime.
|
|
3
|
+
A minimal Astrale domain scaffold. It builds, runs, and deploys before you add any domain concepts.
|
|
28
4
|
|
|
29
5
|
```bash
|
|
30
6
|
pnpm install
|
|
31
|
-
pnpm dev
|
|
32
|
-
|
|
33
|
-
pnpm
|
|
7
|
+
pnpm dev
|
|
8
|
+
pnpm typecheck
|
|
9
|
+
pnpm test
|
|
10
|
+
pnpm prod
|
|
34
11
|
```
|
|
35
12
|
|
|
36
|
-
|
|
37
|
-
members) — then you add classes and handlers.
|
|
13
|
+
Load the `astrale-domain` skill before authoring the domain:
|
|
38
14
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
schema/ classes + interfaces + edges (the data model) + compiled accessors
|
|
43
|
-
icons.ts class icons (raw SVG), attached via nodeClass({ icon })
|
|
44
|
-
core/<context>/ pure, transport-agnostic logic per bounded context
|
|
45
|
-
integrations/ external-API ports + adapters + a lazy registry (built into deps)
|
|
46
|
-
runtime/ the execute() handlers — the composition root (the methods map)
|
|
47
|
-
views/ iframe-mountable UIs (inline HTML or a client/ SPA)
|
|
48
|
-
functions/ standalone Functions (e.g. webhooks, a postInstall seed)
|
|
49
|
-
client/ the SPA served under /ui
|
|
50
|
-
deps.ts env → typed Deps container (what handlers read as ctx.deps)
|
|
51
|
-
domain.ts wires it all together — the worker-safe definition
|
|
52
|
-
astrale.config.ts binds the domain to its deploy adapter (node-only)
|
|
15
|
+
```bash
|
|
16
|
+
npx skills add astrale-os/cli -g
|
|
53
17
|
```
|
|
54
18
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Everything else — the Worker entry, the wrangler config, the signing identity —
|
|
69
|
-
is generated under `.astrale/` (gitignored) by the adapter. You never edit it.
|
|
70
|
-
|
|
71
|
-
## The signing identity (back it up!)
|
|
72
|
-
|
|
73
|
-
The first `pnpm dev`/`pnpm prod` generates an Ed25519 keypair at
|
|
74
|
-
`.astrale/identity.ts`. That private key **is** this domain's identity: every
|
|
75
|
-
instance that installs the domain verifies its credentials against it. The file
|
|
76
|
-
is gitignored, so a fresh clone or a CI runner silently mints a **new** key —
|
|
77
|
-
and redeploying with a new key breaks verification on every existing install.
|
|
78
|
-
Back it up, or move it to a managed secret before deploying from more than one
|
|
79
|
-
machine.
|
|
80
|
-
|
|
81
|
-
## Extra bindings (KV, R2, D1, queues, …)
|
|
82
|
-
|
|
83
|
-
The adapter owns the wrangler config, but you can declare extra bindings from
|
|
84
|
-
`astrale.config.ts` via a `wrangler` block on any env — it's deep-merged into
|
|
85
|
-
the generated config:
|
|
86
|
-
|
|
87
|
-
```ts
|
|
88
|
-
adapter: cloudflare({
|
|
89
|
-
dev: {
|
|
90
|
-
secrets: '.env.dev',
|
|
91
|
-
wrangler: {
|
|
92
|
-
kv_namespaces: [{ binding: 'CACHE', id: '<kv-id>' }],
|
|
93
|
-
r2_buckets: [{ binding: 'FILES', bucket_name: 'my-bucket' }],
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
})
|
|
19
|
+
## Shape
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
schema/ vocabulary, split by bounded context
|
|
23
|
+
runtime/ method implementations, split by bounded context and one file per method
|
|
24
|
+
core/ pure deterministic logic, paths, defaults, and domain errors
|
|
25
|
+
integrations/ external-system ports and adapters
|
|
26
|
+
simulation/ samples and business scenarios
|
|
27
|
+
client/ React views built on @astrale-os/shell-react
|
|
28
|
+
icons.ts shared SVG wrapper; named icons stay with their context
|
|
29
|
+
env.ts worker bindings and secrets
|
|
30
|
+
deps.ts env-to-runtime dependency composition
|
|
31
|
+
domain.ts worker-safe domain assembly
|
|
97
32
|
```
|
|
98
33
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
`workerName` and `route`/`zone`); don't reuse the reserved binding names
|
|
103
|
-
`SELF`/`ASSETS`. Durable Objects aren't supported through this field yet.
|
|
104
|
-
|
|
105
|
-
## The loop
|
|
106
|
-
|
|
107
|
-
- **Edit a handler** (`core/` logic or `runtime/` wiring) → hot-reloads at the same URL. Nothing to reinstall.
|
|
108
|
-
- **Edit the schema** (`schema/`) → rebuilds the graph; reinstall with `astrale domain install <url> --direct`.
|
|
109
|
-
- **`postInstall`** — author a standalone `seed` function in `functions/`, reference
|
|
110
|
-
it from `domain.ts` (`postInstall: functions.seed`), and the kernel runs it once
|
|
111
|
-
after install, as the system identity, so the domain can lay down its initial
|
|
112
|
-
graph and set its own grants. Functions are first-class domain members,
|
|
113
|
-
addressable at `/:origin:function.seed`.
|
|
34
|
+
Keep `schema/index.ts` and `runtime/index.ts` as composition roots. Put standalone functions in the
|
|
35
|
+
bounded context that owns them, then wire them from `domain.ts`; do not create a generic functions
|
|
36
|
+
junk drawer. The same rule applies to views and client code.
|
|
114
37
|
|
|
115
|
-
|
|
38
|
+
The client includes Tailwind CSS v4 and an empty shadcn `radix-nova` setup. Add only the components a
|
|
39
|
+
real view needs with `pnpm exec shadcn add <component>`; component source stays in the project and can
|
|
40
|
+
be adapted to the domain's visual language.
|
|
116
41
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
computes its own `binding.remoteUrl` at install from its public URL, so there's
|
|
120
|
-
no hardcoded URL anywhere in your code.
|
|
42
|
+
The adapter generates worker plumbing under `.astrale/`. Do not edit it. The signing identity in
|
|
43
|
+
`.astrale/identity.ts` is gitignored; back it up before deploying from more than one machine.
|
|
@@ -1,66 +1,15 @@
|
|
|
1
|
-
import { cleanup, render,
|
|
2
|
-
import { afterEach,
|
|
1
|
+
import { cleanup, render, screen } from '@testing-library/react'
|
|
2
|
+
import { afterEach, describe, expect, it } from 'vitest'
|
|
3
3
|
|
|
4
4
|
import { App } from '@/app'
|
|
5
|
-
import { useShell } from '@/shell'
|
|
6
|
-
|
|
7
|
-
import { installFakeParent, type FakeParent } from './harness'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* The router picks a view from `window.location.pathname`. This skeleton has no
|
|
11
|
-
* views registered, so every path falls through to the fallback — that's the
|
|
12
|
-
* test below. The second block exercises the shell handshake plumbing (via the
|
|
13
|
-
* fake parent) so you know the seam works the moment you add a real view.
|
|
14
|
-
*
|
|
15
|
-
* `replaceState` rewrites the happy-dom location without a reload.
|
|
16
|
-
*/
|
|
17
|
-
function mountAt(path: string) {
|
|
18
|
-
window.history.replaceState({}, '', path)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
mountAt('/ui/anything')
|
|
23
|
-
})
|
|
24
5
|
|
|
25
6
|
afterEach(cleanup)
|
|
26
7
|
|
|
27
|
-
describe('
|
|
28
|
-
it('renders
|
|
8
|
+
describe('domain client', () => {
|
|
9
|
+
it('renders a standalone preview outside the Astrale shell', () => {
|
|
29
10
|
render(<App />)
|
|
30
|
-
expect(screen.getByText('No view here')).toBeTruthy()
|
|
31
|
-
expect(screen.getByText(/No view registered for/)).toBeTruthy()
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
describe('shell handshake plumbing', () => {
|
|
36
|
-
let parent: FakeParent | undefined
|
|
37
|
-
|
|
38
|
-
afterEach(() => {
|
|
39
|
-
parent?.restore()
|
|
40
|
-
parent = undefined
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('reaches `ready` with a kernel session after the parent handshake', async () => {
|
|
44
|
-
parent = installFakeParent({
|
|
45
|
-
windowId: 'w-1',
|
|
46
|
-
kernelUrl: 'https://k.example.test/api',
|
|
47
|
-
functionId: 'fn-1',
|
|
48
|
-
delegationToken: 'tok-A',
|
|
49
|
-
tokenExpiresAt: Date.now() + 60_000,
|
|
50
|
-
targetNodeId: 'node-1',
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const { result } = renderHook(() => useShell())
|
|
54
|
-
// waitFor polls inside `act`, so the handshake's async state updates land
|
|
55
|
-
// wrapped — the parent's `ack` promise need not be awaited separately.
|
|
56
|
-
await waitFor(() => expect(result.current.status).toBe('ready'))
|
|
57
|
-
expect(result.current.session).not.toBeNull()
|
|
58
|
-
expect(result.current.nodeId).toBe('node-1')
|
|
59
|
-
})
|
|
60
11
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
await waitFor(() => expect(result.current.status).toBe('standalone'))
|
|
64
|
-
expect(result.current.session).toBeNull()
|
|
12
|
+
expect(screen.getByText('Domain client')).toBeTruthy()
|
|
13
|
+
expect(screen.getByRole('heading', { name: 'Ready to build.' })).toBeTruthy()
|
|
65
14
|
})
|
|
66
15
|
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "radix-nova",
|
|
4
|
+
"rsc": false,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "src/styles.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true,
|
|
11
|
+
"prefix": ""
|
|
12
|
+
},
|
|
13
|
+
"iconLibrary": "lucide",
|
|
14
|
+
"rtl": false,
|
|
15
|
+
"aliases": {
|
|
16
|
+
"components": "@/components",
|
|
17
|
+
"utils": "@/components/ui/cn",
|
|
18
|
+
"ui": "@/components/ui",
|
|
19
|
+
"lib": "@/lib",
|
|
20
|
+
"hooks": "@/hooks"
|
|
21
|
+
},
|
|
22
|
+
"menuColor": "default",
|
|
23
|
+
"menuAccent": "subtle",
|
|
24
|
+
"registries": {}
|
|
25
|
+
}
|
|
@@ -11,16 +11,24 @@
|
|
|
11
11
|
"test": "vitest run"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@astrale-os/shell": ">=0.
|
|
14
|
+
"@astrale-os/shell-react": ">=0.2.5 <1.0.0",
|
|
15
|
+
"@fontsource-variable/instrument-sans": "^5.2.8",
|
|
16
|
+
"@fontsource/ibm-plex-mono": "^5.2.7",
|
|
17
|
+
"clsx": "^2.1.1",
|
|
15
18
|
"react": "^19.2.0",
|
|
16
|
-
"react-dom": "^19.2.0"
|
|
19
|
+
"react-dom": "^19.2.0",
|
|
20
|
+
"shadcn": "^4.13.0",
|
|
21
|
+
"tailwind-merge": "^3.6.0",
|
|
22
|
+
"tw-animate-css": "^1.4.0"
|
|
17
23
|
},
|
|
18
24
|
"devDependencies": {
|
|
25
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
19
26
|
"@testing-library/react": "^16.3.0",
|
|
20
27
|
"@types/react": "^19.2.0",
|
|
21
28
|
"@types/react-dom": "^19.2.0",
|
|
22
29
|
"@vitejs/plugin-react": "^5.0.4",
|
|
23
30
|
"happy-dom": "^20.0.0",
|
|
31
|
+
"tailwindcss": "^4.3.2",
|
|
24
32
|
"vite": "^7.1.7",
|
|
25
33
|
"vitest": "^3.2.4"
|
|
26
34
|
}
|
|
@@ -1,43 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
* Path-based view router for the domain's SPA bundle. The shell mounts each Astrale
|
|
3
|
-
* View in its own iframe at its own mount path, so inside the iframe
|
|
4
|
-
* `window.location.pathname` IS that path. `App` reads it (via `resolveView`) and
|
|
5
|
-
* renders the matching view; an unregistered path shows a self-describing fallback.
|
|
6
|
-
*
|
|
7
|
-
* `ROUTES` starts EMPTY — this is a blank skeleton, so every path falls through to
|
|
8
|
-
* `UnknownView`. Add a view by
|
|
9
|
-
* 1. writing a `ViewComponent` (usually wrapping `ViewFrame` — see `@/shell`),
|
|
10
|
-
* 2. adding a `ROUTES` entry keyed by its mount path,
|
|
11
|
-
* 3. registering a matching `defineView({ mount: '/ui/<path>' })` in the domain's
|
|
12
|
-
* `views/`.
|
|
13
|
-
*/
|
|
1
|
+
import { ShellProvider, useTargetNode, type ShellConfig } from '@astrale-os/shell-react'
|
|
14
2
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const ROUTES: ViewRoutes = {}
|
|
3
|
+
const SHELL_CONFIG: ShellConfig = { mode: 'sandboxed', initTimeoutMs: 8_000 }
|
|
18
4
|
|
|
19
5
|
export function App() {
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
if (typeof window === 'undefined' || window.parent === window) return <Preview />
|
|
7
|
+
return (
|
|
8
|
+
<ShellProvider config={SHELL_CONFIG} fallback={<Loading />}>
|
|
9
|
+
<DomainView />
|
|
10
|
+
</ShellProvider>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function DomainView() {
|
|
15
|
+
const target = useTargetNode()
|
|
22
16
|
|
|
23
|
-
|
|
17
|
+
return (
|
|
18
|
+
<main className="mx-auto flex min-h-screen w-full max-w-5xl flex-col justify-center gap-5 px-6 py-20">
|
|
19
|
+
<p className="font-mono text-xs font-semibold tracking-[0.16em] text-primary uppercase">
|
|
20
|
+
Domain view
|
|
21
|
+
</p>
|
|
22
|
+
<h1 className="max-w-3xl text-5xl leading-[0.95] font-semibold tracking-[-0.055em] md:text-7xl">
|
|
23
|
+
{target.pending ? 'Loading target…' : 'Ready to build.'}
|
|
24
|
+
</h1>
|
|
25
|
+
<p className="max-w-xl text-base text-muted-foreground">
|
|
26
|
+
Replace this component with the view for your first bounded context.
|
|
27
|
+
</p>
|
|
28
|
+
</main>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
24
31
|
|
|
25
|
-
|
|
32
|
+
function Preview() {
|
|
33
|
+
return (
|
|
34
|
+
<main className="mx-auto flex min-h-screen w-full max-w-5xl flex-col justify-center gap-5 px-6 py-20">
|
|
35
|
+
<p className="font-mono text-xs font-semibold tracking-[0.16em] text-primary uppercase">
|
|
36
|
+
Domain client
|
|
37
|
+
</p>
|
|
38
|
+
<h1 className="max-w-3xl text-5xl leading-[0.95] font-semibold tracking-[-0.055em] md:text-7xl">
|
|
39
|
+
Ready to build.
|
|
40
|
+
</h1>
|
|
41
|
+
<p className="max-w-xl text-base text-muted-foreground">
|
|
42
|
+
Views run inside the Astrale shell. Start with a bounded context, then add its view.
|
|
43
|
+
</p>
|
|
44
|
+
</main>
|
|
45
|
+
)
|
|
26
46
|
}
|
|
27
47
|
|
|
28
|
-
|
|
29
|
-
function UnknownView() {
|
|
48
|
+
function Loading() {
|
|
30
49
|
return (
|
|
31
|
-
<
|
|
32
|
-
<div className="card">
|
|
33
|
-
<h1 className="title">No view here</h1>
|
|
34
|
-
<p className="subline">Astrale view SPA</p>
|
|
35
|
-
<div className="banner">
|
|
36
|
-
No view registered for {window.location.pathname}. Add a ROUTES entry in{' '}
|
|
37
|
-
<code>src/app.tsx</code> (and a matching <code>defineView({'{ mount }'})</code> in the
|
|
38
|
-
domain's <code>views/</code>).
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
50
|
+
<main className="grid min-h-screen place-items-center text-muted-foreground">Connecting…</main>
|
|
42
51
|
)
|
|
43
52
|
}
|