unplugin-zed-gpui 0.0.2 → 0.0.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.
Files changed (55) hide show
  1. package/dist/index.cjs +301 -3
  2. package/dist/{index.d.cts → index.d.ts} +1 -2
  3. package/dist/index.mjs +275 -1
  4. package/package.json +10 -44
  5. package/dist/esbuild.cjs +0 -6
  6. package/dist/esbuild.cjs.map +0 -1
  7. package/dist/esbuild.d.cts +0 -6
  8. package/dist/esbuild.d.cts.map +0 -1
  9. package/dist/esbuild.d.mts +0 -7
  10. package/dist/esbuild.d.mts.map +0 -1
  11. package/dist/esbuild.mjs +0 -7
  12. package/dist/esbuild.mjs.map +0 -1
  13. package/dist/index.d.cts.map +0 -1
  14. package/dist/index.d.mts +0 -26
  15. package/dist/index.d.mts.map +0 -1
  16. package/dist/noble.cjs +0 -7
  17. package/dist/noble.d.cts +0 -2
  18. package/dist/noble.d.mts +0 -2
  19. package/dist/noble.mjs +0 -2
  20. package/dist/rollup.cjs +0 -6
  21. package/dist/rollup.cjs.map +0 -1
  22. package/dist/rollup.d.cts +0 -1350
  23. package/dist/rollup.d.cts.map +0 -1
  24. package/dist/rollup.d.mts +0 -1351
  25. package/dist/rollup.d.mts.map +0 -1
  26. package/dist/rollup.mjs +0 -7
  27. package/dist/rollup.mjs.map +0 -1
  28. package/dist/rspack.cjs +0 -6
  29. package/dist/rspack.cjs.map +0 -1
  30. package/dist/rspack.d.cts +0 -6
  31. package/dist/rspack.d.cts.map +0 -1
  32. package/dist/rspack.d.mts +0 -7
  33. package/dist/rspack.d.mts.map +0 -1
  34. package/dist/rspack.mjs +0 -7
  35. package/dist/rspack.mjs.map +0 -1
  36. package/dist/src-CQKToE8V.cjs +0 -30417
  37. package/dist/src-CQKToE8V.cjs.map +0 -1
  38. package/dist/src-Cdq30MRu.mjs +0 -30412
  39. package/dist/src-Cdq30MRu.mjs.map +0 -1
  40. package/dist/vite.cjs +0 -6
  41. package/dist/vite.cjs.map +0 -1
  42. package/dist/vite.d.cts +0 -6
  43. package/dist/vite.d.cts.map +0 -1
  44. package/dist/vite.d.mts +0 -7
  45. package/dist/vite.d.mts.map +0 -1
  46. package/dist/vite.mjs +0 -7
  47. package/dist/vite.mjs.map +0 -1
  48. package/dist/webpack.cjs +0 -6
  49. package/dist/webpack.cjs.map +0 -1
  50. package/dist/webpack.d.cts +0 -6
  51. package/dist/webpack.d.cts.map +0 -1
  52. package/dist/webpack.d.mts +0 -7
  53. package/dist/webpack.d.mts.map +0 -1
  54. package/dist/webpack.mjs +0 -7
  55. package/dist/webpack.mjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -2,6 +2,304 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_src = require("./src-CQKToE8V.cjs");
6
- exports.default = require_src.zedGpuiPlugin;
7
- exports.zedGpuiPlugin = require_src.zedGpuiPlugin;
5
+ //#region \0rolldown/runtime.js
6
+ var __create = Object.create;
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __getProtoOf = Object.getPrototypeOf;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
14
+ key = keys[i];
15
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: ((k) => from[k]).bind(null, key),
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+ //#endregion
27
+ let unplugin = require("unplugin");
28
+ let _babel_parser = require("@babel/parser");
29
+ let _babel_types = require("@babel/types");
30
+ _babel_types = __toESM(_babel_types, 1);
31
+ let _babel_generator = require("@babel/generator");
32
+ _babel_generator = __toESM(_babel_generator, 1);
33
+ //#region src/index.ts
34
+ const defaultOptions = {
35
+ zedGpuiPackageName: "zed-gpui",
36
+ elementPath: "zed-gpui/element",
37
+ debug: false
38
+ };
39
+ const keepHTMLElementMethods = /* @__PURE__ */ new Set([
40
+ "on",
41
+ "off",
42
+ "on_",
43
+ "off_"
44
+ ]);
45
+ const factoryElementTypes = {
46
+ div: "HTMLDivElement",
47
+ span: "HTMLSpanElement",
48
+ section: "HTMLElement",
49
+ p: "HTMLParagraphElement",
50
+ input: "HTMLInputElement",
51
+ textarea: "HTMLTextAreaElement",
52
+ btn: "HTMLButtonElement",
53
+ select: "HTMLSelectElement"
54
+ };
55
+ const tagElementTypes = {
56
+ a: "HTMLAnchorElement",
57
+ button: "HTMLButtonElement",
58
+ details: "HTMLDetailsElement",
59
+ dialog: "HTMLDialogElement",
60
+ form: "HTMLFormElement",
61
+ img: "HTMLImageElement",
62
+ input: "HTMLInputElement",
63
+ label: "HTMLLabelElement",
64
+ meter: "HTMLMeterElement",
65
+ option: "HTMLOptionElement",
66
+ progress: "HTMLProgressElement",
67
+ select: "HTMLSelectElement",
68
+ textarea: "HTMLTextAreaElement",
69
+ video: "HTMLMediaElement",
70
+ audio: "HTMLMediaElement"
71
+ };
72
+ /**
73
+ * Unplugin for zed-gpui tree-shaking optimization
74
+ * Removes unused zed-gpui methods from the bundle
75
+ */
76
+ const zedGpuiPlugin = (0, unplugin.createUnplugin)((options = {}) => {
77
+ const opts = {
78
+ ...defaultOptions,
79
+ ...options
80
+ };
81
+ const usedMethods = {
82
+ unknown: /* @__PURE__ */ new Set(),
83
+ byPrototype: /* @__PURE__ */ new Map()
84
+ };
85
+ return {
86
+ name: "unplugin-zed-gpui",
87
+ transform(code, id) {
88
+ if (shouldProcessFile(id)) analyzeUsage(code, usedMethods, opts);
89
+ if (hasElementPrototypeAssign(code)) {
90
+ if (opts.debug) {
91
+ console.log(`[zed-gpui] Processing element file: ${id}`);
92
+ console.log(`[zed-gpui] Used methods:`, formatUsedMethods(usedMethods));
93
+ }
94
+ return transformElementFile(code, usedMethods, opts);
95
+ }
96
+ return null;
97
+ },
98
+ buildEnd() {
99
+ usedMethods.unknown.clear();
100
+ usedMethods.byPrototype.clear();
101
+ }
102
+ };
103
+ });
104
+ /**
105
+ * Check if a file should be analyzed for zed-gpui usage
106
+ */
107
+ function shouldProcessFile(id) {
108
+ if (id.includes("node_modules") || id.includes("dist")) return false;
109
+ return /\.(ts|js|tsx|jsx)$/.test(id);
110
+ }
111
+ /**
112
+ * Analyze code to find zed-gpui method usage
113
+ */
114
+ function analyzeUsage(code, usedMethods, options) {
115
+ try {
116
+ const ast = (0, _babel_parser.parse)(code, {
117
+ sourceType: "module",
118
+ plugins: ["typescript", "jsx"]
119
+ });
120
+ let hasZedGpuiImport = false;
121
+ const program = ast.program;
122
+ for (const node of program.body) if (_babel_types.isImportDeclaration(node)) {
123
+ const source = node.source.value;
124
+ if (source === options.zedGpuiPackageName || source.startsWith(options.zedGpuiPackageName + "/")) {
125
+ hasZedGpuiImport = true;
126
+ break;
127
+ }
128
+ }
129
+ if (!hasZedGpuiImport && !hasZedGpuiUsage(code)) return;
130
+ scanNodeForMethodCalls(program, usedMethods, /* @__PURE__ */ new Map());
131
+ if (options.debug && (usedMethods.unknown.size > 0 || usedMethods.byPrototype.size > 0)) console.log(`[zed-gpui] Found methods in file:`, formatUsedMethods(usedMethods));
132
+ } catch (error) {
133
+ if (options.debug) console.warn(`[zed-gpui] Failed to parse:`, error);
134
+ }
135
+ }
136
+ /**
137
+ * Quick check if code might contain zed-gpui usage
138
+ */
139
+ function hasZedGpuiUsage(code) {
140
+ return /\.\s*([a-z_][a-zA-Z0-9_]*)\s*\(/.test(code);
141
+ }
142
+ function hasElementPrototypeAssign(code) {
143
+ return code.includes("Object.assign") && /HTML[A-Za-z]*Element\.prototype/.test(code);
144
+ }
145
+ /**
146
+ * Recursively scan AST nodes for method calls
147
+ */
148
+ function scanNodeForMethodCalls(node, usedMethods, bindings) {
149
+ if (_babel_types.isProgram(node) || _babel_types.isBlockStatement(node)) {
150
+ const scopedBindings = new Map(bindings);
151
+ for (const child of node.body) scanNodeForMethodCalls(child, usedMethods, scopedBindings);
152
+ return;
153
+ }
154
+ if (_babel_types.isFunctionDeclaration(node) || _babel_types.isFunctionExpression(node) || _babel_types.isArrowFunctionExpression(node)) {
155
+ const scopedBindings = new Map(bindings);
156
+ for (const param of node.params) bindElementType(param, scopedBindings);
157
+ scanNodeForMethodCalls(node.body, usedMethods, scopedBindings);
158
+ return;
159
+ }
160
+ if (_babel_types.isVariableDeclaration(node)) {
161
+ for (const declaration of node.declarations) {
162
+ if (declaration.init) scanNodeForMethodCalls(declaration.init, usedMethods, bindings);
163
+ if (_babel_types.isIdentifier(declaration.id)) {
164
+ const elementType = getElementTypeFromTypeAnnotation(declaration.id) ?? (declaration.init ? inferElementType(declaration.init, bindings) : void 0);
165
+ if (elementType) bindings.set(declaration.id.name, elementType);
166
+ }
167
+ }
168
+ return;
169
+ }
170
+ if (_babel_types.isAssignmentExpression(node)) {
171
+ scanNodeForMethodCalls(node.right, usedMethods, bindings);
172
+ if (_babel_types.isIdentifier(node.left)) {
173
+ const elementType = inferElementType(node.right, bindings);
174
+ if (elementType) bindings.set(node.left.name, elementType);
175
+ } else scanNodeForMethodCalls(node.left, usedMethods, bindings);
176
+ return;
177
+ }
178
+ if (_babel_types.isCallExpression(node) && _babel_types.isMemberExpression(node.callee) && !_babel_types.isSuper(node.callee.object)) {
179
+ const property = node.callee.property;
180
+ if (_babel_types.isIdentifier(property) && /^[a-z][a-zA-Z0-9_]*$/.test(property.name)) addUsedMethod(usedMethods, inferElementType(node.callee.object, bindings), property.name);
181
+ }
182
+ for (const key in node) {
183
+ if (!Object.prototype.hasOwnProperty.call(node, key)) continue;
184
+ const child = node[key];
185
+ if (Array.isArray(child)) child.forEach((item) => item?.type && scanNodeForMethodCalls(item, usedMethods, bindings));
186
+ else if (child?.type) scanNodeForMethodCalls(child, usedMethods, bindings);
187
+ }
188
+ }
189
+ function bindElementType(node, bindings) {
190
+ if (_babel_types.isIdentifier(node)) {
191
+ const elementType = getElementTypeFromTypeAnnotation(node);
192
+ if (elementType) bindings.set(node.name, elementType);
193
+ }
194
+ }
195
+ function addUsedMethod(usedMethods, elementType, methodName) {
196
+ if (!elementType) {
197
+ usedMethods.unknown.add(methodName);
198
+ return;
199
+ }
200
+ if (!usedMethods.byPrototype.has(elementType)) usedMethods.byPrototype.set(elementType, /* @__PURE__ */ new Set());
201
+ usedMethods.byPrototype.get(elementType).add(methodName);
202
+ }
203
+ function inferElementType(node, bindings) {
204
+ if (_babel_types.isIdentifier(node)) return bindings.get(node.name);
205
+ if (_babel_types.isTSAsExpression(node) || _babel_types.isTSTypeAssertion(node)) return getElementTypeFromTsType(node.typeAnnotation) ?? inferElementType(node.expression, bindings);
206
+ if (_babel_types.isTSNonNullExpression(node)) return inferElementType(node.expression, bindings);
207
+ if (_babel_types.isCallExpression(node)) {
208
+ if (_babel_types.isMemberExpression(node.callee)) {
209
+ if (_babel_types.isIdentifier(node.callee.object, { name: "document" }) && (_babel_types.isIdentifier(node.callee.property, { name: "querySelector" }) || _babel_types.isIdentifier(node.callee.property, { name: "getElementById" }))) {
210
+ const typeArg = node.typeArguments?.params[0];
211
+ return typeArg && _babel_types.isTSType(typeArg) ? getElementTypeFromTsType(typeArg) : "HTMLElement";
212
+ }
213
+ if (_babel_types.isIdentifier(node.callee.property, { name: "createElement" }) && _babel_types.isIdentifier(node.callee.object, { name: "document" }) && _babel_types.isStringLiteral(node.arguments[0])) return tagElementTypes[node.arguments[0].value] ?? "HTMLElement";
214
+ return inferElementType(node.callee.object, bindings);
215
+ }
216
+ if (_babel_types.isIdentifier(node.callee)) {
217
+ if (node.callee.name === "h" && _babel_types.isStringLiteral(node.arguments[0])) return tagElementTypes[node.arguments[0].value] ?? "HTMLElement";
218
+ return factoryElementTypes[node.callee.name];
219
+ }
220
+ }
221
+ }
222
+ function getElementTypeFromTypeAnnotation(node) {
223
+ return node.typeAnnotation && _babel_types.isTSTypeAnnotation(node.typeAnnotation) ? getElementTypeFromTsType(node.typeAnnotation.typeAnnotation) : void 0;
224
+ }
225
+ function getElementTypeFromTsType(node) {
226
+ return _babel_types.isTSTypeReference(node) && _babel_types.isIdentifier(node.typeName) && isElementType(node.typeName.name) ? node.typeName.name : void 0;
227
+ }
228
+ function isElementType(name) {
229
+ return name === "HTMLElement" || /^HTML[A-Za-z]*Element$/.test(name);
230
+ }
231
+ /**
232
+ * Transform element.ts to remove unused methods
233
+ */
234
+ function transformElementFile(code, usedMethods, options) {
235
+ try {
236
+ const ast = (0, _babel_parser.parse)(code, {
237
+ sourceType: "module",
238
+ plugins: ["typescript"]
239
+ });
240
+ let modified = false;
241
+ const prototypeMethods = /* @__PURE__ */ new Map();
242
+ const assignments = [];
243
+ for (const node of ast.program.body) {
244
+ if (!_babel_types.isExpressionStatement(node)) continue;
245
+ for (const expression of _babel_types.isSequenceExpression(node.expression) ? node.expression.expressions : [node.expression]) {
246
+ if (!_babel_types.isCallExpression(expression) || !_babel_types.isMemberExpression(expression.callee) || !_babel_types.isIdentifier(expression.callee.object, { name: "Object" }) || !_babel_types.isIdentifier(expression.callee.property, { name: "assign" }) || expression.arguments.length < 2) continue;
247
+ const targetPrototype = getAssignedPrototype(expression.arguments[0]);
248
+ const sourceArg = unwrapExpression(expression.arguments[1]);
249
+ if (targetPrototype && _babel_types.isObjectExpression(sourceArg)) {
250
+ assignments.push({
251
+ targetPrototype,
252
+ sourceArg
253
+ });
254
+ prototypeMethods.set(targetPrototype, new Set(sourceArg.properties.map((prop) => _babel_types.isObjectProperty(prop) || _babel_types.isObjectMethod(prop) ? getPropertyName(prop.key) : void 0).filter((methodName) => !!methodName)));
255
+ }
256
+ }
257
+ }
258
+ for (const { targetPrototype, sourceArg } of assignments) {
259
+ const originalProperties = sourceArg.properties.length;
260
+ sourceArg.properties = sourceArg.properties.filter((prop) => {
261
+ if (!_babel_types.isObjectProperty(prop) && !_babel_types.isObjectMethod(prop)) return true;
262
+ const methodName = getPropertyName(prop.key);
263
+ if (!methodName || isMethodUsed(targetPrototype, methodName, usedMethods, prototypeMethods)) return true;
264
+ if (options.debug) console.log(`[zed-gpui] Removing unused method: ${targetPrototype}.${methodName}`);
265
+ return false;
266
+ });
267
+ if (sourceArg.properties.length !== originalProperties) {
268
+ modified = true;
269
+ if (options.debug) console.log(`[zed-gpui] Removed ${originalProperties - sourceArg.properties.length} unused methods from ${targetPrototype}`);
270
+ }
271
+ }
272
+ if (modified) return { code: (0, _babel_generator.default)(ast, {}, code).code };
273
+ return null;
274
+ } catch (error) {
275
+ console.error("[zed-gpui] Failed to transform element file:", error);
276
+ return null;
277
+ }
278
+ }
279
+ function getAssignedPrototype(node) {
280
+ return _babel_types.isMemberExpression(node) && _babel_types.isIdentifier(node.object) && _babel_types.isIdentifier(node.property, { name: "prototype" }) && isElementType(node.object.name) ? node.object.name : void 0;
281
+ }
282
+ function unwrapExpression(node) {
283
+ while (_babel_types.isTSAsExpression(node) || _babel_types.isTSTypeAssertion(node) || _babel_types.isTSNonNullExpression(node)) node = node.expression;
284
+ return node;
285
+ }
286
+ function getPropertyName(node) {
287
+ if (_babel_types.isIdentifier(node)) return node.name;
288
+ if (_babel_types.isStringLiteral(node)) return node.value;
289
+ }
290
+ function isMethodUsed(prototypeName, methodName, usedMethods, prototypeMethods) {
291
+ if (usedMethods.unknown.has(methodName) || usedMethods.byPrototype.get(prototypeName)?.has(methodName)) return true;
292
+ if (prototypeName !== "HTMLElement") return false;
293
+ if (keepHTMLElementMethods.has(methodName)) return true;
294
+ for (const [usedPrototype, methods] of usedMethods.byPrototype) if (usedPrototype !== "HTMLElement" && methods.has(methodName) && !prototypeMethods.get(usedPrototype)?.has(methodName)) return true;
295
+ return false;
296
+ }
297
+ function formatUsedMethods(usedMethods) {
298
+ return {
299
+ unknown: Array.from(usedMethods.unknown).sort(),
300
+ byPrototype: Object.fromEntries(Array.from(usedMethods.byPrototype.entries()).map(([prototype, methods]) => [prototype, Array.from(methods).sort()]))
301
+ };
302
+ }
303
+ //#endregion
304
+ exports.default = zedGpuiPlugin;
305
+ exports.zedGpuiPlugin = zedGpuiPlugin;
@@ -22,5 +22,4 @@ interface PluginOptions {
22
22
  */
23
23
  declare const zedGpuiPlugin: import("unplugin").UnpluginInstance<PluginOptions, boolean>;
24
24
  //#endregion
25
- export { PluginOptions, zedGpuiPlugin as default, zedGpuiPlugin };
26
- //# sourceMappingURL=index.d.cts.map
25
+ export { PluginOptions, zedGpuiPlugin as default, zedGpuiPlugin };
package/dist/index.mjs CHANGED
@@ -1,2 +1,276 @@
1
- import { t as zedGpuiPlugin } from "./src-Cdq30MRu.mjs";
1
+ import { createUnplugin } from "unplugin";
2
+ import { parse } from "@babel/parser";
3
+ import * as t from "@babel/types";
4
+ import generate from "@babel/generator";
5
+ //#region src/index.ts
6
+ const defaultOptions = {
7
+ zedGpuiPackageName: "zed-gpui",
8
+ elementPath: "zed-gpui/element",
9
+ debug: false
10
+ };
11
+ const keepHTMLElementMethods = /* @__PURE__ */ new Set([
12
+ "on",
13
+ "off",
14
+ "on_",
15
+ "off_"
16
+ ]);
17
+ const factoryElementTypes = {
18
+ div: "HTMLDivElement",
19
+ span: "HTMLSpanElement",
20
+ section: "HTMLElement",
21
+ p: "HTMLParagraphElement",
22
+ input: "HTMLInputElement",
23
+ textarea: "HTMLTextAreaElement",
24
+ btn: "HTMLButtonElement",
25
+ select: "HTMLSelectElement"
26
+ };
27
+ const tagElementTypes = {
28
+ a: "HTMLAnchorElement",
29
+ button: "HTMLButtonElement",
30
+ details: "HTMLDetailsElement",
31
+ dialog: "HTMLDialogElement",
32
+ form: "HTMLFormElement",
33
+ img: "HTMLImageElement",
34
+ input: "HTMLInputElement",
35
+ label: "HTMLLabelElement",
36
+ meter: "HTMLMeterElement",
37
+ option: "HTMLOptionElement",
38
+ progress: "HTMLProgressElement",
39
+ select: "HTMLSelectElement",
40
+ textarea: "HTMLTextAreaElement",
41
+ video: "HTMLMediaElement",
42
+ audio: "HTMLMediaElement"
43
+ };
44
+ /**
45
+ * Unplugin for zed-gpui tree-shaking optimization
46
+ * Removes unused zed-gpui methods from the bundle
47
+ */
48
+ const zedGpuiPlugin = createUnplugin((options = {}) => {
49
+ const opts = {
50
+ ...defaultOptions,
51
+ ...options
52
+ };
53
+ const usedMethods = {
54
+ unknown: /* @__PURE__ */ new Set(),
55
+ byPrototype: /* @__PURE__ */ new Map()
56
+ };
57
+ return {
58
+ name: "unplugin-zed-gpui",
59
+ transform(code, id) {
60
+ if (shouldProcessFile(id)) analyzeUsage(code, usedMethods, opts);
61
+ if (hasElementPrototypeAssign(code)) {
62
+ if (opts.debug) {
63
+ console.log(`[zed-gpui] Processing element file: ${id}`);
64
+ console.log(`[zed-gpui] Used methods:`, formatUsedMethods(usedMethods));
65
+ }
66
+ return transformElementFile(code, usedMethods, opts);
67
+ }
68
+ return null;
69
+ },
70
+ buildEnd() {
71
+ usedMethods.unknown.clear();
72
+ usedMethods.byPrototype.clear();
73
+ }
74
+ };
75
+ });
76
+ /**
77
+ * Check if a file should be analyzed for zed-gpui usage
78
+ */
79
+ function shouldProcessFile(id) {
80
+ if (id.includes("node_modules") || id.includes("dist")) return false;
81
+ return /\.(ts|js|tsx|jsx)$/.test(id);
82
+ }
83
+ /**
84
+ * Analyze code to find zed-gpui method usage
85
+ */
86
+ function analyzeUsage(code, usedMethods, options) {
87
+ try {
88
+ const ast = parse(code, {
89
+ sourceType: "module",
90
+ plugins: ["typescript", "jsx"]
91
+ });
92
+ let hasZedGpuiImport = false;
93
+ const program = ast.program;
94
+ for (const node of program.body) if (t.isImportDeclaration(node)) {
95
+ const source = node.source.value;
96
+ if (source === options.zedGpuiPackageName || source.startsWith(options.zedGpuiPackageName + "/")) {
97
+ hasZedGpuiImport = true;
98
+ break;
99
+ }
100
+ }
101
+ if (!hasZedGpuiImport && !hasZedGpuiUsage(code)) return;
102
+ scanNodeForMethodCalls(program, usedMethods, /* @__PURE__ */ new Map());
103
+ if (options.debug && (usedMethods.unknown.size > 0 || usedMethods.byPrototype.size > 0)) console.log(`[zed-gpui] Found methods in file:`, formatUsedMethods(usedMethods));
104
+ } catch (error) {
105
+ if (options.debug) console.warn(`[zed-gpui] Failed to parse:`, error);
106
+ }
107
+ }
108
+ /**
109
+ * Quick check if code might contain zed-gpui usage
110
+ */
111
+ function hasZedGpuiUsage(code) {
112
+ return /\.\s*([a-z_][a-zA-Z0-9_]*)\s*\(/.test(code);
113
+ }
114
+ function hasElementPrototypeAssign(code) {
115
+ return code.includes("Object.assign") && /HTML[A-Za-z]*Element\.prototype/.test(code);
116
+ }
117
+ /**
118
+ * Recursively scan AST nodes for method calls
119
+ */
120
+ function scanNodeForMethodCalls(node, usedMethods, bindings) {
121
+ if (t.isProgram(node) || t.isBlockStatement(node)) {
122
+ const scopedBindings = new Map(bindings);
123
+ for (const child of node.body) scanNodeForMethodCalls(child, usedMethods, scopedBindings);
124
+ return;
125
+ }
126
+ if (t.isFunctionDeclaration(node) || t.isFunctionExpression(node) || t.isArrowFunctionExpression(node)) {
127
+ const scopedBindings = new Map(bindings);
128
+ for (const param of node.params) bindElementType(param, scopedBindings);
129
+ scanNodeForMethodCalls(node.body, usedMethods, scopedBindings);
130
+ return;
131
+ }
132
+ if (t.isVariableDeclaration(node)) {
133
+ for (const declaration of node.declarations) {
134
+ if (declaration.init) scanNodeForMethodCalls(declaration.init, usedMethods, bindings);
135
+ if (t.isIdentifier(declaration.id)) {
136
+ const elementType = getElementTypeFromTypeAnnotation(declaration.id) ?? (declaration.init ? inferElementType(declaration.init, bindings) : void 0);
137
+ if (elementType) bindings.set(declaration.id.name, elementType);
138
+ }
139
+ }
140
+ return;
141
+ }
142
+ if (t.isAssignmentExpression(node)) {
143
+ scanNodeForMethodCalls(node.right, usedMethods, bindings);
144
+ if (t.isIdentifier(node.left)) {
145
+ const elementType = inferElementType(node.right, bindings);
146
+ if (elementType) bindings.set(node.left.name, elementType);
147
+ } else scanNodeForMethodCalls(node.left, usedMethods, bindings);
148
+ return;
149
+ }
150
+ if (t.isCallExpression(node) && t.isMemberExpression(node.callee) && !t.isSuper(node.callee.object)) {
151
+ const property = node.callee.property;
152
+ if (t.isIdentifier(property) && /^[a-z][a-zA-Z0-9_]*$/.test(property.name)) addUsedMethod(usedMethods, inferElementType(node.callee.object, bindings), property.name);
153
+ }
154
+ for (const key in node) {
155
+ if (!Object.prototype.hasOwnProperty.call(node, key)) continue;
156
+ const child = node[key];
157
+ if (Array.isArray(child)) child.forEach((item) => item?.type && scanNodeForMethodCalls(item, usedMethods, bindings));
158
+ else if (child?.type) scanNodeForMethodCalls(child, usedMethods, bindings);
159
+ }
160
+ }
161
+ function bindElementType(node, bindings) {
162
+ if (t.isIdentifier(node)) {
163
+ const elementType = getElementTypeFromTypeAnnotation(node);
164
+ if (elementType) bindings.set(node.name, elementType);
165
+ }
166
+ }
167
+ function addUsedMethod(usedMethods, elementType, methodName) {
168
+ if (!elementType) {
169
+ usedMethods.unknown.add(methodName);
170
+ return;
171
+ }
172
+ if (!usedMethods.byPrototype.has(elementType)) usedMethods.byPrototype.set(elementType, /* @__PURE__ */ new Set());
173
+ usedMethods.byPrototype.get(elementType).add(methodName);
174
+ }
175
+ function inferElementType(node, bindings) {
176
+ if (t.isIdentifier(node)) return bindings.get(node.name);
177
+ if (t.isTSAsExpression(node) || t.isTSTypeAssertion(node)) return getElementTypeFromTsType(node.typeAnnotation) ?? inferElementType(node.expression, bindings);
178
+ if (t.isTSNonNullExpression(node)) return inferElementType(node.expression, bindings);
179
+ if (t.isCallExpression(node)) {
180
+ if (t.isMemberExpression(node.callee)) {
181
+ if (t.isIdentifier(node.callee.object, { name: "document" }) && (t.isIdentifier(node.callee.property, { name: "querySelector" }) || t.isIdentifier(node.callee.property, { name: "getElementById" }))) {
182
+ const typeArg = node.typeArguments?.params[0];
183
+ return typeArg && t.isTSType(typeArg) ? getElementTypeFromTsType(typeArg) : "HTMLElement";
184
+ }
185
+ if (t.isIdentifier(node.callee.property, { name: "createElement" }) && t.isIdentifier(node.callee.object, { name: "document" }) && t.isStringLiteral(node.arguments[0])) return tagElementTypes[node.arguments[0].value] ?? "HTMLElement";
186
+ return inferElementType(node.callee.object, bindings);
187
+ }
188
+ if (t.isIdentifier(node.callee)) {
189
+ if (node.callee.name === "h" && t.isStringLiteral(node.arguments[0])) return tagElementTypes[node.arguments[0].value] ?? "HTMLElement";
190
+ return factoryElementTypes[node.callee.name];
191
+ }
192
+ }
193
+ }
194
+ function getElementTypeFromTypeAnnotation(node) {
195
+ return node.typeAnnotation && t.isTSTypeAnnotation(node.typeAnnotation) ? getElementTypeFromTsType(node.typeAnnotation.typeAnnotation) : void 0;
196
+ }
197
+ function getElementTypeFromTsType(node) {
198
+ return t.isTSTypeReference(node) && t.isIdentifier(node.typeName) && isElementType(node.typeName.name) ? node.typeName.name : void 0;
199
+ }
200
+ function isElementType(name) {
201
+ return name === "HTMLElement" || /^HTML[A-Za-z]*Element$/.test(name);
202
+ }
203
+ /**
204
+ * Transform element.ts to remove unused methods
205
+ */
206
+ function transformElementFile(code, usedMethods, options) {
207
+ try {
208
+ const ast = parse(code, {
209
+ sourceType: "module",
210
+ plugins: ["typescript"]
211
+ });
212
+ let modified = false;
213
+ const prototypeMethods = /* @__PURE__ */ new Map();
214
+ const assignments = [];
215
+ for (const node of ast.program.body) {
216
+ if (!t.isExpressionStatement(node)) continue;
217
+ for (const expression of t.isSequenceExpression(node.expression) ? node.expression.expressions : [node.expression]) {
218
+ if (!t.isCallExpression(expression) || !t.isMemberExpression(expression.callee) || !t.isIdentifier(expression.callee.object, { name: "Object" }) || !t.isIdentifier(expression.callee.property, { name: "assign" }) || expression.arguments.length < 2) continue;
219
+ const targetPrototype = getAssignedPrototype(expression.arguments[0]);
220
+ const sourceArg = unwrapExpression(expression.arguments[1]);
221
+ if (targetPrototype && t.isObjectExpression(sourceArg)) {
222
+ assignments.push({
223
+ targetPrototype,
224
+ sourceArg
225
+ });
226
+ prototypeMethods.set(targetPrototype, new Set(sourceArg.properties.map((prop) => t.isObjectProperty(prop) || t.isObjectMethod(prop) ? getPropertyName(prop.key) : void 0).filter((methodName) => !!methodName)));
227
+ }
228
+ }
229
+ }
230
+ for (const { targetPrototype, sourceArg } of assignments) {
231
+ const originalProperties = sourceArg.properties.length;
232
+ sourceArg.properties = sourceArg.properties.filter((prop) => {
233
+ if (!t.isObjectProperty(prop) && !t.isObjectMethod(prop)) return true;
234
+ const methodName = getPropertyName(prop.key);
235
+ if (!methodName || isMethodUsed(targetPrototype, methodName, usedMethods, prototypeMethods)) return true;
236
+ if (options.debug) console.log(`[zed-gpui] Removing unused method: ${targetPrototype}.${methodName}`);
237
+ return false;
238
+ });
239
+ if (sourceArg.properties.length !== originalProperties) {
240
+ modified = true;
241
+ if (options.debug) console.log(`[zed-gpui] Removed ${originalProperties - sourceArg.properties.length} unused methods from ${targetPrototype}`);
242
+ }
243
+ }
244
+ if (modified) return { code: generate(ast, {}, code).code };
245
+ return null;
246
+ } catch (error) {
247
+ console.error("[zed-gpui] Failed to transform element file:", error);
248
+ return null;
249
+ }
250
+ }
251
+ function getAssignedPrototype(node) {
252
+ return t.isMemberExpression(node) && t.isIdentifier(node.object) && t.isIdentifier(node.property, { name: "prototype" }) && isElementType(node.object.name) ? node.object.name : void 0;
253
+ }
254
+ function unwrapExpression(node) {
255
+ while (t.isTSAsExpression(node) || t.isTSTypeAssertion(node) || t.isTSNonNullExpression(node)) node = node.expression;
256
+ return node;
257
+ }
258
+ function getPropertyName(node) {
259
+ if (t.isIdentifier(node)) return node.name;
260
+ if (t.isStringLiteral(node)) return node.value;
261
+ }
262
+ function isMethodUsed(prototypeName, methodName, usedMethods, prototypeMethods) {
263
+ if (usedMethods.unknown.has(methodName) || usedMethods.byPrototype.get(prototypeName)?.has(methodName)) return true;
264
+ if (prototypeName !== "HTMLElement") return false;
265
+ if (keepHTMLElementMethods.has(methodName)) return true;
266
+ for (const [usedPrototype, methods] of usedMethods.byPrototype) if (usedPrototype !== "HTMLElement" && methods.has(methodName) && !prototypeMethods.get(usedPrototype)?.has(methodName)) return true;
267
+ return false;
268
+ }
269
+ function formatUsedMethods(usedMethods) {
270
+ return {
271
+ unknown: Array.from(usedMethods.unknown).sort(),
272
+ byPrototype: Object.fromEntries(Array.from(usedMethods.byPrototype.entries()).map(([prototype, methods]) => [prototype, Array.from(methods).sort()]))
273
+ };
274
+ }
275
+ //#endregion
2
276
  export { zedGpuiPlugin as default, zedGpuiPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unplugin-zed-gpui",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Unplugin for zed-gpui tree-shaking optimization - removes unused zed-gpui methods from bundle",
5
5
  "author": {
6
6
  "name": "Kasukabe Tsumugi",
@@ -8,51 +8,15 @@
8
8
  },
9
9
  "license": "MIT",
10
10
  "type": "module",
11
- "main": "./dist/index.js",
12
- "module": "./dist/index.js",
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.mjs",
13
13
  "types": "./dist/index.d.ts",
14
14
  "exports": {
15
15
  ".": {
16
16
  "types": "./dist/index.d.ts",
17
- "import": "./dist/index.js",
17
+ "import": "./dist/index.mjs",
18
18
  "require": "./dist/index.cjs",
19
- "default": "./dist/index.js"
20
- },
21
- "./noble": {
22
- "types": "./dist/noble.d.ts",
23
- "import": "./dist/noble.js",
24
- "require": "./dist/noble.cjs",
25
- "default": "./dist/noble.js"
26
- },
27
- "./vite": {
28
- "types": "./dist/vite.d.ts",
29
- "import": "./dist/vite.mjs",
30
- "require": "./dist/vite.cjs",
31
- "default": "./dist/vite.mjs"
32
- },
33
- "./webpack": {
34
- "types": "./dist/webpack.d.ts",
35
- "import": "./dist/webpack.mjs",
36
- "require": "./dist/webpack.cjs",
37
- "default": "./dist/webpack.mjs"
38
- },
39
- "./rollup": {
40
- "types": "./dist/rollup.d.ts",
41
- "import": "./dist/rollup.mjs",
42
- "require": "./dist/rollup.cjs",
43
- "default": "./dist/rollup.mjs"
44
- },
45
- "./esbuild": {
46
- "types": "./dist/esbuild.d.ts",
47
- "import": "./dist/esbuild.mjs",
48
- "require": "./dist/esbuild.cjs",
49
- "default": "./dist/esbuild.mjs"
50
- },
51
- "./rspack": {
52
- "types": "./dist/rspack.d.ts",
53
- "import": "./dist/rspack.mjs",
54
- "require": "./dist/rspack.cjs",
55
- "default": "./dist/rspack.mjs"
19
+ "default": "./dist/index.mjs"
56
20
  }
57
21
  },
58
22
  "files": [
@@ -72,9 +36,6 @@
72
36
  "unplugin": "^1.0.0"
73
37
  },
74
38
  "devDependencies": {
75
- "@babel/generator": "^8.0.0",
76
- "@babel/parser": "^8.0.0",
77
- "@babel/types": "^8.0.0",
78
39
  "@types/node": "^25.9.1",
79
40
  "tsdown": "^0.22.3",
80
41
  "typescript": "^6.0.3",
@@ -85,6 +46,11 @@
85
46
  "url": "https://github.com/baendlorel/gpui-ts",
86
47
  "directory": "packages/unplugin-zed-gpui-treeshake"
87
48
  },
49
+ "dependencies": {
50
+ "@babel/generator": "^8.0.0",
51
+ "@babel/parser": "^8.0.0",
52
+ "@babel/types": "^8.0.0"
53
+ },
88
54
  "scripts": {
89
55
  "build": "tsdown",
90
56
  "dev": "tsdown --watch"
package/dist/esbuild.cjs DELETED
@@ -1,6 +0,0 @@
1
- //#region src/esbuild.ts
2
- var esbuild_default = require("./src-CQKToE8V.cjs").zedGpuiPlugin.esbuild;
3
- //#endregion
4
- module.exports = esbuild_default;
5
-
6
- //# sourceMappingURL=esbuild.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"esbuild.cjs","names":["zedGpuiPlugin"],"sources":["../src/esbuild.ts"],"sourcesContent":["import { zedGpuiPlugin } from './index.js';\n\nexport default zedGpuiPlugin.esbuild;\n"],"mappings":";AAEA,IAAA,8CAAeA,CAAAA,CAAAA,cAAc"}