@abide/abide 0.32.2 → 0.33.1
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/AGENTS.md +3 -3
- package/CHANGELOG.md +85 -63
- package/bin/abide.ts +6 -2
- package/package.json +6 -2
- package/src/devEntry.ts +12 -1
- package/src/lib/bundle/exitWithParent.ts +7 -7
- package/src/lib/server/runtime/buildCacheSnapshot.ts +5 -4
- package/src/lib/server/runtime/types/InspectorCacheEntry.ts +1 -1
- package/src/lib/shared/cache.ts +43 -29
- package/src/lib/shared/types/CacheEntry.ts +12 -12
- package/src/lib/shared/types/CacheOptions.ts +17 -13
- package/src/lib/ui/README.md +1 -1
- package/src/lib/ui/compile/UI_RUNTIME_IMPORTS.ts +4 -1
- package/src/lib/ui/compile/componentWrapperTag.ts +1 -1
- package/src/lib/ui/compile/generateBuild.ts +265 -121
- package/src/lib/ui/compile/generateSSR.ts +78 -37
- package/src/lib/ui/compile/parseTemplate.ts +34 -0
- package/src/lib/ui/compile/skeletonable.ts +80 -0
- package/src/lib/ui/dom/MATHML_NAMESPACE.ts +6 -0
- package/src/lib/ui/dom/SVG_NAMESPACE.ts +7 -0
- package/src/lib/ui/dom/anchorCursor.ts +24 -0
- package/src/lib/ui/dom/appendSnippet.ts +1 -1
- package/src/lib/ui/dom/appendTextAt.ts +70 -0
- package/src/lib/ui/dom/awaitBlock.ts +27 -7
- package/src/lib/ui/dom/cloneStatic.ts +14 -7
- package/src/lib/ui/dom/each.ts +44 -25
- package/src/lib/ui/dom/eachAsync.ts +6 -2
- package/src/lib/ui/dom/effectiveChildNamespace.ts +13 -0
- package/src/lib/ui/dom/enterNamespace.ts +20 -0
- package/src/lib/ui/dom/fillBefore.ts +20 -3
- package/src/lib/ui/dom/foreignWrapperTag.ts +22 -0
- package/src/lib/ui/dom/hydrate.ts +1 -1
- package/src/lib/ui/dom/inheritedNamespace.ts +19 -0
- package/src/lib/ui/dom/mountSlot.ts +32 -0
- package/src/lib/ui/dom/openMarker.ts +4 -2
- package/src/lib/ui/dom/skeleton.ts +202 -0
- package/src/lib/ui/dom/switchBlock.ts +10 -3
- package/src/lib/ui/dom/tryBlock.ts +7 -5
- package/src/lib/ui/dom/types/SkeletonHoles.ts +8 -0
- package/src/lib/ui/dom/when.ts +6 -2
- package/src/lib/ui/installHotBridge.ts +8 -2
- package/src/lib/ui/runtime/HOLE_ATTRIBUTE.ts +9 -0
- package/src/lib/ui/runtime/RENDER.ts +7 -0
- package/src/lib/ui/runtime/types/UiProps.ts +3 -4
- package/template/src/ui/pages/about/page.abide +4 -6
- package/template/src/ui/pages/layout.abide +21 -0
- package/template/src/ui/pages/page.abide +5 -8
- package/src/lib/ui/compile/partitionSlots.ts +0 -36
- package/src/lib/ui/dom/openChild.ts +0 -22
- package/template/src/ui/Layout.abide +0 -19
|
@@ -39,20 +39,20 @@ into `__SSR__`; ones still pending were consumed via `{#await}` (render emitted
|
|
|
39
39
|
the pending branch without blocking) and stream a resolve chunk instead.
|
|
40
40
|
|
|
41
41
|
`refreshing` flips true while this entry is reloading data it already held —
|
|
42
|
-
either
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
either an `swr` refetch (stale value still visible) or the default
|
|
43
|
+
drop-then-reload (the prior entry was invalidated and dropped, this is its
|
|
44
|
+
replacement read). It backs refreshing(), distinguishing a reload from a
|
|
45
45
|
first-ever load; cleared when the read settles.
|
|
46
46
|
|
|
47
|
-
`invalidation` holds
|
|
48
|
-
|
|
49
|
-
state, so invalidate()
|
|
50
|
-
the
|
|
51
|
-
creating read declared
|
|
52
|
-
an entry that lacks it (hydrated snapshot entries always start without one) —
|
|
53
|
-
first
|
|
54
|
-
|
|
55
|
-
|
|
47
|
+
`invalidation` holds the entry's `swr` policy: the refetch thunk (the call
|
|
48
|
+
captured with its args) plus its optional throttle/debounce window and runtime
|
|
49
|
+
timer state, so invalidate() keeps the stale value and revalidates this key —
|
|
50
|
+
rate-limited by the window — instead of dropping the entry. Set at registration
|
|
51
|
+
when the creating read declared `swr`, or attached by a later read declaring it
|
|
52
|
+
on an entry that lacks it (hydrated snapshot entries always start without one) —
|
|
53
|
+
first wins. An armed `timer` is cleared if the entry is evicted, so a dead key
|
|
54
|
+
never refetches. Wrap-time validation guarantees `swr` never coexists with
|
|
55
|
+
ttl: 0 and never sits on a non-replayable remote method.
|
|
56
56
|
*/
|
|
57
57
|
export type CacheEntry = {
|
|
58
58
|
key: string
|
|
@@ -18,22 +18,26 @@ for per-request data: the default keeps a per-user response from leaking across
|
|
|
18
18
|
requests. Write only `global: true`; there is no `false` form. On the client
|
|
19
19
|
there is a single tab store, so the flag is a no-op there.
|
|
20
20
|
|
|
21
|
-
`
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
21
|
+
`swr` is stale-while-revalidate: it changes what a `cache.invalidate` hit does
|
|
22
|
+
to this key. Without it, an invalidate drops the entry and the next read shows
|
|
23
|
+
`pending()`. With it, the entry is kept and refetched in the background — the
|
|
24
|
+
existing (stale) value stays visible and `refreshing()` reports the in-flight
|
|
25
|
+
reload — so the reader never blanks. It governs only the refetch-after-invalidate;
|
|
26
|
+
the first fetch and arg-change fetches stay immediate regardless.
|
|
27
|
+
|
|
28
|
+
`swr: true` refetches immediately on every invalidate. An optional window
|
|
29
|
+
coalesces a burst (e.g. a socket spraying `cache.invalidate`) into far fewer
|
|
30
|
+
calls: `swr: { throttle: N }` refetches on the leading edge then at most once
|
|
31
|
+
per N ms while invalidations keep arriving; `swr: { debounce: N }` refetches
|
|
32
|
+
only after N ms of quiet. `swr` declares the call safe to re-run unprompted:
|
|
33
|
+
cache() throws at wrap time on throttle+debounce set at once, on ttl: 0 (nothing
|
|
34
|
+
retained, nothing to revalidate), and on a non-replayable remote method
|
|
35
|
+
(replaying a write is a state change disguised as a refresh). Producers are
|
|
36
|
+
uncheckable — set `swr` only on a producer that is a pure read.
|
|
33
37
|
*/
|
|
34
38
|
export type CacheOptions = {
|
|
35
39
|
ttl?: number
|
|
36
40
|
scope?: string | string[]
|
|
37
41
|
global?: boolean
|
|
38
|
-
|
|
42
|
+
swr?: boolean | { throttle?: number; debounce?: number }
|
|
39
43
|
}
|
package/src/lib/ui/README.md
CHANGED
|
@@ -70,7 +70,7 @@ write-path microbench this runs ~20× faster than a deep-proxy signal baseline.
|
|
|
70
70
|
```
|
|
71
71
|
.abide → analyzeComponent (split script/style/template, desugar signals → doc,
|
|
72
72
|
lower data access, scope CSS)
|
|
73
|
-
→ generateBuild (client:
|
|
73
|
+
→ generateBuild (client: skeleton/cloneStatic/appendText/attr/on/each/when/…)
|
|
74
74
|
→ generateSSR (server: HTML-string back-end, await markers)
|
|
75
75
|
→ hoistCells (static paths → cells)
|
|
76
76
|
→ compileModule (ES module: default mount + render() for SSR)
|
|
@@ -14,11 +14,13 @@ export const UI_RUNTIME_IMPORTS: { name: string; specifier: string }[] = [
|
|
|
14
14
|
{ name: 'derived', specifier: 'ui/derived' },
|
|
15
15
|
{ name: 'effect', specifier: 'ui/effect' },
|
|
16
16
|
{ name: 'mount', specifier: 'ui/dom/mount' },
|
|
17
|
-
{ name: 'openChild', specifier: 'ui/dom/openChild' },
|
|
18
17
|
{ name: 'appendText', specifier: 'ui/dom/appendText' },
|
|
18
|
+
{ name: 'appendTextAt', specifier: 'ui/dom/appendTextAt' },
|
|
19
19
|
{ name: 'appendSnippet', specifier: 'ui/dom/appendSnippet' },
|
|
20
20
|
{ name: 'appendStatic', specifier: 'ui/dom/appendStatic' },
|
|
21
21
|
{ name: 'cloneStatic', specifier: 'ui/dom/cloneStatic' },
|
|
22
|
+
{ name: 'skeleton', specifier: 'ui/dom/skeleton' },
|
|
23
|
+
{ name: 'anchorCursor', specifier: 'ui/dom/anchorCursor' },
|
|
22
24
|
{ name: 'attr', specifier: 'ui/dom/attr' },
|
|
23
25
|
{ name: 'on', specifier: 'ui/dom/on' },
|
|
24
26
|
{ name: 'attach', specifier: 'ui/dom/attach' },
|
|
@@ -28,6 +30,7 @@ export const UI_RUNTIME_IMPORTS: { name: string; specifier: string }[] = [
|
|
|
28
30
|
{ name: 'awaitBlock', specifier: 'ui/dom/awaitBlock' },
|
|
29
31
|
{ name: 'tryBlock', specifier: 'ui/dom/tryBlock' },
|
|
30
32
|
{ name: 'switchBlock', specifier: 'ui/dom/switchBlock' },
|
|
33
|
+
{ name: 'mountSlot', specifier: 'ui/dom/mountSlot' },
|
|
31
34
|
{ name: 'mountChild', specifier: 'ui/dom/mountChild' },
|
|
32
35
|
{ name: 'hydrate', specifier: 'ui/dom/hydrate' },
|
|
33
36
|
{ name: 'nextBlockId', specifier: 'ui/runtime/nextBlockId' },
|
|
@@ -6,7 +6,7 @@ lowercased — readable in devtools, a real box like any abide wrapper. But a na
|
|
|
6
6
|
that lowercases to a real HTML element (`Button`→`button`, `Input`→`input`) yields a
|
|
7
7
|
wrapper with a content model the parser enforces: void elements self-close, and
|
|
8
8
|
`<button>`/`<a>`/table/list/select families reject or foster the component's own
|
|
9
|
-
markup as the wrapper's siblings — so on hydration
|
|
9
|
+
markup as the wrapper's siblings — so on hydration the skeleton locates the wrapper
|
|
10
10
|
empty, claims `null`, and `attr` throws on it. Those names map to a hyphenated
|
|
11
11
|
custom-element tag (a custom element is never void and has no content model) made
|
|
12
12
|
layout-transparent with `display:contents`, so the component's real root still lays
|