@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
package/dist/reactive.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// src/reactive.ts
|
|
2
|
+
var Owner = null;
|
|
3
|
+
var Listener = null;
|
|
4
|
+
var MAX_EFFECT_RUNS = 100;
|
|
5
|
+
var BatchDepth = 0;
|
|
6
|
+
var PendingEffects = new Set;
|
|
7
|
+
function createSignal(initialValue) {
|
|
8
|
+
let value = initialValue;
|
|
9
|
+
const subscribers = new Set;
|
|
10
|
+
const get = () => {
|
|
11
|
+
if (Listener) {
|
|
12
|
+
subscribers.add(Listener);
|
|
13
|
+
Listener.dependencies.add(subscribers);
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
};
|
|
17
|
+
const set = (valueOrFn) => {
|
|
18
|
+
const newValue = typeof valueOrFn === "function" ? valueOrFn(value) : valueOrFn;
|
|
19
|
+
if (Object.is(value, newValue)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
value = newValue;
|
|
23
|
+
if (BatchDepth > 0) {
|
|
24
|
+
for (const effect of subscribers) {
|
|
25
|
+
PendingEffects.add(effect);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
const effectsToRun = [...subscribers];
|
|
29
|
+
for (const effect of effectsToRun) {
|
|
30
|
+
runEffect(effect);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
return [get, set];
|
|
35
|
+
}
|
|
36
|
+
function createEffect(fn) {
|
|
37
|
+
const effect = {
|
|
38
|
+
fn,
|
|
39
|
+
cleanup: null,
|
|
40
|
+
dependencies: new Set,
|
|
41
|
+
owner: Owner,
|
|
42
|
+
children: [],
|
|
43
|
+
disposed: false,
|
|
44
|
+
runCount: 0
|
|
45
|
+
};
|
|
46
|
+
if (Owner)
|
|
47
|
+
Owner.children.push(effect);
|
|
48
|
+
runEffect(effect);
|
|
49
|
+
}
|
|
50
|
+
function runEffect(effect) {
|
|
51
|
+
if (effect.disposed)
|
|
52
|
+
return;
|
|
53
|
+
effect.runCount++;
|
|
54
|
+
if (effect.runCount > MAX_EFFECT_RUNS) {
|
|
55
|
+
effect.runCount = 0;
|
|
56
|
+
throw new Error(`Circular dependency detected: effect re-entered itself ${MAX_EFFECT_RUNS} times.`);
|
|
57
|
+
}
|
|
58
|
+
if (effect.cleanup) {
|
|
59
|
+
effect.cleanup();
|
|
60
|
+
effect.cleanup = null;
|
|
61
|
+
}
|
|
62
|
+
for (const dep of effect.dependencies) {
|
|
63
|
+
dep.delete(effect);
|
|
64
|
+
}
|
|
65
|
+
effect.dependencies.clear();
|
|
66
|
+
const prevOwner = Owner;
|
|
67
|
+
const prevListener = Listener;
|
|
68
|
+
Owner = effect;
|
|
69
|
+
Listener = effect;
|
|
70
|
+
try {
|
|
71
|
+
const result = effect.fn();
|
|
72
|
+
if (typeof result === "function") {
|
|
73
|
+
effect.cleanup = result;
|
|
74
|
+
}
|
|
75
|
+
} finally {
|
|
76
|
+
Owner = prevOwner;
|
|
77
|
+
Listener = prevListener;
|
|
78
|
+
effect.runCount--;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function disposeSubtree(effect) {
|
|
82
|
+
if (effect.disposed)
|
|
83
|
+
return;
|
|
84
|
+
effect.disposed = true;
|
|
85
|
+
for (const child of effect.children) {
|
|
86
|
+
disposeSubtree(child);
|
|
87
|
+
}
|
|
88
|
+
effect.children.length = 0;
|
|
89
|
+
if (effect.cleanup) {
|
|
90
|
+
effect.cleanup();
|
|
91
|
+
effect.cleanup = null;
|
|
92
|
+
}
|
|
93
|
+
for (const dep of effect.dependencies) {
|
|
94
|
+
dep.delete(effect);
|
|
95
|
+
}
|
|
96
|
+
effect.dependencies.clear();
|
|
97
|
+
effect.owner = null;
|
|
98
|
+
}
|
|
99
|
+
function disposeEffect(effect) {
|
|
100
|
+
if (effect.disposed)
|
|
101
|
+
return;
|
|
102
|
+
if (effect.owner) {
|
|
103
|
+
const idx = effect.owner.children.indexOf(effect);
|
|
104
|
+
if (idx >= 0)
|
|
105
|
+
effect.owner.children.splice(idx, 1);
|
|
106
|
+
}
|
|
107
|
+
disposeSubtree(effect);
|
|
108
|
+
}
|
|
109
|
+
function createRoot(fn) {
|
|
110
|
+
const root = {
|
|
111
|
+
fn: () => {},
|
|
112
|
+
cleanup: null,
|
|
113
|
+
dependencies: new Set,
|
|
114
|
+
owner: Owner,
|
|
115
|
+
children: [],
|
|
116
|
+
disposed: false,
|
|
117
|
+
runCount: 0
|
|
118
|
+
};
|
|
119
|
+
if (Owner)
|
|
120
|
+
Owner.children.push(root);
|
|
121
|
+
const prevOwner = Owner;
|
|
122
|
+
const prevListener = Listener;
|
|
123
|
+
Owner = root;
|
|
124
|
+
Listener = null;
|
|
125
|
+
try {
|
|
126
|
+
return fn(() => disposeEffect(root));
|
|
127
|
+
} finally {
|
|
128
|
+
Owner = prevOwner;
|
|
129
|
+
Listener = prevListener;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function createDisposableEffect(fn) {
|
|
133
|
+
let disposed = false;
|
|
134
|
+
const effect = {
|
|
135
|
+
fn: () => {
|
|
136
|
+
if (disposed)
|
|
137
|
+
return;
|
|
138
|
+
return fn();
|
|
139
|
+
},
|
|
140
|
+
cleanup: null,
|
|
141
|
+
dependencies: new Set,
|
|
142
|
+
owner: Owner,
|
|
143
|
+
children: [],
|
|
144
|
+
disposed: false,
|
|
145
|
+
runCount: 0
|
|
146
|
+
};
|
|
147
|
+
if (Owner)
|
|
148
|
+
Owner.children.push(effect);
|
|
149
|
+
runEffect(effect);
|
|
150
|
+
return () => {
|
|
151
|
+
disposeEffect(effect);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function onCleanup(fn) {
|
|
155
|
+
if (Owner) {
|
|
156
|
+
const effect = Owner;
|
|
157
|
+
const prevCleanup = effect.cleanup;
|
|
158
|
+
effect.cleanup = () => {
|
|
159
|
+
if (prevCleanup)
|
|
160
|
+
prevCleanup();
|
|
161
|
+
fn();
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function untrack(fn) {
|
|
166
|
+
const prevListener = Listener;
|
|
167
|
+
Listener = null;
|
|
168
|
+
try {
|
|
169
|
+
return fn();
|
|
170
|
+
} finally {
|
|
171
|
+
Listener = prevListener;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function batch(fn) {
|
|
175
|
+
BatchDepth++;
|
|
176
|
+
try {
|
|
177
|
+
return fn();
|
|
178
|
+
} finally {
|
|
179
|
+
BatchDepth--;
|
|
180
|
+
if (BatchDepth === 0) {
|
|
181
|
+
flushEffects();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function flushEffects() {
|
|
186
|
+
while (PendingEffects.size > 0) {
|
|
187
|
+
const effects = [...PendingEffects];
|
|
188
|
+
PendingEffects.clear();
|
|
189
|
+
for (const effect of effects) {
|
|
190
|
+
runEffect(effect);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function onMount(fn) {
|
|
195
|
+
createEffect(() => untrack(fn));
|
|
196
|
+
}
|
|
197
|
+
function createMemo(fn) {
|
|
198
|
+
const [value, setValue] = createSignal(undefined);
|
|
199
|
+
createEffect(() => {
|
|
200
|
+
const result = fn();
|
|
201
|
+
setValue(() => result);
|
|
202
|
+
});
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
untrack,
|
|
207
|
+
onMount,
|
|
208
|
+
onCleanup,
|
|
209
|
+
createSignal,
|
|
210
|
+
createRoot,
|
|
211
|
+
createMemo,
|
|
212
|
+
createEffect,
|
|
213
|
+
createDisposableEffect,
|
|
214
|
+
batch
|
|
215
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Apply Rest Attributes Helper
|
|
3
|
+
*
|
|
4
|
+
* Applies spread attributes to HTML elements at hydration time.
|
|
5
|
+
* Used when spread props cannot be statically expanded (open types).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Reactively apply rest attributes from a props source onto an HTML element.
|
|
9
|
+
* Runs inside a createEffect so attribute values update when props change.
|
|
10
|
+
*
|
|
11
|
+
* @param el - The target DOM element
|
|
12
|
+
* @param source - The props/rest object to read attributes from
|
|
13
|
+
* @param excludeKeys - Keys already handled statically (don't apply twice)
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyRestAttrs(el: Element, source: Record<string, unknown>, excludeKeys: string[]): void;
|
|
16
|
+
//# sourceMappingURL=apply-rest-attrs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-rest-attrs.d.ts","sourceRoot":"","sources":["../../src/runtime/apply-rest-attrs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,OAAO,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,WAAW,EAAE,MAAM,EAAE,GACpB,IAAI,CAkEN"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branch-template slot helper (#1213).
|
|
3
|
+
*
|
|
4
|
+
* Conditional `template()` arrows interpolate Child-position expressions
|
|
5
|
+
* via `${expr}`. When `expr` evaluates to a live `Node` (e.g. the result
|
|
6
|
+
* of `_p.renderNode(node())` returning an `HTMLElement` from
|
|
7
|
+
* `createComponent`), the surrounding template literal coerces it via
|
|
8
|
+
* `Object.prototype.toString`, producing `"[object HTMLDivElement]"` and
|
|
9
|
+
* destroying the live node identity on hydration.
|
|
10
|
+
*
|
|
11
|
+
* `__bfSlot` intercepts the value before stringification: if it's a
|
|
12
|
+
* `Node`, it stashes the node into the closure-scoped `slots` array and
|
|
13
|
+
* returns a unique marker comment. The `insert()` runtime then walks the
|
|
14
|
+
* parsed fragment for those markers and splices the original node back
|
|
15
|
+
* in by identity (no `cloneNode`), preserving event listeners and signal
|
|
16
|
+
* bindings.
|
|
17
|
+
*
|
|
18
|
+
* Non-node values fall through to `String(value)` for the existing
|
|
19
|
+
* inline-string path.
|
|
20
|
+
*/
|
|
21
|
+
export declare function __bfSlot(value: unknown, slots: Node[]): string;
|
|
22
|
+
//# sourceMappingURL=branch-slot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-slot.d.ts","sourceRoot":"","sources":["../../src/runtime/branch-slot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAW9D"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Client Marker
|
|
3
|
+
*
|
|
4
|
+
* Update text content for @client directive expressions
|
|
5
|
+
* that are evaluated only on the client side.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Update text content for a client marker.
|
|
9
|
+
*
|
|
10
|
+
* Expects comment marker format: <!--bf-client:sX-->
|
|
11
|
+
* Both GoTemplateAdapter and HonoAdapter output this format for @client directives.
|
|
12
|
+
*
|
|
13
|
+
* A zero-width space (\u200B) is used as a prefix to mark text nodes managed by @client.
|
|
14
|
+
* This allows distinguishing managed text nodes from other content.
|
|
15
|
+
*
|
|
16
|
+
* @param scope - The component scope element to search within
|
|
17
|
+
* @param id - The slot ID (e.g., 's5')
|
|
18
|
+
* @param value - The value to display (will be converted to string)
|
|
19
|
+
*/
|
|
20
|
+
export declare function updateClientMarker(scope: Element | null, id: string, value: unknown): void;
|
|
21
|
+
//# sourceMappingURL=client-marker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-marker.d.ts","sourceRoot":"","sources":["../../src/runtime/client-marker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAyB1F"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Component Creation
|
|
3
|
+
*
|
|
4
|
+
* Functions for dynamically creating component instances at runtime.
|
|
5
|
+
* Used by reconcileList() when rendering components in loops.
|
|
6
|
+
*/
|
|
7
|
+
import type { ComponentDef } from './types';
|
|
8
|
+
export declare function setParentScopeId(id: string | null): void;
|
|
9
|
+
/**
|
|
10
|
+
* Create a component instance with DOM element and initialized state.
|
|
11
|
+
*
|
|
12
|
+
* This function:
|
|
13
|
+
* 1. Gets the template function for the component
|
|
14
|
+
* 2. Generates HTML from props using the template
|
|
15
|
+
* 3. Creates DOM element from HTML
|
|
16
|
+
* 4. Sets scope ID and key attributes
|
|
17
|
+
* 5. Initializes the component (attaches event handlers, sets up effects)
|
|
18
|
+
*
|
|
19
|
+
* @param name - Component name (e.g., 'TodoItem')
|
|
20
|
+
* @param props - Props to pass to the component
|
|
21
|
+
* @param key - Optional key for list reconciliation
|
|
22
|
+
* @returns Created DOM element
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const el = createComponent('TodoItem', {
|
|
26
|
+
* todo: { id: 1, text: 'Buy milk', done: false },
|
|
27
|
+
* onDelete: () => handleDelete(1)
|
|
28
|
+
* }, 1)
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Create a component instance from a string name (SSR mode, uses registry)
|
|
32
|
+
* or from a ComponentDef (CSR mode, no registry needed).
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Slot-relationship metadata stamped onto a freshly-created component as
|
|
36
|
+
* `bf-h` / `bf-m`. Top-level CSR mounts pass no `slot` — they own their
|
|
37
|
+
* own hydration lifecycle and `initChild` re-binds callbacks freely on
|
|
38
|
+
* each reconcile.
|
|
39
|
+
*/
|
|
40
|
+
export interface CreateComponentSlotInfo {
|
|
41
|
+
/** Host scope id (this child's `bf-h` value). */
|
|
42
|
+
parent: string;
|
|
43
|
+
/** Slot id in the host (this child's `bf-m` value). */
|
|
44
|
+
mount: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function createComponent(nameOrDef: string | ComponentDef, props: Record<string, unknown>, key?: string | number, slot?: CreateComponentSlotInfo): HTMLElement;
|
|
47
|
+
/**
|
|
48
|
+
* Get the props stored for a component element.
|
|
49
|
+
* Used by reconcileList to pass props to an existing element.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getComponentProps(element: HTMLElement): Record<string, unknown> | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Get the props update function for an element.
|
|
54
|
+
* Used by reconcileList to update props when reusing an element.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getPropsUpdateFn(element: HTMLElement): ((props: Record<string, unknown>) => void) | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Render a child component's template to an HTML string.
|
|
59
|
+
* Used by compiler-generated template functions when a stateless component
|
|
60
|
+
* appears inside a conditional branch or loop template.
|
|
61
|
+
*
|
|
62
|
+
* If the component has a registered template, it renders the HTML and injects
|
|
63
|
+
* a bf-s scope attribute. Otherwise, falls back to an empty placeholder.
|
|
64
|
+
*
|
|
65
|
+
* @param name - Component name (e.g., 'Spinner')
|
|
66
|
+
* @param props - Props to pass to the template
|
|
67
|
+
* @param key - Optional key for list reconciliation
|
|
68
|
+
* @returns HTML string with scope marker
|
|
69
|
+
*/
|
|
70
|
+
export declare function renderChild(name: string, props: Record<string, unknown>, key?: string | number, slotSuffix?: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Escape ">" inside HTML attribute values to prevent broken parsing.
|
|
73
|
+
* UnoCSS classes like has-[>svg]:shrink-0 contain ">" which terminates
|
|
74
|
+
* the opening tag when parsed via innerHTML. The browser decodes >
|
|
75
|
+
* back to ">" in the DOM attribute value, preserving CSS matching.
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* Escape ">" inside HTML attribute values to prevent broken parsing.
|
|
79
|
+
* UnoCSS classes like has-[>svg]:shrink-0 contain ">" which terminates
|
|
80
|
+
* the opening tag when parsed via innerHTML. The browser decodes >
|
|
81
|
+
* back to ">" in the DOM attribute value, preserving CSS matching.
|
|
82
|
+
*/
|
|
83
|
+
export declare function escapeAttrGt(html: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Parse an HTML string into a DocumentFragment, safely escaping ">" in
|
|
86
|
+
* attribute values. All code that sets innerHTML on dynamic HTML should
|
|
87
|
+
* use this instead of raw innerHTML assignment.
|
|
88
|
+
*
|
|
89
|
+
* When `parent` is provided and lives in the SVG namespace, the markup
|
|
90
|
+
* is parsed under SVG foreign-content context by wrapping it in
|
|
91
|
+
* `<svg>...</svg>`; the wrapper's children are moved into the returned
|
|
92
|
+
* fragment so callers see the same shape as the HTML path. Without
|
|
93
|
+
* this, dynamically-inserted SVG elements (e.g., a `<path>` in a
|
|
94
|
+
* conditional drag preview) end up as `HTMLUnknownElement` in the
|
|
95
|
+
* xhtml namespace and the SVG renderer ignores them. Surfaced by the
|
|
96
|
+
* Graph/DAG Editor block (#135).
|
|
97
|
+
*/
|
|
98
|
+
export declare function parseHTML(html: string, parent?: Element | null): DocumentFragment;
|
|
99
|
+
//# sourceMappingURL=component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/runtime/component.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAS3C,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExD;AAWD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;GAGG;AACH;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,GAAG,YAAY,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,WAAW,CAyHb;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAE3F;AAuBD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,CAE7G;AAGD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAiDR;AA+DD;;;;;GAKG;AACH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAcjF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context API: DOM-bound runtime portion.
|
|
3
|
+
*
|
|
4
|
+
* `useContext` and `provideContext` walk the DOM (scope-based) to locate
|
|
5
|
+
* the nearest provider. Portal elements (with bf-po attribute) follow
|
|
6
|
+
* the logical owner chain.
|
|
7
|
+
*
|
|
8
|
+
* A global store is kept as a fallback for non-scoped usage.
|
|
9
|
+
*/
|
|
10
|
+
import type { Context } from '../context';
|
|
11
|
+
export { createContext, type Context } from '../context';
|
|
12
|
+
/**
|
|
13
|
+
* Set the current scope element for context operations.
|
|
14
|
+
* Called by initChild to scope provideContext/useContext to the correct element.
|
|
15
|
+
* Returns the previous scope for restoration.
|
|
16
|
+
*/
|
|
17
|
+
export declare function setCurrentScope(scope: Element | null): Element | null;
|
|
18
|
+
/**
|
|
19
|
+
* Read the current value of a context.
|
|
20
|
+
*
|
|
21
|
+
* Walks up the DOM tree from the current scope element to find
|
|
22
|
+
* the nearest ancestor that provided this context. Falls back to
|
|
23
|
+
* the global store, then to the context's default value, then to
|
|
24
|
+
* `undefined`.
|
|
25
|
+
*
|
|
26
|
+
* Returning `undefined` (rather than throwing) when no provider is
|
|
27
|
+
* available lets templates evaluate safely before init has run
|
|
28
|
+
* `provideContext` — init's `createEffect` repaints once the
|
|
29
|
+
* provider is set up. See piconic-ai/barefootjs#1156.
|
|
30
|
+
*/
|
|
31
|
+
export declare function useContext<T>(context: Context<T>): T;
|
|
32
|
+
/**
|
|
33
|
+
* Provide a value for a context.
|
|
34
|
+
*
|
|
35
|
+
* Stores the value on the current scope DOM element so that child
|
|
36
|
+
* components can find it via useContext's DOM ancestor walk.
|
|
37
|
+
* Also sets the global store as fallback.
|
|
38
|
+
*/
|
|
39
|
+
export declare function provideContext<T>(context: Context<T>, value: T): void;
|
|
40
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAA;AAWxD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAIrE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CA2BpD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CA0BrE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
import type { ComponentDef } from './types';
|
|
40
|
+
/**
|
|
41
|
+
* Look up a registered component definition by name. Used by the CSR
|
|
42
|
+
* `createComponent` path to honour `comment: true` (transparent
|
|
43
|
+
* wrapper) components — without the def lookup, those components
|
|
44
|
+
* overwrite the inner element's `bf-s` and break child-scope
|
|
45
|
+
* resolution at hydration.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getRegisteredDef(name: string): ComponentDef | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Register a component and schedule a document-order hydration walk.
|
|
50
|
+
* Combines registration + template setup + hydration in a single call.
|
|
51
|
+
*
|
|
52
|
+
* **Scheduling semantics** (changed in #1172): the walk runs on the
|
|
53
|
+
* next microtask, then again on the next animation frame. The init
|
|
54
|
+
* functions for registered components are *not* invoked synchronously
|
|
55
|
+
* inside `hydrate()`. Code that needs to observe init effects on the
|
|
56
|
+
* same tick — typically tests, but also advanced consumers wiring
|
|
57
|
+
* imperative bridges — should either:
|
|
58
|
+
*
|
|
59
|
+
* - `await Promise.resolve()` after a batch of `hydrate()` calls, or
|
|
60
|
+
* - call `flushHydration()` (see below) to drain any pending walks
|
|
61
|
+
* synchronously.
|
|
62
|
+
*
|
|
63
|
+
* The deferral is what lets the doc-order walker see a fully populated
|
|
64
|
+
* registry: every `hydrate()` call from the bundled module body lands
|
|
65
|
+
* in the registry *before* the microtask flush kicks off the single
|
|
66
|
+
* walk, so parents always init before their descendants regardless of
|
|
67
|
+
* which file the parent's `hydrate()` was emitted into.
|
|
68
|
+
*
|
|
69
|
+
* @param name - Component name
|
|
70
|
+
* @param def - Component definition (init function + optional template + comment flag)
|
|
71
|
+
*/
|
|
72
|
+
export declare function hydrate(name: string, def: ComponentDef): void;
|
|
73
|
+
/**
|
|
74
|
+
* Re-hydrate all registered components.
|
|
75
|
+
*
|
|
76
|
+
* Called by the streaming resolver after swapping fallback content with
|
|
77
|
+
* resolved content. Goes through the same scheduler as `hydrate()` so
|
|
78
|
+
* back-to-back `__bf_swap` invocations or interleaved `hydrate()` calls
|
|
79
|
+
* collapse to a single walk per tick + per frame. Like `hydrate()` this
|
|
80
|
+
* is asynchronous — see `flushHydration()` if you need a synchronous
|
|
81
|
+
* drain.
|
|
82
|
+
*/
|
|
83
|
+
export declare function rehydrateAll(): void;
|
|
84
|
+
/**
|
|
85
|
+
* Run any pending hydration walk synchronously, right now.
|
|
86
|
+
*
|
|
87
|
+
* The default scheduler is microtask + rAF — the right trade-off for
|
|
88
|
+
* production code (registry populates before the walk; back-to-back
|
|
89
|
+
* `hydrate()` calls coalesce). Tests and advanced consumers that need
|
|
90
|
+
* a deterministic completion point — e.g. imperative mounting code
|
|
91
|
+
* reading DOM state immediately after `render(...)` — call this
|
|
92
|
+
* helper instead of awaiting a microtask.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* hydrate('Counter', def)
|
|
96
|
+
* flushHydration()
|
|
97
|
+
* // safe to read Counter's post-init DOM state
|
|
98
|
+
*/
|
|
99
|
+
export declare function flushHydration(): void;
|
|
100
|
+
//# sourceMappingURL=hydrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../src/runtime/hydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAS3C;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEvE;AA8CD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,CAgB7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAKrC"}
|
|
@@ -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
|
+
* Set of scope elements that have been initialized/hydrated.
|
|
10
|
+
* Used to prevent duplicate initialization.
|
|
11
|
+
*/
|
|
12
|
+
export declare const hydratedScopes: WeakSet<Element>;
|
|
13
|
+
//# sourceMappingURL=hydration-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydration-state.d.ts","sourceRoot":"","sources":["../../src/runtime/hydration-state.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;GAGG;AACH,eAAO,MAAM,cAAc,kBAAyB,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { createSignal, createEffect, createDisposableEffect, createMemo, createRoot, onCleanup, onMount, untrack, batch, type Reactive, type Signal, type Memo, type CleanupFn, type EffectFn, } from '@barefootjs/client/reactive';
|
|
2
|
+
export { splitProps } from '../split-props';
|
|
3
|
+
export { __slot, type SlotMarker } from '../slot';
|
|
4
|
+
export { forwardProps } from '../forward-props';
|
|
5
|
+
export { unwrap } from '../unwrap';
|
|
6
|
+
export { createContext, useContext, provideContext, setCurrentScope, type Context, } from './context';
|
|
7
|
+
export { createPortal, isSSRPortal, findSiblingSlot, cleanupPortalPlaceholder, type Portal, type PortalOptions, type Renderable, type PortalChildren, } from './portal';
|
|
8
|
+
export { reconcileList, type RenderItemFn } from './list';
|
|
9
|
+
export { reconcileElements, getLoopChildren, getLoopNodes } from './reconcile-elements';
|
|
10
|
+
export { qsaItem, upsertChildItem } from './qsa-item';
|
|
11
|
+
export { mapArray } from './map-array';
|
|
12
|
+
export { registerTemplate, getTemplate, hasTemplate, type TemplateFn } from './template';
|
|
13
|
+
export { createComponent, renderChild, getPropsUpdateFn, getComponentProps, parseHTML, } from './component';
|
|
14
|
+
export { applyRestAttrs } from './apply-rest-attrs';
|
|
15
|
+
export { spreadAttrs } from './spread-attrs';
|
|
16
|
+
export { styleToCss } from './style';
|
|
17
|
+
export { findScope, find, $, $c, $t, qsa, qsaChildScope, qsaChildScopes, cssEscape } from './query';
|
|
18
|
+
export { hydrate, rehydrateAll, flushHydration, getRegisteredDef } from './hydrate';
|
|
19
|
+
export { registerComponent, getComponentInit, initChild, upsertChild } from './registry';
|
|
20
|
+
export { insert, type BranchConfig, type BranchTemplateResult } from './insert';
|
|
21
|
+
export { __bfSlot } from './branch-slot';
|
|
22
|
+
export { updateClientMarker } from './client-marker';
|
|
23
|
+
export { hydratedScopes } from './hydration-state';
|
|
24
|
+
export { render } from './render';
|
|
25
|
+
export { __bf_swap, setupStreaming } from './streaming';
|
|
26
|
+
export type { InitFn, ComponentDef } from './types';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,OAAO,EACP,KAAK,EACL,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,QAAQ,GACd,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAIlC,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,eAAe,EACf,KAAK,OAAO,GACb,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,eAAe,EACf,wBAAwB,EACxB,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,cAAc,GACpB,MAAM,UAAU,CAAA;AAGjB,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACvF,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGtC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAA;AAGxF,OAAO,EACL,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGpC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnG,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACnF,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxF,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAGpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAGjC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGvD,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA"}
|