Update git remote domain from privategit.hanson.xyz to git.internal.hanson.xyz, remove port 3322

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-02-20 07:31:38 +00:00
parent 0efdcd4cde
commit d01a6179aa
6 changed files with 115 additions and 38 deletions

View File

@@ -3,5 +3,5 @@
To start a new RSpade project:
```bash
git clone --recurse-submodules ssh://git@privategit.hanson.xyz:3322/brianhansonxyz/rspade_project.git your-project-name
git clone --recurse-submodules ssh://git@git.internal.hanson.xyz/brianhansonxyz/rspade_project.git your-project-name
```

View File

@@ -14,8 +14,7 @@ SYNOPSIS
class User_Card extends Jqhtml_Component {
async on_load() {
// Load async data - ONLY modify this.data
this.data = await fetch('/api/user/' + this.args.id)
.then(r => r.json());
this.data = await User_Controller.get({id: this.args.id});
}
on_ready() {
@@ -43,6 +42,81 @@ DESCRIPTION
- Double-render pattern for loading states
- No build configuration required (auto-discovered)
COMPONENT COMPLEXITY TIERS
Three tiers guide which patterns to use for a new component:
Static Components (template-only, no JS file):
Pure display from this.args. No lifecycle hooks needed.
Use for: badges, labels, static cards, layout wrappers.
<Define:Status_Badge>
<span class="badge <%= this.args.css_class %>">
<%= this.args.label %>
</span>
</Define:Status_Badge>
Simple Components (on_load + reload):
Fetch data in on_load(), re-fetch with reload() when this.args change.
Most common pattern. Framework handles caching and re-render.
class User_List extends Jqhtml_Component {
on_create() {
this.data.users = [];
}
async on_load() {
this.data = await User_Controller.list({
filter: this.args.filter
});
}
on_ready() {
this.$sid('filter_btn').on('click', () => {
this.args.filter = 'active';
this.reload(); // Re-fetches via on_load()
});
}
}
Complex Components (on_load + jQuery DOM manipulation):
Use on_load() for initial/cached data, then jQuery for incremental
mutations after initialization. Avoids unnecessary network round-trips
and preserves user state (selections, scroll position, input).
class Chat_Widget extends Jqhtml_Component {
async on_load() {
this.data = await Chat_Controller.get_messages({
channel: this.args.channel
});
}
on_ready() {
// Incremental updates via DOM, not reload()
this.socket = new WebSocket(this.args.ws_url);
this.socket.onmessage = (e) => {
const msg = JSON.parse(e.data);
this.$sid('messages').append(
'<div class="message">' + Rsx.escape(msg.text) + '</div>'
);
};
}
on_stop() {
this.socket.disconnect();
}
}
this.state Convention:
this.state is not a framework property - it has no special behavior.
Use it as convention for mutable UI state that changes after
initialization, distinct from this.data (immutable after on_load).
on_create() {
this.state = { selected_ids: [], is_expanded: false };
}
on_ready() {
this.$sid('toggle').on('click', () => {
this.state.is_expanded = !this.state.is_expanded;
this.$sid('panel').toggle(this.state.is_expanded);
});
}
SEMANTIC-FIRST DESIGN
JQHTML is designed for mechanical thinkers who think structurally
rather than visually. Components represent logical concepts, not
@@ -553,8 +627,7 @@ DOUBLE-RENDER PATTERN
}
async on_load() {
this.data.products = await fetch('/api/products')
.then(r => r.json());
this.data.products = await Product_Controller.list();
// Automatic re-render happens after this completes
}
@@ -581,7 +654,7 @@ LOADING STATE PATTERN (CRITICAL)
this.data.state = {loading: true};
this.render(); // WRONG: Manual render call
const response = await $.ajax({...}); // WRONG: $.ajax()
const response = await $.ajax({url: '...', ...}); // WRONG: $.ajax()
if (response.success) {
this.data = {
@@ -684,8 +757,7 @@ JAVASCRIPT COMPONENT CLASS
async on_load() {
// Fetch data - NO DOM manipulation allowed!
// ONLY update this.data
this.data.products = await fetch('/api/products')
.then(r => r.json());
this.data.products = await Product_Controller.list();
// Template re-renders automatically with new data
}
@@ -1360,9 +1432,9 @@ EXAMPLES
class Product_Card extends Jqhtml_Component {
async on_load() {
// Load product data
const id = this.args.product_id;
this.data = await fetch(`/api/products/${id}`)
.then(r => r.json());
this.data = await Product_Controller.get({
id: this.args.product_id
});
// Template re-renders automatically with data
}
@@ -1399,8 +1471,7 @@ EXAMPLES
class Todo_List extends Jqhtml_Component {
async on_load() {
this.data.todos = await fetch('/api/todos')
.then(r => r.json());
this.data = await Todo_Controller.list();
}
on_ready() {
@@ -1438,15 +1509,9 @@ EXAMPLES
}
async submit() {
const data = {
await Contact_Controller.send({
email: this.$sid('email').val(),
message: this.$sid('message').val(),
};
await fetch('/contact', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
});
this.$.html('<p>Thank you!</p>');

View File

@@ -86,7 +86,7 @@ if ! git remote get-url rspade_upstream >/dev/null 2>&1; then
# Auto-configure remote for project mode (when system/ is a submodule)
if [ "$IS_PROJECT_MODE" = false ] && [ -f "../.gitmodules" ] && grep -q "path = system" ../.gitmodules 2>/dev/null; then
echo "→ Configuring rspade_upstream remote (first-time setup)..."
UPSTREAM_URL="ssh://git@privategit.hanson.xyz:3322/brianhansonxyz/rspade_system.git"
UPSTREAM_URL="ssh://git@git.internal.hanson.xyz/brianhansonxyz/rspade_system.git"
if git remote add rspade_upstream "$UPSTREAM_URL" 2>&1; then
echo " ✓ Remote configured: $UPSTREAM_URL"
echo ""

View File

@@ -595,12 +595,19 @@ class Toggle_Button extends Component {
### Lifecycle
1. **on_create()** → Setup defaults (sync) - `this.data.rows = []; this.data.loading = true;`
2. **render** → Template executes
3. **on_render()**Hide uninitialized UI (sync)
4. **on_load()** → Fetch data into `this.data` (async)
5. **on_ready()**DOM manipulation safe (async)
2. **render** → Template executes (top-down: parent before children)
3. **on_render()**Fires after render, BEFORE children ready (top-down, sync)
4. **on_load()** → Fetch data into `this.data` (bottom-up, parallel siblings, async)
5. **on_ready()**All children guaranteed ready (bottom-up, async)
6. **on_stop()** → Teardown when destroyed (sync)
If `on_load()` modifies `this.data`, component renders twice (defaults → populated).
If `on_load()` modifies `this.data`, component renders twice (defaults → populated). on_ready() fires once after final render.
### Component Complexity Tiers
- **Static**: Template-only, no JS file. Pure display from this.args.
- **Simple**: on_load() fetches this.data, `reload()` to re-fetch when this.args change.
- **Complex**: on_load() for initial/cached data, then jQuery DOM manipulation for incremental mutations post-initialization.
### Component API
@@ -612,11 +619,12 @@ If `on_load()` modifies `this.data`, component renders twice (defaults → popul
| `this.$sid('name')` | jQuery | Child with `$sid="name"` |
| `this.sid('name')` | Component/null | Child component instance |
**reload() vs render():**
```
reload() = on_load() → render() → on_ready() ← ALWAYS USE THIS
render() = template only (no on_ready) ← NEVER USE
```
**Lifecycle Methods:**
- `reload()` - Reset this.data to on_create() defaults → on_load() → render() → on_ready(). Use when this.args changed.
- `render()` / `redraw()` - Re-execute template → wait for children → on_ready(). Does NOT re-run on_load(). UI-only updates.
- `stop()` - Destroy component and all children. Calls on_stop() if defined.
**render() destroys child DOM**: All child elements and child components are recreated. DOM event handlers on children are lost and must be re-registered.
After mutations, call `this.reload()` - the server round-trip is intentional:
```javascript
@@ -626,11 +634,15 @@ async add_item() {
}
```
**Event handlers** go in `on_ready()` - they auto-reattach after reload. **WRONG:** Event delegation like `this.$.on('click', '[data-sid="btn"]', handler)` to "survive" render calls - use `reload()` instead.
**this.data rules (enforced):** Writable only in `on_create()` (defaults) and `on_load()` (fetched data). Read-only elsewhere.
**on_render():** Ignore - use `on_ready()` for post-render work.
### Event Handler Placement
| What | Where | Why |
|------|-------|-----|
| `this.on('event', ...)` | `on_create()` | Persists across renders; on_ready() risks infinite loops from event replay |
| `this.sid('child').on('event')` | `on_ready()` | Child component events |
| `this.$sid('elem').on('click')` | `on_render()` or `on_ready()` | Child DOM recreated on render, must re-attach |
### Loading Pattern

View File

@@ -7,14 +7,14 @@
Clone the RSpade project with the framework submodule:
```bash
git clone --recurse-submodules ssh://git@privategit.hanson.xyz:3322/brianhansonxyz/rspade_project.git /path/to/project
git clone --recurse-submodules ssh://git@git.internal.hanson.xyz/brianhansonxyz/rspade_project.git /path/to/project
cd /path/to/project
```
**Alternative method** (clone then initialize submodules):
```bash
git clone ssh://git@privategit.hanson.xyz:3322/brianhansonxyz/rspade_project.git /path/to/project
git clone ssh://git@git.internal.hanson.xyz/brianhansonxyz/rspade_project.git /path/to/project
cd /path/to/project
git submodule update --init --recursive
```

View File

@@ -20,7 +20,7 @@ When starting a new project from this template:
bin/framework-upstream setup
```
This configures `ssh://git@192.168.0.3:3322/brianhansonxyz/rspade-publish.git` as the `framework-upstream` remote.
This configures `ssh://git@git.internal.hanson.xyz/brianhansonxyz/rspade-publish.git` as the `framework-upstream` remote.
## Workflow
@@ -171,7 +171,7 @@ The `bin/framework-upstream` script automates these Git commands:
```bash
# Add upstream remote manually
git remote add framework-upstream ssh://git@192.168.0.3:3322/brianhansonxyz/rspade-publish.git
git remote add framework-upstream ssh://git@git.internal.hanson.xyz/brianhansonxyz/rspade-publish.git
# Fetch updates
git fetch framework-upstream