@barefootjs/hono 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.
Files changed (81) hide show
  1. package/dist/adapter/hono-adapter.d.ts +141 -0
  2. package/dist/adapter/hono-adapter.d.ts.map +1 -0
  3. package/dist/adapter/index.d.ts +6 -0
  4. package/dist/adapter/index.d.ts.map +1 -0
  5. package/dist/adapter/index.js +632 -0
  6. package/dist/app.d.ts +131 -0
  7. package/dist/app.d.ts.map +1 -0
  8. package/dist/app.js +139 -0
  9. package/dist/async.d.ts +15 -0
  10. package/dist/async.d.ts.map +1 -0
  11. package/dist/async.js +12 -0
  12. package/dist/build.d.ts +65 -0
  13. package/dist/build.d.ts.map +1 -0
  14. package/dist/build.js +785 -0
  15. package/dist/client-shim.d.ts +59 -0
  16. package/dist/client-shim.d.ts.map +1 -0
  17. package/dist/client-shim.js +90 -0
  18. package/dist/dev-worker.d.ts +25 -0
  19. package/dist/dev-worker.d.ts.map +1 -0
  20. package/dist/dev-worker.js +65 -0
  21. package/dist/dev.d.ts +36 -0
  22. package/dist/dev.d.ts.map +1 -0
  23. package/dist/dev.js +418 -0
  24. package/dist/dialog-context.d.ts +13 -0
  25. package/dist/dialog-context.d.ts.map +1 -0
  26. package/dist/dialog-context.js +10 -0
  27. package/dist/index.d.ts +13 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +632 -0
  30. package/dist/jsx/jsx-dev-runtime/index.d.ts +9 -0
  31. package/dist/jsx/jsx-dev-runtime/index.d.ts.map +1 -0
  32. package/dist/jsx/jsx-dev-runtime/index.js +6 -0
  33. package/dist/jsx/jsx-runtime/index.d.ts +32 -0
  34. package/dist/jsx/jsx-runtime/index.d.ts.map +1 -0
  35. package/dist/jsx/jsx-runtime/index.js +10 -0
  36. package/dist/portal-ssr.d.ts +22 -0
  37. package/dist/portal-ssr.d.ts.map +1 -0
  38. package/dist/portal-ssr.js +73 -0
  39. package/dist/portals.d.ts +26 -0
  40. package/dist/portals.d.ts.map +1 -0
  41. package/dist/portals.js +41 -0
  42. package/dist/preload.d.ts +56 -0
  43. package/dist/preload.d.ts.map +1 -0
  44. package/dist/preload.js +51 -0
  45. package/dist/scripts.d.ts +80 -0
  46. package/dist/scripts.d.ts.map +1 -0
  47. package/dist/scripts.js +198 -0
  48. package/dist/test-render.d.ts +28 -0
  49. package/dist/test-render.d.ts.map +1 -0
  50. package/dist/utils.d.ts +16 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +16 -0
  53. package/package.json +116 -0
  54. package/src/__tests__/async.test.tsx +106 -0
  55. package/src/__tests__/bfscripts-entry-roots.test.tsx +135 -0
  56. package/src/__tests__/build.test.ts +299 -0
  57. package/src/__tests__/dev.test.tsx +123 -0
  58. package/src/__tests__/hydration-props-type.test.ts +141 -0
  59. package/src/__tests__/manifest-scripts.test.ts +87 -0
  60. package/src/__tests__/scaffold.test.ts +209 -0
  61. package/src/__tests__/ssr-context-bridge.test.ts +110 -0
  62. package/src/__tests__/string-literal-css-var-prop.test.ts +84 -0
  63. package/src/__tests__/stub-deps-scripts.test.ts +183 -0
  64. package/src/adapter/hono-adapter.ts +1114 -0
  65. package/src/adapter/index.ts +6 -0
  66. package/src/app.ts +220 -0
  67. package/src/async.tsx +55 -0
  68. package/src/build.ts +230 -0
  69. package/src/client-shim.ts +164 -0
  70. package/src/dev-worker.ts +93 -0
  71. package/src/dev.tsx +146 -0
  72. package/src/dialog-context.tsx +44 -0
  73. package/src/index.ts +26 -0
  74. package/src/jsx/jsx-dev-runtime/index.ts +9 -0
  75. package/src/jsx/jsx-runtime/index.ts +40 -0
  76. package/src/portal-ssr.tsx +92 -0
  77. package/src/portals.tsx +98 -0
  78. package/src/preload.tsx +166 -0
  79. package/src/scripts.tsx +220 -0
  80. package/src/test-render.ts +143 -0
  81. package/src/utils.ts +26 -0
@@ -0,0 +1,59 @@
1
+ /**
2
+ * SSR shim for `@barefootjs/client` when targeting the Hono adapter.
3
+ *
4
+ * The compiler rewrites `@barefootjs/client` imports inside SSR templates to
5
+ * this module. The shim provides:
6
+ *
7
+ * - `useContext` / `provideContext` bridged to Hono's per-render context
8
+ * stack, so context values flow through `<Context.Provider value=...>`
9
+ * during SSR. The compiler emits provider IR via `provideContextSSR`.
10
+ * - Pure helpers (`createContext`, `splitProps`, `forwardProps`, `unwrap`,
11
+ * `__slot`) re-exported from `@barefootjs/client`.
12
+ * - Reactive primitives (`createSignal`, `createMemo`, etc.) replaced with
13
+ * stubs that throw if called — the compiler is expected to rewrite all
14
+ * reachable call sites to plain values during SSR codegen.
15
+ * - Portal helpers as no-ops; portals are realized at hydration time.
16
+ */
17
+ import type { Context as HonoContext } from 'hono/jsx';
18
+ import type { Context } from '@barefootjs/client';
19
+ export { createContext, splitProps, forwardProps, unwrap, __slot, } from '@barefootjs/client';
20
+ export type { Context, Reactive, Signal, Memo, CleanupFn, EffectFn, SlotMarker, Portal, PortalChildren, PortalOptions, Renderable, } from '@barefootjs/client';
21
+ /**
22
+ * Lazily map a BarefootJS Context object to a Hono context. The mapping is
23
+ * stable (WeakMap keyed by the Context object itself), so providers and
24
+ * consumers in the same render see the same Hono context.
25
+ */
26
+ export declare function getHonoContext<T>(bfCtx: Context<T>): HonoContext<T | undefined>;
27
+ /**
28
+ * SSR `useContext`: read from Hono's per-render stack, falling back to the
29
+ * BarefootJS Context's default value, then to `undefined`. Mirrors client
30
+ * semantics — no provider returns `undefined` rather than throwing.
31
+ */
32
+ export declare function useContext<T>(bfCtx: Context<T>): T;
33
+ /**
34
+ * SSR `provideContext`: imperative provider calls inside init code are
35
+ * unreachable from SSR templates (they live in client JS). At SSR, the
36
+ * `<Context.Provider value=...>` JSX is compiled to `provideContextSSR`
37
+ * instead, which uses Hono's stack-scoped Provider.
38
+ */
39
+ export declare function provideContext<T>(_bfCtx: Context<T>, _value: T): void;
40
+ /**
41
+ * Compiler-emitted helper for `<Context.Provider value=...>{children}</...>`
42
+ * at SSR. Wraps children with the bridged Hono Provider so that descendants
43
+ * resolving the same BarefootJS Context via `useContext` see this value.
44
+ */
45
+ export declare function provideContextSSR<T>(bfCtx: Context<T>, value: T, children: unknown): unknown;
46
+ export declare function createSignal<T>(_initial?: T): never;
47
+ export declare function createMemo<T>(_fn: () => T): never;
48
+ export declare function createEffect(_fn: () => void): never;
49
+ export declare function createDisposableEffect(_fn: () => void): never;
50
+ export declare function createRoot<T>(_fn: (dispose: () => void) => T): never;
51
+ export declare function onMount(_fn: () => void): void;
52
+ export declare function onCleanup(_fn: () => void): void;
53
+ export declare function untrack<T>(fn: () => T): T;
54
+ export declare function batch<T>(fn: () => T): T;
55
+ export declare function createPortal(_children: unknown, _container?: unknown, _options?: unknown): never;
56
+ export declare function isSSRPortal(_element: unknown): boolean;
57
+ export declare function findSiblingSlot(_el: unknown, _slotSelector: string): null;
58
+ export declare function cleanupPortalPlaceholder(_portalId: string): void;
59
+ //# sourceMappingURL=client-shim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-shim.d.ts","sourceRoot":"","sources":["../src/client-shim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EACL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,MAAM,EACN,MAAM,GACP,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACV,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,UAAU,EACV,MAAM,EACN,cAAc,EACd,aAAa,EACb,UAAU,GACX,MAAM,oBAAoB,CAAA;AAQ3B;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,GAAG,SAAS,CAAC,CAO/E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAKlD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAErE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EACjB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,OAAO,GAChB,OAAO,CAGT;AAYD,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,KAAK,CAEnD;AACD,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,KAAK,CAEjD;AACD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,IAAI,GAAG,KAAK,CAEnD;AACD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,IAAI,GAAG,KAAK,CAE7D;AACD,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,CAEpE;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,IAAI,GAAG,IAAI,CAE7C;AACD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,IAAI,GAAG,IAAI,CAE/C;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEzC;AACD,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEvC;AAMD,wBAAgB,YAAY,CAC1B,SAAS,EAAE,OAAO,EAClB,UAAU,CAAC,EAAE,OAAO,EACpB,QAAQ,CAAC,EAAE,OAAO,GACjB,KAAK,CAEP;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAEzE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEhE"}
@@ -0,0 +1,90 @@
1
+ // src/client-shim.ts
2
+ import { createContext as honoCreateContext, useContext as honoUseContext, jsx } from "hono/jsx";
3
+ import {
4
+ createContext,
5
+ splitProps,
6
+ forwardProps,
7
+ unwrap,
8
+ __slot
9
+ } from "@barefootjs/client";
10
+ var honoCtxBridge = new WeakMap;
11
+ function getHonoContext(bfCtx) {
12
+ let hc = honoCtxBridge.get(bfCtx);
13
+ if (!hc) {
14
+ hc = honoCreateContext(bfCtx.defaultValue);
15
+ honoCtxBridge.set(bfCtx, hc);
16
+ }
17
+ return hc;
18
+ }
19
+ function useContext(bfCtx) {
20
+ const hc = getHonoContext(bfCtx);
21
+ const v = honoUseContext(hc);
22
+ if (v !== undefined)
23
+ return v;
24
+ return bfCtx.defaultValue;
25
+ }
26
+ function provideContext(_bfCtx, _value) {}
27
+ function provideContextSSR(bfCtx, value, children) {
28
+ const HonoCtx = getHonoContext(bfCtx);
29
+ return jsx(HonoCtx.Provider, { value, children });
30
+ }
31
+ function calledAtSSR(name) {
32
+ throw new Error(`[barefootjs] ${name}() reached SSR. The compiler should have rewritten this call site — please report a bug.`);
33
+ }
34
+ function createSignal(_initial) {
35
+ return calledAtSSR("createSignal");
36
+ }
37
+ function createMemo(_fn) {
38
+ return calledAtSSR("createMemo");
39
+ }
40
+ function createEffect(_fn) {
41
+ return calledAtSSR("createEffect");
42
+ }
43
+ function createDisposableEffect(_fn) {
44
+ return calledAtSSR("createDisposableEffect");
45
+ }
46
+ function createRoot(_fn) {
47
+ return calledAtSSR("createRoot");
48
+ }
49
+ function onMount(_fn) {}
50
+ function onCleanup(_fn) {}
51
+ function untrack(fn) {
52
+ return fn();
53
+ }
54
+ function batch(fn) {
55
+ return fn();
56
+ }
57
+ function createPortal(_children, _container, _options) {
58
+ return calledAtSSR("createPortal");
59
+ }
60
+ function isSSRPortal(_element) {
61
+ return false;
62
+ }
63
+ function findSiblingSlot(_el, _slotSelector) {
64
+ return null;
65
+ }
66
+ function cleanupPortalPlaceholder(_portalId) {}
67
+ export {
68
+ useContext,
69
+ unwrap,
70
+ untrack,
71
+ splitProps,
72
+ provideContextSSR,
73
+ provideContext,
74
+ onMount,
75
+ onCleanup,
76
+ isSSRPortal,
77
+ getHonoContext,
78
+ forwardProps,
79
+ findSiblingSlot,
80
+ createSignal,
81
+ createRoot,
82
+ createPortal,
83
+ createMemo,
84
+ createEffect,
85
+ createDisposableEffect,
86
+ createContext,
87
+ cleanupPortalPlaceholder,
88
+ batch,
89
+ __slot
90
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * BarefootJS Dev Reloader for Cloudflare Workers / other edge runtimes.
3
+ *
4
+ * Unlike `./dev`'s `createDevReloader`, this variant does not watch the local
5
+ * filesystem — it generates a fresh boot ID on every cold start and relies on
6
+ * the standard SSE `Last-Event-ID` reconnection protocol to detect restarts:
7
+ *
8
+ * 1. First connect → send `event: hello`, `id: <BOOT_ID>`.
9
+ * 2. Worker restart → SSE stream drops, client reconnects with
10
+ * `Last-Event-ID: <old BOOT_ID>`.
11
+ * 3. Server sees mismatch → send `event: reload`, client refreshes.
12
+ *
13
+ * Pair with `BfDevReload` from `@barefootjs/hono/dev-reload`.
14
+ */
15
+ import type { Context } from 'hono';
16
+ export interface CreateDevReloaderOptions {
17
+ /** Override the dev gate. Defaults to `process.env.NODE_ENV !== 'production'`. */
18
+ enabled?: boolean;
19
+ }
20
+ /**
21
+ * Hono route handler that streams Server-Sent Events. Returns 404 in
22
+ * production (`NODE_ENV=production`) unless `enabled` is set explicitly.
23
+ */
24
+ export declare function createDevReloader(options?: CreateDevReloaderOptions): (c: Context) => Response | Promise<Response>;
25
+ //# sourceMappingURL=dev-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-worker.d.ts","sourceRoot":"","sources":["../src/dev-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAEnC,MAAM,WAAW,wBAAwB;IACvC,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAoBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,CAAC,CAAC,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8C9C"}
@@ -0,0 +1,65 @@
1
+ // src/dev-worker.ts
2
+ var HEARTBEAT_MS = 5000;
3
+ var BOOT_ID = generateBootId();
4
+ function generateBootId() {
5
+ try {
6
+ return crypto.randomUUID();
7
+ } catch {
8
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 10);
9
+ }
10
+ }
11
+ function isDevDefault() {
12
+ return true;
13
+ }
14
+ function createDevReloader(options = {}) {
15
+ const { enabled = isDevDefault() } = options;
16
+ return (c) => {
17
+ if (!enabled)
18
+ return c.notFound();
19
+ const lastEventId = (c.req.header("Last-Event-ID") ?? "").trim();
20
+ const signal = c.req.raw.signal;
21
+ const stream = new ReadableStream({
22
+ start(controller) {
23
+ const encoder = new TextEncoder;
24
+ const send = (chunk) => {
25
+ try {
26
+ controller.enqueue(encoder.encode(chunk));
27
+ } catch {}
28
+ };
29
+ send(`retry: 1000
30
+
31
+ `);
32
+ const event = lastEventId && lastEventId !== BOOT_ID ? "reload" : "hello";
33
+ send(`event: ${event}
34
+ id: ${BOOT_ID}
35
+ data: ${BOOT_ID}
36
+
37
+ `);
38
+ const heartbeat = setInterval(() => send(`: hb
39
+
40
+ `), HEARTBEAT_MS);
41
+ const onAbort = () => {
42
+ clearInterval(heartbeat);
43
+ try {
44
+ controller.close();
45
+ } catch {}
46
+ };
47
+ if (signal.aborted)
48
+ onAbort();
49
+ else
50
+ signal.addEventListener("abort", onAbort, { once: true });
51
+ }
52
+ });
53
+ return new Response(stream, {
54
+ headers: {
55
+ "Content-Type": "text/event-stream",
56
+ "Cache-Control": "no-cache, no-transform",
57
+ Connection: "keep-alive",
58
+ "X-Accel-Buffering": "no"
59
+ }
60
+ });
61
+ };
62
+ }
63
+ export {
64
+ createDevReloader
65
+ };
package/dist/dev.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * BarefootJS Dev Reloader (Hono, Node-side)
3
+ *
4
+ * `createDevReloader` turns `bf build --watch`'s sentinel file
5
+ * (`<distDir>/.dev/build-id`) into an SSE stream:
6
+ *
7
+ * [bf build --watch] → writes `<distDir>/.dev/build-id` after each successful build
8
+ * [createDevReloader] → watches that file, streams SSE `event: reload`
9
+ *
10
+ * Mount it on a Hono route in the generated app; the matching browser-
11
+ * side subscriber (`<DevReload />`) lives in the project itself (see
12
+ * the hono-node scaffold's `dev-reload.tsx`) so its endpoint URL and
13
+ * reconnect behavior are an in-tree edit.
14
+ *
15
+ * ```ts
16
+ * // factory.ts
17
+ * import { createDevReloader } from '@barefootjs/hono/dev'
18
+ * app.get('/_bf/reload', createDevReloader({ distDir: './dist' }))
19
+ * ```
20
+ *
21
+ * Disabled (404) when `NODE_ENV === 'production'` unless `enabled: true`
22
+ * is passed explicitly.
23
+ */
24
+ import type { Context } from 'hono';
25
+ export interface CreateDevReloaderOptions {
26
+ /** Directory that `bf build` writes output into (contains `.dev/build-id`). */
27
+ distDir: string;
28
+ /** Override the dev gate. Defaults to `process.env.NODE_ENV !== 'production'`. */
29
+ enabled?: boolean;
30
+ }
31
+ /**
32
+ * Hono route handler that streams Server-Sent Events and emits `reload` every
33
+ * time `<distDir>/.dev/build-id` is written. Disabled (404) in production.
34
+ */
35
+ export declare function createDevReloader(options: CreateDevReloaderOptions): (c: Context) => Response | Promise<Response>;
36
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../src/dev.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAInC,MAAM,WAAW,wBAAwB;IACvC,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAmBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,wBAAwB,GAChC,CAAC,CAAC,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsF9C"}