@valbuild/tanstack 0.140.2 → 0.141.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,79 @@
1
1
  # @valbuild/tanstack
2
2
 
3
+ ## 0.141.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`6faacda`](https://github.com/valbuild/val/commit/6faacda398fc92bec187b7afe07a53228a6f2a3b), [`14b18d7`](https://github.com/valbuild/val/commit/14b18d7cb145cec1bc1cd832b9ca857ff4b45adc)]:
8
+ - @valbuild/ui@0.141.1
9
+ - @valbuild/server@0.141.1
10
+ - @valbuild/react@0.141.1
11
+ - @valbuild/language-server@0.141.1
12
+ - @valbuild/mcp@0.141.1
13
+
14
+ ## 0.141.0
15
+
16
+ ### Minor Changes
17
+
18
+ - [#779](https://github.com/valbuild/val/pull/779) [`ba3f330`](https://github.com/valbuild/val/commit/ba3f3300a3dd8649e154097cdfca3b64db209d89) Thanks [@freekh](https://github.com/freekh)! - New: `s.video()`, for mp4/WebM files and HLS streams.
19
+
20
+ ```ts
21
+ const schema = s.object({
22
+ intro: s.video({ stream: { type: "hls" } }),
23
+ });
24
+ ```
25
+
26
+ - **Upload and play in the Studio.** A video field shows a player, the file's size and length, and progress while it uploads.
27
+ - **HLS streaming without a video service.** With `stream: { type: "hls" }`, the Studio converts an upload to an HLS stream in the editor's browser before it uploads it. It makes one H.264 rendition per height (1080p, 720p and 480p by default, and never larger than the upload) and stores them as a folder of files next to your other uploads. Nothing is installed in your app for this: the converter ships inside the Studio and is only downloaded when someone uploads to a streaming field. A browser that can't convert (no WebCodecs, or a non-https address) uploads the original file and says so.
28
+ - **Poster:** pause on a frame and choose "Use current frame". The frame is saved as an image, and `posterTime` records where it was taken.
29
+ - **Start and end:** play part of a video without cutting the file.
30
+ - **Focal point:** marks what must stay in frame when the page crops the video.
31
+ - **Description:** text for people who can't see the video.
32
+ - **Captions:** one WebVTT file per language. `.srt` files are converted on upload.
33
+ - **`<ValVideo>`** in `@valbuild/next` and `@valbuild/tanstack` renders all of the above and is click-to-edit. For HLS in browsers that can't play it natively, pass `hls={() => import("hls.js")}`. It is only loaded when it's needed.
34
+ - **Rename** a video in the Studio. An HLS stream is renamed as a whole: every playlist and segment moves to the new folder.
35
+ - `npx val validate --fix` fills in `mimeType`, `width`, `height` and `duration` for a hand-written `.mp4`, `.mov`, `.webm`, `.mkv` or HLS video, on disk or on Val Remote. A remote video is not downloaded: only its headers are read, usually in one to three small requests.
36
+ - `.remote()` works for videos. `npx val validate --fix` moves a video to Val Remote, or back into the project, together with its poster, captions and every file of an HLS stream.
37
+
38
+ A video value always has a `mimeType`: it is how a page knows whether it has an `.mp4` or an `.m3u8`.
39
+
40
+ New: `s.videoset()`, a collection of videos, like `s.imageset()` for images.
41
+
42
+ ```ts
43
+ const videosVal = c.define(
44
+ "/content/videos.val.ts",
45
+ s.videoset({ dir: "/public/val/videos", stream: { type: "hls" } }),
46
+ {},
47
+ );
48
+ const schema = s.object({ intro: s.video(videosVal) });
49
+ ```
50
+
51
+ - **Upload once, set it up once, use anywhere.** A set's entry holds what is true of the file (its type, size and length) and, as defaults, a description, poster, start and end, focal point and captions. A field that picks from the set (`s.video(videosVal)`) gets all of those, and can override any of them on its own. For example, the same clip can open one page at 0:02 and every other page where the set says.
52
+ - **Media in the Studio.** A set is listed under Media and opens as a gallery of videos, with each video's poster as its thumbnail. Hovering a video previews it, and the selected video plays in a real player (HLS streams too) beside the poster, times, focal point and captions you edit for it. You can upload into the set (with `stream`, uploads become HLS streams, and each upload gets a poster), rename a video, and delete a video that nothing uses. Renaming a video updates every field that uses it. An HLS stream is one entry, and renaming or deleting it moves or removes all of its files.
53
+ - **Picking.** A set-backed field picks from the set, or uploads into it. Each value the set provides is marked "From gallery · Override", and once overridden, "Overridden · Use gallery's".
54
+ - `useVal` and `fetchVal` fill in what the set holds (`mimeType`, `width`, `height`, `duration`, and every default the field does not override), so `<ValVideo>` works the same either way.
55
+ - `.remote()` works for sets. `npx val validate --fix` fills in missing metadata for an entry, adds untracked videos found in the set's directory, and moves a set's videos to Val Remote.
56
+
57
+ Image and file galleries use the same new gallery layout: a grid or list of entries, with the selected one open in a panel beside it.
58
+
59
+ - An `s.imageset()` entry can hold a default focal point, as well as its description. An `s.image(galleryVal)` field shows both, and can override either.
60
+ - Fixed: outside draft mode, `useVal` and `fetchVal` now fill a gallery-backed image or file from its gallery (dimensions, mime type, description). Before, a published page got only the `path`.
61
+
62
+ ### Patch Changes
63
+
64
+ - [#801](https://github.com/valbuild/val/pull/801) [`9cbe428`](https://github.com/valbuild/val/commit/9cbe42895d006d55c3d993dc27f0779808b85306) Thanks [@freekh](https://github.com/freekh)! - Emptying a field in the preview's "On this page" list no longer removes it from the list while you are editing it.
65
+
66
+ The list shows what the page renders, and a field you empty often renders nothing: an empty rich text, an image set to none, or a link whose label was cleared. The row you were typing in used to vanish, taking your cursor with it, and clearing a link's label also removed its URL from the list. Now a field you have worked on stays where it was, marked "Not on page", until you reload the page with the canvas's reload button or go to another page. A field you delete from the content, such as a removed list item, still goes away at once.
67
+
68
+ - Updated dependencies [[`199e214`](https://github.com/valbuild/val/commit/199e21471d98806fb34c579cb876560078c928b9), [`9cbe428`](https://github.com/valbuild/val/commit/9cbe42895d006d55c3d993dc27f0779808b85306), [`fb5f097`](https://github.com/valbuild/val/commit/fb5f09721ac07f4d90b8502fdbee3fb3884d9688), [`6473a2e`](https://github.com/valbuild/val/commit/6473a2efe874f1749b27ed6f8ac4e0d19805edb1), [`ba3f330`](https://github.com/valbuild/val/commit/ba3f3300a3dd8649e154097cdfca3b64db209d89)]:
69
+ - @valbuild/core@0.141.0
70
+ - @valbuild/server@0.141.0
71
+ - @valbuild/shared@0.141.0
72
+ - @valbuild/ui@0.141.0
73
+ - @valbuild/language-server@0.141.0
74
+ - @valbuild/react@0.141.0
75
+ - @valbuild/mcp@0.141.0
76
+
3
77
  ## 0.140.2
4
78
 
5
79
  ### Patch Changes
@@ -0,0 +1,50 @@
1
+ import { Video } from "@valbuild/react/stega";
2
+ /**
3
+ * What `ValVideo` needs from hls.js — written out rather than imported, so
4
+ * this package typechecks in an app that has never installed it.
5
+ */
6
+ type HlsLike = {
7
+ loadSource(url: string): void;
8
+ attachMedia(media: HTMLMediaElement): void;
9
+ destroy(): void;
10
+ };
11
+ type HlsConstructorLike = {
12
+ new (): HlsLike;
13
+ isSupported(): boolean;
14
+ };
15
+ export type ValVideoProps = Omit<React.ComponentProps<"video">, "src" | "poster" | "children"> & {
16
+ src: Video;
17
+ /**
18
+ * How to play an HLS stream in a browser that cannot play one itself, which
19
+ * is every browser but Safari (and recent Chrome). Pass a loader for hls.js:
20
+ *
21
+ * ```tsx
22
+ * <ValVideo src={page.intro} hls={() => import("hls.js")} />
23
+ * ```
24
+ *
25
+ * It is called only when the video IS a stream and the browser needs it, so
26
+ * a page of plain mp4s never downloads it. Without it, such a browser shows
27
+ * the poster and an unplayable player.
28
+ */
29
+ hls?: () => Promise<{
30
+ default: HlsConstructorLike;
31
+ }>;
32
+ /** Ignore the video's hotspot instead of applying it as object-position. */
33
+ disableHotspot?: boolean;
34
+ /** Leave out the caption tracks. */
35
+ disableCaptions?: boolean;
36
+ };
37
+ /**
38
+ * A `<video>` for a Val video, with everything the Studio lets an editor set:
39
+ * the poster, the caption tracks, the start and end time, and the focal point
40
+ * as `object-position`. Like `ValImage`, the edit tag on `src.url` is moved to
41
+ * `data-val-path`, so the video is click-to-edit and the URL the browser
42
+ * fetches is clean.
43
+ *
44
+ * Start and end are applied by the player rather than by cutting the file: it
45
+ * seeks to `startTime` when the video loads and pauses at `endTime`. For a
46
+ * progressive file the `#t=` media fragment says the same thing to the
47
+ * browser before any script runs.
48
+ */
49
+ export declare function ValVideo(props: ValVideoProps): import("react").JSX.Element;
50
+ export {};
@@ -1,7 +1,7 @@
1
1
  export { Schema, type SerializedSchema } from "@valbuild/core";
2
2
  export type { SourceObject, SourcePrimitive, Source } from "@valbuild/core";
3
3
  export type { ValModule, SerializedModule } from "@valbuild/core";
4
- export type { FileSource, ImageSource, MediaSource } from "@valbuild/core";
4
+ export type { FileSource, ImageSource, MediaSource, VideoSource, } from "@valbuild/core";
5
5
  export type { RichTextSource } from "@valbuild/core";
6
6
  export { type Val, type SerializedVal, type ModuleFilePath, type ModulePath, type SourcePath, type JsonOfSource, } from "@valbuild/core";
7
7
  export { modules, type ValModules } from "@valbuild/core";
@@ -13,10 +13,11 @@ export { VAL_EXTENSION, type SourceArray } from "@valbuild/core";
13
13
  export { derefPatch } from "@valbuild/core";
14
14
  export { type SelectorSource, type SelectorOf, GenericSelector, } from "@valbuild/core";
15
15
  export { ValRichText } from "@valbuild/react/internal";
16
- export { type ValEncodedString, type File, type Image, type RichText, } from "@valbuild/react/stega";
16
+ export { type ValEncodedString, type File, type Image, type Video, type RichText, } from "@valbuild/react/stega";
17
17
  export { ValProvider } from "./ValProvider.js";
18
18
  export type { ValDraft } from "./ValDraft.js";
19
19
  export { ValImage, type ValImageProps } from "./ValImage.js";
20
+ export { ValVideo, type ValVideoProps } from "./ValVideo.js";
20
21
  export { ValApp } from "./ValApp.js";
21
22
  export { ValModulesClient, useRegisterValModules } from "./ValModulesClient.js";
22
23
  import { Internal as InternalCore } from "@valbuild/core";
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = require('./version-7dd0b309.cjs.dev.js');
5
+ var version = require('./version-e04493d5.cjs.dev.js');
6
6
  var createForOfIteratorHelper = require('./createForOfIteratorHelper-4497beef.cjs.dev.js');
7
7
  var core = require('@valbuild/core');
8
8
  var stega = require('@valbuild/react/stega');
@@ -325,8 +325,20 @@ function ValCanvasBridge(_ref) {
325
325
  measured = parent;
326
326
  }
327
327
  }
328
+ /**
329
+ * Skipped only when it has no box at all — `display: none`, or inside
330
+ * something that is — and NOT when the box is merely empty.
331
+ *
332
+ * A field emptied in the Studio is still on the page: an inline element
333
+ * whose only text is the invisible edit tag measures 0×0, and it is the
334
+ * field being edited. Dropping it took the field out of the Studio's
335
+ * "On this page" column mid-edit, and with it every other path on the
336
+ * same element: clearing a link's label also removed its `href`. What the
337
+ * column needs to know is whether the content is on the page, and an
338
+ * empty box answers yes.
339
+ */
340
+ if (measured.getClientRects().length === 0) return;
328
341
  var rect = measured.getBoundingClientRect();
329
- if (rect.width === 0 && rect.height === 0) return;
330
342
  elements.push({
331
343
  // Split by the same helper the rest of Val uses, so the studio gets
332
344
  // the paths back in exactly the form it holds them in.
@@ -1786,7 +1798,7 @@ function _objectWithoutProperties(e, t) {
1786
1798
  return i;
1787
1799
  }
1788
1800
 
1789
- var _excluded = ["src", "alt", "style", "width", "disableHotspot", "height"];
1801
+ var _excluded$1 = ["src", "alt", "style", "width", "disableHotspot", "height"];
1790
1802
  function ValImage(props) {
1791
1803
  var src = props.src,
1792
1804
  alt = props.alt,
@@ -1794,7 +1806,7 @@ function ValImage(props) {
1794
1806
  width = props.width,
1795
1807
  disableHotspot = props.disableHotspot,
1796
1808
  height = props.height,
1797
- rest = _objectWithoutProperties(props, _excluded);
1809
+ rest = _objectWithoutProperties(props, _excluded$1);
1798
1810
  var valPathsOfUrl = src !== null && src !== void 0 && src.url ? decodeValPathsOfString(src.url) : undefined;
1799
1811
  var valPaths = valPathsOfUrl ? valPathsOfUrl : [];
1800
1812
  var maybeValPathOfAlt = alt ? decodeValPathsOfString(alt) : undefined;
@@ -1832,6 +1844,147 @@ function ValImage(props) {
1832
1844
  }));
1833
1845
  }
1834
1846
 
1847
+ var _excluded = ["src", "hls", "disableHotspot", "disableCaptions", "style", "width", "height"];
1848
+ /**
1849
+ * A `<video>` for a Val video, with everything the Studio lets an editor set:
1850
+ * the poster, the caption tracks, the start and end time, and the focal point
1851
+ * as `object-position`. Like `ValImage`, the edit tag on `src.url` is moved to
1852
+ * `data-val-path`, so the video is click-to-edit and the URL the browser
1853
+ * fetches is clean.
1854
+ *
1855
+ * Start and end are applied by the player rather than by cutting the file: it
1856
+ * seeks to `startTime` when the video loads and pauses at `endTime`. For a
1857
+ * progressive file the `#t=` media fragment says the same thing to the
1858
+ * browser before any script runs.
1859
+ */
1860
+ function ValVideo(props) {
1861
+ var _src$mimeType, _src$poster, _rest$ariaLabel, _src$captions;
1862
+ var src = props.src,
1863
+ hls = props.hls,
1864
+ disableHotspot = props.disableHotspot,
1865
+ disableCaptions = props.disableCaptions,
1866
+ style = props.style,
1867
+ width = props.width,
1868
+ height = props.height,
1869
+ rest = _objectWithoutProperties(props, _excluded);
1870
+ var ref = React.useRef(null);
1871
+ /** The latest loader, read when a stream is attached; see the effect below. */
1872
+ var hlsRef = React.useRef(hls);
1873
+ React.useEffect(function () {
1874
+ hlsRef.current = hls;
1875
+ }, [hls]);
1876
+ var hasHls = hls !== undefined;
1877
+ var valPathsOfUrl = src !== null && src !== void 0 && src.url ? decodeValPathsOfString(src.url) : undefined;
1878
+ var url = src !== null && src !== void 0 && src.url ? valPathsOfUrl && valPathsOfUrl.length > 0 ? stega.raw(src.url) : src.url : undefined;
1879
+ var isHls = (src === null || src === void 0 ? void 0 : src.mimeType) === "application/vnd.apple.mpegurl" || (src === null || src === void 0 || (_src$mimeType = src.mimeType) === null || _src$mimeType === void 0 ? void 0 : _src$mimeType.toLowerCase()) === "application/x-mpegurl";
1880
+ var startTime = src === null || src === void 0 ? void 0 : src.startTime;
1881
+ var endTime = src === null || src === void 0 ? void 0 : src.endTime;
1882
+ React.useEffect(function () {
1883
+ var video = ref.current;
1884
+ if (!video || !url) {
1885
+ return;
1886
+ }
1887
+ if (!isHls || video.canPlayType("application/vnd.apple.mpegurl") !== "") {
1888
+ video.src = !isHls && (startTime !== undefined || endTime !== undefined) ? "".concat(url, "#t=").concat(startTime !== null && startTime !== void 0 ? startTime : 0).concat(endTime !== undefined ? ",".concat(endTime) : "") : url;
1889
+ return function () {
1890
+ video.removeAttribute("src");
1891
+ video.load();
1892
+ };
1893
+ }
1894
+ var loadHls = hlsRef.current;
1895
+ if (!loadHls) {
1896
+ console.warn('Val: this browser cannot play HLS streams on its own. Pass `hls={() => import("hls.js")}` to ValVideo.');
1897
+ return;
1898
+ }
1899
+ var destroyed = false;
1900
+ var instance = null;
1901
+ loadHls().then(function (_ref) {
1902
+ var Hls = _ref["default"];
1903
+ if (destroyed || !Hls.isSupported()) {
1904
+ return;
1905
+ }
1906
+ instance = new Hls();
1907
+ instance.loadSource(url);
1908
+ instance.attachMedia(video);
1909
+ });
1910
+ return function () {
1911
+ var _instance;
1912
+ destroyed = true;
1913
+ (_instance = instance) === null || _instance === void 0 || _instance.destroy();
1914
+ };
1915
+ // `hasHls`, not `hls`: the loader is passed inline (`hls={() => import(…)}`),
1916
+ // so its identity changes on every render of the parent, and depending on
1917
+ // it tore playback down and started it again for a render that changed
1918
+ // nothing about the video.
1919
+ }, [url, isHls, hasHls, startTime, endTime]);
1920
+ React.useEffect(function () {
1921
+ var video = ref.current;
1922
+ if (!video || startTime === undefined && endTime === undefined) {
1923
+ return;
1924
+ }
1925
+ var onLoaded = function onLoaded() {
1926
+ if (startTime !== undefined && video.currentTime < startTime) {
1927
+ video.currentTime = startTime;
1928
+ }
1929
+ };
1930
+ var onTimeUpdate = function onTimeUpdate() {
1931
+ if (endTime !== undefined && video.currentTime >= endTime) {
1932
+ if (video.loop) {
1933
+ video.currentTime = startTime !== null && startTime !== void 0 ? startTime : 0;
1934
+ } else {
1935
+ video.pause();
1936
+ }
1937
+ }
1938
+ };
1939
+ // Play pressed at the end (or before the start): from the start again.
1940
+ // Without this a video stopped at its end could not be played again —
1941
+ // every play landed past the end and was paused on the next tick.
1942
+ var onPlay = function onPlay() {
1943
+ if (endTime !== undefined && video.currentTime >= endTime || startTime !== undefined && video.currentTime < startTime) {
1944
+ video.currentTime = startTime !== null && startTime !== void 0 ? startTime : 0;
1945
+ }
1946
+ };
1947
+ video.addEventListener("loadedmetadata", onLoaded);
1948
+ video.addEventListener("timeupdate", onTimeUpdate);
1949
+ video.addEventListener("play", onPlay);
1950
+ return function () {
1951
+ video.removeEventListener("loadedmetadata", onLoaded);
1952
+ video.removeEventListener("timeupdate", onTimeUpdate);
1953
+ video.removeEventListener("play", onPlay);
1954
+ };
1955
+ }, [startTime, endTime]);
1956
+ var hotspot = src === null || src === void 0 ? void 0 : src.hotspot;
1957
+ var videoStyle = hotspot && !disableHotspot ? createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({}, style), {}, {
1958
+ objectPosition: "".concat(hotspot.x * 100, "% ").concat(hotspot.y * 100, "%")
1959
+ }) : style;
1960
+ // As for `ValImage`: the file's own size reserves the space, unless the
1961
+ // caller is sizing the element.
1962
+ var preferMetadataDims = ((src === null || src === void 0 ? void 0 : src.width) !== undefined || (src === null || src === void 0 ? void 0 : src.height) !== undefined) && !width && !height;
1963
+ return /*#__PURE__*/jsxRuntime.jsx("video", createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({
1964
+ playsInline: true,
1965
+ preload: "metadata"
1966
+ }, rest), {}, {
1967
+ ref: ref,
1968
+ poster: src === null || src === void 0 || (_src$poster = src.poster) === null || _src$poster === void 0 ? void 0 : _src$poster.url,
1969
+ "aria-label": (_rest$ariaLabel = rest["aria-label"]) !== null && _rest$ariaLabel !== void 0 ? _rest$ariaLabel : src !== null && src !== void 0 && src.alt ? stega.raw(src.alt) : undefined,
1970
+ "data-val-path": valPathsOfUrl === null || valPathsOfUrl === void 0 ? void 0 : valPathsOfUrl.join(","),
1971
+ "data-val-attr-src": valPathsOfUrl === null || valPathsOfUrl === void 0 ? void 0 : valPathsOfUrl.join(","),
1972
+ style: videoStyle,
1973
+ width: preferMetadataDims ? src === null || src === void 0 ? void 0 : src.width : width,
1974
+ height: preferMetadataDims ? src === null || src === void 0 ? void 0 : src.height : height,
1975
+ children: !disableCaptions && (src === null || src === void 0 || (_src$captions = src.captions) === null || _src$captions === void 0 ? void 0 : _src$captions.map(function (track) {
1976
+ var _track$kind;
1977
+ return /*#__PURE__*/jsxRuntime.jsx("track", {
1978
+ src: track.url,
1979
+ srcLang: track.srclang,
1980
+ label: track.label ? stega.raw(track.label) : track.srclang,
1981
+ kind: (_track$kind = track.kind) !== null && _track$kind !== void 0 ? _track$kind : "subtitles",
1982
+ "default": track["default"]
1983
+ }, track.url);
1984
+ }))
1985
+ }));
1986
+ }
1987
+
1835
1988
  var VAL_READY_PING_MS = 100;
1836
1989
  var ValApp = function ValApp(_ref) {
1837
1990
  var config = _ref.config,
@@ -2050,5 +2203,6 @@ exports.ValApp = ValApp;
2050
2203
  exports.ValImage = ValImage;
2051
2204
  exports.ValModulesClient = ValModulesClient;
2052
2205
  exports.ValProvider = ValProvider;
2206
+ exports.ValVideo = ValVideo;
2053
2207
  exports.initVal = initVal;
2054
2208
  exports.useRegisterValModules = useRegisterValModules;
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = require('./version-a29cfb8e.cjs.prod.js');
5
+ var version = require('./version-1205910c.cjs.prod.js');
6
6
  var createForOfIteratorHelper = require('./createForOfIteratorHelper-9afd7d2d.cjs.prod.js');
7
7
  var core = require('@valbuild/core');
8
8
  var stega = require('@valbuild/react/stega');
@@ -325,8 +325,20 @@ function ValCanvasBridge(_ref) {
325
325
  measured = parent;
326
326
  }
327
327
  }
328
+ /**
329
+ * Skipped only when it has no box at all — `display: none`, or inside
330
+ * something that is — and NOT when the box is merely empty.
331
+ *
332
+ * A field emptied in the Studio is still on the page: an inline element
333
+ * whose only text is the invisible edit tag measures 0×0, and it is the
334
+ * field being edited. Dropping it took the field out of the Studio's
335
+ * "On this page" column mid-edit, and with it every other path on the
336
+ * same element: clearing a link's label also removed its `href`. What the
337
+ * column needs to know is whether the content is on the page, and an
338
+ * empty box answers yes.
339
+ */
340
+ if (measured.getClientRects().length === 0) return;
328
341
  var rect = measured.getBoundingClientRect();
329
- if (rect.width === 0 && rect.height === 0) return;
330
342
  elements.push({
331
343
  // Split by the same helper the rest of Val uses, so the studio gets
332
344
  // the paths back in exactly the form it holds them in.
@@ -1786,7 +1798,7 @@ function _objectWithoutProperties(e, t) {
1786
1798
  return i;
1787
1799
  }
1788
1800
 
1789
- var _excluded = ["src", "alt", "style", "width", "disableHotspot", "height"];
1801
+ var _excluded$1 = ["src", "alt", "style", "width", "disableHotspot", "height"];
1790
1802
  function ValImage(props) {
1791
1803
  var src = props.src,
1792
1804
  alt = props.alt,
@@ -1794,7 +1806,7 @@ function ValImage(props) {
1794
1806
  width = props.width,
1795
1807
  disableHotspot = props.disableHotspot,
1796
1808
  height = props.height,
1797
- rest = _objectWithoutProperties(props, _excluded);
1809
+ rest = _objectWithoutProperties(props, _excluded$1);
1798
1810
  var valPathsOfUrl = src !== null && src !== void 0 && src.url ? decodeValPathsOfString(src.url) : undefined;
1799
1811
  var valPaths = valPathsOfUrl ? valPathsOfUrl : [];
1800
1812
  var maybeValPathOfAlt = alt ? decodeValPathsOfString(alt) : undefined;
@@ -1832,6 +1844,147 @@ function ValImage(props) {
1832
1844
  }));
1833
1845
  }
1834
1846
 
1847
+ var _excluded = ["src", "hls", "disableHotspot", "disableCaptions", "style", "width", "height"];
1848
+ /**
1849
+ * A `<video>` for a Val video, with everything the Studio lets an editor set:
1850
+ * the poster, the caption tracks, the start and end time, and the focal point
1851
+ * as `object-position`. Like `ValImage`, the edit tag on `src.url` is moved to
1852
+ * `data-val-path`, so the video is click-to-edit and the URL the browser
1853
+ * fetches is clean.
1854
+ *
1855
+ * Start and end are applied by the player rather than by cutting the file: it
1856
+ * seeks to `startTime` when the video loads and pauses at `endTime`. For a
1857
+ * progressive file the `#t=` media fragment says the same thing to the
1858
+ * browser before any script runs.
1859
+ */
1860
+ function ValVideo(props) {
1861
+ var _src$mimeType, _src$poster, _rest$ariaLabel, _src$captions;
1862
+ var src = props.src,
1863
+ hls = props.hls,
1864
+ disableHotspot = props.disableHotspot,
1865
+ disableCaptions = props.disableCaptions,
1866
+ style = props.style,
1867
+ width = props.width,
1868
+ height = props.height,
1869
+ rest = _objectWithoutProperties(props, _excluded);
1870
+ var ref = React.useRef(null);
1871
+ /** The latest loader, read when a stream is attached; see the effect below. */
1872
+ var hlsRef = React.useRef(hls);
1873
+ React.useEffect(function () {
1874
+ hlsRef.current = hls;
1875
+ }, [hls]);
1876
+ var hasHls = hls !== undefined;
1877
+ var valPathsOfUrl = src !== null && src !== void 0 && src.url ? decodeValPathsOfString(src.url) : undefined;
1878
+ var url = src !== null && src !== void 0 && src.url ? valPathsOfUrl && valPathsOfUrl.length > 0 ? stega.raw(src.url) : src.url : undefined;
1879
+ var isHls = (src === null || src === void 0 ? void 0 : src.mimeType) === "application/vnd.apple.mpegurl" || (src === null || src === void 0 || (_src$mimeType = src.mimeType) === null || _src$mimeType === void 0 ? void 0 : _src$mimeType.toLowerCase()) === "application/x-mpegurl";
1880
+ var startTime = src === null || src === void 0 ? void 0 : src.startTime;
1881
+ var endTime = src === null || src === void 0 ? void 0 : src.endTime;
1882
+ React.useEffect(function () {
1883
+ var video = ref.current;
1884
+ if (!video || !url) {
1885
+ return;
1886
+ }
1887
+ if (!isHls || video.canPlayType("application/vnd.apple.mpegurl") !== "") {
1888
+ video.src = !isHls && (startTime !== undefined || endTime !== undefined) ? "".concat(url, "#t=").concat(startTime !== null && startTime !== void 0 ? startTime : 0).concat(endTime !== undefined ? ",".concat(endTime) : "") : url;
1889
+ return function () {
1890
+ video.removeAttribute("src");
1891
+ video.load();
1892
+ };
1893
+ }
1894
+ var loadHls = hlsRef.current;
1895
+ if (!loadHls) {
1896
+ console.warn('Val: this browser cannot play HLS streams on its own. Pass `hls={() => import("hls.js")}` to ValVideo.');
1897
+ return;
1898
+ }
1899
+ var destroyed = false;
1900
+ var instance = null;
1901
+ loadHls().then(function (_ref) {
1902
+ var Hls = _ref["default"];
1903
+ if (destroyed || !Hls.isSupported()) {
1904
+ return;
1905
+ }
1906
+ instance = new Hls();
1907
+ instance.loadSource(url);
1908
+ instance.attachMedia(video);
1909
+ });
1910
+ return function () {
1911
+ var _instance;
1912
+ destroyed = true;
1913
+ (_instance = instance) === null || _instance === void 0 || _instance.destroy();
1914
+ };
1915
+ // `hasHls`, not `hls`: the loader is passed inline (`hls={() => import(…)}`),
1916
+ // so its identity changes on every render of the parent, and depending on
1917
+ // it tore playback down and started it again for a render that changed
1918
+ // nothing about the video.
1919
+ }, [url, isHls, hasHls, startTime, endTime]);
1920
+ React.useEffect(function () {
1921
+ var video = ref.current;
1922
+ if (!video || startTime === undefined && endTime === undefined) {
1923
+ return;
1924
+ }
1925
+ var onLoaded = function onLoaded() {
1926
+ if (startTime !== undefined && video.currentTime < startTime) {
1927
+ video.currentTime = startTime;
1928
+ }
1929
+ };
1930
+ var onTimeUpdate = function onTimeUpdate() {
1931
+ if (endTime !== undefined && video.currentTime >= endTime) {
1932
+ if (video.loop) {
1933
+ video.currentTime = startTime !== null && startTime !== void 0 ? startTime : 0;
1934
+ } else {
1935
+ video.pause();
1936
+ }
1937
+ }
1938
+ };
1939
+ // Play pressed at the end (or before the start): from the start again.
1940
+ // Without this a video stopped at its end could not be played again —
1941
+ // every play landed past the end and was paused on the next tick.
1942
+ var onPlay = function onPlay() {
1943
+ if (endTime !== undefined && video.currentTime >= endTime || startTime !== undefined && video.currentTime < startTime) {
1944
+ video.currentTime = startTime !== null && startTime !== void 0 ? startTime : 0;
1945
+ }
1946
+ };
1947
+ video.addEventListener("loadedmetadata", onLoaded);
1948
+ video.addEventListener("timeupdate", onTimeUpdate);
1949
+ video.addEventListener("play", onPlay);
1950
+ return function () {
1951
+ video.removeEventListener("loadedmetadata", onLoaded);
1952
+ video.removeEventListener("timeupdate", onTimeUpdate);
1953
+ video.removeEventListener("play", onPlay);
1954
+ };
1955
+ }, [startTime, endTime]);
1956
+ var hotspot = src === null || src === void 0 ? void 0 : src.hotspot;
1957
+ var videoStyle = hotspot && !disableHotspot ? createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({}, style), {}, {
1958
+ objectPosition: "".concat(hotspot.x * 100, "% ").concat(hotspot.y * 100, "%")
1959
+ }) : style;
1960
+ // As for `ValImage`: the file's own size reserves the space, unless the
1961
+ // caller is sizing the element.
1962
+ var preferMetadataDims = ((src === null || src === void 0 ? void 0 : src.width) !== undefined || (src === null || src === void 0 ? void 0 : src.height) !== undefined) && !width && !height;
1963
+ return /*#__PURE__*/jsxRuntime.jsx("video", createForOfIteratorHelper._objectSpread2(createForOfIteratorHelper._objectSpread2({
1964
+ playsInline: true,
1965
+ preload: "metadata"
1966
+ }, rest), {}, {
1967
+ ref: ref,
1968
+ poster: src === null || src === void 0 || (_src$poster = src.poster) === null || _src$poster === void 0 ? void 0 : _src$poster.url,
1969
+ "aria-label": (_rest$ariaLabel = rest["aria-label"]) !== null && _rest$ariaLabel !== void 0 ? _rest$ariaLabel : src !== null && src !== void 0 && src.alt ? stega.raw(src.alt) : undefined,
1970
+ "data-val-path": valPathsOfUrl === null || valPathsOfUrl === void 0 ? void 0 : valPathsOfUrl.join(","),
1971
+ "data-val-attr-src": valPathsOfUrl === null || valPathsOfUrl === void 0 ? void 0 : valPathsOfUrl.join(","),
1972
+ style: videoStyle,
1973
+ width: preferMetadataDims ? src === null || src === void 0 ? void 0 : src.width : width,
1974
+ height: preferMetadataDims ? src === null || src === void 0 ? void 0 : src.height : height,
1975
+ children: !disableCaptions && (src === null || src === void 0 || (_src$captions = src.captions) === null || _src$captions === void 0 ? void 0 : _src$captions.map(function (track) {
1976
+ var _track$kind;
1977
+ return /*#__PURE__*/jsxRuntime.jsx("track", {
1978
+ src: track.url,
1979
+ srcLang: track.srclang,
1980
+ label: track.label ? stega.raw(track.label) : track.srclang,
1981
+ kind: (_track$kind = track.kind) !== null && _track$kind !== void 0 ? _track$kind : "subtitles",
1982
+ "default": track["default"]
1983
+ }, track.url);
1984
+ }))
1985
+ }));
1986
+ }
1987
+
1835
1988
  var VAL_READY_PING_MS = 100;
1836
1989
  var ValApp = function ValApp(_ref) {
1837
1990
  var config = _ref.config,
@@ -2050,5 +2203,6 @@ exports.ValApp = ValApp;
2050
2203
  exports.ValImage = ValImage;
2051
2204
  exports.ValModulesClient = ValModulesClient;
2052
2205
  exports.ValProvider = ValProvider;
2206
+ exports.ValVideo = ValVideo;
2053
2207
  exports.initVal = initVal;
2054
2208
  exports.useRegisterValModules = useRegisterValModules;
@@ -1,4 +1,4 @@
1
- import { _ as _asyncToGenerator, a as _regenerator, r as readValEnableCookie, V as VERSION$1 } from './version-6d26340d.esm.js';
1
+ import { _ as _asyncToGenerator, a as _regenerator, r as readValEnableCookie, V as VERSION$1 } from './version-2cca9e77.esm.js';
2
2
  import { _ as _objectSpread2, a as _slicedToArray, b as _createForOfIteratorHelper } from './createForOfIteratorHelper-93a62170.esm.js';
3
3
  import { Internal as Internal$1, initVal as initVal$1, DEFAULT_CONTENT_HOST } from '@valbuild/core';
4
4
  import * as core from '@valbuild/core';
@@ -8,7 +8,7 @@ import { stegaEncode, stegaDecodeStrings, attrs, raw, SET_AUTO_TAG_JSX_ENABLED,
8
8
  export { ValRichText } from '@valbuild/react/internal';
9
9
  import { VERSION, VAL_APP_PATH, VAL_OVERLAY_ID, VAL_APP_ID } from '@valbuild/ui';
10
10
  import { useRouter, useRouterState } from '@tanstack/react-router';
11
- import React, { useEffect, useState, useRef } from 'react';
11
+ import React, { useEffect, useRef, useState } from 'react';
12
12
  import { V as ValExternalStore, a as ValOverlayProvider } from './ValOverlayContext-28101df3.esm.js';
13
13
  import { VAL_CONFIG_SESSION_STORAGE_KEY, VAL_THEME_SESSION_STORAGE_KEY, VAL_CANVAS_MESSAGE, DEFAULT_CANVAS_SELECTION, DEFAULT_CANVAS_SELECTION_SOFT, isValCanvasStudioMessage, isValCanvasFrame } from '@valbuild/shared/client';
14
14
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -301,8 +301,20 @@ function ValCanvasBridge(_ref) {
301
301
  measured = parent;
302
302
  }
303
303
  }
304
+ /**
305
+ * Skipped only when it has no box at all — `display: none`, or inside
306
+ * something that is — and NOT when the box is merely empty.
307
+ *
308
+ * A field emptied in the Studio is still on the page: an inline element
309
+ * whose only text is the invisible edit tag measures 0×0, and it is the
310
+ * field being edited. Dropping it took the field out of the Studio's
311
+ * "On this page" column mid-edit, and with it every other path on the
312
+ * same element: clearing a link's label also removed its `href`. What the
313
+ * column needs to know is whether the content is on the page, and an
314
+ * empty box answers yes.
315
+ */
316
+ if (measured.getClientRects().length === 0) return;
304
317
  var rect = measured.getBoundingClientRect();
305
- if (rect.width === 0 && rect.height === 0) return;
306
318
  elements.push({
307
319
  // Split by the same helper the rest of Val uses, so the studio gets
308
320
  // the paths back in exactly the form it holds them in.
@@ -1762,7 +1774,7 @@ function _objectWithoutProperties(e, t) {
1762
1774
  return i;
1763
1775
  }
1764
1776
 
1765
- var _excluded = ["src", "alt", "style", "width", "disableHotspot", "height"];
1777
+ var _excluded$1 = ["src", "alt", "style", "width", "disableHotspot", "height"];
1766
1778
  function ValImage(props) {
1767
1779
  var src = props.src,
1768
1780
  alt = props.alt,
@@ -1770,7 +1782,7 @@ function ValImage(props) {
1770
1782
  width = props.width,
1771
1783
  disableHotspot = props.disableHotspot,
1772
1784
  height = props.height,
1773
- rest = _objectWithoutProperties(props, _excluded);
1785
+ rest = _objectWithoutProperties(props, _excluded$1);
1774
1786
  var valPathsOfUrl = src !== null && src !== void 0 && src.url ? decodeValPathsOfString(src.url) : undefined;
1775
1787
  var valPaths = valPathsOfUrl ? valPathsOfUrl : [];
1776
1788
  var maybeValPathOfAlt = alt ? decodeValPathsOfString(alt) : undefined;
@@ -1808,6 +1820,147 @@ function ValImage(props) {
1808
1820
  }));
1809
1821
  }
1810
1822
 
1823
+ var _excluded = ["src", "hls", "disableHotspot", "disableCaptions", "style", "width", "height"];
1824
+ /**
1825
+ * A `<video>` for a Val video, with everything the Studio lets an editor set:
1826
+ * the poster, the caption tracks, the start and end time, and the focal point
1827
+ * as `object-position`. Like `ValImage`, the edit tag on `src.url` is moved to
1828
+ * `data-val-path`, so the video is click-to-edit and the URL the browser
1829
+ * fetches is clean.
1830
+ *
1831
+ * Start and end are applied by the player rather than by cutting the file: it
1832
+ * seeks to `startTime` when the video loads and pauses at `endTime`. For a
1833
+ * progressive file the `#t=` media fragment says the same thing to the
1834
+ * browser before any script runs.
1835
+ */
1836
+ function ValVideo(props) {
1837
+ var _src$mimeType, _src$poster, _rest$ariaLabel, _src$captions;
1838
+ var src = props.src,
1839
+ hls = props.hls,
1840
+ disableHotspot = props.disableHotspot,
1841
+ disableCaptions = props.disableCaptions,
1842
+ style = props.style,
1843
+ width = props.width,
1844
+ height = props.height,
1845
+ rest = _objectWithoutProperties(props, _excluded);
1846
+ var ref = useRef(null);
1847
+ /** The latest loader, read when a stream is attached; see the effect below. */
1848
+ var hlsRef = useRef(hls);
1849
+ useEffect(function () {
1850
+ hlsRef.current = hls;
1851
+ }, [hls]);
1852
+ var hasHls = hls !== undefined;
1853
+ var valPathsOfUrl = src !== null && src !== void 0 && src.url ? decodeValPathsOfString(src.url) : undefined;
1854
+ var url = src !== null && src !== void 0 && src.url ? valPathsOfUrl && valPathsOfUrl.length > 0 ? raw(src.url) : src.url : undefined;
1855
+ var isHls = (src === null || src === void 0 ? void 0 : src.mimeType) === "application/vnd.apple.mpegurl" || (src === null || src === void 0 || (_src$mimeType = src.mimeType) === null || _src$mimeType === void 0 ? void 0 : _src$mimeType.toLowerCase()) === "application/x-mpegurl";
1856
+ var startTime = src === null || src === void 0 ? void 0 : src.startTime;
1857
+ var endTime = src === null || src === void 0 ? void 0 : src.endTime;
1858
+ useEffect(function () {
1859
+ var video = ref.current;
1860
+ if (!video || !url) {
1861
+ return;
1862
+ }
1863
+ if (!isHls || video.canPlayType("application/vnd.apple.mpegurl") !== "") {
1864
+ video.src = !isHls && (startTime !== undefined || endTime !== undefined) ? "".concat(url, "#t=").concat(startTime !== null && startTime !== void 0 ? startTime : 0).concat(endTime !== undefined ? ",".concat(endTime) : "") : url;
1865
+ return function () {
1866
+ video.removeAttribute("src");
1867
+ video.load();
1868
+ };
1869
+ }
1870
+ var loadHls = hlsRef.current;
1871
+ if (!loadHls) {
1872
+ console.warn('Val: this browser cannot play HLS streams on its own. Pass `hls={() => import("hls.js")}` to ValVideo.');
1873
+ return;
1874
+ }
1875
+ var destroyed = false;
1876
+ var instance = null;
1877
+ loadHls().then(function (_ref) {
1878
+ var Hls = _ref["default"];
1879
+ if (destroyed || !Hls.isSupported()) {
1880
+ return;
1881
+ }
1882
+ instance = new Hls();
1883
+ instance.loadSource(url);
1884
+ instance.attachMedia(video);
1885
+ });
1886
+ return function () {
1887
+ var _instance;
1888
+ destroyed = true;
1889
+ (_instance = instance) === null || _instance === void 0 || _instance.destroy();
1890
+ };
1891
+ // `hasHls`, not `hls`: the loader is passed inline (`hls={() => import(…)}`),
1892
+ // so its identity changes on every render of the parent, and depending on
1893
+ // it tore playback down and started it again for a render that changed
1894
+ // nothing about the video.
1895
+ }, [url, isHls, hasHls, startTime, endTime]);
1896
+ useEffect(function () {
1897
+ var video = ref.current;
1898
+ if (!video || startTime === undefined && endTime === undefined) {
1899
+ return;
1900
+ }
1901
+ var onLoaded = function onLoaded() {
1902
+ if (startTime !== undefined && video.currentTime < startTime) {
1903
+ video.currentTime = startTime;
1904
+ }
1905
+ };
1906
+ var onTimeUpdate = function onTimeUpdate() {
1907
+ if (endTime !== undefined && video.currentTime >= endTime) {
1908
+ if (video.loop) {
1909
+ video.currentTime = startTime !== null && startTime !== void 0 ? startTime : 0;
1910
+ } else {
1911
+ video.pause();
1912
+ }
1913
+ }
1914
+ };
1915
+ // Play pressed at the end (or before the start): from the start again.
1916
+ // Without this a video stopped at its end could not be played again —
1917
+ // every play landed past the end and was paused on the next tick.
1918
+ var onPlay = function onPlay() {
1919
+ if (endTime !== undefined && video.currentTime >= endTime || startTime !== undefined && video.currentTime < startTime) {
1920
+ video.currentTime = startTime !== null && startTime !== void 0 ? startTime : 0;
1921
+ }
1922
+ };
1923
+ video.addEventListener("loadedmetadata", onLoaded);
1924
+ video.addEventListener("timeupdate", onTimeUpdate);
1925
+ video.addEventListener("play", onPlay);
1926
+ return function () {
1927
+ video.removeEventListener("loadedmetadata", onLoaded);
1928
+ video.removeEventListener("timeupdate", onTimeUpdate);
1929
+ video.removeEventListener("play", onPlay);
1930
+ };
1931
+ }, [startTime, endTime]);
1932
+ var hotspot = src === null || src === void 0 ? void 0 : src.hotspot;
1933
+ var videoStyle = hotspot && !disableHotspot ? _objectSpread2(_objectSpread2({}, style), {}, {
1934
+ objectPosition: "".concat(hotspot.x * 100, "% ").concat(hotspot.y * 100, "%")
1935
+ }) : style;
1936
+ // As for `ValImage`: the file's own size reserves the space, unless the
1937
+ // caller is sizing the element.
1938
+ var preferMetadataDims = ((src === null || src === void 0 ? void 0 : src.width) !== undefined || (src === null || src === void 0 ? void 0 : src.height) !== undefined) && !width && !height;
1939
+ return /*#__PURE__*/jsx("video", _objectSpread2(_objectSpread2({
1940
+ playsInline: true,
1941
+ preload: "metadata"
1942
+ }, rest), {}, {
1943
+ ref: ref,
1944
+ poster: src === null || src === void 0 || (_src$poster = src.poster) === null || _src$poster === void 0 ? void 0 : _src$poster.url,
1945
+ "aria-label": (_rest$ariaLabel = rest["aria-label"]) !== null && _rest$ariaLabel !== void 0 ? _rest$ariaLabel : src !== null && src !== void 0 && src.alt ? raw(src.alt) : undefined,
1946
+ "data-val-path": valPathsOfUrl === null || valPathsOfUrl === void 0 ? void 0 : valPathsOfUrl.join(","),
1947
+ "data-val-attr-src": valPathsOfUrl === null || valPathsOfUrl === void 0 ? void 0 : valPathsOfUrl.join(","),
1948
+ style: videoStyle,
1949
+ width: preferMetadataDims ? src === null || src === void 0 ? void 0 : src.width : width,
1950
+ height: preferMetadataDims ? src === null || src === void 0 ? void 0 : src.height : height,
1951
+ children: !disableCaptions && (src === null || src === void 0 || (_src$captions = src.captions) === null || _src$captions === void 0 ? void 0 : _src$captions.map(function (track) {
1952
+ var _track$kind;
1953
+ return /*#__PURE__*/jsx("track", {
1954
+ src: track.url,
1955
+ srcLang: track.srclang,
1956
+ label: track.label ? raw(track.label) : track.srclang,
1957
+ kind: (_track$kind = track.kind) !== null && _track$kind !== void 0 ? _track$kind : "subtitles",
1958
+ "default": track["default"]
1959
+ }, track.url);
1960
+ }))
1961
+ }));
1962
+ }
1963
+
1811
1964
  var VAL_READY_PING_MS = 100;
1812
1965
  var ValApp = function ValApp(_ref) {
1813
1966
  var config = _ref.config,
@@ -1996,4 +2149,4 @@ var Internal = _objectSpread2(_objectSpread2({}, Internal$1), {}, {
1996
2149
  })
1997
2150
  });
1998
2151
 
1999
- export { Internal, ValApp, ValImage, ValModulesClient, ValProvider, initVal, useRegisterValModules };
2152
+ export { Internal, ValApp, ValImage, ValModulesClient, ValProvider, ValVideo, initVal, useRegisterValModules };
@@ -212,7 +212,7 @@ var packageJson = {
212
212
  "tanstack-router",
213
213
  "react"
214
214
  ],
215
- version: "0.140.2",
215
+ version: "0.141.1",
216
216
  scripts: {
217
217
  typecheck: "tsc --noEmit",
218
218
  test: "jest"
@@ -210,7 +210,7 @@ var packageJson = {
210
210
  "tanstack-router",
211
211
  "react"
212
212
  ],
213
- version: "0.140.2",
213
+ version: "0.141.1",
214
214
  scripts: {
215
215
  typecheck: "tsc --noEmit",
216
216
  test: "jest"
@@ -212,7 +212,7 @@ var packageJson = {
212
212
  "tanstack-router",
213
213
  "react"
214
214
  ],
215
- version: "0.140.2",
215
+ version: "0.141.1",
216
216
  scripts: {
217
217
  typecheck: "tsc --noEmit",
218
218
  test: "jest"
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "tanstack-router",
15
15
  "react"
16
16
  ],
17
- "version": "0.140.2",
17
+ "version": "0.141.1",
18
18
  "main": "dist/valbuild-tanstack.cjs.js",
19
19
  "module": "dist/valbuild-tanstack.esm.js",
20
20
  "exports": {
@@ -42,13 +42,13 @@
42
42
  "exports": true
43
43
  },
44
44
  "dependencies": {
45
- "@valbuild/core": "0.139.1",
46
- "@valbuild/language-server": "0.140.2",
47
- "@valbuild/mcp": "0.140.2",
48
- "@valbuild/react": "0.140.2",
49
- "@valbuild/shared": "0.140.2",
50
- "@valbuild/server": "0.140.2",
51
- "@valbuild/ui": "0.140.2"
45
+ "@valbuild/core": "0.141.0",
46
+ "@valbuild/language-server": "0.141.1",
47
+ "@valbuild/mcp": "0.141.1",
48
+ "@valbuild/react": "0.141.1",
49
+ "@valbuild/server": "0.141.1",
50
+ "@valbuild/shared": "0.141.0",
51
+ "@valbuild/ui": "0.141.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@tanstack/react-router": "^1.170.41",
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = require('../../dist/version-7dd0b309.cjs.dev.js');
5
+ var version = require('../../dist/version-e04493d5.cjs.dev.js');
6
6
  var core = require('@valbuild/core');
7
7
  var createForOfIteratorHelper = require('../../dist/createForOfIteratorHelper-4497beef.cjs.dev.js');
8
8
  var server = require('@valbuild/server');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var version = require('../../dist/version-a29cfb8e.cjs.prod.js');
5
+ var version = require('../../dist/version-1205910c.cjs.prod.js');
6
6
  var core = require('@valbuild/core');
7
7
  var createForOfIteratorHelper = require('../../dist/createForOfIteratorHelper-9afd7d2d.cjs.prod.js');
8
8
  var server = require('@valbuild/server');
@@ -1,4 +1,4 @@
1
- import { _ as _asyncToGenerator, a as _regenerator, V as VERSION, s as setValEnableCookieReader } from '../../dist/version-6d26340d.esm.js';
1
+ import { _ as _asyncToGenerator, a as _regenerator, V as VERSION, s as setValEnableCookieReader } from '../../dist/version-2cca9e77.esm.js';
2
2
  import { Internal } from '@valbuild/core';
3
3
  import { _ as _objectSpread2, a as _slicedToArray, e as _arrayLikeToArray, f as _unsupportedIterableToArray, b as _createForOfIteratorHelper, d as _defineProperty } from '../../dist/createForOfIteratorHelper-93a62170.esm.js';
4
4
  import { createValApiRouter, createValServer } from '@valbuild/server';