@loadbare/app 0.20.0 → 0.22.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 (61) hide show
  1. package/README.md +18 -0
  2. package/dist/build/assemble.d.ts.map +1 -1
  3. package/dist/build/assemble.js +8 -3
  4. package/dist/build/assemble.js.map +1 -1
  5. package/dist/build/build.d.ts +62 -0
  6. package/dist/build/build.d.ts.map +1 -0
  7. package/dist/build/build.js +148 -0
  8. package/dist/build/build.js.map +1 -0
  9. package/dist/build/cli.d.ts +6 -1
  10. package/dist/build/cli.d.ts.map +1 -1
  11. package/dist/build/cli.js +25 -78
  12. package/dist/build/cli.js.map +1 -1
  13. package/dist/build/declared.d.ts.map +1 -1
  14. package/dist/build/declared.js +3 -0
  15. package/dist/build/declared.js.map +1 -1
  16. package/dist/build/skills-cli.d.ts +2 -1
  17. package/dist/build/skills-cli.d.ts.map +1 -1
  18. package/dist/build/skills-cli.js +8 -1
  19. package/dist/build/skills-cli.js.map +1 -1
  20. package/dist/build/skills.d.ts +2 -0
  21. package/dist/build/skills.d.ts.map +1 -1
  22. package/dist/build/skills.js +2 -0
  23. package/dist/build/skills.js.map +1 -1
  24. package/dist/core/lb-constants.d.ts +14 -0
  25. package/dist/core/lb-constants.d.ts.map +1 -1
  26. package/dist/core/lb-constants.js +25 -0
  27. package/dist/core/lb-constants.js.map +1 -1
  28. package/dist/dev/lb-dev.d.ts +128 -0
  29. package/dist/dev/lb-dev.d.ts.map +1 -0
  30. package/dist/dev/lb-dev.js +289 -0
  31. package/dist/dev/lb-dev.js.map +1 -0
  32. package/dist/hub/lb-apply.d.ts +10 -2
  33. package/dist/hub/lb-apply.d.ts.map +1 -1
  34. package/dist/hub/lb-apply.js +8 -2
  35. package/dist/hub/lb-apply.js.map +1 -1
  36. package/dist/hub/lb-hub.browser.d.ts.map +1 -1
  37. package/dist/hub/lb-hub.browser.js +127 -19
  38. package/dist/hub/lb-hub.browser.js.map +1 -1
  39. package/docs/comparison.md +4 -3
  40. package/docs/reference/builder.md +12 -4
  41. package/docs/reference/chrome.md +52 -1
  42. package/docs/reference/data-binding.md +27 -12
  43. package/docs/reference/dev-server.md +171 -0
  44. package/docs/reference/names.md +14 -1
  45. package/docs/reference/overview.md +1 -0
  46. package/docs/reference/server.md +8 -3
  47. package/docs/reference/widgets.md +10 -277
  48. package/docs/testing.md +2 -1
  49. package/docs/tutorials/000-getting-started.md +1 -1
  50. package/docs/tutorials/040-displaying-data.md +1 -1
  51. package/docs/tutorials/090-using-widget-libraries.md +1 -1
  52. package/package.json +4 -2
  53. package/skills/loadbare-app/SKILL.md +30 -12
  54. package/skills/loadbare-app/references/builder.md +12 -4
  55. package/skills/loadbare-app/references/chrome.md +52 -1
  56. package/skills/loadbare-app/references/data-binding.md +27 -12
  57. package/skills/loadbare-app/references/dev-server.md +171 -0
  58. package/skills/loadbare-app/references/names.md +14 -1
  59. package/skills/loadbare-app/references/overview.md +1 -0
  60. package/skills/loadbare-app/references/server.md +8 -3
  61. package/skills/loadbare-app/references/widgets.md +10 -277
package/dist/build/cli.js CHANGED
@@ -35,19 +35,15 @@
35
35
  * markup, a widget's class, a stylesheet, and `imports.ts` all feed the
36
36
  * same build — and a rebuild that throws is reported without stopping the
37
37
  * watch. There is no dev server and no browser reload here, only the files
38
- * on disk staying current for the next manual refresh.
38
+ * on disk staying current for the next manual refresh; `@loadbare/app/dev`
39
+ * is the dev server.
40
+ *
41
+ * The build itself is build/build.ts. This file is the command: its flags,
42
+ * and the lines it prints, one per build, `wrote ...` on stdout or the
43
+ * failure on stderr.
39
44
  */
40
45
  import { parseArgs } from "node:util";
41
- import { mkdir, watch, writeFile } from "node:fs/promises";
42
- import path from "node:path";
43
- import * as esbuild from "esbuild";
44
- import { assemble } from "./assemble.js";
45
- import { loadDeclared } from "./declared.js";
46
- import { checkReservedMethods, clientEntrySource, resolveElements, } from "./elements.js";
47
- import { resolveLocations } from "./locations.js";
48
- import { cssFrom, scanAll } from "./origins.js";
49
- import { pagesSource } from "./pages.js";
50
- import { stylesSource } from "./styles.js";
46
+ import { buildApp, watchApp } from "./build.js";
51
47
  const { values } = parseArgs({
52
48
  options: {
53
49
  src: { type: "string", default: "src" },
@@ -56,77 +52,28 @@ const { values } = parseArgs({
56
52
  minify: { type: "boolean", default: false },
57
53
  },
58
54
  });
59
- const srcDir = values.src;
60
- async function build() {
61
- const locations = await resolveLocations({ src: srcDir, out: values.out });
62
- const outFile = path.join(locations.outDir, "app.html");
63
- const entryFile = path.join(locations.outDir, "client-entry.ts");
64
- const clientFile = path.join(locations.outDir, "client.js");
65
- const scans = await scanAll(locations, srcDir, locations.importsFile);
66
- await mkdir(locations.outDir, { recursive: true });
67
- const declared = await loadDeclared(locations.pages, locations.pageSources, locations.outDir);
68
- const { html, usedTags } = await assemble({ ...locations, scans, declared });
69
- await writeFile(outFile, html, "utf-8");
70
- const { resolved } = resolveElements({ used: usedTags, scans });
71
- await checkReservedMethods(resolved);
72
- await writeFile(entryFile, clientEntrySource(resolved, locations.outDir), "utf-8");
73
- await esbuild.build({
74
- entryPoints: [entryFile],
75
- bundle: true,
76
- format: "iife",
77
- outfile: clientFile,
78
- minify: values.minify,
79
- });
80
- const generatedPages = pagesSource(locations.pages, locations.pageSources, locations.outDir, locations.packageName);
81
- let pagesMessage = "";
82
- if (generatedPages) {
83
- const pagesFile = path.join(locations.outDir, "pages.ts");
84
- await writeFile(pagesFile, generatedPages, "utf-8");
85
- pagesMessage = ` and ${pagesFile}`;
86
- }
87
- const concatenatedCss = await stylesSource(cssFrom(scans));
88
- let cssMessage = "";
89
- if (concatenatedCss) {
90
- const cssFile = path.join(locations.outDir, "app.css");
91
- const generatedCss = values.minify
92
- ? (await esbuild.transform(concatenatedCss, {
93
- loader: "css",
94
- minify: true,
95
- })).code
96
- : concatenatedCss;
97
- await writeFile(cssFile, generatedCss, "utf-8");
98
- cssMessage = ` and ${cssFile}`;
99
- }
100
- console.log(`loadbare-app-build: wrote ${outFile} and ${clientFile}${pagesMessage}${cssMessage} ` +
101
- `(${resolved.size} custom element${resolved.size === 1 ? "" : "s"})`);
102
- }
103
- async function main() {
55
+ const options = { src: values.src, out: values.out, minify: values.minify };
56
+ if (!values.watch) {
104
57
  try {
105
- await build();
58
+ const { summary } = await buildApp(options);
59
+ console.log(`loadbare-app-build: ${summary}`);
106
60
  }
107
61
  catch (err) {
108
62
  console.error(`loadbare-app-build: ${err.message}`);
109
- if (!values.watch) {
110
- process.exitCode = 1;
111
- return;
112
- }
113
- }
114
- if (!values.watch)
115
- return;
116
- console.log(`loadbare-app-build: watching ${srcDir}`);
117
- const watcher = watch(srcDir, { recursive: true });
118
- for await (const event of watcher) {
119
- if (!event.filename?.endsWith(".html") &&
120
- !event.filename?.endsWith(".ts") &&
121
- !event.filename?.endsWith(".css"))
122
- continue;
123
- try {
124
- await build();
125
- }
126
- catch (err) {
127
- console.error(`loadbare-app-build: ${err.message}`);
128
- }
63
+ process.exitCode = 1;
129
64
  }
130
65
  }
131
- void main();
66
+ else {
67
+ const watcher = watchApp({
68
+ ...options,
69
+ onBuilt: (outcome) => {
70
+ if (outcome.ok)
71
+ console.log(`loadbare-app-build: ${outcome.built.summary}`);
72
+ else
73
+ console.error(`loadbare-app-build: ${outcome.error.message}`);
74
+ },
75
+ });
76
+ await watcher.ready;
77
+ console.log(`loadbare-app-build: watching ${options.src}`);
78
+ }
132
79
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../build/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * loadbare-app-build — assemble a chrome file and its pages into one HTML\n * document, and bundle the client script for exactly the custom elements\n * that document uses. See docs/tutorials/000-getting-started.md.\n *\n * loadbare-app-build [--src src] [--out dist] [--watch] [--minify]\n *\n * `--src` names the application's own tree: the one `chrome.html` file,\n * every `*.page.html` page, its `*.requests.ts`/`*.queries.ts` pairs, and\n * `imports.ts` if there is one — see build/locations.ts. It is also the last\n * origin in the cascade that supplies widget definitions, widget scripts and\n * stylesheets; this package's own widgets come first and each package named\n * in `imports.ts` in between, all scanned the same way — see\n * build/origins.ts.\n *\n * The assembled document is written to `<out>/app.html`; the client bundle\n * to `<out>/client.js`, by way of a generated `<out>/client-entry.ts` — see\n * build/elements.ts for how a tag is resolved to the script that registers\n * it. When any page has a requests or queries file, the hub registry that used\n * to be hand-maintained is written to `<out>/pages.ts` — see build/pages.ts.\n * Every `lb-query` and `lb-request` in the chrome and the pages is checked\n * against what the page declares, which is read by loading the page modules\n * — see build/declared.ts.\n * Every origin's stylesheets are concatenated in that same cascade order and\n * written to `<out>/app.css` — see build/styles.ts.\n *\n * `--minify` minifies both output files: esbuild's own minifier for\n * `client.js`, as part of the same bundling pass, and esbuild's CSS\n * transform for `app.css`, as a pass over the concatenation above. `app.html`\n * is never minified — it is markup an application may still want to read.\n *\n * Without `--watch`, this runs once and exits. With it, every `.html`,\n * `.ts` and `.css` file under `<src>` is watched — a page, a widget's\n * markup, a widget's class, a stylesheet, and `imports.ts` all feed the\n * same build — and a rebuild that throws is reported without stopping the\n * watch. There is no dev server and no browser reload here, only the files\n * on disk staying current for the next manual refresh.\n */\n\nimport { parseArgs } from \"node:util\";\nimport { mkdir, watch, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as esbuild from \"esbuild\";\nimport { assemble } from \"./assemble.js\";\nimport { loadDeclared } from \"./declared.js\";\nimport {\n checkReservedMethods,\n clientEntrySource,\n resolveElements,\n} from \"./elements.js\";\nimport { resolveLocations } from \"./locations.js\";\nimport { cssFrom, scanAll } from \"./origins.js\";\nimport { pagesSource } from \"./pages.js\";\nimport { stylesSource } from \"./styles.js\";\n\nconst { values } = parseArgs({\n options: {\n src: { type: \"string\", default: \"src\" },\n out: { type: \"string\", default: \"dist\" },\n watch: { type: \"boolean\", default: false },\n minify: { type: \"boolean\", default: false },\n },\n});\n\nconst srcDir = values.src!;\n\nasync function build(): Promise<void> {\n const locations = await resolveLocations({ src: srcDir, out: values.out! });\n const outFile = path.join(locations.outDir, \"app.html\");\n const entryFile = path.join(locations.outDir, \"client-entry.ts\");\n const clientFile = path.join(locations.outDir, \"client.js\");\n\n const scans = await scanAll(locations, srcDir, locations.importsFile);\n\n await mkdir(locations.outDir, { recursive: true });\n const declared = await loadDeclared(\n locations.pages,\n locations.pageSources,\n locations.outDir,\n );\n const { html, usedTags } = await assemble({ ...locations, scans, declared });\n await writeFile(outFile, html, \"utf-8\");\n\n const { resolved } = resolveElements({ used: usedTags, scans });\n await checkReservedMethods(resolved);\n await writeFile(\n entryFile,\n clientEntrySource(resolved, locations.outDir),\n \"utf-8\",\n );\n await esbuild.build({\n entryPoints: [entryFile],\n bundle: true,\n format: \"iife\",\n outfile: clientFile,\n minify: values.minify,\n });\n\n const generatedPages = pagesSource(\n locations.pages,\n locations.pageSources,\n locations.outDir,\n locations.packageName,\n );\n let pagesMessage = \"\";\n if (generatedPages) {\n const pagesFile = path.join(locations.outDir, \"pages.ts\");\n await writeFile(pagesFile, generatedPages, \"utf-8\");\n pagesMessage = ` and ${pagesFile}`;\n }\n\n const concatenatedCss = await stylesSource(cssFrom(scans));\n let cssMessage = \"\";\n if (concatenatedCss) {\n const cssFile = path.join(locations.outDir, \"app.css\");\n const generatedCss = values.minify\n ? (\n await esbuild.transform(concatenatedCss, {\n loader: \"css\",\n minify: true,\n })\n ).code\n : concatenatedCss;\n await writeFile(cssFile, generatedCss, \"utf-8\");\n cssMessage = ` and ${cssFile}`;\n }\n\n console.log(\n `loadbare-app-build: wrote ${outFile} and ${clientFile}${pagesMessage}${cssMessage} ` +\n `(${resolved.size} custom element${resolved.size === 1 ? \"\" : \"s\"})`,\n );\n}\n\nasync function main(): Promise<void> {\n try {\n await build();\n } catch (err) {\n console.error(`loadbare-app-build: ${(err as Error).message}`);\n if (!values.watch) {\n process.exitCode = 1;\n return;\n }\n }\n\n if (!values.watch) return;\n\n console.log(`loadbare-app-build: watching ${srcDir}`);\n const watcher = watch(srcDir, { recursive: true });\n for await (const event of watcher) {\n if (\n !event.filename?.endsWith(\".html\") &&\n !event.filename?.endsWith(\".ts\") &&\n !event.filename?.endsWith(\".css\")\n )\n continue;\n try {\n await build();\n } catch (err) {\n console.error(`loadbare-app-build: ${(err as Error).message}`);\n }\n }\n}\n\nvoid main();\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../build/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE;QACP,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QACvC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;QACxC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;KAC5C;CACF,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,GAAI,EAAE,GAAG,EAAE,MAAM,CAAC,GAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AAE9E,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;KAAM,CAAC;IACN,MAAM,OAAO,GAAG,QAAQ,CAAC;QACvB,GAAG,OAAO;QACV,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE;YACnB,IAAI,OAAO,CAAC,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;;gBACvE,OAAO,CAAC,KAAK,CAAC,uBAAuB,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,CAAC;KACF,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,KAAK,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,gCAAgC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * loadbare-app-build — assemble a chrome file and its pages into one HTML\n * document, and bundle the client script for exactly the custom elements\n * that document uses. See docs/tutorials/000-getting-started.md.\n *\n * loadbare-app-build [--src src] [--out dist] [--watch] [--minify]\n *\n * `--src` names the application's own tree: the one `chrome.html` file,\n * every `*.page.html` page, its `*.requests.ts`/`*.queries.ts` pairs, and\n * `imports.ts` if there is one — see build/locations.ts. It is also the last\n * origin in the cascade that supplies widget definitions, widget scripts and\n * stylesheets; this package's own widgets come first and each package named\n * in `imports.ts` in between, all scanned the same way — see\n * build/origins.ts.\n *\n * The assembled document is written to `<out>/app.html`; the client bundle\n * to `<out>/client.js`, by way of a generated `<out>/client-entry.ts` — see\n * build/elements.ts for how a tag is resolved to the script that registers\n * it. When any page has a requests or queries file, the hub registry that used\n * to be hand-maintained is written to `<out>/pages.ts` — see build/pages.ts.\n * Every `lb-query` and `lb-request` in the chrome and the pages is checked\n * against what the page declares, which is read by loading the page modules\n * — see build/declared.ts.\n * Every origin's stylesheets are concatenated in that same cascade order and\n * written to `<out>/app.css` — see build/styles.ts.\n *\n * `--minify` minifies both output files: esbuild's own minifier for\n * `client.js`, as part of the same bundling pass, and esbuild's CSS\n * transform for `app.css`, as a pass over the concatenation above. `app.html`\n * is never minified — it is markup an application may still want to read.\n *\n * Without `--watch`, this runs once and exits. With it, every `.html`,\n * `.ts` and `.css` file under `<src>` is watched — a page, a widget's\n * markup, a widget's class, a stylesheet, and `imports.ts` all feed the\n * same build — and a rebuild that throws is reported without stopping the\n * watch. There is no dev server and no browser reload here, only the files\n * on disk staying current for the next manual refresh; `@loadbare/app/dev`\n * is the dev server.\n *\n * The build itself is build/build.ts. This file is the command: its flags,\n * and the lines it prints, one per build, `wrote ...` on stdout or the\n * failure on stderr.\n */\n\nimport { parseArgs } from \"node:util\";\nimport { buildApp, watchApp } from \"./build.js\";\n\nconst { values } = parseArgs({\n options: {\n src: { type: \"string\", default: \"src\" },\n out: { type: \"string\", default: \"dist\" },\n watch: { type: \"boolean\", default: false },\n minify: { type: \"boolean\", default: false },\n },\n});\n\nconst options = { src: values.src!, out: values.out!, minify: values.minify };\n\nif (!values.watch) {\n try {\n const { summary } = await buildApp(options);\n console.log(`loadbare-app-build: ${summary}`);\n } catch (err) {\n console.error(`loadbare-app-build: ${(err as Error).message}`);\n process.exitCode = 1;\n }\n} else {\n const watcher = watchApp({\n ...options,\n onBuilt: (outcome) => {\n if (outcome.ok) console.log(`loadbare-app-build: ${outcome.built.summary}`);\n else console.error(`loadbare-app-build: ${outcome.error.message}`);\n },\n });\n await watcher.ready;\n console.log(`loadbare-app-build: watching ${options.src}`);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"declared.d.ts","sourceRoot":"","sources":["../../build/declared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG3D,wBAAwB;AACxB,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,gFAAgF;IAChF,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAChC;AAED,oEAAoE;AACpE,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAkBlD,wBAAsB,YAAY,CAChC,KAAK,EAAE,QAAQ,EAAE,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CAiCxB"}
1
+ {"version":3,"file":"declared.d.ts","sourceRoot":"","sources":["../../build/declared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG3D,wBAAwB;AACxB,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,gFAAgF;IAChF,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CAChC;AAED,oEAAoE;AACpE,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAkBlD,wBAAsB,YAAY,CAChC,KAAK,EAAE,QAAQ,EAAE,EACjB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACpC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,CAoCxB"}
@@ -46,6 +46,9 @@ export async function loadDeclared(pages, pageSources, outDir) {
46
46
  format: "esm",
47
47
  packages: "external",
48
48
  outfile: file,
49
+ // esbuild keeps the directory it started in, and paths here are the
50
+ // caller's, relative to where it is now.
51
+ absWorkingDir: process.cwd(),
49
52
  logLevel: "silent",
50
53
  });
51
54
  ({ pages: loaded } = await import(pathToFileURL(file).href));
@@ -1 +1 @@
1
- {"version":3,"file":"declared.js","sourceRoot":"","sources":["../../build/declared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAa5C,SAAS,OAAO,CAAC,IAAsB;IACrC,OAAO;QACL,OAAO,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAClD,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,EAAE,IAAI,GAAG,CACX,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/D,KAAK;YACL,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC3B,CAAC,CACH;KACF,CAAC;AACJ,CAAC;AAED,wGAAwG;AACxG,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,WAAoC,EACpC,MAAc;IAEd,IAAI,MAAM,GAAyB,EAAE,CAAC;IACtC,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,MAAM,EACN,gBAAgB,OAAO,CAAC,GAAG,IAAI,EAAE,UAAU,MAAM,CAClD,CAAC;QACF,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,MAAM,OAAO,CAAC,KAAK,CAAC;gBAClB,KAAK,EAAE;oBACL,QAAQ,EAAE,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC;oBACpD,UAAU,EAAE,MAAM;oBAClB,UAAU,EAAE,UAAU;oBACtB,MAAM,EAAE,IAAI;iBACb;gBACD,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YACH,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,8CAA+C,GAAa,CAAC,OAAO,EAAE,CACvE,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC","sourcesContent":["/**\n * What each page declares: the names its queries, its declared requests and\n * its `crud` entries answer to, read so the markup can be checked against\n * them before anything ships — see build/assemble.ts.\n *\n * The names are read off the finished objects rather than out of the\n * source, so they are exact however a module builds them. The page modules\n * are bundled from build/pages.ts's `declaredSource`, with every package\n * left external, into a module beside `pages.ts` in `outDir`, so it resolves\n * packages as `pages.ts` does. That module is imported and removed. The\n * build therefore runs each page module's import-time code, as the server\n * does when it starts.\n */\n\nimport { mkdir, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport * as esbuild from \"esbuild\";\nimport type { Page } from \"../server/lb-server.js\";\nimport type { PageFile, PageSource } from \"./locations.js\";\nimport { declaredSource } from \"./pages.js\";\n\n/** One page's names. */\nexport interface Declared {\n queries: Set<string>;\n handlers: Set<string>;\n /** By query name, the `Crud` keys declared for it: `rowInsert` and the rest. */\n crud: Map<string, Set<string>>;\n}\n\n/** By page name, every page, including one with no page modules. */\nexport type DeclaredPages = Map<string, Declared>;\n\nfunction namesOf(page: Page | undefined): Declared {\n return {\n queries: new Set(Object.keys(page?.queries ?? {})),\n handlers: new Set(Object.keys(page?.requests.handlers ?? {})),\n crud: new Map(\n Object.entries(page?.requests.crud ?? {}).map(([query, crud]) => [\n query,\n new Set(Object.keys(crud)),\n ]),\n ),\n };\n}\n\n/** Each import gets a module of its own, so a rebuild under --watch reads the files as they now are. */\nlet generation = 0;\n\nexport async function loadDeclared(\n pages: PageFile[],\n pageSources: Map<string, PageSource>,\n outDir: string,\n): Promise<DeclaredPages> {\n let loaded: Record<string, Page> = {};\n if (pageSources.size > 0) {\n const file = path.join(\n outDir,\n `.lb-declared-${process.pid}-${++generation}.mjs`,\n );\n try {\n await mkdir(outDir, { recursive: true });\n await esbuild.build({\n stdin: {\n contents: declaredSource(pages, pageSources, outDir),\n resolveDir: outDir,\n sourcefile: \"pages.ts\",\n loader: \"ts\",\n },\n bundle: true,\n platform: \"node\",\n format: \"esm\",\n packages: \"external\",\n outfile: file,\n logLevel: \"silent\",\n });\n ({ pages: loaded } = await import(pathToFileURL(file).href));\n } catch (err) {\n throw new Error(\n `declared: could not load the page modules: ${(err as Error).message}`,\n );\n } finally {\n await rm(file, { force: true });\n }\n }\n return new Map(pages.map(({ name }) => [name, namesOf(loaded[name])]));\n}\n"]}
1
+ {"version":3,"file":"declared.js","sourceRoot":"","sources":["../../build/declared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAa5C,SAAS,OAAO,CAAC,IAAsB;IACrC,OAAO;QACL,OAAO,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAClD,QAAQ,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,EAAE,IAAI,GAAG,CACX,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/D,KAAK;YACL,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC3B,CAAC,CACH;KACF,CAAC;AACJ,CAAC;AAED,wGAAwG;AACxG,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,WAAoC,EACpC,MAAc;IAEd,IAAI,MAAM,GAAyB,EAAE,CAAC;IACtC,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,MAAM,EACN,gBAAgB,OAAO,CAAC,GAAG,IAAI,EAAE,UAAU,MAAM,CAClD,CAAC;QACF,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzC,MAAM,OAAO,CAAC,KAAK,CAAC;gBAClB,KAAK,EAAE;oBACL,QAAQ,EAAE,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC;oBACpD,UAAU,EAAE,MAAM;oBAClB,UAAU,EAAE,UAAU;oBACtB,MAAM,EAAE,IAAI;iBACb;gBACD,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,IAAI;gBACb,oEAAoE;gBACpE,yCAAyC;gBACzC,aAAa,EAAE,OAAO,CAAC,GAAG,EAAE;gBAC5B,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YACH,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,8CAA+C,GAAa,CAAC,OAAO,EAAE,CACvE,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC","sourcesContent":["/**\n * What each page declares: the names its queries, its declared requests and\n * its `crud` entries answer to, read so the markup can be checked against\n * them before anything ships — see build/assemble.ts.\n *\n * The names are read off the finished objects rather than out of the\n * source, so they are exact however a module builds them. The page modules\n * are bundled from build/pages.ts's `declaredSource`, with every package\n * left external, into a module beside `pages.ts` in `outDir`, so it resolves\n * packages as `pages.ts` does. That module is imported and removed. The\n * build therefore runs each page module's import-time code, as the server\n * does when it starts.\n */\n\nimport { mkdir, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport * as esbuild from \"esbuild\";\nimport type { Page } from \"../server/lb-server.js\";\nimport type { PageFile, PageSource } from \"./locations.js\";\nimport { declaredSource } from \"./pages.js\";\n\n/** One page's names. */\nexport interface Declared {\n queries: Set<string>;\n handlers: Set<string>;\n /** By query name, the `Crud` keys declared for it: `rowInsert` and the rest. */\n crud: Map<string, Set<string>>;\n}\n\n/** By page name, every page, including one with no page modules. */\nexport type DeclaredPages = Map<string, Declared>;\n\nfunction namesOf(page: Page | undefined): Declared {\n return {\n queries: new Set(Object.keys(page?.queries ?? {})),\n handlers: new Set(Object.keys(page?.requests.handlers ?? {})),\n crud: new Map(\n Object.entries(page?.requests.crud ?? {}).map(([query, crud]) => [\n query,\n new Set(Object.keys(crud)),\n ]),\n ),\n };\n}\n\n/** Each import gets a module of its own, so a rebuild under --watch reads the files as they now are. */\nlet generation = 0;\n\nexport async function loadDeclared(\n pages: PageFile[],\n pageSources: Map<string, PageSource>,\n outDir: string,\n): Promise<DeclaredPages> {\n let loaded: Record<string, Page> = {};\n if (pageSources.size > 0) {\n const file = path.join(\n outDir,\n `.lb-declared-${process.pid}-${++generation}.mjs`,\n );\n try {\n await mkdir(outDir, { recursive: true });\n await esbuild.build({\n stdin: {\n contents: declaredSource(pages, pageSources, outDir),\n resolveDir: outDir,\n sourcefile: \"pages.ts\",\n loader: \"ts\",\n },\n bundle: true,\n platform: \"node\",\n format: \"esm\",\n packages: \"external\",\n outfile: file,\n // esbuild keeps the directory it started in, and paths here are the\n // caller's, relative to where it is now.\n absWorkingDir: process.cwd(),\n logLevel: \"silent\",\n });\n ({ pages: loaded } = await import(pathToFileURL(file).href));\n } catch (err) {\n throw new Error(\n `declared: could not load the page modules: ${(err as Error).message}`,\n );\n } finally {\n await rm(file, { force: true });\n }\n }\n return new Map(pages.map(({ name }) => [name, namesOf(loaded[name])]));\n}\n"]}
@@ -6,7 +6,8 @@
6
6
  *
7
7
  * Installs the agent skills that ship in this package into `.agents/skills`
8
8
  * and `.claude/skills`, or into `--dir` alone — see build/skills.ts. Nothing
9
- * goes to stdout; every line is progress, on stderr.
9
+ * goes to stdout but the usage `--help` asks for; every other line is
10
+ * progress, on stderr.
10
11
  */
11
12
  export {};
12
13
  //# sourceMappingURL=skills-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills-cli.d.ts","sourceRoot":"","sources":["../../build/skills-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
1
+ {"version":3,"file":"skills-cli.d.ts","sourceRoot":"","sources":["../../build/skills-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
@@ -6,7 +6,8 @@
6
6
  *
7
7
  * Installs the agent skills that ship in this package into `.agents/skills`
8
8
  * and `.claude/skills`, or into `--dir` alone — see build/skills.ts. Nothing
9
- * goes to stdout; every line is progress, on stderr.
9
+ * goes to stdout but the usage `--help` asks for; every other line is
10
+ * progress, on stderr.
10
11
  */
11
12
  import { parseArgs } from "node:util";
12
13
  import path from "node:path";
@@ -22,6 +23,7 @@ async function main() {
22
23
  options: {
23
24
  copy: { type: "boolean", default: false },
24
25
  dir: { type: "string" },
26
+ help: { type: "boolean", short: "h", default: false },
25
27
  },
26
28
  });
27
29
  }
@@ -31,6 +33,11 @@ async function main() {
31
33
  return 1;
32
34
  }
33
35
  const { values, positionals } = parsed;
36
+ // Asked for, the usage is the product, so it alone goes to stdout.
37
+ if (values.help) {
38
+ console.log(USAGE);
39
+ return 0;
40
+ }
34
41
  if (positionals.join(" ") !== "skills install") {
35
42
  console.error(USAGE);
36
43
  return 1;
@@ -1 +1 @@
1
- {"version":3,"file":"skills-cli.js","sourceRoot":"","sources":["../../build/skills-cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * loadbare-app — commands that are not the build.\n *\n * loadbare-app skills install [--copy] [--dir <path>]\n *\n * Installs the agent skills that ship in this package into `.agents/skills`\n * and `.claude/skills`, or into `--dir` alone — see build/skills.ts. Nothing\n * goes to stdout; every line is progress, on stderr.\n */\n\nimport { parseArgs } from \"node:util\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { findPackageRoot } from \"./package-root.js\";\nimport { installSkills, SKILL_DESTINATIONS } from \"./skills.js\";\n\nconst USAGE = \"usage: loadbare-app skills install [--copy] [--dir <path>]\";\n\nasync function main(): Promise<number> {\n let parsed;\n try {\n parsed = parseArgs({\n allowPositionals: true,\n options: {\n copy: { type: \"boolean\", default: false },\n dir: { type: \"string\" },\n },\n });\n } catch (err) {\n console.error(`loadbare-app: ${(err as Error).message}`);\n console.error(USAGE);\n return 1;\n }\n\n const { values, positionals } = parsed;\n if (positionals.join(\" \") !== \"skills install\") {\n console.error(USAGE);\n return 1;\n }\n\n // Source and compiled output sit at different depths, so the package is\n // found by walking up rather than by counting.\n const packageRoot = await findPackageRoot(\n path.dirname(fileURLToPath(import.meta.url)),\n );\n const source = path.join(packageRoot, \"skills\");\n const destinations = values.dir ? [values.dir] : SKILL_DESTINATIONS;\n\n const result = installSkills({\n source,\n destinations,\n copy: values.copy!,\n cwd: process.cwd(),\n log: (line) => console.error(line),\n });\n\n // An install with no skills in it is a packaging fault, not a user error,\n // and saying where it looked is what makes that diagnosable.\n if (result.names.length === 0) {\n console.error(\n `loadbare-app: this install of @loadbare/app carries no skills (looked in ${source})`,\n );\n return 1;\n }\n\n console.error(\"\");\n if (result.copiedInstead) {\n console.error(\n \"Some links could not be created and those skills were copied instead.\",\n );\n console.error(\n \"A copy does not follow the package when it is upgraded — rerun this\",\n );\n console.error(\n \"command after an upgrade, or use --copy everywhere and commit the result.\",\n );\n console.error(\"\");\n }\n\n if (values.copy) {\n console.error(\n \"These are copies. Commit them, and rerun this command after upgrading\",\n );\n console.error(\"@loadbare/app so the skill matches the framework.\");\n } else {\n console.error(\n \"These are links into node_modules. To keep them out of git:\",\n );\n console.error(\"\");\n for (const destination of destinations) {\n for (const name of result.names) {\n console.error(` ${path.join(destination, name)}`);\n }\n }\n }\n\n console.error(\"\");\n console.error(\"Start your agent from this directory and it will find them.\");\n\n return result.refused > 0 ? 1 : 0;\n}\n\nprocess.exitCode = await main();\n"]}
1
+ {"version":3,"file":"skills-cli.js","sourceRoot":"","sources":["../../build/skills-cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * loadbare-app — commands that are not the build.\n *\n * loadbare-app skills install [--copy] [--dir <path>]\n *\n * Installs the agent skills that ship in this package into `.agents/skills`\n * and `.claude/skills`, or into `--dir` alone — see build/skills.ts. Nothing\n * goes to stdout but the usage `--help` asks for; every other line is\n * progress, on stderr.\n */\n\nimport { parseArgs } from \"node:util\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { findPackageRoot } from \"./package-root.js\";\nimport { installSkills, SKILL_DESTINATIONS } from \"./skills.js\";\n\nconst USAGE = \"usage: loadbare-app skills install [--copy] [--dir <path>]\";\n\nasync function main(): Promise<number> {\n let parsed;\n try {\n parsed = parseArgs({\n allowPositionals: true,\n options: {\n copy: { type: \"boolean\", default: false },\n dir: { type: \"string\" },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n });\n } catch (err) {\n console.error(`loadbare-app: ${(err as Error).message}`);\n console.error(USAGE);\n return 1;\n }\n\n const { values, positionals } = parsed;\n // Asked for, the usage is the product, so it alone goes to stdout.\n if (values.help) {\n console.log(USAGE);\n return 0;\n }\n if (positionals.join(\" \") !== \"skills install\") {\n console.error(USAGE);\n return 1;\n }\n\n // Source and compiled output sit at different depths, so the package is\n // found by walking up rather than by counting.\n const packageRoot = await findPackageRoot(\n path.dirname(fileURLToPath(import.meta.url)),\n );\n const source = path.join(packageRoot, \"skills\");\n const destinations = values.dir ? [values.dir] : SKILL_DESTINATIONS;\n\n const result = installSkills({\n source,\n destinations,\n copy: values.copy!,\n cwd: process.cwd(),\n log: (line) => console.error(line),\n });\n\n // An install with no skills in it is a packaging fault, not a user error,\n // and saying where it looked is what makes that diagnosable.\n if (result.names.length === 0) {\n console.error(\n `loadbare-app: this install of @loadbare/app carries no skills (looked in ${source})`,\n );\n return 1;\n }\n\n console.error(\"\");\n if (result.copiedInstead) {\n console.error(\n \"Some links could not be created and those skills were copied instead.\",\n );\n console.error(\n \"A copy does not follow the package when it is upgraded — rerun this\",\n );\n console.error(\n \"command after an upgrade, or use --copy everywhere and commit the result.\",\n );\n console.error(\"\");\n }\n\n if (values.copy) {\n console.error(\n \"These are copies. Commit them, and rerun this command after upgrading\",\n );\n console.error(\"@loadbare/app so the skill matches the framework.\");\n } else {\n console.error(\n \"These are links into node_modules. To keep them out of git:\",\n );\n console.error(\"\");\n for (const destination of destinations) {\n for (const name of result.names) {\n console.error(` ${path.join(destination, name)}`);\n }\n }\n }\n\n console.error(\"\");\n console.error(\"Start your agent from this directory and it will find them.\");\n\n return result.refused > 0 ? 1 : 0;\n}\n\nprocess.exitCode = await main();\n"]}
@@ -5,6 +5,8 @@
5
5
  * The same command as `loadbare-db skills install`, and deliberately a copy
6
6
  * of it rather than a shared module: `@loadbare/db` shares no code with this
7
7
  * package, and this package imports nothing from the repository.
8
+ * `@loadbare/widgets` carries a third copy. The copies are kept identical,
9
+ * so a change to one belongs in all three.
8
10
  *
9
11
  * A symlink by default, because the point is that the skill tracks the
10
12
  * dependency: `npm install @loadbare/app@next` and the skill moves with it.
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../build/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAcH;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,UAAuC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,6BAA6B;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;CACxB;AAwCD,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAUtD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAsDpE"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../build/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAcH;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,UAAuC,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,6BAA6B;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,aAAa,EAAE,OAAO,CAAC;CACxB;AAwCD,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAUtD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CAsDpE"}
@@ -5,6 +5,8 @@
5
5
  * The same command as `loadbare-db skills install`, and deliberately a copy
6
6
  * of it rather than a shared module: `@loadbare/db` shares no code with this
7
7
  * package, and this package imports nothing from the repository.
8
+ * `@loadbare/widgets` carries a third copy. The copies are kept identical,
9
+ * so a change to one belongs in all three.
8
10
  *
9
11
  * A symlink by default, because the point is that the skill tracks the
10
12
  * dependency: `npm install @loadbare/app@next` and the skill moves with it.
@@ -1 +1 @@
1
- {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../build/skills.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Put the agent skills that ship in this package where a coding agent will\n * find them.\n *\n * The same command as `loadbare-db skills install`, and deliberately a copy\n * of it rather than a shared module: `@loadbare/db` shares no code with this\n * package, and this package imports nothing from the repository.\n *\n * A symlink by default, because the point is that the skill tracks the\n * dependency: `npm install @loadbare/app@next` and the skill moves with it.\n * `copy` is for a team that would rather commit the text than have every\n * clone depend on `node_modules` being populated.\n *\n * Nothing is done to `.gitignore`. Whether these paths are committed is a\n * decision about the project, and the command that installs a file is not the\n * one to make it.\n */\n\nimport {\n cpSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n symlinkSync,\n} from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Where a coding agent looks for skills.\n *\n * `.agents/skills` is the vendor-neutral location, read by Codex, Cursor and\n * Copilot; `.claude/skills` is Claude Code's, and Cursor reads it too. Both\n * are written rather than guessing from what happens to be configured.\n */\nexport const SKILL_DESTINATIONS = [\".agents/skills\", \".claude/skills\"];\n\nexport interface InstallOptions {\n /** The directory holding one subdirectory per skill. */\n source: string;\n /** The directories to install into. */\n destinations: string[];\n /** Copy rather than link. */\n copy: boolean;\n /** The project root; a link to a package inside it is relative. */\n cwd: string;\n /** Where progress goes, one line at a time. */\n log: (line: string) => void;\n}\n\nexport interface InstallResult {\n names: string[];\n refused: number;\n /** A link was refused by the platform and a copy made in its place. */\n copiedInstead: boolean;\n}\n\n/** `absent` covers a dangling symlink, which `existsSync` reports as missing. */\nfunction entryKind(p: string): \"absent\" | \"symlink\" | \"directory\" | \"other\" {\n let stat;\n try {\n stat = lstatSync(p);\n } catch {\n return \"absent\";\n }\n if (stat.isSymbolicLink()) return \"symlink\";\n if (stat.isDirectory()) return \"directory\";\n return \"other\";\n}\n\n/** The `name:` a skill directory declares, or null if there is no skill there. */\nfunction declaredSkillName(dir: string): string | null {\n try {\n const match = /^name:\\s*(\\S+)\\s*$/m.exec(\n readFileSync(path.join(dir, \"SKILL.md\"), \"utf-8\"),\n );\n return match?.[1] ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * A link into `node_modules` is relative, so the project stays movable and the\n * link means the same thing to everyone who checks it out. A globally\n * installed package gets an absolute path, since a relative one breaks the\n * moment the project moves.\n */\nfunction linkTarget(from: string, to: string, cwd: string): string {\n const inside = path.resolve(from).startsWith(path.resolve(cwd) + path.sep);\n return inside\n ? path.relative(path.dirname(path.resolve(cwd, to)), path.resolve(from))\n : path.resolve(from);\n}\n\n/** The skills under `source`: each directory holding a `SKILL.md`. */\nexport function shippedSkills(source: string): string[] {\n if (!existsSync(source)) return [];\n return readdirSync(source, { withFileTypes: true })\n .filter(\n (entry) =>\n entry.isDirectory() &&\n existsSync(path.join(source, entry.name, \"SKILL.md\")),\n )\n .map((entry) => entry.name)\n .sort();\n}\n\nexport function installSkills(options: InstallOptions): InstallResult {\n const { source, destinations, copy, cwd, log } = options;\n const names = shippedSkills(source);\n let refused = 0;\n let copiedInstead = false;\n\n for (const destination of destinations) {\n for (const name of names) {\n const from = path.join(source, name);\n const to = path.join(destination, name);\n const at = path.resolve(cwd, to);\n const kind = entryKind(at);\n\n // A directory this command wrote says so on its own front matter, and\n // is replaced. Anything else at that path belongs to someone, and a\n // skill install is not permitted to be the thing that lost it.\n if (kind === \"directory\" && declaredSkillName(at) !== name) {\n log(\n ` refused ${to} — a directory is already there and is not the ${name} skill`,\n );\n refused++;\n continue;\n }\n if (kind === \"other\") {\n log(` refused ${to} — a file is already there`);\n refused++;\n continue;\n }\n\n mkdirSync(path.resolve(cwd, destination), { recursive: true });\n rmSync(at, { recursive: true, force: true });\n\n if (copy) {\n cpSync(from, at, { recursive: true });\n log(` copied ${to}`);\n continue;\n }\n\n try {\n symlinkSync(linkTarget(from, to, cwd), at, \"dir\");\n log(` linked ${to}`);\n } catch (error) {\n // Windows refuses a symlink to an unprivileged process unless\n // developer mode is on. A copy is the same skill, so the install\n // succeeds and the difference is reported rather than raised.\n if ((error as NodeJS.ErrnoException).code !== \"EPERM\") throw error;\n cpSync(from, at, { recursive: true });\n copiedInstead = true;\n log(` copied ${to}`);\n }\n }\n }\n\n return { names, refused, copiedInstead };\n}\n"]}
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../build/skills.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Put the agent skills that ship in this package where a coding agent will\n * find them.\n *\n * The same command as `loadbare-db skills install`, and deliberately a copy\n * of it rather than a shared module: `@loadbare/db` shares no code with this\n * package, and this package imports nothing from the repository.\n * `@loadbare/widgets` carries a third copy. The copies are kept identical,\n * so a change to one belongs in all three.\n *\n * A symlink by default, because the point is that the skill tracks the\n * dependency: `npm install @loadbare/app@next` and the skill moves with it.\n * `copy` is for a team that would rather commit the text than have every\n * clone depend on `node_modules` being populated.\n *\n * Nothing is done to `.gitignore`. Whether these paths are committed is a\n * decision about the project, and the command that installs a file is not the\n * one to make it.\n */\n\nimport {\n cpSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n symlinkSync,\n} from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Where a coding agent looks for skills.\n *\n * `.agents/skills` is the vendor-neutral location, read by Codex, Cursor and\n * Copilot; `.claude/skills` is Claude Code's, and Cursor reads it too. Both\n * are written rather than guessing from what happens to be configured.\n */\nexport const SKILL_DESTINATIONS = [\".agents/skills\", \".claude/skills\"];\n\nexport interface InstallOptions {\n /** The directory holding one subdirectory per skill. */\n source: string;\n /** The directories to install into. */\n destinations: string[];\n /** Copy rather than link. */\n copy: boolean;\n /** The project root; a link to a package inside it is relative. */\n cwd: string;\n /** Where progress goes, one line at a time. */\n log: (line: string) => void;\n}\n\nexport interface InstallResult {\n names: string[];\n refused: number;\n /** A link was refused by the platform and a copy made in its place. */\n copiedInstead: boolean;\n}\n\n/** `absent` covers a dangling symlink, which `existsSync` reports as missing. */\nfunction entryKind(p: string): \"absent\" | \"symlink\" | \"directory\" | \"other\" {\n let stat;\n try {\n stat = lstatSync(p);\n } catch {\n return \"absent\";\n }\n if (stat.isSymbolicLink()) return \"symlink\";\n if (stat.isDirectory()) return \"directory\";\n return \"other\";\n}\n\n/** The `name:` a skill directory declares, or null if there is no skill there. */\nfunction declaredSkillName(dir: string): string | null {\n try {\n const match = /^name:\\s*(\\S+)\\s*$/m.exec(\n readFileSync(path.join(dir, \"SKILL.md\"), \"utf-8\"),\n );\n return match?.[1] ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * A link into `node_modules` is relative, so the project stays movable and the\n * link means the same thing to everyone who checks it out. A globally\n * installed package gets an absolute path, since a relative one breaks the\n * moment the project moves.\n */\nfunction linkTarget(from: string, to: string, cwd: string): string {\n const inside = path.resolve(from).startsWith(path.resolve(cwd) + path.sep);\n return inside\n ? path.relative(path.dirname(path.resolve(cwd, to)), path.resolve(from))\n : path.resolve(from);\n}\n\n/** The skills under `source`: each directory holding a `SKILL.md`. */\nexport function shippedSkills(source: string): string[] {\n if (!existsSync(source)) return [];\n return readdirSync(source, { withFileTypes: true })\n .filter(\n (entry) =>\n entry.isDirectory() &&\n existsSync(path.join(source, entry.name, \"SKILL.md\")),\n )\n .map((entry) => entry.name)\n .sort();\n}\n\nexport function installSkills(options: InstallOptions): InstallResult {\n const { source, destinations, copy, cwd, log } = options;\n const names = shippedSkills(source);\n let refused = 0;\n let copiedInstead = false;\n\n for (const destination of destinations) {\n for (const name of names) {\n const from = path.join(source, name);\n const to = path.join(destination, name);\n const at = path.resolve(cwd, to);\n const kind = entryKind(at);\n\n // A directory this command wrote says so on its own front matter, and\n // is replaced. Anything else at that path belongs to someone, and a\n // skill install is not permitted to be the thing that lost it.\n if (kind === \"directory\" && declaredSkillName(at) !== name) {\n log(\n ` refused ${to} — a directory is already there and is not the ${name} skill`,\n );\n refused++;\n continue;\n }\n if (kind === \"other\") {\n log(` refused ${to} — a file is already there`);\n refused++;\n continue;\n }\n\n mkdirSync(path.resolve(cwd, destination), { recursive: true });\n rmSync(at, { recursive: true, force: true });\n\n if (copy) {\n cpSync(from, at, { recursive: true });\n log(` copied ${to}`);\n continue;\n }\n\n try {\n symlinkSync(linkTarget(from, to, cwd), at, \"dir\");\n log(` linked ${to}`);\n } catch (error) {\n // Windows refuses a symlink to an unprivileged process unless\n // developer mode is on. A copy is the same skill, so the install\n // succeeds and the difference is reported rather than raised.\n if ((error as NodeJS.ErrnoException).code !== \"EPERM\") throw error;\n cpSync(from, at, { recursive: true });\n copiedInstead = true;\n log(` copied ${to}`);\n }\n }\n }\n\n return { names, refused, copiedInstead };\n}\n"]}
@@ -65,6 +65,20 @@ export declare const URL_QUERY = "lb-url";
65
65
  export declare const URL_COLUMN_PATH = "lb-path";
66
66
  export declare const URL_COLUMN_PAGE_LABEL = "lb-page-label";
67
67
  export declare const URL_COLUMN_PAGE_UNKNOWN = "lb-page-unknown";
68
+ export declare const HUB_QUERY = "lb-hub";
69
+ export declare const HUB_COLUMN_LOAD_STATE = "lb-load-state";
70
+ export declare const HUB_COLUMN_SERVER_STATE = "lb-server-state";
71
+ export declare const HUB_COLUMN_ERROR = "lb-error";
72
+ export declare const HUB_COLUMN_PENDING = "lb-pending";
73
+ export declare const HUB_COLUMN_AS_OF = "lb-as-of";
74
+ export declare const HUB_LOAD_LOADING = "loading";
75
+ export declare const HUB_LOAD_LOADED = "loaded";
76
+ export declare const HUB_LOAD_FAILED = "failed";
77
+ export declare const HUB_SERVER_REACHABLE = "reachable";
78
+ export declare const HUB_SERVER_FAILING = "failing";
79
+ export declare const HUB_SERVER_UNREACHABLE = "unreachable";
80
+ export declare const HUB_ERROR_NETWORK = "network";
81
+ export declare const HUB_ERROR_TIMEOUT = "timeout";
68
82
  export declare const ATTR_URL_LINK = "lb-url-link";
69
83
  export declare const ATTR_URL_PUSH = "lb-url-push";
70
84
  export declare const ATTR_URL_PARM = "lb-url-parm";
@@ -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":"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"}
@@ -257,6 +257,31 @@ export const URL_QUERY = "lb-url";
257
257
  export const URL_COLUMN_PATH = "lb-path";
258
258
  export const URL_COLUMN_PAGE_LABEL = "lb-page-label";
259
259
  export const URL_COLUMN_PAGE_UNKNOWN = "lb-page-unknown";
260
+ // --- Round trips (docs/reference/chrome.md) ------------------------------
261
+ // The query the hub serves with its own state: one row, keyed by the path,
262
+ // telling whether the page's data arrived and whether the server answers.
263
+ // The hub stamps the same columns on `<lb-hub>` itself, for a stylesheet.
264
+ export const HUB_QUERY = "lb-hub";
265
+ // `loading`, `loaded` or `failed`: the page load for the URL showing.
266
+ export const HUB_COLUMN_LOAD_STATE = "lb-load-state";
267
+ // `reachable`, `failing` or `unreachable`: how the latest round trip of any
268
+ // kind went. Empty until the first one returns.
269
+ export const HUB_COLUMN_SERVER_STATE = "lb-server-state";
270
+ // Empty, or why the latest round trip failed: HUB_ERROR_NETWORK,
271
+ // HUB_ERROR_TIMEOUT, or the HTTP status the server answered with.
272
+ export const HUB_COLUMN_ERROR = "lb-error";
273
+ // How many round trips are in flight.
274
+ export const HUB_COLUMN_PENDING = "lb-pending";
275
+ // When rows last came from the server, as an ISO timestamp.
276
+ export const HUB_COLUMN_AS_OF = "lb-as-of";
277
+ export const HUB_LOAD_LOADING = "loading";
278
+ export const HUB_LOAD_LOADED = "loaded";
279
+ export const HUB_LOAD_FAILED = "failed";
280
+ export const HUB_SERVER_REACHABLE = "reachable";
281
+ export const HUB_SERVER_FAILING = "failing";
282
+ export const HUB_SERVER_UNREACHABLE = "unreachable";
283
+ export const HUB_ERROR_NETWORK = "network";
284
+ export const HUB_ERROR_TIMEOUT = "timeout";
260
285
  // On an `<a>`: a plain primary click sets `lb-path` from the `href`.
261
286
  export const ATTR_URL_LINK = "lb-url-link";
262
287
  // On an element with `lb-request`: its update of `lb-url` pushes a history
@@ -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// 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 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"]}