brustjs 0.1.50-alpha → 0.1.52-alpha

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 (90) hide show
  1. package/package.json +39 -15
  2. package/runtime/cache-sync.ts +291 -0
  3. package/runtime/cache.ts +4 -0
  4. package/runtime/cli/dev.ts +7 -0
  5. package/runtime/cli/native-routes-emit.ts +147 -1
  6. package/runtime/config.ts +42 -0
  7. package/runtime/index.d.ts +63 -0
  8. package/runtime/index.js +57 -52
  9. package/runtime/index.ts +108 -9
  10. package/runtime/native/runtime.ts +220 -7
  11. package/runtime/render/fragment.ts +87 -0
  12. package/runtime/routes.ts +225 -48
  13. package/runtime/templates.ts +47 -0
  14. package/runtime/treaty.ts +24 -1
  15. package/types/action-error.d.ts +18 -0
  16. package/types/cache-sync.d.ts +42 -0
  17. package/types/cache.d.ts +20 -0
  18. package/types/cli/help.d.ts +28 -0
  19. package/types/cli/jinja-staleness.d.ts +14 -0
  20. package/types/cli/native-routes-emit.d.ts +217 -0
  21. package/types/cli/new.d.ts +30 -0
  22. package/types/cli/templates.d.ts +39 -0
  23. package/types/client/index.d.ts +14 -0
  24. package/types/config.d.ts +42 -0
  25. package/types/cookies.d.ts +25 -0
  26. package/types/create.d.ts +1 -0
  27. package/types/css/build.d.ts +11 -0
  28. package/types/css/component-build.d.ts +17 -0
  29. package/types/css/component-loader.d.ts +8 -0
  30. package/types/css/manifest.d.ts +21 -0
  31. package/types/css/process-modules.d.ts +31 -0
  32. package/types/css/route-deps.d.ts +20 -0
  33. package/types/css/scan-imports.d.ts +13 -0
  34. package/types/css.d.ts +16 -0
  35. package/types/define-actions.d.ts +133 -0
  36. package/types/dev/client.d.ts +8 -0
  37. package/types/dev/coordinator.d.ts +33 -0
  38. package/types/dev/inject.d.ts +6 -0
  39. package/types/dev/jinja-reload.d.ts +7 -0
  40. package/types/dev/tui.d.ts +35 -0
  41. package/types/dev/watcher.d.ts +34 -0
  42. package/types/dev/worker-registry.d.ts +17 -0
  43. package/types/dev/ws-channel.d.ts +39 -0
  44. package/types/generator.d.ts +23 -0
  45. package/types/index.d.ts +222 -0
  46. package/types/islands/brust-page.d.ts +74 -0
  47. package/types/islands/build.d.ts +49 -0
  48. package/types/islands/chunk-id.d.ts +10 -0
  49. package/types/islands/importmap.d.ts +2 -0
  50. package/types/islands/island.d.ts +65 -0
  51. package/types/islands/isr-jsx.d.ts +31 -0
  52. package/types/islands/native-render.d.ts +89 -0
  53. package/types/loader-cache.d.ts +18 -0
  54. package/types/mcp/extractor.d.ts +14 -0
  55. package/types/mcp/manifest.d.ts +23 -0
  56. package/types/mcp/schema.d.ts +19 -0
  57. package/types/mcp/server.d.ts +15 -0
  58. package/types/md/emit.d.ts +72 -0
  59. package/types/md/render.d.ts +80 -0
  60. package/types/md/routes.d.ts +119 -0
  61. package/types/md/scan.d.ts +34 -0
  62. package/types/md/slug.d.ts +1 -0
  63. package/types/native/build.d.ts +30 -0
  64. package/types/native/index.d.ts +2 -0
  65. package/types/native/runtime.d.ts +52 -0
  66. package/types/navigation/active-nav.d.ts +2 -0
  67. package/types/navigation/index.d.ts +5 -0
  68. package/types/navigation/navigate.d.ts +14 -0
  69. package/types/navigation/react.d.ts +15 -0
  70. package/types/navigation/store.d.ts +44 -0
  71. package/types/render/fragment.d.ts +20 -0
  72. package/types/render/inject-action-prefix.d.ts +9 -0
  73. package/types/render/inject-css-link.d.ts +8 -0
  74. package/types/render/inject-dev-client.d.ts +6 -0
  75. package/types/render/inject-generator.d.ts +7 -0
  76. package/types/render/inject-store.d.ts +9 -0
  77. package/types/render/stream.d.ts +45 -0
  78. package/types/request-context.d.ts +16 -0
  79. package/types/routes.d.ts +506 -0
  80. package/types/sse/handler.d.ts +22 -0
  81. package/types/standard-schema.d.ts +31 -0
  82. package/types/store/define-store.d.ts +31 -0
  83. package/types/store/index.d.ts +5 -0
  84. package/types/store/react.d.ts +2 -0
  85. package/types/store/serialize.d.ts +5 -0
  86. package/types/store/server-context.d.ts +4 -0
  87. package/types/store/signal.d.ts +18 -0
  88. package/types/templates.d.ts +18 -0
  89. package/types/treaty.d.ts +70 -0
  90. package/types/ws/handler.d.ts +26 -0
@@ -0,0 +1,15 @@
1
+ import { type NavState } from './store.ts';
2
+ /** Watch the navigation state from a React island.
3
+ *
4
+ * ```tsx
5
+ * import { useNav } from 'brustjs/client'
6
+ * function Crumb() {
7
+ * const { path, phase } = useNav()
8
+ * return <span>{phase === 'loading' ? 'Loading…' : path}</span>
9
+ * }
10
+ * ```
11
+ *
12
+ * The third arg (server snapshot) is the same getter — on the server the store
13
+ * holds its idle defaults (no `location`), so SSR renders the idle state and the
14
+ * client hydrates the real one on mount. */
15
+ export declare function useNav(): NavState;
@@ -0,0 +1,44 @@
1
+ import { type Signal } from '../store/signal.ts';
2
+ export type NavPhase = 'idle' | 'loading' | 'success' | 'error';
3
+ export interface NavState {
4
+ path: string;
5
+ search: string;
6
+ phase: NavPhase;
7
+ error: Error | null;
8
+ from: string | null;
9
+ to: string | null;
10
+ }
11
+ export interface NavStore {
12
+ path: Signal<string>;
13
+ search: Signal<string>;
14
+ phase: Signal<NavPhase>;
15
+ error: Signal<Error | null>;
16
+ from: Signal<string | null>;
17
+ to: Signal<string | null>;
18
+ }
19
+ type BeforeCb = (e: {
20
+ from: string;
21
+ to: string;
22
+ }) => void;
23
+ type NavCb = (e: NavState) => void;
24
+ type ErrorCb = (e: {
25
+ to: string;
26
+ error: Error;
27
+ }) => void;
28
+ export declare const nav: NavStore;
29
+ export declare function getNavState(): NavState;
30
+ export declare function subscribe(cb: NavCb): () => void;
31
+ export declare function onBeforeNavigate(cb: BeforeCb): () => void;
32
+ export declare function onNavigate(cb: NavCb): () => void;
33
+ export declare function onNavigateError(cb: ErrorCb): () => void;
34
+ export declare function __navInit(path: string, search: string): void;
35
+ export declare function __navStart(toPath: string, _toSearch: string): void;
36
+ export declare function __navCommit(toPath: string, toSearch: string): void;
37
+ export declare function __navError(toPath: string, error: unknown): void;
38
+ /** Register the SPA navigator implementation (bootstrap's swap). Last-write-wins;
39
+ * re-registration with the same closure (HMR / multiple chunks) is idempotent. */
40
+ export declare function registerNavigator(fn: (url: URL, replace: boolean) => Promise<void>): void;
41
+ /** @internal — the registered navigator, or null when no islands bootstrap loaded. */
42
+ export declare function _getNavigator(): ((url: URL, replace: boolean) => Promise<void>) | null;
43
+ export declare function __resetNavForTest(): void;
44
+ export {};
@@ -0,0 +1,20 @@
1
+ import { type ComponentType, type ReactNode } from 'react';
2
+ /** Render a React element to a single HTML string, awaiting all Suspense
3
+ * boundaries via onAllReady. Used by navigationBranch — renderToString
4
+ * would only capture the shell + fallbacks, while renderBranchStreaming
5
+ * is for the streaming render path. */
6
+ export declare function renderToAwaitedString(element: ReactNode): Promise<string>;
7
+ export interface RenderFragmentOpts {
8
+ /** Request cookies visible to cookies()/session helpers inside the tree. */
9
+ cookies?: Record<string, string>;
10
+ }
11
+ /** Render a component to an HTML string with framework contexts scoped:
12
+ * request scope (cookies) ∘ request cache (cachedFetch/dedupe) ∘ store
13
+ * context (fresh per call — no cross-call leakage; concurrency-safe via
14
+ * AsyncLocalStorage). Suspense supported — the promise resolves when the
15
+ * whole tree is ready, never with fallbacks. Static HTML only: no island
16
+ * hydration markers/scripts (an `<Island>` inside the fragment SSRs its
17
+ * component but ships no hydration), no head/CSS collection, no streaming.
18
+ * Native/jinja fragments are served by `templates.render` instead.
19
+ * Errors reject with the component's error — no error-boundary semantics. */
20
+ export declare function renderFragment<P extends object>(Component: ComponentType<P>, props: P, opts?: RenderFragmentOpts): Promise<string>;
@@ -0,0 +1,9 @@
1
+ /** @internal — used by tests to reset the warn-once flag. */
2
+ export declare function _resetWarnedForTests(): void;
3
+ /** Splice `snippet` (a full `<script>…</script>`) into `body` immediately
4
+ * before the first `</head>` (case-insensitive on the four ASCII letters
5
+ * only). Returns the original body untouched if `snippet` is null/empty or if
6
+ * `</head>` is absent. */
7
+ export declare function injectActionPrefix(body: Uint8Array, snippet: string | null): Uint8Array;
8
+ export declare function configureActionPrefixSnippet(s: string | null): void;
9
+ export declare function getActionPrefixSnippet(): string | null;
@@ -0,0 +1,8 @@
1
+ /** @internal — used by the unit test suite to reset the warn-once flag. */
2
+ export declare function _resetWarnedForTests(): void;
3
+ /** Splice `<link rel="stylesheet" href="...">` tags into `body` immediately
4
+ * before the first occurrence of `</head>` (case-insensitive). Returns the
5
+ * original body untouched if `hrefs` is empty or if `</head>` is absent
6
+ * (warns once in the latter case). Renderer calls this on the first chunk
7
+ * only — see spec S"SSR <link> injection". */
8
+ export declare function injectCssLink(body: Uint8Array, hrefs: readonly string[]): Uint8Array;
@@ -0,0 +1,6 @@
1
+ /** @internal — used by tests to reset the warn-once flag. */
2
+ export declare function _resetWarnedForTests(): void;
3
+ /** Splice `snippet` into `body` immediately before the first `</head>`
4
+ * (case-insensitive on the four ASCII letters only). Returns the original body
5
+ * untouched if `snippet` is null/empty or if `</head>` is absent. */
6
+ export declare function injectDevClient(body: Uint8Array, snippet: string | null): Uint8Array;
@@ -0,0 +1,7 @@
1
+ /** Seed from generator.json at boot (main + worker). null → no injection. */
2
+ export declare function configureGeneratorMeta(meta: string | null): void;
3
+ export declare function getGeneratorMeta(): string | null;
4
+ /** Splice `metaTag` immediately before the first `</head>` (case-insensitive).
5
+ * No </head> in the chunk, empty tag, or an existing generator meta → body
6
+ * returned untouched. Byte-level (no decode) — safe with multibyte content. */
7
+ export declare function injectGeneratorMeta(body: Uint8Array, metaTag: string | null): Uint8Array;
@@ -0,0 +1,9 @@
1
+ /** @internal — used by tests to reset the warn-once flag. */
2
+ export declare function _resetWarnedForTests(): void;
3
+ /** Build the combined `<script type="application/json">` blob for every touched
4
+ * store. Returns '' when the snapshot is null/empty. */
5
+ export declare function buildStoreScripts(snap: Record<string, Record<string, unknown>> | null): string;
6
+ /** Splice the store snapshot `<script>`(s) into `body` immediately before the
7
+ * first `</head>`. Returns the original body untouched if the snapshot is
8
+ * null/empty or if `</head>` is absent. */
9
+ export declare function injectBrustStore(body: Uint8Array, snap: Record<string, Record<string, unknown>> | null): Uint8Array;
@@ -0,0 +1,45 @@
1
+ import { type ReactNode, type ComponentType } from 'react';
2
+ export interface RenderBranchStreamingArgs {
3
+ element: ReactNode;
4
+ /** The render's SAB sub-view (whole buffer at slots=1). All chunk encodes
5
+ * write at offset 0 of this view → automatically the slot's base. */
6
+ view: Uint8Array;
7
+ /** The render slot index, passed to every napi.renderChunk* call so Rust
8
+ * reads/writes the matching SAB sub-region. Default 0 (single-slot path). */
9
+ slot?: number;
10
+ workerId: bigint;
11
+ napi: {
12
+ renderChunk: (workerId: bigint, slot: number, len: number, sabBytes: Uint8Array) => Promise<void>;
13
+ renderChunkFinal: (workerId: bigint, slot: number, len: number, sabBytes: Uint8Array) => Promise<void>;
14
+ };
15
+ errorBoundary: ComponentType<{
16
+ error: Error;
17
+ }>;
18
+ /** Status for the successful (non-error) render. Default 200. Used by
19
+ * middleware-wrapped routes that want to set a non-200 status before
20
+ * the component runs (e.g. 201 from a server action redirect). */
21
+ status?: number;
22
+ /** Extra response headers injected by middleware (e.g. `x-render-ms`).
23
+ * Merged into the meta envelope's `headers` map. */
24
+ headers?: Record<string, string>;
25
+ /** The matched route's fullPath (e.g. '/' or '/blog/{slug}'). Used to
26
+ * combine global CSS hrefs with per-route CSS hrefs before injection. */
27
+ routePath?: string;
28
+ /** Per-request store snapshot collected after loaders run. Injected as a
29
+ * `<script data-brust-store="…">` blob before `</head>` (buffering) or into
30
+ * the streaming first-chunk prepend. Null/undefined → no injection. */
31
+ storeSnapshot?: Record<string, Record<string, unknown>> | null;
32
+ /** Inject the islands importmap + bootstrap even when no <Island> rendered.
33
+ * SSG fallback shells need the bootstrap (client takeover runtime) on pages
34
+ * that may have zero real islands. */
35
+ forceIslands?: boolean;
36
+ }
37
+ /** JSON.stringify the per-chunk meta. Defaults match the renderToString
38
+ * path so single-chunk responses keep their existing wire shape. */
39
+ export declare function makeMeta(opts: {
40
+ status: number;
41
+ streaming: boolean;
42
+ contentType?: string;
43
+ headers?: Record<string, string>;
44
+ }): string;
45
+ export declare function renderBranchStreaming(args: RenderBranchStreamingArgs): Promise<void>;
@@ -0,0 +1,16 @@
1
+ interface RequestScope {
2
+ ctx: Map<string, unknown>;
3
+ reqCookies: Record<string, string>;
4
+ setCookies: string[];
5
+ }
6
+ /** Open a per-request scope. `reqCookies` is the parsed incoming Cookie header
7
+ * (BrustRequest.cookies). Staged Set-Cookie strings accumulate in `setCookies`
8
+ * and are flushed by routes.ts onto the response headers. */
9
+ export declare function runInRequestScope<T>(reqCookies: Record<string, string>, fn: () => T): T;
10
+ /** Per-request scratch Map for apps building request-scoped state on top of the
11
+ * module-global store. Throws when called outside a request scope. */
12
+ export declare function getRequestContext(): Map<string, unknown>;
13
+ /** Internal — the active scope (or undefined). Used by cookies.ts and the
14
+ * routes.ts flush. Not re-exported from the package entry. */
15
+ export declare function __scope(): RequestScope | undefined;
16
+ export {};