@valbuild/tanstack 0.124.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 (50) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +380 -0
  3. package/client/dist/valbuild-tanstack-client.cjs.d.ts +2 -0
  4. package/client/dist/valbuild-tanstack-client.cjs.dev.js +288 -0
  5. package/client/dist/valbuild-tanstack-client.cjs.js +7 -0
  6. package/client/dist/valbuild-tanstack-client.cjs.prod.js +288 -0
  7. package/client/dist/valbuild-tanstack-client.esm.js +280 -0
  8. package/client/package.json +4 -0
  9. package/dist/ValOverlayContext-87cb022d.esm.js +284 -0
  10. package/dist/ValOverlayContext-abd6ab9a.cjs.prod.js +292 -0
  11. package/dist/ValOverlayContext-d3bfacb1.cjs.dev.js +292 -0
  12. package/dist/createForOfIteratorHelper-0324e063.cjs.prod.js +157 -0
  13. package/dist/createForOfIteratorHelper-485c2ce1.esm.js +151 -0
  14. package/dist/createForOfIteratorHelper-e75681d7.cjs.dev.js +157 -0
  15. package/dist/declarations/src/ValApp.d.ts +6 -0
  16. package/dist/declarations/src/ValImage.d.ts +24 -0
  17. package/dist/declarations/src/ValModulesClient.d.ts +34 -0
  18. package/dist/declarations/src/ValProvider.d.ts +6 -0
  19. package/dist/declarations/src/ValTypes.d.ts +4 -0
  20. package/dist/declarations/src/client/index.d.ts +1 -0
  21. package/dist/declarations/src/client/initValClient.d.ts +27 -0
  22. package/dist/declarations/src/decodeValPathsOfString.d.ts +2 -0
  23. package/dist/declarations/src/external_exempt_from_val_quickjs.d.ts +41 -0
  24. package/dist/declarations/src/getUnpatchedUnencodedVal.d.ts +3 -0
  25. package/dist/declarations/src/index.d.ts +2 -0
  26. package/dist/declarations/src/initVal.d.ts +74 -0
  27. package/dist/declarations/src/server/index.d.ts +5 -0
  28. package/dist/declarations/src/server/initValContent.d.ts +122 -0
  29. package/dist/declarations/src/server/initValMcp.d.ts +27 -0
  30. package/dist/declarations/src/server/initValServer.d.ts +41 -0
  31. package/dist/declarations/src/server/valDraftMode.d.ts +49 -0
  32. package/dist/declarations/src/version.d.ts +1 -0
  33. package/dist/routeFromVal-6693e037.cjs.prod.js +218 -0
  34. package/dist/routeFromVal-728295a0.esm.js +212 -0
  35. package/dist/routeFromVal-a9147ceb.cjs.dev.js +218 -0
  36. package/dist/valbuild-tanstack.cjs.d.ts +2 -0
  37. package/dist/valbuild-tanstack.cjs.dev.js +2005 -0
  38. package/dist/valbuild-tanstack.cjs.js +7 -0
  39. package/dist/valbuild-tanstack.cjs.prod.js +2005 -0
  40. package/dist/valbuild-tanstack.esm.js +1950 -0
  41. package/dist/version-1a88fd21.cjs.dev.js +229 -0
  42. package/dist/version-5ac70ccf.cjs.prod.js +229 -0
  43. package/dist/version-ac8df696.esm.js +225 -0
  44. package/package.json +84 -0
  45. package/server/dist/valbuild-tanstack-server.cjs.d.ts +2 -0
  46. package/server/dist/valbuild-tanstack-server.cjs.dev.js +1032 -0
  47. package/server/dist/valbuild-tanstack-server.cjs.js +7 -0
  48. package/server/dist/valbuild-tanstack-server.cjs.prod.js +1032 -0
  49. package/server/dist/valbuild-tanstack-server.esm.js +1005 -0
  50. package/server/package.json +4 -0
@@ -0,0 +1,1032 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var createForOfIteratorHelper = require('../../dist/createForOfIteratorHelper-0324e063.cjs.prod.js');
6
+ var core = require('@valbuild/core');
7
+ var server = require('@valbuild/server');
8
+ var version = require('../../dist/version-5ac70ccf.cjs.prod.js');
9
+ var routeFromVal = require('../../dist/routeFromVal-6693e037.cjs.prod.js');
10
+ var stega = require('@valbuild/react/stega');
11
+ var internal = require('@valbuild/shared/internal');
12
+ var mcp = require('@valbuild/mcp');
13
+ require('@valbuild/shared/client');
14
+
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n["default"] = e;
30
+ return Object.freeze(n);
31
+ }
32
+
33
+ /**
34
+ * The cookie that says a request is previewing unpublished content.
35
+ *
36
+ * Next has `draftMode()` for this; TanStack Start has no such notion, so Val
37
+ * brings its own. Deliberately NOT the thing that grants access: every draft
38
+ * read also carries the Val session cookie, which is a signed JWT the server
39
+ * verifies, and a request with this cookie and no session gets published
40
+ * content and a 401 in the log. So this is a mode switch, not a credential —
41
+ * which is why an ordinary cookie is enough.
42
+ */
43
+ var VAL_DRAFT_MODE_COOKIE = "val_draft_mode";
44
+ var ENABLED = "1";
45
+
46
+ /**
47
+ * Reading and writing the draft-mode flag for the current request.
48
+ *
49
+ * Handed to `createValServer` as its callbacks, and exported so an app can ask
50
+ * the same question its loaders ask.
51
+ */
52
+
53
+ /**
54
+ * The draft-mode flag, read from and written to the current request.
55
+ *
56
+ * TanStack's request helpers resolve the current request out of async local
57
+ * storage, so this only works where there IS one: a server route handler, a
58
+ * server function, or an SSR render. Everywhere else — a client navigation, a
59
+ * build-time render — it answers "off", which is the right answer: there is no
60
+ * session to authorize a draft read either.
61
+ *
62
+ * The import is dynamic for the same reason it is in `isValEnabled`: this
63
+ * module is reachable from the package's server entry, and pulling TanStack's
64
+ * server half in eagerly would put it in front of anything that merely
65
+ * type-imports from here.
66
+ */
67
+ function valDraftMode() {
68
+ return {
69
+ isEnabled: function isEnabled() {
70
+ return version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee() {
71
+ var _yield$import, getCookie;
72
+ return version._regenerator().w(function (_context) {
73
+ while (1) switch (_context.p = _context.n) {
74
+ case 0:
75
+ _context.p = 0;
76
+ _context.n = 1;
77
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@tanstack/react-start/server')); });
78
+ case 1:
79
+ _yield$import = _context.v;
80
+ getCookie = _yield$import.getCookie;
81
+ return _context.a(2, getCookie(VAL_DRAFT_MODE_COOKIE) === ENABLED);
82
+ case 2:
83
+ _context.p = 2;
84
+ _context.v;
85
+ return _context.a(2, false);
86
+ }
87
+ }, _callee, null, [[0, 2]]);
88
+ }))();
89
+ },
90
+ enable: function enable() {
91
+ return version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee2() {
92
+ var _yield$import2, setCookie, getRequest;
93
+ return version._regenerator().w(function (_context2) {
94
+ while (1) switch (_context2.n) {
95
+ case 0:
96
+ _context2.n = 1;
97
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@tanstack/react-start/server')); });
98
+ case 1:
99
+ _yield$import2 = _context2.v;
100
+ setCookie = _yield$import2.setCookie;
101
+ getRequest = _yield$import2.getRequest;
102
+ setCookie(VAL_DRAFT_MODE_COOKIE, ENABLED, {
103
+ httpOnly: true,
104
+ sameSite: "lax",
105
+ path: "/",
106
+ // Not `secure` unconditionally: the Studio is used over http on
107
+ // localhost, and a Secure cookie is silently dropped there — which
108
+ // looks exactly like draft mode refusing to turn on.
109
+ secure: isSecureRequest(getRequest)
110
+ });
111
+ case 2:
112
+ return _context2.a(2);
113
+ }
114
+ }, _callee2);
115
+ }))();
116
+ },
117
+ disable: function disable() {
118
+ return version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee3() {
119
+ var _yield$import3, deleteCookie;
120
+ return version._regenerator().w(function (_context3) {
121
+ while (1) switch (_context3.n) {
122
+ case 0:
123
+ _context3.n = 1;
124
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@tanstack/react-start/server')); });
125
+ case 1:
126
+ _yield$import3 = _context3.v;
127
+ deleteCookie = _yield$import3.deleteCookie;
128
+ deleteCookie(VAL_DRAFT_MODE_COOKIE, {
129
+ path: "/"
130
+ });
131
+ case 2:
132
+ return _context3.a(2);
133
+ }
134
+ }, _callee3);
135
+ }))();
136
+ }
137
+ };
138
+ }
139
+ function isSecureRequest(getRequest) {
140
+ try {
141
+ return new URL(getRequest().url).protocol === "https:";
142
+ } catch (_unused2) {
143
+ return false;
144
+ }
145
+ }
146
+
147
+ /**
148
+ * The Val Enable cookie, as seen by the current request.
149
+ *
150
+ * Separate from draft mode: enabling Val is what makes the Studio overlay mount
151
+ * at all, and draft mode is what makes the content it shows be the unpublished
152
+ * one. The Studio turns the first on for the browser and the second on per
153
+ * preview.
154
+ */
155
+ function hasValEnableCookieOnServer() {
156
+ return _hasValEnableCookieOnServer.apply(this, arguments);
157
+ }
158
+ function _hasValEnableCookieOnServer() {
159
+ _hasValEnableCookieOnServer = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee4() {
160
+ var _yield$import4, getCookie;
161
+ return version._regenerator().w(function (_context4) {
162
+ while (1) switch (_context4.p = _context4.n) {
163
+ case 0:
164
+ _context4.p = 0;
165
+ _context4.n = 1;
166
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@tanstack/react-start/server')); });
167
+ case 1:
168
+ _yield$import4 = _context4.v;
169
+ getCookie = _yield$import4.getCookie;
170
+ return _context4.a(2, getCookie(core.Internal.VAL_ENABLE_COOKIE_NAME) === "true");
171
+ case 2:
172
+ _context4.p = 2;
173
+ _context4.v;
174
+ return _context4.a(2, false);
175
+ }
176
+ }, _callee4, null, [[0, 2]]);
177
+ }));
178
+ return _hasValEnableCookieOnServer.apply(this, arguments);
179
+ }
180
+
181
+ /**
182
+ * The Val API, as a handler you can mount on a TanStack Start server route.
183
+ *
184
+ * `createValApiRouter` already speaks the platform's own vocabulary — it takes
185
+ * a `Request` and hands back a `ValServerGenericResult` — so all this adds is
186
+ * the conversion to a `Response`, which for Next needed `NextResponse` and here
187
+ * does not need anything.
188
+ */
189
+ var initValApiHandler = function initValApiHandler(valModules, config, draftMode, formatter) {
190
+ var route = "/api/val"; // TODO: get from config
191
+ var coreVersion = core.Internal.VERSION.core;
192
+ if (!coreVersion) {
193
+ throw new Error("Could not get @valbuild/core package version");
194
+ }
195
+ var tanstackVersion = version.VERSION;
196
+ if (!tanstackVersion) {
197
+ throw new Error("Could not get @valbuild/tanstack package version");
198
+ }
199
+ return server.createValApiRouter(route, server.createValServer(valModules, route, createForOfIteratorHelper._objectSpread2({
200
+ versions: {
201
+ /*
202
+ * Reported as `next` because that is the field the wire contract has.
203
+ *
204
+ * `Versions` in `@valbuild/server` names the framework half of the
205
+ * pair `next`, and admin.val.build reads it. Renaming it is a change
206
+ * to a published contract with a server on the other end, so the
207
+ * TanStack package fills the same field rather than adding one
208
+ * nothing reads.
209
+ */
210
+ next: tanstackVersion,
211
+ core: coreVersion
212
+ }
213
+ }, config), config, {
214
+ isEnabled: function isEnabled() {
215
+ return draftMode.isEnabled();
216
+ },
217
+ onEnable: function onEnable() {
218
+ return draftMode.enable();
219
+ },
220
+ onDisable: function onDisable() {
221
+ return draftMode.disable();
222
+ }
223
+ }, formatter), function (valRes) {
224
+ var headers = new Headers();
225
+ var valResHeaders = "headers" in valRes && valRes.headers || {};
226
+ for (var key in valResHeaders) {
227
+ var value = valResHeaders[key];
228
+ if (typeof value === "string") {
229
+ headers.set(key, value);
230
+ }
231
+ }
232
+ if ("cookies" in valRes && valRes.cookies) {
233
+ for (var _i = 0, _Object$entries = Object.entries(valRes.cookies); _i < _Object$entries.length; _i++) {
234
+ var _Object$entries$_i = createForOfIteratorHelper._slicedToArray(_Object$entries[_i], 2),
235
+ cookieName = _Object$entries$_i[0],
236
+ cookie = _Object$entries$_i[1];
237
+ headers.append("Set-Cookie", serializeCookie(cookieName, cookie));
238
+ }
239
+ }
240
+ if ("json" in valRes) {
241
+ headers.set("Content-Type", "application/json");
242
+ return new Response(JSON.stringify(valRes.json), {
243
+ headers: headers,
244
+ status: valRes.status
245
+ });
246
+ }
247
+ if (valRes.status === 302) {
248
+ headers.set("Location", valRes.redirectTo);
249
+ /*
250
+ * Built by hand rather than with `Response.redirect`.
251
+ *
252
+ * `Response.redirect` produces an immutable response whose headers
253
+ * cannot be added to, and the redirect that enables Val is precisely
254
+ * the one that has to set cookies on its way out.
255
+ */
256
+ return new Response(null, {
257
+ status: valRes.status,
258
+ headers: headers
259
+ });
260
+ }
261
+ return new Response("body" in valRes ? valRes.body : null, {
262
+ headers: headers,
263
+ status: valRes.status
264
+ });
265
+ });
266
+ };
267
+
268
+ /**
269
+ * One `Set-Cookie` header value.
270
+ *
271
+ * `value` is nullable because clearing a cookie is expressed as a null value
272
+ * rather than a separate op — which is also why a falsy value gets `Max-Age=0`
273
+ * below when no explicit expiry was given.
274
+ */
275
+
276
+ function serializeCookie(name, cookie) {
277
+ var _options$path;
278
+ var options = cookie.options;
279
+ /*
280
+ * `Path=/` unless told otherwise — the default is not "the whole site".
281
+ *
282
+ * A `Set-Cookie` with no `Path` defaults to the DIRECTORY of the request
283
+ * that set it, and every cookie Val sets is set by a response from
284
+ * `/api/val/...`. So `val_enable` — which the page reads from
285
+ * `document.cookie` to decide whether to mount the Studio overlay — was
286
+ * scoped to `/api/val` and invisible on the site itself: enabling Val
287
+ * appeared to do nothing at all. Next's `NextResponse` normalises this for
288
+ * the Next package; a plain `Response` does not.
289
+ */
290
+ var path = (_options$path = options === null || options === void 0 ? void 0 : options.path) !== null && _options$path !== void 0 ? _options$path : "/";
291
+ return "".concat(name, "=").concat(encodeURIComponent(cookie.value || "")) + "".concat(options !== null && options !== void 0 && options.httpOnly ? "; HttpOnly" : "") + "".concat(options !== null && options !== void 0 && options.secure ? "; Secure" : "") + "".concat(options !== null && options !== void 0 && options.sameSite ? "; SameSite=".concat(options.sameSite) : "") + "; Path=".concat(path) + "".concat(options !== null && options !== void 0 && options.expires ? "; Expires=".concat(options.expires.toISOString()) : "".concat(!cookie.value ? "; Max-Age=0" : ""));
292
+ }
293
+ function initValServer(valModules, config, opts) {
294
+ var _opts$draftMode;
295
+ var draftMode = (_opts$draftMode = opts === null || opts === void 0 ? void 0 : opts.draftMode) !== null && _opts$draftMode !== void 0 ? _opts$draftMode : valDraftMode();
296
+ return {
297
+ valApiHandler: initValApiHandler(valModules, config, draftMode, opts === null || opts === void 0 ? void 0 : opts.formatter),
298
+ draftMode: draftMode
299
+ };
300
+ }
301
+
302
+ /*
303
+ * NOTE: no `SET_RSC(true)` here, unlike the Next package.
304
+ *
305
+ * That flag marks elements as having been rendered by a React Server Component
306
+ * — a tree the browser cannot re-render, only re-request. A TanStack Start page
307
+ * is server-RENDERED and then hydrated, so every element it produces is a
308
+ * normal client element and the distinction does not exist.
309
+ */
310
+ var initFetchValStega = function initFetchValStega(config, valApiEndpoints, valServerPromise, isEnabled, getHeaders, getCookies) {
311
+ return function (selector) {
312
+ var exec = /*#__PURE__*/function () {
313
+ var _ref = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee() {
314
+ var enabled, headers, cookies, host, _cookies, valServer, treeRes, modules, _t, _t2, _t3;
315
+ return version._regenerator().w(function (_context) {
316
+ while (1) switch (_context.p = _context.n) {
317
+ case 0:
318
+ enabled = false;
319
+ _context.p = 1;
320
+ _context.n = 2;
321
+ return isEnabled();
322
+ case 2:
323
+ enabled = _context.v;
324
+ _context.n = 4;
325
+ break;
326
+ case 3:
327
+ _context.p = 3;
328
+ _t = _context.v;
329
+ console.error("Val: could not check if Val is enabled! This might be due to an error reading draft mode. fetchVal can only be used server-side (in a loader, a server function, or a server route). Use useVal in components.", _t);
330
+ case 4:
331
+ if (!enabled) {
332
+ _context.n = 17;
333
+ break;
334
+ }
335
+ stega.SET_AUTO_TAG_JSX_ENABLED(true);
336
+ _context.p = 5;
337
+ _context.n = 6;
338
+ return getHeaders();
339
+ case 6:
340
+ headers = _context.v;
341
+ if (!(typeof headers.get !== "function")) {
342
+ _context.n = 7;
343
+ break;
344
+ }
345
+ throw new Error("Invalid headers");
346
+ case 7:
347
+ _context.n = 9;
348
+ break;
349
+ case 8:
350
+ _context.p = 8;
351
+ _t2 = _context.v;
352
+ console.error("Val: could not read headers! fetchVal can only be used server-side (in a loader, a server function, or a server route). Use useVal in components.", _t2);
353
+ headers = null;
354
+ case 9:
355
+ _context.p = 9;
356
+ _context.n = 10;
357
+ return getCookies();
358
+ case 10:
359
+ cookies = _context.v;
360
+ _context.n = 12;
361
+ break;
362
+ case 11:
363
+ _context.p = 11;
364
+ _t3 = _context.v;
365
+ console.error("Val: could not read cookies! fetchVal can only be used server-side (in a loader, a server function, or a server route). Use useVal in components.", _t3);
366
+ cookies = null;
367
+ case 12:
368
+ host = headers && getHost(headers);
369
+ if (!(host && cookies)) {
370
+ _context.n = 17;
371
+ break;
372
+ }
373
+ _context.n = 13;
374
+ return valServerPromise;
375
+ case 13:
376
+ valServer = _context.v;
377
+ _context.n = 14;
378
+ return valServer["/sources/~"]["PUT"]({
379
+ path: "/",
380
+ query: {
381
+ validate_sources: true,
382
+ validate_binary_files: false,
383
+ exclude_patches: false,
384
+ // The server-side read uses the legacy "server applies patches"
385
+ // path, same as the Next package's.
386
+ apply_patches: undefined,
387
+ /*
388
+ * The caller's own staged work, and nobody else's.
389
+ *
390
+ * A draft render cannot name its group ids — it has no client
391
+ * state — so it asks for "mine" and the server resolves them from
392
+ * the session. Without this a preview shows base + every pending
393
+ * patch on the branch, so one person's half-finished edit appears
394
+ * in another person's draft.
395
+ *
396
+ * `patch_id` stays `undefined`: naming an explicit list is for a
397
+ * caller that already knows what it wants, and it would override
398
+ * the resolution rather than intersect with it.
399
+ */
400
+ patch_id: undefined,
401
+ own_patch_groups_only: true
402
+ },
403
+ cookies: createForOfIteratorHelper._defineProperty({}, internal.VAL_SESSION_COOKIE, (_cookies = cookies) === null || _cookies === void 0 || (_cookies = _cookies.get(internal.VAL_SESSION_COOKIE)) === null || _cookies === void 0 ? void 0 : _cookies.value)
404
+ });
405
+ case 14:
406
+ treeRes = _context.v;
407
+ if (!(treeRes.status === 200)) {
408
+ _context.n = 15;
409
+ break;
410
+ }
411
+ modules = treeRes.json.modules;
412
+ return _context.a(2, stega.stegaEncode(selector, {
413
+ disabled: !enabled,
414
+ getModule: function getModule(path) {
415
+ var module = modules[path];
416
+ if (module) {
417
+ return module.source;
418
+ }
419
+ }
420
+ }));
421
+ case 15:
422
+ if (!(treeRes.status === 401)) {
423
+ _context.n = 16;
424
+ break;
425
+ }
426
+ console.warn("Val: authentication error: ", treeRes.json.message);
427
+ _context.n = 17;
428
+ break;
429
+ case 16:
430
+ throw Error(JSON.stringify(treeRes.json, null, 2));
431
+ case 17:
432
+ return _context.a(2, stega.stegaEncode(selector, {
433
+ disabled: !enabled
434
+ }));
435
+ }
436
+ }, _callee, null, [[9, 11], [5, 8], [1, 3]]);
437
+ }));
438
+ return function exec() {
439
+ return _ref.apply(this, arguments);
440
+ };
441
+ }();
442
+ return exec()["catch"](function (err) {
443
+ console.error("Val: failed to fetch ", err);
444
+ return stega.stegaEncode(selector, {});
445
+ });
446
+ };
447
+ };
448
+ function getHost(headers) {
449
+ var _headers$get;
450
+ var host = headers === null || headers === void 0 ? void 0 : headers.get("host");
451
+ var proto = "https";
452
+ if ((headers === null || headers === void 0 ? void 0 : headers.get("x-forwarded-proto")) === "http") {
453
+ proto = "http";
454
+ } else if (headers !== null && headers !== void 0 && (_headers$get = headers.get("referer")) !== null && _headers$get !== void 0 && _headers$get.startsWith("http://")) {
455
+ proto = "http";
456
+ } else if (host !== null && host !== void 0 && host.startsWith("localhost")) {
457
+ proto = "http";
458
+ }
459
+ if (host && proto) {
460
+ return "".concat(proto, "://").concat(host);
461
+ }
462
+ return null;
463
+ }
464
+
465
+ // TODO: remove
466
+ // function getValAuthHeaders(cookies: {
467
+ // get(name: string): { name: string; value: string } | undefined;
468
+ // }): Record<string, string> {
469
+ // try {
470
+ // const session = cookies.get(Internal.VAL_SESSION_COOKIE);
471
+ // if (session) {
472
+ // return {
473
+ // Cookie: `${Internal.VAL_SESSION_COOKIE}=${encodeURIComponent(
474
+ // session.value
475
+ // )}`,
476
+ // };
477
+ // }
478
+ // return {};
479
+ // } catch (err) {
480
+ // console.error(
481
+ // "Val: could not read cookies! fetchVal can only be used server-side (in a loader, a server function, or a server route). Use useVal in components.",
482
+ // err
483
+ // );
484
+ // return {};
485
+ // }
486
+ // }
487
+
488
+ var initFetchValRouteStega = function initFetchValRouteStega(config, valApiEndpoints, valServerPromise, isEnabled, getHeaders, getCookies) {
489
+ return /*#__PURE__*/function () {
490
+ var _ref2 = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee2(selector, params) {
491
+ var resolvedParams, path, schema, source, url, enabled, draft, content, fetchVal, val, route, _t5;
492
+ return version._regenerator().w(function (_context2) {
493
+ while (1) switch (_context2.p = _context2.n) {
494
+ case 0:
495
+ _context2.n = 1;
496
+ return Promise.resolve(params);
497
+ case 1:
498
+ resolvedParams = _context2.v;
499
+ path = selector && core.Internal.getValPath(selector);
500
+ schema = selector && core.Internal.getSchema(selector); // `.jsonValues()` router: map params → the entry key and load ONLY that
501
+ // entry's backing `*.val.json`, instead of eagerly resolving the whole
502
+ // record via `fetchVal`.
503
+ if (!routeFromVal.isJsonValuesRecordSchema(schema)) {
504
+ _context2.n = 11;
505
+ break;
506
+ }
507
+ source = selector && core.Internal.getSource(selector);
508
+ url = routeFromVal.getValRouteUrlFromVal(resolvedParams, "fetchValRoute", path, schema, source);
509
+ if (url) {
510
+ _context2.n = 2;
511
+ break;
512
+ }
513
+ return _context2.a(2, null);
514
+ case 2:
515
+ enabled = false;
516
+ _context2.p = 3;
517
+ _context2.n = 4;
518
+ return isEnabled();
519
+ case 4:
520
+ enabled = _context2.v;
521
+ _context2.n = 6;
522
+ break;
523
+ case 5:
524
+ _context2.p = 5;
525
+ _context2.v;
526
+ case 6:
527
+ draft = {
528
+ status: "unavailable"
529
+ };
530
+ if (!(enabled && path)) {
531
+ _context2.n = 8;
532
+ break;
533
+ }
534
+ stega.SET_AUTO_TAG_JSX_ENABLED(true);
535
+ _context2.n = 7;
536
+ return loadDraftJsonEntry(valServerPromise, getCookies, path, url);
537
+ case 7:
538
+ draft = _context2.v;
539
+ case 8:
540
+ _context2.n = 9;
541
+ return resolveDraftOrCommittedEntry(draft, function () {
542
+ return loadJsonEntryContent(source, url);
543
+ });
544
+ case 9:
545
+ content = _context2.v;
546
+ if (!(content === undefined)) {
547
+ _context2.n = 10;
548
+ break;
549
+ }
550
+ return _context2.a(2, null);
551
+ case 10:
552
+ return _context2.a(2, stega.stegaEncode(content, {
553
+ disabled: !enabled,
554
+ root: routeFromVal.getJsonEntryStegaRoot(selector, url)
555
+ }));
556
+ case 11:
557
+ fetchVal = initFetchValStega(config, valApiEndpoints, valServerPromise, isEnabled, getHeaders, getCookies);
558
+ _t5 = selector;
559
+ if (!_t5) {
560
+ _context2.n = 13;
561
+ break;
562
+ }
563
+ _context2.n = 12;
564
+ return fetchVal(selector);
565
+ case 12:
566
+ _t5 = _context2.v;
567
+ case 13:
568
+ val = _t5;
569
+ route = routeFromVal.initValRouteFromVal(resolvedParams, "fetchValRoute", path, schema, val);
570
+ return _context2.a(2, route);
571
+ }
572
+ }, _callee2, null, [[3, 5]]);
573
+ }));
574
+ return function (_x, _x2) {
575
+ return _ref2.apply(this, arguments);
576
+ };
577
+ }();
578
+ };
579
+
580
+ /**
581
+ * Resolves a single `.jsonValues()` entry's content by key from a module's local
582
+ * source markers (one dynamic import). Returns `undefined` when the key is
583
+ * missing or its marker has no runtime thunk (transport marker / draft entry).
584
+ */
585
+ function loadJsonEntryContent(_x3, _x4) {
586
+ return _loadJsonEntryContent.apply(this, arguments);
587
+ }
588
+ /**
589
+ * Loads a single `.jsonValues()` entry's DRAFT content via the in-process
590
+ * `/json` endpoint (which replays pending patches). Returns `undefined` when the
591
+ * entry has no draft content to serve — the caller then falls back to the
592
+ * locally-bundled committed content.
593
+ */
594
+ /**
595
+ * What the draft state says about an entry.
596
+ *
597
+ * The three cases have to stay distinct: `absent` is an ANSWER — the entry is not
598
+ * there in the draft state, e.g. a pending patch removed it — while `unavailable`
599
+ * means we could not ask. Collapsing them into `undefined` is what made a
600
+ * draft-deleted entry keep rendering its committed content: the caller could not
601
+ * tell "it is gone" from "ask the committed source instead".
602
+ */
603
+ /**
604
+ * The slice of `ValServer` the single-entry readers actually use. Narrower than
605
+ * `ValServer` on purpose: it says what the dependency IS, and it lets a test
606
+ * drive these readers with a one-route fake instead of casting a partial object
607
+ * to the whole server type.
608
+ */
609
+ function _loadJsonEntryContent() {
610
+ _loadJsonEntryContent = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee5(source, key) {
611
+ var marker, thunk;
612
+ return version._regenerator().w(function (_context5) {
613
+ while (1) switch (_context5.n) {
614
+ case 0:
615
+ if (!(!source || routeFromVal._typeof(source) !== "object")) {
616
+ _context5.n = 1;
617
+ break;
618
+ }
619
+ return _context5.a(2, undefined);
620
+ case 1:
621
+ marker = source[key];
622
+ if (core.Internal.isJson(marker)) {
623
+ _context5.n = 2;
624
+ break;
625
+ }
626
+ return _context5.a(2, undefined);
627
+ case 2:
628
+ thunk = core.Internal.getJsonImport(marker);
629
+ if (thunk) {
630
+ _context5.n = 3;
631
+ break;
632
+ }
633
+ return _context5.a(2, undefined);
634
+ case 3:
635
+ _context5.n = 4;
636
+ return thunk();
637
+ case 4:
638
+ return _context5.a(2, _context5.v["default"]);
639
+ }
640
+ }, _callee5);
641
+ }));
642
+ return _loadJsonEntryContent.apply(this, arguments);
643
+ }
644
+ /**
645
+ * Picks the content a draft-aware single-entry read should render.
646
+ *
647
+ * The rule the two callers share: the draft state WINS when it has an answer —
648
+ * including the answer "this entry is gone" — and the committed content is used
649
+ * only when there is no draft answer to be had (Val disabled, or we could not
650
+ * ask). Returning `undefined` means "render nothing"; both callers turn that into
651
+ * a null/undefined result.
652
+ */
653
+ function resolveDraftOrCommittedEntry(_x5, _x6) {
654
+ return _resolveDraftOrCommittedEntry.apply(this, arguments);
655
+ }
656
+ function _resolveDraftOrCommittedEntry() {
657
+ _resolveDraftOrCommittedEntry = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee6(draft, loadCommitted) {
658
+ return version._regenerator().w(function (_context6) {
659
+ while (1) switch (_context6.n) {
660
+ case 0:
661
+ if (!(draft.status === "content")) {
662
+ _context6.n = 1;
663
+ break;
664
+ }
665
+ return _context6.a(2, draft.content);
666
+ case 1:
667
+ if (!(draft.status === "absent")) {
668
+ _context6.n = 2;
669
+ break;
670
+ }
671
+ return _context6.a(2, undefined);
672
+ case 2:
673
+ return _context6.a(2, loadCommitted());
674
+ }
675
+ }, _callee6);
676
+ }));
677
+ return _resolveDraftOrCommittedEntry.apply(this, arguments);
678
+ }
679
+ function loadDraftJsonEntry(_x7, _x8, _x9, _x0) {
680
+ return _loadDraftJsonEntry.apply(this, arguments);
681
+ } // The (loosened) content type a single `.jsonValues()` entry resolves to.
682
+ function _loadDraftJsonEntry() {
683
+ _loadDraftJsonEntry = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee7(valServerPromise, getCookies, moduleFilePath, key) {
684
+ var _cookies3;
685
+ var cookies, valServer, res;
686
+ return version._regenerator().w(function (_context7) {
687
+ while (1) switch (_context7.p = _context7.n) {
688
+ case 0:
689
+ _context7.p = 0;
690
+ _context7.n = 1;
691
+ return getCookies();
692
+ case 1:
693
+ cookies = _context7.v;
694
+ _context7.n = 3;
695
+ break;
696
+ case 2:
697
+ _context7.p = 2;
698
+ _context7.v;
699
+ return _context7.a(2, {
700
+ status: "unavailable"
701
+ });
702
+ case 3:
703
+ _context7.n = 4;
704
+ return valServerPromise;
705
+ case 4:
706
+ valServer = _context7.v;
707
+ _context7.n = 5;
708
+ return valServer["/json"]["GET"]({
709
+ query: {
710
+ path: moduleFilePath,
711
+ key: key,
712
+ keys: undefined,
713
+ // single-entry shape
714
+ offset: undefined,
715
+ limit: undefined,
716
+ apply_patches: true,
717
+ /*
718
+ * Scoped the same way the module content beside it is.
719
+ *
720
+ * A draft page renders both, and this call was unscoped — so one page
721
+ * showed base + the caller's group for its modules and base + EVERY
722
+ * pending patch on the branch for any `jsonValues` entry, including other
723
+ * authors' half-finished edits. See the same flag on `/sources/~` above.
724
+ */
725
+ own_patch_groups_only: true
726
+ },
727
+ cookies: createForOfIteratorHelper._defineProperty({}, internal.VAL_SESSION_COOKIE, (_cookies3 = cookies) === null || _cookies3 === void 0 || (_cookies3 = _cookies3.get(internal.VAL_SESSION_COOKIE)) === null || _cookies3 === void 0 ? void 0 : _cookies3.value)
728
+ });
729
+ case 5:
730
+ res = _context7.v;
731
+ if (!(res.status === 200 && "content" in res.json)) {
732
+ _context7.n = 6;
733
+ break;
734
+ }
735
+ return _context7.a(2, {
736
+ status: "content",
737
+ content: res.json.content
738
+ });
739
+ case 6:
740
+ if (!(res.status === 401)) {
741
+ _context7.n = 7;
742
+ break;
743
+ }
744
+ console.warn("Val: authentication error: ", res.json.message);
745
+ return _context7.a(2, {
746
+ status: "unavailable"
747
+ });
748
+ case 7:
749
+ if (!(res.status === 404)) {
750
+ _context7.n = 8;
751
+ break;
752
+ }
753
+ return _context7.a(2, {
754
+ status: "absent"
755
+ });
756
+ case 8:
757
+ console.error("Val: could not load draft JSON entry: ", "message" in res.json ? res.json.message : "status ".concat(res.status));
758
+ return _context7.a(2, {
759
+ status: "unavailable"
760
+ });
761
+ }
762
+ }, _callee7, null, [[0, 2]]);
763
+ }));
764
+ return _loadDraftJsonEntry.apply(this, arguments);
765
+ }
766
+ /**
767
+ * Resolves ONE `.jsonValues()` entry by key, loading only that entry instead of
768
+ * the whole record — the runtime-scaling counterpart to the eager `fetchVal`.
769
+ *
770
+ * Production (Val disabled): resolves the entry's lazy import thunk from the
771
+ * locally-bundled module. One dynamic import, no server round-trip.
772
+ *
773
+ * Enabled (draft mode): reads the entry through `/json`, which replays pending
774
+ * patches, so uncommitted Studio edits show up. Falls back to the local thunk if
775
+ * the draft read yields nothing.
776
+ */
777
+ var initFetchValKeyStega = function initFetchValKeyStega(valServerPromise, isEnabled, getCookies) {
778
+ return /*#__PURE__*/function () {
779
+ var _ref3 = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee3(selector, key) {
780
+ var enabled, source, moduleFilePath, draft, content;
781
+ return version._regenerator().w(function (_context3) {
782
+ while (1) switch (_context3.p = _context3.n) {
783
+ case 0:
784
+ enabled = false;
785
+ _context3.p = 1;
786
+ _context3.n = 2;
787
+ return isEnabled();
788
+ case 2:
789
+ enabled = _context3.v;
790
+ _context3.n = 4;
791
+ break;
792
+ case 3:
793
+ _context3.p = 3;
794
+ _context3.v;
795
+ case 4:
796
+ source = selector && core.Internal.getSource(selector);
797
+ moduleFilePath = selector && core.Internal.getValPath(selector);
798
+ draft = {
799
+ status: "unavailable"
800
+ };
801
+ if (!(enabled && moduleFilePath)) {
802
+ _context3.n = 6;
803
+ break;
804
+ }
805
+ stega.SET_AUTO_TAG_JSX_ENABLED(true);
806
+ _context3.n = 5;
807
+ return loadDraftJsonEntry(valServerPromise, getCookies, moduleFilePath, key);
808
+ case 5:
809
+ draft = _context3.v;
810
+ case 6:
811
+ _context3.n = 7;
812
+ return resolveDraftOrCommittedEntry(draft, function () {
813
+ return loadJsonEntryContent(source, key);
814
+ });
815
+ case 7:
816
+ content = _context3.v;
817
+ if (!(content === undefined)) {
818
+ _context3.n = 8;
819
+ break;
820
+ }
821
+ return _context3.a(2, undefined);
822
+ case 8:
823
+ return _context3.a(2, stega.stegaEncode(content, {
824
+ disabled: !enabled,
825
+ root: routeFromVal.getJsonEntryStegaRoot(selector, key)
826
+ }));
827
+ }
828
+ }, _callee3, null, [[1, 3]]);
829
+ }));
830
+ return function (_x1, _x10) {
831
+ return _ref3.apply(this, arguments);
832
+ };
833
+ }();
834
+ };
835
+ var initFetchValRouteUrl = function initFetchValRouteUrl(config, valApiEndpoints, valServerPromise, isEnabled, getHeaders, getCookies) {
836
+ return /*#__PURE__*/function () {
837
+ var _ref4 = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee4(selector, params) {
838
+ var fetchVal, resolvedParams, path, schema, val, route, _t7, _t8;
839
+ return version._regenerator().w(function (_context4) {
840
+ while (1) switch (_context4.n) {
841
+ case 0:
842
+ fetchVal = initFetchValStega(config, valApiEndpoints, valServerPromise, isEnabled, getHeaders, getCookies);
843
+ if (!(params === undefined)) {
844
+ _context4.n = 1;
845
+ break;
846
+ }
847
+ _t7 = undefined;
848
+ _context4.n = 3;
849
+ break;
850
+ case 1:
851
+ _context4.n = 2;
852
+ return Promise.resolve(params);
853
+ case 2:
854
+ _t7 = _context4.v;
855
+ case 3:
856
+ resolvedParams = _t7;
857
+ path = selector && core.Internal.getValPath(selector);
858
+ schema = selector && core.Internal.getSchema(selector);
859
+ _t8 = selector;
860
+ if (!_t8) {
861
+ _context4.n = 5;
862
+ break;
863
+ }
864
+ _context4.n = 4;
865
+ return fetchVal(selector);
866
+ case 4:
867
+ _t8 = _context4.v;
868
+ case 5:
869
+ val = _t8;
870
+ route = routeFromVal.getValRouteUrlFromVal(resolvedParams, "fetchValRouteUrl", path, schema, val);
871
+ return _context4.a(2, route);
872
+ }
873
+ }, _callee4);
874
+ }));
875
+ return function (_x11, _x12) {
876
+ return _ref4.apply(this, arguments);
877
+ };
878
+ }();
879
+ };
880
+ var valApiEndpoints = "/api/val";
881
+
882
+ /**
883
+ * The request's headers, as the readers above want them.
884
+ *
885
+ * TanStack resolves the current request out of async local storage, so there
886
+ * is nothing to pass in — and nothing to read outside a request, which is what
887
+ * the throw is: the callers catch it and fall back to published content.
888
+ */
889
+ function requestHeaders() {
890
+ return _requestHeaders.apply(this, arguments);
891
+ }
892
+ /** The request's cookies, in the `{ name, value }` shape the readers want. */
893
+ function _requestHeaders() {
894
+ _requestHeaders = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee8() {
895
+ var _yield$import, getRequestHeaders, headers;
896
+ return version._regenerator().w(function (_context8) {
897
+ while (1) switch (_context8.n) {
898
+ case 0:
899
+ _context8.n = 1;
900
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@tanstack/react-start/server')); });
901
+ case 1:
902
+ _yield$import = _context8.v;
903
+ getRequestHeaders = _yield$import.getRequestHeaders;
904
+ headers = getRequestHeaders();
905
+ return _context8.a(2, {
906
+ get: function get(name) {
907
+ var _headers$get2;
908
+ return (_headers$get2 = headers.get(name)) !== null && _headers$get2 !== void 0 ? _headers$get2 : null;
909
+ }
910
+ });
911
+ }
912
+ }, _callee8);
913
+ }));
914
+ return _requestHeaders.apply(this, arguments);
915
+ }
916
+ function requestCookies() {
917
+ return _requestCookies.apply(this, arguments);
918
+ }
919
+ /**
920
+ * Val's content readers for the server side of a TanStack Start app.
921
+ *
922
+ * Use them where the server runs: a route `loader` during SSR, a
923
+ * `createServerFn`, or a server route handler. In the browser — a client
924
+ * navigation re-running a loader, say — there is no request to read draft
925
+ * state from, so they resolve the published content, which is the same answer
926
+ * the visitor would get.
927
+ *
928
+ * @example
929
+ * // src/val/server.ts
930
+ * import { initValContent } from "@valbuild/tanstack/server";
931
+ * import { config } from "../val.config";
932
+ * import valModules from "../val.modules";
933
+ *
934
+ * export const {
935
+ * fetchValStega: fetchVal,
936
+ * fetchValRouteStega: fetchValRoute,
937
+ * } = initValContent(config, valModules);
938
+ */
939
+ function _requestCookies() {
940
+ _requestCookies = version._asyncToGenerator(/*#__PURE__*/version._regenerator().m(function _callee9() {
941
+ var _yield$import2, getCookie;
942
+ return version._regenerator().w(function (_context9) {
943
+ while (1) switch (_context9.n) {
944
+ case 0:
945
+ _context9.n = 1;
946
+ return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@tanstack/react-start/server')); });
947
+ case 1:
948
+ _yield$import2 = _context9.v;
949
+ getCookie = _yield$import2.getCookie;
950
+ return _context9.a(2, {
951
+ get: function get(name) {
952
+ var value = getCookie(name);
953
+ return value === undefined ? undefined : {
954
+ name: name,
955
+ value: value
956
+ };
957
+ }
958
+ });
959
+ }
960
+ }, _callee9);
961
+ }));
962
+ return _requestCookies.apply(this, arguments);
963
+ }
964
+ function initValContent(config, valModules, opts) {
965
+ var _opts$draftMode;
966
+ var coreVersion = core.Internal.VERSION.core;
967
+ if (!coreVersion) {
968
+ throw new Error("Could not get @valbuild/core package version");
969
+ }
970
+ var tanstackVersion = version.VERSION;
971
+ if (!tanstackVersion) {
972
+ throw new Error("Could not get @valbuild/tanstack package version");
973
+ }
974
+ var draftMode = (_opts$draftMode = opts === null || opts === void 0 ? void 0 : opts.draftMode) !== null && _opts$draftMode !== void 0 ? _opts$draftMode : valDraftMode();
975
+ var isEnabled = function isEnabled() {
976
+ return draftMode.isEnabled();
977
+ };
978
+ var valServerPromise = server.createValServer(valModules, valApiEndpoints, createForOfIteratorHelper._objectSpread2({
979
+ versions: {
980
+ // `next` is the field name in the wire contract; see initValServer.
981
+ next: tanstackVersion,
982
+ core: coreVersion
983
+ }
984
+ }, config), config, {
985
+ isEnabled: isEnabled,
986
+ onEnable: function onEnable() {
987
+ return draftMode.enable();
988
+ },
989
+ onDisable: function onDisable() {
990
+ return draftMode.disable();
991
+ }
992
+ });
993
+ return {
994
+ fetchValStega: initFetchValStega(config, valApiEndpoints,
995
+ // TODO: get from config
996
+ valServerPromise, isEnabled, requestHeaders, requestCookies),
997
+ fetchValKeyStega: initFetchValKeyStega(valServerPromise, isEnabled, requestCookies),
998
+ fetchValRouteStega: initFetchValRouteStega(config, valApiEndpoints, valServerPromise, isEnabled, requestHeaders, requestCookies),
999
+ fetchValRouteUrl: initFetchValRouteUrl(config, valApiEndpoints, valServerPromise, isEnabled, requestHeaders, requestCookies)
1000
+ };
1001
+ }
1002
+
1003
+ /**
1004
+ * Val's tools over MCP, bound to this package.
1005
+ *
1006
+ * The MCP endpoint itself — the tools, the request guards, the access-token
1007
+ * verification — lives in `@valbuild/mcp`, which knows nothing about any
1008
+ * framework. All that is left here is the one thing this package can answer and
1009
+ * that one cannot: which version of `@valbuild/tanstack` is running, which
1010
+ * `initHandlerOptions` insists on before it will build a proxy-mode config.
1011
+ *
1012
+ * The version goes in the `next` field because that is the field name in the
1013
+ * wire contract; see `initValServer`.
1014
+ */
1015
+ function initValMcp(valModules, config, opts) {
1016
+ var tanstackVersion = version.VERSION;
1017
+ if (!tanstackVersion) {
1018
+ throw new Error("Could not get @valbuild/tanstack package version");
1019
+ }
1020
+ return mcp.initValMcp(valModules, config, createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({}, opts), {}, {
1021
+ versions: {
1022
+ next: tanstackVersion
1023
+ }
1024
+ }));
1025
+ }
1026
+
1027
+ exports.VAL_DRAFT_MODE_COOKIE = VAL_DRAFT_MODE_COOKIE;
1028
+ exports.hasValEnableCookieOnServer = hasValEnableCookieOnServer;
1029
+ exports.initValContent = initValContent;
1030
+ exports.initValMcp = initValMcp;
1031
+ exports.initValServer = initValServer;
1032
+ exports.valDraftMode = valDraftMode;