@loadbare/app 0.14.0 → 0.15.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.
- package/dist/build/elements.d.ts +12 -2
- package/dist/build/elements.d.ts.map +1 -1
- package/dist/build/elements.js +44 -10
- package/dist/build/elements.js.map +1 -1
- package/dist/core/lb-constants.d.ts +2 -1
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +16 -3
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +25 -8
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +2 -0
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +18 -29
- package/dist/hub/lb-apply.js.map +1 -1
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +41 -5
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/hub/lb-lifecycle.d.ts +40 -0
- package/dist/hub/lb-lifecycle.d.ts.map +1 -0
- package/dist/hub/lb-lifecycle.js +140 -0
- package/dist/hub/lb-lifecycle.js.map +1 -0
- package/docs/TECHREF-1.0.md +49 -47
- package/docs/comparison.md +7 -5
- package/docs/possible-ideas.md +6 -0
- package/docs/reference/custom-elements.md +106 -87
- package/docs/reference/data-binding.md +7 -7
- package/docs/reference/widgets.md +2 -2
- package/docs/testing.md +2 -2
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +20 -16
- package/skills/loadbare-app/references/TECHREF-1.0.md +49 -47
- package/skills/loadbare-app/references/custom-elements.md +106 -87
- package/skills/loadbare-app/references/data-binding.md +7 -7
- package/skills/loadbare-app/references/widgets.md +2 -2
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The hub's lifecycle — see docs/reference/custom-elements.md, When its code
|
|
4
|
+
* runs.
|
|
5
|
+
*
|
|
6
|
+
* A custom element hears what the hub did to it, in the hub's terms, rather
|
|
7
|
+
* than the browser's insertions. The hub knows every moment it places an
|
|
8
|
+
* element and every moment it removes one, so it says so: `lbAttached` once
|
|
9
|
+
* the element is placed and filled, `lbDetached` once it is gone. A move, or
|
|
10
|
+
* `lb-show` parking an element and bringing it back, is neither, and the
|
|
11
|
+
* element hears nothing.
|
|
12
|
+
*
|
|
13
|
+
* Placing is noted as it happens and told at the end of the landing that
|
|
14
|
+
* follows, so an element is filled before it hears it, and an outer element
|
|
15
|
+
* hears it before the ones inside it.
|
|
16
|
+
*
|
|
17
|
+
* Every custom element the hub places has upgraded before it is filled: a
|
|
18
|
+
* live row and a group are imported into the document, and an absent branch
|
|
19
|
+
* is imported again as it arrives — see upgradeAbsent().
|
|
20
|
+
*/
|
|
21
|
+
import { ATTR_GROUP_LEAVING, ATTR_ROW_LEAVING, ATTR_SHOW, } from "../core/lb-constants.js";
|
|
22
|
+
/** The template holding an absent branch — see ATTR_SHOW. */
|
|
23
|
+
export const PARKED = `template[${ATTR_SHOW}]`;
|
|
24
|
+
/** A row or a group on its way out. */
|
|
25
|
+
export const LEAVING = `[${ATTR_ROW_LEAVING}], [${ATTR_GROUP_LEAVING}]`;
|
|
26
|
+
/** An Element's nodeType. Tier 3 has no `Node` global to read it from. */
|
|
27
|
+
const ELEMENT_NODE = 1;
|
|
28
|
+
/** Every custom element the hub has attached and not yet detached. */
|
|
29
|
+
const attached = new WeakSet();
|
|
30
|
+
/** What the hub has placed since the last landing ended. */
|
|
31
|
+
let placedSince = [];
|
|
32
|
+
/** A custom element whose class has run on it. */
|
|
33
|
+
function upgraded(el) {
|
|
34
|
+
if (!el.localName.includes("-"))
|
|
35
|
+
return false;
|
|
36
|
+
const registry = globalThis
|
|
37
|
+
.customElements;
|
|
38
|
+
const defined = registry?.get(el.localName);
|
|
39
|
+
return defined !== undefined && el instanceof defined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Every upgraded custom element at and under `root`, in tree order, outer
|
|
43
|
+
* before inner. An absent branch is searched where its template stands.
|
|
44
|
+
*/
|
|
45
|
+
function customIn(root, found) {
|
|
46
|
+
if (root.nodeType === ELEMENT_NODE && upgraded(root)) {
|
|
47
|
+
found.push(root);
|
|
48
|
+
}
|
|
49
|
+
for (const child of root.children) {
|
|
50
|
+
customIn(child.matches(PARKED) ? child.content : child, found);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Call one of the hub's methods, if the element has it. */
|
|
54
|
+
function tell(el, method, ...args) {
|
|
55
|
+
const fn = el[method];
|
|
56
|
+
try {
|
|
57
|
+
fn?.apply(el, args);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
console.error(`lb-hub: <${el.localName}> ${method} threw`, err);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Make every absent branch under `root` from elements that have upgraded.
|
|
65
|
+
*
|
|
66
|
+
* The builder ships each `lb-show` element inside its template, and a
|
|
67
|
+
* template's content belongs to a document with no definitions, so nothing
|
|
68
|
+
* shipped there has upgraded. Importing the branch into `doc` upgrades it as
|
|
69
|
+
* it is made, and it goes back into its template already the class it will
|
|
70
|
+
* be when it shows: the hub sets a control's `value` while it is away, and
|
|
71
|
+
* calls its methods, as on any other.
|
|
72
|
+
*
|
|
73
|
+
* Called on what the hub places before anything lands on it, while every
|
|
74
|
+
* branch is as the builder shipped it.
|
|
75
|
+
*/
|
|
76
|
+
export function upgradeAbsent(root, doc) {
|
|
77
|
+
for (const parked of root.querySelectorAll(PARKED)) {
|
|
78
|
+
const content = parked.content;
|
|
79
|
+
const branch = content.firstElementChild;
|
|
80
|
+
if (!branch)
|
|
81
|
+
continue;
|
|
82
|
+
const made = doc.importNode(branch, true);
|
|
83
|
+
branch.replaceWith(made);
|
|
84
|
+
upgradeAbsent(made, doc);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Note that the hub has placed `root`, to attach at the end of landing. */
|
|
88
|
+
export function placed(root) {
|
|
89
|
+
placedSince.push(root);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Attach every custom element in what the hub has placed since the last
|
|
93
|
+
* landing ended. A root inside another is reached from the outer one, so an
|
|
94
|
+
* outer element is attached before the ones inside it. An element on its way
|
|
95
|
+
* out is passed over.
|
|
96
|
+
*/
|
|
97
|
+
export function attachPlaced() {
|
|
98
|
+
const roots = placedSince;
|
|
99
|
+
placedSince = [];
|
|
100
|
+
const outer = roots.filter((root) => !roots.some((other) => other !== root && other.contains(root)));
|
|
101
|
+
for (const root of outer) {
|
|
102
|
+
if (root.closest(LEAVING))
|
|
103
|
+
continue;
|
|
104
|
+
const found = [];
|
|
105
|
+
customIn(root, found);
|
|
106
|
+
for (const el of found) {
|
|
107
|
+
if (attached.has(el) || el.closest(LEAVING))
|
|
108
|
+
continue;
|
|
109
|
+
attached.add(el);
|
|
110
|
+
tell(el, "lbAttached");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Detach every attached custom element in nodes the hub has removed, inner
|
|
116
|
+
* before outer. An element the hub never attached, such as the copy a moved
|
|
117
|
+
* row leaves behind, hears nothing.
|
|
118
|
+
*/
|
|
119
|
+
export function detachRemoved(nodes) {
|
|
120
|
+
const found = [];
|
|
121
|
+
for (const node of nodes) {
|
|
122
|
+
if (node.nodeType === ELEMENT_NODE)
|
|
123
|
+
customIn(node, found);
|
|
124
|
+
}
|
|
125
|
+
for (const el of found.reverse()) {
|
|
126
|
+
if (attached.delete(el))
|
|
127
|
+
tell(el, "lbDetached");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Tell the attached custom elements from `origin` outward how its request
|
|
132
|
+
* turned out, innermost first.
|
|
133
|
+
*/
|
|
134
|
+
export function requestDone(origin, detail) {
|
|
135
|
+
for (let el = origin; el; el = el.parentElement) {
|
|
136
|
+
if (attached.has(el))
|
|
137
|
+
tell(el, "lbRequestDone", detail, origin);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=lb-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lb-lifecycle.js","sourceRoot":"","sources":["../../hub/lb-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference lib=\"dom\" />\n\n/**\n * The hub's lifecycle — see docs/reference/custom-elements.md, When its code\n * runs.\n *\n * A custom element hears what the hub did to it, in the hub's terms, rather\n * than the browser's insertions. The hub knows every moment it places an\n * element and every moment it removes one, so it says so: `lbAttached` once\n * the element is placed and filled, `lbDetached` once it is gone. A move, or\n * `lb-show` parking an element and bringing it back, is neither, and the\n * element hears nothing.\n *\n * Placing is noted as it happens and told at the end of the landing that\n * follows, so an element is filled before it hears it, and an outer element\n * hears it before the ones inside it.\n *\n * Every custom element the hub places has upgraded before it is filled: a\n * live row and a group are imported into the document, and an absent branch\n * is imported again as it arrives — see upgradeAbsent().\n */\n\nimport {\n ATTR_GROUP_LEAVING,\n ATTR_ROW_LEAVING,\n ATTR_SHOW,\n} from \"../core/lb-constants.js\";\nimport type { HubLifecycle, HubRequestDone } from \"../core/lb-types.js\";\n\n/** The template holding an absent branch — see ATTR_SHOW. */\nexport const PARKED = `template[${ATTR_SHOW}]`;\n\n/** A row or a group on its way out. */\nexport const LEAVING = `[${ATTR_ROW_LEAVING}], [${ATTR_GROUP_LEAVING}]`;\n\n/** An Element's nodeType. Tier 3 has no `Node` global to read it from. */\nconst ELEMENT_NODE = 1;\n\n/** Every custom element the hub has attached and not yet detached. */\nconst attached = new WeakSet<Element>();\n\n/** What the hub has placed since the last landing ended. */\nlet placedSince: Element[] = [];\n\n/** A custom element whose class has run on it. */\nfunction upgraded(el: Element): boolean {\n if (!el.localName.includes(\"-\")) return false;\n const registry = (globalThis as { customElements?: CustomElementRegistry })\n .customElements;\n const defined = registry?.get(el.localName);\n return defined !== undefined && el instanceof defined;\n}\n\n/**\n * Every upgraded custom element at and under `root`, in tree order, outer\n * before inner. An absent branch is searched where its template stands.\n */\nfunction customIn(root: Element | DocumentFragment, found: Element[]): void {\n if (root.nodeType === ELEMENT_NODE && upgraded(root as Element)) {\n found.push(root as Element);\n }\n for (const child of root.children) {\n customIn(\n child.matches(PARKED) ? (child as HTMLTemplateElement).content : child,\n found,\n );\n }\n}\n\n/** Call one of the hub's methods, if the element has it. */\nfunction tell<K extends keyof HubLifecycle>(\n el: Element,\n method: K,\n ...args: Parameters<NonNullable<HubLifecycle[K]>>\n): void {\n const fn = (el as Element & HubLifecycle)[method] as\n ((...a: typeof args) => void) | undefined;\n try {\n fn?.apply(el, args);\n } catch (err) {\n console.error(`lb-hub: <${el.localName}> ${method} threw`, err);\n }\n}\n\n/**\n * Make every absent branch under `root` from elements that have upgraded.\n *\n * The builder ships each `lb-show` element inside its template, and a\n * template's content belongs to a document with no definitions, so nothing\n * shipped there has upgraded. Importing the branch into `doc` upgrades it as\n * it is made, and it goes back into its template already the class it will\n * be when it shows: the hub sets a control's `value` while it is away, and\n * calls its methods, as on any other.\n *\n * Called on what the hub places before anything lands on it, while every\n * branch is as the builder shipped it.\n */\nexport function upgradeAbsent(\n root: Element | DocumentFragment,\n doc: Document,\n): void {\n for (const parked of root.querySelectorAll(PARKED)) {\n const content = (parked as HTMLTemplateElement).content;\n const branch = content.firstElementChild;\n if (!branch) continue;\n const made = doc.importNode(branch, true);\n branch.replaceWith(made);\n upgradeAbsent(made, doc);\n }\n}\n\n/** Note that the hub has placed `root`, to attach at the end of landing. */\nexport function placed(root: Element): void {\n placedSince.push(root);\n}\n\n/**\n * Attach every custom element in what the hub has placed since the last\n * landing ended. A root inside another is reached from the outer one, so an\n * outer element is attached before the ones inside it. An element on its way\n * out is passed over.\n */\nexport function attachPlaced(): void {\n const roots = placedSince;\n placedSince = [];\n const outer = roots.filter(\n (root) => !roots.some((other) => other !== root && other.contains(root)),\n );\n for (const root of outer) {\n if (root.closest(LEAVING)) continue;\n const found: Element[] = [];\n customIn(root, found);\n for (const el of found) {\n if (attached.has(el) || el.closest(LEAVING)) continue;\n attached.add(el);\n tell(el, \"lbAttached\");\n }\n }\n}\n\n/**\n * Detach every attached custom element in nodes the hub has removed, inner\n * before outer. An element the hub never attached, such as the copy a moved\n * row leaves behind, hears nothing.\n */\nexport function detachRemoved(nodes: Iterable<ChildNode>): void {\n const found: Element[] = [];\n for (const node of nodes) {\n if (node.nodeType === ELEMENT_NODE) customIn(node as Element, found);\n }\n for (const el of found.reverse()) {\n if (attached.delete(el)) tell(el, \"lbDetached\");\n }\n}\n\n/**\n * Tell the attached custom elements from `origin` outward how its request\n * turned out, innermost first.\n */\nexport function requestDone(origin: Element, detail: HubRequestDone): void {\n for (let el: Element | null = origin; el; el = el.parentElement) {\n if (attached.has(el)) tell(el, \"lbRequestDone\", detail, origin);\n }\n}\n"]}
|
package/docs/TECHREF-1.0.md
CHANGED
|
@@ -715,10 +715,9 @@ standing where it stood, and moved back out when the column turns on. It is
|
|
|
715
715
|
not rendered, focused, clicked, announced or gathered. It is moved and
|
|
716
716
|
never rebuilt, so a custom element keeps its instance and a control keeps
|
|
717
717
|
what was typed into it. Landing reaches into that template, so the element
|
|
718
|
-
and everything inside it return current. A custom element
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
`lb-column-value` while it is away.
|
|
718
|
+
and everything inside it return current. A custom element hears nothing
|
|
719
|
+
going in or coming out, and still receives `lb-column-value` while it is
|
|
720
|
+
away.
|
|
722
721
|
|
|
723
722
|
The builder ships every `lb-show` element already inside its template, so
|
|
724
723
|
nothing conditional shows until its row lands. An absent element's template
|
|
@@ -1098,8 +1097,10 @@ makes a confirmation wrapper possible without the wrapped element knowing
|
|
|
1098
1097
|
about it.
|
|
1099
1098
|
|
|
1100
1099
|
Once what the request brought back has landed, or its round trip has failed,
|
|
1101
|
-
the hub
|
|
1102
|
-
element
|
|
1100
|
+
the hub calls `lbRequestDone(detail, origin)` on the committing element and
|
|
1101
|
+
every custom element around it, innermost first (see
|
|
1102
|
+
[Lifecycle](#lifecycle)), then dispatches the bubbling `lb-request-done`
|
|
1103
|
+
event from the same element. Its `detail`, `HubRequestDone` in `@loadbare/app/types`, holds
|
|
1103
1104
|
the request as the hub sent it and `items`, every response item that landed
|
|
1104
1105
|
because of it, in order. An answer that moved the URL contributes its
|
|
1105
1106
|
`lb-url` item and the page load. `error` is set instead when the round trip
|
|
@@ -1884,14 +1885,12 @@ Each direction has one mechanism for each kind of message:
|
|
|
1884
1885
|
| -------------- | ------------------------------------------- | ---------------------------- | ------------------------------------------------ |
|
|
1885
1886
|
| Hub to element | State that lasts | An attribute the hub stamps | `lb-column-value`, `lb-key-value`, `lb-query-row-count`, `lb-group-*`, `lb-row-*`, `lb-request-pending`, `lb-request-error` |
|
|
1886
1887
|
| Hub to element | State the platform already names | A property | A control's `value` |
|
|
1887
|
-
| Hub to element |
|
|
1888
|
+
| Hub to element | What the hub did | An optional `lb` method | `lbAttached`, `lbRowsLanded`, `lbRequestDone`, `lbDetached` |
|
|
1888
1889
|
| Hub to element | A moment an element started | A bubbling event | `lb-request-done` |
|
|
1889
1890
|
| Element to hub | A moment | A bubbling event | `lb-request`, and `change`, `click` and `submit` |
|
|
1890
1891
|
|
|
1891
|
-
State is an attribute, because a stylesheet can select on it
|
|
1892
|
-
|
|
1893
|
-
on without, since it acts on one element at one point in landing and nothing
|
|
1894
|
-
else can do it. A moment is an event, because the element that cares is
|
|
1892
|
+
State is an attribute, because a stylesheet can select on it. A method is
|
|
1893
|
+
how the hub tells one element what it just did to that element. A moment is an event, because the element that cares is
|
|
1895
1894
|
often an ancestor of the one it concerns, and an event reaches it with no
|
|
1896
1895
|
knowledge of either.
|
|
1897
1896
|
|
|
@@ -1910,45 +1909,47 @@ class NoteField extends HTMLElement {
|
|
|
1910
1909
|
}
|
|
1911
1910
|
```
|
|
1912
1911
|
|
|
1913
|
-
A control that is not yet upgraded when its column lands receives
|
|
1914
|
-
`lb-column-value` alone, since the hub sets `value` only on a control. That
|
|
1915
|
-
happens to an element the builder shipped absent, and to one whose
|
|
1916
|
-
definition loads after the hub lands. A control takes the stamp up the
|
|
1917
|
-
first time it connects, and never again.
|
|
1918
|
-
|
|
1919
1912
|
A custom element that is not a control receives `lb-column-value` and
|
|
1920
1913
|
renders it; its content is never replaced.
|
|
1921
1914
|
|
|
1922
1915
|
### Lifecycle
|
|
1923
1916
|
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
|
1929
|
-
|
|
|
1930
|
-
|
|
|
1931
|
-
|
|
|
1932
|
-
|
|
|
1933
|
-
|
|
|
1934
|
-
|
|
|
1917
|
+
A custom element hears the hub's lifecycle, never the browser's. The hub
|
|
1918
|
+
calls four optional methods, which the `HubLifecycle` interface in
|
|
1919
|
+
`@loadbare/app/types` declares:
|
|
1920
|
+
|
|
1921
|
+
| The hub | A custom element hears |
|
|
1922
|
+
| ------------------------------------------------ | ------------------------------- |
|
|
1923
|
+
| Places it: chrome at startup, a page, a new live row, a new group | `lbAttached()`, once, after every column has landed on it |
|
|
1924
|
+
| Lands rows on it | `lbRowsLanded()` |
|
|
1925
|
+
| Finishes a request committed by it or inside it | `lbRequestDone(detail, origin)` |
|
|
1926
|
+
| Removes it: a row or group done leaving, the page replaced | `lbDetached()`, once |
|
|
1927
|
+
| Moves a live row the order put elsewhere | Nothing |
|
|
1928
|
+
| Turns `lb-show` off or on | Nothing |
|
|
1929
|
+
| Leaves a copy of a moved row behind | Nothing, on the copy |
|
|
1930
|
+
|
|
1931
|
+
The chrome and a page are placed as the page's first answer lands, or once
|
|
1932
|
+
that round trip fails. An element under an `lb-show` that is off is placed
|
|
1933
|
+
inside its template, so `lbAttached` runs whether it shows or not. `lbAttached` reaches an outer
|
|
1934
|
+
custom element before the ones inside it, and `lbDetached` the inner ones
|
|
1935
|
+
first. `lbRequestDone` reaches the committing element and every custom
|
|
1936
|
+
element around it, innermost first, before the `lb-request-done` event.
|
|
1937
|
+
An element a script creates hears none of them.
|
|
1935
1938
|
|
|
1936
1939
|
A listener on the element itself goes in the constructor, which reads no
|
|
1937
|
-
attribute and no child. A child is looked up when it is needed.
|
|
1938
|
-
|
|
1939
|
-
done once per instance goes behind a flag.
|
|
1940
|
+
attribute and no child. A child is looked up when it is needed. Work done
|
|
1941
|
+
once per instance goes in `lbAttached`, and its undoing in `lbDetached`.
|
|
1940
1942
|
|
|
1941
|
-
|
|
1943
|
+
The build refuses a script that declares `connectedCallback`,
|
|
1944
|
+
`disconnectedCallback`, `adoptedCallback` or `connectedMoveCallback`.
|
|
1942
1945
|
|
|
1943
|
-
|
|
1944
|
-
| ---------------- | -------------- | ------------------------------------------------------ |
|
|
1945
|
-
| `lbRowsLanded()` | Developer | After the rows land, with every row placed and stamped |
|
|
1946
|
+
### Row hooks
|
|
1946
1947
|
|
|
1947
|
-
The hub calls
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1948
|
+
The hub calls `lbRowsLanded()` on a custom element with `lb-query` and a row
|
|
1949
|
+
template, after the rows land, with every row placed and stamped. The hub
|
|
1950
|
+
places every row and builds every group itself, so a custom element reacts
|
|
1951
|
+
to rows and never places them. Scrolling to the row the page's request
|
|
1952
|
+
created is the case:
|
|
1952
1953
|
|
|
1953
1954
|
```ts
|
|
1954
1955
|
lbRowsLanded() {
|
|
@@ -1957,10 +1958,8 @@ lbRowsLanded() {
|
|
|
1957
1958
|
}
|
|
1958
1959
|
```
|
|
1959
1960
|
|
|
1960
|
-
A custom element
|
|
1961
|
-
|
|
1962
|
-
upgrades, the hub lands the query's last answer on it again, as all rows,
|
|
1963
|
-
so the hook runs.
|
|
1961
|
+
A custom element under an `lb-show` that is off holds its rows all the
|
|
1962
|
+
same, and the hook runs as they land.
|
|
1964
1963
|
|
|
1965
1964
|
`applyRow(root, row)`, exported by `@loadbare/app`, fills `root` from one
|
|
1966
1965
|
row, the same operation that fills a live row.
|
|
@@ -2136,9 +2135,12 @@ Loadbare/app owns every DOM event in this table, both the name and what its
|
|
|
2136
2135
|
|
|
2137
2136
|
### Reserved methods
|
|
2138
2137
|
|
|
2139
|
-
| Method
|
|
2140
|
-
|
|
|
2141
|
-
| `
|
|
2138
|
+
| Method | On | Defined in |
|
|
2139
|
+
| --------------- | --------------------------------------------------- | ----------------------- |
|
|
2140
|
+
| `lbAttached` | Any custom element the hub places | [Lifecycle](#lifecycle) |
|
|
2141
|
+
| `lbRowsLanded` | A custom element with `lb-query` and a row template | [Row hooks](#row-hooks) |
|
|
2142
|
+
| `lbRequestDone` | A custom element that committed, or holds one that did | [Lifecycle](#lifecycle) |
|
|
2143
|
+
| `lbDetached` | Any custom element the hub removes | [Lifecycle](#lifecycle) |
|
|
2142
2144
|
|
|
2143
2145
|
### Constants
|
|
2144
2146
|
|
package/docs/comparison.md
CHANGED
|
@@ -319,10 +319,11 @@ without `.browser` is not bundled, and the build error names it.
|
|
|
319
319
|
- A widget may send a request by dispatching a bubbling `lb-request`
|
|
320
320
|
`CustomEvent`. The hub completes it with `query`, `key` and `values` from
|
|
321
321
|
where the element sits. An ancestor may stop the event.
|
|
322
|
-
- A custom element
|
|
323
|
-
`
|
|
324
|
-
|
|
325
|
-
|
|
322
|
+
- A custom element hears the hub's lifecycle rather than the browser's:
|
|
323
|
+
`lbAttached()` and `lbDetached()` once each, when the hub places and
|
|
324
|
+
removes it, `lbRowsLanded()` once rows land on it, and `lbRequestDone()`
|
|
325
|
+
when a request from inside it finishes. The hub does the cloning,
|
|
326
|
+
matching, ordering, grouping, removal and counting.
|
|
326
327
|
- Method names beginning with `lb` on a custom element are reserved.
|
|
327
328
|
|
|
328
329
|
Widget libraries are npm packages listed in `imports.ts`. The builder scans
|
|
@@ -791,7 +792,7 @@ TECHREF-1.0 lists every name Loadbare/app owns in one cross-reference.
|
|
|
791
792
|
| `lb-*` stamps | 17 | `lb-column-value`, `lb-key-value`, `lb-row-live`, `lb-query-row-count`, `lb-group-live`, `lb-group-column`, `lb-group-value`, `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested`, `lb-row-leaving`, `lb-group-leaving`, `lb-request-pending`, `lb-request-error`, `lb-page`, `lb-page-title` |
|
|
792
793
|
| `lb-*` build-time attributes | 2 | `lb-exp-slot`, `lb-exp-template` |
|
|
793
794
|
| Requests Loadbare provides | 3 | `lb-row-insert`, `lb-row-update`, `lb-row-delete` |
|
|
794
|
-
| `lb*` methods on custom elements |
|
|
795
|
+
| `lb*` methods on custom elements | 4 | `lbAttached`, `lbRowsLanded`, `lbRequestDone`, `lbDetached` |
|
|
795
796
|
| Query parms Loadbare reads | 1 | `lb-order-<query>` |
|
|
796
797
|
| Attribute namespace for expansion | 1 | `exp-*` |
|
|
797
798
|
| Reserved tags | 1 | `<lb-hub>` |
|
|
@@ -1185,6 +1186,7 @@ Each equivalent is approximate.
|
|
|
1185
1186
|
| `exp-` parameter | A prop fixed at build time |
|
|
1186
1187
|
| `lb-exp-slot`, `lb-exp-template` | Default slot and named slots; `ng-content` with `select` |
|
|
1187
1188
|
| `lbRowsLanded` | An effect after a list renders |
|
|
1189
|
+
| `lbAttached`, `lbDetached` | Mount and unmount; `onMounted` and `onUnmounted` (Vue); `onMount` and `onDestroy` (Svelte) |
|
|
1188
1190
|
| `order`, `lb-group` | `ORDER BY` with report-writer control breaks (`BREAK ON`, group bands) |
|
|
1189
1191
|
| `ctx` / `HubContext` | `event.locals` (SvelteKit); loader `context` (React Router 7); request-scoped dependency injection |
|
|
1190
1192
|
| `imports.ts` | Installing and registering a component library |
|
package/docs/possible-ideas.md
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
> 2026-10-02 against `@loadbare/app` 0.12.0, from a session in ef. Nothing
|
|
5
5
|
> here is decided or planned.
|
|
6
6
|
|
|
7
|
+
> **Status, 2026-10-04.** The lifecycle in the hub's terms was adopted, on
|
|
8
|
+
> custom elements rather than on behaviors: see
|
|
9
|
+
> [When its code runs](./reference/custom-elements.md#when-its-code-runs).
|
|
10
|
+
> Behavior by attribute, and expansion that replaces the tag, were set aside.
|
|
11
|
+
> What follows is kept as the record of how the decision was reached.
|
|
12
|
+
|
|
7
13
|
## Why these are being considered
|
|
8
14
|
|
|
9
15
|
A custom element is the platform's one way to attach code to markup, and
|