@bgub/fig-tanstack-start 0.0.0-tegami-trusted-publish-setup → 0.1.0-alpha.2

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 (42) hide show
  1. package/CHANGELOG.md +225 -0
  2. package/LICENSE +21 -0
  3. package/README.md +280 -3
  4. package/dist/client-B2okTbp3.js +29 -0
  5. package/dist/client-B2okTbp3.js.map +1 -0
  6. package/dist/client.d.ts +13 -0
  7. package/dist/client.js +2 -0
  8. package/dist/data.d.ts +14 -0
  9. package/dist/data.js +34 -0
  10. package/dist/data.js.map +1 -0
  11. package/dist/default-entry/client.d.ts +1 -0
  12. package/dist/default-entry/client.js +7 -0
  13. package/dist/default-entry/client.js.map +1 -0
  14. package/dist/default-entry/server.d.ts +4 -0
  15. package/dist/default-entry/server.js +6 -0
  16. package/dist/default-entry/server.js.map +1 -0
  17. package/dist/default-entry/start.d.ts +4 -0
  18. package/dist/default-entry/start.js +6 -0
  19. package/dist/default-entry/start.js.map +1 -0
  20. package/dist/payload-assets-eHfSAMbN.js +14 -0
  21. package/dist/payload-assets-eHfSAMbN.js.map +1 -0
  22. package/dist/payload-internal-CZhfVhwH.js +168 -0
  23. package/dist/payload-internal-CZhfVhwH.js.map +1 -0
  24. package/dist/payload.d.ts +19 -0
  25. package/dist/payload.js +38 -0
  26. package/dist/payload.js.map +1 -0
  27. package/dist/plugin/vite.d.ts +6 -0
  28. package/dist/plugin/vite.js +857 -0
  29. package/dist/plugin/vite.js.map +1 -0
  30. package/dist/server.d.ts +20 -0
  31. package/dist/server.js +111 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/start-context-DZ2gsb5m.js +12 -0
  34. package/dist/start-context-DZ2gsb5m.js.map +1 -0
  35. package/dist/storage-context.d.ts +9 -0
  36. package/dist/storage-context.js +21 -0
  37. package/dist/storage-context.js.map +1 -0
  38. package/dist/store-CibAGqiI.js +13 -0
  39. package/dist/store-CibAGqiI.js.map +1 -0
  40. package/dist/transport-DKcSG44e.js +33 -0
  41. package/dist/transport-DKcSG44e.js.map +1 -0
  42. package/package.json +90 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,225 @@
1
+ ## @bgub/fig-tanstack-start@0.1.0-alpha.1
2
+
3
+ ### Refresh resolves the app's renderer runtime
4
+
5
+ `figRefresh` now imports `@bgub/fig-dom/refresh` through its bare specifier
6
+ rather than a resolved `/@fs/` path, so app-level aliases, dedupe, and
7
+ prebundling apply and the refresh scheduler cannot be instantiated twice.
8
+
9
+ ### TanStack Start's client graph is prebundled
10
+
11
+ The TanStack Start adapter now prebundles `@tanstack/start-client-core` in
12
+ development while leaving its application-bound router and Start imports as
13
+ external Vite modules. This reduces the module-request waterfall without
14
+ freezing generated app entries or the linked Fig adapter packages. Production
15
+ continues to use Vite's normal application bundling.
16
+
17
+ ### Make Payload trees directly renderable
18
+
19
+ `createPayloadComponent` now creates a props-typed component backed by Fig's
20
+ ordinary data store. Complete props form its cache identity by default through
21
+ a canonical encoding of Payload-compatible values, and the component works
22
+ with route loaders and the existing data-resource freshness APIs and explicit
23
+ store handles.
24
+
25
+ The lower-level `payloadDataLoader` and `PayloadDataLoaderOptions` exports have
26
+ been removed. Use `createPayloadComponent`, or `decodePayloadStream` when
27
+ managing the transport and data integration directly.
28
+
29
+ TanStack Start replaces `payloadResource({ key, render })` with
30
+ `createPayloadComponent({ key, load: serverPayload(render) })`. Its compiler
31
+ can extract a component imported from `.server.tsx`, while initial companion
32
+ streams, client references, and compiled asset dependencies keep their existing
33
+ transport behavior.
34
+
35
+ Payload component loaders receive the resolved resource `key` alongside
36
+ `signal`, so framework transports can register responses under the exact cache
37
+ entry without changing ordinary data loaders.
38
+
39
+ Default keys are canonical across plain-object property order, and Payload
40
+ components use their namespace as their DevTools label. TanStack Start renders
41
+ the supplied component inside the Payload renderer so root-level reads and
42
+ suspension work, and rejects uncompiled `serverPayload` calls before invoking
43
+ application code.
44
+
45
+ Payload rendering also rejects nesting one Payload component inside another in
46
+ development. Payload components are client-visible delivery boundaries;
47
+ compose ordinary server components inside them or mount separate Payload
48
+ components from the client tree to preserve independent refresh keys.
49
+
50
+ ### Promise-valued children render through Suspense
51
+
52
+ `FigNode` now accepts promises of nodes. Promise children occupy distinct,
53
+ host-transparent child slots, suspend through the nearest `Suspense`, and route
54
+ rejections or invalid resolved children through normal error handling.
55
+
56
+ HTML rendering retains exact promise children as independent streaming tasks,
57
+ while Payload uses node-validated promise rows that decode to the same child
58
+ shape. Payload-rendered async components are invoked once and retain their
59
+ component-scoped assets on the outlined row.
60
+
61
+ ### Move HTML escaping helpers to a focused subpath
62
+
63
+ `escapeAttribute`, `escapeText`, `escapeScriptText`, and `escapeScriptJson` now export from
64
+ `@bgub/fig-server/html` instead of the main `@bgub/fig-server` entry.
65
+ The dedicated subpath keeps companion-markup helpers separate from server
66
+ render entry points while preserving their exact escaping behavior. The
67
+ TanStack Start adapter now consumes these helpers, Fig's internal data-store
68
+ brand predicate, and its own storage-context API instead of duplicating them.
69
+
70
+ ### Expose render-discovered assets as response preload headers
71
+
72
+ Server stream results now provide a bounded, deduplicated HTTP `Link` value for
73
+ preconnects, fonts, stylesheets, explicit preloads, and module preloads
74
+ discovered before the shell becomes ready. Filters let adapters exclude asset
75
+ URLs that are unsafe for a shared cache.
76
+
77
+ The TanStack Start renderer can opt into merging that shell snapshot with the
78
+ response's existing `Link` header before constructing the streamed response.
79
+ Assets discovered after the shell continue to arrive through HTML streaming.
80
+
81
+ ### Build generated TanStack Start file routes with Fig
82
+
83
+ `@bgub/fig-tanstack-router` now implements generated file routes, lazy route
84
+ records, lazy components, and lazy loader functions. TanStack Start builds and
85
+ reloads those routes in development through its existing generator and code
86
+ splitter.
87
+
88
+ `@bgub/fig-tanstack-start` now exposes Start configuration and middleware
89
+ factories. Its demo covers request-isolated middleware context, server and
90
+ client redirects, generated error and not-found routes, split chunks, SSR,
91
+ hydration, and server-function mutations.
92
+
93
+ ### Complete Fig-native data and navigation patterns
94
+
95
+ TanStack Start routes can now preload Payload data and return immediately,
96
+ letting Fig Suspense stream the result and its asset resources without copying
97
+ values into Router loader data. Initial Payload responses registered after the
98
+ document shell starts are embedded before hydration, preventing a duplicate
99
+ client request.
100
+
101
+ The Router adapter adds modern object-only `useBlocker` and reactive
102
+ `useCanGoBack` hooks, makes the concrete Router and RouteApi constructors
103
+ internal, and rejects unsupported proximity preloading in `LinkProps`.
104
+ Fig's structural `ViewTransition` remains the sole document-transition owner,
105
+ even when a TanStack navigation carries its `viewTransition` option.
106
+
107
+ ### Give each matched route ownership of its Fig assets
108
+
109
+ Route stylesheets, preload hints, preconnects, font preloads, and async scripts
110
+ now enter Fig's shared asset registry at the matched subtree. This gives Start
111
+ streaming, client navigation, and Payload assets one deduplicating ownership
112
+ model while title, meta, inline styles, JSON-LD, and synchronous scripts retain
113
+ their declared document positions.
114
+
115
+ Manifest `assetCrossOrigin` configuration now belongs to `createRouter`
116
+ options, where it is available before the root match renders.
117
+
118
+ ### Fix first-load styling and development client navigation
119
+
120
+ Keep TanStack Start's compiler-sensitive client modules out of Vite dependency
121
+ prebundling so client navigation uses the client server-function transport
122
+ instead of executing server-only context access in the browser. Preserve
123
+ browser-extension roots appended to document singletons during hydration so a
124
+ third-party node cannot trigger document replacement and remove stylesheets.
125
+
126
+ ### Compile Payload components and their assets
127
+
128
+ Fig TanStack Start now turns stylesheet imports in the ordinary component graph
129
+ reached from a `payloadResource` render callback into Payload asset dependencies
130
+ automatically. The same declaration compiles to a private TanStack server
131
+ function and Payload response, so applications no longer author
132
+ `createServerFn`, `renderPayloadResponse`, or request plumbing for Payload
133
+ routes. Payload rendering is independent of filenames. Applications
134
+ conventionally use `.payload.tsx` for the shared resource declaration, but the
135
+ suffix is only a human label. Components and assets referenced only by the
136
+ render callback are omitted from the browser bundle. Compiled styles use the
137
+ existing Payload row ownership, dedupe, streaming, and reveal-gating behavior
138
+ without requiring an `assets(stylesheet(...))` wrapper.
139
+
140
+ Applications mark the exceptional SSR-plus-hydration boundary with
141
+ `<Isomorphic component={Counter} ... />` and an ordinary static import. The
142
+ generated per-bundle manifest owns module resolution, stable component
143
+ identity, and client CSS metadata, so applications no longer author
144
+ `clientReference`, `createPayloadClientReferenceResolver`, ids, or dynamic
145
+ imports. Ordinary component uses remain Payload-rendered.
146
+
147
+ ### Own the TanStack Start document transport
148
+
149
+ `StartScripts` now owns Fig data serialization, the initial Payload insertion
150
+ point, and TanStack's bootstrap scripts as one ordered document surface. The
151
+ Payload transport targets a Fig-owned marker instead of matching TanStack's
152
+ private hydration-barrier markup.
153
+
154
+ The Vite adapter records its exact Router and Start core compatibility profile
155
+ and rejects emitted Solid Router or Start adapter modules. Server-only assets
156
+ are still mirrored into the public client output, but a conflicting client
157
+ asset now fails the build instead of being silently overwritten.
158
+
159
+ ### TanStack Start gains state-preserving Fast Refresh
160
+
161
+ The TanStack Start Vite adapter now installs Fig Fast Refresh automatically.
162
+ Component edits update in place and preserve hook state in accepted modules.
163
+
164
+ `@bgub/fig-vite` is now a public package containing the reusable Fast Refresh
165
+ and server data-resource transforms.
166
+
167
+ ### Add Payload routes to the TanStack Start adapter
168
+
169
+ `@bgub/fig-tanstack-start/payload` now exposes `payloadResource`, which compiles
170
+ an inline render callback into a private server function and Fig-owned route
171
+ data resource. Applications supply the cache key and component tree without
172
+ authoring transport plumbing. The shared declaration can stay in one
173
+ `.payload.tsx` module; its render callback and render-only imports are omitted
174
+ from the browser build. The initial SSR response is embedded into the document
175
+ and adopted without refetching; client navigation and refresh use the same
176
+ resource request path. Payload data rows
177
+ hydrate the shared store, asset resources are retained on their owning server
178
+ segments or inserted through the browser registry, and client references retain
179
+ their resolver-defined identity. `decodePayloadStream` and `payloadDataLoader`
180
+ now expose `retainAssets` for server document renderers that need this delivery
181
+ path.
182
+
183
+ `@bgub/fig-tanstack-start/server` exposes the lower-level
184
+ `renderPayloadResponse` used by the generated TanStack server function; it
185
+ defaults its render abort signal to the incoming request, so a disconnected
186
+ client cancels the Payload render. Shell
187
+ HTML streams while outlined Suspense holes settle, and the completed initial
188
+ responses are embedded before TanStack starts full-document hydration. The Vite
189
+ adapter also publishes assets imported only by server modules into the client
190
+ build output. Fig Router links also consume TanStack's `viewTransition`
191
+ navigation option without forwarding it as an invalid attribute to the rendered
192
+ anchor, and derive active state from the resolved route instead of an in-flight
193
+ location.
194
+
195
+ ### Add the TanStack Start runtime adapter
196
+
197
+ `createDataStore` now creates a root-neutral Fig store that route loaders can
198
+ populate before a renderer exists. Server and client renderers adopt that exact
199
+ store, preserving one cache while attaching their lifecycle and scheduling.
200
+
201
+ The new TanStack Start runtime uses the store for route loading, server
202
+ rendering, Fig-owned document serialization, client deserialization, and
203
+ hydration. Route-managed head and script output maps through the Router adapter,
204
+ including Fig asset resources. The end-to-end contract verifies no initial
205
+ client refetch and exactly one reload after invalidation.
206
+
207
+ ### Build Fig applications with TanStack Start and Vite
208
+
209
+ `@bgub/fig-tanstack-start/plugin/vite` now delegates client and SSR builds,
210
+ development and preview serving, manifests, and server-function compilation to
211
+ TanStack Start's plugin core. Default entries stream and hydrate Fig documents
212
+ without application-owned build or HTTP glue.
213
+
214
+ The package root now exposes `createServerFn`. Compiled mutations use TanStack's
215
+ RPC transport and can invalidate the live Fig data store afterward; the demo
216
+ proves the full production flow from SSR hydration through mutation and one
217
+ data-resource refresh.
218
+
219
+ ## @bgub/fig-tanstack-start@0.1.0-alpha.0 (alpha)
220
+
221
+ ### Initial alpha release
222
+
223
+ First public alpha release of the TanStack Start adapter for Fig.
224
+
225
+ # Changelog
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Ben Gubler
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,5 +1,282 @@
1
- # Placeholder package
1
+ # @bgub/fig-tanstack-start
2
2
 
3
- This empty package was published by [Tegami](https://tegami.fuma-nama.dev) to configure npm trusted publishing.
3
+ The TanStack Start adapter for Fig. TanStack owns builds, requests, route
4
+ loading, redirects, and server-function transport; Fig owns rendering, data
5
+ resources, asset resources, and the single data store used by loaders and
6
+ components.
4
7
 
5
- The real package contents will be published via CI with OIDC.
8
+ ```bash
9
+ pnpm add @bgub/fig-tanstack-start @bgub/fig-tanstack-router
10
+ ```
11
+
12
+ Add the adapter to Vite:
13
+
14
+ ```ts
15
+ import { tanstackStart } from "@bgub/fig-tanstack-start/plugin/vite";
16
+
17
+ const plugins = [tanstackStart()];
18
+ ```
19
+
20
+ The plugin supplies the default client and server entries, including streamed
21
+ Fig SSR, full-document hydration, and state-preserving Fig Fast Refresh. It
22
+ currently uses TanStack's Solid target
23
+ as a private compiler compatibility layer because plugin core has no custom
24
+ framework target. The generator currently normalizes file-route constructor
25
+ imports to its Solid package ID; the plugin maps that ID directly to Fig, and no
26
+ Solid Router or Start adapter runtime is installed or bundled. TypeScript needs the corresponding
27
+ compiler-only `paths` entry:
28
+
29
+ ```json
30
+ {
31
+ "compilerOptions": {
32
+ "paths": {
33
+ "@tanstack/solid-router": ["./node_modules/@bgub/fig-tanstack-router"],
34
+ "@tanstack/solid-start": ["./node_modules/@bgub/fig-tanstack-start"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ## Response preload headers
41
+
42
+ The default server entry leaves response `Link` headers disabled because a CDN
43
+ may cache and replay request-specific asset URLs. A custom server entry can opt
44
+ in globally or provide a resource filter:
45
+
46
+ ```ts
47
+ import { createFigStartHandler } from "@bgub/fig-tanstack-start/server";
48
+
49
+ const fetch = createFigStartHandler({
50
+ preloadHeader: {
51
+ filter: (resource) => resource.href.startsWith("/assets/"),
52
+ },
53
+ });
54
+
55
+ export default { fetch };
56
+ ```
57
+
58
+ The header contains assets discovered before Fig's document shell becomes
59
+ ready. Assets discovered later through Suspense or Payload remain in the HTML
60
+ stream and cannot be added after the response is created.
61
+
62
+ The Start mapping lets the generated registration footer carry middleware
63
+ context types from a conventional `src/start.ts` into `createServerFn`.
64
+
65
+ Create the router with a root-neutral Fig store:
66
+
67
+ ```tsx
68
+ import { createStartDataContext } from "@bgub/fig-tanstack-start";
69
+ import {
70
+ createRouter,
71
+ createRootRouteWithContext,
72
+ } from "@bgub/fig-tanstack-router";
73
+
74
+ const startData = createStartDataContext();
75
+ const rootRoute = createRootRouteWithContext<typeof startData.context>()({
76
+ component: Document,
77
+ });
78
+
79
+ export const router = createRouter({
80
+ ...startData,
81
+ routeTree: rootRoute,
82
+ });
83
+ ```
84
+
85
+ The root document renders route-managed assets followed by Start's combined Fig data and TanStack script transport:
86
+
87
+ ```tsx
88
+ import { StartScripts } from "@bgub/fig-tanstack-start";
89
+ import { HeadContent, Outlet } from "@bgub/fig-tanstack-router";
90
+
91
+ function Document() {
92
+ return (
93
+ <html lang="en">
94
+ <head>
95
+ <HeadContent />
96
+ </head>
97
+ <body>
98
+ <Outlet />
99
+ <StartScripts />
100
+ </body>
101
+ </html>
102
+ );
103
+ }
104
+ ```
105
+
106
+ `StartScripts` serializes the Fig store into the server document with Fig's value codec, establishes the adapter's Payload insertion point, and then renders TanStack's bootstrap scripts. Client router creation decodes the data before TanStack hydration can start route loaders; `hydrateStart` repeats that step idempotently as a fallback before `hydrateRoot` adopts the same client store. The first `readData` therefore hits the hydrated entry without re-running its loader, and `invalidateData` operates directly on the live root store.
107
+
108
+ ## Request and function middleware
109
+
110
+ The package root also exports TanStack's `createStart`, `createMiddleware`, and
111
+ `createCsrfMiddleware`. A conventional `src/start.ts` configures global request
112
+ and server-function middleware:
113
+
114
+ ```ts
115
+ import {
116
+ createCsrfMiddleware,
117
+ createMiddleware,
118
+ createStart,
119
+ } from "@bgub/fig-tanstack-start";
120
+
121
+ const requestContext = createMiddleware({ type: "request" }).server(
122
+ ({ request, next }) =>
123
+ next({ context: { requestId: request.headers.get("x-request-id") } }),
124
+ );
125
+
126
+ export const startInstance = createStart(() => ({
127
+ requestMiddleware: [
128
+ requestContext,
129
+ createCsrfMiddleware({
130
+ filter: (context) => context.handlerType === "serverFn",
131
+ }),
132
+ ],
133
+ }));
134
+ ```
135
+
136
+ Start's global async context remains request-local across interleaved SSR and
137
+ server-function work. Redirects thrown by generated route loaders or
138
+ `beforeLoad` use Router Core's normal server and client redirect handling.
139
+
140
+ ## Server functions
141
+
142
+ The package root exports TanStack's `createServerFn`. The Vite plugin compiles
143
+ the handler into the server build and the browser call into an RPC request:
144
+
145
+ ```ts
146
+ import { createServerFn } from "@bgub/fig-tanstack-start";
147
+
148
+ export const renameUser = createServerFn({ method: "POST" })
149
+ .validator((input: { id: string; name: string }) => input)
150
+ .handler(async ({ data }) => {
151
+ await database.users.rename(data.id, data.name);
152
+ });
153
+ ```
154
+
155
+ An async event must capture the Fig store before its first `await` when it
156
+ needs to refresh data afterward:
157
+
158
+ ```ts
159
+ import { readDataStore } from "@bgub/fig";
160
+
161
+ const data = readDataStore();
162
+ await renameUser({ data: { id, name }, signal });
163
+ data.invalidateData(userResource, id);
164
+ ```
165
+
166
+ ## Payload routes
167
+
168
+ Payload routes keep Payload-rendered component trees out of the client bundle
169
+ while using the same Fig data store as ordinary route data. The smallest route
170
+ is one colocated declaration:
171
+
172
+ ```tsx
173
+ // profile.payload.tsx
174
+ import { createPayloadComponent } from "@bgub/fig-dom";
175
+ import { serverPayload } from "@bgub/fig-tanstack-start/payload";
176
+ import { Profile } from "./Profile.server.tsx";
177
+
178
+ export const ProfilePage = createPayloadComponent<{ id: string }>({
179
+ key: ["profile-payload"],
180
+ load: serverPayload(Profile),
181
+ });
182
+ ```
183
+
184
+ `serverPayload` accepts a component or render callback; it is the semantic
185
+ boundary that the compiler extracts into a private server function. It may be
186
+ async. The browser bundle keeps the component handle, cache, and RPC stub; it
187
+ omits the server render and imports used only by it. Keep the Payload component
188
+ declaration in a client-importable module such as `.payload.tsx` because the
189
+ route imports that handle. The rendered component itself may live in a
190
+ TanStack-protected `.server.tsx` module.
191
+
192
+ When the tree grows, the callback can import ordinary components. Those imports
193
+ also stay out of the browser bundle when only the callback uses them. A filename
194
+ does not cause a component to render through Payload—`serverPayload` does.
195
+ Applications do not call `createServerFn` or `renderPayloadResponse` for Payload
196
+ resources.
197
+
198
+ Mark the exceptional SSR-plus-hydration boundary with `Isomorphic` and an
199
+ ordinary static component import. For example, a separate Payload component can
200
+ contain the boundary:
201
+
202
+ ```tsx
203
+ import type { FigNode } from "@bgub/fig";
204
+ import { Isomorphic } from "@bgub/fig-tanstack-start/payload";
205
+ import { LikeButton } from "./LikeButton.tsx";
206
+
207
+ export function Profile({ id }: { id: string }): FigNode {
208
+ return <Isomorphic component={LikeButton} userId={id} />;
209
+ }
210
+ ```
211
+
212
+ The Vite plugin replaces only the `component` prop with an opaque Payload
213
+ reference and generates its server/browser module resolver. The component
214
+ remains an ordinary export and can render through Payload elsewhere without
215
+ the boundary. `component` must be a named or default static import.
216
+ Applications do not use a `.client.tsx` suffix, `clientReference`,
217
+ `createPayloadClientReferenceResolver`, reference ids, or dynamic imports.
218
+
219
+ The route can start the load early, then render the component normally:
220
+
221
+ ```tsx
222
+ import { ensureRouteData } from "@bgub/fig-tanstack-router";
223
+ import { createFileRoute } from "@tanstack/solid-router";
224
+ import { ProfilePage } from "../profile.payload.tsx";
225
+
226
+ export const Route = createFileRoute("/profiles/$id")({
227
+ loader: ({ context, params }) =>
228
+ ensureRouteData(context, ProfilePage, { id: params.id }),
229
+ component: ProfileRoute,
230
+ });
231
+
232
+ function ProfileRoute() {
233
+ const { id } = Route.useParams();
234
+ return <ProfilePage id={id} />;
235
+ }
236
+ ```
237
+
238
+ When the route does not need the tree before commit, preload it and return
239
+ `void`; Fig Suspense then owns the pending UI and stream:
240
+
241
+ ```tsx
242
+ import { Suspense } from "@bgub/fig";
243
+
244
+ export const Route = createFileRoute("/profiles/$id")({
245
+ loader: ({ context, params }) => {
246
+ context.data.preloadData(ProfilePage, { id: params.id });
247
+ },
248
+ component: () => (
249
+ <Suspense fallback={<p>Streaming profile…</p>}>
250
+ <ProfileRoute />
251
+ </Suspense>
252
+ ),
253
+ });
254
+ ```
255
+
256
+ On SSR, Fig decodes and renders the root once, retains Payload-discovered asset
257
+ resources on the rows that declared them, and embeds the response bytes for
258
+ hydration. This includes Payload resources registered after the document shell
259
+ starts. The document renderer emits each asset before its dependent HTML
260
+ segment, including streamed Suspense holes. The browser adopts the embedded
261
+ bytes without a second server-function call. Shell HTML streams while Suspense
262
+ holes settle; TanStack starts full-document hydration after each complete
263
+ initial Payload response is embedded in a keyed carrier. Client navigation and
264
+ refresh use the same raw response path.
265
+
266
+ The Vite adapter follows ordinary component imports from each `serverPayload`
267
+ render and compiles their static stylesheet imports into Payload asset
268
+ dependencies. Import CSS normally; no manual
269
+ `assets(stylesheet(...))` wrapper or `?url` import is needed. A Payload-rendered
270
+ component's stylesheet is copied from the server build into the public client
271
+ output. An `Isomorphic` component's hashed client CSS is attached through the
272
+ generated manifest. Both use the existing Payload asset row and reveal gate
273
+ and are emitted only when their component renders.
274
+
275
+ The [`demo-tanstack-start`](../../apps/demo-tanstack-start) app exercises the
276
+ adapter through Vite's production client and SSR builds: generated and split
277
+ file routes, streamed SSR, Router dehydration, Fig-owned data serialization,
278
+ full-document hydration, request-derived themes, view transitions, live
279
+ data-resource invalidation, nested routes, and post and asset Payload trees all
280
+ run through public adapter entries. The asset route embeds two independent
281
+ Payload resources and hydrates an explicit `Isomorphic` component whose CSS and
282
+ SVG are emitted through the production builds.
@@ -0,0 +1,29 @@
1
+ import { n as hydrateStartDataStore } from "./transport-DKcSG44e.js";
2
+ import { RouterProvider } from "@bgub/fig-tanstack-router";
3
+ import { hydrateRoot } from "@bgub/fig-dom";
4
+ import { hydrateStart } from "@tanstack/start-client-core/client";
5
+ import { jsx } from "@bgub/fig-dom/jsx-runtime";
6
+ //#region src/client.tsx
7
+ async function hydrateStart$1(options = {}) {
8
+ const { container = document, ...rootOptions } = options;
9
+ await waitForRouterBootstrap();
10
+ const router = await hydrateStart();
11
+ const dataStore = hydrateStartDataStore(router.options.context, document);
12
+ const root = hydrateRoot(container, /* @__PURE__ */ jsx(RouterProvider, { router }), {
13
+ ...rootOptions,
14
+ dataStore
15
+ });
16
+ window.$_TSR?.h();
17
+ return {
18
+ root,
19
+ router
20
+ };
21
+ }
22
+ async function waitForRouterBootstrap() {
23
+ if (window.$_TSR !== void 0 || document.readyState !== "loading") return;
24
+ await new Promise((resolve) => document.addEventListener("DOMContentLoaded", () => resolve(), { once: true }));
25
+ }
26
+ //#endregion
27
+ export { hydrateStart$1 as t };
28
+
29
+ //# sourceMappingURL=client-B2okTbp3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-B2okTbp3.js","names":["hydrateStart","hydrateTanStackStart"],"sources":["../src/client.tsx"],"sourcesContent":["import {\n type Container,\n type FigRoot,\n type FigRootOptions,\n hydrateRoot,\n} from \"@bgub/fig-dom\";\nimport { RouterProvider } from \"@bgub/fig-tanstack-router\";\nimport { hydrateStart as hydrateTanStackStart } from \"@tanstack/start-client-core/client\";\nimport type { AnyRouter } from \"@tanstack/router-core\";\nimport { hydrateStartDataStore } from \"./transport.ts\";\n\nexport interface HydrateStartOptions extends Omit<\n FigRootOptions,\n \"dataPartition\" | \"dataStore\" | \"initialData\"\n> {\n container?: Container;\n}\n\nexport interface HydratedStart {\n root: FigRoot;\n router: AnyRouter;\n}\n\nexport async function hydrateStart(\n options: HydrateStartOptions = {},\n): Promise<HydratedStart> {\n const { container = document, ...rootOptions } = options;\n await waitForRouterBootstrap();\n const router = await hydrateTanStackStart();\n const dataStore = hydrateStartDataStore(router.options.context, document);\n\n const root = hydrateRoot(container, <RouterProvider router={router} />, {\n ...rootOptions,\n dataStore,\n });\n window.$_TSR?.h();\n return { root, router };\n}\n\nasync function waitForRouterBootstrap(): Promise<void> {\n if (window.$_TSR !== undefined || document.readyState !== \"loading\") return;\n await new Promise<void>((resolve) =>\n document.addEventListener(\"DOMContentLoaded\", () => resolve(), {\n once: true,\n }),\n );\n}\n"],"mappings":";;;;;;AAuBA,eAAsBA,eACpB,UAA+B,CAAC,GACR;CACxB,MAAM,EAAE,YAAY,UAAU,GAAG,gBAAgB;CACjD,MAAM,uBAAuB;CAC7B,MAAM,SAAS,MAAMC,aAAqB;CAC1C,MAAM,YAAY,sBAAsB,OAAO,QAAQ,SAAS,QAAQ;CAExE,MAAM,OAAO,YAAY,WAAW,oBAAC,gBAAD,EAAwB,OAAS,CAAA,GAAG;EACtE,GAAG;EACH;CACF,CAAC;CACD,OAAO,OAAO,EAAE;CAChB,OAAO;EAAE;EAAM;CAAO;AACxB;AAEA,eAAe,yBAAwC;CACrD,IAAI,OAAO,UAAU,KAAA,KAAa,SAAS,eAAe,WAAW;CACrE,MAAM,IAAI,SAAe,YACvB,SAAS,iBAAiB,0BAA0B,QAAQ,GAAG,EAC7D,MAAM,KACR,CAAC,CACH;AACF"}
@@ -0,0 +1,13 @@
1
+ import { Container, FigRoot, FigRootOptions } from "@bgub/fig-dom";
2
+ import { AnyRouter } from "@tanstack/router-core";
3
+ //#region src/client.d.ts
4
+ interface HydrateStartOptions extends Omit<FigRootOptions, "dataPartition" | "dataStore" | "initialData"> {
5
+ container?: Container;
6
+ }
7
+ interface HydratedStart {
8
+ root: FigRoot;
9
+ router: AnyRouter;
10
+ }
11
+ declare function hydrateStart(options?: HydrateStartOptions): Promise<HydratedStart>;
12
+ //#endregion
13
+ export { HydrateStartOptions, HydratedStart, hydrateStart };
package/dist/client.js ADDED
@@ -0,0 +1,2 @@
1
+ import { t as hydrateStart } from "./client-B2okTbp3.js";
2
+ export { hydrateStart };
package/dist/data.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { FigDataStoreController, FigNode } from "@bgub/fig";
2
+ import { RouteDataContext } from "@bgub/fig-tanstack-router";
3
+ import { createCsrfMiddleware, createMiddleware, createServerFn, createStart } from "@tanstack/start-client-core";
4
+ import { Register } from "@tanstack/router-core";
5
+ //#region src/data.d.ts
6
+ interface StartDataContext extends RouteDataContext {
7
+ data: FigDataStoreController;
8
+ }
9
+ declare function createStartDataContext(): {
10
+ context: StartDataContext;
11
+ };
12
+ declare function StartScripts(): FigNode;
13
+ //#endregion
14
+ export { type Register, StartDataContext, StartScripts, createCsrfMiddleware, createMiddleware, createServerFn, createStart, createStartDataContext };
package/dist/data.js ADDED
@@ -0,0 +1,34 @@
1
+ import { a as payloadTransportMarkerId } from "./payload-internal-CZhfVhwH.js";
2
+ import { t as requireStartDataStore } from "./store-CibAGqiI.js";
3
+ import { i as startDataScriptId, r as serializeStartDataStore, t as createStartDataStore } from "./transport-DKcSG44e.js";
4
+ import { createElement } from "@bgub/fig";
5
+ import { HYDRATION_SKIP_ATTRIBUTE } from "@bgub/fig/internal";
6
+ import { Scripts, useRouter } from "@bgub/fig-tanstack-router";
7
+ import { createCsrfMiddleware, createMiddleware, createServerFn, createStart } from "@tanstack/start-client-core";
8
+ //#region src/data.ts
9
+ function createStartDataContext() {
10
+ return { context: { data: createStartDataStore() } };
11
+ }
12
+ function StartScripts() {
13
+ const router = useRouter();
14
+ const routerScripts = createElement(Scripts);
15
+ if (!router.isServer) return routerScripts;
16
+ const dataStore = requireStartDataStore(router.options.context);
17
+ return [
18
+ createElement("script", {
19
+ [HYDRATION_SKIP_ATTRIBUTE]: true,
20
+ id: startDataScriptId,
21
+ type: "application/json",
22
+ unsafeHTML: serializeStartDataStore(dataStore)
23
+ }),
24
+ createElement("template", {
25
+ id: payloadTransportMarkerId,
26
+ [HYDRATION_SKIP_ATTRIBUTE]: true
27
+ }),
28
+ routerScripts
29
+ ];
30
+ }
31
+ //#endregion
32
+ export { StartScripts, createCsrfMiddleware, createMiddleware, createServerFn, createStart, createStartDataContext };
33
+
34
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","names":["RouterScripts"],"sources":["../src/data.ts"],"sourcesContent":["import {\n createElement,\n type FigDataStoreController,\n type FigNode,\n} from \"@bgub/fig\";\nimport { HYDRATION_SKIP_ATTRIBUTE } from \"@bgub/fig/internal\";\nimport {\n type AnyRouter,\n type RouteDataContext,\n Scripts as RouterScripts,\n useRouter,\n} from \"@bgub/fig-tanstack-router\";\nimport { payloadTransportMarkerId } from \"./document-markers.ts\";\nimport { requireStartDataStore } from \"./store.ts\";\nimport {\n createStartDataStore,\n serializeStartDataStore,\n startDataScriptId,\n} from \"./transport.ts\";\n\nexport {\n createCsrfMiddleware,\n createMiddleware,\n createServerFn,\n createStart,\n} from \"@tanstack/start-client-core\";\nexport type { Register } from \"@tanstack/router-core\";\n\nexport interface StartDataContext extends RouteDataContext {\n data: FigDataStoreController;\n}\n\nexport function createStartDataContext(): { context: StartDataContext } {\n return {\n context: {\n data: createStartDataStore(),\n },\n };\n}\n\nexport function StartScripts(): FigNode {\n const router = useRouter<AnyRouter>();\n const routerScripts = createElement(RouterScripts);\n if (!router.isServer) return routerScripts;\n\n const dataStore = requireStartDataStore(router.options.context);\n return [\n createElement(\"script\", {\n [HYDRATION_SKIP_ATTRIBUTE]: true,\n id: startDataScriptId,\n type: \"application/json\",\n unsafeHTML: serializeStartDataStore(dataStore),\n }),\n createElement(\"template\", {\n id: payloadTransportMarkerId,\n [HYDRATION_SKIP_ATTRIBUTE]: true,\n }),\n routerScripts,\n ];\n}\n"],"mappings":";;;;;;;;AAgCA,SAAgB,yBAAwD;CACtE,OAAO,EACL,SAAS,EACP,MAAM,qBAAqB,EAC7B,EACF;AACF;AAEA,SAAgB,eAAwB;CACtC,MAAM,SAAS,UAAqB;CACpC,MAAM,gBAAgB,cAAcA,OAAa;CACjD,IAAI,CAAC,OAAO,UAAU,OAAO;CAE7B,MAAM,YAAY,sBAAsB,OAAO,QAAQ,OAAO;CAC9D,OAAO;EACL,cAAc,UAAU;IACrB,2BAA2B;GAC5B,IAAI;GACJ,MAAM;GACN,YAAY,wBAAwB,SAAS;EAC/C,CAAC;EACD,cAAc,YAAY;GACxB,IAAI;IACH,2BAA2B;EAC9B,CAAC;EACD;CACF;AACF"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,7 @@
1
+ import { t as hydrateStart } from "../client-B2okTbp3.js";
2
+ //#region src/default-entry/client.ts
3
+ await hydrateStart();
4
+ //#endregion
5
+ export {};
6
+
7
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":[],"sources":["../../src/default-entry/client.ts"],"sourcesContent":["import { hydrateStart } from \"../client.tsx\";\n\nawait hydrateStart();\n"],"mappings":";;AAEA,MAAM,aAAa"}
@@ -0,0 +1,4 @@
1
+ //#region src/default-entry/server.d.ts
2
+ declare const figTanStackStartDefaultServerEntry = true;
3
+ //#endregion
4
+ export { figTanStackStartDefaultServerEntry };