@ai-matrx/code-runtime 0.1.4
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 +50 -0
- package/LICENSE +21 -0
- package/README.md +31 -0
- package/dist/execute.cjs +890 -0
- package/dist/execute.cjs.map +1 -0
- package/dist/execute.d.cts +11 -0
- package/dist/execute.d.ts +11 -0
- package/dist/execute.js +858 -0
- package/dist/execute.js.map +1 -0
- package/dist/gate-lists.json +105 -0
- package/dist/gate.cjs +291 -0
- package/dist/gate.cjs.map +1 -0
- package/dist/gate.d.cts +49 -0
- package/dist/gate.d.ts +49 -0
- package/dist/gate.js +268 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.cjs +1196 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +87 -0
- package/dist/index.d.ts +87 -0
- package/dist/index.js +1164 -0
- package/dist/index.js.map +1 -0
- package/dist/scope-lrQkC0jP.d.cts +205 -0
- package/dist/scope-lrQkC0jP.d.ts +205 -0
- package/dist/scope.cjs +597 -0
- package/dist/scope.cjs.map +1 -0
- package/dist/scope.d.cts +2 -0
- package/dist/scope.d.ts +2 -0
- package/dist/scope.js +565 -0
- package/dist/scope.js.map +1 -0
- package/dist/transform.cjs +140 -0
- package/dist/transform.cjs.map +1 -0
- package/dist/transform.d.cts +12 -0
- package/dist/transform.d.ts +12 -0
- package/dist/transform.js +117 -0
- package/dist/transform.js.map +1 -0
- package/dist/types-DL6oTcV_.d.cts +50 -0
- package/dist/types-DL6oTcV_.d.ts +50 -0
- package/package.json +137 -0
package/dist/execute.js
ADDED
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/gate-lists.json
|
|
4
|
+
var gate_lists_default = {
|
|
5
|
+
_comment: [
|
|
6
|
+
"CANONICAL, MACHINE-READABLE source-gate lists for stored code compiled by @ai-matrx/code-runtime.",
|
|
7
|
+
"ONE list per rule, sorted, byte-comparable across runtimes. Three guards keep the copies honest:",
|
|
8
|
+
" - src/gate.test.ts asserts allowedImports equals listScopeEntryPaths() sorted",
|
|
9
|
+
" (the documented scope registry is the truth);",
|
|
10
|
+
" - aidream packages/matrx-ai/tests/test_component_source_gate_parity.py asserts the Python",
|
|
11
|
+
" twins in kind_shared.py equal these arrays;",
|
|
12
|
+
" - the database trigger's parity test asserts the trigger names every entry of every",
|
|
13
|
+
" security list below."
|
|
14
|
+
],
|
|
15
|
+
allowedImports: [
|
|
16
|
+
"@/applets",
|
|
17
|
+
"@/components/Markdown",
|
|
18
|
+
"@/components/MarkdownStream",
|
|
19
|
+
"@/components/agent-copy/CopyButtons",
|
|
20
|
+
"@/components/agent-copy/CopyForAiButton",
|
|
21
|
+
"@/components/kind-kit/KindHeaderBar",
|
|
22
|
+
"@/components/kind-kit/KindPanel",
|
|
23
|
+
"@/components/kind-kit/KindPanelGrid",
|
|
24
|
+
"@/components/kind-kit/SortableList",
|
|
25
|
+
"@/components/kind-kit/StreamingSkeleton",
|
|
26
|
+
"@/components/kind-kit/TagList",
|
|
27
|
+
"@/components/mardown",
|
|
28
|
+
"@/components/markdown",
|
|
29
|
+
"@/components/official/icons/IconResolver",
|
|
30
|
+
"@/components/ui/accordion",
|
|
31
|
+
"@/components/ui/alert",
|
|
32
|
+
"@/components/ui/avatar",
|
|
33
|
+
"@/components/ui/badge",
|
|
34
|
+
"@/components/ui/button",
|
|
35
|
+
"@/components/ui/card",
|
|
36
|
+
"@/components/ui/checkbox",
|
|
37
|
+
"@/components/ui/collapsible",
|
|
38
|
+
"@/components/ui/dialog",
|
|
39
|
+
"@/components/ui/dropdown-menu",
|
|
40
|
+
"@/components/ui/input",
|
|
41
|
+
"@/components/ui/label",
|
|
42
|
+
"@/components/ui/popover",
|
|
43
|
+
"@/components/ui/progress",
|
|
44
|
+
"@/components/ui/radio-group",
|
|
45
|
+
"@/components/ui/scroll-area",
|
|
46
|
+
"@/components/ui/select",
|
|
47
|
+
"@/components/ui/separator",
|
|
48
|
+
"@/components/ui/sheet",
|
|
49
|
+
"@/components/ui/skeleton",
|
|
50
|
+
"@/components/ui/slider",
|
|
51
|
+
"@/components/ui/switch",
|
|
52
|
+
"@/components/ui/table",
|
|
53
|
+
"@/components/ui/tabs",
|
|
54
|
+
"@/components/ui/textarea",
|
|
55
|
+
"@/components/ui/tooltip",
|
|
56
|
+
"@/lib/utils",
|
|
57
|
+
"@ai-matrx/applets/react",
|
|
58
|
+
"@ai-matrx/design-system",
|
|
59
|
+
"@ai-matrx/design-system/controls",
|
|
60
|
+
"@ai-matrx/icons",
|
|
61
|
+
"@react-three/fiber",
|
|
62
|
+
"date-fns",
|
|
63
|
+
"lodash",
|
|
64
|
+
"lucide-react",
|
|
65
|
+
"motion/react",
|
|
66
|
+
"react",
|
|
67
|
+
"react-katex",
|
|
68
|
+
"react-pdf",
|
|
69
|
+
"recharts",
|
|
70
|
+
"three",
|
|
71
|
+
"xlsx"
|
|
72
|
+
],
|
|
73
|
+
bannedGlobals: [
|
|
74
|
+
"EventSource",
|
|
75
|
+
"WebSocket",
|
|
76
|
+
"XMLHttpRequest",
|
|
77
|
+
"fetch",
|
|
78
|
+
"importScripts",
|
|
79
|
+
"localStorage",
|
|
80
|
+
"sessionStorage"
|
|
81
|
+
],
|
|
82
|
+
bannedCallables: [
|
|
83
|
+
"Function",
|
|
84
|
+
"eval"
|
|
85
|
+
],
|
|
86
|
+
bannedMemberAccess: [
|
|
87
|
+
"EventSource",
|
|
88
|
+
"Function",
|
|
89
|
+
"WebSocket",
|
|
90
|
+
"XMLHttpRequest",
|
|
91
|
+
"cookie",
|
|
92
|
+
"eval",
|
|
93
|
+
"fetch",
|
|
94
|
+
"importScripts",
|
|
95
|
+
"sendBeacon"
|
|
96
|
+
],
|
|
97
|
+
bannedMemberCalls: [
|
|
98
|
+
"constructor"
|
|
99
|
+
],
|
|
100
|
+
bannedComputedAccess: [
|
|
101
|
+
"globalThis",
|
|
102
|
+
"self",
|
|
103
|
+
"window"
|
|
104
|
+
],
|
|
105
|
+
bannedSyntax: [
|
|
106
|
+
"dynamicImport"
|
|
107
|
+
]
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/gate.ts
|
|
111
|
+
var GATE_ALLOWED_IMPORTS = gate_lists_default.allowedImports;
|
|
112
|
+
var GATE_BANNED_GLOBALS = gate_lists_default.bannedGlobals;
|
|
113
|
+
var GATE_BANNED_CALLABLES = gate_lists_default.bannedCallables;
|
|
114
|
+
var GATE_BANNED_MEMBER_ACCESS = gate_lists_default.bannedMemberAccess;
|
|
115
|
+
var GATE_BANNED_MEMBER_CALLS = gate_lists_default.bannedMemberCalls;
|
|
116
|
+
var GATE_BANNED_COMPUTED_ACCESS = gate_lists_default.bannedComputedAccess;
|
|
117
|
+
var GATE_BANNED_SYNTAX = gate_lists_default.bannedSyntax;
|
|
118
|
+
function resolveRelativePath(fromFile, specifier) {
|
|
119
|
+
const base = fromFile.split("/").slice(0, -1);
|
|
120
|
+
for (const part of specifier.split("/")) {
|
|
121
|
+
if (part === "" || part === ".") continue;
|
|
122
|
+
if (part === "..") base.pop();
|
|
123
|
+
else base.push(part);
|
|
124
|
+
}
|
|
125
|
+
return base.join("/");
|
|
126
|
+
}
|
|
127
|
+
var RESOLVE_SUFFIXES = ["", ".tsx", ".ts", ".jsx", ".js", ".json", "/index.tsx", "/index.ts", "/index.jsx", "/index.js"];
|
|
128
|
+
function resolveRelativeFile(files, fromFile, specifier) {
|
|
129
|
+
const target = resolveRelativePath(fromFile, specifier);
|
|
130
|
+
for (const suffix of RESOLVE_SUFFIXES) {
|
|
131
|
+
const candidate = `${target}${suffix}`;
|
|
132
|
+
if (Object.prototype.hasOwnProperty.call(files, candidate)) return candidate;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/scope/entries.ts
|
|
138
|
+
var REACT_EXPORTS = [
|
|
139
|
+
"useState",
|
|
140
|
+
"useEffect",
|
|
141
|
+
"useMemo",
|
|
142
|
+
"useCallback",
|
|
143
|
+
"useRef",
|
|
144
|
+
"useReducer",
|
|
145
|
+
"useContext",
|
|
146
|
+
"useId",
|
|
147
|
+
"useTransition",
|
|
148
|
+
"useDeferredValue",
|
|
149
|
+
"useLayoutEffect",
|
|
150
|
+
"Fragment"
|
|
151
|
+
];
|
|
152
|
+
function ui(name, exports, description) {
|
|
153
|
+
return { path: `@/components/ui/${name}`, strategy: "named", exports, core: true, owner: "package", description };
|
|
154
|
+
}
|
|
155
|
+
function markdownAlias(path, description) {
|
|
156
|
+
return { path, strategy: "named", exportMap: { default: "MarkdownStream" }, core: true, owner: "host", description };
|
|
157
|
+
}
|
|
158
|
+
function kindKit(name, exports, description) {
|
|
159
|
+
return { path: `@/components/kind-kit/${name}`, strategy: "named", exports, owner: "host", description };
|
|
160
|
+
}
|
|
161
|
+
var SCOPE_ENTRIES = [
|
|
162
|
+
// ── Core ─────────────────────────────────────────────────────────────────
|
|
163
|
+
{ path: "react", strategy: "named", exports: REACT_EXPORTS, exportMap: { default: "React" }, core: true, owner: "package", description: "React core (hooks, Fragment)" },
|
|
164
|
+
{ path: "lucide-react", strategy: "spread", safeProxy: true, core: true, owner: "package", description: "Lucide icons; a missing name renders a marked placeholder" },
|
|
165
|
+
{ path: "@ai-matrx/icons", strategy: "named", exports: ["DynamicIcon", "renderIcon", "getIconComponent"], core: true, owner: "package", description: "DynamicIcon: any icon by string name" },
|
|
166
|
+
{ path: "@/components/official/icons/IconResolver", strategy: "named", exports: ["DynamicIcon", "renderIcon", "getIconComponent"], core: true, owner: "package", description: "Legacy alias of @ai-matrx/icons" },
|
|
167
|
+
{ path: "@/lib/utils", strategy: "named", exports: ["cn"], core: true, owner: "package", description: "cn(): className merge" },
|
|
168
|
+
// ── The primary UI set ───────────────────────────────────────────────────
|
|
169
|
+
{ path: "@ai-matrx/design-system/controls", strategy: "spread", core: true, owner: "package", description: "THE controls: Button, Field, SearchField, Select, SegmentedControl, Tabs, Badge, Switch, Textarea, EmptyState\u2026" },
|
|
170
|
+
{ path: "@ai-matrx/design-system", strategy: "spread", owner: "package", description: "Design-system surfaces: Card, Dialog, Popover, Tooltip, Table, Accordion\u2026" },
|
|
171
|
+
// ── Copy actions ─────────────────────────────────────────────────────────
|
|
172
|
+
{ path: "@/components/agent-copy/CopyButtons", strategy: "named", exports: ["CopyButtons"], owner: "host", description: "Copy / Copy-for-AI / JSON / Export bar from caller-supplied builders" },
|
|
173
|
+
{ path: "@/components/agent-copy/CopyForAiButton", strategy: "named", exports: ["CopyForAiButton"], owner: "host", description: "Single Copy-for-AI action" },
|
|
174
|
+
// ── kind-kit ─────────────────────────────────────────────────────────────
|
|
175
|
+
kindKit("SortableList", ["SortableList"], "Drag-to-reorder list with arrow fallback and onRemove"),
|
|
176
|
+
kindKit("KindPanelGrid", ["KindPanelGrid"], "Content-aware auto-fit grid of equal-height panels"),
|
|
177
|
+
kindKit("KindPanel", ["KindPanel"], "Compact panel: header + overflow menu, subline, body, footer"),
|
|
178
|
+
kindKit("KindHeaderBar", ["KindHeaderBar"], "Kind title + stats + copy bar"),
|
|
179
|
+
kindKit("StreamingSkeleton", ["StreamingSkeleton", "useStreamingValue", "streamList", "streamText"], "Streaming skeletons + tolerant partial-value reads"),
|
|
180
|
+
kindKit("TagList", ["KeywordChip", "TagList"], "Wrapping chips with select, remove, inline edit, add"),
|
|
181
|
+
// ── Markdown (one renderer, four spellings stored code uses) ─────────────
|
|
182
|
+
markdownAlias("@/components/MarkdownStream", "MarkdownStream: the one markdown renderer"),
|
|
183
|
+
markdownAlias("@/components/Markdown", "MarkdownStream (legacy path)"),
|
|
184
|
+
markdownAlias("@/components/markdown", "MarkdownStream (lowercase path)"),
|
|
185
|
+
markdownAlias("@/components/mardown", "MarkdownStream (common misspelling)"),
|
|
186
|
+
// ── Legacy UI aliases (each = the design-system export the app re-exports) ─
|
|
187
|
+
ui("button", ["Button"], "Button"),
|
|
188
|
+
ui("input", ["Input"], "Input"),
|
|
189
|
+
ui("textarea", ["Textarea"], "Textarea"),
|
|
190
|
+
ui("card", ["Card", "CardAction", "CardContent", "CardDescription", "CardFooter", "CardHeader", "CardTitle"], "Card family"),
|
|
191
|
+
ui("label", ["Label"], "Label"),
|
|
192
|
+
ui("select", ["Select", "SelectContent", "SelectGroup", "SelectItem", "SelectLabel", "SelectScrollDownButton", "SelectScrollUpButton", "SelectSeparator", "SelectValue", "selectTriggerVariants", "SelectTrigger", "SelectTriggerLegacy"], "Select family"),
|
|
193
|
+
ui("slider", ["Slider"], "Slider"),
|
|
194
|
+
ui("switch", ["Switch"], "Switch"),
|
|
195
|
+
ui("tabs", ["Tabs", "TabsContent", "TabsList", "TabsTrigger", "TabsTriggerCore", "TabsListLegacy", "TabsTriggerLegacy", "TabsTriggerCoreLegacy"], "Tabs family"),
|
|
196
|
+
ui("badge", ["Badge"], "Badge"),
|
|
197
|
+
ui("tooltip", ["Tooltip", "TooltipContent", "TooltipProvider", "TooltipTrigger"], "Tooltip family"),
|
|
198
|
+
ui("accordion", ["Accordion", "AccordionContent", "AccordionItem", "AccordionTrigger", "useAccordionSize"], "Accordion family"),
|
|
199
|
+
ui("collapsible", ["Collapsible", "CollapsibleContent", "CollapsibleTrigger"], "Collapsible family"),
|
|
200
|
+
ui("progress", ["Progress"], "Progress bar"),
|
|
201
|
+
ui("separator", ["Separator"], "Separator"),
|
|
202
|
+
ui("scroll-area", ["ScrollArea", "ScrollBar"], "ScrollArea"),
|
|
203
|
+
ui("dialog", ["Dialog", "DialogClose", "DialogContent", "DialogContentPrimitive", "DialogDescription", "DialogFooter", "DialogHeader", "DialogOverlay", "DialogPortal", "DialogTitle", "DialogTrigger", "useDialogContainer"], "Dialog family"),
|
|
204
|
+
ui("sheet", ["Sheet", "SheetPortal", "SheetOverlay", "SheetTrigger", "SheetClose", "SheetContent", "SheetHeader", "SheetFooter", "SheetTitle", "SheetDescription"], "Sheet family"),
|
|
205
|
+
ui("dropdown-menu", ["DropdownMenu", "DropdownMenuCheckboxItem", "DropdownMenuContent", "DropdownMenuGroup", "DropdownMenuItem", "DropdownMenuLabel", "DropdownMenuPortal", "DropdownMenuRadioGroup", "DropdownMenuRadioItem", "DropdownMenuSeparator", "DropdownMenuShortcut", "DropdownMenuSub", "DropdownMenuSubContent", "DropdownMenuSubTrigger", "DropdownMenuTrigger"], "Dropdown menu family"),
|
|
206
|
+
ui("table", ["Table", "TableBody", "TableCaption", "TableCell", "TableFooter", "TableHead", "TableHeader", "TableRow"], "Table family"),
|
|
207
|
+
ui("checkbox", ["Checkbox"], "Checkbox"),
|
|
208
|
+
ui("radio-group", ["RadioGroup", "RadioGroupItem"], "Radio group"),
|
|
209
|
+
ui("popover", ["Popover", "PopoverTrigger", "PopoverContent", "PopoverAnchor"], "Popover family"),
|
|
210
|
+
ui("avatar", ["Avatar", "AvatarFallback", "AvatarImage"], "Avatar family"),
|
|
211
|
+
ui("alert", ["Alert", "AlertDescription", "AlertTitle", "alertVariants"], "Alert family"),
|
|
212
|
+
ui("skeleton", ["Skeleton"], "Skeleton"),
|
|
213
|
+
// ── Applet parts ─────────────────────────────────────────────────────────
|
|
214
|
+
{ path: "@/applets", strategy: "named", exports: ["DataPage", "Applet"], owner: "host", description: "A table-built page and a nested Applet (legacy path; becomes @ai-matrx/applets/react)" },
|
|
215
|
+
{ path: "@ai-matrx/applets/react", strategy: "spread", owner: "host", description: "The Applet hooks: useRows, useJob, useValue, useAction, <Kind>, <Pages>, navigate\u2026" },
|
|
216
|
+
// ── Heavy libraries (loaded only when referenced) ────────────────────────
|
|
217
|
+
{ path: "recharts", strategy: "spread", owner: "package", provides: ["ResponsiveContainer", "LineChart", "BarChart", "AreaChart", "PieChart", "RadarChart", "ScatterChart", "ComposedChart", "RadialBarChart"], description: "Charts (recharts)" },
|
|
218
|
+
{ path: "motion/react", strategy: "spread", owner: "host", provides: ["motion", "AnimatePresence", "useAnimate", "useInView"], description: "Animation (motion)" },
|
|
219
|
+
{ path: "react-katex", strategy: "spread", owner: "host", provides: ["BlockMath", "InlineMath"], description: "Math typesetting (KaTeX)" },
|
|
220
|
+
{ path: "react-pdf", strategy: "named", exports: ["Document", "Page", "Outline"], owner: "host", provides: ["Document", "Page", "Outline"], description: "PDF viewing (react-pdf)" },
|
|
221
|
+
{ path: "xlsx", strategy: "namespace", namespaceName: "XLSX", owner: "host", provides: ["XLSX"], description: "Workbooks (xlsx)" },
|
|
222
|
+
{ path: "@react-three/fiber", strategy: "spread", owner: "host", provides: ["Canvas", "useFrame", "useThree", "useLoader"], description: "3D React renderer" },
|
|
223
|
+
{ path: "three", strategy: "namespace", namespaceName: "THREE", owner: "host", provides: ["THREE"], description: "3D engine (three.js)" },
|
|
224
|
+
{ path: "date-fns", strategy: "namespace", namespaceName: "dateFns", owner: "host", provides: ["dateFns"], description: "Date utilities (date-fns)" },
|
|
225
|
+
{ path: "lodash", strategy: "namespace", namespaceName: "_", owner: "host", provides: ["_"], description: "Utility helpers (lodash)" }
|
|
226
|
+
];
|
|
227
|
+
var BY_PATH = new Map(SCOPE_ENTRIES.map((e) => [e.path, e]));
|
|
228
|
+
function getScopeEntry(path) {
|
|
229
|
+
return BY_PATH.get(path);
|
|
230
|
+
}
|
|
231
|
+
function listScopeEntryPaths() {
|
|
232
|
+
return SCOPE_ENTRIES.map((e) => e.path);
|
|
233
|
+
}
|
|
234
|
+
function listScopeEntries() {
|
|
235
|
+
return SCOPE_ENTRIES;
|
|
236
|
+
}
|
|
237
|
+
function defaultComponentEntries() {
|
|
238
|
+
return SCOPE_ENTRIES.filter((e) => !e.provides || e.path === "recharts").map((e) => e.path);
|
|
239
|
+
}
|
|
240
|
+
function coreEntryPaths() {
|
|
241
|
+
return SCOPE_ENTRIES.filter((e) => e.core).map((e) => e.path);
|
|
242
|
+
}
|
|
243
|
+
function detectEntries(files) {
|
|
244
|
+
const needed = new Set(coreEntryPaths());
|
|
245
|
+
const code = Object.values(files).join("\n");
|
|
246
|
+
const imported = /* @__PURE__ */ new Set();
|
|
247
|
+
for (const m of code.matchAll(/from\s+['"]([^'"]+)['"]/g)) if (m[1]) imported.add(m[1]);
|
|
248
|
+
for (const entry of SCOPE_ENTRIES) {
|
|
249
|
+
if (entry.core) continue;
|
|
250
|
+
if (imported.has(entry.path)) needed.add(entry.path);
|
|
251
|
+
else if (entry.provides?.some((id) => new RegExp(`(?<![\\w$.])${id.replace(/[$]/g, "\\$")}\\b`).test(code))) {
|
|
252
|
+
needed.add(entry.path);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return SCOPE_ENTRIES.map((e) => e.path).filter((p) => needed.has(p));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// src/scope/build.ts
|
|
259
|
+
import * as ReactModule2 from "react";
|
|
260
|
+
|
|
261
|
+
// src/scope/modules.ts
|
|
262
|
+
import * as ReactModule from "react";
|
|
263
|
+
import * as LucideModule from "lucide-react";
|
|
264
|
+
import * as IconsModule from "@ai-matrx/icons";
|
|
265
|
+
import * as DesignSystem from "@ai-matrx/design-system";
|
|
266
|
+
import * as Controls from "@ai-matrx/design-system/controls";
|
|
267
|
+
var STORE_KEY = /* @__PURE__ */ Symbol.for("ai-matrx.code-runtime.modules");
|
|
268
|
+
function store() {
|
|
269
|
+
const g = globalThis;
|
|
270
|
+
let s = g[STORE_KEY];
|
|
271
|
+
if (!s) {
|
|
272
|
+
s = { announced: /* @__PURE__ */ new Set(), provided: /* @__PURE__ */ new Map(), loaded: /* @__PURE__ */ new Map(), pending: /* @__PURE__ */ new Map(), failed: /* @__PURE__ */ new Map() };
|
|
273
|
+
g[STORE_KEY] = s;
|
|
274
|
+
}
|
|
275
|
+
return s;
|
|
276
|
+
}
|
|
277
|
+
var ds = DesignSystem;
|
|
278
|
+
var controls = Controls;
|
|
279
|
+
var LEGACY_UI_MODULE = {
|
|
280
|
+
...ds,
|
|
281
|
+
Button: controls.Button,
|
|
282
|
+
Textarea: controls.Textarea,
|
|
283
|
+
Switch: controls.Switch,
|
|
284
|
+
SelectTrigger: controls.SelectTrigger,
|
|
285
|
+
SelectTriggerLegacy: ds.SelectTrigger,
|
|
286
|
+
TabsList: controls.TabsList,
|
|
287
|
+
TabsTrigger: controls.TabsTrigger,
|
|
288
|
+
TabsListLegacy: ds.TabsList,
|
|
289
|
+
TabsTriggerLegacy: ds.TabsTrigger
|
|
290
|
+
};
|
|
291
|
+
function packageLoader(path) {
|
|
292
|
+
if (path === "react") return () => ReactModule;
|
|
293
|
+
if (path === "lucide-react") return () => LucideModule;
|
|
294
|
+
if (path === "@ai-matrx/icons" || path === "@/components/official/icons/IconResolver") return () => IconsModule;
|
|
295
|
+
if (path === "@ai-matrx/design-system") return () => DesignSystem;
|
|
296
|
+
if (path === "@ai-matrx/design-system/controls") return () => Controls;
|
|
297
|
+
if (path === "@/lib/utils") return () => ({ cn: ds.cn });
|
|
298
|
+
if (path.startsWith("@/components/ui/")) return () => LEGACY_UI_MODULE;
|
|
299
|
+
if (path === "recharts") return () => import("recharts");
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
function provideScopeModules(map) {
|
|
303
|
+
const s = store();
|
|
304
|
+
for (const [path, loader] of Object.entries(map)) {
|
|
305
|
+
if (!getScopeEntry(path)) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`[code-runtime] "${path}" is not a documented scope entry. Add it to the registry in @ai-matrx/code-runtime (scope/entries.ts) with a description first.`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
s.provided.set(path, loader);
|
|
311
|
+
s.loaded.delete(path);
|
|
312
|
+
s.pending.delete(path);
|
|
313
|
+
s.failed.delete(path);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function isPromiseLike(value) {
|
|
317
|
+
return !!value && typeof value.then === "function";
|
|
318
|
+
}
|
|
319
|
+
function loaderFor(path) {
|
|
320
|
+
return store().provided.get(path) ?? packageLoader(path);
|
|
321
|
+
}
|
|
322
|
+
function readScopeModule(path) {
|
|
323
|
+
const s = store();
|
|
324
|
+
if (s.loaded.has(path)) return { state: "ready", module: s.loaded.get(path) };
|
|
325
|
+
const failed = s.failed.get(path);
|
|
326
|
+
if (failed) return { state: "failed", message: failed };
|
|
327
|
+
if (s.pending.has(path)) return { state: "pending" };
|
|
328
|
+
const loader = loaderFor(path);
|
|
329
|
+
if (!loader) return { state: "missing" };
|
|
330
|
+
try {
|
|
331
|
+
const value = loader();
|
|
332
|
+
if (isPromiseLike(value)) {
|
|
333
|
+
const promise = Promise.resolve(value).then(
|
|
334
|
+
(mod) => {
|
|
335
|
+
s.loaded.set(path, mod);
|
|
336
|
+
s.pending.delete(path);
|
|
337
|
+
return mod;
|
|
338
|
+
},
|
|
339
|
+
(err) => {
|
|
340
|
+
s.failed.set(path, err instanceof Error ? err.message : String(err));
|
|
341
|
+
s.pending.delete(path);
|
|
342
|
+
return void 0;
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
s.pending.set(path, promise);
|
|
346
|
+
return { state: "pending" };
|
|
347
|
+
}
|
|
348
|
+
s.loaded.set(path, value);
|
|
349
|
+
return { state: "ready", module: value };
|
|
350
|
+
} catch (err) {
|
|
351
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
352
|
+
s.failed.set(path, message);
|
|
353
|
+
return { state: "failed", message };
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
async function prepareScopeModules(paths) {
|
|
357
|
+
const s = store();
|
|
358
|
+
for (const path of paths) readScopeModule(path);
|
|
359
|
+
await Promise.all(paths.map((p) => s.pending.get(p)).filter((p) => !!p));
|
|
360
|
+
}
|
|
361
|
+
function announceFailedModule(path, message) {
|
|
362
|
+
const s = store();
|
|
363
|
+
if (s.announced.has(path)) return;
|
|
364
|
+
s.announced.add(path);
|
|
365
|
+
console.error(`[code-runtime] The scope entry "${path}" failed to load (${message}); code that imports it renders marked placeholders.`);
|
|
366
|
+
}
|
|
367
|
+
function resetScopeModules() {
|
|
368
|
+
const s = store();
|
|
369
|
+
s.announced.clear();
|
|
370
|
+
s.provided.clear();
|
|
371
|
+
s.loaded.clear();
|
|
372
|
+
s.pending.clear();
|
|
373
|
+
s.failed.clear();
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/scope/stand-in.ts
|
|
377
|
+
import * as React from "react";
|
|
378
|
+
var UNRESOLVED_IMPORT_MARK = /* @__PURE__ */ Symbol.for("matrx.sandbox.unresolvedImport");
|
|
379
|
+
function readUnresolvedImportMark(value) {
|
|
380
|
+
if (!value || typeof value !== "object" && typeof value !== "function") return null;
|
|
381
|
+
const mark = value[UNRESOLVED_IMPORT_MARK];
|
|
382
|
+
return mark && typeof mark === "object" ? mark : null;
|
|
383
|
+
}
|
|
384
|
+
function createUnresolvedImportStandIn(identifier, importPath = null) {
|
|
385
|
+
const tip = importPath ? `Not found: ${identifier} in "${importPath}"` : `Not found: ${identifier}`;
|
|
386
|
+
const StandIn = React.forwardRef(({ children }, ref) => {
|
|
387
|
+
const chip = React.createElement(
|
|
388
|
+
"span",
|
|
389
|
+
{
|
|
390
|
+
ref,
|
|
391
|
+
title: tip,
|
|
392
|
+
"aria-label": tip,
|
|
393
|
+
role: "note",
|
|
394
|
+
"data-unresolved-import": identifier,
|
|
395
|
+
"data-import-path": importPath ?? void 0,
|
|
396
|
+
className: "inline-flex items-center gap-0.5 rounded border border-dashed border-destructive/60 px-1 align-middle font-mono text-[10px] leading-4 text-destructive"
|
|
397
|
+
},
|
|
398
|
+
React.createElement(
|
|
399
|
+
"svg",
|
|
400
|
+
{
|
|
401
|
+
width: 10,
|
|
402
|
+
height: 10,
|
|
403
|
+
viewBox: "0 0 24 24",
|
|
404
|
+
fill: "none",
|
|
405
|
+
stroke: "currentColor",
|
|
406
|
+
strokeWidth: 2.5,
|
|
407
|
+
strokeLinecap: "round",
|
|
408
|
+
strokeLinejoin: "round",
|
|
409
|
+
"aria-hidden": true
|
|
410
|
+
},
|
|
411
|
+
React.createElement("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
|
|
412
|
+
React.createElement("line", { x1: 12, y1: 9, x2: 12, y2: 13 }),
|
|
413
|
+
React.createElement("line", { x1: 12, y1: 17, x2: 12.01, y2: 17 })
|
|
414
|
+
),
|
|
415
|
+
identifier
|
|
416
|
+
);
|
|
417
|
+
return children == null ? chip : React.createElement(React.Fragment, null, chip, children);
|
|
418
|
+
});
|
|
419
|
+
StandIn.displayName = `UnresolvedImport(${identifier})`;
|
|
420
|
+
Object.defineProperty(StandIn, UNRESOLVED_IMPORT_MARK, {
|
|
421
|
+
value: { identifier, importPath },
|
|
422
|
+
enumerable: false
|
|
423
|
+
});
|
|
424
|
+
return StandIn;
|
|
425
|
+
}
|
|
426
|
+
function describeUnresolved(entry) {
|
|
427
|
+
if (entry.identifier === "*") return `"${entry.importPath}" (not in this scope)`;
|
|
428
|
+
return entry.importPath ? `${entry.identifier} from "${entry.importPath}"` : entry.identifier;
|
|
429
|
+
}
|
|
430
|
+
function stripLiteralsForScan(code) {
|
|
431
|
+
return code.replace(/"(?:[^"\\]|\\.)*"/g, '""').replace(/'(?:[^'\\]|\\.)*'/g, "''").replace(/`(?:[^`\\]|\\.)*`/gs, "``");
|
|
432
|
+
}
|
|
433
|
+
function extractJsxComponentIdentifiers(codeForScanning) {
|
|
434
|
+
const components = /* @__PURE__ */ new Set();
|
|
435
|
+
const patterns = [
|
|
436
|
+
// `(?![\w$.])`: `<C.Button>` names the namespace `C`, which is an
|
|
437
|
+
// import or a declaration, never a bare missing component.
|
|
438
|
+
/React\.createElement\s*\(\s*([A-Z][a-zA-Z0-9]*)(?![\w$.])/g,
|
|
439
|
+
/\.default\.createElement\s*\(\s*([A-Z][a-zA-Z0-9]*)(?![\w$.])/g,
|
|
440
|
+
/\bjsxs?\s*\(\s*([A-Z][a-zA-Z0-9]*)(?![\w$.])/g
|
|
441
|
+
];
|
|
442
|
+
for (const pattern of patterns) {
|
|
443
|
+
let match;
|
|
444
|
+
while ((match = pattern.exec(codeForScanning)) !== null) {
|
|
445
|
+
if (match[1]) components.add(match[1]);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return components;
|
|
449
|
+
}
|
|
450
|
+
var PATCH_SCOPE_SKIP_IDENTIFIERS = /* @__PURE__ */ new Set([
|
|
451
|
+
"React",
|
|
452
|
+
"Object",
|
|
453
|
+
"Array",
|
|
454
|
+
"String",
|
|
455
|
+
"Number",
|
|
456
|
+
"Boolean",
|
|
457
|
+
"Date",
|
|
458
|
+
"Math",
|
|
459
|
+
"JSON",
|
|
460
|
+
"Promise",
|
|
461
|
+
"Error",
|
|
462
|
+
"TypeError",
|
|
463
|
+
"RangeError",
|
|
464
|
+
"RegExp",
|
|
465
|
+
"Map",
|
|
466
|
+
"Set",
|
|
467
|
+
"WeakMap",
|
|
468
|
+
"WeakSet",
|
|
469
|
+
"Symbol",
|
|
470
|
+
"Proxy",
|
|
471
|
+
"Reflect",
|
|
472
|
+
"Intl",
|
|
473
|
+
"URL",
|
|
474
|
+
"FormData",
|
|
475
|
+
"Headers",
|
|
476
|
+
"Request",
|
|
477
|
+
"Response",
|
|
478
|
+
"AbortController",
|
|
479
|
+
"HTMLElement",
|
|
480
|
+
"SVGElement",
|
|
481
|
+
"Event",
|
|
482
|
+
"MouseEvent",
|
|
483
|
+
"KeyboardEvent",
|
|
484
|
+
"HTMLInputElement",
|
|
485
|
+
"HTMLTextAreaElement",
|
|
486
|
+
"HTMLSelectElement",
|
|
487
|
+
"HTMLButtonElement",
|
|
488
|
+
"HTMLDivElement",
|
|
489
|
+
"HTMLFormElement",
|
|
490
|
+
"Node",
|
|
491
|
+
"Element",
|
|
492
|
+
"Document",
|
|
493
|
+
"Window",
|
|
494
|
+
"Infinity",
|
|
495
|
+
"NaN",
|
|
496
|
+
"Fragment"
|
|
497
|
+
]);
|
|
498
|
+
|
|
499
|
+
// src/scope/build.ts
|
|
500
|
+
function recordUnresolved(state, entry) {
|
|
501
|
+
if (!state.unresolved.some((e) => e.identifier === entry.identifier && e.importPath === entry.importPath)) {
|
|
502
|
+
state.unresolved.push(entry);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function asRecord(value) {
|
|
506
|
+
return value && (typeof value === "object" || typeof value === "function") ? value : {};
|
|
507
|
+
}
|
|
508
|
+
function ownKeys(mod) {
|
|
509
|
+
try {
|
|
510
|
+
return Object.keys(mod);
|
|
511
|
+
} catch {
|
|
512
|
+
return [];
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
function createSafeModuleProxy(importPath, moduleExports, state) {
|
|
516
|
+
const target = { ...moduleExports, __esModule: true };
|
|
517
|
+
return new Proxy(target, {
|
|
518
|
+
get(t, prop) {
|
|
519
|
+
if (typeof prop !== "string") return Reflect.get(t, prop);
|
|
520
|
+
if (prop in t) return t[prop];
|
|
521
|
+
if (prop.startsWith("_") || prop === "default" || prop === "then") return void 0;
|
|
522
|
+
if (/^[A-Z]/.test(prop)) {
|
|
523
|
+
const fallback = createUnresolvedImportStandIn(prop, importPath);
|
|
524
|
+
t[prop] = fallback;
|
|
525
|
+
recordUnresolved(state, { identifier: prop, importPath });
|
|
526
|
+
return fallback;
|
|
527
|
+
}
|
|
528
|
+
return void 0;
|
|
529
|
+
},
|
|
530
|
+
has(t, prop) {
|
|
531
|
+
if (typeof prop === "string" && /^[A-Z]/.test(prop)) return true;
|
|
532
|
+
return prop in t;
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
function moduleView(entry, mod, state) {
|
|
537
|
+
if (entry.strategy === "namespace") {
|
|
538
|
+
const ns = asRecord(mod.default ?? mod);
|
|
539
|
+
return { ...ns, default: ns, __esModule: true };
|
|
540
|
+
}
|
|
541
|
+
if (entry.safeProxy) return createSafeModuleProxy(entry.path, mod, state);
|
|
542
|
+
const view = { ...mod, __esModule: true };
|
|
543
|
+
for (const [moduleKey, scopeKey] of Object.entries(entry.exportMap ?? {})) {
|
|
544
|
+
const value = moduleKey === "default" ? mod.default ?? mod : mod[moduleKey];
|
|
545
|
+
view[scopeKey] = value;
|
|
546
|
+
if (moduleKey === "default") view.default = value;
|
|
547
|
+
}
|
|
548
|
+
if (!("default" in view)) view.default = mod.default;
|
|
549
|
+
return view;
|
|
550
|
+
}
|
|
551
|
+
function applyToFlatScope(entry, mod, values) {
|
|
552
|
+
if (entry.strategy === "namespace") {
|
|
553
|
+
if (entry.namespaceName) values[entry.namespaceName] = mod.default ?? mod;
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
if (entry.strategy === "spread") {
|
|
557
|
+
for (const key of ownKeys(mod)) {
|
|
558
|
+
if (key === "default" || key === "__esModule") continue;
|
|
559
|
+
values[key] = mod[key];
|
|
560
|
+
}
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
for (const name of entry.exports ?? []) values[name] = mod[name];
|
|
564
|
+
for (const [moduleKey, scopeKey] of Object.entries(entry.exportMap ?? {})) {
|
|
565
|
+
values[scopeKey] = moduleKey === "default" ? mod.default ?? mod : mod[moduleKey];
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function buildDangerousGlobalStubs() {
|
|
569
|
+
const stubs = {};
|
|
570
|
+
for (const name of [...gate_lists_default.bannedGlobals, ...gate_lists_default.bannedCallables]) {
|
|
571
|
+
stubs[name] = function bannedGlobal() {
|
|
572
|
+
throw new Error(
|
|
573
|
+
`This component tried to use "${name}". Components stored in the database run inside the signed-in page and may not reach the network, browser storage, or the JavaScript evaluator. Render what the Shape hands you in props.data, and use a Shape action for anything you need from the server.`
|
|
574
|
+
);
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
return stubs;
|
|
578
|
+
}
|
|
579
|
+
function buildScopeState(spec) {
|
|
580
|
+
const state = { values: {}, modules: /* @__PURE__ */ new Map(), safeProxyPaths: /* @__PURE__ */ new Map(), unresolved: [], pending: [] };
|
|
581
|
+
const R = ReactModule2;
|
|
582
|
+
state.values.React = R;
|
|
583
|
+
for (const hook of ["useState", "useEffect", "useMemo", "useCallback", "useRef"]) state.values[hook] = R[hook];
|
|
584
|
+
state.modules.set("react", { ...R, default: R, __esModule: true });
|
|
585
|
+
for (const path of spec.entries ?? []) {
|
|
586
|
+
const entry = getScopeEntry(path);
|
|
587
|
+
if (!entry) {
|
|
588
|
+
recordUnresolved(state, { identifier: "*", importPath: path });
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
const read = readScopeModule(path);
|
|
592
|
+
if (read.state === "pending") {
|
|
593
|
+
state.pending.push(path);
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
if (read.state === "missing") {
|
|
597
|
+
continue;
|
|
598
|
+
}
|
|
599
|
+
if (read.state === "failed") {
|
|
600
|
+
announceFailedModule(path, read.message);
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
const mod = asRecord(read.module);
|
|
604
|
+
const view = moduleView(entry, mod, state);
|
|
605
|
+
state.modules.set(path, view);
|
|
606
|
+
if (entry.safeProxy) {
|
|
607
|
+
state.safeProxyPaths.set(path, { proxy: view, keys: new Set(ownKeys(mod)) });
|
|
608
|
+
}
|
|
609
|
+
applyToFlatScope(entry, mod, state.values);
|
|
610
|
+
}
|
|
611
|
+
if (state.values.MarkdownStream && !state.values.Markdown) state.values.Markdown = state.values.MarkdownStream;
|
|
612
|
+
if (!state.values.DynamicIcon) {
|
|
613
|
+
const icons = readScopeModule("@ai-matrx/icons");
|
|
614
|
+
if (icons.state === "ready") {
|
|
615
|
+
const m = asRecord(icons.module);
|
|
616
|
+
state.values.DynamicIcon = m.DynamicIcon;
|
|
617
|
+
state.values.renderIcon = m.renderIcon;
|
|
618
|
+
state.values.getIconComponent = m.getIconComponent;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const overrides = spec.overrides ?? {};
|
|
622
|
+
Object.assign(state.values, overrides);
|
|
623
|
+
if (Object.keys(overrides).length > 0) {
|
|
624
|
+
for (const [path, view] of state.modules) {
|
|
625
|
+
const entry = getScopeEntry(path);
|
|
626
|
+
for (const [moduleKey, scopeKey] of Object.entries(entry?.exportMap ?? {})) {
|
|
627
|
+
if (!(scopeKey in overrides)) continue;
|
|
628
|
+
view[scopeKey] = overrides[scopeKey];
|
|
629
|
+
if (moduleKey === "default") view.default = overrides[scopeKey];
|
|
630
|
+
else view[moduleKey] = overrides[scopeKey];
|
|
631
|
+
}
|
|
632
|
+
for (const name of entry?.exports ?? []) {
|
|
633
|
+
if (name in overrides) view[name] = overrides[name];
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
if (spec.shadowDangerousGlobals) Object.assign(state.values, buildDangerousGlobalStubs());
|
|
638
|
+
return state;
|
|
639
|
+
}
|
|
640
|
+
function buildScope(spec) {
|
|
641
|
+
return { ...buildScopeState(spec).values };
|
|
642
|
+
}
|
|
643
|
+
function patchMissingJsx(identifiers, state, declared, skip) {
|
|
644
|
+
for (const identifier of identifiers) {
|
|
645
|
+
if (skip.has(identifier) || identifier in state.values || declared.has(identifier)) continue;
|
|
646
|
+
let provided = false;
|
|
647
|
+
for (const [, { proxy, keys }] of state.safeProxyPaths) {
|
|
648
|
+
if (!keys.has(identifier)) continue;
|
|
649
|
+
const value = proxy[identifier];
|
|
650
|
+
if (value !== void 0) {
|
|
651
|
+
state.values[identifier] = value;
|
|
652
|
+
const mark = readUnresolvedImportMark(value);
|
|
653
|
+
if (mark) recordUnresolved(state, mark);
|
|
654
|
+
provided = true;
|
|
655
|
+
break;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (provided) continue;
|
|
659
|
+
state.values[identifier] = createUnresolvedImportStandIn(identifier);
|
|
660
|
+
recordUnresolved(state, { identifier, importPath: null });
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// src/execute-core.ts
|
|
665
|
+
var IDENTIFIER_RE = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
666
|
+
function missingModule(path) {
|
|
667
|
+
const target = { __esModule: true };
|
|
668
|
+
return new Proxy(target, {
|
|
669
|
+
get(t, prop) {
|
|
670
|
+
if (typeof prop !== "string") return Reflect.get(t, prop);
|
|
671
|
+
if (prop in t) return t[prop];
|
|
672
|
+
if (prop === "then" || prop.startsWith("_")) return void 0;
|
|
673
|
+
if (prop === "default" || /^[A-Z]/.test(prop)) {
|
|
674
|
+
const fallback = createUnresolvedImportStandIn(prop === "default" ? path.split("/").pop() ?? path : prop, path);
|
|
675
|
+
t[prop] = fallback;
|
|
676
|
+
return fallback;
|
|
677
|
+
}
|
|
678
|
+
return void 0;
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
function bindImports(mod, allFiles, state) {
|
|
683
|
+
for (const binding of mod.importBindings) {
|
|
684
|
+
const { source, imported, local } = binding;
|
|
685
|
+
if (source.startsWith("./") || source.startsWith("../")) {
|
|
686
|
+
if (!resolveRelativeFile(allFiles, mod.file, source)) {
|
|
687
|
+
recordUnresolved(state, { identifier: imported === "*" ? `* as ${local}` : imported, importPath: source });
|
|
688
|
+
}
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
const view = state.modules.get(source);
|
|
692
|
+
if (!view) {
|
|
693
|
+
recordUnresolved(state, {
|
|
694
|
+
identifier: imported === "*" ? `* as ${local}` : imported === "default" ? local : imported,
|
|
695
|
+
importPath: source
|
|
696
|
+
});
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
if (imported === "*") continue;
|
|
700
|
+
if (imported === "default") {
|
|
701
|
+
if (view.default === void 0) {
|
|
702
|
+
view.default = createUnresolvedImportStandIn(local, source);
|
|
703
|
+
recordUnresolved(state, { identifier: local, importPath: source });
|
|
704
|
+
}
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
let present;
|
|
708
|
+
try {
|
|
709
|
+
present = view[imported] !== void 0;
|
|
710
|
+
} catch {
|
|
711
|
+
present = false;
|
|
712
|
+
}
|
|
713
|
+
if (!present) {
|
|
714
|
+
if (/^[A-Z]/.test(imported)) view[imported] = createUnresolvedImportStandIn(imported, source);
|
|
715
|
+
recordUnresolved(state, { identifier: imported === local ? local : `${imported} as ${local}`, importPath: source });
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
var CONVENTIONAL_NAMES = /^(App|Main|Page|Component|Demo|Example|Root)$/;
|
|
720
|
+
function pickCandidate(candidates, rule) {
|
|
721
|
+
if (rule === "conventional") {
|
|
722
|
+
const preferred = [...candidates].reverse().find((name) => CONVENTIONAL_NAMES.test(name));
|
|
723
|
+
if (preferred) return preferred;
|
|
724
|
+
}
|
|
725
|
+
return candidates[candidates.length - 1];
|
|
726
|
+
}
|
|
727
|
+
function reportOnce(options, unresolved) {
|
|
728
|
+
if (unresolved.length === 0) return;
|
|
729
|
+
const origin = options?.origin ?? "code-runtime";
|
|
730
|
+
if (options?.onUnresolved) {
|
|
731
|
+
try {
|
|
732
|
+
options.onUnresolved(origin, unresolved);
|
|
733
|
+
} catch {
|
|
734
|
+
}
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
console.warn(`[code-runtime] ${origin}: ${unresolved.map(describeUnresolved).join(", ")} could not be resolved; each renders as a marked placeholder.`);
|
|
738
|
+
}
|
|
739
|
+
function executeGraph(graph, spec, options) {
|
|
740
|
+
const state = buildScopeState(spec);
|
|
741
|
+
const blocking = state.pending.filter((path) => {
|
|
742
|
+
const entry = getScopeEntry(path);
|
|
743
|
+
return Object.values(graph.modules).some(
|
|
744
|
+
(m) => m.importBindings.some((b) => b.source === path) || (entry?.provides ?? []).some((id) => new RegExp(`(?<![\\w$.])${id.replace(/[$]/g, "\\$")}\\b`).test(m.code))
|
|
745
|
+
);
|
|
746
|
+
});
|
|
747
|
+
if (blocking.length > 0) {
|
|
748
|
+
return {
|
|
749
|
+
ok: false,
|
|
750
|
+
error: {
|
|
751
|
+
code: "scope_not_ready",
|
|
752
|
+
message: `The scope entries ${blocking.join(", ")} are still loading. Call prepareScope(spec) before compiling.`,
|
|
753
|
+
retryable: true
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
const fileSet = new Set(Object.keys(graph.modules));
|
|
758
|
+
const allFiles = Object.fromEntries([...fileSet].map((f) => [f, ""]));
|
|
759
|
+
for (const mod of Object.values(graph.modules)) bindImports(mod, allFiles, state);
|
|
760
|
+
for (const mod of Object.values(graph.modules)) {
|
|
761
|
+
const ids = extractJsxComponentIdentifiers(stripLiteralsForScan(mod.code));
|
|
762
|
+
patchMissingJsx(ids, state, new Set(mod.declaredTopLevel), PATCH_SCOPE_SKIP_IDENTIFIERS);
|
|
763
|
+
}
|
|
764
|
+
const cache = /* @__PURE__ */ new Map();
|
|
765
|
+
let current = graph.entry;
|
|
766
|
+
const run = (file) => {
|
|
767
|
+
const cached = cache.get(file);
|
|
768
|
+
if (cached) return cached.exports;
|
|
769
|
+
const mod = graph.modules[file];
|
|
770
|
+
if (!mod) return missingModule(file);
|
|
771
|
+
const module = { exports: {} };
|
|
772
|
+
const record = { exports: module.exports, done: false };
|
|
773
|
+
cache.set(file, record);
|
|
774
|
+
const declared = new Set(mod.declaredTopLevel);
|
|
775
|
+
const paramNames = Object.keys(state.values).filter(
|
|
776
|
+
(k) => IDENTIFIER_RE.test(k) && !k.startsWith("__") && !declared.has(k) && k !== "require" && k !== "module" && k !== "exports"
|
|
777
|
+
);
|
|
778
|
+
const paramValues = paramNames.map((k) => state.values[k]);
|
|
779
|
+
const requireFn = (specifier) => {
|
|
780
|
+
if (specifier.startsWith("./") || specifier.startsWith("../")) {
|
|
781
|
+
const target = resolveRelativeFile(allFiles, file, specifier);
|
|
782
|
+
if (!target) return missingModule(specifier);
|
|
783
|
+
const prev = current;
|
|
784
|
+
current = target;
|
|
785
|
+
try {
|
|
786
|
+
return run(target);
|
|
787
|
+
} finally {
|
|
788
|
+
current = prev;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return state.modules.get(specifier) ?? missingModule(specifier);
|
|
792
|
+
};
|
|
793
|
+
const candidate = file === graph.entry ? pickCandidate(mod.componentCandidates, options?.componentCandidate) : void 0;
|
|
794
|
+
const tail = candidate ? `
|
|
795
|
+
;return typeof ${candidate} !== "undefined" ? ${candidate} : undefined;` : "";
|
|
796
|
+
const factory = new Function(...paramNames, "require", "module", "exports", `${mod.code}${tail}`);
|
|
797
|
+
const returned = factory(...paramValues, requireFn, module, module.exports);
|
|
798
|
+
if (module.exports !== record.exports) record.exports = module.exports;
|
|
799
|
+
if (returned !== void 0 && record.exports.default === void 0) {
|
|
800
|
+
record.exports.__candidate = returned;
|
|
801
|
+
}
|
|
802
|
+
record.done = true;
|
|
803
|
+
return record.exports;
|
|
804
|
+
};
|
|
805
|
+
try {
|
|
806
|
+
const exportsOfEntry = run(graph.entry);
|
|
807
|
+
const Component = exportsOfEntry.default ?? exportsOfEntry.__candidate;
|
|
808
|
+
const unresolved = [...state.unresolved];
|
|
809
|
+
reportOnce(options, unresolved);
|
|
810
|
+
if (typeof Component !== "function" && !(Component && typeof Component === "object" && "$$typeof" in Component)) {
|
|
811
|
+
return {
|
|
812
|
+
ok: false,
|
|
813
|
+
error: {
|
|
814
|
+
code: "no_component",
|
|
815
|
+
message: "This code compiled but returned nothing to render. Export a React component as the default export of the entry file.",
|
|
816
|
+
retryable: false,
|
|
817
|
+
diagnostic: graph.entry
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
return {
|
|
822
|
+
ok: true,
|
|
823
|
+
Component,
|
|
824
|
+
unresolved: unresolved.map(describeUnresolved),
|
|
825
|
+
unresolvedImports: unresolved
|
|
826
|
+
};
|
|
827
|
+
} catch (err) {
|
|
828
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
829
|
+
return {
|
|
830
|
+
ok: false,
|
|
831
|
+
error: {
|
|
832
|
+
code: "evaluation_error",
|
|
833
|
+
message: fileSet.size > 1 ? `${current}: ${message}` : message,
|
|
834
|
+
retryable: false,
|
|
835
|
+
diagnostic: current
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
export {
|
|
841
|
+
SCOPE_ENTRIES,
|
|
842
|
+
buildDangerousGlobalStubs,
|
|
843
|
+
buildScope,
|
|
844
|
+
coreEntryPaths,
|
|
845
|
+
createUnresolvedImportStandIn,
|
|
846
|
+
defaultComponentEntries,
|
|
847
|
+
describeUnresolved,
|
|
848
|
+
detectEntries,
|
|
849
|
+
executeGraph,
|
|
850
|
+
getScopeEntry,
|
|
851
|
+
listScopeEntries,
|
|
852
|
+
listScopeEntryPaths,
|
|
853
|
+
prepareScopeModules,
|
|
854
|
+
provideScopeModules,
|
|
855
|
+
readUnresolvedImportMark,
|
|
856
|
+
resetScopeModules
|
|
857
|
+
};
|
|
858
|
+
//# sourceMappingURL=execute.js.map
|