gitoriaLog in with ident

components

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit3bc905c53bc905c5components #15 (mission 003) 2/2: docs (README Look, STATUS, LOG), reportmre3bc905c5/README.md

12.9 KB

  1. # components.hybriel.worldapi.org
  2. Hybriel components, developed standalone (CONCEPT.md). The home lists them; each component has a demo page, a README
  3. and a browser gate. Apps vendor a component by copying its folder. https://components.hybriel.worldapi.org
  4. ## Components
  5. | Component | Demo | README |
  6. |-----------|------|--------|
  7. | Month view | `/month-view` | `components/month-view/README.md` (also `/month-view/README.md`) |
  8. | Date picker | `/date-picker` | `components/date-picker/README.md` (also `/date-picker/README.md`) |
  9. | Date range picker | `/range-picker` | `components/range-picker/README.md` (also `/range-picker/README.md`) |
  10. | Pagination | `/pagination` | `components/pagination/README.md` (also `/pagination/README.md`) |
  11. | Markdown editor | `/md-editor` | `components/md-editor/README.md` (also `/md-editor/README.md`) |
  12. | Code editor | `/code-editor` | `components/code-editor/README.md` (also `/code-editor/README.md`) |
  13. | Modal | `/modal` | `components/modal/README.md` (also `/modal/README.md`) |
  14. 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.
  15. ## Look (ticket #15, mission 003)
  16. The library is generic: every component renders in a neutral **base look** — black, white and four greys for nuances, no app's
  17. palette, no decorative frames. Light by default (white page, black text): it is the plain look of a document, and a theme can turn
  18. it dark without the base fighting it. The values are named once in `shared/base.hl`:
  19. | name | value | used for |
  20. |------|-------|----------|
  21. | `black` | `#000` | text, the selected day / current page / main modal button (white on black), today's ring, the site header |
  22. | `greyDark` | `#555` | muted text, line numbers, syntax (keywords, strings, comments in italics), focus rings, the dim page behind a modal |
  23. | `grey` | `#999` | functional lines only: the drop zone's dashed border |
  24. | `greyLight` | `#ddd` | a strip or block on a field: editor toolbar, code, gutter; hover on a day tile; the days of a range |
  25. | `greyLighter` | `#f2f2f2` | fields and tiles on the white page: inputs, editors, day cells; hover on white |
  26. | `white` | `#fff` | the page, popups, the modal window, text on black |
  27. - A component's browser module cannot import `base.hl`, so each component writes the value as the FALLBACK of the semantic WorldAPI
  28. token: `var(--color-text, #000)`. A bare copy (no tokens) shows the base look; an app that declares the tokens — layouts.worldapi.org's
  29. `theme/theme.hl` — restyles it. **The token names, elements and classes stay as they are** (the theme targets them).
  30. - No frames: a border or ring only where it means something — focus ring (`#555`), today (`#000`), an invalid field (dashed),
  31. the drop zone (dashed `#999`). A floating popup separates by a soft black shadow, the modal by the dimmed page.
  32. - The site itself (`components/styles.hl`) uses the base names and declares **none** of the WorldAPI tokens, so the showcase shows
  33. each component exactly as a bare copy looks. Header black, page white; icon white blocks on black (`icons/`).
  34. - 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 +
  35. open date popup + open modal at 1280 and 390 px: no `--color-…` on `:root`, white page / black text, every computed colour
  36. (text, background, visible border, outline, caret, accent, text decoration, shadow, `::backdrop`) is a grey (r = g = b), and no
  37. visible border inside a component except the drop zone. Screenshots `.scratch/gate-bw-<page>-<width>.png` — LOOK at them.
  38. - Chrome quirk found on the way: when a `<strong>`'s colour equals the text around it, Chrome's `insertHTML` writes it inline
  39. (`<strong style="color: …">`); `md-editor.hl` `inlineRule` removes every `style` attribute from the surface after it inserts.
  40. ## Layout
  41. - Code order (antcolony docs/code-order.md, mission 002): `project.hl` is the MAP (its head comment says which file handles what) +
  42. config + routes, no functions; no other `.hl` in the root; `let` only for a variable that is reassigned
  43. (`python3 tests/letcount.py .` → "never reassigned 0"; kept: reassigned, loop body, a member's name, declared twice in one function).
  44. - `project.hl` routes · `components/styles.hl` the site's page layout only (colours from `shared/base.hl`, see "Look") ·
  45. `components/main.hl` shell · `components/index.hl` the home · `components/<name>/` one folder per component (component, demo,
  46. README) · `lib/uploads.hl` where the demos keep uploaded files (one day; the demos' `on server` handlers only call it).
  47. - **Public**: `components/<name>/<name>.hl` (+ `clock.hl`, READMEs) are what apps copy and what layouts.worldapi.org's `theme/theme.hl`
  48. styles (`html <element>` rules) — never rename them, their elements or classes; layouts keeps verbatim copies in its `components/`.
  49. - 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
  50. project.hl map, its own `Style` in its file, checks in `tests/browser.mjs`.
  51. - `bin/hybriel` + `plugins/` (core crypto data fs http http1 proc time web) are vendored = hybriel **master 06617221**
  52. (2026-10-03, antcolony mission 074: plugin allocators 3a781359 + 413f60e4 (#126), http1 773de63e (request owns its parse —
  53. uploads no longer retained), mpackdb 2cb7ae5e, f0ac2d2d (plugin ABI field — bin and .so must match); no lambda semantics change;
  54. sha256 `21059cc7…d77bdb`, built the same way from `git archive 06617221`; previous copy (190aa11d) in `.scratch/pre-074/`. Gate
  55. `COMPONENTS_GATE_PORT=8760 COMPONENTS_GATE_CHROME=8761-8769 node tests/browser.mjs` → 220/0. Memory: `LOADS=N UPLOADS=N [IDLE=s]
  56. node .scratch/w074/memtest.mjs <vendor dir with bin/+plugins/> <label>` (port 8760, Chrome 8761–8769; needs the live storage copy in
  57. `.scratch/w074/live/storage`, deleted after the run): 2000 loads 184 → 205 MB flat, 400 × 1 MiB uploads level at ~363–403 MB
  58. (old 190aa11d: +1 MB per upload, 829 MB).
  59. Before: master 190aa11d (2026-10-02, antcolony mission 072: fc838894 GC correctness (string index / plugin error read freed memory), 038d84b3 #126
  60. returned closure scopes, #127 d98926c6/04df4428; no lambda semantics change since 8efba065), sha256 `860f5e61…0a23626`,
  61. built read-only from `git archive 190aa11d`; previous copy (8efba065) in `.scratch/pre-072/`. Gate
  62. `COMPONENTS_GATE_PORT=8720 COMPONENTS_GATE_CHROME=8721-8729 node tests/browser.mjs` 220/0. Memory:
  63. `node .scratch/w072/memtest.mjs <vendor dir> <label>` (port 8720, Chrome 8721-8728; LOADS/UPLOADS/IDLE; needs the live
  64. storage copy in `.scratch/w072/live/storage`, deleted after each run — re-tar it): 200 loads new 182 → 205 MB (old 288 → 353);
  65. uploads still retain RAM: 400 × 1 MiB new 185 → 751 MB (old 8efba065 277 → 713 MB, HWM 823), nothing freed after 60 s idle.
  66. Before: master 8efba065 (2026-10-02, antcolony mission 069: #126 the collector also runs by bytes — memory is freed now; #48 a lambda PARAMETER
  67. COPIES its argument like a method does, write `(&p) =>` when the caller must see the change; #112 #117 #119 #120 opt-in, not
  68. used; earlier: #113, #115/#116, #118, SVG namespace, #111, #103–#106, #94, #83 hashed URLs, #82).
  69. Built from a read-only `git archive master` with `zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux-gnu.2.39` in
  70. `native/`; binary sha256 `231fb9f2…395546fc6`. **No local patch**: a re-vendor = copy binary + plugins (the ones listed;
  71. the build also refreshes their `.so`), run the gate. Previous copy: `.scratch/pre-069/` (master ff51cf46).
  72. - **#48 lambda rule**: the app has 5 lambdas (`python3 .scratch/w069/lambdas.py` / `lambdas2.py` list them and flag writes
  73. to parameters); none writes to a parameter, so none needs `&`. Components are methods / faces, which already copied.
  74. Probe: `bin/hybriel .scratch/w069/probe48.hl` → `copy: n=1 len=0` = #48 active.
  75. - **Memory check** (RSS of one server, live storage copy, 200 loads of the 9 pages + 100 file-upload drops of 1 MiB):
  76. `node .scratch/w069/memtest.mjs <dir with bin/ + plugins/> <label>` (port 8730, Chrome 8722–8729; env LOADS, UPLOADS,
  77. IDLE; it copies the app without .env into `.scratch/w069/mem-<label>/` — copy the live `storage/` to
  78. `.scratch/w069/live/storage` first, delete both afterwards).
  79. ## PWA (antcolony mission 046)
  80. Installable, the same way as calendar/tracker: hl:web's own manifest (`/__hl/manifest.webmanifest`) + service worker
  81. (`/__hl/sw.js`) from settings in `project.hl`, no JavaScript of ours.
  82. - `appTitle` "Hybriel components", `appShortName` "Components", `appIcons` (192 + 512 PNG, each `any` + `maskable`),
  83. `appTouchIcon` (180), `appFavicon` `/icons/favicon.svg`, `appThemeColor` = base `black` (the header, #000),
  84. `appBackgroundColor` = base `white` (#15; before: tokens `darker` / `dark`). `/favicon.ico` is a real icon (16/32/48). Each icon has a `file` route.
  85. - **Icons** (`icons/`): `icon.svg` = source (512, hand-written: three stacked building blocks with studs, white `#fff`
  86. on black `#000` (#15; before green-light on dark), all inside the maskable safe circle r = 204 → one image for `any` + `maskable`);
  87. `favicon.svg` = the same drawing cropped on a rounded tile. Rendered on Loreana:
  88. ```bash
  89. rsvg-convert -w 192 -h 192 icons/icon.svg -o icons/icon-192.png
  90. rsvg-convert -w 512 -h 512 icons/icon.svg -o icons/icon-512.png
  91. rsvg-convert -w 180 -h 180 icons/icon.svg -o icons/apple-touch-icon.png
  92. for s in 16 32 48; do rsvg-convert -w $s -h $s icons/favicon.svg -o /tmp/fav-$s.png; done
  93. magick /tmp/fav-16.png /tmp/fav-32.png /tmp/fav-48.png icons/favicon.ico
  94. ```
  95. - **Offline**: `offline = [ Index ]` — the worker keeps the shell and `/` (the home list). Without a network `/` opens
  96. from the cache and says "You are offline. The demos need the network." (`components/main.hl`: an invisible `netProbe`
  97. runs a 1 s CSS animation, each `animationiteration` reads `navigator.onLine` — hl:web has no connection state / mount
  98. hook). Every demo page offline gets hl:web's "Unavailable offline" page.
  99. - Gate: the `pwa:` / `offline:` checks at the end of `tests/browser.mjs` (manifest + icons over HTTP, Chrome's
  100. installability + manifest parse, worker scope `/`, then CDP offline + the server stopped → reload of `/` shows the
  101. shell; screenshots `.scratch/gate-pwa-phone-{online,offline}.png`, 390 px).
  102. ## Run, test, deploy
  103. - `COMPONENTS_PORT=8700 ./bin/hybriel project.hl` (env: `COMPONENTS_WATCH=0` no watcher, `HL_HOST`).
  104. - `node tests/browser.mjs` — the gate (230 checks since #15): own server + headless Chrome (ports 8700, 8701–8709). Other ports (workers):
  105. `COMPONENTS_GATE_PORT=8720 COMPONENTS_GATE_CHROME=8721-8729 node tests/browser.mjs`.
  106. - **Same output** (for cleanups, mission 002): run on CODE-ONLY copies (it wipes `<copy>/storage`), ports 8750 (server) + 8751–8759:
  107. ```bash
  108. rsync -a --exclude .scratch --exclude storage --exclude .sessions --exclude .git --exclude '.env*' ./ /tmp/c-new/ # same for the old tree (git worktree / git archive)
  109. node tests/same-output.mjs /tmp/c-old .scratch/out-old; node tests/same-output.mjs /tmp/c-new .scratch/out-new
  110. python3 tests/same-output-compare.py .scratch/out-old .scratch/out-new -v # every page, README, icon, css, manifest, worker, browser module;
  111. # hydrated DOM of the 9 pages; file-upload drop + choose; md-editor drop; stored files' sha256
  112. python3 tests/same-output-modules.py .scratch/out-old .scratch/out-new # browser modules: same component code + imported functions
  113. ```
  114. Masks: `?v=` hashes, source positions, times, upload names. Two runs of one tree compare clean. A moved static changes only a module's
  115. import tables; dropping `let` turns `var` into `const` in the modules (nothing else).
  116. - **Layouts theme gate** after a component change: commit here, then in layouts.worldapi.org `tools/sync-components.sh <commit>`
  117. (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
  118. `node theme/check-theme.mjs .` (0 problems) in that copy — never in parallel with this gate (same ports).
  119. - `./deploy.sh` on Loreana (architect): gate → backup → rsync → `docker compose up -d --build` on Byrodin (port 45006) → URL 200.
  120. ## History and worker briefs
  121. - `LOG.md` — append-only history, one dated line per step (moved here from the antcolony LOG on 2026-10-01).
  122. - `missions/NNN-*.md` — worker briefs for this app; `reports/NNN-*.md` — their reports (same name). Numbered per
  123. project since 2026-10-01 (antcolony#40); older text, code comments and commits use the old antcolony numbers →
  124. map: `/media/STORAGE/projects/antcolony-docs/docs/mission-map.md` (Byrodin: `/CONTAINERS/projects/antcolony/docs/mission-map.md`).

Branches

Latest commits

  • 3bc905c5components #15 (mission 003) 2/2: docs (README Look, STATUS, LOG), reportmre
  • 5a98d77ecomponents #15 (mission 003) 1/2: black/white base look — greys for nuances, no WorldAPI fallbacks, no decorative frames; site + icon black/white; gate 230/0mre
  • 3f93d716components code order (mission 002) 4/4: docs, tests/letcount.py, tests/same-output*, reportmre
  • e747cfa0components code order (mission 002) 3/4: let only where reassigned (257 dropped, 0 never-reassigned left); gate 220/0, layouts gate 73/0, same outputmre
  • 172914a3components code order (mission 002) 2/4: lib/uploads.hl (demo upload storage), thin demo handlers, project.hl map; gate 220/0, same outputmre
  • d29f35b1components code order (mission 002) 1/4: styles.hl -> components/styles.hl; gate 220/0, same outputmre
  • 09945750components: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, http1 773de63e); gate 220/0mre
  • ede4d19acomponents: Hybriel master 190aa11d (fc838894 GC correctness, #126 closure scopes, #127); gate 220/0mre
  • 2bb9a935components: Hybriel master 8efba065 (re-vendor round 069: #126 memory, #48 lambda copy)mre
  • e4f01768antcolony#40: mission references point to the moved missionsmre
  • d32b44e2antcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
  • 0fb80b57components: Hybriel master ff51cf46 (re-vendor round)mre
  • 57408b6ecomponents#14: installable app (manifest, service worker, offline index), own iconmre
  • 317bd09fdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • becbd59bcomponents#13: modal dialog (<dialog> based, focus wrap, backdrop/Esc/x close with reason, scroll lock, footer buttons)mre
  • 367dd19adeploy.sh: never send .git or .gitignore to Byrodinmre
  • 4b4dabe5State of 2026-09-27, before the move to gitoriamre