@barefootjs/client 0.5.3 → 0.6.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.
|
@@ -1 +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,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,WAAW,
|
|
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,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,WAAW,CAgLb;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;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEjD;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,gBAAgB,CAcjF"}
|
package/dist/runtime/index.js
CHANGED
|
@@ -123,6 +123,7 @@ function loopEndMarker(markerId) {
|
|
|
123
123
|
return `${BF_LOOP_END}:${markerId}`;
|
|
124
124
|
}
|
|
125
125
|
var BF_KEY = "data-key";
|
|
126
|
+
var BF_PLACEHOLDER = "data-bf-ph";
|
|
126
127
|
var BF_ASYNC = "bf-async";
|
|
127
128
|
var BF_ASYNC_RESOLVE = "bf-async-resolve";
|
|
128
129
|
var BF_PARENT_SCOPE_PLACEHOLDER = "__BF_PARENT_SCOPE__";
|
|
@@ -793,7 +794,7 @@ function upsertChild(parent, name, slotId, props, key, anchorScope) {
|
|
|
793
794
|
return ssr;
|
|
794
795
|
}
|
|
795
796
|
const phId = slotId ?? name;
|
|
796
|
-
const ph = parent.querySelector(`[
|
|
797
|
+
const ph = parent.getAttribute(BF_PLACEHOLDER) === phId ? parent : parent.querySelector(`[${BF_PLACEHOLDER}="${phId}"]`);
|
|
797
798
|
if (ph) {
|
|
798
799
|
const slot = slotId ? buildSlotInfo(parent, slotId, anchorScope) : undefined;
|
|
799
800
|
const comp = createComponent(name, props, key, slot);
|
|
@@ -1019,10 +1020,24 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1019
1020
|
element.setAttribute(BF_KEY, String(key));
|
|
1020
1021
|
}
|
|
1021
1022
|
const prevScope = setCurrentScope(element);
|
|
1023
|
+
const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER);
|
|
1024
|
+
let placeholderWrapper = null;
|
|
1025
|
+
if (rootIsDeferredPlaceholder) {
|
|
1026
|
+
placeholderWrapper = parseHTML("<div></div>").firstChild;
|
|
1027
|
+
placeholderWrapper.appendChild(element);
|
|
1028
|
+
}
|
|
1022
1029
|
const initFn = getComponentInit(name);
|
|
1023
1030
|
if (initFn) {
|
|
1024
1031
|
initFn(element, props);
|
|
1025
1032
|
}
|
|
1033
|
+
if (rootIsDeferredPlaceholder && placeholderWrapper) {
|
|
1034
|
+
const materialised = placeholderWrapper.firstElementChild;
|
|
1035
|
+
if (materialised && !materialised.hasAttribute(BF_PLACEHOLDER)) {
|
|
1036
|
+
setCurrentScope(prevScope);
|
|
1037
|
+
return materialised;
|
|
1038
|
+
}
|
|
1039
|
+
placeholderWrapper.removeChild(element);
|
|
1040
|
+
}
|
|
1026
1041
|
if (childrenIsGetter) {
|
|
1027
1042
|
const children = untrack(() => childrenDescriptor.get());
|
|
1028
1043
|
if (children != null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/runtime/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAarC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAclE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,GAAG,IAAI,EAC1B,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAClC,IAAI,CAoCN;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,GAC3B,WAAW,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/runtime/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAarC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAclE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,GAAG,IAAI,EAC1B,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAClC,IAAI,CAoCN;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EACrB,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,GAC3B,WAAW,GAAG,IAAI,CA8BpB"}
|
|
@@ -314,6 +314,7 @@ function loopEndMarker(markerId) {
|
|
|
314
314
|
return `${BF_LOOP_END}:${markerId}`;
|
|
315
315
|
}
|
|
316
316
|
var BF_KEY = "data-key";
|
|
317
|
+
var BF_PLACEHOLDER = "data-bf-ph";
|
|
317
318
|
var BF_ASYNC = "bf-async";
|
|
318
319
|
var BF_ASYNC_RESOLVE = "bf-async-resolve";
|
|
319
320
|
var BF_PARENT_SCOPE_PLACEHOLDER = "__BF_PARENT_SCOPE__";
|
|
@@ -984,7 +985,7 @@ function upsertChild(parent, name, slotId, props, key, anchorScope) {
|
|
|
984
985
|
return ssr;
|
|
985
986
|
}
|
|
986
987
|
const phId = slotId ?? name;
|
|
987
|
-
const ph = parent.querySelector(`[
|
|
988
|
+
const ph = parent.getAttribute(BF_PLACEHOLDER) === phId ? parent : parent.querySelector(`[${BF_PLACEHOLDER}="${phId}"]`);
|
|
988
989
|
if (ph) {
|
|
989
990
|
const slot = slotId ? buildSlotInfo(parent, slotId, anchorScope) : undefined;
|
|
990
991
|
const comp = createComponent(name, props, key, slot);
|
|
@@ -1209,10 +1210,24 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1209
1210
|
element.setAttribute(BF_KEY, String(key));
|
|
1210
1211
|
}
|
|
1211
1212
|
const prevScope = setCurrentScope(element);
|
|
1213
|
+
const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER);
|
|
1214
|
+
let placeholderWrapper = null;
|
|
1215
|
+
if (rootIsDeferredPlaceholder) {
|
|
1216
|
+
placeholderWrapper = parseHTML("<div></div>").firstChild;
|
|
1217
|
+
placeholderWrapper.appendChild(element);
|
|
1218
|
+
}
|
|
1212
1219
|
const initFn = getComponentInit(name);
|
|
1213
1220
|
if (initFn) {
|
|
1214
1221
|
initFn(element, props);
|
|
1215
1222
|
}
|
|
1223
|
+
if (rootIsDeferredPlaceholder && placeholderWrapper) {
|
|
1224
|
+
const materialised = placeholderWrapper.firstElementChild;
|
|
1225
|
+
if (materialised && !materialised.hasAttribute(BF_PLACEHOLDER)) {
|
|
1226
|
+
setCurrentScope(prevScope);
|
|
1227
|
+
return materialised;
|
|
1228
|
+
}
|
|
1229
|
+
placeholderWrapper.removeChild(element);
|
|
1230
|
+
}
|
|
1216
1231
|
if (childrenIsGetter) {
|
|
1217
1232
|
const children = untrack(() => childrenDescriptor.get());
|
|
1218
1233
|
if (children != null) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "BarefootJS client package: reactive primitives (SSR-safe) plus browser runtime under the `/runtime` subpath (compiler target)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"directory": "packages/client"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@barefootjs/shared": "0.
|
|
58
|
+
"@barefootjs/shared": "0.6.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@barefootjs/jsx": ">=0.2.0"
|
package/src/runtime/component.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { getRegisteredDef } from './hydrate'
|
|
|
11
11
|
import { hydratedScopes } from './hydration-state'
|
|
12
12
|
import { untrack } from '@barefootjs/client/reactive'
|
|
13
13
|
import { setCurrentScope } from './context'
|
|
14
|
-
import { BF_SCOPE, BF_KEY, BF_HOST, BF_AT, BF_PARENT_SCOPE_PLACEHOLDER } from '@barefootjs/shared'
|
|
14
|
+
import { BF_SCOPE, BF_KEY, BF_HOST, BF_AT, BF_PARENT_SCOPE_PLACEHOLDER, BF_PLACEHOLDER } from '@barefootjs/shared'
|
|
15
15
|
import type { ComponentDef } from './types'
|
|
16
16
|
|
|
17
17
|
// Parent scope ID context for renderChild() inside insert() branch templates.
|
|
@@ -186,13 +186,52 @@ export function createComponent(
|
|
|
186
186
|
// This allows context providers in initFn to store context on this element.
|
|
187
187
|
const prevScope = setCurrentScope(element)
|
|
188
188
|
|
|
189
|
+
// 8b. Root-level deferred child (dropped-prop fix): a comment-wrapper
|
|
190
|
+
// parent whose entire render is a single deferred child renders as a
|
|
191
|
+
// bare `data-bf-ph` placeholder. The parent's init calls
|
|
192
|
+
// `upsertChild(__scope, ...)` which replaces the placeholder via
|
|
193
|
+
// `replaceWith` — but a detached root node can't replace itself in
|
|
194
|
+
// place. Park it in a throwaway wrapper so the replacement lands
|
|
195
|
+
// somewhere we can recover, then return the materialised child.
|
|
196
|
+
const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER)
|
|
197
|
+
let placeholderWrapper: HTMLElement | null = null
|
|
198
|
+
if (rootIsDeferredPlaceholder) {
|
|
199
|
+
placeholderWrapper = parseHTML('<div></div>').firstChild as HTMLElement
|
|
200
|
+
placeholderWrapper.appendChild(element)
|
|
201
|
+
}
|
|
202
|
+
|
|
189
203
|
// 9. Initialize the component (context providers set up here).
|
|
190
204
|
const initFn = getComponentInit(name)
|
|
191
205
|
if (initFn) {
|
|
192
|
-
// Pass original props (with getters) for reactivity
|
|
206
|
+
// Pass original props (with getters) for reactivity. For a root
|
|
207
|
+
// deferred placeholder, init's `upsertChild(element, ...)` matches the
|
|
208
|
+
// placeholder element itself and replaces it inside the wrapper.
|
|
193
209
|
initFn(element, props)
|
|
194
210
|
}
|
|
195
211
|
|
|
212
|
+
if (rootIsDeferredPlaceholder && placeholderWrapper) {
|
|
213
|
+
const materialised = placeholderWrapper.firstElementChild as HTMLElement | null
|
|
214
|
+
if (materialised && !materialised.hasAttribute(BF_PLACEHOLDER)) {
|
|
215
|
+
// The deferred child was created in place of the placeholder.
|
|
216
|
+
// `materialised` is the child's OWN element, created via
|
|
217
|
+
// upsertChild -> createComponent, which already registered itself
|
|
218
|
+
// (hydratedScopes / propsMap / registerPropsUpdate) keyed to the
|
|
219
|
+
// child with the child's own props. We must NOT re-register it here:
|
|
220
|
+
// overwriting propsMap/registerPropsUpdate with the *parent's* props
|
|
221
|
+
// would mis-key the child (e.g. a later getComponentProps would read
|
|
222
|
+
// the parent's props), and re-running the parent's init on an element
|
|
223
|
+
// whose placeholder is already gone could not re-materialise. So just
|
|
224
|
+
// restore the scope and return the already-registered child.
|
|
225
|
+
// (Parent-scope effects are unaffected: createEffect ownership lives
|
|
226
|
+
// in the EffectContext tree, not the discarded placeholder element.)
|
|
227
|
+
setCurrentScope(prevScope)
|
|
228
|
+
return materialised
|
|
229
|
+
}
|
|
230
|
+
// Placeholder was not replaced (no init / no matching child): fall
|
|
231
|
+
// through with the original placeholder element detached from wrapper.
|
|
232
|
+
placeholderWrapper.removeChild(element)
|
|
233
|
+
}
|
|
234
|
+
|
|
196
235
|
// 10. Evaluate getter children and insert them.
|
|
197
236
|
// Children are evaluated NOW (after initFn) so that context provided by
|
|
198
237
|
// the parent is in the global store when children call useContext().
|
package/src/runtime/registry.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Each component registers its init function so parents can initialize children with props.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { BF_SCOPE, BF_HOST } from '@barefootjs/shared'
|
|
8
|
+
import { BF_SCOPE, BF_HOST, BF_PLACEHOLDER } from '@barefootjs/shared'
|
|
9
9
|
import { hydratedScopes } from './hydration-state'
|
|
10
10
|
import { setCurrentScope } from './context'
|
|
11
11
|
import { createComponent } from './component'
|
|
@@ -148,8 +148,14 @@ export function upsertChild(
|
|
|
148
148
|
return ssr
|
|
149
149
|
}
|
|
150
150
|
// CSR: replace placeholder with a freshly-created component.
|
|
151
|
+
// The placeholder is normally a descendant of `parent`; but a
|
|
152
|
+
// comment-scope parent whose root IS the deferred child renders the
|
|
153
|
+
// placeholder as `parent` itself (no wrapper element), so match the
|
|
154
|
+
// parent element directly before falling back to a subtree query.
|
|
151
155
|
const phId = slotId ?? name
|
|
152
|
-
const ph = parent.
|
|
156
|
+
const ph = (parent.getAttribute(BF_PLACEHOLDER) === phId
|
|
157
|
+
? (parent as HTMLElement)
|
|
158
|
+
: parent.querySelector(`[${BF_PLACEHOLDER}="${phId}"]`)) as HTMLElement | null
|
|
153
159
|
if (ph) {
|
|
154
160
|
const slot = slotId ? buildSlotInfo(parent, slotId, anchorScope) : undefined
|
|
155
161
|
const comp = createComponent(name, props, key, slot)
|