camox 0.42.0 → 0.44.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.
- package/bin/camox.mjs +9 -1
- package/dist/core/components/lexical/{GradientNode.js → HighlightNode.js} +34 -34
- package/dist/core/components/lexical/InlineLexicalEditor.js +14 -14
- package/dist/core/components/lexical/InlineStylesPlugin.js +25 -9
- package/dist/core/components/lexical/SelectionBroadcaster.js +7 -7
- package/dist/core/components/lexical/SidebarLexicalEditor.js +24 -24
- package/dist/core/components/lexical/TextLinkPopover.js +191 -208
- package/dist/core/components/lexical/editorConfig.js +2 -2
- package/dist/core/createApp.d.ts +31 -4
- package/dist/core/createApp.js +2 -1
- package/dist/core/createBlock.js +24 -10
- package/dist/core/createLayout.d.ts +16 -3
- package/dist/core/createLayout.js +15 -15
- package/dist/core/derivedRoutes.js +1 -1
- package/dist/core/dom.d.ts +17 -0
- package/dist/core/dom.js +22 -0
- package/dist/core/editing/createEditableBlock.d.ts +135 -1
- package/dist/core/editing/createEditableBlock.js +209 -74
- package/dist/core/lib/contentType.d.ts +5 -0
- package/dist/core/lib/contentType.js +11 -0
- package/dist/core/lib/fieldTypes.js +1 -0
- package/dist/core/lib/iconTypes.d.ts +13 -0
- package/dist/core/lib/icons.d.ts +6 -0
- package/dist/core/lib/icons.js +130 -0
- package/dist/core/lib/lexicalReact.js +4 -4
- package/dist/core/lib/lexicalState.js +8 -8
- package/dist/core/lib/modifierFormats.js +2 -2
- package/dist/core/lib/textLinks.js +5 -2
- package/dist/core/lib/textStyles.d.ts +3 -3
- package/dist/core/lib/textStyles.js +9 -14
- package/dist/core/pageDestinations.js +37 -0
- package/dist/features/content/components/AssetCard.js +104 -68
- package/dist/features/og/imageResponse.node.js +11 -9
- package/dist/features/preview/CamoxPreview.js +148 -146
- package/dist/features/preview/commentsEnabled.js +2 -2
- package/dist/features/preview/components/AddBlockSidebar.js +1 -1
- package/dist/features/preview/components/AssetLightbox.js +17 -6
- package/dist/features/preview/components/AttachedComments.js +224 -87
- package/dist/features/preview/components/BlockActionsPopover.js +1 -1
- package/dist/features/preview/components/CommentTargetQuote.js +22 -21
- package/dist/features/preview/components/CreatePageModal.js +4 -4
- package/dist/features/preview/components/DerivedLayoutDialog.js +36 -21
- package/dist/features/preview/components/DerivedLayoutSidebar.js +45 -26
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +38 -26
- package/dist/features/preview/components/FieldOverlayStyles.js +29 -9
- package/dist/features/preview/components/FieldToolbar.js +12 -12
- package/dist/features/preview/components/IconFieldEditor.js +231 -0
- package/dist/features/preview/components/ItemFieldsEditor.js +21 -14
- package/dist/features/preview/components/LinkFieldEditor.js +212 -209
- package/dist/features/preview/components/OverlayTracker.js +1 -1
- package/dist/features/preview/components/PageEditorSidebar.js +1 -1
- package/dist/features/preview/components/PageInfoSidebar.js +28 -28
- package/dist/features/preview/components/PagePicker.js +46 -46
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +224 -225
- package/dist/features/preview/components/PublicationRow.js +8 -4
- package/dist/features/preview/components/SendFeedbackDialog.js +83 -0
- package/dist/features/preview/components/useRepeatableItemActions.js +1 -1
- package/dist/features/preview/overlayHighlights.js +54 -0
- package/dist/features/preview/previewCommentsStore.js +54 -34
- package/dist/features/preview/previewSelection.js +28 -23
- package/dist/features/preview/publication.js +10 -0
- package/dist/features/preview/usePageComments.js +39 -0
- package/dist/features/provider/CoreCamoxProvider.js +38 -6
- package/dist/features/provider/LocalhostPreviewProvider.js +81 -45
- package/dist/features/provider/components/CommandPalette.js +35 -84
- package/dist/features/runtime/pageApp.js +32 -28
- package/dist/features/runtime/pageServer.js +4 -1
- package/dist/features/runtime/runtime.d.ts +2 -0
- package/dist/features/runtime/runtime.js +45 -21
- package/dist/features/studio/components/EnvironmentMenu.js +76 -63
- package/dist/features/studio/components/Navbar.js +53 -80
- package/dist/features/vite/auth.js +1 -50
- package/dist/features/vite/iconGeneration.js +16 -0
- package/dist/features/vite/layoutGeneration.js +7 -3
- package/dist/features/vite/vite.d.ts +4 -2
- package/dist/features/vite/vite.js +24 -3
- package/dist/hooks/use-page-destinations.js +53 -0
- package/dist/lib/auth.js +40 -20
- package/dist/lib/preview-handoff.js +13 -0
- package/dist/lib/queries.js +12 -1
- package/dist/lib/server-auth-cookie.js +21 -0
- package/dist/lib/use-project-room.js +5 -2
- package/dist/studio-overlays.css +19 -15
- package/dist/studio.css +1 -1
- package/package.json +9 -4
- package/skills/camox/SKILL.md +38 -9
- package/skills/camox/references/block-definitions.md +107 -286
- package/skills/camox/references/cli-common.md +16 -4
- package/skills/camox/references/cli-content.md +158 -0
- package/skills/camox/references/cli-environments.md +1 -1
- package/skills/camox/references/dom-integrations.md +93 -0
- package/skills/camox/references/field-styling.md +50 -0
- package/skills/camox/references/layout-definitions.md +33 -147
- package/skills/camox/references/routed-layouts.md +71 -0
- package/skills/camoxify/SKILL.md +66 -0
- package/skills/camox/references/cli-blocks.md +0 -78
- package/skills/camox/references/cli-pages.md +0 -53
|
@@ -12,12 +12,15 @@ function createPageTextLinkTarget(pageId) {
|
|
|
12
12
|
function isHttpTextLinkTarget(target) {
|
|
13
13
|
return /^https?:\/\//i.test(target);
|
|
14
14
|
}
|
|
15
|
+
function isInternalTextLinkTarget(target) {
|
|
16
|
+
return /^\/(?!\/)[^\s\\\p{Cc}]*$/u.test(target);
|
|
17
|
+
}
|
|
15
18
|
function isValidTextLinkTarget(target) {
|
|
16
|
-
return getPageIdFromTextLinkTarget(target) != null || isHttpTextLinkTarget(target);
|
|
19
|
+
return getPageIdFromTextLinkTarget(target) != null || isHttpTextLinkTarget(target) || isInternalTextLinkTarget(target);
|
|
17
20
|
}
|
|
18
21
|
function resolveTextLinkHref(target, pages, fallbackHref) {
|
|
19
22
|
const pageId = getPageIdFromTextLinkTarget(target);
|
|
20
|
-
if (pageId == null) return
|
|
23
|
+
if (pageId == null) return isValidTextLinkTarget(target) ? target : null;
|
|
21
24
|
return (pages?.find((p) => String(p.id) === pageId))?.fullPath ?? fallbackHref;
|
|
22
25
|
}
|
|
23
26
|
function shouldOpenTextLinkInNewTab(target) {
|
|
@@ -6,11 +6,11 @@ interface InlineStyle {
|
|
|
6
6
|
style?: CSSProperties;
|
|
7
7
|
}
|
|
8
8
|
interface TextStyleData {
|
|
9
|
-
/** True when styling the shared
|
|
10
|
-
|
|
9
|
+
/** True when styling the shared highlight wrapper. Other flags are false for this call. */
|
|
10
|
+
highlight: boolean;
|
|
11
11
|
bold: boolean;
|
|
12
12
|
italic: boolean;
|
|
13
|
-
|
|
13
|
+
strikethrough: boolean;
|
|
14
14
|
}
|
|
15
15
|
interface TextLinkStyleData {
|
|
16
16
|
target: string;
|
|
@@ -3,10 +3,10 @@ import { FORMAT_FLAGS } from "./modifierFormats.js";
|
|
|
3
3
|
//#region src/core/lib/textStyles.ts
|
|
4
4
|
function getTextStyleData(format) {
|
|
5
5
|
return {
|
|
6
|
-
|
|
6
|
+
highlight: false,
|
|
7
7
|
bold: !!(format & FORMAT_FLAGS.bold),
|
|
8
8
|
italic: !!(format & FORMAT_FLAGS.italic),
|
|
9
|
-
|
|
9
|
+
strikethrough: !!(format & FORMAT_FLAGS.strikethrough)
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
function getTextAppearance(format, styles) {
|
|
@@ -16,32 +16,27 @@ function getTextAppearance(format, styles) {
|
|
|
16
16
|
className: custom?.className,
|
|
17
17
|
style: {
|
|
18
18
|
...flags.bold && flags.italic ? { fontStyle: "italic" } : {},
|
|
19
|
-
...flags.
|
|
19
|
+
...flags.strikethrough ? { textDecorationLine: "line-through" } : {},
|
|
20
20
|
...custom?.style
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
backgroundClip: "text",
|
|
27
|
-
WebkitBackgroundClip: "text",
|
|
28
|
-
WebkitTextFillColor: "transparent"
|
|
29
|
-
};
|
|
30
|
-
function getGradientStyle(styles) {
|
|
24
|
+
const defaultHighlightStyle = { color: "var(--primary, currentColor)" };
|
|
25
|
+
function getHighlightStyle(styles) {
|
|
31
26
|
const custom = styles.textStyle?.({
|
|
32
|
-
|
|
27
|
+
highlight: true,
|
|
33
28
|
bold: false,
|
|
34
29
|
italic: false,
|
|
35
|
-
|
|
30
|
+
strikethrough: false
|
|
36
31
|
});
|
|
37
32
|
return {
|
|
38
33
|
className: custom?.className,
|
|
39
34
|
style: {
|
|
40
|
-
...
|
|
35
|
+
...defaultHighlightStyle,
|
|
41
36
|
...custom?.style
|
|
42
37
|
}
|
|
43
38
|
};
|
|
44
39
|
}
|
|
45
40
|
|
|
46
41
|
//#endregion
|
|
47
|
-
export {
|
|
42
|
+
export { getHighlightStyle, getTextAppearance };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createPageTextLinkTarget } from "./lib/textLinks.js";
|
|
2
|
+
|
|
3
|
+
//#region src/core/pageDestinations.ts
|
|
4
|
+
/** Concrete navigable pages, not records that can all be mutated through pages.*. */
|
|
5
|
+
function getPageDestinations(pages, layouts) {
|
|
6
|
+
return [...pages.map((page) => ({
|
|
7
|
+
key: `page:${page.id}`,
|
|
8
|
+
kind: "curated",
|
|
9
|
+
pageId: page.id,
|
|
10
|
+
title: page.nickname,
|
|
11
|
+
fullPath: page.fullPath
|
|
12
|
+
})), ...layouts.filter((layout) => layout._internal.kind === "singleton").map(({ _internal: layout }) => ({
|
|
13
|
+
key: `singleton:${layout.id}`,
|
|
14
|
+
kind: "singleton",
|
|
15
|
+
layoutId: layout.id,
|
|
16
|
+
title: layout.title,
|
|
17
|
+
fullPath: `/${layout.id.split(".").map(encodeURIComponent).join("/")}`
|
|
18
|
+
}))];
|
|
19
|
+
}
|
|
20
|
+
/** Singleton links are ordinary internal URLs, never synthetic database page IDs. */
|
|
21
|
+
function destinationLink(destination) {
|
|
22
|
+
if (destination.kind === "curated") return {
|
|
23
|
+
type: "page",
|
|
24
|
+
pageId: String(destination.pageId)
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
type: "external",
|
|
28
|
+
href: destination.fullPath
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function destinationTextLink(destination) {
|
|
32
|
+
if (destination.kind === "curated") return createPageTextLinkTarget(destination.pageId);
|
|
33
|
+
return destination.fullPath;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { destinationLink, destinationTextLink, getPageDestinations };
|
|
@@ -2,20 +2,21 @@ import { transformImageUrl } from "../../../core/lib/imageTransform.js";
|
|
|
2
2
|
import { cn } from "../../../lib/utils.js";
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { FileIcon } from "lucide-react";
|
|
5
|
+
import { FileIcon, Play } from "lucide-react";
|
|
6
6
|
|
|
7
7
|
//#region src/features/content/components/AssetCard.tsx
|
|
8
8
|
const OPAQUE_IMAGE_MIME_TYPES = new Set(["image/jpeg", "image/jpg"]);
|
|
9
9
|
const AssetCard = (t0) => {
|
|
10
|
-
const $ = c(
|
|
11
|
-
if ($[0] !== "
|
|
12
|
-
for (let $i = 0; $i <
|
|
13
|
-
$[0] = "
|
|
10
|
+
const $ = c(50);
|
|
11
|
+
if ($[0] !== "9aebb85bb22fc4b24c35af733cd21a00df48ad736a0749a2028271c210f9e9e9") {
|
|
12
|
+
for (let $i = 0; $i < 50; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
13
|
+
$[0] = "9aebb85bb22fc4b24c35af733cd21a00df48ad736a0749a2028271c210f9e9e9";
|
|
14
14
|
}
|
|
15
15
|
const { file, selected, onSelect, onOpen } = t0;
|
|
16
16
|
let extension;
|
|
17
17
|
let isImage;
|
|
18
18
|
let isOpaqueImage;
|
|
19
|
+
let isVideo;
|
|
19
20
|
let t1;
|
|
20
21
|
let t2;
|
|
21
22
|
let t3;
|
|
@@ -24,38 +25,45 @@ const AssetCard = (t0) => {
|
|
|
24
25
|
let t6;
|
|
25
26
|
if ($[1] !== file.filename || $[2] !== file.id || $[3] !== file.mimeType || $[4] !== onOpen || $[5] !== onSelect || $[6] !== selected) {
|
|
26
27
|
isImage = file.mimeType?.startsWith("image/");
|
|
27
|
-
isOpaqueImage = isImage && OPAQUE_IMAGE_MIME_TYPES.has(file.mimeType ?? "");
|
|
28
28
|
let t7;
|
|
29
|
-
if ($[
|
|
30
|
-
t7 = file.
|
|
31
|
-
$[
|
|
32
|
-
$[
|
|
33
|
-
} else t7 = $[
|
|
34
|
-
|
|
29
|
+
if ($[17] !== file.mimeType) {
|
|
30
|
+
t7 = file.mimeType?.startsWith("video/");
|
|
31
|
+
$[17] = file.mimeType;
|
|
32
|
+
$[18] = t7;
|
|
33
|
+
} else t7 = $[18];
|
|
34
|
+
isVideo = t7;
|
|
35
|
+
isOpaqueImage = isImage && OPAQUE_IMAGE_MIME_TYPES.has(file.mimeType ?? "");
|
|
36
|
+
let t8;
|
|
37
|
+
if ($[19] !== file.filename) {
|
|
38
|
+
t8 = file.filename?.split(".").pop()?.toUpperCase() ?? "";
|
|
39
|
+
$[19] = file.filename;
|
|
40
|
+
$[20] = t8;
|
|
41
|
+
} else t8 = $[20];
|
|
42
|
+
extension = t8;
|
|
35
43
|
t2 = "button";
|
|
36
44
|
t3 = file.id;
|
|
37
|
-
const
|
|
38
|
-
if ($[
|
|
39
|
-
t4 = cn("group flex flex-col gap-1.5 rounded-lg p-2 text-left border-2 border-transparent",
|
|
40
|
-
$[
|
|
41
|
-
$[
|
|
42
|
-
} else t4 = $[
|
|
43
|
-
if ($[
|
|
45
|
+
const t9 = selected ? "bg-primary/20 border-2 border-primary" : "hover:bg-accent/75";
|
|
46
|
+
if ($[21] !== t9) {
|
|
47
|
+
t4 = cn("group flex flex-col gap-1.5 rounded-lg p-2 text-left border-2 border-transparent", t9);
|
|
48
|
+
$[21] = t9;
|
|
49
|
+
$[22] = t4;
|
|
50
|
+
} else t4 = $[22];
|
|
51
|
+
if ($[23] !== onSelect) {
|
|
44
52
|
t5 = (e) => {
|
|
45
53
|
e.stopPropagation();
|
|
46
54
|
onSelect();
|
|
47
55
|
};
|
|
48
|
-
$[
|
|
49
|
-
$[
|
|
50
|
-
} else t5 = $[
|
|
51
|
-
if ($[
|
|
56
|
+
$[23] = onSelect;
|
|
57
|
+
$[24] = t5;
|
|
58
|
+
} else t5 = $[24];
|
|
59
|
+
if ($[25] !== onOpen) {
|
|
52
60
|
t6 = (e_0) => {
|
|
53
61
|
e_0.stopPropagation();
|
|
54
62
|
onOpen();
|
|
55
63
|
};
|
|
56
|
-
$[
|
|
57
|
-
$[
|
|
58
|
-
} else t6 = $[
|
|
64
|
+
$[25] = onOpen;
|
|
65
|
+
$[26] = t6;
|
|
66
|
+
} else t6 = $[26];
|
|
59
67
|
t1 = cn("flex aspect-4/3 w-full items-center justify-center overflow-hidden rounded-sm", isOpaqueImage && "bg-muted", !isImage && "bg-muted", isImage && !isOpaqueImage && "checkered p-1.5");
|
|
60
68
|
$[1] = file.filename;
|
|
61
69
|
$[2] = file.id;
|
|
@@ -66,25 +74,27 @@ const AssetCard = (t0) => {
|
|
|
66
74
|
$[7] = extension;
|
|
67
75
|
$[8] = isImage;
|
|
68
76
|
$[9] = isOpaqueImage;
|
|
69
|
-
$[10] =
|
|
70
|
-
$[11] =
|
|
71
|
-
$[12] =
|
|
72
|
-
$[13] =
|
|
73
|
-
$[14] =
|
|
74
|
-
$[15] =
|
|
77
|
+
$[10] = isVideo;
|
|
78
|
+
$[11] = t1;
|
|
79
|
+
$[12] = t2;
|
|
80
|
+
$[13] = t3;
|
|
81
|
+
$[14] = t4;
|
|
82
|
+
$[15] = t5;
|
|
83
|
+
$[16] = t6;
|
|
75
84
|
} else {
|
|
76
85
|
extension = $[7];
|
|
77
86
|
isImage = $[8];
|
|
78
87
|
isOpaqueImage = $[9];
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
isVideo = $[10];
|
|
89
|
+
t1 = $[11];
|
|
90
|
+
t2 = $[12];
|
|
91
|
+
t3 = $[13];
|
|
92
|
+
t4 = $[14];
|
|
93
|
+
t5 = $[15];
|
|
94
|
+
t6 = $[16];
|
|
85
95
|
}
|
|
86
96
|
let t7;
|
|
87
|
-
if ($[
|
|
97
|
+
if ($[27] !== extension || $[28] !== file.alt || $[29] !== file.filename || $[30] !== file.mimeType || $[31] !== file.size || $[32] !== file.url || $[33] !== isImage || $[34] !== isOpaqueImage || $[35] !== isVideo) {
|
|
88
98
|
t7 = isImage ? /* @__PURE__ */ jsx("img", {
|
|
89
99
|
src: transformImageUrl(file.url, {
|
|
90
100
|
width: 480,
|
|
@@ -94,6 +104,27 @@ const AssetCard = (t0) => {
|
|
|
94
104
|
alt: file.alt || file.filename,
|
|
95
105
|
draggable: false,
|
|
96
106
|
className: cn("pointer-events-none h-full w-full", isOpaqueImage ? "object-cover" : "object-contain")
|
|
107
|
+
}) : isVideo ? /* @__PURE__ */ jsxs("div", {
|
|
108
|
+
className: "pointer-events-none relative h-full w-full",
|
|
109
|
+
children: [/* @__PURE__ */ jsx("video", {
|
|
110
|
+
src: file.url,
|
|
111
|
+
muted: true,
|
|
112
|
+
playsInline: true,
|
|
113
|
+
preload: "metadata",
|
|
114
|
+
"aria-hidden": "true",
|
|
115
|
+
className: "h-full w-full object-cover",
|
|
116
|
+
onLoadedMetadata: _temp
|
|
117
|
+
}, file.url), /* @__PURE__ */ jsx("span", {
|
|
118
|
+
className: "absolute inset-0 flex items-center justify-center",
|
|
119
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
120
|
+
className: "rounded-full bg-black/50 p-2 text-white",
|
|
121
|
+
children: /* @__PURE__ */ jsx(Play, {
|
|
122
|
+
className: "h-5 w-5",
|
|
123
|
+
fill: "currentColor",
|
|
124
|
+
"aria-hidden": "true"
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
})]
|
|
97
128
|
}) : /* @__PURE__ */ jsxs("div", {
|
|
98
129
|
className: "text-muted-foreground flex flex-col items-center gap-1",
|
|
99
130
|
children: [/* @__PURE__ */ jsx(FileIcon, { className: "h-8 w-8" }), extension && /* @__PURE__ */ jsx("span", {
|
|
@@ -101,37 +132,38 @@ const AssetCard = (t0) => {
|
|
|
101
132
|
children: extension
|
|
102
133
|
})]
|
|
103
134
|
});
|
|
104
|
-
$[
|
|
105
|
-
$[
|
|
106
|
-
$[
|
|
107
|
-
$[
|
|
108
|
-
$[
|
|
109
|
-
$[
|
|
110
|
-
$[
|
|
111
|
-
$[
|
|
112
|
-
$[
|
|
113
|
-
|
|
135
|
+
$[27] = extension;
|
|
136
|
+
$[28] = file.alt;
|
|
137
|
+
$[29] = file.filename;
|
|
138
|
+
$[30] = file.mimeType;
|
|
139
|
+
$[31] = file.size;
|
|
140
|
+
$[32] = file.url;
|
|
141
|
+
$[33] = isImage;
|
|
142
|
+
$[34] = isOpaqueImage;
|
|
143
|
+
$[35] = isVideo;
|
|
144
|
+
$[36] = t7;
|
|
145
|
+
} else t7 = $[36];
|
|
114
146
|
let t8;
|
|
115
|
-
if ($[
|
|
147
|
+
if ($[37] !== t1 || $[38] !== t7) {
|
|
116
148
|
t8 = /* @__PURE__ */ jsx("div", {
|
|
117
149
|
className: t1,
|
|
118
150
|
children: t7
|
|
119
151
|
});
|
|
120
|
-
$[
|
|
121
|
-
$[
|
|
122
|
-
$[
|
|
123
|
-
} else t8 = $[
|
|
152
|
+
$[37] = t1;
|
|
153
|
+
$[38] = t7;
|
|
154
|
+
$[39] = t8;
|
|
155
|
+
} else t8 = $[39];
|
|
124
156
|
let t9;
|
|
125
|
-
if ($[
|
|
157
|
+
if ($[40] !== file.filename) {
|
|
126
158
|
t9 = /* @__PURE__ */ jsx("p", {
|
|
127
159
|
className: "line-clamp-2 px-0.5 text-xs break-all",
|
|
128
160
|
children: file.filename
|
|
129
161
|
});
|
|
130
|
-
$[
|
|
131
|
-
$[
|
|
132
|
-
} else t9 = $[
|
|
162
|
+
$[40] = file.filename;
|
|
163
|
+
$[41] = t9;
|
|
164
|
+
} else t9 = $[41];
|
|
133
165
|
let t10;
|
|
134
|
-
if ($[
|
|
166
|
+
if ($[42] !== t2 || $[43] !== t3 || $[44] !== t4 || $[45] !== t5 || $[46] !== t6 || $[47] !== t8 || $[48] !== t9) {
|
|
135
167
|
t10 = /* @__PURE__ */ jsxs("button", {
|
|
136
168
|
type: t2,
|
|
137
169
|
"data-asset-id": t3,
|
|
@@ -140,17 +172,21 @@ const AssetCard = (t0) => {
|
|
|
140
172
|
onDoubleClick: t6,
|
|
141
173
|
children: [t8, t9]
|
|
142
174
|
});
|
|
143
|
-
$[
|
|
144
|
-
$[
|
|
145
|
-
$[
|
|
146
|
-
$[
|
|
147
|
-
$[
|
|
148
|
-
$[
|
|
149
|
-
$[
|
|
150
|
-
$[
|
|
151
|
-
} else t10 = $[
|
|
175
|
+
$[42] = t2;
|
|
176
|
+
$[43] = t3;
|
|
177
|
+
$[44] = t4;
|
|
178
|
+
$[45] = t5;
|
|
179
|
+
$[46] = t6;
|
|
180
|
+
$[47] = t8;
|
|
181
|
+
$[48] = t9;
|
|
182
|
+
$[49] = t10;
|
|
183
|
+
} else t10 = $[49];
|
|
152
184
|
return t10;
|
|
153
185
|
};
|
|
186
|
+
function _temp(event) {
|
|
187
|
+
const video = event.currentTarget;
|
|
188
|
+
if (Number.isFinite(video.duration) && video.duration > 0) video.currentTime = Math.min(.1, video.duration / 2);
|
|
189
|
+
}
|
|
154
190
|
|
|
155
191
|
//#endregion
|
|
156
192
|
export { AssetCard };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_FONTS } from "./defaultFonts.js";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
2
|
import { ImageResponse as ImageResponse$1 } from "@takumi-rs/image-response/wasm";
|
|
3
|
+
import wasmModule from "@takumi-rs/wasm/next";
|
|
5
4
|
import { Renderer, initSync } from "@takumi-rs/wasm/no-bundler";
|
|
6
5
|
|
|
7
6
|
//#region src/features/og/imageResponse.node.ts
|
|
@@ -14,12 +13,10 @@ import { Renderer, initSync } from "@takumi-rs/wasm/no-bundler";
|
|
|
14
13
|
* about which engine to use any more — it's only about *how* the wasm module
|
|
15
14
|
* gets loaded:
|
|
16
15
|
*
|
|
17
|
-
* - Here, we
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* once the package is externalised by Nitro/Vite — so we go through the
|
|
22
|
-
* `no-bundler` entry directly.
|
|
16
|
+
* - Here, we import the wasm module and `initSync` it ourselves before
|
|
17
|
+
* constructing a `Renderer`. The static `?module` import lets Nitro emit
|
|
18
|
+
* the asset into the deployment instead of relying on a runtime
|
|
19
|
+
* `require.resolve` that dependency tracing cannot reliably discover.
|
|
23
20
|
*
|
|
24
21
|
* - In `imageResponse.workerd.ts` there's no filesystem; instead we pass a
|
|
25
22
|
* `WebAssembly.Module` reference via `?module` import and let the
|
|
@@ -28,7 +25,12 @@ import { Renderer, initSync } from "@takumi-rs/wasm/no-bundler";
|
|
|
28
25
|
* We use the BYO-renderer path of `@takumi-rs/image-response/wasm` so the
|
|
29
26
|
* `module:` option isn't needed here — the renderer is already alive.
|
|
30
27
|
*/
|
|
31
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Resolve and initialise the wasm module once at module load. `initSync`
|
|
30
|
+
* compiles the wasm and wires up the JS bindings; subsequent `new Renderer()`
|
|
31
|
+
* calls are cheap.
|
|
32
|
+
*/
|
|
33
|
+
initSync({ module: wasmModule });
|
|
32
34
|
/**
|
|
33
35
|
* Module-scoped singleton — building the renderer compiles the wasm module
|
|
34
36
|
* and loads Geist; not free, and there's no reason to do it per request.
|