one
Version:
One is a new React Framework that makes Vite serve both native and web.
356 lines (353 loc) • 12.4 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: true
}), mod);
var sourceInspectorPlugin_exports = {};
__export(sourceInspectorPlugin_exports, {
sourceInspectorPlugin: () => sourceInspectorPlugin
});
module.exports = __toCommonJS(sourceInspectorPlugin_exports);
var import_child_process = require("child_process");
var import_path = __toESM(require("path"), 1);
var import_oxc_parser = require("oxc-parser");
var import_vite = require("vite");
function _type_of(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
async function findJsxElements(code, filename) {
var result = await (0, import_oxc_parser.parse)(filename, code);
if (result.errors.length > 0) {
return [];
}
var locations = [];
function getJsxName(node) {
if (!node) return null;
if (node.type === "JSXIdentifier") return node.name;
if (node.type === "JSXMemberExpression") {
var _node_property;
var obj = getJsxName(node.object);
return obj ? `${obj}.${(_node_property = node.property) === null || _node_property === void 0 ? void 0 : _node_property.name}` : null;
}
return null;
}
function getLocation(offset) {
var before = code.slice(0, offset);
var lines = before.split("\n");
return {
line: lines.length,
column: lines[lines.length - 1].length + 1
};
}
function walk(node) {
if (!node || (typeof node === "undefined" ? "undefined" : _type_of(node)) !== "object") return;
if (node.type === "JSXOpeningElement" && node.name) {
var tagName = getJsxName(node.name);
if (tagName && tagName !== "Fragment" && !tagName.endsWith(".Fragment")) {
var _node_attributes;
var hasSourceAttr = (_node_attributes = node.attributes) === null || _node_attributes === void 0 ? void 0 : _node_attributes.some(function (attr) {
var _attr_name;
return attr.type === "JSXAttribute" && ((_attr_name = attr.name) === null || _attr_name === void 0 ? void 0 : _attr_name.name) === "data-one-source";
});
if (!hasSourceAttr) {
var nameEnd = node.name.end;
var loc = getLocation(node.start);
locations.push({
insertOffset: nameEnd,
line: loc.line,
column: loc.column
});
}
}
}
var _iteratorNormalCompletion = true,
_didIteratorError = false,
_iteratorError = void 0;
try {
for (var _iterator = Object.keys(node)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
if (key === "parent") continue;
var value = node[key];
if (Array.isArray(value)) {
var _iteratorNormalCompletion1 = true,
_didIteratorError1 = false,
_iteratorError1 = void 0;
try {
for (var _iterator1 = value[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
var child = _step1.value;
walk(child);
}
} catch (err) {
_didIteratorError1 = true;
_iteratorError1 = err;
} finally {
try {
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
} finally {
if (_didIteratorError1) {
throw _iteratorError1;
}
}
}
} else if (value && (typeof value === "undefined" ? "undefined" : _type_of(value)) === "object") {
walk(value);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
walk(result.program);
return locations.sort(function (a, b) {
return b.insertOffset - a.insertOffset;
});
}
async function injectSourceToJsx(code, id) {
var [filePath] = id.split("?");
if (!filePath) return;
var location = filePath.replace((0, import_vite.normalizePath)(process.cwd()), "");
if (!code.includes("<") || !code.includes(">")) {
return;
}
var jsxLocations = await findJsxElements(code, filePath);
if (jsxLocations.length === 0) {
return;
}
var result = code;
var _iteratorNormalCompletion = true,
_didIteratorError = false,
_iteratorError = void 0;
try {
for (var _iterator = jsxLocations[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var jsx = _step.value;
var sourceAttr = ` data-one-source="${location}:${jsx.line}:${jsx.column}"`;
result = result.slice(0, jsx.insertOffset) + sourceAttr + result.slice(jsx.insertOffset);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return {
code: result,
map: null
};
}
var editorWarned = false;
var editorArgs = {
code: function (f, l, c) {
return ["-g", `${f}:${l}:${c}`];
},
cursor: function (f, l, c) {
return ["-g", `${f}:${l}:${c}`];
},
codium: function (f, l, c) {
return ["-g", `${f}:${l}:${c}`];
},
vscodium: function (f, l, c) {
return ["-g", `${f}:${l}:${c}`];
},
zed: function (f, l, c) {
return [`${f}:${l}:${c}`];
},
subl: function (f, l, c) {
return [`${f}:${l}:${c}`];
},
webstorm: function (f, l, c) {
return ["--line", l, "--column", c, f];
},
idea: function (f, l, c) {
return ["--line", l, "--column", c, f];
},
vim: function (f, l) {
return [`+${l}`, f];
},
nvim: function (f, l) {
return [`+${l}`, f];
},
emacs: function (f, l, c) {
return [`+${l}:${c}`, f];
}
};
function openInEditor(editor, filePath, line, column) {
var resolved = editor || process.env.LAUNCH_EDITOR || process.env.EDITOR;
if (!resolved) {
if (!editorWarned) {
editorWarned = true;
console.warn(`[one] Set devtools.editor in your one config or LAUNCH_EDITOR env var to open files from the inspector (e.g. 'cursor', 'code', 'zed')`);
}
return;
}
var fullPath = import_path.default.join(process.cwd(), filePath);
var l = line || "1";
var c = column || "1";
var buildArgs = editorArgs[resolved];
var args = buildArgs ? buildArgs(fullPath, l, c) : [fullPath];
var child = (0, import_child_process.spawn)(resolved, args, {
stdio: "ignore",
detached: true
});
child.unref();
child.on("error", function (err) {
console.warn(`[one:source-inspector] Failed to open editor '${resolved}': ${err.message}`);
});
}
var vscodeClients = /* @__PURE__ */new Set();
function sourceInspectorPlugin(opts) {
var cache = /* @__PURE__ */new Map();
return [
// Transform plugin - injects data-one-source attributes
{
name: "one:source-inspector-transform",
enforce: "pre",
apply: "serve",
transform: {
// must run before clientTreeShakePlugin which also uses order: 'pre'
// (within same order, plugin array position determines precedence)
order: "pre",
async handler(code, id) {
var _this_environment;
var envName = (_this_environment = this.environment) === null || _this_environment === void 0 ? void 0 : _this_environment.name;
if (envName === "ios" || envName === "android") return;
if (id.includes("node_modules") || id.includes("?raw") || id.includes("dist") || id.includes("build")) {
return;
}
if (!id.endsWith(".jsx") && !id.endsWith(".tsx")) return;
if (cache.has(code)) {
return cache.get(code);
}
var out = await injectSourceToJsx(code, id);
cache.set(code, out);
if (cache.size > 100) {
cache.clear();
}
return out;
}
}
},
// Note: Inspector UI script is now injected via DevHead.tsx for SSR compatibility
// Server plugin - handles open-source requests and cursor WebSocket
{
name: "one:source-inspector-server",
apply: "serve",
configureServer(server) {
var wss = null;
import("ws").then(function (param) {
var {
WebSocketServer
} = param;
var _server_httpServer;
wss = new WebSocketServer({
noServer: true
});
(_server_httpServer = server.httpServer) === null || _server_httpServer === void 0 ? void 0 : _server_httpServer.on("upgrade", function (req, socket, head) {
if (req.url !== "/__one/cursor") return;
wss.handleUpgrade(req, socket, head, function (ws) {
vscodeClients.add(ws);
ws.on("message", function (data) {
try {
var message = JSON.parse(data.toString());
if (message.type === "cursor-position") {
server.hot.send("one:cursor-highlight", {
file: message.file,
line: message.line,
column: message.column
});
} else if (message.type === "cursor-clear") {
server.hot.send("one:cursor-highlight", {
clear: true
});
}
} catch (unused) {}
});
ws.on("close", function () {
vscodeClients.delete(ws);
server.hot.send("one:cursor-highlight", {
clear: true
});
});
});
});
});
server.middlewares.use(async function (req, res, next) {
var _req_url;
if (!((_req_url = req.url) === null || _req_url === void 0 ? void 0 : _req_url.startsWith("/__one/open-source"))) {
return next();
}
try {
var url = new URL(req.url, "http://localhost");
var source = url.searchParams.get("source");
if (!source) {
res.statusCode = 400;
res.end("Missing source parameter");
return;
}
var parts = source.split(":");
var column = parts.pop();
var line = parts.pop();
var filePath = parts.join(":");
openInEditor(opts === null || opts === void 0 ? void 0 : opts.editor, filePath, line, column);
res.statusCode = 200;
res.end("OK");
} catch (err) {
console.error("[one:source-inspector] Error:", err);
res.statusCode = 500;
res.end("Internal server error");
}
});
}
}];
}
//# sourceMappingURL=sourceInspectorPlugin.native.js.map