gitoriaLog in with ident

components

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Address
https://components.gitoria.worldapi.org/
Owner
Caramboleyo
Created

components.hybriel.worldapi.org

Hybriel components, developed standalone (CONCEPT.md). The home lists them; each component has a demo page, a README and a browser gate. Apps vendor a component by copying its folder. https://components.hybriel.worldapi.org

Components

ComponentDemoREADME
Month view/month-viewcomponents/month-view/README.md (also /month-view/README.md)
Date picker/date-pickercomponents/date-picker/README.md (also /date-picker/README.md)
Date range picker/range-pickercomponents/range-picker/README.md (also /range-picker/README.md)
Pagination/paginationcomponents/pagination/README.md (also /pagination/README.md)
Markdown editor/md-editorcomponents/md-editor/README.md (also /md-editor/README.md)
Code editor/code-editorcomponents/code-editor/README.md (also /code-editor/README.md)
Modal/modalcomponents/modal/README.md (also /modal/README.md)

The Markdown editor takes files and images (drop, paste, File button) through emit server mdUpload (hybriel#94). The one-file upload (components/file-upload/, ticket #4) sends its file through emit server saveFile (hybriel#94). The multi-file upload (#5) is not built yet.

Look (ticket #15, mission 003)

The library is generic: every component renders in a neutral base look — black, white and four greys for nuances, no app's palette, no decorative frames. Light by default (white page, black text): it is the plain look of a document, and a theme can turn it dark without the base fighting it. The values are named once in shared/base.hl:

namevalueused for
black#000text, the selected day / current page / main modal button (white on black), today's ring, the site header
greyDark#555muted text, line numbers, syntax (keywords, strings, comments in italics), focus rings, the dim page behind a modal
grey#999functional lines only: the drop zone's dashed border
greyLight#ddda strip or block on a field: editor toolbar, code, gutter; hover on a day tile; the days of a range
greyLighter#f2f2f2fields and tiles on the white page: inputs, editors, day cells; hover on white
white#fffthe page, popups, the modal window, text on black
  • A component's browser module cannot import base.hl, so each component writes the value as the FALLBACK of the semantic WorldAPI token: var(--color-text, #000). A bare copy (no tokens) shows the base look; an app that declares the tokens — layouts.worldapi.org's theme/theme.hl — restyles it. The token names, elements and classes stay as they are (the theme targets them).
  • No frames: a border or ring only where it means something — focus ring (#555), today (#000), an invalid field (dashed), the drop zone (dashed #999). A floating popup separates by a soft black shadow, the modal by the dimmed page.
  • The site itself (components/styles.hl) uses the base names and declares none of the WorldAPI tokens, so the showcase shows each component exactly as a bare copy looks. Header black, page white; icon white blocks on black (icons/).
  • Gate: the base look: checks in tests/browser.mjs — every colour in the 9 public files is a base value; on the home + 8 demos + open date popup + open modal at 1280 and 390 px: no --color-… on :root, white page / black text, every computed colour (text, background, visible border, outline, caret, accent, text decoration, shadow, ::backdrop) is a grey (r = g = b), and no visible border inside a component except the drop zone. Screenshots .scratch/gate-bw-<page>-<width>.png — LOOK at them.
  • Chrome quirk found on the way: when a <strong>'s colour equals the text around it, Chrome's insertHTML writes it inline (<strong style="color: …">); md-editor.hl inlineRule removes every style attribute from the surface after it inserts.

Layout

  • Code order (antcolony docs/code-order.md, mission 002): project.hl is the MAP (its head comment says which file handles what) + config + routes, no functions; no other .hl in the root; let only for a variable that is reassigned (python3 tests/letcount.py . → "never reassigned 0"; kept: reassigned, loop body, a member's name, declared twice in one function).
  • project.hl routes · components/styles.hl the site's page layout only (colours from shared/base.hl, see "Look") · components/main.hl shell · components/index.hl the home · components/<name>/ one folder per component (component, demo, README) · lib/uploads.hl where the demos keep uploaded files (one day; the demos' on server handlers only call it).
  • Public: components/<name>/<name>.hl (+ clock.hl, READMEs) are what apps copy and what layouts.worldapi.org's theme/theme.hl styles (html <element> rules) — never rename them, their elements or classes; layouts keeps verbatim copies in its components/.
  • To add a component: its folder, a demo route + a README route in project.hl, one entry in components/index.hl, a line in the project.hl map, its own Style in its file, checks in tests/browser.mjs.
  • bin/hybriel + plugins/ (core crypto data fs http http1 proc time web) are vendored = hybriel master 06617221 (2026-10-03, antcolony mission 074: plugin allocators 3a781359 + 413f60e4 (#126), http1 773de63e (request owns its parse — uploads no longer retained), mpackdb 2cb7ae5e, f0ac2d2d (plugin ABI field — bin and .so must match); no lambda semantics change; sha256 21059cc7…d77bdb, built the same way from git archive 06617221; previous copy (190aa11d) in .scratch/pre-074/. Gate COMPONENTS_GATE_PORT=8760 COMPONENTS_GATE_CHROME=8761-8769 node tests/browser.mjs → 220/0. Memory: LOADS=N UPLOADS=N [IDLE=s] node .scratch/w074/memtest.mjs <vendor dir with bin/+plugins/> <label> (port 8760, Chrome 8761–8769; needs the live storage copy in .scratch/w074/live/storage, deleted after the run): 2000 loads 184 → 205 MB flat, 400 × 1 MiB uploads level at ~363–403 MB (old 190aa11d: +1 MB per upload, 829 MB). Before: master 190aa11d (2026-10-02, antcolony mission 072: fc838894 GC correctness (string index / plugin error read freed memory), 038d84b3 #126 returned closure scopes, #127 d98926c6/04df4428; no lambda semantics change since 8efba065), sha256 860f5e61…0a23626, built read-only from git archive 190aa11d; previous copy (8efba065) in .scratch/pre-072/. Gate COMPONENTS_GATE_PORT=8720 COMPONENTS_GATE_CHROME=8721-8729 node tests/browser.mjs 220/0. Memory: node .scratch/w072/memtest.mjs <vendor dir> <label> (port 8720, Chrome 8721-8728; LOADS/UPLOADS/IDLE; needs the live storage copy in .scratch/w072/live/storage, deleted after each run — re-tar it): 200 loads new 182 → 205 MB (old 288 → 353); uploads still retain RAM: 400 × 1 MiB new 185 → 751 MB (old 8efba065 277 → 713 MB, HWM 823), nothing freed after 60 s idle. Before: master 8efba065 (2026-10-02, antcolony mission 069: #126 the collector also runs by bytes — memory is freed now; #48 a lambda PARAMETER COPIES its argument like a method does, write (&p) => when the caller must see the change; #112 #117 #119 #120 opt-in, not used; earlier: #113, #115/#116, #118, SVG namespace, #111, #103–#106, #94, #83 hashed URLs, #82). Built from a read-only git archive master with zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux-gnu.2.39 in native/; binary sha256 231fb9f2…395546fc6. No local patch: a re-vendor = copy binary + plugins (the ones listed; the build also refreshes their .so), run the gate. Previous copy: .scratch/pre-069/ (master ff51cf46).
  • #48 lambda rule: the app has 5 lambdas (python3 .scratch/w069/lambdas.py / lambdas2.py list them and flag writes to parameters); none writes to a parameter, so none needs &. Components are methods / faces, which already copied. Probe: bin/hybriel .scratch/w069/probe48.hl → copy: n=1 len=0 = #48 active.
  • Memory check (RSS of one server, live storage copy, 200 loads of the 9 pages + 100 file-upload drops of 1 MiB): node .scratch/w069/memtest.mjs <dir with bin/ + plugins/> <label> (port 8730, Chrome 8722–8729; env LOADS, UPLOADS, IDLE; it copies the app without .env into .scratch/w069/mem-<label>/ — copy the live storage/ to .scratch/w069/live/storage first, delete both afterwards).

PWA (antcolony mission 046)

Installable, the same way as calendar/tracker: hl:web's own manifest (/__hl/manifest.webmanifest) + service worker (/__hl/sw.js) from settings in project.hl, no JavaScript of ours.

  • appTitle "Hybriel components", appShortName "Components", appIcons (192 + 512 PNG, each any + maskable), appTouchIcon (180), appFavicon /icons/favicon.svg, appThemeColor = base black (the header, #000), appBackgroundColor = base white (#15; before: tokens darker / dark). /favicon.ico is a real icon (16/32/48). Each icon has a file route.
  • Icons (icons/): icon.svg = source (512, hand-written: three stacked building blocks with studs, white #fff on black #000 (#15; before green-light on dark), all inside the maskable safe circle r = 204 → one image for any + maskable); favicon.svg = the same drawing cropped on a rounded tile. Rendered on Loreana:
  rsvg-convert -w 192 -h 192 icons/icon.svg -o icons/icon-192.png
  rsvg-convert -w 512 -h 512 icons/icon.svg -o icons/icon-512.png
  rsvg-convert -w 180 -h 180 icons/icon.svg -o icons/apple-touch-icon.png
  for s in 16 32 48; do rsvg-convert -w $s -h $s icons/favicon.svg -o /tmp/fav-$s.png; done
  magick /tmp/fav-16.png /tmp/fav-32.png /tmp/fav-48.png icons/favicon.ico
  • Offline: offline = [ Index ] — the worker keeps the shell and / (the home list). Without a network / opens from the cache and says "You are offline. The demos need the network." (components/main.hl: an invisible netProbe runs a 1 s CSS animation, each animationiteration reads navigator.onLine — hl:web has no connection state / mount hook). Every demo page offline gets hl:web's "Unavailable offline" page.
  • Gate: the pwa: / offline: checks at the end of tests/browser.mjs (manifest + icons over HTTP, Chrome's installability + manifest parse, worker scope /, then CDP offline + the server stopped → reload of / shows the shell; screenshots .scratch/gate-pwa-phone-{online,offline}.png, 390 px).

Run, test, deploy

  • COMPONENTS_PORT=8700 ./bin/hybriel project.hl (env: COMPONENTS_WATCH=0 no watcher, HL_HOST).
  • node tests/browser.mjs — the gate (230 checks since #15): own server + headless Chrome (ports 8700, 8701–8709). Other ports (workers): COMPONENTS_GATE_PORT=8720 COMPONENTS_GATE_CHROME=8721-8729 node tests/browser.mjs.
  • Same output (for cleanups, mission 002): run on CODE-ONLY copies (it wipes <copy>/storage), ports 8750 (server) + 8751–8759:
  rsync -a --exclude .scratch --exclude storage --exclude .sessions --exclude .git --exclude '.env*' ./ /tmp/c-new/   # same for the old tree (git worktree / git archive)
  node tests/same-output.mjs /tmp/c-old .scratch/out-old; node tests/same-output.mjs /tmp/c-new .scratch/out-new
  python3 tests/same-output-compare.py .scratch/out-old .scratch/out-new -v     # every page, README, icon, css, manifest, worker, browser module;
                                                                               # hydrated DOM of the 9 pages; file-upload drop + choose; md-editor drop; stored files' sha256
  python3 tests/same-output-modules.py .scratch/out-old .scratch/out-new       # browser modules: same component code + imported functions

Masks: ?v= hashes, source positions, times, upload names. Two runs of one tree compare clean. A moved static changes only a module's import tables; dropping let turns var into const in the modules (nothing else).

  • Layouts theme gate after a component change: commit here, then in layouts.worldapi.org tools/sync-components.sh <commit> (byte-verbatim copies out of git) — or for a dry run copy layouts code-only and copy components/<name>/* over its components/<name>/ —, then LAYOUTS_GATE_PORT=8750 LAYOUTS_GATE_CHROME=8751-8759 node tests/browser.mjs (73/0) and node theme/check-theme.mjs . (0 problems) in that copy — never in parallel with this gate (same ports).
  • ./deploy.sh on Loreana (architect): gate → backup → rsync → docker compose up -d --build on Byrodin (port 45006) → URL 200.

History and worker briefs

  • LOG.md — append-only history, one dated line per step (moved here from the antcolony LOG on 2026-10-01).
  • missions/NNN-*.md — worker briefs for this app; reports/NNN-*.md — their reports (same name). Numbered per project since 2026-10-01 (antcolony#40); older text, code comments and commits use the old antcolony numbers → map: /media/STORAGE/projects/antcolony-docs/docs/mission-map.md (Byrodin: /CONTAINERS/projects/antcolony/docs/mission-map.md).