notes
All repositories: gitoria
5.7 KB
// project.hl — notes.worldapi.org: THE MAP. Config, routes and WHO HEARS WHAT. Hybriel on hl:web.// Notes with an ident login (ticket notes#1): a sidebar of the user's notes (subject = first line, last edited// first) and the selected note on the right, edited with <md-editor> (shared/md-editor.js, vendored from// worldapi-components). Saved on the server in storage/mpackdb/; kept offline in the browser (ticket notes#2).//// WHERE WHAT IS (README "Files"):// notes, their sync rules, every write to notes.db lib/notes.hl (+ lib/notes-helpers.hl)// users, the ident exchange, both logins' user step lib/users.hl// /login/callback, /api/me, /api/notes lib/api.hl (+ lib/api-helpers.hl, lib/jsoncheck.hl)// env, table folder, lists, id checks lib/util.hl// the page shell, login/logout faces components/main.hl// the notes page, /login/failed, all CSS components/notes.hl, loginfailed.hl, styles.hl// the notes area in the browser, offline copy notes-offline.js, sw.js (login.js = ident selector bridge)import WebFramework from 'hl:web'import { env } from 'hl:proc'import Styles from './components/styles.hl'import { tagOf } from './lib/users.hl'import { loginCallback, apiMe, apiNotes } from './lib/api.hl'import { dark, darker } from './shared/tokens.hl'import Notes from './components/notes.hl'import LoginFailed from './components/loginfailed.hl'static siteName = "notes"appTitle = siteName// ---- THE INSTALLABLE APP (mission 046), as calendar.worldapi.org / tracker do it: hl:web's own web app manifest// (/__hl/manifest.webmanifest, linked from every head with the apple-touch-icon and theme-color) from these settings.// Icons in icons/ (icon.svg is the source, the PNGs are rendered from it with rsvg-convert, README "PWA"). The theme// colour is the header's background (darker), the splash background the page's (dark) — both off the tokens.// NO `offline = [...]` here ON PURPOSE: that would make hl:web register its own service worker (/__hl/sw.js, scope /)// over notes' own /sw.js (notes-offline.js registers it, same scope) — one would replace the other. Notes keeps its// own offline copy (sw.js + IndexedDB, ticket notes#2) until notes#4 moves it to Hybriel.appThemeColor = darker.valueappBackgroundColor = dark.valueappIcons = [{ src = '/icons/icon-192.png' sizes = '192x192' purpose = 'any' }{ src = '/icons/icon-512.png' sizes = '512x512' purpose = 'any' }{ src = '/icons/icon-192.png' sizes = '192x192' purpose = 'maskable' }{ src = '/icons/icon-512.png' sizes = '512x512' purpose = 'maskable' }]appTouchIcon = '/icons/apple-touch-icon.png'appFavicon = '/icons/favicon.svg'styles = Stylesroutes = [{ pattern = "/favicon.ico" file = "./icons/favicon.ico" headers = { 'Cache-Control' = 'no-cache' } }// the installable app (mission 046): the icons (the manifest is hl:web's own, from appIcons){ pattern = "/icons/icon-192.png" file = "./icons/icon-192.png" headers = { 'Cache-Control' = 'no-cache' } }{ pattern = "/icons/icon-512.png" file = "./icons/icon-512.png" headers = { 'Cache-Control' = 'no-cache' } }{ pattern = "/icons/apple-touch-icon.png" file = "./icons/apple-touch-icon.png" headers = { 'Cache-Control' = 'no-cache' } }{ pattern = "/icons/favicon.svg" file = "./icons/favicon.svg" headers = { 'Cache-Control' = 'no-cache' } }// the login button's return writes the session: the request and the store go BY REFERENCE (lib/api.hl){ pattern = "/login/callback" function = (route, req) => { return loginCallback(route, &req, &server.sessions) } }{ pattern = "/login/failed" component = LoginFailed }{ pattern = "/login.js" file = "./login.js" headers = { 'Cache-Control' = 'no-cache' } }// the Markdown editor <md-editor>, vendored from worldapi-components (one <script> in the shell would do too:// it is loaded by the page component's parent, see components/main.hl){ pattern = "/md-editor.js" file = "./shared/md-editor.js" headers = { 'Cache-Control' = 'no-cache' } }// the sync API (ticket notes#2, lib/api.hl){ pattern = "/api/me" function = apiMe }{ pattern = "/api/notes" function = apiNotes }// the offline copy: the service worker (network first, the cached page when there is none) and the client that// keeps the notes in IndexedDB and syncs them{ pattern = "/sw.js" file = "./sw.js" headers = { 'Cache-Control' = 'no-cache' } }{ pattern = "/notes-offline.js" file = "./notes-offline.js" headers = { 'Cache-Control' = 'no-cache' } }{ pattern = "/" component = Notes }{ pattern = "/note/:id" component = Notes }]// WHO GETS THE PUSH: the login state reaches the tabs of one session. (Notes are not pushed: the browser's own copy// pulls through /api/notes.)// `notesSignedIn` / `notesSignedOut` go to the tabs of ONE session: the one whose login carries that random tag.audience = {notesSignedIn = (tag, session) => { return tag != null && tagOf(session) == tag }notesSignedOut = (tag, session) => { return tag != null && tagOf(session) == tag }}sessionDir = env('NOTES_SESSIONS') != null ? env('NOTES_SESSIONS') : nullport = env('NOTES_PORT') != null ? toNumber(env('NOTES_PORT')) : 8710// HL_HOST = the interface hl:web binds: 127.0.0.1 on Byrodin behind nginx; unset = 0.0.0.0 (dev on Loreana).// NOTES_WATCH=0 = no dev watcher. The session cookie is `notessid` (hybriel #10). A note taker is not logged// out after 15 minutes of thinking: the session idles out after the 14 days of sessionMaxAge.watching = env('NOTES_WATCH') != '0'sessionCookie = 'notessid'sessionIdle = 1209600server = new WebFramework(routes = routes, styles = styles, minify = true, port = port, watchMode = watching, sessionCookie = sessionCookie)on Error(e) { console.log('error absorbed: ' + e.message) }
Branches
- mainmain branch
Latest commits
- 47db4fc1notes mission 002 (3/4): code order — let only where reassigned (58 dropped; 34 left: 19 reassigned, 15 loop-bound); gates 50/0 + 18/0, live-data run = step 2mre
- 3f8cb383notes mission 002 (2/4): code order — topics, map, thin wrappers: lib/util.hl, lib/notes(-helpers).hl, lib/users.hl (+userOfLoginCode, tagOf), lib/api(-helpers).hl; project.hl = map; login routes take &req/&sessions (failed-login reason now kept); dead notes#1 functions removed; gates 50/0 + 18/0mre
- 8cda5412notes mission 002 (1/4): code order — files moved: lib/notes.hl, lib/users.hl, lib/jsoncheck.hl, components/styles.hl (imports only); gates 50/0 + 18/0, live-data run identicalmre
- 47dad68bnotes: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gates 50/0 + 18/0mre
- a4a2b2aeantcolony#40: tracker missions moved too — references to them in missions/reports/LOG.md updatedmre
- 3dea0ef2notes: Hybriel master 190aa11d (fc838894 GC correctness, #126 closure scopes, #127); gate 50/0mre
- e27c7d71notes: Hybriel master 8efba065 (#126 GC by bytes, #48 lambda params copy; audit: nothing to fix; gate 50/0)mre
- 124613b6antcolony#40: mission references point to the moved missionsmre
- 1ca2f34dantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- 2bebebdanotes: Hybriel master ff51cf46 (re-vendor round)mre
- 3eff126dnotes#3: installable app (manifest + own icon/favicon; notes' own sw.js kept)mre
- 9883c540deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- eee693b8deploy.sh: never send .git or .gitignore to Byrodinmre
- c8904061State of 2026-09-27, before the move to gitoriamre