@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,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Out-of-Order Streaming
|
|
3
|
+
*
|
|
4
|
+
* Client-side resolver for OOS (Out-of-Order Streaming) SSR.
|
|
5
|
+
* Handles swapping fallback content with resolved content that arrives
|
|
6
|
+
* via chunked HTTP responses.
|
|
7
|
+
*
|
|
8
|
+
* Protocol:
|
|
9
|
+
* 1. Server sends HTML with fallback placeholders: <div bf-async="a0">...</div>
|
|
10
|
+
* 2. As async data resolves, server appends chunks:
|
|
11
|
+
* <template bf-async-resolve="a0">...resolved...</template>
|
|
12
|
+
* <script>__bf_swap("a0")</script>
|
|
13
|
+
* 3. This module swaps fallback → resolved content and triggers hydration.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Swap a streaming fallback placeholder with its resolved content.
|
|
17
|
+
*
|
|
18
|
+
* Finds the placeholder element (`[bf-async="<id>"]`) and the resolve
|
|
19
|
+
* template (`<template bf-async-resolve="<id>">`), replaces the placeholder's
|
|
20
|
+
* children with the resolved content, then triggers hydration.
|
|
21
|
+
*
|
|
22
|
+
* @param id - The async boundary ID (e.g., "a0")
|
|
23
|
+
*/
|
|
24
|
+
export declare function __bf_swap(id: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Install the global streaming resolver.
|
|
27
|
+
*
|
|
28
|
+
* Makes `__bf_swap` available as `window.__bf_swap` so that inline
|
|
29
|
+
* `<script>__bf_swap("a0")</script>` tags in streaming chunks can call it.
|
|
30
|
+
*
|
|
31
|
+
* Also exposes `window.__bf_hydrate` for manual re-hydration triggers.
|
|
32
|
+
*
|
|
33
|
+
* Call this once, early in the page (before any streaming chunks arrive).
|
|
34
|
+
*/
|
|
35
|
+
export declare function setupStreaming(): void;
|
|
36
|
+
//# sourceMappingURL=streaming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/runtime/streaming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAmB1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAMrC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Style attribute helpers for client-side DOM updates.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert a style value (string or object) to a CSS string, or null to remove the attribute.
|
|
6
|
+
*
|
|
7
|
+
* - null/undefined → null (remove the attribute)
|
|
8
|
+
* - string → the string as-is
|
|
9
|
+
* - object → camelCase keys converted to kebab-case, joined with semicolons
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* styleToCss({ backgroundColor: 'red', fontSize: '16px' }) // "background-color:red;font-size:16px"
|
|
13
|
+
* styleToCss('color:red') // "color:red"
|
|
14
|
+
* styleToCss(null) // null
|
|
15
|
+
*/
|
|
16
|
+
export declare function styleToCss(value: unknown): string | null;
|
|
17
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/runtime/style.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAUxD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Template Registry
|
|
3
|
+
*
|
|
4
|
+
* Stores template functions for client-side component creation.
|
|
5
|
+
* Templates generate HTML strings from props, used by createComponent().
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Template function type - generates HTML string from props
|
|
9
|
+
*/
|
|
10
|
+
export type TemplateFn = (props: Record<string, unknown>) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Register a template function for a component.
|
|
13
|
+
*
|
|
14
|
+
* @param name - Component name (e.g., 'TodoItem')
|
|
15
|
+
* @param templateFn - Function that generates HTML from props
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* registerTemplate('TodoItem', (props) => `
|
|
19
|
+
* <li class="${props.done ? 'done' : ''}">
|
|
20
|
+
* <span>${props.text}</span>
|
|
21
|
+
* </li>
|
|
22
|
+
* `)
|
|
23
|
+
*/
|
|
24
|
+
export declare function registerTemplate(name: string, templateFn: TemplateFn): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get a registered template function by component name.
|
|
27
|
+
*
|
|
28
|
+
* @param name - Component name
|
|
29
|
+
* @returns Template function or undefined if not registered
|
|
30
|
+
*/
|
|
31
|
+
export declare function getTemplate(name: string): TemplateFn | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a template is registered for a component.
|
|
34
|
+
*
|
|
35
|
+
* @param name - Component name
|
|
36
|
+
* @returns true if template is registered
|
|
37
|
+
*/
|
|
38
|
+
export declare function hasTemplate(name: string): boolean;
|
|
39
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/runtime/template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;AAOnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CAE3E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Core Types
|
|
3
|
+
*
|
|
4
|
+
* Shared type definitions for component initialization and registration.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Component init function type.
|
|
8
|
+
* Takes the scope element and props, initializes the component
|
|
9
|
+
* by setting up event handlers, effects, and reactive bindings.
|
|
10
|
+
*/
|
|
11
|
+
export type InitFn = (scope: Element, props: Record<string, unknown>) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Component definition.
|
|
14
|
+
* Bundles the init function with optional template and scope metadata.
|
|
15
|
+
*/
|
|
16
|
+
export interface ComponentDef {
|
|
17
|
+
/** Component name (e.g., 'Counter'). Used for scope ID generation. */
|
|
18
|
+
name?: string;
|
|
19
|
+
/** Init function that hydrates a scope element */
|
|
20
|
+
init: InitFn;
|
|
21
|
+
/** Template function for client-side component creation */
|
|
22
|
+
template?: (props: Record<string, unknown>) => string;
|
|
23
|
+
/** When true, use comment-based scope hydration (fragment roots) */
|
|
24
|
+
comment?: boolean;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE7E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrD,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB"}
|
package/dist/shims.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-only API shims.
|
|
3
|
+
*
|
|
4
|
+
* These functions have real implementations in `./runtime/` that the
|
|
5
|
+
* compiler emits for `'use client'` components. The exports here exist
|
|
6
|
+
* for type-checking in user source files.
|
|
7
|
+
*
|
|
8
|
+
* If one of these ever runs, it means a `'use client'` component was
|
|
9
|
+
* executed without going through the compiler — or a non-client file
|
|
10
|
+
* slipped past the `MISSING_USE_CLIENT` check. Either way, it's a bug.
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from './context';
|
|
13
|
+
import type { Portal, PortalChildren, PortalOptions } from './runtime/portal';
|
|
14
|
+
export type { Portal, PortalChildren, PortalOptions, Renderable } from './runtime/portal';
|
|
15
|
+
export declare function useContext<T>(_context: Context<T>): T;
|
|
16
|
+
export declare function provideContext<T>(_context: Context<T>, _value: T): void;
|
|
17
|
+
export declare function createPortal(_children: PortalChildren, _container?: Element, _options?: PortalOptions): Portal;
|
|
18
|
+
export declare function isSSRPortal(_element: HTMLElement): boolean;
|
|
19
|
+
export declare function findSiblingSlot(_el: HTMLElement, _slotSelector: string): HTMLElement | null;
|
|
20
|
+
export declare function cleanupPortalPlaceholder(_portalId: string): void;
|
|
21
|
+
//# sourceMappingURL=shims.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shims.d.ts","sourceRoot":"","sources":["../src/shims.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE7E,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AASzF,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAErD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAEvE;AAED,wBAAgB,YAAY,CAC1B,SAAS,EAAE,cAAc,EACzB,UAAU,CAAC,EAAE,OAAO,EACpB,QAAQ,CAAC,EAAE,aAAa,GACvB,MAAM,CAER;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAE1D;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,aAAa,EAAE,MAAM,GACpB,WAAW,GAAG,IAAI,CAEpB;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEhE"}
|
package/dist/slot.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slot marker for JSX props that contain components.
|
|
3
|
+
*
|
|
4
|
+
* When a caller passes `<Button />` inside a JSX prop, the compiler wraps
|
|
5
|
+
* the value with `__slot()`. The callee's text effect checks `__isSlot`
|
|
6
|
+
* and skips the destructive `nodeValue = String(...)` update, preserving
|
|
7
|
+
* the server-rendered DOM for hydration.
|
|
8
|
+
*/
|
|
9
|
+
export interface SlotMarker {
|
|
10
|
+
__isSlot: true;
|
|
11
|
+
toString(): string;
|
|
12
|
+
}
|
|
13
|
+
export declare function __slot(thunk: () => unknown): SlotMarker;
|
|
14
|
+
//# sourceMappingURL=slot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot.d.ts","sourceRoot":"","sources":["../src/slot.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,IAAI,CAAA;IACd,QAAQ,IAAI,MAAM,CAAA;CACnB;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,OAAO,GAAG,UAAU,CAQvD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - splitProps
|
|
3
|
+
*
|
|
4
|
+
* SolidJS-compatible utility for splitting a props object into local and rest.
|
|
5
|
+
* Uses Proxy to preserve getter-based reactivity.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { splitProps } from '@barefootjs/client'
|
|
10
|
+
*
|
|
11
|
+
* function Checkbox(props: CheckboxProps) {
|
|
12
|
+
* const [local, rest] = splitProps(props, ['checked', 'onCheckedChange'])
|
|
13
|
+
* return <button {...rest} aria-checked={local.checked} />
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Split a props object into two: one with the specified keys, one with the rest.
|
|
19
|
+
* Both returned objects use Proxy to defer reads, preserving reactive tracking.
|
|
20
|
+
*
|
|
21
|
+
* @param props - The source props object
|
|
22
|
+
* @param keys - Keys to extract into the first (local) object
|
|
23
|
+
* @returns A tuple [local, rest] where local has the specified keys and rest has everything else
|
|
24
|
+
*/
|
|
25
|
+
export declare function splitProps<T extends Record<string, unknown>, K extends (keyof T)[]>(props: T, keys: K): [Pick<T, K[number]>, Omit<T, K[number]>];
|
|
26
|
+
//# sourceMappingURL=split-props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-props.d.ts","sourceRoot":"","sources":["../src/split-props.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAErB,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,CAAC,GACN,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAsD1C"}
|
package/dist/unwrap.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Unwrap Utility
|
|
3
|
+
*
|
|
4
|
+
* Unwrap a prop value that may be a getter function.
|
|
5
|
+
* When props are passed from parent to child components, reactive values
|
|
6
|
+
* are wrapped as getter functions to maintain reactivity.
|
|
7
|
+
* This helper unwraps them transparently.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Unwrap a prop value that may be a getter function.
|
|
11
|
+
*
|
|
12
|
+
* @param prop - The prop value (may be a value or a getter function)
|
|
13
|
+
* @returns The unwrapped value
|
|
14
|
+
*/
|
|
15
|
+
export declare function unwrap<T>(prop: T | (() => T)): T;
|
|
16
|
+
//# sourceMappingURL=unwrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unwrap.d.ts","sourceRoot":"","sources":["../src/unwrap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAEhD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@barefootjs/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "BarefootJS client package: reactive primitives (SSR-safe) plus browser runtime under the `/runtime` subpath (compiler target)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./reactive": {
|
|
14
|
+
"types": "./dist/reactive.d.ts",
|
|
15
|
+
"import": "./dist/reactive.js"
|
|
16
|
+
},
|
|
17
|
+
"./runtime": {
|
|
18
|
+
"types": "./dist/runtime/index.d.ts",
|
|
19
|
+
"import": "./dist/runtime/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./runtime/standalone": {
|
|
22
|
+
"types": "./dist/runtime/index.d.ts",
|
|
23
|
+
"import": "./dist/runtime/standalone.js"
|
|
24
|
+
},
|
|
25
|
+
"./build": {
|
|
26
|
+
"types": "./dist/build.d.ts",
|
|
27
|
+
"import": "./dist/build.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"src"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "bun run build:js && bun run build:types",
|
|
36
|
+
"build:js": "bun build ./src/reactive.ts --outdir ./dist --format esm && bun build ./src/index.ts --outdir ./dist --format esm --external '@barefootjs/client/reactive' && bun build ./src/runtime/index.ts --outdir ./dist/runtime --format esm --external '@barefootjs/client/reactive' && bun build ./src/runtime/index.ts --outfile ./dist/runtime/standalone.js --format esm && bun build ./src/build.ts --outdir ./dist --format esm --external '@barefootjs/jsx'",
|
|
37
|
+
"build:types": "tsgo --emitDeclarationOnly --outDir ./dist",
|
|
38
|
+
"test": "bun test",
|
|
39
|
+
"clean": "rm -rf dist"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"reactive",
|
|
43
|
+
"signals",
|
|
44
|
+
"dom",
|
|
45
|
+
"runtime",
|
|
46
|
+
"barefoot"
|
|
47
|
+
],
|
|
48
|
+
"author": "kobaken <kentafly88@gmail.com>",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/piconic-ai/barefootjs",
|
|
53
|
+
"directory": "packages/client"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@barefootjs/shared": "workspace:*"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@barefootjs/jsx": "workspace:*"
|
|
60
|
+
},
|
|
61
|
+
"peerDependenciesMeta": {
|
|
62
|
+
"@barefootjs/jsx": {
|
|
63
|
+
"optional": true
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@barefootjs/jsx": "workspace:*",
|
|
68
|
+
"@happy-dom/global-registrator": "^20.0.11",
|
|
69
|
+
"typescript": "^5.0.0"
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/build.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// CSR build config factory for `barefoot.config.ts`.
|
|
2
|
+
//
|
|
3
|
+
// CSR (client-side rendering) projects emit client JS only — no marked
|
|
4
|
+
// templates, no SSR. Pair this config with `render()` from
|
|
5
|
+
// `@barefootjs/client/runtime` on the page.
|
|
6
|
+
//
|
|
7
|
+
// The compiler still needs a `TemplateAdapter` to drive IR→client-JS
|
|
8
|
+
// codegen (the analyzer consults `acceptsTemplateCall` when deciding
|
|
9
|
+
// template-scope vs init-scope placement). The marked templates the
|
|
10
|
+
// adapter would produce are simply not written to disk. The default
|
|
11
|
+
// `CSRAdapter` is the minimum that satisfies the interface — its
|
|
12
|
+
// `generate()` returns an empty `AdapterOutput` and the build
|
|
13
|
+
// pipeline drops the empty marked-template file at the
|
|
14
|
+
// `clientOnly` gate.
|
|
15
|
+
//
|
|
16
|
+
// (Pre-1.0 this was `HonoAdapter` from `@barefootjs/hono/adapter`,
|
|
17
|
+
// which pulled the entire Hono package into a CSR app's
|
|
18
|
+
// `node_modules` for output that was always thrown away. See
|
|
19
|
+
// `csr-adapter.ts` for the rationale on the new in-package adapter.)
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
BarefootPaths,
|
|
23
|
+
BundleEntry,
|
|
24
|
+
ExternalSpec,
|
|
25
|
+
OutputLayout,
|
|
26
|
+
PostBuildContext,
|
|
27
|
+
TemplateAdapter,
|
|
28
|
+
} from '@barefootjs/jsx'
|
|
29
|
+
import { CSRAdapter } from './csr-adapter'
|
|
30
|
+
import type { CSRAdapterOptions } from './csr-adapter'
|
|
31
|
+
|
|
32
|
+
export interface CSRBuildOptions {
|
|
33
|
+
/** Project layout paths consumed by registry tooling. */
|
|
34
|
+
paths?: BarefootPaths
|
|
35
|
+
/** Source component directories relative to the config file. */
|
|
36
|
+
components?: string[]
|
|
37
|
+
/** Output directory relative to the config file. */
|
|
38
|
+
outDir?: string
|
|
39
|
+
/** Minify client JS output. */
|
|
40
|
+
minify?: boolean
|
|
41
|
+
/** Add content hash to client JS filenames. */
|
|
42
|
+
contentHash?: boolean
|
|
43
|
+
/** Custom output directory layout. */
|
|
44
|
+
outputLayout?: OutputLayout
|
|
45
|
+
/** Post-build hook called after minification, before manifest write. */
|
|
46
|
+
postBuild?: (ctx: PostBuildContext) => Promise<void> | void
|
|
47
|
+
/** Vendor packages to split out as separately-cached browser chunks. */
|
|
48
|
+
externals?: Record<string, ExternalSpec>
|
|
49
|
+
/** URL base path for vendor chunks in the emitted importmap. */
|
|
50
|
+
externalsBasePath?: string
|
|
51
|
+
/** Additional entry points to bundle with esbuild directly. */
|
|
52
|
+
bundleEntries?: BundleEntry[]
|
|
53
|
+
/**
|
|
54
|
+
* Override the compiler adapter. The marked templates this adapter
|
|
55
|
+
* generates are discarded in CSR mode — set this only if you need
|
|
56
|
+
* a different `TemplateAdapter` (e.g. a custom test adapter).
|
|
57
|
+
*/
|
|
58
|
+
adapter?: TemplateAdapter
|
|
59
|
+
/** Options forwarded to the default `CSRAdapter`. Ignored when `adapter` is set. */
|
|
60
|
+
adapterOptions?: CSRAdapterOptions
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Create a BarefootBuildConfig for CSR projects.
|
|
65
|
+
*
|
|
66
|
+
* Uses structural typing — does not import `BarefootBuildConfig` to avoid
|
|
67
|
+
* a circular dependency between `@barefootjs/client` and `@barefootjs/cli`.
|
|
68
|
+
*/
|
|
69
|
+
export function createConfig(options: CSRBuildOptions = {}) {
|
|
70
|
+
// `name` defaults to `'csr'` inside `CSRAdapter`; a caller-supplied
|
|
71
|
+
// `adapterOptions.name` (or a fully-custom `adapter`) wins, matching
|
|
72
|
+
// the pre-decoupling behaviour where `bf build`'s `Adapter: …`
|
|
73
|
+
// banner reflected the option override.
|
|
74
|
+
const adapter = options.adapter ?? new CSRAdapter(options.adapterOptions)
|
|
75
|
+
return {
|
|
76
|
+
adapter,
|
|
77
|
+
paths: options.paths,
|
|
78
|
+
components: options.components,
|
|
79
|
+
outDir: options.outDir,
|
|
80
|
+
minify: options.minify,
|
|
81
|
+
contentHash: options.contentHash,
|
|
82
|
+
clientOnly: true,
|
|
83
|
+
externals: options.externals,
|
|
84
|
+
externalsBasePath: options.externalsBasePath,
|
|
85
|
+
bundleEntries: options.bundleEntries,
|
|
86
|
+
outputLayout: options.outputLayout,
|
|
87
|
+
postBuild: options.postBuild,
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { CSRAdapter } from './csr-adapter'
|
|
92
|
+
export type { CSRAdapterOptions } from './csr-adapter'
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context API: pure metadata portion.
|
|
3
|
+
*
|
|
4
|
+
* `createContext` is DOM-free and safe to use anywhere (including SSR).
|
|
5
|
+
* The DOM-bound operations (`useContext`, `provideContext`) live in
|
|
6
|
+
* `./runtime/context.ts` and are emitted by the compiler for `'use client'`
|
|
7
|
+
* components.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export type Context<T> = {
|
|
11
|
+
readonly id: symbol
|
|
12
|
+
readonly defaultValue: T | undefined
|
|
13
|
+
/** JSX Provider component. Compiled to provideContext() by the compiler. */
|
|
14
|
+
readonly Provider: (props: { value: T; children?: unknown }) => unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a new context with an optional default value.
|
|
19
|
+
*
|
|
20
|
+
* `useContext()` returns the nearest provider value, then the default,
|
|
21
|
+
* then `undefined`. It never throws — guard with optional chaining.
|
|
22
|
+
*/
|
|
23
|
+
export function createContext<T>(defaultValue?: T): Context<T> {
|
|
24
|
+
return {
|
|
25
|
+
id: Symbol(),
|
|
26
|
+
defaultValue,
|
|
27
|
+
// Provider is compiled away by the JSX compiler into provideContext() calls.
|
|
28
|
+
// This runtime stub exists only for TypeScript type checking.
|
|
29
|
+
Provider: (() => {
|
|
30
|
+
throw new Error('Context.Provider should be compiled away')
|
|
31
|
+
}) as Context<T>['Provider'],
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Minimal `TemplateAdapter` used by `@barefootjs/client/build`'s
|
|
2
|
+
// `createConfig` for CSR projects.
|
|
3
|
+
//
|
|
4
|
+
// CSR builds emit client JS only — the marked-template output the
|
|
5
|
+
// `TemplateAdapter` contract requires is discarded by the build
|
|
6
|
+
// pipeline when `clientOnly: true` (see `cli/src/lib/build.ts`, the
|
|
7
|
+
// `!config.clientOnly && markedTemplates.length > 0` gate). All this
|
|
8
|
+
// adapter has to do is satisfy the interface so the compiler's
|
|
9
|
+
// pass-2 loop can call `adapter.generate()` without crashing.
|
|
10
|
+
//
|
|
11
|
+
// Historically `createConfig` reused `HonoAdapter` from
|
|
12
|
+
// `@barefootjs/hono/adapter` here as a "broad-acceptance JS template
|
|
13
|
+
// runtime". That pulled the entire Hono package into a CSR app's
|
|
14
|
+
// `node_modules` for an adapter whose every output was thrown away
|
|
15
|
+
// — confusing for users who picked CSR specifically to avoid an SSR
|
|
16
|
+
// framework dependency. Replacing it with this in-package adapter
|
|
17
|
+
// deletes the transitive Hono dep and keeps the analyzer-side
|
|
18
|
+
// behaviour identical (`acceptsTemplateCall: () => true`).
|
|
19
|
+
//
|
|
20
|
+
// What we still need from a "template adapter" in CSR mode:
|
|
21
|
+
//
|
|
22
|
+
// - `acceptsTemplateCall: () => true`. This is consulted by the
|
|
23
|
+
// IR analyzer + relocate pipeline (#1187 phase 3) when
|
|
24
|
+
// deciding whether a call expression can live at template
|
|
25
|
+
// scope vs init scope. The CSR "template" runs in the browser
|
|
26
|
+
// via `@barefootjs/client/runtime`, so any synchronous JS call
|
|
27
|
+
// is valid there — same contract as Hono SSR, where the broad
|
|
28
|
+
// predicate originally lived. Without this the analyzer would
|
|
29
|
+
// conservatively force calls into init scope and emit different
|
|
30
|
+
// (less efficient) client JS.
|
|
31
|
+
//
|
|
32
|
+
// - Sentinel `generate()` returning an empty `AdapterOutput`. The
|
|
33
|
+
// compiler's pass-2 unconditionally calls `adapter.generate()`
|
|
34
|
+
// to assemble the marked-template module string; in CSR mode
|
|
35
|
+
// every field of that string is discarded before write, so we
|
|
36
|
+
// just hand back empty strings and let the pipeline drop the
|
|
37
|
+
// empty `markedTemplate` file at the gate.
|
|
38
|
+
//
|
|
39
|
+
// - No-op render methods. The `TemplateAdapter` interface lists
|
|
40
|
+
// them (`renderNode`, `renderElement`, etc.) but they are only
|
|
41
|
+
// ever invoked from inside an adapter's own `generate()`. Since
|
|
42
|
+
// ours returns early, these are never reached at runtime — they
|
|
43
|
+
// exist purely to satisfy the contract.
|
|
44
|
+
//
|
|
45
|
+
// Everything else (`clientShimSource`, `templatePrimitives`,
|
|
46
|
+
// `generateSignalInitializers`, ...) is optional on `TemplateAdapter`
|
|
47
|
+
// and intentionally omitted: CSR has no SSR templates to shim into,
|
|
48
|
+
// no DSL-side primitive registry, and no init block to emit.
|
|
49
|
+
|
|
50
|
+
import type { AdapterOutput, TemplateSections } from '@barefootjs/jsx'
|
|
51
|
+
import { BaseAdapter } from '@barefootjs/jsx'
|
|
52
|
+
|
|
53
|
+
export interface CSRAdapterOptions {
|
|
54
|
+
/**
|
|
55
|
+
* Display name surfaced through `TemplateAdapter.name` — read by
|
|
56
|
+
* `bf build` for its `Adapter: …` banner. Defaults to `'csr'`.
|
|
57
|
+
*/
|
|
58
|
+
name?: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Frozen so a single shared sentinel can be returned from every
|
|
62
|
+
// `generate()` call without risking that a downstream consumer
|
|
63
|
+
// mutates it and bleeds state across compilations. `Object.freeze`
|
|
64
|
+
// is shallow, so we freeze both the outer `AdapterOutput` and the
|
|
65
|
+
// nested `sections` object — those are the two objects callers
|
|
66
|
+
// could write to (string/extension fields are primitives).
|
|
67
|
+
const EMPTY_SECTIONS: TemplateSections = Object.freeze({
|
|
68
|
+
imports: '',
|
|
69
|
+
types: '',
|
|
70
|
+
component: '',
|
|
71
|
+
defaultExport: '',
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const EMPTY_OUTPUT: AdapterOutput = Object.freeze({
|
|
75
|
+
template: '',
|
|
76
|
+
sections: EMPTY_SECTIONS,
|
|
77
|
+
extension: '.tsx',
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
export class CSRAdapter extends BaseAdapter {
|
|
81
|
+
name: string
|
|
82
|
+
extension = '.tsx'
|
|
83
|
+
|
|
84
|
+
// Broad acceptance — matches Hono's contract, see the comment at
|
|
85
|
+
// the top of this file for why CSR shares it.
|
|
86
|
+
acceptsTemplateCall = (): boolean => true
|
|
87
|
+
|
|
88
|
+
constructor(options: CSRAdapterOptions = {}) {
|
|
89
|
+
super()
|
|
90
|
+
this.name = options.name ?? 'csr'
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Sentinel: the marked-template is discarded in clientOnly mode,
|
|
94
|
+
// so a single shared empty `AdapterOutput` (frozen — see
|
|
95
|
+
// `EMPTY_OUTPUT` above) is enough. Re-creating per call would just
|
|
96
|
+
// allocate garbage.
|
|
97
|
+
generate(): AdapterOutput {
|
|
98
|
+
return EMPTY_OUTPUT
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// The render methods below would only ever be called from inside
|
|
102
|
+
// an adapter's own `generate()`; since ours returns early, none of
|
|
103
|
+
// them run at compile time. They exist purely to satisfy
|
|
104
|
+
// `BaseAdapter`'s abstract surface. `BaseAdapter` already provides
|
|
105
|
+
// a sensible default `renderAsync` that delegates to `renderNode`
|
|
106
|
+
// + `renderChildren`, so we inherit that for free.
|
|
107
|
+
renderNode(): string {
|
|
108
|
+
return ''
|
|
109
|
+
}
|
|
110
|
+
renderElement(): string {
|
|
111
|
+
return ''
|
|
112
|
+
}
|
|
113
|
+
renderExpression(): string {
|
|
114
|
+
return ''
|
|
115
|
+
}
|
|
116
|
+
renderConditional(): string {
|
|
117
|
+
return ''
|
|
118
|
+
}
|
|
119
|
+
renderLoop(): string {
|
|
120
|
+
return ''
|
|
121
|
+
}
|
|
122
|
+
renderComponent(): string {
|
|
123
|
+
return ''
|
|
124
|
+
}
|
|
125
|
+
renderScopeMarker(): string {
|
|
126
|
+
return ''
|
|
127
|
+
}
|
|
128
|
+
renderSlotMarker(): string {
|
|
129
|
+
return ''
|
|
130
|
+
}
|
|
131
|
+
renderCondMarker(): string {
|
|
132
|
+
return ''
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Forward Props Helper
|
|
3
|
+
*
|
|
4
|
+
* Forwards spread props to child components using getter delegation
|
|
5
|
+
* to preserve reactivity. Used by compiler-generated code for
|
|
6
|
+
* components with {...rest} spread on child components.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create a props object that merges explicit overrides with forwarded source props.
|
|
11
|
+
* Preserves getter-based reactivity from both overrides and source.
|
|
12
|
+
*
|
|
13
|
+
* @param source - The parent props object (reads are deferred via getters)
|
|
14
|
+
* @param overrides - Object literal with getters/values that override source props
|
|
15
|
+
* @param excludeKeys - Keys from source to exclude (already destructured)
|
|
16
|
+
*/
|
|
17
|
+
export function forwardProps<T extends Record<string, unknown>>(
|
|
18
|
+
source: T,
|
|
19
|
+
overrides: Record<string, unknown>,
|
|
20
|
+
excludeKeys: string[]
|
|
21
|
+
): Record<string, unknown> {
|
|
22
|
+
const result: Record<string, unknown> = {}
|
|
23
|
+
const exclude = new Set(excludeKeys)
|
|
24
|
+
|
|
25
|
+
// Copy overrides preserving getter descriptors
|
|
26
|
+
const descs = Object.getOwnPropertyDescriptors(overrides)
|
|
27
|
+
for (const key of Object.keys(descs)) {
|
|
28
|
+
Object.defineProperty(result, key, { ...descs[key], enumerable: true, configurable: true })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Forward remaining source props via getters (deferred read = reactive)
|
|
32
|
+
for (const key of Object.keys(source)) {
|
|
33
|
+
if (exclude.has(key) || key in result) continue
|
|
34
|
+
const k = key
|
|
35
|
+
Object.defineProperty(result, k, {
|
|
36
|
+
get: () => (source as Record<string, unknown>)[k],
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return result
|
|
43
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Reactive primitives live at the shared `@barefootjs/client/reactive`
|
|
2
|
+
// subpath so main and the `/runtime` entry point reference a single
|
|
3
|
+
// physical module — see src/runtime/index.ts for the rationale.
|
|
4
|
+
export {
|
|
5
|
+
createSignal,
|
|
6
|
+
createEffect,
|
|
7
|
+
createDisposableEffect,
|
|
8
|
+
createMemo,
|
|
9
|
+
createRoot,
|
|
10
|
+
onCleanup,
|
|
11
|
+
onMount,
|
|
12
|
+
untrack,
|
|
13
|
+
batch,
|
|
14
|
+
type Reactive,
|
|
15
|
+
type Signal,
|
|
16
|
+
type Memo,
|
|
17
|
+
type CleanupFn,
|
|
18
|
+
type EffectFn,
|
|
19
|
+
} from '@barefootjs/client/reactive'
|
|
20
|
+
|
|
21
|
+
export { splitProps } from './split-props'
|
|
22
|
+
|
|
23
|
+
export { __slot, type SlotMarker } from './slot'
|
|
24
|
+
|
|
25
|
+
export { forwardProps } from './forward-props'
|
|
26
|
+
|
|
27
|
+
export { unwrap } from './unwrap'
|
|
28
|
+
|
|
29
|
+
export { createContext, type Context } from './context'
|
|
30
|
+
|
|
31
|
+
export {
|
|
32
|
+
useContext,
|
|
33
|
+
provideContext,
|
|
34
|
+
createPortal,
|
|
35
|
+
isSSRPortal,
|
|
36
|
+
findSiblingSlot,
|
|
37
|
+
cleanupPortalPlaceholder,
|
|
38
|
+
type Portal,
|
|
39
|
+
type PortalChildren,
|
|
40
|
+
type PortalOptions,
|
|
41
|
+
type Renderable,
|
|
42
|
+
} from './shims'
|