@runner-ai/vite-uuid-tagger 0.0.4 → 0.0.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 (3) hide show
  1. package/dist/index.d.ts +6 -8
  2. package/dist/index.js +231 -374
  3. package/package.json +13 -20
package/dist/index.d.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  import { Plugin } from 'vite';
2
2
 
3
- interface ViteUUIDTaggerOptions {
4
- /** Enable the plugin (default: true) */
5
- enabled?: boolean;
6
- /** Enable Tailwind theme registry extraction (default: true) */
7
- extractColors?: boolean;
3
+ interface UuidTaggerOptions {
4
+ projectRoot: string;
5
+ /** Env var name for @runner-ai/design script tag version. Default: VITE_DESIGN_SCRIPT_TAG */
6
+ scriptTagEnvVar?: string;
8
7
  }
8
+ declare function uuidTagger(options: UuidTaggerOptions): Plugin;
9
9
 
10
- declare function viteUuidTagger(options?: ViteUUIDTaggerOptions): Plugin;
11
-
12
- export { type ViteUUIDTaggerOptions, viteUuidTagger as default };
10
+ export { type UuidTaggerOptions, uuidTagger };
package/dist/index.js CHANGED
@@ -1,416 +1,273 @@
1
- // src/features/dev-middleware.ts
2
- function createDevMiddleware() {
3
- return {
4
- configureServer(server) {
5
- server.middlewares.use((req, res, next) => {
6
- if (req.url === "/uuid-mappings.json") {
7
- res.statusCode = 200;
8
- res.setHeader("content-type", "application/json");
9
- res.end(JSON.stringify({}));
10
- return;
11
- }
12
- next();
13
- });
14
- }
15
- };
16
- }
17
-
18
- // src/features/jsx-source-tagger.ts
19
- var CLIENT_RUNTIME_CODE = `
20
- import { jsxDEV as _jsxDEV, Fragment } from 'react/jsx-dev-runtime';
21
-
22
- if (typeof window !== 'undefined' && !window.sourceElementMap) {
23
- window.sourceElementMap = new Map();
24
- }
1
+ // src/plugin.ts
2
+ import path2 from "path";
3
+ import { parse } from "@babel/parser";
4
+ import MagicString from "magic-string";
25
5
 
26
- function getCleanFileName(fileName) {
27
- if (!fileName) return '';
28
- return fileName
29
- .replace(/^.*?\\/src\\//, 'src/')
30
- .replace(/^\\//, '');
6
+ // src/ast-helpers.ts
7
+ import path from "path";
8
+ var NON_TAGGABLE_ELEMENTS = ["Fragment", "React.Fragment"];
9
+ var VALID_EXTENSIONS = /* @__PURE__ */ new Set([".jsx", ".tsx", ".js", ".ts"]);
10
+ function shouldSkipFile(filename) {
11
+ return filename.includes("node_modules") || !VALID_EXTENSIONS.has(path.extname(filename));
31
12
  }
32
-
33
- function wrapRef(originalRef, sourceInfo) {
34
- return function taggedRef(node) {
35
- if (node && node instanceof Element) {
36
- var loc = sourceInfo.fileName + ':' + sourceInfo.lineNumber + ':' + sourceInfo.columnNumber;
37
- node.setAttribute('data-uuid-loc', loc);
38
-
39
- var sym = Symbol.for('__jsxSource__');
40
- node[sym] = sourceInfo;
41
-
42
- if (typeof window !== 'undefined' && window.sourceElementMap) {
43
- var key = loc;
44
- if (!window.sourceElementMap.has(key)) {
45
- window.sourceElementMap.set(key, new Set());
46
- }
47
- window.sourceElementMap.get(key).add(new WeakRef(node));
48
- }
49
- }
50
-
51
- if (typeof originalRef === 'function') {
52
- originalRef(node);
53
- } else if (originalRef && typeof originalRef === 'object') {
54
- originalRef.current = node;
55
- }
56
- };
57
- }
58
-
59
- var VOID_ELEMENTS = new Set([
60
- 'area','base','br','col','embed','hr','img','input',
61
- 'link','meta','param','source','track','wbr'
62
- ]);
63
-
64
- var _isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
65
-
66
- export function jsxDEV(type, props, key, isStaticChildren, source, self) {
67
- if (_isBrowser && source && source.fileName && typeof type === 'string' && !VOID_ELEMENTS.has(type)) {
68
- var cleanFileName = getCleanFileName(source.fileName);
69
- var sourceInfo = {
70
- fileName: cleanFileName,
71
- lineNumber: source.lineNumber || 0,
72
- columnNumber: source.columnNumber || 0,
73
- };
74
-
75
- var newProps = Object.assign({}, props);
76
- newProps.ref = wrapRef(props ? props.ref : undefined, sourceInfo);
77
-
78
- return _jsxDEV(type, newProps, key, isStaticChildren, source, self);
13
+ function getElementName(node) {
14
+ if (node.name.type === "JSXIdentifier") {
15
+ return node.name.name;
79
16
  }
80
-
81
- return _jsxDEV(type, props, key, isStaticChildren, source, self);
82
- }
83
-
84
- export { Fragment };
85
- export { jsx, jsxs } from 'react/jsx-dev-runtime';
86
- `;
87
- var PASSTHROUGH_CODE = `export * from 'react/jsx-dev-runtime';
88
- `;
89
- function createJsxSourceTagger() {
90
- return {
91
- resolveId(source, importer, options) {
92
- if (source !== "react/jsx-dev-runtime") {
93
- return null;
94
- }
95
- if (importer?.includes("\0runner-jsx")) {
96
- return null;
97
- }
98
- const self = this;
99
- const env = self?.environment;
100
- const isSSR = env?.config?.consumer === "server" || options?.ssr === true;
101
- return isSSR ? "\0runner-jsx/passthrough" : "\0runner-jsx/client-runtime";
102
- },
103
- load(id) {
104
- if (id === "\0runner-jsx/client-runtime") {
105
- return CLIENT_RUNTIME_CODE;
106
- }
107
- if (id === "\0runner-jsx/passthrough") {
108
- return PASSTHROUGH_CODE;
109
- }
110
- return null;
111
- }
112
- };
17
+ if (node.name.type === "JSXMemberExpression") {
18
+ return `${node.name.object.name}.${node.name.property.name}`;
19
+ }
20
+ return null;
113
21
  }
114
-
115
- // src/features/tailwind-registry.ts
116
- import fs from "fs/promises";
117
- import glob from "fast-glob";
118
- function parseThemeColors(cssContent) {
119
- const themeColors = {};
120
- const themeRegex = /@theme\s*\{([^}]*)\}/gs;
121
- for (const match of cssContent.matchAll(themeRegex)) {
122
- const content = match[1];
123
- const colorRegex = /--color-([\w-]+):\s*([^;]+);/g;
124
- for (const colorMatch of content.matchAll(colorRegex)) {
125
- themeColors[colorMatch[1]] = colorMatch[2].trim();
126
- }
22
+ function shouldTagElement(node) {
23
+ if (node.type !== "JSXElement") {
24
+ return false;
127
25
  }
128
- const rootRegex = /:root\s*\{([^}]*)\}/gs;
129
- for (const match of cssContent.matchAll(rootRegex)) {
130
- const content = match[1];
131
- const colorRegex = /--color-([\w-]+):\s*([^;]+);/g;
132
- for (const colorMatch of content.matchAll(colorRegex)) {
133
- if (!themeColors[colorMatch[1]]) {
134
- themeColors[colorMatch[1]] = colorMatch[2].trim();
135
- }
136
- }
26
+ const openingElement = node.openingElement;
27
+ if (!openingElement) {
28
+ return false;
29
+ }
30
+ const elementName = getElementName(openingElement);
31
+ if (!elementName || NON_TAGGABLE_ELEMENTS.includes(elementName)) {
32
+ return false;
137
33
  }
138
- return themeColors;
34
+ return true;
139
35
  }
140
- function buildColorRegistry(tailwindColors = {}, tailwindSpacing = {}, themeColors = {}) {
141
- const serializedColors = JSON.stringify(
142
- tailwindColors,
143
- (_, value) => typeof value === "function" ? void 0 : value
144
- );
145
- const serializedSpacing = JSON.stringify(
146
- tailwindSpacing,
147
- (_, value) => typeof value === "function" ? void 0 : value
148
- );
149
- const serializedThemeColors = JSON.stringify(themeColors);
150
- return `
151
- (function() {
152
- var registry = { default: {}, custom: {} };
153
-
154
- var tailwindColors = ${serializedColors};
155
- if (tailwindColors && Object.keys(tailwindColors).length > 0) {
156
- Object.entries(tailwindColors).forEach(function(entry) {
157
- var name = entry[0], shades = entry[1];
158
- if (name === 'lightBlue' || name === 'warmGray' || name === 'trueGray' || name === 'coolGray' || name === 'blueGray' || typeof shades === 'function') return;
159
- if (typeof shades === 'object' && shades !== null && !Array.isArray(shades)) {
160
- registry.default[name] = {};
161
- Object.entries(shades).forEach(function(se) {
162
- var shade = se[0], value = se[1];
163
- if (typeof value === 'string') {
164
- registry.default[name][shade] = {
165
- value: value,
166
- classes: { bg: 'bg-' + name + '-' + shade, text: 'text-' + name + '-' + shade, border: 'border-' + name + '-' + shade, ring: 'ring-' + name + '-' + shade }
167
- };
168
- }
169
- });
170
- } else if (typeof shades === 'string') {
171
- registry.default[name] = {
172
- value: shades,
173
- classes: { bg: 'bg-' + name, text: 'text-' + name, border: 'border-' + name }
174
- };
175
- }
176
- });
36
+ function isStaticExpression(expression) {
37
+ if (!expression) {
38
+ return false;
39
+ }
40
+ if (expression.type === "JSXEmptyExpression") {
41
+ return true;
42
+ }
43
+ if (["NumericLiteral", "BooleanLiteral", "StringLiteral", "NullLiteral"].includes(expression.type)) {
44
+ return true;
45
+ }
46
+ if (expression.type === "ObjectExpression") {
47
+ const obj = expression;
48
+ return obj.properties.every((prop) => {
49
+ if (prop.type === "SpreadElement") {
50
+ return false;
177
51
  }
178
-
179
- var themeColors = ${serializedThemeColors};
180
- Object.entries(themeColors).forEach(function(entry) {
181
- var name = entry[0], value = entry[1];
182
- registry.custom[name] = {
183
- value: value,
184
- variable: '--color-' + name,
185
- classes: { bg: 'bg-' + name, text: 'text-' + name, border: 'border-' + name, ring: 'ring-' + name }
186
- };
187
- });
188
-
189
- var computed = getComputedStyle(document.documentElement);
190
- var cssVarArray = Array.from(computed).filter(function(p) { return p.startsWith('--'); });
191
- cssVarArray.forEach(function(prop) {
192
- if (prop.startsWith('--color-')) {
193
- var value = computed.getPropertyValue(prop).trim();
194
- var name = prop.replace('--color-', '').replace(/^-+|-+$/g, '');
195
- if (!registry.custom[name]) {
196
- registry.custom[name] = {
197
- value: value, variable: prop,
198
- classes: { bg: 'bg-' + name, text: 'text-' + name, border: 'border-' + name, ring: 'ring-' + name }
199
- };
200
- }
52
+ if (prop.type === "ObjectProperty") {
53
+ if (prop.computed) {
54
+ return false;
201
55
  }
202
- });
203
-
204
- var tailwindSpacing = ${serializedSpacing};
205
- var spacingRegistry = {};
206
- if (tailwindSpacing && Object.keys(tailwindSpacing).length > 0) {
207
- Object.entries(tailwindSpacing).forEach(function(entry) {
208
- if (typeof entry[1] === 'string') spacingRegistry[entry[0]] = entry[1];
209
- });
56
+ return isStaticExpression(prop.value);
210
57
  }
211
-
212
- var baseSpacing = '0.25rem';
213
- cssVarArray.forEach(function(prop) {
214
- if (prop === '--spacing') baseSpacing = computed.getPropertyValue(prop).trim();
215
- });
216
-
217
- if (Object.keys(spacingRegistry).length === 0) {
218
- var scale = [0, 'px', 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96];
219
- scale.forEach(function(step) {
220
- if (step === 0) { spacingRegistry['0'] = '0'; }
221
- else if (step === 'px') { spacingRegistry['px'] = '1px'; }
222
- else {
223
- var match = baseSpacing.match(/([0-9.]+)([a-z%]+)/);
224
- if (match) spacingRegistry[String(step)] = (parseFloat(match[1]) * step) + match[2];
225
- }
226
- });
58
+ return false;
59
+ });
60
+ }
61
+ if (expression.type === "ArrayExpression") {
62
+ const arr = expression;
63
+ return arr.elements.every((elem) => {
64
+ if (elem === null) {
65
+ return true;
227
66
  }
228
-
229
- window.__TAILWIND_REGISTRY__ = {
230
- colors: registry,
231
- spacing: spacingRegistry,
232
- baseSpacing: baseSpacing,
233
- timestamp: Date.now()
234
- };
235
-
236
- if (window.parent !== window) {
237
- window.parent.postMessage({ type: 'TAILWIND_REGISTRY_UPDATE', data: window.__TAILWIND_REGISTRY__ }, '*');
67
+ if (elem.type === "SpreadElement") {
68
+ return false;
238
69
  }
239
- })();
240
- `;
241
- }
242
- async function loadTailwindDefaults() {
243
- try {
244
- const defaultTheme = await import("tailwindcss/defaultTheme.js");
245
- const rawColors = defaultTheme?.default?.colors;
246
- const rawSpacing = defaultTheme?.default?.spacing;
247
- const colors = typeof rawColors === "function" ? rawColors() : rawColors ?? {};
248
- const spacing = typeof rawSpacing === "function" ? rawSpacing() : rawSpacing ?? {};
249
- return { colors, spacing };
250
- } catch {
251
- return { colors: {}, spacing: {} };
70
+ return isStaticExpression(elem);
71
+ });
252
72
  }
73
+ return false;
253
74
  }
254
- function createTailwindRegistry() {
255
- let tailwindColors = {};
256
- let tailwindSpacing = {};
257
- let themeColors = {};
258
- return {
259
- async buildStart() {
260
- const tw = await loadTailwindDefaults();
261
- tailwindColors = tw.colors;
262
- tailwindSpacing = tw.spacing;
263
- try {
264
- const cssFiles = await glob("**/*.css", {
265
- ignore: ["**/node_modules/**", "**/dist/**", "**/.next/**", "**/.git/**", "**/build/**"],
266
- cwd: process.cwd(),
267
- absolute: true
268
- });
269
- for (const file of cssFiles) {
270
- try {
271
- const content = await fs.readFile(file, "utf-8");
272
- const parsed = parseThemeColors(content);
273
- themeColors = { ...themeColors, ...parsed };
274
- } catch {
275
- }
276
- }
277
- } catch {
278
- }
279
- },
280
- transformIndexHtml(html) {
281
- const script = buildColorRegistry(tailwindColors, tailwindSpacing, themeColors);
282
- return html.replace("</body>", `<script>${script}</script></body>`);
283
- }
284
- };
285
- }
286
-
287
- // src/features/virtual-overrides.ts
288
- var LEADING_DOT_SLASH = /^\.\//;
289
- var BACKSLASH = /\\/g;
290
- function normalizePath(path) {
291
- return path.replace(LEADING_DOT_SLASH, "").replace(BACKSLASH, "/");
292
- }
293
- function isPathSafe(path) {
294
- if (path.includes("..")) {
75
+ function supportsContentEditable(jsxElement) {
76
+ if (!jsxElement.children || jsxElement.children.length === 0) {
295
77
  return false;
296
78
  }
297
- if (path.includes("node_modules")) {
79
+ const hasValidChildren = jsxElement.children.every((child) => {
80
+ if (child.type === "JSXText") {
81
+ return true;
82
+ }
83
+ if (child.type === "JSXExpressionContainer") {
84
+ return isStaticExpression(child.expression);
85
+ }
86
+ return false;
87
+ });
88
+ if (!hasValidChildren) {
298
89
  return false;
299
90
  }
300
- return true;
91
+ return jsxElement.children.some((child) => {
92
+ if (child.type === "JSXText") {
93
+ return child.value.trim().length > 0;
94
+ }
95
+ if (child.type === "JSXExpressionContainer") {
96
+ return child.expression.type !== "JSXEmptyExpression";
97
+ }
98
+ return false;
99
+ });
301
100
  }
302
- function createVirtualOverrides() {
303
- const overrides = /* @__PURE__ */ new Map();
304
- let _server = null;
305
- function invalidateAndUpdate(path) {
306
- if (!_server) {
307
- return;
101
+ function isInlineEditable(jsxElement) {
102
+ const hasStaticChildren = jsxElement.children && jsxElement.children.length > 0 && jsxElement.children.every((child) => {
103
+ if (child.type === "JSXText") {
104
+ return true;
308
105
  }
309
- const normalizedPath = normalizePath(path);
310
- const mod = _server.moduleGraph.getModuleById(normalizedPath);
311
- if (mod) {
312
- _server.moduleGraph.invalidateModule(mod);
313
- _server.ws.send({
314
- type: "update",
315
- updates: [
316
- {
317
- type: "js-update",
318
- path: mod.url,
319
- acceptedPath: mod.url,
320
- timestamp: Date.now()
321
- }
322
- ]
323
- });
106
+ if (child.type === "JSXExpressionContainer") {
107
+ return isStaticExpression(child.expression);
108
+ }
109
+ return false;
110
+ });
111
+ const hasEditableContent = jsxElement.children?.some((child) => {
112
+ if (child.type === "JSXText") {
113
+ return child.value.trim().length > 0;
114
+ }
115
+ if (child.type === "JSXExpressionContainer") {
116
+ return child.expression.type !== "JSXEmptyExpression";
324
117
  }
118
+ return false;
119
+ });
120
+ if (hasStaticChildren && hasEditableContent) {
121
+ return true;
325
122
  }
326
- return {
327
- configureServer(server) {
328
- _server = server;
329
- server.ws.on("runner:override", (data) => {
330
- const normalizedPath = normalizePath(data.path);
331
- if (!isPathSafe(normalizedPath)) {
332
- return;
333
- }
334
- overrides.set(normalizedPath, data.content);
335
- invalidateAndUpdate(normalizedPath);
336
- });
337
- server.ws.on("runner:clear-override", (data) => {
338
- const normalizedPath = normalizePath(data.path);
339
- overrides.delete(normalizedPath);
340
- invalidateAndUpdate(normalizedPath);
341
- });
342
- server.ws.on("runner:clear-all-overrides", () => {
343
- const paths = Array.from(overrides.keys());
344
- overrides.clear();
345
- for (const path of paths) {
346
- invalidateAndUpdate(path);
347
- }
348
- });
349
- },
350
- load(id) {
351
- if (!id) {
352
- return null;
123
+ if (jsxElement.openingElement.attributes && jsxElement.openingElement.attributes.length > 0) {
124
+ const hasStaticAttributes = jsxElement.openingElement.attributes.some((attr) => {
125
+ if (attr.type === "JSXSpreadAttribute") {
126
+ return false;
353
127
  }
354
- const cleanId = id.split("?")[0];
355
- const normalizedId = normalizePath(cleanId);
356
- if (!isPathSafe(normalizedId)) {
357
- return null;
128
+ if (attr.value && attr.value.type === "JSXExpressionContainer") {
129
+ return isStaticExpression(attr.value.expression);
130
+ }
131
+ if (attr.value && attr.value.type === "StringLiteral") {
132
+ return true;
358
133
  }
359
- return overrides.get(normalizedId) ?? null;
134
+ return false;
135
+ });
136
+ if (hasStaticAttributes) {
137
+ return true;
360
138
  }
361
- };
139
+ }
140
+ return false;
362
141
  }
363
142
 
364
- // src/plugin.ts
365
- function viteUuidTagger(options = {}) {
366
- const { enabled = true, extractColors = true } = options;
367
- if (!enabled) {
368
- return {
369
- name: "vite-uuid-tagger",
370
- enforce: "pre"
143
+ // src/uuid-mapping-manager.ts
144
+ import { createHash } from "crypto";
145
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
146
+ import { dirname, join } from "path";
147
+ var UUIDMappingManager = class {
148
+ mappingFile;
149
+ mappings;
150
+ constructor(projectRoot) {
151
+ this.mappingFile = join(projectRoot, "public", "uuid-mappings.json");
152
+ this.mappings = this.loadMappings();
153
+ }
154
+ loadMappings() {
155
+ try {
156
+ if (existsSync(this.mappingFile)) {
157
+ const content = readFileSync(this.mappingFile, "utf8");
158
+ return JSON.parse(content);
159
+ }
160
+ } catch {
161
+ }
162
+ return {};
163
+ }
164
+ saveMappings() {
165
+ try {
166
+ const dir = dirname(this.mappingFile);
167
+ if (!existsSync(dir)) {
168
+ mkdirSync(dir, { recursive: true });
169
+ }
170
+ writeFileSync(this.mappingFile, JSON.stringify(this.mappings, null, 2));
171
+ } catch {
172
+ }
173
+ }
174
+ generateStableUUID(seed) {
175
+ const hash = createHash("sha256").update(seed).digest("hex");
176
+ return [
177
+ hash.substring(0, 8),
178
+ hash.substring(8, 12),
179
+ hash.substring(12, 16),
180
+ hash.substring(16, 20),
181
+ hash.substring(20, 32)
182
+ ].join("-");
183
+ }
184
+ getOrCreateUUID(filePath, line, column, elementName) {
185
+ const existingUUID = Object.keys(this.mappings).find((uuid2) => {
186
+ const m = this.mappings[uuid2];
187
+ return m.filePath === filePath && m.line === line && m.column === column && m.elementName === elementName;
188
+ });
189
+ if (existingUUID) {
190
+ return existingUUID;
191
+ }
192
+ const seed = `${filePath}:${line}:${column}:${elementName}`;
193
+ const uuid = this.generateStableUUID(seed);
194
+ this.mappings[uuid] = {
195
+ filePath,
196
+ line,
197
+ column,
198
+ elementName,
199
+ lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
371
200
  };
201
+ this.saveMappings();
202
+ return uuid;
372
203
  }
373
- const jsxTagger = createJsxSourceTagger();
374
- const overrides = createVirtualOverrides();
375
- const tailwindRegistry = extractColors ? createTailwindRegistry() : null;
376
- const devMiddleware = createDevMiddleware();
204
+ };
205
+
206
+ // src/plugin.ts
207
+ function uuidTagger(options) {
208
+ const { projectRoot, scriptTagEnvVar = "VITE_DESIGN_SCRIPT_TAG" } = options;
209
+ const uuidManager = new UUIDMappingManager(projectRoot);
377
210
  return {
378
211
  name: "vite-uuid-tagger",
379
212
  enforce: "pre",
380
- resolveId(source, importer, resolveOptions) {
381
- return jsxTagger.resolveId.call(this, source, importer, resolveOptions);
382
- },
383
- load(id) {
384
- const overrideResult = overrides.load(id);
385
- if (overrideResult !== null) {
386
- return overrideResult;
213
+ async transform(code, id) {
214
+ if (shouldSkipFile(id)) {
215
+ return null;
387
216
  }
388
- return jsxTagger.load(id);
389
- },
390
- config() {
391
- return {
392
- optimizeDeps: {
393
- exclude: ["react/jsx-dev-runtime"]
217
+ const ext = path2.extname(id);
218
+ if (ext !== ".tsx" && ext !== ".jsx") {
219
+ return null;
220
+ }
221
+ const relativePath = path2.relative(projectRoot, id);
222
+ const { walk } = await import("estree-walker");
223
+ try {
224
+ const ast = parse(code, {
225
+ sourceType: "module",
226
+ plugins: ["jsx", "typescript"]
227
+ });
228
+ const magic = new MagicString(code);
229
+ let changed = 0;
230
+ walk(ast, {
231
+ enter(node) {
232
+ const n = node;
233
+ if (!shouldTagElement(n)) {
234
+ return;
235
+ }
236
+ const openingElement = n.openingElement;
237
+ const elementName = getElementName(openingElement);
238
+ if (!elementName) {
239
+ return;
240
+ }
241
+ const { line = 0, column = 0 } = openingElement.loc?.start ?? {};
242
+ const uuid = uuidManager.getOrCreateUUID(relativePath, line, column, elementName);
243
+ magic.appendLeft(openingElement.name.end ?? 0, ` data-uuid-loc="${uuid}"`);
244
+ if (supportsContentEditable(n)) {
245
+ magic.appendLeft(openingElement.name.end ?? 0, " data-content-editable");
246
+ }
247
+ if (isInlineEditable(n)) {
248
+ magic.appendLeft(openingElement.name.end ?? 0, " data-inline-editable");
249
+ }
250
+ changed++;
251
+ }
252
+ });
253
+ if (changed > 0) {
254
+ return {
255
+ code: magic.toString(),
256
+ map: magic.generateMap({ hires: true })
257
+ };
394
258
  }
395
- };
396
- },
397
- configureServer(server) {
398
- overrides.configureServer(server);
399
- devMiddleware.configureServer(server);
400
- },
401
- async buildStart() {
402
- if (tailwindRegistry) {
403
- await tailwindRegistry.buildStart();
259
+ return null;
260
+ } catch {
261
+ return null;
404
262
  }
405
263
  },
406
264
  transformIndexHtml(html) {
407
- if (tailwindRegistry) {
408
- return tailwindRegistry.transformIndexHtml(html);
409
- }
410
- return html;
265
+ const tag = process.env[scriptTagEnvVar];
266
+ const src = `https://unpkg.com/@runner-ai/design${tag ? `@${tag}` : ""}`;
267
+ return html.replace("</body>", `<script src="${src}"></script></body>`);
411
268
  }
412
269
  };
413
270
  }
414
271
  export {
415
- viteUuidTagger as default
272
+ uuidTagger
416
273
  };
package/package.json CHANGED
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "@runner-ai/vite-uuid-tagger",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
5
7
  "exports": {
6
8
  ".": {
7
9
  "types": "./dist/index.d.ts",
@@ -12,31 +14,22 @@
12
14
  "dist"
13
15
  ],
14
16
  "scripts": {
15
- "build": "tsup",
17
+ "build": "tsup src/index.ts --format esm --dts --out-dir dist",
16
18
  "test": "vitest run",
17
- "test:watch": "vitest",
18
- "typecheck": "tsc --noEmit",
19
- "clean": "rm -rf .turbo node_modules dist",
20
- "publish:dev": "bun run build && npm publish --tag dev --access public",
21
19
  "publish:prod": "bun run build && npm publish --access public"
22
20
  },
23
21
  "dependencies": {
24
- "fast-glob": "^3.3.2"
25
- },
26
- "devDependencies": {
27
- "@types/react": "^19.0.0",
28
- "tsup": "^8.5.0",
29
- "typescript": "^5.8.0",
30
- "vite": "^7.0.0",
31
- "vitest": "^3.0.0"
22
+ "@babel/parser": "^7.24.0",
23
+ "estree-walker": "^3.0.3",
24
+ "magic-string": "^0.30.0"
32
25
  },
33
26
  "peerDependencies": {
34
- "vite": ">=6.0.0",
35
- "tailwindcss": ">=3.0.0"
27
+ "vite": ">=4.0.0"
36
28
  },
37
- "peerDependenciesMeta": {
38
- "tailwindcss": {
39
- "optional": true
40
- }
29
+ "devDependencies": {
30
+ "tsup": "^8.0.0",
31
+ "vite": "^7.0.0",
32
+ "vitest": "^3.0.0",
33
+ "typescript": "^5.8.0"
41
34
  }
42
35
  }