@loadbare/app 0.23.0 → 0.24.0

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.
Files changed (38) hide show
  1. package/dist/build/assemble.d.ts.map +1 -1
  2. package/dist/build/assemble.js +28 -1
  3. package/dist/build/assemble.js.map +1 -1
  4. package/dist/core/lb-constants.d.ts +8 -5
  5. package/dist/core/lb-constants.d.ts.map +1 -1
  6. package/dist/core/lb-constants.js +20 -11
  7. package/dist/core/lb-constants.js.map +1 -1
  8. package/dist/core/lb-types.d.ts +19 -3
  9. package/dist/core/lb-types.d.ts.map +1 -1
  10. package/dist/core/lb-types.js +35 -5
  11. package/dist/core/lb-types.js.map +1 -1
  12. package/dist/hub/lb-apply.d.ts +18 -22
  13. package/dist/hub/lb-apply.d.ts.map +1 -1
  14. package/dist/hub/lb-apply.js +115 -51
  15. package/dist/hub/lb-apply.js.map +1 -1
  16. package/dist/hub/lb-hub.browser.d.ts.map +1 -1
  17. package/dist/hub/lb-hub.browser.js +15 -22
  18. package/dist/hub/lb-hub.browser.js.map +1 -1
  19. package/dist/server/lb-server.d.ts +2 -2
  20. package/dist/server/lb-server.d.ts.map +1 -1
  21. package/dist/server/lb-server.js +29 -9
  22. package/dist/server/lb-server.js.map +1 -1
  23. package/docs/comparison.md +11 -11
  24. package/docs/miswarts.md +4 -3
  25. package/docs/reference/chrome.md +42 -0
  26. package/docs/reference/custom-elements.md +9 -4
  27. package/docs/reference/data-binding.md +79 -61
  28. package/docs/reference/names.md +10 -7
  29. package/docs/reference/page-files.md +8 -4
  30. package/docs/testing.md +3 -3
  31. package/package.json +1 -1
  32. package/skills/loadbare-app/SKILL.md +23 -12
  33. package/skills/loadbare-app/references/chrome.md +42 -0
  34. package/skills/loadbare-app/references/custom-elements.md +9 -4
  35. package/skills/loadbare-app/references/data-binding.md +79 -61
  36. package/skills/loadbare-app/references/miswarts.md +4 -3
  37. package/skills/loadbare-app/references/names.md +10 -7
  38. package/skills/loadbare-app/references/page-files.md +8 -4
@@ -1 +1 @@
1
- {"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../build/assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAyCH,OAAO,KAAK,EAAY,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA6d/C,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,8EAA8E;IAC9E,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,wBAAsB,QAAQ,CAAC,EAC7B,UAAU,EACV,KAAK,EACL,KAAK,EACL,QAAQ,GACT,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAgEtC"}
1
+ {"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../build/assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA4CH,OAAO,KAAK,EAAY,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAigB/C,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,8EAA8E;IAC9E,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,wBAAsB,QAAQ,CAAC,EAC7B,UAAU,EACV,KAAK,EACL,KAAK,EACL,QAAQ,GACT,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAgEtC"}
@@ -19,7 +19,7 @@
19
19
  import { readFile } from "node:fs/promises";
20
20
  import { addDefinitions, customElementTags, expandTree, } from "./expand.js";
21
21
  import { formatHtml } from "./format.js";
22
- import { AGGREGATES, ATTR_FILTER, ATTR_ORDER, ATTR_COLUMN, ATTR_COUNT, ATTR_GROUP, ATTR_PAGE, ATTR_PAGE_TITLE, ATTR_QUERY, ATTR_REQUEST, ATTR_SELECT, ATTR_SHOW, ATTR_URL_LINK, ATTR_URL_PUSH, ATTR_URL_PARM, ATTR_URL_UNKNOWN, CHOICES_QUERY, HUB_QUERY, DEVELOPER_ATTRIBUTES, HUB_TAG_NAME, LB_COMMAND_PREFIX, LB_COMMANDS, LB_RESERVED_PREFIX, REQUEST_ROW_DELETE, REQUEST_ROW_INSERT, REQUEST_ROW_UPDATE, SHOW_NOT, URL_QUERY, } from "../core/lb-constants.js";
22
+ import { AGGREGATES, ATTR_FILTER, ATTR_MANUAL, ATTR_ORDER, MANUAL_FILTER, MANUAL_ORDER, ATTR_COLUMN, ATTR_COUNT, ATTR_GROUP, ATTR_PAGE, ATTR_PAGE_TITLE, ATTR_QUERY, ATTR_REQUEST, ATTR_SELECT, ATTR_SHOW, ATTR_URL_LINK, ATTR_URL_PUSH, ATTR_URL_PARM, ATTR_URL_UNKNOWN, CHOICES_QUERY, HUB_QUERY, DEVELOPER_ATTRIBUTES, HUB_TAG_NAME, LB_COMMAND_PREFIX, LB_COMMANDS, LB_RESERVED_PREFIX, REQUEST_ROW_DELETE, REQUEST_ROW_INSERT, REQUEST_ROW_UPDATE, SHOW_NOT, URL_QUERY, } from "../core/lb-constants.js";
23
23
  import { isRowRequest } from "../core/lb-types.js";
24
24
  /**
25
25
  * The hub is one element, and it swaps each page into the one `<main>`
@@ -208,6 +208,19 @@ function walkMarkup(node, scope, names, problems) {
208
208
  problems.push(`<${tag}> carries ${ATTR_URL_PUSH} and no ${ATTR_REQUEST}; it goes ` +
209
209
  `on an element with ${ATTR_REQUEST}`);
210
210
  }
211
+ // A column holds one value, except a query parm, which a URL may repeat.
212
+ // The column belongs to the query around the element, even one that
213
+ // names a query of its own, as a picker does.
214
+ if (el.hasAttribute(ATTR_COLUMN) &&
215
+ (el.hasAttribute("multiple") ||
216
+ (tag === "input" &&
217
+ el.getAttribute("type") === "checkbox" &&
218
+ el.hasAttribute("value"))) &&
219
+ scope?.query !== URL_QUERY) {
220
+ problems.push(`<${tag}> carries ${ATTR_COLUMN} and holds several values; only a ` +
221
+ `column of ${URL_QUERY} holds several, so it goes inside ` +
222
+ `${ATTR_QUERY}="${URL_QUERY}"`);
223
+ }
211
224
  // A selector is a checkbox in a live row, and selects that row. It is no
212
225
  // column, and commits nothing of its own.
213
226
  if (el.hasAttribute(ATTR_SELECT)) {
@@ -276,6 +289,20 @@ function walkMarkup(node, scope, names, problems) {
276
289
  problems.push(`<${tag}> carries ${name} naming no column`);
277
290
  }
278
291
  }
292
+ const manual = el.getAttribute(ATTR_MANUAL);
293
+ if (manual !== null) {
294
+ const sides = manual.trim().split(/\s+/).filter((side) => side !== "");
295
+ const known = [MANUAL_ORDER, MANUAL_FILTER];
296
+ if (!el.hasAttribute(ATTR_QUERY)) {
297
+ problems.push(`<${tag}> carries ${ATTR_MANUAL}; it goes on the element carrying ` +
298
+ `${ATTR_QUERY}`);
299
+ }
300
+ else if (sides.length === 0 ||
301
+ sides.some((side) => !known.includes(side))) {
302
+ problems.push(`<${tag}> carries ${ATTR_MANUAL}="${manual}"; it names ` +
303
+ `${MANUAL_ORDER}, ${MANUAL_FILTER} or both, separated by a space`);
304
+ }
305
+ }
279
306
  // Judged by the scope around the element, not one the element carries:
280
307
  // its condition is a column of the row around it. With no lb-query
281
308
  // around it at all, nothing ever lands on it, and the element never
@@ -1 +1 @@
1
- {"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../build/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Assembling one document out of a chrome file and a set of pages.\n *\n * Every `.html` file in play — the chrome and each page — goes through the\n * same `expand()` (see build/expand.ts) against the same definitions: the\n * built-in widgets and whatever definitions were found in the caller's own\n * source tree. `expand()` only ever sees a fragment, so the chrome's own is\n * the text between its `<body>` tags; a page's is the whole file. A page's\n * expanded host is wrapped in `<template lb-page=\"<name>\">` and, together\n * with the chrome's own expanded body content, spliced back into the\n * chrome's `<body>`. The result is the one document a server has to serve\n * for every route — see docs/tutorials/000-getting-started.md and\n * docs/reference/builder.md.\n *\n * Every path here is a parameter, resolved once by build/locations.ts — this\n * module never reconstructs one of its own, and never reads a directory\n * looking for pages or widgets; it is handed exactly which files those are.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport {\n addDefinitions,\n customElementTags,\n expandTree,\n type Definitions,\n} from \"./expand.js\";\nimport { formatHtml } from \"./format.js\";\nimport {\n AGGREGATES,\n ATTR_FILTER,\n ATTR_ORDER,\n ATTR_COLUMN,\n ATTR_COUNT,\n ATTR_GROUP,\n ATTR_PAGE,\n ATTR_PAGE_TITLE,\n ATTR_QUERY,\n ATTR_REQUEST,\n ATTR_SELECT,\n ATTR_SHOW,\n ATTR_URL_LINK,\n ATTR_URL_PUSH,\n ATTR_URL_PARM,\n ATTR_URL_UNKNOWN,\n CHOICES_QUERY,\n HUB_QUERY,\n DEVELOPER_ATTRIBUTES,\n HUB_TAG_NAME,\n LB_COMMAND_PREFIX,\n LB_COMMANDS,\n LB_RESERVED_PREFIX,\n REQUEST_ROW_DELETE,\n REQUEST_ROW_INSERT,\n REQUEST_ROW_UPDATE,\n SHOW_NOT,\n URL_QUERY,\n} from \"../core/lb-constants.js\";\nimport { isRowRequest } from \"../core/lb-types.js\";\nimport type { Declared, DeclaredPages } from \"./declared.js\";\nimport type { PageFile } from \"./locations.js\";\nimport type { OriginScan } from \"./origins.js\";\n\n/**\n * The hub is one element, and it swaps each page into the one `<main>`\n * inside it (hub/lb-hub.browser.ts), so the chrome holds exactly one of each,\n * the `<main>` inside the hub and empty, since whatever it held would be\n * replaced by the first page. A page is swapped into that `<main>`, so it\n * carries neither.\n */\nfunction checkChrome(chromeFile: string, body: ParentNode): void {\n const where = `assemble: '${chromeFile}'`;\n const hubs = body.querySelectorAll(HUB_TAG_NAME).length;\n if (hubs !== 1) {\n throw new Error(\n `${where} has ${hubs} <${HUB_TAG_NAME}>; it needs exactly one`,\n );\n }\n const mains = body.querySelectorAll(\"main\");\n if (mains.length !== 1) {\n throw new Error(\n `${where} has ${mains.length} <main>; it needs exactly one`,\n );\n }\n const main = mains[0]!;\n if (!main.closest(HUB_TAG_NAME)) {\n throw new Error(\n `${where} has its <main> outside <${HUB_TAG_NAME}>, where the hub cannot reach it`,\n );\n }\n if (main.children.length > 0 || main.textContent!.trim() !== \"\") {\n throw new Error(\n `${where} has content in its <main>, which the first page replaces; it goes empty`,\n );\n }\n}\n\n/** A page lands inside the chrome's `<main>`, so it brings no second one and no hub. */\nfunction checkPage(file: string, root: ParentNode): void {\n for (const tag of [HUB_TAG_NAME, \"main\"]) {\n if (root.querySelector(tag)) {\n throw new Error(\n `assemble: '${file}' carries a <${tag}>, which belongs to the chrome alone`,\n );\n }\n }\n}\n\n/**\n * The hub calls showModal() on the `<dialog>` carrying lb-url-unknown\n * (hub/lb-hub.browser.ts), and looks for it inside itself, as it does for\n * everything else it acts on. A dialog elsewhere in the body would never open\n * and would say nothing about why.\n */\nfunction checkUnknownPageDialog(chromeFile: string, body: ParentNode): void {\n const el = body.querySelector(`[${ATTR_URL_UNKNOWN}]`);\n if (!el) return;\n if (!el.closest(HUB_TAG_NAME)) {\n throw new Error(\n `assemble: '${chromeFile}' declares ${ATTR_URL_UNKNOWN} outside ` +\n `<${HUB_TAG_NAME}>, where the hub cannot reach it`,\n );\n }\n}\n\n/**\n * Where the markup stands while the check walks it: inside which `lb-query`,\n * and whether there is a row there to take a value from. Inside a row\n * template there always is. Inside an `lb-query` outside one, there is when\n * the query is of kind `row`, which only the server knows.\n */\ninterface Scope {\n query: string;\n row: boolean | \"unknown\";\n}\n\n/** The queries the hub serves, which every page and the chrome may name. */\nconst HUB_QUERIES: readonly string[] = [URL_QUERY, CHOICES_QUERY, HUB_QUERY];\n\n/** The `Crud` key each request Loadbare provides runs. */\nconst CRUD_KEYS: Record<string, string> = {\n [REQUEST_ROW_INSERT]: \"rowInsert\",\n [REQUEST_ROW_UPDATE]: \"rowUpdate\",\n [REQUEST_ROW_DELETE]: \"rowDelete\",\n};\n\n/**\n * What a file's names are checked against: a page's declarations, or `null`\n * for the chrome, which belongs to no page and so names only what the hub\n * serves.\n */\ntype Names = { declared: Declared | null };\n\n/**\n * An `lb-query` or `lb-request` naming nothing the page declares would be\n * found only on the first round trip, as a server warning and an empty\n * answer, so a typo would build cleanly.\n *\n * A request Loadbare provides is for the query of what it gathers: a form's\n * own when the form carries `lb-query`, otherwise the nearest around the\n * element, as the hub decides it (hub/lb-hub.browser.ts). With no query\n * around it, the hub reports it in the browser.\n */\nfunction checkNames(\n el: Element,\n scope: Scope | null,\n names: Names,\n problems: string[],\n): void {\n const tag = el.localName;\n const { declared } = names;\n\n const query = el.getAttribute(ATTR_QUERY);\n if (query !== null && !HUB_QUERIES.includes(query)) {\n if (declared === null) {\n problems.push(\n `<${tag}> carries ${ATTR_QUERY}=\"${query}\"; the chrome belongs to ` +\n `no page, and names only ${HUB_QUERIES.slice(0, -1).join(\", \")} and ${HUB_QUERIES.at(-1)}`,\n );\n } else if (!declared.queries.has(query)) {\n problems.push(\n `<${tag}> carries ${ATTR_QUERY}=\"${query}\", which the page's ` +\n `queries do not declare`,\n );\n }\n }\n\n const request = el.getAttribute(ATTR_REQUEST);\n if (!request) return;\n if (isRowRequest(request)) {\n const target =\n tag === \"form\" && query !== null ? query : (scope?.query ?? null);\n if (target === null) return;\n if (target === HUB_QUERY) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\" for '${target}'; ` +\n `the hub's own state is written by the hub alone`,\n );\n return;\n }\n if (HUB_QUERIES.includes(target)) {\n if (request !== REQUEST_ROW_UPDATE) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\" for '${target}'; ` +\n `the hub answers only ${REQUEST_ROW_UPDATE} for it`,\n );\n }\n return;\n }\n // A query the page does not declare is reported once, where it is named.\n if (declared === null || !declared.queries.has(target)) return;\n const key = CRUD_KEYS[request]!;\n if (!declared.crud.get(target)?.has(key)) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\" for '${target}', ` +\n `whose crud entry the page does not declare with ${key}`,\n );\n }\n } else if (request.startsWith(LB_RESERVED_PREFIX)) {\n // Reported by walkMarkup as naming no request Loadbare provides.\n } else if (declared === null) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\"; the chrome belongs ` +\n `to no page, and sends no declared request`,\n );\n } else if (!declared.handlers.has(request)) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\", which the page's ` +\n `handlers do not declare`,\n );\n }\n}\n\n/**\n * The markup, checked once against the finished document rather than\n * discovered one console error at a time in a browser.\n *\n * Every rule here is a fact the markup states about itself. The developer\n * writes `lb-*` attributes in markup, and script never assigns them, which is\n * what makes checking the markup sound. See docs/reference/data-binding.md.\n *\n * A `<template>`'s children are walked in the scope that encloses the\n * template, because a row template's clones land in the element around it.\n */\nfunction walkMarkup(\n node: ParentNode,\n scope: Scope | null,\n names: Names | null,\n problems: string[],\n): void {\n for (const el of node.children) {\n const tag = el.localName;\n let here = scope;\n const query = el.getAttribute(ATTR_QUERY);\n if (query !== null) here = { query, row: \"unknown\" };\n if (names) checkNames(el, scope, names, problems);\n\n for (const { name } of el.attributes) {\n if (\n name.startsWith(LB_RESERVED_PREFIX) &&\n !(DEVELOPER_ATTRIBUTES as readonly string[]).includes(name)\n ) {\n problems.push(\n `<${tag}> carries ${name}, which is not an attribute a developer ` +\n `writes`,\n );\n }\n }\n\n const request = el.getAttribute(ATTR_REQUEST);\n if (\n request !== null &&\n request.startsWith(LB_RESERVED_PREFIX) &&\n !isRowRequest(request)\n ) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\", which begins with ` +\n `'${LB_RESERVED_PREFIX}' but names no request Loadbare provides`,\n );\n }\n if (el.hasAttribute(ATTR_URL_LINK) && tag !== \"a\") {\n problems.push(`<${tag}> carries ${ATTR_URL_LINK}; it goes on an <a>`);\n }\n // A link's parms are columns of the row around it, and only a link the\n // hub handles takes them: the parms are the application's own URL.\n const parms = el.getAttribute(ATTR_URL_PARM);\n if (parms !== null) {\n const columns = parms.split(\",\").map((column) => column.trim());\n if (tag !== \"a\" || !el.hasAttribute(ATTR_URL_LINK)) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}; it goes on an <a> carrying ` +\n `${ATTR_URL_LINK}`,\n );\n } else if (columns.some((column) => column === \"\")) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\", which names no ` +\n `column between two commas or at either end`,\n );\n } else if (columns.some((column) => /\\s/.test(column))) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\"; columns are ` +\n `separated by commas`,\n );\n } else if (columns.some((c) => c.startsWith(LB_RESERVED_PREFIX))) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\"; a parm beginning ` +\n `'${LB_RESERVED_PREFIX}' is the hub's own`,\n );\n } else if (scope === null || scope.row === false) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\" with no row around ` +\n `it to take the values from`,\n );\n }\n }\n if (el.hasAttribute(ATTR_URL_PUSH) && request === null) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PUSH} and no ${ATTR_REQUEST}; it goes ` +\n `on an element with ${ATTR_REQUEST}`,\n );\n }\n // A selector is a checkbox in a live row, and selects that row. It is no\n // column, and commits nothing of its own.\n if (el.hasAttribute(ATTR_SELECT)) {\n if (tag !== \"input\" || el.getAttribute(\"type\") !== \"checkbox\") {\n problems.push(\n `<${tag}> carries ${ATTR_SELECT}; it goes on an ` +\n `<input type=\"checkbox\">`,\n );\n } else if (scope?.row !== true) {\n problems.push(\n `<input> carries ${ATTR_SELECT} outside a row template; it ` +\n `selects the row it sits in`,\n );\n }\n for (const name of [ATTR_COLUMN, ATTR_REQUEST]) {\n if (el.hasAttribute(name)) {\n problems.push(\n `<${tag}> carries ${ATTR_SELECT} and ${name}; a selector is no ` +\n `column and sends nothing`,\n );\n }\n }\n }\n // HTML's own command attribute, whose `--lb-` values are Loadbare's.\n const command = el.getAttribute(\"command\");\n if (command !== null && command.startsWith(LB_COMMAND_PREFIX)) {\n if (!(LB_COMMANDS as readonly string[]).includes(command)) {\n problems.push(\n `<${tag}> carries command=\"${command}\", which begins with ` +\n `'${LB_COMMAND_PREFIX}' but names no command Loadbare provides`,\n );\n } else if (!el.hasAttribute(\"commandfor\")) {\n problems.push(\n `<${tag}> carries command=\"${command}\" and no commandfor; it ` +\n `names the element the command is for`,\n );\n }\n }\n if (el.hasAttribute(ATTR_URL_UNKNOWN) && tag !== \"dialog\") {\n problems.push(\n `<${tag}> carries ${ATTR_URL_UNKNOWN}; it goes on a <dialog>`,\n );\n }\n\n // A group is a template holding a heading and the template its\n // contents go in; an aggregate is set on an element, from the column it\n // names.\n if (el.hasAttribute(ATTR_GROUP)) {\n if (tag !== \"template\") {\n problems.push(\n `<${tag}> carries ${ATTR_GROUP}; it goes on a <template>`,\n );\n } else if (\n !(el as HTMLTemplateElement).content.querySelector(\n `template:not([${ATTR_SHOW}])`,\n )\n ) {\n problems.push(\n `a <template ${ATTR_GROUP}> holds no <template> for its contents`,\n );\n }\n }\n for (const name of AGGREGATES) {\n if (!el.hasAttribute(name)) continue;\n if (tag === \"template\") {\n problems.push(`a <template> carries ${name}; it goes on an element`);\n } else if (name !== ATTR_COUNT && !el.getAttribute(name)) {\n problems.push(`<${tag}> carries ${name} naming no column`);\n }\n }\n\n // The user's order and filter for the rows an element holds, each read\n // from a column of lb-choices it names.\n for (const name of [ATTR_ORDER, ATTR_FILTER]) {\n const value = el.getAttribute(name);\n if (value === null) continue;\n if (!el.hasAttribute(ATTR_QUERY)) {\n problems.push(\n `<${tag}> carries ${name}; it goes on the element carrying ` +\n `${ATTR_QUERY}`,\n );\n } else if (value.trim() === \"\") {\n problems.push(`<${tag}> carries ${name} naming no column`);\n }\n }\n\n // Judged by the scope around the element, not one the element carries:\n // its condition is a column of the row around it. With no lb-query\n // around it at all, nothing ever lands on it, and the element never\n // shows.\n const show = el.getAttribute(ATTR_SHOW);\n if (show !== null) {\n if (tag === \"template\") {\n problems.push(\n `a <template> carries ${ATTR_SHOW}=\"${show}\"; write it on the ` +\n `element it shows, and Loadbare supplies the template`,\n );\n } else if (scope === null || scope.row === false) {\n problems.push(\n `<${tag}> carries ${ATTR_SHOW}=\"${show}\" with no row around it ` +\n `to take the value from`,\n );\n } else if (show === SHOW_NOT || show.startsWith(SHOW_NOT + SHOW_NOT)) {\n problems.push(\n `<${tag}> carries ${ATTR_SHOW}=\"${show}\"; write one ` +\n `${SHOW_NOT} and then the column it reverses`,\n );\n }\n }\n\n walkMarkup(el, here, names, problems);\n // By tag name rather than by instanceof: template content belongs to a\n // document with no window, so the constructor is not reachable from the\n // node.\n if (tag === \"template\") {\n const content = (el as HTMLTemplateElement).content;\n const isRowTemplate =\n scope !== null && !!el.parentElement?.closest(`[${ATTR_QUERY}]`);\n if (isRowTemplate) {\n for (const root of content.children) {\n if (root.hasAttribute(ATTR_SHOW)) {\n problems.push(\n `<${root.localName}> is a row template's root and carries ` +\n `${ATTR_SHOW}; a row that should not show is left out by ` +\n `the query`,\n );\n }\n }\n }\n walkMarkup(\n content,\n isRowTemplate ? { query: scope!.query, row: true } : here,\n names,\n problems,\n );\n }\n }\n}\n\n/**\n * Ship every `lb-show` element already inside the template the hub keeps an\n * absent branch in, so nothing conditional shows until its value says so.\n * A page is in the document before its data arrives, and a value that has not\n * arrived is no value.\n *\n * Elements are collected before any is moved, and a wrapped element is still\n * reached once its outer one has gone into a template, because the references\n * are held.\n */\nfunction wrapShown(holder: HTMLTemplateElement): void {\n const doc = holder.ownerDocument;\n const shown: Element[] = [];\n const collect = (root: ParentNode): void => {\n shown.push(...root.querySelectorAll(`[${ATTR_SHOW}]`));\n for (const t of root.querySelectorAll(\"template\")) {\n collect((t as HTMLTemplateElement).content);\n }\n };\n collect(holder.content);\n for (const el of shown) {\n const parked = doc.createElement(\"template\");\n parked.setAttribute(ATTR_SHOW, el.getAttribute(ATTR_SHOW)!);\n el.replaceWith(parked);\n parked.content.append(el);\n }\n}\n\n/**\n * Expand one file's markup, naming the file if expansion refuses it.\n *\n * What comes back is the tree the browser will build, so every pass after\n * this reads and changes it in place, and it is serialized once, when it\n * ships.\n */\nfunction expandFile(\n file: string,\n source: string,\n defs: Definitions,\n): HTMLTemplateElement {\n try {\n return expandTree(source, defs);\n } catch (e) {\n throw new Error(`assemble: '${file}': ${(e as Error).message}`);\n }\n}\n\n/** Check one expanded fragment, and name the file if anything is wrong. */\nfunction checkMarkup(\n file: string,\n root: ParentNode,\n names: Names | null,\n): void {\n const problems: string[] = [];\n walkMarkup(root, null, names, problems);\n if (problems.length > 0) {\n throw new Error(`assemble: '${file}' markup:\\n ` + problems.join(`\\n `));\n }\n}\n\n/**\n * A page file's `<title>` names the page. It is lifted out, since a page is\n * a fragment inside `<main>` and a `<title>` belongs in a document's head,\n * and its text content is stamped on the page as ATTR_PAGE_TITLE.\n */\nfunction liftTitle(holder: HTMLTemplateElement): string | null {\n const title = holder.content.querySelector(\"title\");\n if (!title) return null;\n const text = title.textContent?.trim() ?? \"\";\n title.remove();\n return text;\n}\n\n/** An attribute value, escaped for a double-quoted attribute. */\nfunction attributeValue(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nexport interface AssembleOptions {\n chromeFile: string;\n pages: PageFile[];\n /** Every origin, already scanned, in cascade order — see build/origins.ts. */\n scans: OriginScan[];\n /**\n * What each page declares — see build/declared.ts. Without it, the names\n * `lb-query` and `lb-request` carry are not checked.\n */\n declared?: DeclaredPages;\n}\n\nexport interface Assembled {\n html: string;\n /** Every custom element tag left in the document once expansion is done. */\n usedTags: Set<string>;\n}\n\nexport async function assemble({\n chromeFile,\n pages,\n scans,\n declared,\n}: AssembleOptions): Promise<Assembled> {\n // One layer per origin, in order, so a later origin's definition overrides\n // an earlier one's for the same tag. Each layer is checked for cycles as it\n // lands, against everything merged so far.\n let defs: Definitions = {};\n for (const scan of scans) {\n defs = await addDefinitions(defs, scan.definitions);\n }\n\n // Tags are collected from each tree as it goes by. What ships is these\n // trees and the chrome around its body, which is collected on its own.\n const usedTags = new Set<string>();\n const templates: string[] = [];\n for (const { name, file } of pages) {\n const authored = await readFile(file, \"utf-8\");\n const host = expandFile(file, authored, defs);\n const title = liftTitle(host);\n checkPage(file, host.content);\n checkMarkup(\n file,\n host.content,\n declared ? { declared: declared.get(name)! } : null,\n );\n wrapShown(host);\n customElementTags(host.content, usedTags);\n const titled =\n title === null ? \"\" : ` ${ATTR_PAGE_TITLE}=\"${attributeValue(title)}\"`;\n templates.push(\n `<template ${ATTR_PAGE}=\"${name}\"${titled}>${host.innerHTML}</template>`,\n );\n }\n\n let chromeSource: string;\n try {\n chromeSource = await readFile(chromeFile, \"utf-8\");\n } catch {\n throw new Error(`assemble: no chrome file at '${chromeFile}'`);\n }\n\n const body = /<body([^>]*)>([\\s\\S]*)<\\/body>/i.exec(chromeSource);\n if (!body) {\n throw new Error(\n `assemble: '${chromeFile}' has no <body>...</body> to expand`,\n );\n }\n const [whole, bodyAttrs, bodyContent] = body;\n const chromeBody = expandFile(chromeFile, bodyContent!, defs);\n checkChrome(chromeFile, chromeBody.content);\n checkUnknownPageDialog(chromeFile, chromeBody.content);\n checkMarkup(\n chromeFile,\n chromeBody.content,\n declared ? { declared: null } : null,\n );\n wrapShown(chromeBody);\n customElementTags(chromeBody.content, usedTags);\n customElementTags(chromeSource.replace(whole!, \"\"), usedTags);\n const withPages = chromeSource.replace(\n whole!,\n () =>\n `<body${bodyAttrs}>${chromeBody.innerHTML}\\n${templates.join(\"\\n\")}\\n</body>`,\n );\n\n return { html: await formatHtml(withPages), usedTags };\n}\n"]}
1
+ {"version":3,"file":"assemble.js","sourceRoot":"","sources":["../../build/assemble.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Assembling one document out of a chrome file and a set of pages.\n *\n * Every `.html` file in play — the chrome and each page — goes through the\n * same `expand()` (see build/expand.ts) against the same definitions: the\n * built-in widgets and whatever definitions were found in the caller's own\n * source tree. `expand()` only ever sees a fragment, so the chrome's own is\n * the text between its `<body>` tags; a page's is the whole file. A page's\n * expanded host is wrapped in `<template lb-page=\"<name>\">` and, together\n * with the chrome's own expanded body content, spliced back into the\n * chrome's `<body>`. The result is the one document a server has to serve\n * for every route — see docs/tutorials/000-getting-started.md and\n * docs/reference/builder.md.\n *\n * Every path here is a parameter, resolved once by build/locations.ts — this\n * module never reconstructs one of its own, and never reads a directory\n * looking for pages or widgets; it is handed exactly which files those are.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport {\n addDefinitions,\n customElementTags,\n expandTree,\n type Definitions,\n} from \"./expand.js\";\nimport { formatHtml } from \"./format.js\";\nimport {\n AGGREGATES,\n ATTR_FILTER,\n ATTR_MANUAL,\n ATTR_ORDER,\n MANUAL_FILTER,\n MANUAL_ORDER,\n ATTR_COLUMN,\n ATTR_COUNT,\n ATTR_GROUP,\n ATTR_PAGE,\n ATTR_PAGE_TITLE,\n ATTR_QUERY,\n ATTR_REQUEST,\n ATTR_SELECT,\n ATTR_SHOW,\n ATTR_URL_LINK,\n ATTR_URL_PUSH,\n ATTR_URL_PARM,\n ATTR_URL_UNKNOWN,\n CHOICES_QUERY,\n HUB_QUERY,\n DEVELOPER_ATTRIBUTES,\n HUB_TAG_NAME,\n LB_COMMAND_PREFIX,\n LB_COMMANDS,\n LB_RESERVED_PREFIX,\n REQUEST_ROW_DELETE,\n REQUEST_ROW_INSERT,\n REQUEST_ROW_UPDATE,\n SHOW_NOT,\n URL_QUERY,\n} from \"../core/lb-constants.js\";\nimport { isRowRequest } from \"../core/lb-types.js\";\nimport type { Declared, DeclaredPages } from \"./declared.js\";\nimport type { PageFile } from \"./locations.js\";\nimport type { OriginScan } from \"./origins.js\";\n\n/**\n * The hub is one element, and it swaps each page into the one `<main>`\n * inside it (hub/lb-hub.browser.ts), so the chrome holds exactly one of each,\n * the `<main>` inside the hub and empty, since whatever it held would be\n * replaced by the first page. A page is swapped into that `<main>`, so it\n * carries neither.\n */\nfunction checkChrome(chromeFile: string, body: ParentNode): void {\n const where = `assemble: '${chromeFile}'`;\n const hubs = body.querySelectorAll(HUB_TAG_NAME).length;\n if (hubs !== 1) {\n throw new Error(\n `${where} has ${hubs} <${HUB_TAG_NAME}>; it needs exactly one`,\n );\n }\n const mains = body.querySelectorAll(\"main\");\n if (mains.length !== 1) {\n throw new Error(\n `${where} has ${mains.length} <main>; it needs exactly one`,\n );\n }\n const main = mains[0]!;\n if (!main.closest(HUB_TAG_NAME)) {\n throw new Error(\n `${where} has its <main> outside <${HUB_TAG_NAME}>, where the hub cannot reach it`,\n );\n }\n if (main.children.length > 0 || main.textContent!.trim() !== \"\") {\n throw new Error(\n `${where} has content in its <main>, which the first page replaces; it goes empty`,\n );\n }\n}\n\n/** A page lands inside the chrome's `<main>`, so it brings no second one and no hub. */\nfunction checkPage(file: string, root: ParentNode): void {\n for (const tag of [HUB_TAG_NAME, \"main\"]) {\n if (root.querySelector(tag)) {\n throw new Error(\n `assemble: '${file}' carries a <${tag}>, which belongs to the chrome alone`,\n );\n }\n }\n}\n\n/**\n * The hub calls showModal() on the `<dialog>` carrying lb-url-unknown\n * (hub/lb-hub.browser.ts), and looks for it inside itself, as it does for\n * everything else it acts on. A dialog elsewhere in the body would never open\n * and would say nothing about why.\n */\nfunction checkUnknownPageDialog(chromeFile: string, body: ParentNode): void {\n const el = body.querySelector(`[${ATTR_URL_UNKNOWN}]`);\n if (!el) return;\n if (!el.closest(HUB_TAG_NAME)) {\n throw new Error(\n `assemble: '${chromeFile}' declares ${ATTR_URL_UNKNOWN} outside ` +\n `<${HUB_TAG_NAME}>, where the hub cannot reach it`,\n );\n }\n}\n\n/**\n * Where the markup stands while the check walks it: inside which `lb-query`,\n * and whether there is a row there to take a value from. Inside a row\n * template there always is. Inside an `lb-query` outside one, there is when\n * the query is of kind `row`, which only the server knows.\n */\ninterface Scope {\n query: string;\n row: boolean | \"unknown\";\n}\n\n/** The queries the hub serves, which every page and the chrome may name. */\nconst HUB_QUERIES: readonly string[] = [URL_QUERY, CHOICES_QUERY, HUB_QUERY];\n\n/** The `Crud` key each request Loadbare provides runs. */\nconst CRUD_KEYS: Record<string, string> = {\n [REQUEST_ROW_INSERT]: \"rowInsert\",\n [REQUEST_ROW_UPDATE]: \"rowUpdate\",\n [REQUEST_ROW_DELETE]: \"rowDelete\",\n};\n\n/**\n * What a file's names are checked against: a page's declarations, or `null`\n * for the chrome, which belongs to no page and so names only what the hub\n * serves.\n */\ntype Names = { declared: Declared | null };\n\n/**\n * An `lb-query` or `lb-request` naming nothing the page declares would be\n * found only on the first round trip, as a server warning and an empty\n * answer, so a typo would build cleanly.\n *\n * A request Loadbare provides is for the query of what it gathers: a form's\n * own when the form carries `lb-query`, otherwise the nearest around the\n * element, as the hub decides it (hub/lb-hub.browser.ts). With no query\n * around it, the hub reports it in the browser.\n */\nfunction checkNames(\n el: Element,\n scope: Scope | null,\n names: Names,\n problems: string[],\n): void {\n const tag = el.localName;\n const { declared } = names;\n\n const query = el.getAttribute(ATTR_QUERY);\n if (query !== null && !HUB_QUERIES.includes(query)) {\n if (declared === null) {\n problems.push(\n `<${tag}> carries ${ATTR_QUERY}=\"${query}\"; the chrome belongs to ` +\n `no page, and names only ${HUB_QUERIES.slice(0, -1).join(\", \")} and ${HUB_QUERIES.at(-1)}`,\n );\n } else if (!declared.queries.has(query)) {\n problems.push(\n `<${tag}> carries ${ATTR_QUERY}=\"${query}\", which the page's ` +\n `queries do not declare`,\n );\n }\n }\n\n const request = el.getAttribute(ATTR_REQUEST);\n if (!request) return;\n if (isRowRequest(request)) {\n const target =\n tag === \"form\" && query !== null ? query : (scope?.query ?? null);\n if (target === null) return;\n if (target === HUB_QUERY) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\" for '${target}'; ` +\n `the hub's own state is written by the hub alone`,\n );\n return;\n }\n if (HUB_QUERIES.includes(target)) {\n if (request !== REQUEST_ROW_UPDATE) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\" for '${target}'; ` +\n `the hub answers only ${REQUEST_ROW_UPDATE} for it`,\n );\n }\n return;\n }\n // A query the page does not declare is reported once, where it is named.\n if (declared === null || !declared.queries.has(target)) return;\n const key = CRUD_KEYS[request]!;\n if (!declared.crud.get(target)?.has(key)) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\" for '${target}', ` +\n `whose crud entry the page does not declare with ${key}`,\n );\n }\n } else if (request.startsWith(LB_RESERVED_PREFIX)) {\n // Reported by walkMarkup as naming no request Loadbare provides.\n } else if (declared === null) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\"; the chrome belongs ` +\n `to no page, and sends no declared request`,\n );\n } else if (!declared.handlers.has(request)) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\", which the page's ` +\n `handlers do not declare`,\n );\n }\n}\n\n/**\n * The markup, checked once against the finished document rather than\n * discovered one console error at a time in a browser.\n *\n * Every rule here is a fact the markup states about itself. The developer\n * writes `lb-*` attributes in markup, and script never assigns them, which is\n * what makes checking the markup sound. See docs/reference/data-binding.md.\n *\n * A `<template>`'s children are walked in the scope that encloses the\n * template, because a row template's clones land in the element around it.\n */\nfunction walkMarkup(\n node: ParentNode,\n scope: Scope | null,\n names: Names | null,\n problems: string[],\n): void {\n for (const el of node.children) {\n const tag = el.localName;\n let here = scope;\n const query = el.getAttribute(ATTR_QUERY);\n if (query !== null) here = { query, row: \"unknown\" };\n if (names) checkNames(el, scope, names, problems);\n\n for (const { name } of el.attributes) {\n if (\n name.startsWith(LB_RESERVED_PREFIX) &&\n !(DEVELOPER_ATTRIBUTES as readonly string[]).includes(name)\n ) {\n problems.push(\n `<${tag}> carries ${name}, which is not an attribute a developer ` +\n `writes`,\n );\n }\n }\n\n const request = el.getAttribute(ATTR_REQUEST);\n if (\n request !== null &&\n request.startsWith(LB_RESERVED_PREFIX) &&\n !isRowRequest(request)\n ) {\n problems.push(\n `<${tag}> carries ${ATTR_REQUEST}=\"${request}\", which begins with ` +\n `'${LB_RESERVED_PREFIX}' but names no request Loadbare provides`,\n );\n }\n if (el.hasAttribute(ATTR_URL_LINK) && tag !== \"a\") {\n problems.push(`<${tag}> carries ${ATTR_URL_LINK}; it goes on an <a>`);\n }\n // A link's parms are columns of the row around it, and only a link the\n // hub handles takes them: the parms are the application's own URL.\n const parms = el.getAttribute(ATTR_URL_PARM);\n if (parms !== null) {\n const columns = parms.split(\",\").map((column) => column.trim());\n if (tag !== \"a\" || !el.hasAttribute(ATTR_URL_LINK)) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}; it goes on an <a> carrying ` +\n `${ATTR_URL_LINK}`,\n );\n } else if (columns.some((column) => column === \"\")) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\", which names no ` +\n `column between two commas or at either end`,\n );\n } else if (columns.some((column) => /\\s/.test(column))) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\"; columns are ` +\n `separated by commas`,\n );\n } else if (columns.some((c) => c.startsWith(LB_RESERVED_PREFIX))) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\"; a parm beginning ` +\n `'${LB_RESERVED_PREFIX}' is the hub's own`,\n );\n } else if (scope === null || scope.row === false) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PARM}=\"${parms}\" with no row around ` +\n `it to take the values from`,\n );\n }\n }\n if (el.hasAttribute(ATTR_URL_PUSH) && request === null) {\n problems.push(\n `<${tag}> carries ${ATTR_URL_PUSH} and no ${ATTR_REQUEST}; it goes ` +\n `on an element with ${ATTR_REQUEST}`,\n );\n }\n // A column holds one value, except a query parm, which a URL may repeat.\n // The column belongs to the query around the element, even one that\n // names a query of its own, as a picker does.\n if (\n el.hasAttribute(ATTR_COLUMN) &&\n (el.hasAttribute(\"multiple\") ||\n (tag === \"input\" &&\n el.getAttribute(\"type\") === \"checkbox\" &&\n el.hasAttribute(\"value\"))) &&\n scope?.query !== URL_QUERY\n ) {\n problems.push(\n `<${tag}> carries ${ATTR_COLUMN} and holds several values; only a ` +\n `column of ${URL_QUERY} holds several, so it goes inside ` +\n `${ATTR_QUERY}=\"${URL_QUERY}\"`,\n );\n }\n // A selector is a checkbox in a live row, and selects that row. It is no\n // column, and commits nothing of its own.\n if (el.hasAttribute(ATTR_SELECT)) {\n if (tag !== \"input\" || el.getAttribute(\"type\") !== \"checkbox\") {\n problems.push(\n `<${tag}> carries ${ATTR_SELECT}; it goes on an ` +\n `<input type=\"checkbox\">`,\n );\n } else if (scope?.row !== true) {\n problems.push(\n `<input> carries ${ATTR_SELECT} outside a row template; it ` +\n `selects the row it sits in`,\n );\n }\n for (const name of [ATTR_COLUMN, ATTR_REQUEST]) {\n if (el.hasAttribute(name)) {\n problems.push(\n `<${tag}> carries ${ATTR_SELECT} and ${name}; a selector is no ` +\n `column and sends nothing`,\n );\n }\n }\n }\n // HTML's own command attribute, whose `--lb-` values are Loadbare's.\n const command = el.getAttribute(\"command\");\n if (command !== null && command.startsWith(LB_COMMAND_PREFIX)) {\n if (!(LB_COMMANDS as readonly string[]).includes(command)) {\n problems.push(\n `<${tag}> carries command=\"${command}\", which begins with ` +\n `'${LB_COMMAND_PREFIX}' but names no command Loadbare provides`,\n );\n } else if (!el.hasAttribute(\"commandfor\")) {\n problems.push(\n `<${tag}> carries command=\"${command}\" and no commandfor; it ` +\n `names the element the command is for`,\n );\n }\n }\n if (el.hasAttribute(ATTR_URL_UNKNOWN) && tag !== \"dialog\") {\n problems.push(\n `<${tag}> carries ${ATTR_URL_UNKNOWN}; it goes on a <dialog>`,\n );\n }\n\n // A group is a template holding a heading and the template its\n // contents go in; an aggregate is set on an element, from the column it\n // names.\n if (el.hasAttribute(ATTR_GROUP)) {\n if (tag !== \"template\") {\n problems.push(\n `<${tag}> carries ${ATTR_GROUP}; it goes on a <template>`,\n );\n } else if (\n !(el as HTMLTemplateElement).content.querySelector(\n `template:not([${ATTR_SHOW}])`,\n )\n ) {\n problems.push(\n `a <template ${ATTR_GROUP}> holds no <template> for its contents`,\n );\n }\n }\n for (const name of AGGREGATES) {\n if (!el.hasAttribute(name)) continue;\n if (tag === \"template\") {\n problems.push(`a <template> carries ${name}; it goes on an element`);\n } else if (name !== ATTR_COUNT && !el.getAttribute(name)) {\n problems.push(`<${tag}> carries ${name} naming no column`);\n }\n }\n\n // The user's order and filter for the rows an element holds, each read\n // from a column of lb-choices it names.\n for (const name of [ATTR_ORDER, ATTR_FILTER]) {\n const value = el.getAttribute(name);\n if (value === null) continue;\n if (!el.hasAttribute(ATTR_QUERY)) {\n problems.push(\n `<${tag}> carries ${name}; it goes on the element carrying ` +\n `${ATTR_QUERY}`,\n );\n } else if (value.trim() === \"\") {\n problems.push(`<${tag}> carries ${name} naming no column`);\n }\n }\n const manual = el.getAttribute(ATTR_MANUAL);\n if (manual !== null) {\n const sides = manual.trim().split(/\\s+/).filter((side) => side !== \"\");\n const known = [MANUAL_ORDER, MANUAL_FILTER];\n if (!el.hasAttribute(ATTR_QUERY)) {\n problems.push(\n `<${tag}> carries ${ATTR_MANUAL}; it goes on the element carrying ` +\n `${ATTR_QUERY}`,\n );\n } else if (\n sides.length === 0 ||\n sides.some((side) => !known.includes(side))\n ) {\n problems.push(\n `<${tag}> carries ${ATTR_MANUAL}=\"${manual}\"; it names ` +\n `${MANUAL_ORDER}, ${MANUAL_FILTER} or both, separated by a space`,\n );\n }\n }\n\n // Judged by the scope around the element, not one the element carries:\n // its condition is a column of the row around it. With no lb-query\n // around it at all, nothing ever lands on it, and the element never\n // shows.\n const show = el.getAttribute(ATTR_SHOW);\n if (show !== null) {\n if (tag === \"template\") {\n problems.push(\n `a <template> carries ${ATTR_SHOW}=\"${show}\"; write it on the ` +\n `element it shows, and Loadbare supplies the template`,\n );\n } else if (scope === null || scope.row === false) {\n problems.push(\n `<${tag}> carries ${ATTR_SHOW}=\"${show}\" with no row around it ` +\n `to take the value from`,\n );\n } else if (show === SHOW_NOT || show.startsWith(SHOW_NOT + SHOW_NOT)) {\n problems.push(\n `<${tag}> carries ${ATTR_SHOW}=\"${show}\"; write one ` +\n `${SHOW_NOT} and then the column it reverses`,\n );\n }\n }\n\n walkMarkup(el, here, names, problems);\n // By tag name rather than by instanceof: template content belongs to a\n // document with no window, so the constructor is not reachable from the\n // node.\n if (tag === \"template\") {\n const content = (el as HTMLTemplateElement).content;\n const isRowTemplate =\n scope !== null && !!el.parentElement?.closest(`[${ATTR_QUERY}]`);\n if (isRowTemplate) {\n for (const root of content.children) {\n if (root.hasAttribute(ATTR_SHOW)) {\n problems.push(\n `<${root.localName}> is a row template's root and carries ` +\n `${ATTR_SHOW}; a row that should not show is left out by ` +\n `the query`,\n );\n }\n }\n }\n walkMarkup(\n content,\n isRowTemplate ? { query: scope!.query, row: true } : here,\n names,\n problems,\n );\n }\n }\n}\n\n/**\n * Ship every `lb-show` element already inside the template the hub keeps an\n * absent branch in, so nothing conditional shows until its value says so.\n * A page is in the document before its data arrives, and a value that has not\n * arrived is no value.\n *\n * Elements are collected before any is moved, and a wrapped element is still\n * reached once its outer one has gone into a template, because the references\n * are held.\n */\nfunction wrapShown(holder: HTMLTemplateElement): void {\n const doc = holder.ownerDocument;\n const shown: Element[] = [];\n const collect = (root: ParentNode): void => {\n shown.push(...root.querySelectorAll(`[${ATTR_SHOW}]`));\n for (const t of root.querySelectorAll(\"template\")) {\n collect((t as HTMLTemplateElement).content);\n }\n };\n collect(holder.content);\n for (const el of shown) {\n const parked = doc.createElement(\"template\");\n parked.setAttribute(ATTR_SHOW, el.getAttribute(ATTR_SHOW)!);\n el.replaceWith(parked);\n parked.content.append(el);\n }\n}\n\n/**\n * Expand one file's markup, naming the file if expansion refuses it.\n *\n * What comes back is the tree the browser will build, so every pass after\n * this reads and changes it in place, and it is serialized once, when it\n * ships.\n */\nfunction expandFile(\n file: string,\n source: string,\n defs: Definitions,\n): HTMLTemplateElement {\n try {\n return expandTree(source, defs);\n } catch (e) {\n throw new Error(`assemble: '${file}': ${(e as Error).message}`);\n }\n}\n\n/** Check one expanded fragment, and name the file if anything is wrong. */\nfunction checkMarkup(\n file: string,\n root: ParentNode,\n names: Names | null,\n): void {\n const problems: string[] = [];\n walkMarkup(root, null, names, problems);\n if (problems.length > 0) {\n throw new Error(`assemble: '${file}' markup:\\n ` + problems.join(`\\n `));\n }\n}\n\n/**\n * A page file's `<title>` names the page. It is lifted out, since a page is\n * a fragment inside `<main>` and a `<title>` belongs in a document's head,\n * and its text content is stamped on the page as ATTR_PAGE_TITLE.\n */\nfunction liftTitle(holder: HTMLTemplateElement): string | null {\n const title = holder.content.querySelector(\"title\");\n if (!title) return null;\n const text = title.textContent?.trim() ?? \"\";\n title.remove();\n return text;\n}\n\n/** An attribute value, escaped for a double-quoted attribute. */\nfunction attributeValue(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nexport interface AssembleOptions {\n chromeFile: string;\n pages: PageFile[];\n /** Every origin, already scanned, in cascade order — see build/origins.ts. */\n scans: OriginScan[];\n /**\n * What each page declares — see build/declared.ts. Without it, the names\n * `lb-query` and `lb-request` carry are not checked.\n */\n declared?: DeclaredPages;\n}\n\nexport interface Assembled {\n html: string;\n /** Every custom element tag left in the document once expansion is done. */\n usedTags: Set<string>;\n}\n\nexport async function assemble({\n chromeFile,\n pages,\n scans,\n declared,\n}: AssembleOptions): Promise<Assembled> {\n // One layer per origin, in order, so a later origin's definition overrides\n // an earlier one's for the same tag. Each layer is checked for cycles as it\n // lands, against everything merged so far.\n let defs: Definitions = {};\n for (const scan of scans) {\n defs = await addDefinitions(defs, scan.definitions);\n }\n\n // Tags are collected from each tree as it goes by. What ships is these\n // trees and the chrome around its body, which is collected on its own.\n const usedTags = new Set<string>();\n const templates: string[] = [];\n for (const { name, file } of pages) {\n const authored = await readFile(file, \"utf-8\");\n const host = expandFile(file, authored, defs);\n const title = liftTitle(host);\n checkPage(file, host.content);\n checkMarkup(\n file,\n host.content,\n declared ? { declared: declared.get(name)! } : null,\n );\n wrapShown(host);\n customElementTags(host.content, usedTags);\n const titled =\n title === null ? \"\" : ` ${ATTR_PAGE_TITLE}=\"${attributeValue(title)}\"`;\n templates.push(\n `<template ${ATTR_PAGE}=\"${name}\"${titled}>${host.innerHTML}</template>`,\n );\n }\n\n let chromeSource: string;\n try {\n chromeSource = await readFile(chromeFile, \"utf-8\");\n } catch {\n throw new Error(`assemble: no chrome file at '${chromeFile}'`);\n }\n\n const body = /<body([^>]*)>([\\s\\S]*)<\\/body>/i.exec(chromeSource);\n if (!body) {\n throw new Error(\n `assemble: '${chromeFile}' has no <body>...</body> to expand`,\n );\n }\n const [whole, bodyAttrs, bodyContent] = body;\n const chromeBody = expandFile(chromeFile, bodyContent!, defs);\n checkChrome(chromeFile, chromeBody.content);\n checkUnknownPageDialog(chromeFile, chromeBody.content);\n checkMarkup(\n chromeFile,\n chromeBody.content,\n declared ? { declared: null } : null,\n );\n wrapShown(chromeBody);\n customElementTags(chromeBody.content, usedTags);\n customElementTags(chromeSource.replace(whole!, \"\"), usedTags);\n const withPages = chromeSource.replace(\n whole!,\n () =>\n `<body${bodyAttrs}>${chromeBody.innerHTML}\\n${templates.join(\"\\n\")}\\n</body>`,\n );\n\n return { html: await formatHtml(withPages), usedTags };\n}\n"]}
@@ -7,7 +7,7 @@ export declare const ATTR_KEY_VALUE = "lb-key-value";
7
7
  export declare const ATTR_ROW_LIVE = "lb-row-live";
8
8
  export declare const LIVE_ROW = "[lb-row-live]";
9
9
  export declare const ATTR_QUERY_ROW_COUNT = "lb-query-row-count";
10
- export declare const ATTR_QUERY_UNSORTED_COUNT = "lb-query-unsorted-count";
10
+ export declare const ATTR_QUERY_UNPLACED_COUNT = "lb-query-unplaced-count";
11
11
  export declare const ATTR_QUERY_ORDER = "lb-query-order";
12
12
  export declare const ATTR_GROUP = "lb-group";
13
13
  export declare const ATTR_GROUP_LIVE = "lb-group-live";
@@ -25,6 +25,9 @@ export declare const COLUMN_TYPES: readonly ["number", "boolean", "text"];
25
25
  export declare const CHOICES_QUERY = "lb-choices";
26
26
  export declare const ATTR_ORDER = "lb-order";
27
27
  export declare const ATTR_FILTER = "lb-filter";
28
+ export declare const ATTR_MANUAL = "lb-manual";
29
+ export declare const MANUAL_ORDER = "order";
30
+ export declare const MANUAL_FILTER = "filter";
28
31
  export declare const FILTER_OPERATORS: readonly ["!=", "^=", "$=", "*=", "<=", ">=", "=", "<", ">"];
29
32
  export declare const ATTR_ROW_CREATED = "lb-row-created";
30
33
  export declare const ATTR_ROW_CHANGED = "lb-row-changed";
@@ -33,7 +36,7 @@ export declare const ATTR_ROW_REQUESTED = "lb-row-requested";
33
36
  export declare const REQUESTED_CREATED = "created";
34
37
  export declare const REQUESTED_CHANGED = "changed";
35
38
  export declare const REQUESTED_MOVED = "moved";
36
- export declare const ATTR_ROW_UNSORTED = "lb-row-unsorted";
39
+ export declare const ATTR_ROW_UNPLACED = "lb-row-unplaced";
37
40
  export declare const ATTR_ROW_LEAVING = "lb-row-leaving";
38
41
  export declare const ATTR_GROUP_LEAVING = "lb-group-leaving";
39
42
  export declare const ATTR_REQUEST = "lb-request";
@@ -46,8 +49,8 @@ export declare const ATTR_REQUEST_ERROR = "lb-request-error";
46
49
  export declare const COMMAND_EDIT = "--lb-edit";
47
50
  export declare const COMMAND_NEW = "--lb-new";
48
51
  export declare const COMMAND_RELEASE = "--lb-release";
49
- export declare const COMMAND_SORT = "--lb-sort";
50
- export declare const LB_COMMANDS: readonly ["--lb-edit", "--lb-new", "--lb-release", "--lb-sort"];
52
+ export declare const COMMAND_PLACE = "--lb-place";
53
+ export declare const LB_COMMANDS: readonly ["--lb-edit", "--lb-new", "--lb-release", "--lb-place"];
51
54
  export declare const LB_COMMAND_PREFIX = "--lb-";
52
55
  export declare const ATTR_ROW_EDITING = "lb-row-editing";
53
56
  export declare const ATTR_SELECT = "lb-select";
@@ -87,7 +90,7 @@ export declare const ATTR_EXP_SLOT = "lb-exp-slot";
87
90
  export declare const ATTR_EXP_TEMPLATE = "lb-exp-template";
88
91
  export declare const ATTR_PAGE = "lb-page";
89
92
  export declare const ATTR_PAGE_TITLE = "lb-page-title";
90
- export declare const DEVELOPER_ATTRIBUTES: readonly ["lb-query", "lb-column", "lb-show", "lb-group", "lb-count", "lb-sum", "lb-avg", "lb-min", "lb-max", "lb-order", "lb-filter", "lb-request", "lb-select", "lb-url-link", "lb-url-push", "lb-url-parm", "lb-url-unknown"];
93
+ export declare const DEVELOPER_ATTRIBUTES: readonly ["lb-query", "lb-column", "lb-show", "lb-group", "lb-count", "lb-sum", "lb-avg", "lb-min", "lb-max", "lb-order", "lb-filter", "lb-manual", "lb-request", "lb-select", "lb-url-link", "lb-url-push", "lb-url-parm", "lb-url-unknown"];
91
94
  export declare const HUB_TAG_NAME = "lb-hub";
92
95
  export declare const LB_ENDPOINT = "/lb";
93
96
  export declare const LB_REQUEST_TIMEOUT_MS = 10000;
@@ -1 +1 @@
1
- {"version":3,"file":"lb-constants.d.ts","sourceRoot":"","sources":["../../core/lb-constants.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lb-constants.d.ts","sourceRoot":"","sources":["../../core/lb-constants.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,UAAU,aAAa,CAAC;AAKrC,eAAO,MAAM,WAAW,cAAc,CAAC;AAavC,eAAO,MAAM,SAAS,YAAY,CAAC;AAInC,eAAO,MAAM,QAAQ,MAAM,CAAC;AAK5B,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAKnD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAM7C,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAI3C,eAAO,MAAM,QAAQ,kBAAuB,CAAC;AAK7C,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAKzD,eAAO,MAAM,yBAAyB,4BAA4B,CAAC;AAKnE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAajD,eAAO,MAAM,UAAU,aAAa,CAAC;AAIrC,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAI/C,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AACnD,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAGjD,eAAO,MAAM,UAAU,oBAAyB,CAAC;AAMjD,eAAO,MAAM,UAAU,aAAa,CAAC;AACrC,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,QAAQ,WAAW,CAAC;AAEjC,eAAO,MAAM,UAAU,+DAMb,CAAC;AAGX,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAKpC,eAAO,MAAM,YAAY,wCAAyC,CAAC;AAOnE,eAAO,MAAM,aAAa,eAAe,CAAC;AAK1C,eAAO,MAAM,UAAU,aAAa,CAAC;AAKrC,eAAO,MAAM,WAAW,cAAc,CAAC;AAOvC,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,aAAa,WAAW,CAAC;AAKtC,eAAO,MAAM,gBAAgB,8DAUnB,CAAC;AASX,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAGjD,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAIjD,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAK7C,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AACrD,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,eAAe,UAAU,CAAC;AAKvC,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAKnD,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AACjD,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAKrD,eAAO,MAAM,YAAY,eAAe,CAAC;AAIzC,eAAO,MAAM,aAAa,eAAe,CAAC;AAM1C,eAAO,MAAM,kBAAkB,oBAAoB,CAAC;AAIpD,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAMzD,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAIzD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAKrC,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAUrD,eAAO,MAAM,YAAY,cAAc,CAAC;AAGxC,eAAO,MAAM,WAAW,aAAa,CAAC;AAGtC,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAI9C,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,WAAW,kEAKd,CAAC;AAGX,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAIzC,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAMjD,eAAO,MAAM,WAAW,cAAc,CAAC;AAGvC,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAOnD,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAIxC,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAElD,eAAO,MAAM,eAAe,8DAIlB,CAAC;AAKX,eAAO,MAAM,UAAU,wEAKb,CAAC;AAIX,eAAO,MAAM,iBAAiB,oGAKpB,CAAC;AAGX,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,SAAS,SAAS,CAAC;AAKhC,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,eAAO,MAAM,eAAe,YAAY,CAAC;AACzC,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AACrD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAMzD,eAAO,MAAM,SAAS,WAAW,CAAC;AAGlC,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAIrD,eAAO,MAAM,uBAAuB,oBAAoB,CAAC;AAIzD,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAG3C,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAG/C,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAE3C,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAC1C,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,eAAO,MAAM,eAAe,WAAW,CAAC;AAExC,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAChD,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAC5C,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAG3C,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAI3C,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAK3C,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAG3C,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAMjD,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAK3C,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAGnD,eAAO,MAAM,SAAS,YAAY,CAAC;AAInC,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAK/C,eAAO,MAAM,oBAAoB,+OAevB,CAAC;AAQX,eAAO,MAAM,YAAY,WAAW,CAAC;AASrC,eAAO,MAAM,WAAW,QAAQ,CAAC;AAIjC,eAAO,MAAM,qBAAqB,QAAS,CAAC"}
@@ -49,9 +49,9 @@ export const LIVE_ROW = `[${ATTR_ROW_LIVE}]`;
49
49
  // conditional in every widget. A row a filter hides is not counted.
50
50
  export const ATTR_QUERY_ROW_COUNT = "lb-query-row-count";
51
51
  // Stamped by the hub beside ATTR_QUERY_ROW_COUNT: how many live rows stand
52
- // where the order would not put them, so a stylesheet shows a re-sort
53
- // control only while one would do something.
54
- export const ATTR_QUERY_UNSORTED_COUNT = "lb-query-unsorted-count";
52
+ // where the order or the filter would not leave them, so a stylesheet shows
53
+ // a control that places them only while one would do something.
54
+ export const ATTR_QUERY_UNPLACED_COUNT = "lb-query-unplaced-count";
55
55
  // Stamped by the hub beside ATTR_QUERY_ROW_COUNT: the order its rows are
56
56
  // placed by, the user's or else the server's, as an order's text, so a
57
57
  // widget or a stylesheet can show it. Absent when the rows have no order.
@@ -112,6 +112,14 @@ export const ATTR_ORDER = "lb-order";
112
112
  // may filter, separated by commas. The column of `lb-choices` of the same
113
113
  // name holds the filter, and a row it does not pass is `hidden`.
114
114
  export const ATTR_FILTER = "lb-filter";
115
+ // On an element naming a `rows` query: which placements wait for the user,
116
+ // `order`, `filter` or both, separated by spaces. A side not named is placed
117
+ // on every landing. A side named is placed when the page loads, when the
118
+ // user's order or filter changes, and on COMMAND_PLACE; an answer to a
119
+ // request leaves the rows on that side where they stand.
120
+ export const ATTR_MANUAL = "lb-manual";
121
+ export const MANUAL_ORDER = "order";
122
+ export const MANUAL_FILTER = "filter";
115
123
  // A filter's operators, written before each value: `^=Amazon`, or
116
124
  // `>=2026-01-01 <=2026-03-31` for a range. A value with none is `*=`. The
117
125
  // longer are listed first, which is the order they are read in.
@@ -145,10 +153,10 @@ export const ATTR_ROW_REQUESTED = "lb-row-requested";
145
153
  export const REQUESTED_CREATED = "created";
146
154
  export const REQUESTED_CHANGED = "changed";
147
155
  export const REQUESTED_MOVED = "moved";
148
- // The row stands where the order would not put it: an edit from inside its
149
- // list changed or created it, and the hub left it where the user was
150
- // working. Cleared when the rows are next placed by the order.
151
- export const ATTR_ROW_UNSORTED = "lb-row-unsorted";
156
+ // The row stands where the order or the filter would not leave it: an answer
157
+ // changed or created it in a list that places that side by hand, and the hub
158
+ // left it where it stood. Cleared when the rows are next placed.
159
+ export const ATTR_ROW_UNPLACED = "lb-row-unplaced";
152
160
  // A row or a group on its way out. It is no longer live, takes no input, and
153
161
  // is removed once the animations running on it have finished, at once when
154
162
  // there are none.
@@ -185,7 +193,7 @@ export const ATTR_REQUEST_ERROR = "lb-request-error";
185
193
  // One form edits any row of its query, or enters a new one. A button points
186
194
  // it with HTML's own `commandfor="<form id>"` and one of these commands,
187
195
  // which HTML requires to begin with `--`. The hub hears the `command` event
188
- // on the form. COMMAND_SORT, the last of them, is for a list, not a form.
196
+ // on the form. COMMAND_PLACE, the last of them, is for a list, not a form.
189
197
  // From a button in a live row of the form's query: fill the form from that
190
198
  // row, as the hub holds it, and key it by that row.
191
199
  export const COMMAND_EDIT = "--lb-edit";
@@ -194,13 +202,13 @@ export const COMMAND_NEW = "--lb-new";
194
202
  // From any button: let the form go without saving.
195
203
  export const COMMAND_RELEASE = "--lb-release";
196
204
  // From any button, for an element carrying `lb-query` rather than a form:
197
- // place its rows by the order, from the rows the hub holds.
198
- export const COMMAND_SORT = "--lb-sort";
205
+ // place its rows by the order and the filter, from the rows the hub holds.
206
+ export const COMMAND_PLACE = "--lb-place";
199
207
  export const LB_COMMANDS = [
200
208
  COMMAND_EDIT,
201
209
  COMMAND_NEW,
202
210
  COMMAND_RELEASE,
203
- COMMAND_SORT,
211
+ COMMAND_PLACE,
204
212
  ];
205
213
  // Loadbare owns every command beginning with this prefix.
206
214
  export const LB_COMMAND_PREFIX = "--lb-";
@@ -318,6 +326,7 @@ export const DEVELOPER_ATTRIBUTES = [
318
326
  ...AGGREGATES,
319
327
  ATTR_ORDER,
320
328
  ATTR_FILTER,
329
+ ATTR_MANUAL,
321
330
  ATTR_REQUEST,
322
331
  ATTR_SELECT,
323
332
  ATTR_URL_LINK,
@@ -1 +1 @@
1
- {"version":3,"file":"lb-constants.js","sourceRoot":"","sources":["../../core/lb-constants.ts"],"names":[],"mappings":"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","sourcesContent":["// Every Loadbare attribute name lives here. Nothing writes one as a string\n// literal — not a widget, not a page host, not a test. See\n// docs/reference/data-binding.md.\n\n// --- Landing (docs/reference/data-binding.md) ----------------------------\n// Everything is a query. The server answers every request with response\n// items, one per query, and each carries the query's kind and key. The\n// markup names a query and the columns it shows; it never repeats what the\n// server already declared.\n\n// Names the query whose rows land in an element's content. A nested one\n// begins a new query: what is inside it is that query's.\nexport const ATTR_QUERY = \"lb-query\";\n\n// The column an element shows, read from the nearest ancestor row. On a\n// control the hub sets its value, and gathers it back under this name when\n// the control's request is issued.\nexport const ATTR_COLUMN = \"lb-column\";\n\n// The column that decides whether an element is present: `null` and `false`\n// are off, and every other value is on. It reads from the nearest ancestor\n// row, as ATTR_COLUMN does.\n//\n// An element that is off is moved into a `<template>` carrying this attribute\n// and the same column, standing where the element stood, and moved back out\n// when the column turns on. The builder ships every such element already\n// inside its template. A developer writes this attribute on an element and\n// never on a template: the template form is Loadbare's, and holds the absent\n// branch in the document so the hub holds nothing. Landing reaches inside it,\n// so a branch that returns is already current; nothing else does.\nexport const ATTR_SHOW = \"lb-show\";\n\n// Written before the column in ATTR_SHOW, it reverses the condition:\n// `lb-show=\"!chosen\"` is present while `chosen` is null or false.\nexport const SHOW_NOT = \"!\";\n\n// Stamped by the hub on every element it sets from a column: the value it\n// set, so a stylesheet can select on it and a custom element that is not a\n// control can render it.\nexport const ATTR_COLUMN_VALUE = \"lb-column-value\";\n\n// Stamped by the hub on each live row, and on an element a `row` lands on\n// itself: the row's key. The key column is the query's, declared by the\n// server and carried by every response item.\nexport const ATTR_KEY_VALUE = \"lb-key-value\";\n\n// Stamped by the hub on each live row, and on nothing else: the element it\n// cloned from a row template. A key alone does not say so, because an\n// element a `row` lands on carries one too, and a live row may name a query\n// of its own, so neither the key nor `lb-query` tells the two apart.\nexport const ATTR_ROW_LIVE = \"lb-row-live\";\n\n// Selects a live row. Anything that walks rows — reconciliation, gathering,\n// a custom element's own placement — finds them with this and nothing else.\nexport const LIVE_ROW = `[${ATTR_ROW_LIVE}]`;\n\n// Stamped by the hub on an element with a row template: how many live rows\n// it shows, so \"no members yet\" is a stylesheet rule rather than a\n// conditional in every widget. A row a filter hides is not counted.\nexport const ATTR_QUERY_ROW_COUNT = \"lb-query-row-count\";\n\n// Stamped by the hub beside ATTR_QUERY_ROW_COUNT: how many live rows stand\n// where the order would not put them, so a stylesheet shows a re-sort\n// control only while one would do something.\nexport const ATTR_QUERY_UNSORTED_COUNT = \"lb-query-unsorted-count\";\n\n// Stamped by the hub beside ATTR_QUERY_ROW_COUNT: the order its rows are\n// placed by, the user's or else the server's, as an order's text, so a\n// widget or a stylesheet can show it. Absent when the rows have no order.\nexport const ATTR_QUERY_ORDER = \"lb-query-order\";\n\n// --- Order and groups (docs/reference/data-binding.md) -------------------\n// A `rows` query's order is a rule over its columns, and the hub places\n// live rows by it, except that an edit from inside a list leaves that list's\n// rows where they stand. A group is a run of rows sharing the order's leading term.\n\n// On a `<template>` inside an element naming a query: a group template. Its\n// content holds the group's heading and exactly one nested `<template>`,\n// which is where the group's contents go: the next group template, or, at\n// the innermost level, the row template. The nth group template breaks on\n// the order's nth term. The markup's nesting decides whether the contents\n// land inside the heading's element or beside it.\nexport const ATTR_GROUP = \"lb-group\";\n\n// Stamped by the hub on each top-level element of a group it built, and on\n// nothing else, as ATTR_ROW_LIVE is on a live row.\nexport const ATTR_GROUP_LIVE = \"lb-group-live\";\n\n// Stamped beside ATTR_GROUP_LIVE: the column the group breaks on, and its\n// value there.\nexport const ATTR_GROUP_COLUMN = \"lb-group-column\";\nexport const ATTR_GROUP_VALUE = \"lb-group-value\";\n\n// Selects a group's element, as LIVE_ROW selects a live row.\nexport const LIVE_GROUP = `[${ATTR_GROUP_LIVE}]`;\n\n// Aggregates, written on any element in a group template or in the element\n// naming the query: the hub sets the element from the rows of the nearest\n// group around it, or of the whole list outside any group. `lb-count` takes\n// no value; the others name the column they aggregate.\nexport const ATTR_COUNT = \"lb-count\";\nexport const ATTR_SUM = \"lb-sum\";\nexport const ATTR_AVG = \"lb-avg\";\nexport const ATTR_MIN = \"lb-min\";\nexport const ATTR_MAX = \"lb-max\";\n\nexport const AGGREGATES = [\n ATTR_COUNT,\n ATTR_SUM,\n ATTR_AVG,\n ATTR_MIN,\n ATTR_MAX,\n] as const;\n\n// Written before a column in an order, it sorts that column descending.\nexport const ORDER_DESCENDING = \"-\";\n\n// The types a `rows` query may declare for its columns. Sorting, filtering,\n// `lb-min` and `lb-max` read a declared column as its type rather than by\n// the JSON type its values arrive as.\nexport const COLUMN_TYPES = [\"number\", \"boolean\", \"text\"] as const;\n\n// --- Choices (docs/reference/data-binding.md) -----------------------------\n// What the user chose for how rows show: an order, a filter. The hub serves\n// them as its own query, one row keyed by the path, with a column per choice,\n// and any control inside `lb-query=\"lb-choices\"` writes one with\n// `lb-row-update`. They hold until the page changes.\nexport const CHOICES_QUERY = \"lb-choices\";\n\n// On an element naming a `rows` query: the column of `lb-choices` holding the\n// user's order for its rows, as an order's text. While that column is empty,\n// the order the server declared places them.\nexport const ATTR_ORDER = \"lb-order\";\n\n// On an element naming a `rows` query: the columns of its rows that a choice\n// may filter, separated by commas. The column of `lb-choices` of the same\n// name holds the filter, and a row it does not pass is `hidden`.\nexport const ATTR_FILTER = \"lb-filter\";\n\n// A filter's operators, written before each value: `^=Amazon`, or\n// `>=2026-01-01 <=2026-03-31` for a range. A value with none is `*=`. The\n// longer are listed first, which is the order they are read in.\nexport const FILTER_OPERATORS = [\n \"!=\",\n \"^=\",\n \"$=\",\n \"*=\",\n \"<=\",\n \">=\",\n \"=\",\n \"<\",\n \">\",\n] as const;\n\n// --- What happened to a row (docs/reference/data-binding.md) ------------\n// Every change the hub makes to a list is one a stylesheet can see, so an\n// application animates with CSS alone. The first three are cleared when the\n// hub next touches the row, and a stamp applied again is removed and added\n// as two changes, so an animation keyed to it plays again.\n\n// The row was created when the hub last touched it.\nexport const ATTR_ROW_CREATED = \"lb-row-created\";\n\n// The row's values changed when the hub last touched it.\nexport const ATTR_ROW_CHANGED = \"lb-row-changed\";\n\n// The row moved when the hub last touched it: its values changed, and the\n// order put it somewhere else among the rows whose values did not.\nexport const ATTR_ROW_MOVED = \"lb-row-moved\";\n\n// What a request from this page did to the row: one of the three values\n// below. Cleared at every landing of the row's query, so a script reading it\n// after a landing reads only what that landing did.\nexport const ATTR_ROW_REQUESTED = \"lb-row-requested\";\nexport const REQUESTED_CREATED = \"created\";\nexport const REQUESTED_CHANGED = \"changed\";\nexport const REQUESTED_MOVED = \"moved\";\n\n// The row stands where the order would not put it: an edit from inside its\n// list changed or created it, and the hub left it where the user was\n// working. Cleared when the rows are next placed by the order.\nexport const ATTR_ROW_UNSORTED = \"lb-row-unsorted\";\n\n// A row or a group on its way out. It is no longer live, takes no input, and\n// is removed once the animations running on it have finished, at once when\n// there are none.\nexport const ATTR_ROW_LEAVING = \"lb-row-leaving\";\nexport const ATTR_GROUP_LEAVING = \"lb-group-leaving\";\n\n// --- Requests (docs/reference/data-binding.md) --------------------------\n// Names the request an element issues when it commits: a form on submit, a\n// control on change, anything else on click.\nexport const ATTR_REQUEST = \"lb-request\";\n\n// Every request travels as one bubbling event of this name, whoever issued\n// it, so an ancestor may stop it.\nexport const LB_EVENT_NAME = \"lb-request\";\n\n// The counterpart of LB_EVENT_NAME: raised on the element that committed,\n// once what the request brought back has landed or the round trip has\n// failed. It bubbles, so the element that cares about the outcome need not\n// be the one that committed.\nexport const LB_DONE_EVENT_NAME = \"lb-request-done\";\n\n// Stamped on the element that issued a request while its round trip is in\n// flight, alongside aria-busy. A commit on an element carrying it is ignored.\nexport const ATTR_REQUEST_PENDING = \"lb-request-pending\";\n\n// Stamped on the element that issued a request when its handler refused it:\n// the refusal's message for the request as a whole, empty when it has none.\n// Cleared at the start of that element's next request. A refusal is not a\n// failure, and does not stamp ATTR_REQUEST_ERROR.\nexport const ATTR_REQUEST_REFUSED = \"lb-request-refused\";\n\n// The status a refusal travels with. Every other failure is a 500 with no\n// body, so nothing but a refusal's own words reaches the browser.\nexport const LB_REFUSAL_STATUS = 422;\n\n// Stamped on the element that issued a request when its round trip failed —\n// a non-2xx response, a thrown application error, or a timeout, all alike.\n// Cleared at the start of that element's next request.\nexport const ATTR_REQUEST_ERROR = \"lb-request-error\";\n\n// --- A form pointed at a row (docs/reference/data-binding.md) -----------\n// One form edits any row of its query, or enters a new one. A button points\n// it with HTML's own `commandfor=\"<form id>\"` and one of these commands,\n// which HTML requires to begin with `--`. The hub hears the `command` event\n// on the form. COMMAND_SORT, the last of them, is for a list, not a form.\n\n// From a button in a live row of the form's query: fill the form from that\n// row, as the hub holds it, and key it by that row.\nexport const COMMAND_EDIT = \"--lb-edit\";\n\n// From any button: start the form empty, for an insert.\nexport const COMMAND_NEW = \"--lb-new\";\n\n// From any button: let the form go without saving.\nexport const COMMAND_RELEASE = \"--lb-release\";\n\n// From any button, for an element carrying `lb-query` rather than a form:\n// place its rows by the order, from the rows the hub holds.\nexport const COMMAND_SORT = \"--lb-sort\";\n\nexport const LB_COMMANDS = [\n COMMAND_EDIT,\n COMMAND_NEW,\n COMMAND_RELEASE,\n COMMAND_SORT,\n] as const;\n\n// Loadbare owns every command beginning with this prefix.\nexport const LB_COMMAND_PREFIX = \"--lb-\";\n\n// Stamped by the hub on the live row a form is pointed at, until the form\n// lets go of it.\nexport const ATTR_ROW_EDITING = \"lb-row-editing\";\n\n// --- Selecting rows (docs/reference/data-binding.md) ---------------------\n// On a checkbox in a row template: ticking it selects the live row it sits\n// in. It is not a column and is not gathered as one. A request for the\n// row's query that names no one row carries the keys of every row selected.\nexport const ATTR_SELECT = \"lb-select\";\n\n// Stamped by the hub on a live row while its `lb-select` checkbox is ticked.\nexport const ATTR_ROW_SELECTED = \"lb-row-selected\";\n\n// --- Reserved names ----------------------------------------------------\n// Loadbare owns every name beginning with this prefix: attribute names, the\n// values of its attributes, query names, request names, the column names of\n// its own queries, custom element names and event names. The server refuses\n// a page that declares a query or a request so named.\nexport const LB_RESERVED_PREFIX = \"lb-\";\n\n// The requests Loadbare provides. Each runs the page's crud declaration for\n// the request's query.\nexport const REQUEST_ROW_INSERT = \"lb-row-insert\";\nexport const REQUEST_ROW_UPDATE = \"lb-row-update\";\nexport const REQUEST_ROW_DELETE = \"lb-row-delete\";\n\nexport const LB_ROW_REQUESTS = [\n REQUEST_ROW_INSERT,\n REQUEST_ROW_UPDATE,\n REQUEST_ROW_DELETE,\n] as const;\n\n// Loadbare also owns every method name on a custom element that begins with\n// `lb` and a capital. These are the ones it calls (the HubLifecycle interface\n// in core/lb-types.ts); the builder refuses a script that declares any other.\nexport const LB_METHODS = [\n \"lbAttached\",\n \"lbRowsLanded\",\n \"lbRequestDone\",\n \"lbDetached\",\n] as const;\n\n// The browser's lifecycle callbacks, which the hub's methods replace. The\n// builder refuses a script that declares any of them.\nexport const BROWSER_LIFECYCLE = [\n \"connectedCallback\",\n \"disconnectedCallback\",\n \"adoptedCallback\",\n \"connectedMoveCallback\",\n] as const;\n\n// --- Kinds --------------------------------------------------------------\nexport const KIND_ROW = \"row\";\nexport const KIND_ROWS = \"rows\";\n\n// --- The URL (docs/reference/chrome.md) ---------------------------------\n// The query the hub serves: one row, keyed by the path, whose other columns\n// are the query parms.\nexport const URL_QUERY = \"lb-url\";\nexport const URL_COLUMN_PATH = \"lb-path\";\nexport const URL_COLUMN_PAGE_LABEL = \"lb-page-label\";\nexport const URL_COLUMN_PAGE_UNKNOWN = \"lb-page-unknown\";\n\n// --- Round trips (docs/reference/chrome.md) ------------------------------\n// The query the hub serves with its own state: one row, keyed by the path,\n// telling whether the page's data arrived and whether the server answers.\n// The hub stamps the same columns on `<lb-hub>` itself, for a stylesheet.\nexport const HUB_QUERY = \"lb-hub\";\n\n// `loading`, `loaded` or `failed`: the page load for the URL showing.\nexport const HUB_COLUMN_LOAD_STATE = \"lb-load-state\";\n\n// `reachable`, `failing` or `unreachable`: how the latest round trip of any\n// kind went. Empty until the first one returns.\nexport const HUB_COLUMN_SERVER_STATE = \"lb-server-state\";\n\n// Empty, or why the latest round trip failed: HUB_ERROR_NETWORK,\n// HUB_ERROR_TIMEOUT, or the HTTP status the server answered with.\nexport const HUB_COLUMN_ERROR = \"lb-error\";\n\n// How many round trips are in flight.\nexport const HUB_COLUMN_PENDING = \"lb-pending\";\n\n// When rows last came from the server, as an ISO timestamp.\nexport const HUB_COLUMN_AS_OF = \"lb-as-of\";\n\nexport const HUB_LOAD_LOADING = \"loading\";\nexport const HUB_LOAD_LOADED = \"loaded\";\nexport const HUB_LOAD_FAILED = \"failed\";\n\nexport const HUB_SERVER_REACHABLE = \"reachable\";\nexport const HUB_SERVER_FAILING = \"failing\";\nexport const HUB_SERVER_UNREACHABLE = \"unreachable\";\n\nexport const HUB_ERROR_NETWORK = \"network\";\nexport const HUB_ERROR_TIMEOUT = \"timeout\";\n\n// On an `<a>`: a plain primary click sets `lb-path` from the `href`.\nexport const ATTR_URL_LINK = \"lb-url-link\";\n\n// On an element with `lb-request`: its update of `lb-url` pushes a history\n// entry instead of replacing one.\nexport const ATTR_URL_PUSH = \"lb-url-push\";\n\n// On an `<a>` carrying ATTR_URL_LINK: columns of the row around it, separated\n// by commas, each added to the `href`'s query string as the parm of the same\n// name.\nexport const ATTR_URL_PARM = \"lb-url-parm\";\n\n// On a `<dialog>`: the hub calls showModal() when `lb-page-unknown` is true.\nexport const ATTR_URL_UNKNOWN = \"lb-url-unknown\";\n\n// --- Build time (docs/reference/custom-elements.md) ---------------------\n// Marks the element in an element file whose children receive the rest of\n// the custom element's content. An attribute rather than an element because\n// HTML content models discard foreign elements inside <select> and <table>.\nexport const ATTR_EXP_SLOT = \"lb-exp-slot\";\n\n// One name in two positions. In an element file it marks a destination; on a\n// `<template>` in the custom element's content it names the destination\n// that template is for, and the template's content moves into it.\nexport const ATTR_EXP_TEMPLATE = \"lb-exp-template\";\n\n// A page ships as <template lb-page=\"<stub>\">.\nexport const ATTR_PAGE = \"lb-page\";\n\n// Stamped by the builder beside ATTR_PAGE: the text content of the page\n// file's `<title>`, which the builder removes.\nexport const ATTR_PAGE_TITLE = \"lb-page-title\";\n\n// The attributes a developer writes. The builder refuses any other `lb-`\n// attribute in markup: the rest are stamps, written by the hub or the\n// builder and never by hand or by script.\nexport const DEVELOPER_ATTRIBUTES = [\n ATTR_QUERY,\n ATTR_COLUMN,\n ATTR_SHOW,\n ATTR_GROUP,\n ...AGGREGATES,\n ATTR_ORDER,\n ATTR_FILTER,\n ATTR_REQUEST,\n ATTR_SELECT,\n ATTR_URL_LINK,\n ATTR_URL_PUSH,\n ATTR_URL_PARM,\n ATTR_URL_UNKNOWN,\n] as const;\n\n// The hub's own tag. It is exempt from the rule every other LB-* tag\n// follows: expansion does not require it to have a definition (build/expand.ts),\n// and the client build does not require it to have a script of its own\n// (build/elements.ts) — it is the framework's live element, always present,\n// registered once by the package's main entry point, not a widget an\n// application discovers or declares.\nexport const HUB_TAG_NAME = \"lb-hub\";\n\n// --- Wire --------------------------------------------------------------\n// One path, one method: everything the hub asks of the server is a POST\n// below this path. The page's stub follows it, and the query string the\n// browser is showing rides after that verbatim, so `/accounts?acct=23` asks\n// as `POST /lb/accounts?acct=23` and the server always knows what URL the\n// browser is showing. Navigation is therefore the only GET an application\n// serves, which is what leaves the page name space unrestricted.\nexport const LB_ENDPOINT = \"/lb\";\n\n// A client-side deadline for one round trip. fetch() has no deadline of its\n// own; past this the request is aborted and treated as a failure.\nexport const LB_REQUEST_TIMEOUT_MS = 10_000;\n"]}
1
+ {"version":3,"file":"lb-constants.js","sourceRoot":"","sources":["../../core/lb-constants.ts"],"names":[],"mappings":"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","sourcesContent":["// Every Loadbare attribute name lives here. Nothing writes one as a string\n// literal — not a widget, not a page host, not a test. See\n// docs/reference/data-binding.md.\n\n// --- Landing (docs/reference/data-binding.md) ----------------------------\n// Everything is a query. The server answers every request with response\n// items, one per query, and each carries the query's kind and key. The\n// markup names a query and the columns it shows; it never repeats what the\n// server already declared.\n\n// Names the query whose rows land in an element's content. A nested one\n// begins a new query: what is inside it is that query's.\nexport const ATTR_QUERY = \"lb-query\";\n\n// The column an element shows, read from the nearest ancestor row. On a\n// control the hub sets its value, and gathers it back under this name when\n// the control's request is issued.\nexport const ATTR_COLUMN = \"lb-column\";\n\n// The column that decides whether an element is present: `null` and `false`\n// are off, and every other value is on. It reads from the nearest ancestor\n// row, as ATTR_COLUMN does.\n//\n// An element that is off is moved into a `<template>` carrying this attribute\n// and the same column, standing where the element stood, and moved back out\n// when the column turns on. The builder ships every such element already\n// inside its template. A developer writes this attribute on an element and\n// never on a template: the template form is Loadbare's, and holds the absent\n// branch in the document so the hub holds nothing. Landing reaches inside it,\n// so a branch that returns is already current; nothing else does.\nexport const ATTR_SHOW = \"lb-show\";\n\n// Written before the column in ATTR_SHOW, it reverses the condition:\n// `lb-show=\"!chosen\"` is present while `chosen` is null or false.\nexport const SHOW_NOT = \"!\";\n\n// Stamped by the hub on every element it sets from a column: the value it\n// set, so a stylesheet can select on it and a custom element that is not a\n// control can render it.\nexport const ATTR_COLUMN_VALUE = \"lb-column-value\";\n\n// Stamped by the hub on each live row, and on an element a `row` lands on\n// itself: the row's key. The key column is the query's, declared by the\n// server and carried by every response item.\nexport const ATTR_KEY_VALUE = \"lb-key-value\";\n\n// Stamped by the hub on each live row, and on nothing else: the element it\n// cloned from a row template. A key alone does not say so, because an\n// element a `row` lands on carries one too, and a live row may name a query\n// of its own, so neither the key nor `lb-query` tells the two apart.\nexport const ATTR_ROW_LIVE = \"lb-row-live\";\n\n// Selects a live row. Anything that walks rows — reconciliation, gathering,\n// a custom element's own placement — finds them with this and nothing else.\nexport const LIVE_ROW = `[${ATTR_ROW_LIVE}]`;\n\n// Stamped by the hub on an element with a row template: how many live rows\n// it shows, so \"no members yet\" is a stylesheet rule rather than a\n// conditional in every widget. A row a filter hides is not counted.\nexport const ATTR_QUERY_ROW_COUNT = \"lb-query-row-count\";\n\n// Stamped by the hub beside ATTR_QUERY_ROW_COUNT: how many live rows stand\n// where the order or the filter would not leave them, so a stylesheet shows\n// a control that places them only while one would do something.\nexport const ATTR_QUERY_UNPLACED_COUNT = \"lb-query-unplaced-count\";\n\n// Stamped by the hub beside ATTR_QUERY_ROW_COUNT: the order its rows are\n// placed by, the user's or else the server's, as an order's text, so a\n// widget or a stylesheet can show it. Absent when the rows have no order.\nexport const ATTR_QUERY_ORDER = \"lb-query-order\";\n\n// --- Order and groups (docs/reference/data-binding.md) -------------------\n// A `rows` query's order is a rule over its columns, and the hub places\n// live rows by it, except that an edit from inside a list leaves that list's\n// rows where they stand. A group is a run of rows sharing the order's leading term.\n\n// On a `<template>` inside an element naming a query: a group template. Its\n// content holds the group's heading and exactly one nested `<template>`,\n// which is where the group's contents go: the next group template, or, at\n// the innermost level, the row template. The nth group template breaks on\n// the order's nth term. The markup's nesting decides whether the contents\n// land inside the heading's element or beside it.\nexport const ATTR_GROUP = \"lb-group\";\n\n// Stamped by the hub on each top-level element of a group it built, and on\n// nothing else, as ATTR_ROW_LIVE is on a live row.\nexport const ATTR_GROUP_LIVE = \"lb-group-live\";\n\n// Stamped beside ATTR_GROUP_LIVE: the column the group breaks on, and its\n// value there.\nexport const ATTR_GROUP_COLUMN = \"lb-group-column\";\nexport const ATTR_GROUP_VALUE = \"lb-group-value\";\n\n// Selects a group's element, as LIVE_ROW selects a live row.\nexport const LIVE_GROUP = `[${ATTR_GROUP_LIVE}]`;\n\n// Aggregates, written on any element in a group template or in the element\n// naming the query: the hub sets the element from the rows of the nearest\n// group around it, or of the whole list outside any group. `lb-count` takes\n// no value; the others name the column they aggregate.\nexport const ATTR_COUNT = \"lb-count\";\nexport const ATTR_SUM = \"lb-sum\";\nexport const ATTR_AVG = \"lb-avg\";\nexport const ATTR_MIN = \"lb-min\";\nexport const ATTR_MAX = \"lb-max\";\n\nexport const AGGREGATES = [\n ATTR_COUNT,\n ATTR_SUM,\n ATTR_AVG,\n ATTR_MIN,\n ATTR_MAX,\n] as const;\n\n// Written before a column in an order, it sorts that column descending.\nexport const ORDER_DESCENDING = \"-\";\n\n// The types a `rows` query may declare for its columns. Sorting, filtering,\n// `lb-min` and `lb-max` read a declared column as its type rather than by\n// the JSON type its values arrive as.\nexport const COLUMN_TYPES = [\"number\", \"boolean\", \"text\"] as const;\n\n// --- Choices (docs/reference/data-binding.md) -----------------------------\n// What the user chose for how rows show: an order, a filter. The hub serves\n// them as its own query, one row keyed by the path, with a column per choice,\n// and any control inside `lb-query=\"lb-choices\"` writes one with\n// `lb-row-update`. They hold until the page changes.\nexport const CHOICES_QUERY = \"lb-choices\";\n\n// On an element naming a `rows` query: the column of `lb-choices` holding the\n// user's order for its rows, as an order's text. While that column is empty,\n// the order the server declared places them.\nexport const ATTR_ORDER = \"lb-order\";\n\n// On an element naming a `rows` query: the columns of its rows that a choice\n// may filter, separated by commas. The column of `lb-choices` of the same\n// name holds the filter, and a row it does not pass is `hidden`.\nexport const ATTR_FILTER = \"lb-filter\";\n\n// On an element naming a `rows` query: which placements wait for the user,\n// `order`, `filter` or both, separated by spaces. A side not named is placed\n// on every landing. A side named is placed when the page loads, when the\n// user's order or filter changes, and on COMMAND_PLACE; an answer to a\n// request leaves the rows on that side where they stand.\nexport const ATTR_MANUAL = \"lb-manual\";\nexport const MANUAL_ORDER = \"order\";\nexport const MANUAL_FILTER = \"filter\";\n\n// A filter's operators, written before each value: `^=Amazon`, or\n// `>=2026-01-01 <=2026-03-31` for a range. A value with none is `*=`. The\n// longer are listed first, which is the order they are read in.\nexport const FILTER_OPERATORS = [\n \"!=\",\n \"^=\",\n \"$=\",\n \"*=\",\n \"<=\",\n \">=\",\n \"=\",\n \"<\",\n \">\",\n] as const;\n\n// --- What happened to a row (docs/reference/data-binding.md) ------------\n// Every change the hub makes to a list is one a stylesheet can see, so an\n// application animates with CSS alone. The first three are cleared when the\n// hub next touches the row, and a stamp applied again is removed and added\n// as two changes, so an animation keyed to it plays again.\n\n// The row was created when the hub last touched it.\nexport const ATTR_ROW_CREATED = \"lb-row-created\";\n\n// The row's values changed when the hub last touched it.\nexport const ATTR_ROW_CHANGED = \"lb-row-changed\";\n\n// The row moved when the hub last touched it: its values changed, and the\n// order put it somewhere else among the rows whose values did not.\nexport const ATTR_ROW_MOVED = \"lb-row-moved\";\n\n// What a request from this page did to the row: one of the three values\n// below. Cleared at every landing of the row's query, so a script reading it\n// after a landing reads only what that landing did.\nexport const ATTR_ROW_REQUESTED = \"lb-row-requested\";\nexport const REQUESTED_CREATED = \"created\";\nexport const REQUESTED_CHANGED = \"changed\";\nexport const REQUESTED_MOVED = \"moved\";\n\n// The row stands where the order or the filter would not leave it: an answer\n// changed or created it in a list that places that side by hand, and the hub\n// left it where it stood. Cleared when the rows are next placed.\nexport const ATTR_ROW_UNPLACED = \"lb-row-unplaced\";\n\n// A row or a group on its way out. It is no longer live, takes no input, and\n// is removed once the animations running on it have finished, at once when\n// there are none.\nexport const ATTR_ROW_LEAVING = \"lb-row-leaving\";\nexport const ATTR_GROUP_LEAVING = \"lb-group-leaving\";\n\n// --- Requests (docs/reference/data-binding.md) --------------------------\n// Names the request an element issues when it commits: a form on submit, a\n// control on change, anything else on click.\nexport const ATTR_REQUEST = \"lb-request\";\n\n// Every request travels as one bubbling event of this name, whoever issued\n// it, so an ancestor may stop it.\nexport const LB_EVENT_NAME = \"lb-request\";\n\n// The counterpart of LB_EVENT_NAME: raised on the element that committed,\n// once what the request brought back has landed or the round trip has\n// failed. It bubbles, so the element that cares about the outcome need not\n// be the one that committed.\nexport const LB_DONE_EVENT_NAME = \"lb-request-done\";\n\n// Stamped on the element that issued a request while its round trip is in\n// flight, alongside aria-busy. A commit on an element carrying it is ignored.\nexport const ATTR_REQUEST_PENDING = \"lb-request-pending\";\n\n// Stamped on the element that issued a request when its handler refused it:\n// the refusal's message for the request as a whole, empty when it has none.\n// Cleared at the start of that element's next request. A refusal is not a\n// failure, and does not stamp ATTR_REQUEST_ERROR.\nexport const ATTR_REQUEST_REFUSED = \"lb-request-refused\";\n\n// The status a refusal travels with. Every other failure is a 500 with no\n// body, so nothing but a refusal's own words reaches the browser.\nexport const LB_REFUSAL_STATUS = 422;\n\n// Stamped on the element that issued a request when its round trip failed —\n// a non-2xx response, a thrown application error, or a timeout, all alike.\n// Cleared at the start of that element's next request.\nexport const ATTR_REQUEST_ERROR = \"lb-request-error\";\n\n// --- A form pointed at a row (docs/reference/data-binding.md) -----------\n// One form edits any row of its query, or enters a new one. A button points\n// it with HTML's own `commandfor=\"<form id>\"` and one of these commands,\n// which HTML requires to begin with `--`. The hub hears the `command` event\n// on the form. COMMAND_PLACE, the last of them, is for a list, not a form.\n\n// From a button in a live row of the form's query: fill the form from that\n// row, as the hub holds it, and key it by that row.\nexport const COMMAND_EDIT = \"--lb-edit\";\n\n// From any button: start the form empty, for an insert.\nexport const COMMAND_NEW = \"--lb-new\";\n\n// From any button: let the form go without saving.\nexport const COMMAND_RELEASE = \"--lb-release\";\n\n// From any button, for an element carrying `lb-query` rather than a form:\n// place its rows by the order and the filter, from the rows the hub holds.\nexport const COMMAND_PLACE = \"--lb-place\";\n\nexport const LB_COMMANDS = [\n COMMAND_EDIT,\n COMMAND_NEW,\n COMMAND_RELEASE,\n COMMAND_PLACE,\n] as const;\n\n// Loadbare owns every command beginning with this prefix.\nexport const LB_COMMAND_PREFIX = \"--lb-\";\n\n// Stamped by the hub on the live row a form is pointed at, until the form\n// lets go of it.\nexport const ATTR_ROW_EDITING = \"lb-row-editing\";\n\n// --- Selecting rows (docs/reference/data-binding.md) ---------------------\n// On a checkbox in a row template: ticking it selects the live row it sits\n// in. It is not a column and is not gathered as one. A request for the\n// row's query that names no one row carries the keys of every row selected.\nexport const ATTR_SELECT = \"lb-select\";\n\n// Stamped by the hub on a live row while its `lb-select` checkbox is ticked.\nexport const ATTR_ROW_SELECTED = \"lb-row-selected\";\n\n// --- Reserved names ----------------------------------------------------\n// Loadbare owns every name beginning with this prefix: attribute names, the\n// values of its attributes, query names, request names, the column names of\n// its own queries, custom element names and event names. The server refuses\n// a page that declares a query or a request so named.\nexport const LB_RESERVED_PREFIX = \"lb-\";\n\n// The requests Loadbare provides. Each runs the page's crud declaration for\n// the request's query.\nexport const REQUEST_ROW_INSERT = \"lb-row-insert\";\nexport const REQUEST_ROW_UPDATE = \"lb-row-update\";\nexport const REQUEST_ROW_DELETE = \"lb-row-delete\";\n\nexport const LB_ROW_REQUESTS = [\n REQUEST_ROW_INSERT,\n REQUEST_ROW_UPDATE,\n REQUEST_ROW_DELETE,\n] as const;\n\n// Loadbare also owns every method name on a custom element that begins with\n// `lb` and a capital. These are the ones it calls (the HubLifecycle interface\n// in core/lb-types.ts); the builder refuses a script that declares any other.\nexport const LB_METHODS = [\n \"lbAttached\",\n \"lbRowsLanded\",\n \"lbRequestDone\",\n \"lbDetached\",\n] as const;\n\n// The browser's lifecycle callbacks, which the hub's methods replace. The\n// builder refuses a script that declares any of them.\nexport const BROWSER_LIFECYCLE = [\n \"connectedCallback\",\n \"disconnectedCallback\",\n \"adoptedCallback\",\n \"connectedMoveCallback\",\n] as const;\n\n// --- Kinds --------------------------------------------------------------\nexport const KIND_ROW = \"row\";\nexport const KIND_ROWS = \"rows\";\n\n// --- The URL (docs/reference/chrome.md) ---------------------------------\n// The query the hub serves: one row, keyed by the path, whose other columns\n// are the query parms.\nexport const URL_QUERY = \"lb-url\";\nexport const URL_COLUMN_PATH = \"lb-path\";\nexport const URL_COLUMN_PAGE_LABEL = \"lb-page-label\";\nexport const URL_COLUMN_PAGE_UNKNOWN = \"lb-page-unknown\";\n\n// --- Round trips (docs/reference/chrome.md) ------------------------------\n// The query the hub serves with its own state: one row, keyed by the path,\n// telling whether the page's data arrived and whether the server answers.\n// The hub stamps the same columns on `<lb-hub>` itself, for a stylesheet.\nexport const HUB_QUERY = \"lb-hub\";\n\n// `loading`, `loaded` or `failed`: the page load for the URL showing.\nexport const HUB_COLUMN_LOAD_STATE = \"lb-load-state\";\n\n// `reachable`, `failing` or `unreachable`: how the latest round trip of any\n// kind went. Empty until the first one returns.\nexport const HUB_COLUMN_SERVER_STATE = \"lb-server-state\";\n\n// Empty, or why the latest round trip failed: HUB_ERROR_NETWORK,\n// HUB_ERROR_TIMEOUT, or the HTTP status the server answered with.\nexport const HUB_COLUMN_ERROR = \"lb-error\";\n\n// How many round trips are in flight.\nexport const HUB_COLUMN_PENDING = \"lb-pending\";\n\n// When rows last came from the server, as an ISO timestamp.\nexport const HUB_COLUMN_AS_OF = \"lb-as-of\";\n\nexport const HUB_LOAD_LOADING = \"loading\";\nexport const HUB_LOAD_LOADED = \"loaded\";\nexport const HUB_LOAD_FAILED = \"failed\";\n\nexport const HUB_SERVER_REACHABLE = \"reachable\";\nexport const HUB_SERVER_FAILING = \"failing\";\nexport const HUB_SERVER_UNREACHABLE = \"unreachable\";\n\nexport const HUB_ERROR_NETWORK = \"network\";\nexport const HUB_ERROR_TIMEOUT = \"timeout\";\n\n// On an `<a>`: a plain primary click sets `lb-path` from the `href`.\nexport const ATTR_URL_LINK = \"lb-url-link\";\n\n// On an element with `lb-request`: its update of `lb-url` pushes a history\n// entry instead of replacing one.\nexport const ATTR_URL_PUSH = \"lb-url-push\";\n\n// On an `<a>` carrying ATTR_URL_LINK: columns of the row around it, separated\n// by commas, each added to the `href`'s query string as the parm of the same\n// name.\nexport const ATTR_URL_PARM = \"lb-url-parm\";\n\n// On a `<dialog>`: the hub calls showModal() when `lb-page-unknown` is true.\nexport const ATTR_URL_UNKNOWN = \"lb-url-unknown\";\n\n// --- Build time (docs/reference/custom-elements.md) ---------------------\n// Marks the element in an element file whose children receive the rest of\n// the custom element's content. An attribute rather than an element because\n// HTML content models discard foreign elements inside <select> and <table>.\nexport const ATTR_EXP_SLOT = \"lb-exp-slot\";\n\n// One name in two positions. In an element file it marks a destination; on a\n// `<template>` in the custom element's content it names the destination\n// that template is for, and the template's content moves into it.\nexport const ATTR_EXP_TEMPLATE = \"lb-exp-template\";\n\n// A page ships as <template lb-page=\"<stub>\">.\nexport const ATTR_PAGE = \"lb-page\";\n\n// Stamped by the builder beside ATTR_PAGE: the text content of the page\n// file's `<title>`, which the builder removes.\nexport const ATTR_PAGE_TITLE = \"lb-page-title\";\n\n// The attributes a developer writes. The builder refuses any other `lb-`\n// attribute in markup: the rest are stamps, written by the hub or the\n// builder and never by hand or by script.\nexport const DEVELOPER_ATTRIBUTES = [\n ATTR_QUERY,\n ATTR_COLUMN,\n ATTR_SHOW,\n ATTR_GROUP,\n ...AGGREGATES,\n ATTR_ORDER,\n ATTR_FILTER,\n ATTR_MANUAL,\n ATTR_REQUEST,\n ATTR_SELECT,\n ATTR_URL_LINK,\n ATTR_URL_PUSH,\n ATTR_URL_PARM,\n ATTR_URL_UNKNOWN,\n] as const;\n\n// The hub's own tag. It is exempt from the rule every other LB-* tag\n// follows: expansion does not require it to have a definition (build/expand.ts),\n// and the client build does not require it to have a script of its own\n// (build/elements.ts) — it is the framework's live element, always present,\n// registered once by the package's main entry point, not a widget an\n// application discovers or declares.\nexport const HUB_TAG_NAME = \"lb-hub\";\n\n// --- Wire --------------------------------------------------------------\n// One path, one method: everything the hub asks of the server is a POST\n// below this path. The page's stub follows it, and the query string the\n// browser is showing rides after that verbatim, so `/accounts?acct=23` asks\n// as `POST /lb/accounts?acct=23` and the server always knows what URL the\n// browser is showing. Navigation is therefore the only GET an application\n// serves, which is what leaves the page name space unrestricted.\nexport const LB_ENDPOINT = \"/lb\";\n\n// A client-side deadline for one round trip. fetch() has no deadline of its\n// own; past this the request is aborted and treated as a failure.\nexport const LB_REQUEST_TIMEOUT_MS = 10_000;\n"]}
@@ -80,7 +80,11 @@ export interface HubRequest {
80
80
  * for a request that names no one row. Never sent beside `key`.
81
81
  */
82
82
  keys?: string[];
83
- values?: Record<string, string>;
83
+ /**
84
+ * The gathered controls' values, by column. A column of `lb-url` may hold
85
+ * several, as a URL repeats a parm; every other column holds one.
86
+ */
87
+ values?: Record<string, ParmValue>;
84
88
  /**
85
89
  * The rows of the queries nested in a form, by query name, each with the
86
90
  * values of its own controls: a set of rows gathered beside the form's
@@ -93,6 +97,16 @@ export interface GatheredRow {
93
97
  key: string;
94
98
  values: Record<string, string>;
95
99
  }
100
+ /**
101
+ * What a control gathers: one value, or several from a control that holds
102
+ * several, which only a column of `lb-url` takes.
103
+ */
104
+ export type ParmValue = string | string[];
105
+ /**
106
+ * The query parms of a URL as a row of `lb-url`: a parm the URL carries
107
+ * once is a string, and one it repeats is every value it carries, in order.
108
+ */
109
+ export declare function parmsRow(parms: URLSearchParams): Row;
96
110
  /**
97
111
  * The detail of the `lb-request-done` event: the request as the hub
98
112
  * completed and sent it, and what came of it. `items` is every response
@@ -116,7 +130,9 @@ export interface HubRefusal {
116
130
  columns?: Record<string, string>;
117
131
  }
118
132
  /** The fields a handler receives: the request, less its name. */
119
- export type RequestFields = Omit<HubRequest, "name">;
133
+ export type RequestFields = Omit<HubRequest, "name" | "values"> & {
134
+ values?: Record<string, string>;
135
+ };
120
136
  /** Whether a name is one of the requests Loadbare provides. */
121
137
  export declare function isRowRequest(name: string): boolean;
122
138
  /**
@@ -129,7 +145,7 @@ export declare function isRowRequest(name: string): boolean;
129
145
  * returned `lb-url`. The two must agree, or what the page shows would differ
130
146
  * from what the address bar says.
131
147
  */
132
- export declare function withQueryParms(search: URLSearchParams, parms: Record<string, string>): URLSearchParams;
148
+ export declare function withQueryParms(search: URLSearchParams, parms: Record<string, ParmValue>): URLSearchParams;
133
149
  /**
134
150
  * A path names a page by its stub, and nothing finer. The bare path resolves
135
151
  * to `index`, the same convention a static file server follows.
@@ -1 +1 @@
1
- {"version":3,"file":"lb-types.d.ts","sourceRoot":"","sources":["../../core/lb-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lb-types.d.ts","sourceRoot":"","sources":["../../core/lb-types.ts"],"names":[],"mappings":"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"}