zelune 1.6.3 → 1.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/bin/cli.mjs +13 -53
  3. package/dist/assets/CheckoutScreen-CoLb16nl.js +229 -0
  4. package/dist/assets/HomeScreen-DtWSrKS1.js +316 -0
  5. package/dist/assets/LoginScreen-C1EtAYek.js +189 -0
  6. package/dist/assets/ProductDetailScreen-a9PXPTEY.js +196 -0
  7. package/dist/assets/ProfileScreen-ChKW9gJP.js +185 -0
  8. package/dist/assets/index-xam7XuSg.js +44764 -0
  9. package/{index.html → dist/index.html} +3 -1
  10. package/mcp/server.mjs +1906 -32
  11. package/package.json +10 -13
  12. package/plugin.json +1 -1
  13. package/socket.yml +11 -0
  14. package/mcp/server.ts +0 -446
  15. package/plugins/viteReactNativeFallbackPlugin.ts +0 -522
  16. package/plugins/viteRnSourceInject.ts +0 -105
  17. package/plugins/viteVirtualScreensPlugin.ts +0 -216
  18. package/src/canvas/CanvasApp.tsx +0 -1655
  19. package/src/canvas/FlowArrowsLayer.tsx +0 -239
  20. package/src/canvas/InspectorPanel.tsx +0 -1494
  21. package/src/canvas/ScreenArtboard.tsx +0 -1491
  22. package/src/canvas/types.ts +0 -23
  23. package/src/main.tsx +0 -80
  24. package/src/runtime/MockNavigationContext.tsx +0 -1869
  25. package/src/runtime/ScreenErrorBoundary.tsx +0 -86
  26. package/src/runtime/nativewindShim.ts +0 -997
  27. package/src/runtime/reactNativeShim.ts +0 -1674
  28. package/src/screens/CheckoutScreen.tsx +0 -229
  29. package/src/screens/HomeScreen.tsx +0 -288
  30. package/src/screens/LoginScreen.tsx +0 -176
  31. package/src/screens/ProductDetailScreen.tsx +0 -207
  32. package/src/screens/ProfileScreen.tsx +0 -172
  33. package/src/screens/index.ts +0 -1
  34. package/src/server/apiMiddleware.ts +0 -378
  35. package/src/server/astEngine.ts +0 -2624
  36. package/src/vite-env.d.ts +0 -7
  37. package/tsconfig.json +0 -23
  38. package/vite.config.ts +0 -339
  39. /package/{src/styles.css → dist/assets/index-C7nrS82N.css} +0 -0
@@ -1,216 +0,0 @@
1
- import type { Plugin } from 'vite';
2
- import { discoverScreenFilesSync } from '../src/server/astEngine';
3
-
4
- const VIRTUAL_MODULE_ID = 'virtual:zelune-screens';
5
- const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
6
-
7
- const PREFERRED_ORDER = ['Login', 'Home', 'ProductDetail', 'Checkout', 'Profile'];
8
-
9
- /**
10
- * Vite Virtual Module plugin that dynamically discovers and loads React Native / Expo
11
- * screen components from any target project (`--project /path/to/app`) with per-screen
12
- * dynamic import() fault isolation so a broken import or top-level exception in one screen
13
- * can never blank out the entire Zelune studio canvas.
14
- */
15
- export function viteVirtualScreensPlugin(workspaceRoot: string): Plugin {
16
- let isBuild = false;
17
-
18
- return {
19
- name: 'vite-virtual-zelune-screens',
20
- configResolved(config) {
21
- isBuild = config.command === 'build';
22
- },
23
- resolveId(id) {
24
- if (id === VIRTUAL_MODULE_ID) {
25
- return RESOLVED_VIRTUAL_MODULE_ID;
26
- }
27
- return null;
28
- },
29
- load(id) {
30
- if (id !== RESOLVED_VIRTUAL_MODULE_ID) {
31
- return null;
32
- }
33
-
34
- const discovered = discoverScreenFilesSync(workspaceRoot);
35
- const lines: string[] = [
36
- `import React from 'react';`,
37
- `function resolveScreenComponent(mod) {`,
38
- ` if (!mod) return null;`,
39
- ` if (typeof mod.default === 'function' || (typeof mod.default === 'object' && mod.default !== null)) {`,
40
- ` return mod.default;`,
41
- ` }`,
42
- ` for (const key of Object.keys(mod)) {`,
43
- ` if (typeof mod[key] === 'function') return mod[key];`,
44
- ` }`,
45
- ` return null;`,
46
- `}`,
47
- `function createIsolatedScreenComponent(screenId, filePath, loader) {`,
48
- ` let cachedComp = null;`,
49
- ` return function IsolatedScreenWrapper(props) {`,
50
- ` const [state, setState] = React.useState(() => ({`,
51
- ` Comp: cachedComp,`,
52
- ` error: null,`,
53
- ` attempt: 0,`,
54
- ` }));`,
55
- ` React.useEffect(() => {`,
56
- ` let cancelled = false;`,
57
- ` Promise.resolve()`,
58
- ` .then(() => loader(state.attempt))`,
59
- ` .then((mod) => {`,
60
- ` if (cancelled) return;`,
61
- ` const resolved = resolveScreenComponent(mod);`,
62
- ` if (!resolved) {`,
63
- ` setState((prev) => ({`,
64
- ` ...prev,`,
65
- ` Comp: null,`,
66
- ` error: 'No exported React component found in ' + filePath,`,
67
- ` }));`,
68
- ` } else {`,
69
- ` cachedComp = resolved;`,
70
- ` setState((prev) => ({ ...prev, Comp: resolved, error: null }));`,
71
- ` }`,
72
- ` })`,
73
- ` .catch((err) => {`,
74
- ` if (cancelled) return;`,
75
- ` const msg = err instanceof Error ? err.message : String(err);`,
76
- ` setState((prev) => ({ ...prev, Comp: null, error: msg }));`,
77
- ` });`,
78
- ` return () => {`,
79
- ` cancelled = true;`,
80
- ` };`,
81
- ` }, [state.attempt]);`,
82
- ` if (state.error) {`,
83
- ` return React.createElement(`,
84
- ` 'div',`,
85
- ` {`,
86
- ` style: {`,
87
- ` flex: 1,`,
88
- ` padding: 24,`,
89
- ` backgroundColor: '#18181B',`,
90
- ` color: '#FCA5A5',`,
91
- ` display: 'flex',`,
92
- ` flexDirection: 'column',`,
93
- ` justifyContent: 'center',`,
94
- ` gap: 10,`,
95
- ` fontFamily: 'var(--font-mono)',`,
96
- ` },`,
97
- ` },`,
98
- ` React.createElement(`,
99
- ` 'div',`,
100
- ` { style: { color: '#F87171', fontWeight: 700, fontSize: 13 } },`,
101
- ` 'Module Load Error in ' + filePath`,
102
- ` ),`,
103
- ` React.createElement(`,
104
- ` 'div',`,
105
- ` {`,
106
- ` style: {`,
107
- ` fontSize: 11,`,
108
- ` color: '#FECACA',`,
109
- ` whiteSpace: 'pre-wrap',`,
110
- ` wordBreak: 'break-word',`,
111
- ` maxHeight: 360,`,
112
- ` overflowY: 'auto',`,
113
- ` },`,
114
- ` },`,
115
- ` state.error`,
116
- ` ),`,
117
- ` React.createElement(`,
118
- ` 'button',`,
119
- ` {`,
120
- ` type: 'button',`,
121
- ` onClick: () => setState((prev) => ({ ...prev, error: null, attempt: prev.attempt + 1 })),`,
122
- ` style: {`,
123
- ` alignSelf: 'flex-start',`,
124
- ` marginTop: 6,`,
125
- ` padding: '6px 12px',`,
126
- ` borderRadius: 6,`,
127
- ` border: '1px solid rgba(248, 113, 113, 0.45)',`,
128
- ` backgroundColor: 'rgba(127, 29, 29, 0.4)',`,
129
- ` color: '#FEE2E2',`,
130
- ` fontSize: 11,`,
131
- ` fontWeight: 600,`,
132
- ` cursor: 'pointer',`,
133
- ` },`,
134
- ` },`,
135
- ` 'Retry Screen Load'`,
136
- ` )`,
137
- ` );`,
138
- ` }`,
139
- ` if (!state.Comp) {`,
140
- ` return React.createElement(`,
141
- ` 'div',`,
142
- ` {`,
143
- ` style: {`,
144
- ` flex: 1,`,
145
- ` display: 'flex',`,
146
- ` alignItems: 'center',`,
147
- ` justifyContent: 'center',`,
148
- ` color: '#64748B',`,
149
- ` fontSize: 12,`,
150
- ` fontFamily: 'var(--font-mono)',`,
151
- ` },`,
152
- ` },`,
153
- ` 'Loading ' + screenId + '...'`,
154
- ` );`,
155
- ` }`,
156
- ` return React.createElement(state.Comp, props);`,
157
- ` };`,
158
- `}`,
159
- ];
160
-
161
- const mapEntries: string[] = [];
162
- const orderIds: string[] = [];
163
-
164
- const sorted = [...discovered].sort((a, b) => {
165
- const idxA = PREFERRED_ORDER.indexOf(a.id);
166
- const idxB = PREFERRED_ORDER.indexOf(b.id);
167
- if (idxA !== -1 && idxB !== -1) return idxA - idxB;
168
- if (idxA !== -1) return -1;
169
- if (idxB !== -1) return 1;
170
- return a.id.localeCompare(b.id);
171
- });
172
-
173
- sorted.forEach((scr) => {
174
- const normalizedFullPath = scr.fullPath.replace(/\\/g, '/');
175
- const fsUrl =
176
- '/@fs' + (normalizedFullPath.startsWith('/') ? '' : '/') + normalizedFullPath;
177
- const loaderExpr = isBuild
178
- ? `(attempt) => attempt > 0 ? import(/* @vite-ignore */ ${JSON.stringify(
179
- normalizedFullPath
180
- )} + '?t=' + Date.now()) : import(${JSON.stringify(normalizedFullPath)})`
181
- : `(attempt) => import(/* @vite-ignore */ ${JSON.stringify(
182
- fsUrl
183
- )} + (attempt > 0 ? '?t=' + Date.now() : ''))`;
184
-
185
- mapEntries.push(
186
- ` ${JSON.stringify(scr.id)}: createIsolatedScreenComponent(${JSON.stringify(
187
- scr.id
188
- )}, ${JSON.stringify(scr.relPath)}, ${loaderExpr})`
189
- );
190
- orderIds.push(scr.id);
191
- });
192
-
193
- return [
194
- ...lines,
195
- `export const SCREEN_COMPONENTS = {`,
196
- mapEntries.join(',\n'),
197
- `};`,
198
- `export const SCREEN_ORDER = ${JSON.stringify(orderIds)};`,
199
- ].join('\n');
200
- },
201
- configureServer(server) {
202
- server.watcher.on('add', (file) => {
203
- if (file.endsWith('.tsx') || file.endsWith('.jsx')) {
204
- const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID);
205
- if (mod) server.moduleGraph.invalidateModule(mod);
206
- }
207
- });
208
- server.watcher.on('unlink', (file) => {
209
- if (file.endsWith('.tsx') || file.endsWith('.jsx')) {
210
- const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID);
211
- if (mod) server.moduleGraph.invalidateModule(mod);
212
- }
213
- });
214
- },
215
- };
216
- }