caspian-utils 0.0.5 → 0.0.7
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/docs/components.md +60 -1
- package/dist/docs/index.md +1 -1
- package/dist/docs/project-structure.md +7 -0
- package/dist/docs/routing.md +14 -0
- package/package.json +1 -1
package/dist/docs/components.md
CHANGED
|
@@ -53,7 +53,7 @@ Notes:
|
|
|
53
53
|
|
|
54
54
|
## Import And Use Components
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Place component imports at the top of the HTML template, above the authored root element.
|
|
57
57
|
|
|
58
58
|
```html
|
|
59
59
|
<!-- @import Container from "../components" -->
|
|
@@ -65,9 +65,66 @@ Import components inside the HTML template where they are used.
|
|
|
65
65
|
|
|
66
66
|
The import comment is the bridge between the Python component file and the JSX-style tag.
|
|
67
67
|
|
|
68
|
+
Treat `<!-- @import ... -->` as a file-level directive, not as rendered markup. It does not count as the template root, and it should not be nested inside the root wrapper element.
|
|
69
|
+
|
|
68
70
|
- `<!-- @import Container from "../components" -->` resolves `Container.py` from that folder.
|
|
69
71
|
- The component function name should match the tag name you render, such as `Container` for `<Container />`.
|
|
70
72
|
- Grouped imports and aliases are also supported, for example `<!-- @import { Button, Card as UserCard } from "../components/ui" -->`.
|
|
73
|
+
- If one Python file exports several `@component` functions, point `from` at that exact file instead of assuming one file per tag.
|
|
74
|
+
- In that case, prefer one grouped import so every rendered tag resolves back to the same Python module.
|
|
75
|
+
|
|
76
|
+
Good:
|
|
77
|
+
|
|
78
|
+
```html
|
|
79
|
+
<!-- @import { Button, Input, Label } from "../../../lib/maddex" -->
|
|
80
|
+
|
|
81
|
+
<section class="auth-panel auth-panel-compact fade-up">
|
|
82
|
+
<Label>Email</Label>
|
|
83
|
+
<Input type="email" />
|
|
84
|
+
<Button>Continue</Button>
|
|
85
|
+
</section>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Bad:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<section class="auth-panel auth-panel-compact fade-up">
|
|
92
|
+
<!-- @import { Button, Input, Label } from "../../../lib/maddex" -->
|
|
93
|
+
<Label>Email</Label>
|
|
94
|
+
</section>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Same-File Component Exports
|
|
98
|
+
|
|
99
|
+
Caspian does not require one Python file per component. A single file can export a main component plus related subcomponents.
|
|
100
|
+
|
|
101
|
+
If `Breadcrumb.py` defines `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, and `BreadcrumbSeparator`, import those names from `Breadcrumb.py` itself.
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<!-- @import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "../maddex/Breadcrumb.py" -->
|
|
105
|
+
|
|
106
|
+
<div class="dashboard-topbar">
|
|
107
|
+
<Breadcrumb class="dashboard-breadcrumbs" aria-label="Dashboard breadcrumbs">
|
|
108
|
+
<BreadcrumbList class="dashboard-breadcrumbs__list">
|
|
109
|
+
<BreadcrumbItem class="dashboard-breadcrumbs__item">
|
|
110
|
+
<BreadcrumbLink href="/dashboard">Dashboard</BreadcrumbLink>
|
|
111
|
+
</BreadcrumbItem>
|
|
112
|
+
<BreadcrumbSeparator class="dashboard-breadcrumbs__separator" />
|
|
113
|
+
<BreadcrumbItem class="dashboard-breadcrumbs__item">
|
|
114
|
+
<BreadcrumbPage class="dashboard-breadcrumbs__page">Reports</BreadcrumbPage>
|
|
115
|
+
</BreadcrumbItem>
|
|
116
|
+
</BreadcrumbList>
|
|
117
|
+
</Breadcrumb>
|
|
118
|
+
</div>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If you only need one component from that file, keep the same file path:
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<!-- @import Breadcrumb from "../maddex/Breadcrumb.py" -->
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Do not invent folder-level imports for symbols that do not have their own file. If `BreadcrumbItem` lives inside `Breadcrumb.py`, import it from `Breadcrumb.py`, not from `../maddex` as if `BreadcrumbItem.py` existed.
|
|
71
128
|
|
|
72
129
|
## Template-Backed Components
|
|
73
130
|
|
|
@@ -161,6 +218,8 @@ Every component HTML template must render exactly one top-level lowercase HTML e
|
|
|
161
218
|
|
|
162
219
|
The same rule applies to route templates such as `src/app/**/index.html`: one root element, no sibling roots, and no manual `pp-component` authoring.
|
|
163
220
|
|
|
221
|
+
Top-of-file `<!-- @import ... -->` directives are allowed before that root element and do not violate the single-root rule.
|
|
222
|
+
|
|
164
223
|
This is not just style guidance. The installed compiler injects `pp-component` onto the root element, and it raises an error when the template has no root, multiple sibling roots, stray top-level text, or a component tag as the root.
|
|
165
224
|
|
|
166
225
|
For AI-generated templates, treat this as a hard authoring rule: write the HTML the same way a React component returns one parent element. If the template needs a PulsePoint script, keep that script inside the same parent root.
|
package/dist/docs/index.md
CHANGED
|
@@ -58,7 +58,7 @@ Preferred lookup order:
|
|
|
58
58
|
1. Read `node_modules/caspian-utils/dist/docs/index.md` to discover available local docs.
|
|
59
59
|
2. Read `./caspian.config.json` before making any feature assumption. Use it to confirm which project capabilities are enabled and which directories or tooling rules apply.
|
|
60
60
|
3. Read `database.md` for Prisma setup and ORM usage, `auth.md` for session auth and route protection, `components.md` for reusable UI authoring, `pulsepoint.md` for browser-side reactive runtime behavior, `fetch-data.md` for data flows, `state.md` for transient request-scoped state, `cache.md` for page caching, and `validation.md` for input boundaries.
|
|
61
|
-
4. For authored component, route, and layout HTML files, generate exactly one top-level lowercase HTML element. Think React-style single parent wrapper: keep any owned PulsePoint logic in a plain `<script>` inside that root,
|
|
61
|
+
4. For authored component, route, and layout HTML files, generate exactly one top-level lowercase HTML element. Think React-style single parent wrapper: keep any owned PulsePoint logic in a plain `<script>` inside that root, do not handwrite `pp-component="..."` or `type="text/pp"` because Caspian injects those runtime attributes automatically, and treat `<!-- @import ... -->` comments as file-level directives that belong above the authored root element instead of inside `<div>`, `<section>`, or `<html>`. When several component tags come from one Python file, import them from that exact file path, for example `<!-- @import { Breadcrumb, BreadcrumbItem, BreadcrumbList } from "../components/Breadcrumb.py" -->`.
|
|
62
62
|
5. Prefer local docs before generating code, commands, or migration guidance.
|
|
63
63
|
6. Check `node_modules/caspian-utils/dist/docs/` for packaged Caspian docs when local docs need more detail.
|
|
64
64
|
7. Only fall back to upstream documentation when local and packaged markdown do not cover the topic.
|
|
@@ -98,6 +98,8 @@ Use this folder for reusable UI components that should be imported into route te
|
|
|
98
98
|
|
|
99
99
|
The common Caspian pattern is a Python file such as `Button.py` with `@component`, optionally paired with a same-name HTML file such as `Button.html` when the component has richer markup or PulsePoint behavior.
|
|
100
100
|
|
|
101
|
+
One Python file can also export multiple related `@component` functions. When that happens, import those tags from that exact file path in HTML, for example `<!-- @import { Breadcrumb, BreadcrumbItem, BreadcrumbList } from "../components/Breadcrumb.py" -->`, instead of assuming each tag has its own sibling `.py` file.
|
|
102
|
+
|
|
101
103
|
For component HTML files, follow the same one-parent rule as route HTML files: one top-level lowercase HTML element only, with no sibling roots and no top-level script sitting outside that root.
|
|
102
104
|
|
|
103
105
|
Do not handwrite `pp-component="..."` or `type="text/pp"` in component source templates either. Write plain `<script>` inside the single root and let the render pipeline inject the runtime shape.
|
|
@@ -161,6 +163,8 @@ The project auth configuration file. Use this path when changing authentication
|
|
|
161
163
|
|
|
162
164
|
The root layout shared across pages.
|
|
163
165
|
|
|
166
|
+
If this layout imports reusable components, place each `<!-- @import ... -->` comment above the authored root `<html>` element instead of nesting the comment inside `<html>` or `<body>`.
|
|
167
|
+
|
|
164
168
|
### `src/app/index.py`
|
|
165
169
|
|
|
166
170
|
The backend logic for the route. This is where route behavior can load first-render data, expose `@rpc()` actions, and import framework features such as auth helpers, `casp.validate`, and route-level `Cache(...)` declarations.
|
|
@@ -169,6 +173,8 @@ The backend logic for the route. This is where route behavior can load first-ren
|
|
|
169
173
|
|
|
170
174
|
The route template. It supports standard HTML, `<!-- @import ... -->` component imports, and PulsePoint directives, and it should be the default place for reactive frontend behavior in Caspian.
|
|
171
175
|
|
|
176
|
+
Treat import comments as top-of-file directives that belong above the route's single authored root element.
|
|
177
|
+
|
|
172
178
|
Use `components.md` when the task involves authoring reusable `<MyComponent />` tags backed by Python files.
|
|
173
179
|
|
|
174
180
|
### `src/app/globals.css`
|
|
@@ -198,6 +204,7 @@ If an AI agent is deciding where to make changes, use these rules first.
|
|
|
198
204
|
- Put route templates and route-specific backend logic in `src/app/`.
|
|
199
205
|
- Check [routing.md](./routing.md) when you need URL segment rules, layout nesting behavior, or dynamic route conventions.
|
|
200
206
|
- Put reusable component files in `src/components/` and check [components.md](./components.md) for `@component`, `render_html(__file__)`, import comments, and single-root template rules.
|
|
207
|
+
- Keep `<!-- @import ... -->` comments above the single authored root element in route, layout, and component HTML files.
|
|
201
208
|
- For route and component HTML files, always emit one top-level lowercase HTML element. Good: one wrapper containing the content and a plain `<script>` when needed. Bad: a wrapper element followed by a sibling top-level `<script>`, or handwritten `pp-component="..."` and `type="text/pp"` attributes in source.
|
|
202
209
|
- Put shared helpers and reusable libraries in `src/lib/`.
|
|
203
210
|
- Use PulsePoint conventions in route templates for reactive frontend behavior.
|
package/dist/docs/routing.md
CHANGED
|
@@ -76,6 +76,8 @@ Use `index.html` for the route template. This is the route's view layer.
|
|
|
76
76
|
|
|
77
77
|
Route templates can import reusable Python components with `<!-- @import ... -->` comments and render them with JSX-style tags such as `<Button />`. Use [components.md](./components.md) for the component authoring rules.
|
|
78
78
|
|
|
79
|
+
Place those import comments at the top of the file, above the authored root element. They are file-level directives, not children of the route root.
|
|
80
|
+
|
|
79
81
|
Do not manually add `pp-component="..."` to the route root. The Python render pipeline injects that attribute onto the route's single top-level lowercase HTML element.
|
|
80
82
|
|
|
81
83
|
Do not manually add `type="text/pp"` to a route-owned script either. In source templates, write a plain `<script>` inside the root and let `main.py` call `transform_scripts(...)` before the browser runtime sees the HTML.
|
|
@@ -108,6 +110,15 @@ Bad:
|
|
|
108
110
|
</script>
|
|
109
111
|
```
|
|
110
112
|
|
|
113
|
+
Also bad:
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<section class="dashboard-shell">
|
|
117
|
+
<!-- @import StatsCard from "../components" -->
|
|
118
|
+
<StatsCard title="Users" value="42" />
|
|
119
|
+
</section>
|
|
120
|
+
```
|
|
121
|
+
|
|
111
122
|
Example authored route template:
|
|
112
123
|
|
|
113
124
|
```html
|
|
@@ -219,6 +230,8 @@ Route groups are useful when you want to:
|
|
|
219
230
|
|
|
220
231
|
Layouts work like the Next.js App Router layout system. A `layout.html` file wraps the routes beneath its folder, and nested layouts compose automatically.
|
|
221
232
|
|
|
233
|
+
When a layout imports components, keep each `<!-- @import ... -->` comment above the layout's authored wrapper element, such as the root `<section>` in a nested layout or the root `<html>` in the app layout.
|
|
234
|
+
|
|
222
235
|
Resolved SEO fields are exposed to layouts as `[[ metadata.* ]]`, while values returned from `layout.py` are exposed separately as `[[ layout.* ]]`.
|
|
223
236
|
|
|
224
237
|
For example, a page inside `/dashboard/settings` is wrapped by the root layout first and then by the dashboard layout.
|
|
@@ -300,6 +313,7 @@ If an AI agent is choosing where to add or update route code, apply these rules
|
|
|
300
313
|
- Use `index.html` for route templates and `index.py` for route-level async logic.
|
|
301
314
|
- Use [cache.md](./cache.md) when an `index.py` route should opt into page-level HTML caching.
|
|
302
315
|
- Use `layout.html` for shared wrappers and `layout.py` for layout-level synchronous props or metadata.
|
|
316
|
+
- Keep `<!-- @import ... -->` directives at the top of `index.html` and `layout.html`, above the single authored root element.
|
|
303
317
|
- Use [metadata.md](./metadata.md) when a route or layout needs SEO fields.
|
|
304
318
|
- Use `[segment]` for single dynamic parameters.
|
|
305
319
|
- Use `[...segment]` for catch-all route matching.
|