@barefootjs/client 0.1.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.d.ts +56 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +76 -0
- package/dist/context.d.ts +25 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/csr-adapter.d.ts +26 -0
- package/dist/csr-adapter.d.ts.map +1 -0
- package/dist/forward-props.d.ts +17 -0
- package/dist/forward-props.d.ts.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +154 -0
- package/dist/reactive.d.ts +150 -0
- package/dist/reactive.d.ts.map +1 -0
- package/dist/reactive.js +215 -0
- package/dist/runtime/apply-rest-attrs.d.ts +16 -0
- package/dist/runtime/apply-rest-attrs.d.ts.map +1 -0
- package/dist/runtime/branch-slot.d.ts +22 -0
- package/dist/runtime/branch-slot.d.ts.map +1 -0
- package/dist/runtime/client-marker.d.ts +21 -0
- package/dist/runtime/client-marker.d.ts.map +1 -0
- package/dist/runtime/component.d.ts +99 -0
- package/dist/runtime/component.d.ts.map +1 -0
- package/dist/runtime/context.d.ts +40 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/hydrate.d.ts +100 -0
- package/dist/runtime/hydrate.d.ts.map +1 -0
- package/dist/runtime/hydration-state.d.ts +13 -0
- package/dist/runtime/hydration-state.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +27 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +2093 -0
- package/dist/runtime/insert.d.ts +75 -0
- package/dist/runtime/insert.d.ts.map +1 -0
- package/dist/runtime/list.d.ts +21 -0
- package/dist/runtime/list.d.ts.map +1 -0
- package/dist/runtime/map-array.d.ts +32 -0
- package/dist/runtime/map-array.d.ts.map +1 -0
- package/dist/runtime/portal.d.ts +96 -0
- package/dist/runtime/portal.d.ts.map +1 -0
- package/dist/runtime/qsa-item.d.ts +52 -0
- package/dist/runtime/qsa-item.d.ts.map +1 -0
- package/dist/runtime/query.d.ts +86 -0
- package/dist/runtime/query.d.ts.map +1 -0
- package/dist/runtime/reconcile-elements.d.ts +44 -0
- package/dist/runtime/reconcile-elements.d.ts.map +1 -0
- package/dist/runtime/registry.d.ts +53 -0
- package/dist/runtime/registry.d.ts.map +1 -0
- package/dist/runtime/render.d.ts +35 -0
- package/dist/runtime/render.d.ts.map +1 -0
- package/dist/runtime/scope.d.ts +28 -0
- package/dist/runtime/scope.d.ts.map +1 -0
- package/dist/runtime/slot-resolver.d.ts +36 -0
- package/dist/runtime/slot-resolver.d.ts.map +1 -0
- package/dist/runtime/spread-attrs.d.ts +19 -0
- package/dist/runtime/spread-attrs.d.ts.map +1 -0
- package/dist/runtime/standalone.js +2278 -0
- package/dist/runtime/streaming.d.ts +36 -0
- package/dist/runtime/streaming.d.ts.map +1 -0
- package/dist/runtime/style.d.ts +17 -0
- package/dist/runtime/style.d.ts.map +1 -0
- package/dist/runtime/template.d.ts +39 -0
- package/dist/runtime/template.d.ts.map +1 -0
- package/dist/runtime/types.d.ts +26 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/shims.d.ts +21 -0
- package/dist/shims.d.ts.map +1 -0
- package/dist/slot.d.ts +14 -0
- package/dist/slot.d.ts.map +1 -0
- package/dist/split-props.d.ts +26 -0
- package/dist/split-props.d.ts.map +1 -0
- package/dist/unwrap.d.ts +16 -0
- package/dist/unwrap.d.ts.map +1 -0
- package/package.json +71 -0
- package/src/build.ts +92 -0
- package/src/context.ts +33 -0
- package/src/csr-adapter.ts +134 -0
- package/src/forward-props.ts +43 -0
- package/src/index.ts +42 -0
- package/src/reactive.ts +411 -0
- package/src/runtime/apply-rest-attrs.ts +109 -0
- package/src/runtime/branch-slot.ts +32 -0
- package/src/runtime/client-marker.ts +46 -0
- package/src/runtime/component.ts +501 -0
- package/src/runtime/context.ts +111 -0
- package/src/runtime/hydrate.ts +311 -0
- package/src/runtime/hydration-state.ts +13 -0
- package/src/runtime/index.ts +96 -0
- package/src/runtime/insert.ts +407 -0
- package/src/runtime/list.ts +47 -0
- package/src/runtime/map-array.ts +381 -0
- package/src/runtime/portal.ts +174 -0
- package/src/runtime/qsa-item.ts +128 -0
- package/src/runtime/query.ts +632 -0
- package/src/runtime/reconcile-elements.ts +391 -0
- package/src/runtime/registry.ts +160 -0
- package/src/runtime/render.ts +105 -0
- package/src/runtime/scope.ts +46 -0
- package/src/runtime/slot-resolver.ts +66 -0
- package/src/runtime/spread-attrs.ts +88 -0
- package/src/runtime/streaming.ts +65 -0
- package/src/runtime/style.ts +27 -0
- package/src/runtime/template.ts +53 -0
- package/src/runtime/types.ts +27 -0
- package/src/shims.ts +54 -0
- package/src/slot.ts +23 -0
- package/src/split-props.ts +86 -0
- package/src/unwrap.ts +18 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Hydration
|
|
3
|
+
*
|
|
4
|
+
* Combined component registration + template registration + hydration.
|
|
5
|
+
* Single entry point for compiler-generated code.
|
|
6
|
+
*
|
|
7
|
+
* Design (post #1172):
|
|
8
|
+
*
|
|
9
|
+
* 1. `hydrate(name, def)` only **registers** the def + template +
|
|
10
|
+
* component-registry entry, then schedules a walk.
|
|
11
|
+
* 2. The walk visits every scope in **true document order** — both
|
|
12
|
+
* `[bf-s]` element scopes and `<!--bf-scope:Name_xxx-->` comment
|
|
13
|
+
* scopes are interleaved by their actual DOM position. Parents
|
|
14
|
+
* always init before descendants regardless of which kind of
|
|
15
|
+
* scope each one is, so a comment-rooted parent that calls
|
|
16
|
+
* `provideContext()` is visible to an element-rooted descendant
|
|
17
|
+
* that calls `useContext()` on the very first hydrate pass.
|
|
18
|
+
* 3. Two scheduling phases, each capped to one in-flight callback:
|
|
19
|
+
* - microtask: collapses every `hydrate()` call from the
|
|
20
|
+
* bundled module body into a single walk on the next tick.
|
|
21
|
+
* - rAF: catches scope elements that the streaming protocol
|
|
22
|
+
* (Hono / `__bf_swap`) injects into the document *after*
|
|
23
|
+
* the synchronous module body has finished.
|
|
24
|
+
* 4. `rehydrateAll()` and the comment-scope path both share this
|
|
25
|
+
* walker, so streaming swaps and comment-rooted fragments enjoy
|
|
26
|
+
* the same ordering guarantee.
|
|
27
|
+
*
|
|
28
|
+
* Same-name nesting (`<Counter>` inside `<Counter>`):
|
|
29
|
+
* The walker's `hydratedScopes.has(el)` check is the *only* skip
|
|
30
|
+
* guard. Parents that intentionally own their nested same-name
|
|
31
|
+
* children call `initChild(...)` from their init body — initChild
|
|
32
|
+
* marks the child scope as hydrated, so when the walker reaches it
|
|
33
|
+
* later it short-circuits. Parents that *don't* call `initChild`
|
|
34
|
+
* (the descendant is a coincidental same-name component, not a
|
|
35
|
+
* structural child) get the descendant hydrated by the walker as a
|
|
36
|
+
* normal top-level component. This makes nesting depth a non-issue
|
|
37
|
+
* — the previous ancestor-walk guard is gone.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
import { setCurrentScope } from './context'
|
|
41
|
+
import { commentScopeRegistry } from './scope'
|
|
42
|
+
import { hydratedScopes } from './hydration-state'
|
|
43
|
+
import { registerComponent } from './registry'
|
|
44
|
+
import { registerTemplate } from './template'
|
|
45
|
+
import { BF_SCOPE, BF_PROPS, BF_HOST, BF_SCOPE_COMMENT_PREFIX } from '@barefootjs/shared'
|
|
46
|
+
import type { ComponentDef } from './types'
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Registry of all hydrated component definitions.
|
|
50
|
+
* Used by the walker to look up an element's init/def by name, and by
|
|
51
|
+
* rehydrateAll() to re-scan the DOM after streaming chunks arrive.
|
|
52
|
+
*/
|
|
53
|
+
const registeredDefs = new Map<string, ComponentDef>()
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Look up a registered component definition by name. Used by the CSR
|
|
57
|
+
* `createComponent` path to honour `comment: true` (transparent
|
|
58
|
+
* wrapper) components — without the def lookup, those components
|
|
59
|
+
* overwrite the inner element's `bf-s` and break child-scope
|
|
60
|
+
* resolution at hydration.
|
|
61
|
+
*/
|
|
62
|
+
export function getRegisteredDef(name: string): ComponentDef | undefined {
|
|
63
|
+
return registeredDefs.get(name)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let microtaskScheduled = false
|
|
67
|
+
let rafScheduled = false
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Cross-runtime microtask scheduler. `queueMicrotask` is widely
|
|
71
|
+
* supported but absent in some test DOMs / older runtimes; fall back
|
|
72
|
+
* to `Promise.resolve().then(...)` so importing this module never
|
|
73
|
+
* throws on environments missing the global.
|
|
74
|
+
*/
|
|
75
|
+
const scheduleMicrotask: (cb: () => void) => void =
|
|
76
|
+
typeof queueMicrotask === 'function'
|
|
77
|
+
? queueMicrotask
|
|
78
|
+
: (cb) => {
|
|
79
|
+
Promise.resolve().then(cb)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Schedule the document-order walk once per tick (microtask) and once
|
|
84
|
+
* per frame (rAF). Both flags are cleared inside their respective
|
|
85
|
+
* callbacks, so a flood of `hydrate()` / `rehydrateAll()` calls can
|
|
86
|
+
* never queue more than two pending walks in total. The callbacks
|
|
87
|
+
* also re-check their own flag on entry so that a synchronous
|
|
88
|
+
* `flushHydration()` between scheduling and firing turns the queued
|
|
89
|
+
* callback into a no-op.
|
|
90
|
+
*/
|
|
91
|
+
function scheduleWalk(): void {
|
|
92
|
+
if (!microtaskScheduled) {
|
|
93
|
+
microtaskScheduled = true
|
|
94
|
+
scheduleMicrotask(() => {
|
|
95
|
+
if (!microtaskScheduled) return
|
|
96
|
+
microtaskScheduled = false
|
|
97
|
+
walkAllInDocumentOrder()
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
if (!rafScheduled && typeof requestAnimationFrame === 'function') {
|
|
101
|
+
rafScheduled = true
|
|
102
|
+
requestAnimationFrame(() => {
|
|
103
|
+
if (!rafScheduled) return
|
|
104
|
+
rafScheduled = false
|
|
105
|
+
walkAllInDocumentOrder()
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Register a component and schedule a document-order hydration walk.
|
|
112
|
+
* Combines registration + template setup + hydration in a single call.
|
|
113
|
+
*
|
|
114
|
+
* **Scheduling semantics** (changed in #1172): the walk runs on the
|
|
115
|
+
* next microtask, then again on the next animation frame. The init
|
|
116
|
+
* functions for registered components are *not* invoked synchronously
|
|
117
|
+
* inside `hydrate()`. Code that needs to observe init effects on the
|
|
118
|
+
* same tick — typically tests, but also advanced consumers wiring
|
|
119
|
+
* imperative bridges — should either:
|
|
120
|
+
*
|
|
121
|
+
* - `await Promise.resolve()` after a batch of `hydrate()` calls, or
|
|
122
|
+
* - call `flushHydration()` (see below) to drain any pending walks
|
|
123
|
+
* synchronously.
|
|
124
|
+
*
|
|
125
|
+
* The deferral is what lets the doc-order walker see a fully populated
|
|
126
|
+
* registry: every `hydrate()` call from the bundled module body lands
|
|
127
|
+
* in the registry *before* the microtask flush kicks off the single
|
|
128
|
+
* walk, so parents always init before their descendants regardless of
|
|
129
|
+
* which file the parent's `hydrate()` was emitted into.
|
|
130
|
+
*
|
|
131
|
+
* @param name - Component name
|
|
132
|
+
* @param def - Component definition (init function + optional template + comment flag)
|
|
133
|
+
*/
|
|
134
|
+
export function hydrate(name: string, def: ComponentDef): void {
|
|
135
|
+
// Ensure name is always set on the def so createComponentFromDef()
|
|
136
|
+
// doesn't rely on def.init.name (which may be lost under minification).
|
|
137
|
+
def.name = name
|
|
138
|
+
|
|
139
|
+
registeredDefs.set(name, def)
|
|
140
|
+
|
|
141
|
+
// Register component for parent-child communication
|
|
142
|
+
registerComponent(name, def.init)
|
|
143
|
+
|
|
144
|
+
// Register template for client-side component creation
|
|
145
|
+
if (def.template) {
|
|
146
|
+
registerTemplate(name, def.template)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
scheduleWalk()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Re-hydrate all registered components.
|
|
154
|
+
*
|
|
155
|
+
* Called by the streaming resolver after swapping fallback content with
|
|
156
|
+
* resolved content. Goes through the same scheduler as `hydrate()` so
|
|
157
|
+
* back-to-back `__bf_swap` invocations or interleaved `hydrate()` calls
|
|
158
|
+
* collapse to a single walk per tick + per frame. Like `hydrate()` this
|
|
159
|
+
* is asynchronous — see `flushHydration()` if you need a synchronous
|
|
160
|
+
* drain.
|
|
161
|
+
*/
|
|
162
|
+
export function rehydrateAll(): void {
|
|
163
|
+
scheduleWalk()
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Run any pending hydration walk synchronously, right now.
|
|
168
|
+
*
|
|
169
|
+
* The default scheduler is microtask + rAF — the right trade-off for
|
|
170
|
+
* production code (registry populates before the walk; back-to-back
|
|
171
|
+
* `hydrate()` calls coalesce). Tests and advanced consumers that need
|
|
172
|
+
* a deterministic completion point — e.g. imperative mounting code
|
|
173
|
+
* reading DOM state immediately after `render(...)` — call this
|
|
174
|
+
* helper instead of awaiting a microtask.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* hydrate('Counter', def)
|
|
178
|
+
* flushHydration()
|
|
179
|
+
* // safe to read Counter's post-init DOM state
|
|
180
|
+
*/
|
|
181
|
+
export function flushHydration(): void {
|
|
182
|
+
if (!microtaskScheduled && !rafScheduled) return
|
|
183
|
+
microtaskScheduled = false
|
|
184
|
+
rafScheduled = false
|
|
185
|
+
walkAllInDocumentOrder()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Single document-order walk visiting element scopes (`[bf-s]`) and
|
|
190
|
+
* comment scopes (`<!--bf-scope:Name_xxx-->`) interleaved by their
|
|
191
|
+
* actual DOM position. The parent's init — whichever scope shape it
|
|
192
|
+
* takes — always runs before any descendant init, so a comment-scope
|
|
193
|
+
* provider is visible to an element-scope descendant on the first pass.
|
|
194
|
+
*
|
|
195
|
+
* Both paths skip `~`-prefixed scopes (owned by `initChild`) and mark
|
|
196
|
+
* the scope as hydrated *before* running init: re-entrant `hydrate()`
|
|
197
|
+
* / `rehydrateAll()` calls from the init body (or a synchronous effect
|
|
198
|
+
* they trigger) must see the slot already taken so the next scheduled
|
|
199
|
+
* walk doesn't re-enter the same scope.
|
|
200
|
+
*/
|
|
201
|
+
function walkAllInDocumentOrder(): void {
|
|
202
|
+
if (typeof document === 'undefined') return
|
|
203
|
+
|
|
204
|
+
const walker = document.createTreeWalker(
|
|
205
|
+
document,
|
|
206
|
+
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
while (walker.nextNode()) {
|
|
210
|
+
const node = walker.currentNode
|
|
211
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
212
|
+
hydrateElementScope(node as Element)
|
|
213
|
+
} else if (node.nodeType === Node.COMMENT_NODE) {
|
|
214
|
+
hydrateCommentScope(node as Comment)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Component name segment of a scope ID (everything before the first `_`). */
|
|
220
|
+
function scopeName(id: string): string | null {
|
|
221
|
+
const idx = id.indexOf('_')
|
|
222
|
+
return idx < 0 ? null : id.slice(0, idx)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function parseProps(json: string | null, where: string): Record<string, unknown> {
|
|
226
|
+
if (!json) return {}
|
|
227
|
+
try {
|
|
228
|
+
return JSON.parse(json) as Record<string, unknown>
|
|
229
|
+
} catch {
|
|
230
|
+
console.warn(`[BarefootJS] Invalid props JSON on ${where}:`, json)
|
|
231
|
+
return {}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function runInit(scope: Element, def: ComponentDef, props: Record<string, unknown>): void {
|
|
236
|
+
const prevScope = setCurrentScope(scope)
|
|
237
|
+
try {
|
|
238
|
+
def.init(scope, props)
|
|
239
|
+
} finally {
|
|
240
|
+
setCurrentScope(prevScope)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function hydrateElementScope(el: Element): void {
|
|
245
|
+
if (hydratedScopes.has(el)) return
|
|
246
|
+
|
|
247
|
+
const bfs = el.getAttribute(BF_SCOPE)
|
|
248
|
+
if (!bfs) return
|
|
249
|
+
// Skip child scopes — parent's initChild call owns their lifecycle.
|
|
250
|
+
// Child detection uses bf-h presence (#1249).
|
|
251
|
+
if (el.hasAttribute(BF_HOST)) return
|
|
252
|
+
|
|
253
|
+
const name = scopeName(bfs)
|
|
254
|
+
if (!name) return
|
|
255
|
+
|
|
256
|
+
const def = registeredDefs.get(name)
|
|
257
|
+
if (!def) return
|
|
258
|
+
|
|
259
|
+
hydratedScopes.add(el)
|
|
260
|
+
// Comment-based components hydrate via the comment-scope path; their
|
|
261
|
+
// bf-s attribute sits on a proxy element. Marking it above lets the
|
|
262
|
+
// next walk skip at the WeakSet check rather than re-resolving the def.
|
|
263
|
+
if (def.comment) return
|
|
264
|
+
|
|
265
|
+
runInit(el, def, parseProps(el.getAttribute(BF_PROPS), bfs))
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function hydrateCommentScope(comment: Comment): void {
|
|
269
|
+
const value = comment.nodeValue
|
|
270
|
+
if (!value?.startsWith(BF_SCOPE_COMMENT_PREFIX)) return
|
|
271
|
+
|
|
272
|
+
const rest = value.slice(BF_SCOPE_COMMENT_PREFIX.length)
|
|
273
|
+
// Comment-scope child detection: child fragment scopes embed host metadata
|
|
274
|
+
// as a `|h=<hostBfs>|m=<slot>` segment after the scope id. Their parent's
|
|
275
|
+
// initChild call owns hydration; the walker must skip them.
|
|
276
|
+
// Root scopes have only `|<propsJson>` (no `h=` segment).
|
|
277
|
+
if (rest.includes('|h=')) return
|
|
278
|
+
|
|
279
|
+
const flagged = comment as unknown as { __bfInitialized?: boolean }
|
|
280
|
+
if (flagged.__bfInitialized) return
|
|
281
|
+
|
|
282
|
+
const pipeIdx = rest.indexOf('|')
|
|
283
|
+
const scopeId = pipeIdx >= 0 ? rest.slice(0, pipeIdx) : rest
|
|
284
|
+
const propsJson = pipeIdx >= 0 ? rest.slice(pipeIdx + 1) : ''
|
|
285
|
+
|
|
286
|
+
const name = scopeName(scopeId)
|
|
287
|
+
if (!name) return
|
|
288
|
+
|
|
289
|
+
const def = registeredDefs.get(name)
|
|
290
|
+
if (!def?.comment) return
|
|
291
|
+
|
|
292
|
+
flagged.__bfInitialized = true
|
|
293
|
+
|
|
294
|
+
const proxyEl = nextElementSibling(comment) ?? comment.parentElement
|
|
295
|
+
if (!proxyEl) return
|
|
296
|
+
|
|
297
|
+
commentScopeRegistry.set(proxyEl, { commentNode: comment, scopeId })
|
|
298
|
+
|
|
299
|
+
const parsed = parseProps(propsJson || null, `comment scope ${scopeId}`)
|
|
300
|
+
const props = (parsed[name] ?? {}) as Record<string, unknown>
|
|
301
|
+
runInit(proxyEl, def, props)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function nextElementSibling(node: Node): Element | null {
|
|
305
|
+
let sibling: Node | null = node.nextSibling
|
|
306
|
+
while (sibling) {
|
|
307
|
+
if (sibling.nodeType === Node.ELEMENT_NODE) return sibling as Element
|
|
308
|
+
sibling = sibling.nextSibling
|
|
309
|
+
}
|
|
310
|
+
return null
|
|
311
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Hydration State
|
|
3
|
+
*
|
|
4
|
+
* Tracks which scope elements have been hydrated using a WeakSet
|
|
5
|
+
* instead of a DOM attribute. This avoids polluting the DOM and
|
|
6
|
+
* enables tree-shaking.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Set of scope elements that have been initialized/hydrated.
|
|
11
|
+
* Used to prevent duplicate initialization.
|
|
12
|
+
*/
|
|
13
|
+
export const hydratedScopes = new WeakSet<Element>()
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Re-export all user-facing @barefootjs/client APIs so compiler-generated
|
|
2
|
+
// code can use a single import source.
|
|
3
|
+
//
|
|
4
|
+
// The reactive runtime has module-local state (`Listener`, `Owner`, the
|
|
5
|
+
// pending-effect queue) and MUST NOT be duplicated across bundles —
|
|
6
|
+
// otherwise a signal created via one copy is invisible to an effect
|
|
7
|
+
// registered via the other. Both `@barefootjs/client` (main) and this
|
|
8
|
+
// `/runtime` entry pull the reactive primitives from the shared
|
|
9
|
+
// `@barefootjs/client/reactive` subpath so downstream bundlers see a
|
|
10
|
+
// single physical module.
|
|
11
|
+
export {
|
|
12
|
+
createSignal,
|
|
13
|
+
createEffect,
|
|
14
|
+
createDisposableEffect,
|
|
15
|
+
createMemo,
|
|
16
|
+
createRoot,
|
|
17
|
+
onCleanup,
|
|
18
|
+
onMount,
|
|
19
|
+
untrack,
|
|
20
|
+
batch,
|
|
21
|
+
type Reactive,
|
|
22
|
+
type Signal,
|
|
23
|
+
type Memo,
|
|
24
|
+
type CleanupFn,
|
|
25
|
+
type EffectFn,
|
|
26
|
+
} from '@barefootjs/client/reactive'
|
|
27
|
+
|
|
28
|
+
export { splitProps } from '../split-props'
|
|
29
|
+
export { __slot, type SlotMarker } from '../slot'
|
|
30
|
+
export { forwardProps } from '../forward-props'
|
|
31
|
+
export { unwrap } from '../unwrap'
|
|
32
|
+
|
|
33
|
+
// Context API (real DOM-bound implementations; `createContext` is the
|
|
34
|
+
// same pure function re-exported from `../context`).
|
|
35
|
+
export {
|
|
36
|
+
createContext,
|
|
37
|
+
useContext,
|
|
38
|
+
provideContext,
|
|
39
|
+
setCurrentScope,
|
|
40
|
+
type Context,
|
|
41
|
+
} from './context'
|
|
42
|
+
|
|
43
|
+
// Portal system
|
|
44
|
+
export {
|
|
45
|
+
createPortal,
|
|
46
|
+
isSSRPortal,
|
|
47
|
+
findSiblingSlot,
|
|
48
|
+
cleanupPortalPlaceholder,
|
|
49
|
+
type Portal,
|
|
50
|
+
type PortalOptions,
|
|
51
|
+
type Renderable,
|
|
52
|
+
type PortalChildren,
|
|
53
|
+
} from './portal'
|
|
54
|
+
|
|
55
|
+
// List reconciliation
|
|
56
|
+
export { reconcileList, type RenderItemFn } from './list'
|
|
57
|
+
export { reconcileElements, getLoopChildren, getLoopNodes } from './reconcile-elements'
|
|
58
|
+
export { qsaItem, upsertChildItem } from './qsa-item'
|
|
59
|
+
export { mapArray } from './map-array'
|
|
60
|
+
|
|
61
|
+
// Template registry
|
|
62
|
+
export { registerTemplate, getTemplate, hasTemplate, type TemplateFn } from './template'
|
|
63
|
+
|
|
64
|
+
// Component creation
|
|
65
|
+
export {
|
|
66
|
+
createComponent,
|
|
67
|
+
renderChild,
|
|
68
|
+
getPropsUpdateFn,
|
|
69
|
+
getComponentProps,
|
|
70
|
+
parseHTML,
|
|
71
|
+
} from './component'
|
|
72
|
+
|
|
73
|
+
// Spread props helpers
|
|
74
|
+
export { applyRestAttrs } from './apply-rest-attrs'
|
|
75
|
+
export { spreadAttrs } from './spread-attrs'
|
|
76
|
+
export { styleToCss } from './style'
|
|
77
|
+
|
|
78
|
+
// Runtime helpers
|
|
79
|
+
export { findScope, find, $, $c, $t, qsa, qsaChildScope, qsaChildScopes, cssEscape } from './query'
|
|
80
|
+
export { hydrate, rehydrateAll, flushHydration, getRegisteredDef } from './hydrate'
|
|
81
|
+
export { registerComponent, getComponentInit, initChild, upsertChild } from './registry'
|
|
82
|
+
export { insert, type BranchConfig, type BranchTemplateResult } from './insert'
|
|
83
|
+
export { __bfSlot } from './branch-slot'
|
|
84
|
+
export { updateClientMarker } from './client-marker'
|
|
85
|
+
|
|
86
|
+
// Hydration state
|
|
87
|
+
export { hydratedScopes } from './hydration-state'
|
|
88
|
+
|
|
89
|
+
// CSR entry point
|
|
90
|
+
export { render } from './render'
|
|
91
|
+
|
|
92
|
+
// Streaming (Out-of-Order SSR)
|
|
93
|
+
export { __bf_swap, setupStreaming } from './streaming'
|
|
94
|
+
|
|
95
|
+
// Core types
|
|
96
|
+
export type { InitFn, ComponentDef } from './types'
|