mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
this kind of works, but there is a crash when bundling. I think its missing a Stmt.Data.Store.reset()
This commit is contained in:
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
// {
|
||||
// "type": "lldb",
|
||||
// "request": "launch",
|
||||
@@ -65,9 +67,10 @@
|
||||
"--resolve=lazy",
|
||||
"--outdir=public",
|
||||
"--serve",
|
||||
"--public-url=http://localhost:9000/"
|
||||
"--public-url=http://localhost:9000/",
|
||||
"--framework=./framework.tsx"
|
||||
],
|
||||
"cwd": "${workspaceFolder}/demos/simple-react",
|
||||
"cwd": "${workspaceFolder}/demos/css-stress-test",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
|
||||
0
.vscode/settings.json
vendored
Normal file
0
.vscode/settings.json
vendored
Normal file
10
build.zig
10
build.zig
@@ -114,11 +114,12 @@ pub fn build(b: *std.build.Builder) void {
|
||||
exe.setTarget(target);
|
||||
exe.setBuildMode(mode);
|
||||
b.install_path = output_dir;
|
||||
|
||||
var javascript: @TypeOf(exe) = undefined;
|
||||
// exe.want_lto = true;
|
||||
if (!target.getCpuArch().isWasm()) {
|
||||
addPicoHTTP(exe, cwd);
|
||||
var javascript = b.addExecutable("spjs", "src/main_javascript.zig");
|
||||
javascript = b.addExecutable("spjs", "src/main_javascript.zig");
|
||||
addPicoHTTP(javascript, cwd);
|
||||
javascript.packages = std.ArrayList(std.build.Pkg).fromOwnedSlice(std.heap.c_allocator, std.heap.c_allocator.dupe(std.build.Pkg, exe.packages.items) catch unreachable);
|
||||
javascript.setOutputDir(output_dir);
|
||||
javascript.setBuildMode(mode);
|
||||
@@ -131,11 +132,14 @@ pub fn build(b: *std.build.Builder) void {
|
||||
}
|
||||
|
||||
javascript.strip = false;
|
||||
javascript.install();
|
||||
}
|
||||
|
||||
exe.install();
|
||||
|
||||
if (!target.getCpuArch().isWasm()) {
|
||||
javascript.install();
|
||||
}
|
||||
|
||||
const run_cmd = exe.run();
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| {
|
||||
|
||||
28
demos/css-stress-test/framework.tsx
Normal file
28
demos/css-stress-test/framework.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import ReactDOMServer from "react-dom/server.browser";
|
||||
import { Base } from "./src/index";
|
||||
|
||||
addEventListener("fetch", (event: FetchEvent) => {
|
||||
const response = new Response(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
crossorigin="anonymous"
|
||||
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;700&family=Space+Mono:wght@400;700"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<link rel="stylesheet" href="./src/index.css" />
|
||||
<div id="reactroot">${ReactDOMServer.renderToString(<Base />)}</div>
|
||||
|
||||
<script src="./src/index.tsx" async type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
|
||||
event.respondWith(response);
|
||||
});
|
||||
|
||||
// typescript isolated modules
|
||||
export {};
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"@snowpack/plugin-react-refresh": "^2.5.0",
|
||||
"typescript": "^4.3.4"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import ReactDOMServer from "react-dom/server.browser";
|
||||
|
||||
import { Main } from "./main";
|
||||
import classNames from "classnames";
|
||||
const Base = ({}) => {
|
||||
@@ -15,10 +13,6 @@ function startReact() {
|
||||
ReactDOM.render(<Base />, document.querySelector("#reactroot"));
|
||||
}
|
||||
|
||||
function ssr() {
|
||||
console.log(ReactDOMServer.renderToString(<Base />));
|
||||
}
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
console.log("HERE!!");
|
||||
globalThis.addEventListener("DOMContentLoaded", () => {
|
||||
@@ -26,8 +20,6 @@ if (typeof window !== "undefined") {
|
||||
});
|
||||
|
||||
startReact();
|
||||
} else {
|
||||
ssr();
|
||||
}
|
||||
|
||||
export { Base };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"lib": ["dom", "dom.iterable", "esnext", "WebWorker"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
|
||||
318
out.txt
318
out.txt
@@ -1,318 +0,0 @@
|
||||
/Users/jarredsumner/Code/esdev: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo/.: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo/./pages/..: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/.: readFile error -- IsDir/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/.: readFile error -- IsDir
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo/.": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo/./pages/..": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/.": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot read file "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/.": IsDir
|
||||
|
||||
|
||||
|
||||
error: Cannot assign to property on import "newObj"
|
||||
"use strict";exports.__esModule=true;exports.defaultHead=defaultHead;exports.default=void 0;var _react=_interopRequireWildcard(require("react"));var _sideEffect=_interopRequireDefault(require("./side-effect"));var _ampContext=require("./amp-context");var _headManagerContext=require("./head-manager-context");var _amp=require("./amp");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _getRequireWildcardCache(){if(typeof WeakMap!=="function")return null;var cache=new WeakMap();_getRequireWildcardCache=function(){return cache;};return cache;}function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj};}var cache=_getRequireWildcardCache();if(cache&&cache.has(obj)){return cache.get(obj);}var newObj={};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc);}else{newObj[key]=obj[key];}}}newObj.default=obj;if(cache){cache.set(obj,newObj);}return newObj;}function defaultHead(inAmpMode=false){const head=[/*#__PURE__*/_react.default.createElement("meta",{charSet:"utf-8"})];if(!inAmpMode){head.push(/*#__PURE__*/_react.default.createElement("meta",{name:"viewport",content:"width=device-width"}));}return head;}function onlyReactElement(list,child){// React children can be "string" or "number" in this case we ignore them for backwards compat
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/next-server/lib/head.js:1:1149 1148
|
||||
|
||||
|
||||
error: Cannot assign to property on import "metaCategories"
|
||||
switch(h.type){case'title':case'base':if(tags.has(h.type)){isUnique=false;}else{tags.add(h.type);}break;case'meta':for(let i=0,len=METATYPES.length;i<len;i++){const metatype=METATYPES[i];if(!h.props.hasOwnProperty(metatype))continue;if(metatype==='charSet'){if(metaTypes.has(metatype)){isUnique=false;}else{metaTypes.add(metatype);}}else{const category=h.props[metatype];const categories=metaCategories[metatype]||new Set();if((metatype!=='name'||!hasKey)&&categories.has(category)){isUnique=false;}else{categories.add(category);metaCategories[metatype]=categories;}}}break;}return isUnique;};}/**
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/next-server/lib/head.js:8:530 3158
|
||||
|
||||
|
||||
error: Cannot assign to property on import "newProps"
|
||||
['https://fonts.googleapis.com/css'].some(url=>c.props['href'].startsWith(url))){const newProps={...(c.props||{})};newProps['data-href']=newProps['href'];newProps['href']=undefined;return/*#__PURE__*/_react.default.cloneElement(c,newProps);}}return/*#__PURE__*/_react.default.cloneElement(c,{key});});}/**
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/next-server/lib/head.js:12:116 3986
|
||||
|
||||
|
||||
error: Cannot assign to property on import "newProps"
|
||||
['https://fonts.googleapis.com/css'].some(url=>c.props['href'].startsWith(url))){const newProps={...(c.props||{})};newProps['data-href']=newProps['href'];newProps['href']=undefined;return/*#__PURE__*/_react.default.cloneElement(c,newProps);}}return/*#__PURE__*/_react.default.cloneElement(c,{key});});}/**
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/next-server/lib/head.js:12:155 4025
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./node_modules/@babel": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/node_modules/@babel": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/@babel/runtime": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/node_modules/@babel/runtime": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/node_modules/@babel/runtime": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/node_modules/@babel/runtime/helpers": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./node_modules/react": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/node_modules/react": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Expected ")" but found ,
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:89 2171
|
||||
|
||||
|
||||
error: Expected ";" but found )
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:120 2202
|
||||
|
||||
|
||||
error: Expected ")" but found ,
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:338 2420
|
||||
|
||||
|
||||
error: Expected ";" but found )
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:340 2422
|
||||
|
||||
|
||||
error: Cannot assign to property on import "d"
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:157 2239
|
||||
|
||||
|
||||
error: Cannot assign to property on import "f"
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:259 2341
|
||||
|
||||
|
||||
error: Cannot assign to property on import "d"
|
||||
function J(a,b,c){var e,d={},k=null,h=null;if(null!=b)for(e in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)H.call(b,e)&&!I.hasOwnProperty(e)&&(d[e]=b[e]);var g=arguments.length-2;if(1===g)d.children=c;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];d.children=f}if(a&&a.defaultProps)for(e in g=a.defaultProps,g)void 0===d[e]&&(d[e]=g[e]);return{$$typeof:n,type:a,key:k,ref:h,props:d,_owner:G.current}}
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:14:357 2439
|
||||
|
||||
|
||||
error: Cannot assign to property on import "e"
|
||||
exports.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error(z(267,a));var e=l({},a.props),d=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=G.current);void 0!==b.key&&(d=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)H.call(b,f)&&!I.hasOwnProperty(f)&&(e[f]=void 0===b[f]&&void 0!==g?g[f]:b[f])}var f=arguments.length-2;if(1===f)e.children=c;else if(1<f){g=Array(f);for(var m=0;m<f;m++)g[m]=arguments[m+2];e.children=g}return{$$typeof:n,type:a.type,
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:20:314 4973
|
||||
|
||||
|
||||
error: Cannot assign to property on import "g"
|
||||
exports.cloneElement=function(a,b,c){if(null===a||void 0===a)throw Error(z(267,a));var e=l({},a.props),d=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=G.current);void 0!==b.key&&(d=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)H.call(b,f)&&!I.hasOwnProperty(f)&&(e[f]=void 0===b[f]&&void 0!==g?g[f]:b[f])}var f=arguments.length-2;if(1===f)e.children=c;else if(1<f){g=Array(f);for(var m=0;m<f;m++)g[m]=arguments[m+2];e.children=g}return{$$typeof:n,type:a.type,
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.production.min.js:20:447 5106
|
||||
|
||||
|
||||
error: Cannot assign to property on import "args"
|
||||
args[_key - 1] = arguments[_key];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:184:7 5256
|
||||
|
||||
|
||||
error: Cannot assign to property on import "args"
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:193:7 5499
|
||||
|
||||
|
||||
error: Cannot assign to property on import "didWarnStateUpdateForUnmountedComponent"
|
||||
didWarnStateUpdateForUnmountedComponent[warningKey] = true;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:238:5 7144
|
||||
|
||||
|
||||
error: Cannot assign to property on import "didWarnAboutStringRefs"
|
||||
didWarnAboutStringRefs[componentName] = true;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:622:9 19312
|
||||
|
||||
|
||||
error: Cannot assign to property on import "props"
|
||||
props[propName] = config[propName];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:734:9 22825
|
||||
|
||||
|
||||
error: Cannot assign to property on import "childArray"
|
||||
childArray[i] = arguments[i + 2];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:749:7 23234
|
||||
|
||||
|
||||
error: Cannot assign to property on import "props"
|
||||
props[propName] = defaultProps[propName];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:767:9 23588
|
||||
|
||||
|
||||
error: Cannot assign to property on import "props"
|
||||
props[propName] = defaultProps[propName];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:842:11 25862
|
||||
|
||||
|
||||
error: Cannot assign to property on import "props"
|
||||
props[propName] = config[propName];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:844:11 25931
|
||||
|
||||
|
||||
error: Cannot assign to property on import "childArray"
|
||||
childArray[i] = arguments[i + 2];
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:860:7 26350
|
||||
|
||||
|
||||
error: Cannot use "break" here
|
||||
break;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:1790:11 55454
|
||||
|
||||
|
||||
error: Cannot assign to property on import "loggedTypeFailures"
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:1932:11 60269
|
||||
|
||||
|
||||
error: Cannot assign to property on import "ownerHasKeyUseWarning"
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:2038:3 62986
|
||||
|
||||
|
||||
error: Cannot use "break" here
|
||||
break;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./cjs/react.development.js:2169:9 67164
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/./node_modules/object-assign": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/react/node_modules/object-assign": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/object-assign": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/src/api/demo/node_modules/object-assign": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Cannot read directory "/Users/jarredsumner/Code/esdev/node_modules/object-assign": FileNotFound
|
||||
|
||||
|
||||
|
||||
error: Unexpected "super"
|
||||
"use strict";exports.__esModule=true;exports.default=void 0;var _react=require("react");const isServer=typeof window==='undefined';class _default extends _react.Component{constructor(props){super(props);this._hasHeadManager=void 0;this.emitChange=()=>{if(this._hasHeadManager){this.props.headManager.updateHead(this.props.reduceComponentsToState([...this.props.headManager.mountedInstances],this.props));}};this._hasHeadManager=this.props.headManager&&this.props.headManager.mountedInstances;if(isServer&&this._hasHeadManager){this.props.headManager.mountedInstances.add(this);this.emitChange();}}componentDidMount(){if(this._hasHeadManager){this.props.headManager.mountedInstances.add(this);}this.emitChange();}componentDidUpdate(){this.emitChange();}componentWillUnmount(){if(this._hasHeadManager){this.props.headManager.mountedInstances.delete(this);}this.emitChange();}render(){return null;}}exports.default=_default;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/next-server/lib/./side-effect.js:1:191 190
|
||||
|
||||
|
||||
error: Cannot assign to property on import "newObj"
|
||||
"use strict";exports.__esModule=true;exports.defaultHead=defaultHead;exports.default=void 0;var _react=_interopRequireWildcard(require("react"));var _sideEffect=_interopRequireDefault(require("./side-effect"));var _ampContext=require("./amp-context");var _headManagerContext=require("./head-manager-context");var _amp=require("./amp");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function _getRequireWildcardCache(){if(typeof WeakMap!=="function")return null;var cache=new WeakMap();_getRequireWildcardCache=function(){return cache;};return cache;}function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj;}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj};}var cache=_getRequireWildcardCache();if(cache&&cache.has(obj)){return cache.get(obj);}var newObj={};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc);}else{newObj[key]=obj[key];}}}newObj.default=obj;if(cache){cache.set(obj,newObj);}return newObj;}function defaultHead(inAmpMode=false){const head=[/*#__PURE__*/_react.default.createElement("meta",{charSet:"utf-8"})];if(!inAmpMode){head.push(/*#__PURE__*/_react.default.createElement("meta",{name:"viewport",content:"width=device-width"}));}return head;}function onlyReactElement(list,child){// React children can be "string" or "number" in this case we ignore them for backwards compat
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/client/../next-server/lib/head.js:1:1149 1148
|
||||
|
||||
|
||||
error: Cannot assign to property on import "metaCategories"
|
||||
switch(h.type){case'title':case'base':if(tags.has(h.type)){isUnique=false;}else{tags.add(h.type);}break;case'meta':for(let i=0,len=METATYPES.length;i<len;i++){const metatype=METATYPES[i];if(!h.props.hasOwnProperty(metatype))continue;if(metatype==='charSet'){if(metaTypes.has(metatype)){isUnique=false;}else{metaTypes.add(metatype);}}else{const category=h.props[metatype];const categories=metaCategories[metatype]||new Set();if((metatype!=='name'||!hasKey)&&categories.has(category)){isUnique=false;}else{categories.add(category);metaCategories[metatype]=categories;}}}break;}return isUnique;};}/**
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/client/../next-server/lib/head.js:8:530 3158
|
||||
|
||||
|
||||
error: Cannot assign to property on import "newProps"
|
||||
['https://fonts.googleapis.com/css'].some(url=>c.props['href'].startsWith(url))){const newProps={...(c.props||{})};newProps['data-href']=newProps['href'];newProps['href']=undefined;return/*#__PURE__*/_react.default.cloneElement(c,newProps);}}return/*#__PURE__*/_react.default.cloneElement(c,{key});});}/**
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/client/../next-server/lib/head.js:12:116 3986
|
||||
|
||||
|
||||
error: Cannot assign to property on import "newProps"
|
||||
['https://fonts.googleapis.com/css'].some(url=>c.props['href'].startsWith(url))){const newProps={...(c.props||{})};newProps['data-href']=newProps['href'];newProps['href']=undefined;return/*#__PURE__*/_react.default.cloneElement(c,newProps);}}return/*#__PURE__*/_react.default.cloneElement(c,{key});});}/**
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/client/../next-server/lib/head.js:12:155 4025
|
||||
|
||||
|
||||
error: Unexpected "super"
|
||||
"use strict";exports.__esModule=true;exports.default=void 0;var _react=require("react");const isServer=typeof window==='undefined';class _default extends _react.Component{constructor(props){super(props);this._hasHeadManager=void 0;this.emitChange=()=>{if(this._hasHeadManager){this.props.headManager.updateHead(this.props.reduceComponentsToState([...this.props.headManager.mountedInstances],this.props));}};this._hasHeadManager=this.props.headManager&&this.props.headManager.mountedInstances;if(isServer&&this._hasHeadManager){this.props.headManager.mountedInstances.add(this);this.emitChange();}}componentDidMount(){if(this._hasHeadManager){this.props.headManager.mountedInstances.add(this);}this.emitChange();}componentDidUpdate(){this.emitChange();}componentWillUnmount(){if(this._hasHeadManager){this.props.headManager.mountedInstances.delete(this);}this.emitChange();}render(){return null;}}exports.default=_default;
|
||||
|
||||
/Users/jarredsumner/Code/esdev/src/api/demo/./node_modules/next/./dist/client/../next-server/lib/./side-effect.js:1:191 190
|
||||
|
||||
1
src/api/schema.d.ts
vendored
1
src/api/schema.d.ts
vendored
@@ -256,6 +256,7 @@ type uint32 = number;
|
||||
only_scan_dependencies?: ScanDependencyMode;
|
||||
generate_node_module_bundle?: boolean;
|
||||
node_modules_bundle_path?: string;
|
||||
javascript_framework_file?: string;
|
||||
}
|
||||
|
||||
export interface FileHandle {
|
||||
|
||||
@@ -671,6 +671,10 @@ function decodeTransformOptions(bb) {
|
||||
result["node_modules_bundle_path"] = bb.readString();
|
||||
break;
|
||||
|
||||
case 22:
|
||||
result["javascript_framework_file"] = bb.readString();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Attempted to parse invalid message");
|
||||
}
|
||||
@@ -835,6 +839,12 @@ bb.writeByte(encoded);
|
||||
bb.writeByte(21);
|
||||
bb.writeString(value);
|
||||
}
|
||||
|
||||
var value = message["javascript_framework_file"];
|
||||
if (value != null) {
|
||||
bb.writeByte(22);
|
||||
bb.writeString(value);
|
||||
}
|
||||
bb.writeByte(0);
|
||||
|
||||
}
|
||||
|
||||
@@ -168,6 +168,8 @@ message TransformOptions {
|
||||
bool generate_node_module_bundle = 20;
|
||||
|
||||
string node_modules_bundle_path = 21;
|
||||
|
||||
string javascript_framework_file = 22;
|
||||
}
|
||||
|
||||
struct FileHandle {
|
||||
|
||||
@@ -823,6 +823,9 @@ generate_node_module_bundle: ?bool = null,
|
||||
/// node_modules_bundle_path
|
||||
node_modules_bundle_path: ?[]const u8 = null,
|
||||
|
||||
/// javascript_framework_file
|
||||
javascript_framework_file: ?[]const u8 = null,
|
||||
|
||||
|
||||
pub fn decode(reader: anytype) anyerror!TransformOptions {
|
||||
var this = std.mem.zeroes(TransformOptions);
|
||||
@@ -893,6 +896,9 @@ pub fn decode(reader: anytype) anyerror!TransformOptions {
|
||||
},
|
||||
21 => {
|
||||
this.node_modules_bundle_path = try reader.readValue([]const u8);
|
||||
},
|
||||
22 => {
|
||||
this.javascript_framework_file = try reader.readValue([]const u8);
|
||||
},
|
||||
else => {
|
||||
return error.InvalidMessage;
|
||||
@@ -987,6 +993,10 @@ if (this.node_modules_bundle_path) |node_modules_bundle_path| {
|
||||
try writer.writeFieldID(21);
|
||||
try writer.writeValue(node_modules_bundle_path);
|
||||
}
|
||||
if (this.javascript_framework_file) |javascript_framework_file| {
|
||||
try writer.writeFieldID(22);
|
||||
try writer.writeValue(javascript_framework_file);
|
||||
}
|
||||
try writer.endMessage();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ pub const Cli = struct {
|
||||
clap.parseParam("--scan Instead of bundling or transpiling, print a list of every file imported by an entry point, recursively") catch unreachable,
|
||||
clap.parseParam("--new-jsb Generate a new node_modules.jsb file from node_modules and entry point(s)") catch unreachable,
|
||||
clap.parseParam("--jsb <STR> Use a Speedy JavaScript Bundle (default: \"./node_modules.jsb\" if exists)") catch unreachable,
|
||||
clap.parseParam("--framework <STR> Use a JavaScript framework (file path) with --serve") catch unreachable,
|
||||
// clap.parseParam("--no-jsb Use a Speedy JavaScript Bundle (default: \"./node_modules.jsb\" if exists)") catch unreachable,
|
||||
clap.parseParam("<POS>... Entry points to use") catch unreachable,
|
||||
};
|
||||
@@ -183,6 +184,8 @@ pub const Cli = struct {
|
||||
var jsx_production = args.flag("--jsx-production");
|
||||
var react_fast_refresh = false;
|
||||
|
||||
var javascript_framework = args.option("--framework");
|
||||
|
||||
if (serve or args.flag("--new-jsb")) {
|
||||
react_fast_refresh = true;
|
||||
if (args.flag("--disable-react-fast-refresh") or jsx_production) {
|
||||
@@ -280,6 +283,10 @@ pub const Cli = struct {
|
||||
std.process.exit(1);
|
||||
}
|
||||
|
||||
if (!serve) {
|
||||
javascript_framework = null;
|
||||
}
|
||||
|
||||
return Api.TransformOptions{
|
||||
.jsx = jsx,
|
||||
.output_dir = output_dir,
|
||||
@@ -307,6 +314,7 @@ pub const Cli = struct {
|
||||
.platform = platform,
|
||||
.only_scan_dependencies = if (args.flag("--scan")) Api.ScanDependencyMode.all else Api.ScanDependencyMode._none,
|
||||
.generate_node_module_bundle = if (args.flag("--new-jsb")) true else false,
|
||||
.javascript_framework_file = javascript_framework,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
249
src/http.zig
249
src/http.zig
@@ -12,6 +12,7 @@ const logger = @import("logger.zig");
|
||||
const Fs = @import("./fs.zig");
|
||||
const Options = @import("./options.zig");
|
||||
const Css = @import("css_scanner.zig");
|
||||
const NodeModuleBundle = @import("./node_module_bundle.zig").NodeModuleBundle;
|
||||
|
||||
pub fn constStrToU8(s: string) []u8 {
|
||||
return @intToPtr([*]u8, @ptrToInt(s.ptr))[0..s.len];
|
||||
@@ -31,8 +32,8 @@ const picohttp = @import("picohttp");
|
||||
const Header = picohttp.Header;
|
||||
const Request = picohttp.Request;
|
||||
const Response = picohttp.Response;
|
||||
const Headers = picohttp.Headers;
|
||||
const MimeType = @import("http/mime_type.zig");
|
||||
pub const Headers = picohttp.Headers;
|
||||
pub const MimeType = @import("http/mime_type.zig");
|
||||
const Bundler = bundler.ServeBundler;
|
||||
const Websocket = @import("./http/websocket.zig");
|
||||
const js_printer = @import("js_printer.zig");
|
||||
@@ -41,6 +42,8 @@ const watcher = @import("./watcher.zig");
|
||||
threadlocal var req_headers_buf: [100]picohttp.Header = undefined;
|
||||
threadlocal var res_headers_buf: [100]picohttp.Header = undefined;
|
||||
const sync = @import("./sync.zig");
|
||||
const JavaScript = @import("./javascript/jsc/JavaScript.zig");
|
||||
const js = @import("javascript/jsc/javascript.zig");
|
||||
|
||||
pub const Watcher = watcher.NewWatcher(*Server);
|
||||
|
||||
@@ -189,10 +192,23 @@ pub const RequestContext = struct {
|
||||
watcher: *Watcher,
|
||||
timer: std.time.Timer,
|
||||
|
||||
full_url: [:0]const u8 = "",
|
||||
res_headers_count: usize = 0,
|
||||
|
||||
pub const bundle_prefix = "__speedy";
|
||||
|
||||
pub fn getFullURL(this: *RequestContext) [:0]const u8 {
|
||||
if (this.full_url.len == 0) {
|
||||
if (this.bundler.options.public_url.len > 0) {
|
||||
this.full_url = std.fmt.allocPrintZ(this.allocator, "{s}{s}", .{ this.bundler.options.public_url, this.request.path }) catch unreachable;
|
||||
} else {
|
||||
this.full_url = this.allocator.dupeZ(u8, this.request.path) catch unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
return this.full_url;
|
||||
}
|
||||
|
||||
pub fn header(ctx: *RequestContext, comptime name: anytype) ?Header {
|
||||
if (name.len < 17) {
|
||||
for (ctx.request.headers) |head| {
|
||||
@@ -246,6 +262,17 @@ pub const RequestContext = struct {
|
||||
try ctx.flushHeaders();
|
||||
}
|
||||
|
||||
pub fn clearHeaders(
|
||||
this: *RequestContext,
|
||||
) !void {
|
||||
this.res_headers_count = 0;
|
||||
}
|
||||
|
||||
pub fn appendHeaderSlow(this: *RequestContext, name: string, value: string) !void {
|
||||
res_headers_buf[this.res_headers_count] = picohttp.Header{ .name = name, .value = value };
|
||||
this.res_headers_count += 1;
|
||||
}
|
||||
|
||||
threadlocal var resp_header_out_buf: [4096]u8 = undefined;
|
||||
pub fn flushHeaders(ctx: *RequestContext) !void {
|
||||
if (ctx.res_headers_count == 0) return;
|
||||
@@ -288,6 +315,20 @@ pub const RequestContext = struct {
|
||||
ctx.status = code;
|
||||
}
|
||||
|
||||
threadlocal var status_buf: [std.fmt.count("HTTP/1.1 {d} {s}\r\n", .{ 200, "OK" })]u8 = undefined;
|
||||
pub fn writeStatusSlow(ctx: *RequestContext, code: u16) !void {
|
||||
_ = try ctx.writeSocket(
|
||||
try std.fmt.bufPrint(
|
||||
&status_buf,
|
||||
"HTTP/1.1 {d} {s}\r\n",
|
||||
.{ code, if (code > 299) "HM" else "OK" },
|
||||
),
|
||||
SOCKET_FLAGS,
|
||||
);
|
||||
|
||||
ctx.status = @truncate(HTTPStatusCode, code);
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
req: Request,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
@@ -592,6 +633,132 @@ pub const RequestContext = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const JavaScriptHandler = struct {
|
||||
ctx: RequestContext,
|
||||
conn: tcp.Connection,
|
||||
|
||||
pub const HandlerThread = struct {
|
||||
args: Api.TransformOptions,
|
||||
existing_bundle: ?*NodeModuleBundle,
|
||||
log: ?*logger.Log = null,
|
||||
};
|
||||
|
||||
pub const Channel = sync.Channel(*JavaScriptHandler, .{ .Static = 100 });
|
||||
pub var channel: Channel = undefined;
|
||||
var has_loaded_channel = false;
|
||||
pub var javascript_disabled = false;
|
||||
var thread: std.Thread = undefined;
|
||||
pub fn spawnThread(handler: HandlerThread) !void {
|
||||
_ = try std.Thread.spawn(spawn, handler);
|
||||
}
|
||||
|
||||
pub fn spawn(handler: HandlerThread) void {
|
||||
var _handler = handler;
|
||||
_spawn(&_handler) catch {};
|
||||
}
|
||||
|
||||
pub fn _spawn(handler: *HandlerThread) !void {
|
||||
defer {
|
||||
javascript_disabled = true;
|
||||
}
|
||||
|
||||
var stdout = std.io.getStdOut();
|
||||
// var stdout = std.io.bufferedWriter(stdout_file.writer());
|
||||
var stderr = std.io.getStdErr();
|
||||
// var stderr = std.io.bufferedWriter(stderr_file.writer());
|
||||
var output_source = Output.Source.init(stdout, stderr);
|
||||
// defer stdout.flush() catch {};
|
||||
// defer stderr.flush() catch {};
|
||||
Output.Source.set(&output_source);
|
||||
Output.enable_ansi_colors = stderr.isTty();
|
||||
js_ast.Stmt.Data.Store.create(std.heap.c_allocator);
|
||||
js_ast.Expr.Data.Store.create(std.heap.c_allocator);
|
||||
|
||||
defer Output.flush();
|
||||
var boot = handler.args.javascript_framework_file.?;
|
||||
var vm = try JavaScript.VirtualMachine.init(std.heap.c_allocator, handler.args, handler.existing_bundle, handler.log);
|
||||
defer vm.deinit();
|
||||
|
||||
var resolved_entry_point = try vm.bundler.resolver.resolve(
|
||||
std.fs.path.dirname(boot).?,
|
||||
boot,
|
||||
.entry_point,
|
||||
);
|
||||
JavaScript.VirtualMachine.instance = vm;
|
||||
var exception: js.JSValueRef = null;
|
||||
var load_result = try JavaScript.Module.loadFromResolveResult(vm, vm.ctx, resolved_entry_point, &exception);
|
||||
|
||||
// We've already printed the exception here!
|
||||
if (exception != null) {
|
||||
Output.prettyErrorln(
|
||||
"JavaScript VM failed to start",
|
||||
.{},
|
||||
);
|
||||
Output.flush();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (load_result) {
|
||||
.Module => {
|
||||
Output.prettyln(
|
||||
"Loaded JavaScript VM: \"{s}\"",
|
||||
.{vm.bundler.fs.relativeTo(boot)},
|
||||
);
|
||||
Output.flush();
|
||||
},
|
||||
.Path => {
|
||||
Output.prettyErrorln(
|
||||
"Error loading JavaScript VM: Expected framework to be a path to a JavaScript-like file but received \"{s}\"",
|
||||
.{boot},
|
||||
);
|
||||
Output.flush();
|
||||
return;
|
||||
},
|
||||
}
|
||||
|
||||
js_ast.Stmt.Data.Store.reset();
|
||||
js_ast.Expr.Data.Store.reset();
|
||||
|
||||
try runLoop(vm);
|
||||
}
|
||||
|
||||
pub fn runLoop(vm: *JavaScript.VirtualMachine) !void {
|
||||
while (true) {
|
||||
defer {
|
||||
js_ast.Stmt.Data.Store.reset();
|
||||
js_ast.Expr.Data.Store.reset();
|
||||
}
|
||||
var handler: *JavaScriptHandler = try channel.readItem();
|
||||
try JavaScript.EventListenerMixin.emitFetchEvent(vm, &handler.ctx);
|
||||
}
|
||||
}
|
||||
|
||||
var one: [1]*JavaScriptHandler = undefined;
|
||||
pub fn enqueue(ctx: *RequestContext, server: *Server) !void {
|
||||
var clone = try ctx.allocator.create(JavaScriptHandler);
|
||||
clone.ctx = ctx.*;
|
||||
clone.conn = ctx.conn.*;
|
||||
clone.ctx.conn = &clone.conn;
|
||||
|
||||
if (!has_loaded_channel) {
|
||||
has_loaded_channel = true;
|
||||
channel = Channel.init();
|
||||
try JavaScriptHandler.spawnThread(
|
||||
HandlerThread{
|
||||
.args = server.transform_options,
|
||||
.existing_bundle = server.bundler.options.node_modules_bundle,
|
||||
.log = &server.log,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
defer ctx.controlled = true;
|
||||
one[0] = clone;
|
||||
_ = try channel.write(&one);
|
||||
}
|
||||
};
|
||||
|
||||
pub const WebsocketHandler = struct {
|
||||
accept_key: [28]u8 = undefined,
|
||||
ctx: RequestContext,
|
||||
@@ -943,6 +1110,22 @@ pub const RequestContext = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn writeETag(this: *RequestContext, buffer: anytype) !bool {
|
||||
const strong_etag = std.hash.Wyhash.hash(1, buffer);
|
||||
const etag_content_slice = std.fmt.bufPrintIntToSlice(strong_etag_buffer[0..49], strong_etag, 16, .upper, .{});
|
||||
|
||||
this.appendHeader("ETag", etag_content_slice);
|
||||
|
||||
if (this.header("If-None-Match")) |etag_header| {
|
||||
if (std.mem.eql(u8, etag_content_slice, etag_header.value)) {
|
||||
try this.sendNotModified();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn handleWebsocket(ctx: *RequestContext) anyerror!void {
|
||||
ctx.controlled = true;
|
||||
var handler = try WebsocketHandler.addWebsocket(ctx);
|
||||
@@ -1228,18 +1411,8 @@ pub const RequestContext = struct {
|
||||
}
|
||||
|
||||
if (FeatureFlags.strong_etags_for_built_files) {
|
||||
// TODO: don't hash runtime.js
|
||||
const strong_etag = std.hash.Wyhash.hash(1, buffer);
|
||||
const etag_content_slice = std.fmt.bufPrintIntToSlice(strong_etag_buffer[0..49], strong_etag, 16, .upper, .{});
|
||||
|
||||
ctx.appendHeader("ETag", etag_content_slice);
|
||||
|
||||
if (ctx.header("If-None-Match")) |etag_header| {
|
||||
if (std.mem.eql(u8, etag_content_slice, etag_header.value)) {
|
||||
try ctx.sendNotModified();
|
||||
return;
|
||||
}
|
||||
}
|
||||
const did_send = ctx.writeETag(buffer) catch false;
|
||||
if (did_send) return;
|
||||
}
|
||||
|
||||
if (buffer.len == 0) {
|
||||
@@ -1313,6 +1486,7 @@ pub const Server = struct {
|
||||
bundler: Bundler,
|
||||
watcher: *Watcher,
|
||||
timer: std.time.Timer = undefined,
|
||||
transform_options: Api.TransformOptions,
|
||||
|
||||
pub fn adjustUlimit() !void {
|
||||
var limit = try std.os.getrlimit(.NOFILE);
|
||||
@@ -1465,17 +1639,25 @@ pub const Server = struct {
|
||||
req_ctx.keep_alive = false;
|
||||
}
|
||||
|
||||
req_ctx.handleRequest() catch |err| {
|
||||
switch (err) {
|
||||
error.ModuleNotFound => {
|
||||
req_ctx.sendNotFound() catch {};
|
||||
},
|
||||
else => {
|
||||
Output.printErrorln("FAIL [{s}] - {s}: {s}", .{ @errorName(err), req.method, req.path });
|
||||
return;
|
||||
},
|
||||
if (req_ctx.url.extname.len == 0 and !RequestContext.JavaScriptHandler.javascript_disabled) {
|
||||
if (server.transform_options.javascript_framework_file != null) {
|
||||
RequestContext.JavaScriptHandler.enqueue(&req_ctx, server) catch unreachable;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!req_ctx.controlled) {
|
||||
req_ctx.handleRequest() catch |err| {
|
||||
switch (err) {
|
||||
error.ModuleNotFound => {
|
||||
req_ctx.sendNotFound() catch {};
|
||||
},
|
||||
else => {
|
||||
Output.printErrorln("FAIL [{s}] - {s}: {s}", .{ @errorName(err), req.method, req.path });
|
||||
return;
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!req_ctx.controlled) {
|
||||
const status = req_ctx.status orelse @intCast(HTTPStatusCode, 500);
|
||||
@@ -1503,11 +1685,30 @@ pub const Server = struct {
|
||||
.log = log,
|
||||
.bundler = undefined,
|
||||
.watcher = undefined,
|
||||
.transform_options = options,
|
||||
.timer = try std.time.Timer.start(),
|
||||
};
|
||||
server.bundler = try Bundler.init(allocator, &server.log, options, null);
|
||||
server.bundler.configureLinker();
|
||||
|
||||
load_framework: {
|
||||
if (options.javascript_framework_file) |framework_file_path| {
|
||||
var framework_file = server.bundler.normalizeEntryPointPath(framework_file_path);
|
||||
var resolved = server.bundler.resolver.resolve(
|
||||
server.bundler.fs.top_level_dir,
|
||||
framework_file,
|
||||
.entry_point,
|
||||
) catch |err| {
|
||||
Output.prettyError("Failed to load framework: {s}", .{@errorName(err)});
|
||||
Output.flush();
|
||||
server.transform_options.javascript_framework_file = null;
|
||||
break :load_framework;
|
||||
};
|
||||
|
||||
server.transform_options.javascript_framework_file = try server.allocator.dupe(u8, resolved.path_pair.primary.text);
|
||||
}
|
||||
}
|
||||
|
||||
try server.initWatcher();
|
||||
|
||||
try server.run();
|
||||
|
||||
@@ -29,6 +29,8 @@ pub const other = MimeType.init("application/octet-stream", .other);
|
||||
pub const css = MimeType.init("text/css", .css);
|
||||
pub const javascript = MimeType.init("text/javascript;charset=utf-8", .javascript);
|
||||
pub const ico = MimeType.init("image/vnd.microsoft.icon", .image);
|
||||
pub const html = MimeType.init("text/html;charset=utf-8", .html);
|
||||
pub const json = MimeType.init("application/json;charset=utf-8", .json);
|
||||
|
||||
fn init(comptime str: string, t: Category) MimeType {
|
||||
return MimeType{
|
||||
@@ -89,11 +91,11 @@ pub fn byExtension(ext: string) MimeType {
|
||||
},
|
||||
4 => {
|
||||
return switch (Four.match(ext)) {
|
||||
Four.case("json") => MimeType.init("application/json;charset=utf-8", .json),
|
||||
Four.case("json") => MimeType.json,
|
||||
Four.case("jpeg") => MimeType.init("image/jpeg", .image),
|
||||
Four.case("aiff") => MimeType.init("image/png", .image),
|
||||
Four.case("tiff") => MimeType.init("image/tiff", .image),
|
||||
Four.case("html") => MimeType.init("text/html;charset=utf-8", .html),
|
||||
Four.case("html") => MimeType.html,
|
||||
Four.case("wasm") => MimeType.init(
|
||||
"application/wasm",
|
||||
.wasm,
|
||||
|
||||
@@ -246,3 +246,26 @@ pub const OpaqueJSValue = struct_OpaqueJSValue;
|
||||
// https://github.com/WebKit/webkit/blob/main/Source/JavaScriptCore/API/JSStringRef.cpp#L62
|
||||
pub extern fn JSStringCreateWithCharactersNoCopy(string: [*c]const JSChar, numChars: size_t) JSStringRef;
|
||||
const size_t = usize;
|
||||
|
||||
const then_key = "then";
|
||||
var thenable_string: JSStringRef = null;
|
||||
pub fn isObjectOfClassAndResolveIfNeeded(ctx: JSContextRef, obj: JSObjectRef, class: JSClassRef) ?JSObjectRef {
|
||||
if (JSValueIsObjectOfClass(ctx, obj, class)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (!JSValueIsObject(ctx, obj)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (thenable_string == null) {
|
||||
thenable_string = JSStringCreateWithUTF8CString(then_key[0.. :0]);
|
||||
}
|
||||
|
||||
var prop = JSObjectGetPropertyForKey(ctx, obj, JSValueMakeString(ctx, thenable_string), null);
|
||||
if (prop == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,79 @@ pub const To = struct {
|
||||
return function;
|
||||
}
|
||||
|
||||
pub fn Finalize(
|
||||
comptime ZigContextType: type,
|
||||
comptime ctxfn: fn (
|
||||
this: *ZigContextType,
|
||||
object: js.JSObjectRef,
|
||||
) void,
|
||||
) type {
|
||||
return struct {
|
||||
pub fn rfn(
|
||||
object: js.JSObjectRef,
|
||||
) callconv(.C) void {
|
||||
var object_ptr_ = js.JSObjectGetPrivate(object);
|
||||
if (object_ptr_ == null) return;
|
||||
|
||||
return ctxfn(
|
||||
@ptrCast(*ZigContextType, @alignCast(@alignOf(*ZigContextType), object_ptr_.?)),
|
||||
object,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn Constructor(
|
||||
comptime ctxfn: fn (
|
||||
ctx: js.JSContextRef,
|
||||
function: js.JSObjectRef,
|
||||
arguments: []const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef,
|
||||
) type {
|
||||
return struct {
|
||||
pub fn rfn(
|
||||
ctx: js.JSContextRef,
|
||||
function: js.JSObjectRef,
|
||||
argumentCount: usize,
|
||||
arguments: [*c]const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
return ctxfn(
|
||||
ctx,
|
||||
function,
|
||||
if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
|
||||
exception,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn ConstructorCallback(
|
||||
comptime ctxfn: fn (
|
||||
ctx: js.JSContextRef,
|
||||
function: js.JSObjectRef,
|
||||
arguments: []const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef,
|
||||
) type {
|
||||
return struct {
|
||||
pub fn rfn(
|
||||
ctx: js.JSContextRef,
|
||||
function: js.JSObjectRef,
|
||||
argumentCount: usize,
|
||||
arguments: [*c]const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
return ctxfn(
|
||||
ctx,
|
||||
function,
|
||||
if (arguments) |args| args[0..argumentCount] else &[_]js.JSValueRef{},
|
||||
exception,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn Callback(
|
||||
comptime ZigContextType: type,
|
||||
comptime ctxfn: fn (
|
||||
@@ -107,6 +180,18 @@ pub const Properties = struct {
|
||||
pub const initialize_bundled_module = "$$m";
|
||||
pub const load_module_function = "$lOaDuRcOdE$";
|
||||
pub const window = "window";
|
||||
pub const default = "default";
|
||||
pub const include = "include";
|
||||
|
||||
pub const GET = "GET";
|
||||
pub const PUT = "PUT";
|
||||
pub const POST = "POST";
|
||||
pub const PATCH = "PATCH";
|
||||
pub const HEAD = "HEAD";
|
||||
pub const OPTIONS = "OPTIONS";
|
||||
|
||||
pub const navigate = "navigate";
|
||||
pub const follow = "follow";
|
||||
};
|
||||
|
||||
pub const UTF16 = struct {
|
||||
@@ -125,24 +210,50 @@ pub const Properties = struct {
|
||||
pub const initialize_bundled_module = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.initialize_bundled_module);
|
||||
pub const load_module_function: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.load_module_function);
|
||||
pub const window: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.window);
|
||||
pub const default: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.default);
|
||||
pub const include: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.include);
|
||||
|
||||
pub const GET: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.GET);
|
||||
pub const PUT: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.PUT);
|
||||
pub const POST: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.POST);
|
||||
pub const PATCH: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.PATCH);
|
||||
pub const HEAD: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.HEAD);
|
||||
pub const OPTIONS: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.OPTIONS);
|
||||
|
||||
pub const navigate: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.navigate);
|
||||
pub const follow: []c_ushort = std.unicode.utf8ToUtf16LeStringLiteral(UTF8.follow);
|
||||
};
|
||||
|
||||
pub const Refs = struct {
|
||||
pub var module: js.JSStringRef = null;
|
||||
pub var globalThis: js.JSStringRef = null;
|
||||
pub var exports: js.JSStringRef = null;
|
||||
pub var log: js.JSStringRef = null;
|
||||
pub var debug: js.JSStringRef = null;
|
||||
pub var info: js.JSStringRef = null;
|
||||
pub var error_: js.JSStringRef = null;
|
||||
pub var warn: js.JSStringRef = null;
|
||||
pub var console: js.JSStringRef = null;
|
||||
pub var require: js.JSStringRef = null;
|
||||
pub var description: js.JSStringRef = null;
|
||||
pub var name: js.JSStringRef = null;
|
||||
pub var initialize_bundled_module: js.JSStringRef = null;
|
||||
pub var load_module_function: js.JSStringRef = null;
|
||||
pub var window: js.JSStringRef = null;
|
||||
pub var module: js.JSStringRef = undefined;
|
||||
pub var globalThis: js.JSStringRef = undefined;
|
||||
pub var exports: js.JSStringRef = undefined;
|
||||
pub var log: js.JSStringRef = undefined;
|
||||
pub var debug: js.JSStringRef = undefined;
|
||||
pub var info: js.JSStringRef = undefined;
|
||||
pub var error_: js.JSStringRef = undefined;
|
||||
pub var warn: js.JSStringRef = undefined;
|
||||
pub var console: js.JSStringRef = undefined;
|
||||
pub var require: js.JSStringRef = undefined;
|
||||
pub var description: js.JSStringRef = undefined;
|
||||
pub var name: js.JSStringRef = undefined;
|
||||
pub var initialize_bundled_module: js.JSStringRef = undefined;
|
||||
pub var load_module_function: js.JSStringRef = undefined;
|
||||
pub var window: js.JSStringRef = undefined;
|
||||
pub var default: js.JSStringRef = undefined;
|
||||
pub var include: js.JSStringRef = undefined;
|
||||
pub var GET: js.JSStringRef = undefined;
|
||||
pub var PUT: js.JSStringRef = undefined;
|
||||
pub var POST: js.JSStringRef = undefined;
|
||||
pub var PATCH: js.JSStringRef = undefined;
|
||||
pub var HEAD: js.JSStringRef = undefined;
|
||||
pub var OPTIONS: js.JSStringRef = undefined;
|
||||
|
||||
pub var empty_string_ptr = [_]u8{0};
|
||||
pub var empty_string: js.JSStringRef = undefined;
|
||||
|
||||
pub var navigate: js.JSStringRef = undefined;
|
||||
pub var follow: js.JSStringRef = undefined;
|
||||
};
|
||||
|
||||
pub fn init() void {
|
||||
@@ -160,9 +271,13 @@ pub const Properties = struct {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Refs.empty_string = js.JSStringCreateWithUTF8CString(&Refs.empty_string_ptr);
|
||||
}
|
||||
};
|
||||
|
||||
const hasSetter = std.meta.trait.hasField("set");
|
||||
const hasFinalize = std.meta.trait.hasField("finalize");
|
||||
pub fn NewClass(
|
||||
comptime ZigType: type,
|
||||
comptime name: string,
|
||||
@@ -215,6 +330,65 @@ pub fn NewClass(
|
||||
};
|
||||
var static_properties: [property_names.len]js.JSStaticValue = undefined;
|
||||
|
||||
pub var ref: js.JSClassRef = null;
|
||||
pub var loaded = false;
|
||||
pub var definition: js.JSClassDefinition = undefined;
|
||||
const ConstructorWrapper = struct {
|
||||
pub fn rfn(
|
||||
ctx: js.JSContextRef,
|
||||
function: js.JSObjectRef,
|
||||
thisObject: js.JSObjectRef,
|
||||
argumentCount: usize,
|
||||
arguments: [*c]const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
return definition.callAsConstructor.?(ctx, function, argumentCount, arguments, exception);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Constructor = ConstructorWrapper.rfn;
|
||||
|
||||
pub const static_value_count = static_properties.len;
|
||||
|
||||
pub fn get() callconv(.C) [*c]js.JSClassRef {
|
||||
if (!loaded) {
|
||||
loaded = true;
|
||||
definition = define();
|
||||
ref = js.JSClassRetain(js.JSClassCreate(&definition));
|
||||
}
|
||||
return &ref;
|
||||
}
|
||||
|
||||
pub fn RawGetter(comptime ReceiverType: type) type {
|
||||
const ClassGetter = struct {
|
||||
pub fn getter(
|
||||
ctx: js.JSContextRef,
|
||||
obj: js.JSObjectRef,
|
||||
prop: js.JSStringRef,
|
||||
exception: js.ExceptionRef,
|
||||
) callconv(.C) js.JSValueRef {
|
||||
return js.JSObjectMake(ctx, get().*, null);
|
||||
}
|
||||
};
|
||||
|
||||
return ClassGetter;
|
||||
}
|
||||
|
||||
pub fn GetClass(comptime ReceiverType: type) type {
|
||||
const ClassGetter = struct {
|
||||
pub fn getter(
|
||||
receiver: *ReceiverType,
|
||||
ctx: js.JSContextRef,
|
||||
obj: js.JSObjectRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
return js.JSObjectMake(ctx, get().*, null);
|
||||
}
|
||||
};
|
||||
|
||||
return ClassGetter;
|
||||
}
|
||||
|
||||
pub fn getPropertyCallback(
|
||||
ctx: js.JSContextRef,
|
||||
obj: js.JSObjectRef,
|
||||
@@ -281,7 +455,7 @@ pub fn NewClass(
|
||||
),
|
||||
);
|
||||
|
||||
var exc: js.ExceptionRef = null;
|
||||
var exc: js.JSValueRef = null;
|
||||
|
||||
switch (comptime @typeInfo(@TypeOf(@field(
|
||||
properties,
|
||||
@@ -372,15 +546,18 @@ pub fn NewClass(
|
||||
var count: usize = 0;
|
||||
inline for (function_name_literals) |function_name, i| {
|
||||
if (comptime strings.eqlComptime(function_names[i], "constructor")) {
|
||||
def.callAsConstructor = @field(staticFunctions, function_names[i]);
|
||||
def.callAsConstructor = To.JS.Constructor(@field(staticFunctions, function_names[i])).rfn;
|
||||
} else if (comptime strings.eqlComptime(function_names[i], "finalize")) {
|
||||
def.finalize = To.JS.Finalize(ZigType, staticFunctions.finalize).rfn;
|
||||
} else {
|
||||
count += 1;
|
||||
var callback = To.JS.Callback(ZigType, @field(staticFunctions, function_names[i])).rfn;
|
||||
static_functions[count] = js.JSStaticFunction{
|
||||
.name = (function_names[i][0.. :0]).ptr,
|
||||
.callAsFunction = callback,
|
||||
.attributes = comptime if (read_only) js.JSPropertyAttributes.kJSPropertyAttributeReadOnly else js.JSPropertyAttributes.kJSPropertyAttributeNone,
|
||||
};
|
||||
|
||||
count += 1;
|
||||
}
|
||||
|
||||
// if (singleton) {
|
||||
@@ -402,7 +579,7 @@ pub fn NewClass(
|
||||
static_properties[i].getProperty = StaticProperty(i).getter;
|
||||
|
||||
const field = comptime @field(properties, property_names[i]);
|
||||
const hasSetter = std.meta.trait.hasField("set");
|
||||
|
||||
if (comptime hasSetter(@TypeOf(field))) {
|
||||
static_properties[i].setProperty = StaticProperty(i).setter;
|
||||
}
|
||||
@@ -415,8 +592,6 @@ pub fn NewClass(
|
||||
def.className = class_name_str;
|
||||
// def.getProperty = getPropertyCallback;
|
||||
|
||||
def.finalize
|
||||
|
||||
return def;
|
||||
}
|
||||
};
|
||||
@@ -437,20 +612,18 @@ pub fn JSError(
|
||||
exception.* = js.JSObjectMakeError(ctx, 1, &error_args, null);
|
||||
} else {
|
||||
var buf = std.fmt.allocPrintZ(allocator, fmt, args) catch unreachable;
|
||||
defer allocator.free(buf);
|
||||
|
||||
var message = js.JSStringCreateWithUTF8CString(buf);
|
||||
defer js.JSStringRelease(message);
|
||||
defer allocator.free(buf);
|
||||
|
||||
error_args[0] = js.JSValueMakeString(ctx, message);
|
||||
exception.* = js.JSObjectMakeError(ctx, 1, &error_args, null);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getAllocator(ctx: js.JSContextRef) *std.mem.Allocator {
|
||||
var global_obj = js.JSContextGetGlobalObject(ctx);
|
||||
var priv = js.JSObjectGetPrivate(global_obj).?;
|
||||
var global = @ptrCast(*javascript.GlobalObject, @alignCast(@alignOf(*javascript.GlobalObject), priv));
|
||||
|
||||
return global.vm.allocator;
|
||||
return std.heap.c_allocator;
|
||||
}
|
||||
|
||||
pub const JSStringList = std.ArrayList(js.JSStringRef);
|
||||
@@ -465,3 +638,10 @@ pub const ArrayBuffer = struct {
|
||||
|
||||
typed_array_type: js.JSTypedArrayType,
|
||||
};
|
||||
|
||||
pub fn castObj(obj: js.JSObjectRef, comptime Type: type) *Type {
|
||||
return @ptrCast(
|
||||
*Type,
|
||||
@alignCast(@alignOf(*Type), js.JSObjectGetPrivate(obj).?),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ const http = @import("../../http.zig");
|
||||
|
||||
usingnamespace @import("./node_env_buf_map.zig");
|
||||
usingnamespace @import("./base.zig");
|
||||
usingnamespace @import("./webcore/response.zig");
|
||||
|
||||
const DefaultSpeedyDefines = struct {
|
||||
pub const Keys = struct {
|
||||
@@ -138,6 +139,15 @@ pub const VirtualMachine = struct {
|
||||
log: *logger.Log,
|
||||
watcher: ?*http.Watcher = null,
|
||||
|
||||
event_listeners: EventListenerMixin.Map,
|
||||
|
||||
pub threadlocal var instance: *VirtualMachine = undefined;
|
||||
|
||||
pub fn deinit(vm: *VirtualMachine) void {
|
||||
js.JSGlobalContextRelease(vm.ctx);
|
||||
js.JSContextGroupRelease(vm.group);
|
||||
}
|
||||
|
||||
pub fn init(
|
||||
allocator: *std.mem.Allocator,
|
||||
_args: Api.TransformOptions,
|
||||
@@ -167,6 +177,8 @@ pub const VirtualMachine = struct {
|
||||
.log = log,
|
||||
.group = group,
|
||||
|
||||
.event_listeners = EventListenerMixin.Map.init(allocator),
|
||||
|
||||
.require_cache = RequireCacheType.init(allocator),
|
||||
.global = global,
|
||||
};
|
||||
@@ -191,8 +203,6 @@ pub const VirtualMachine = struct {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
pub const Object = struct {
|
||||
ref: js.jsObjectRef,
|
||||
};
|
||||
@@ -525,13 +535,41 @@ pub const Module = struct {
|
||||
size += this_size;
|
||||
longest_size = std.math.max(this_size, longest_size);
|
||||
}
|
||||
var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 2);
|
||||
static_properties[static_properties.len - 2] = js.JSStaticValue{
|
||||
var static_properties = try vm.allocator.alloc(js.JSStaticValue, bundle.bundle.modules.len + 1 + GlobalObject.GlobalClass.static_value_count);
|
||||
var copied_static_values = static_properties[bundle.bundle.modules.len..];
|
||||
copied_static_values = copied_static_values[0 .. copied_static_values.len - 1];
|
||||
|
||||
copied_static_values[0] = js.JSStaticValue{
|
||||
.name = Properties.UTF8.console[0.. :0],
|
||||
.getProperty = getConsole,
|
||||
.setProperty = null,
|
||||
.attributes = .kJSPropertyAttributeNone,
|
||||
};
|
||||
|
||||
copied_static_values[1] = js.JSStaticValue{
|
||||
.name = Response.Class.definition.className,
|
||||
.getProperty = Response.Class.RawGetter(NodeModuleList).getter,
|
||||
.setProperty = null,
|
||||
.attributes = .kJSPropertyAttributeNone,
|
||||
};
|
||||
|
||||
copied_static_values[2] = js.JSStaticValue{
|
||||
.name = Headers.Class.definition.className,
|
||||
.getProperty = Headers.Class.RawGetter(NodeModuleList).getter,
|
||||
.setProperty = null,
|
||||
.attributes = .kJSPropertyAttributeNone,
|
||||
};
|
||||
|
||||
copied_static_values[3] = js.JSStaticValue{
|
||||
.name = Request.Class.definition.className,
|
||||
.getProperty = Request.Class.RawGetter(NodeModuleList).getter,
|
||||
.setProperty = null,
|
||||
.attributes = .kJSPropertyAttributeNone,
|
||||
};
|
||||
|
||||
// copied_static_values must match GlobalObject.GlobalClass.static_value_count
|
||||
std.debug.assert(copied_static_values.len == 4);
|
||||
|
||||
static_properties[static_properties.len - 1] = std.mem.zeroes(js.JSStaticValue);
|
||||
var utf8 = try vm.allocator.alloc(u8, size + std.math.max(longest_size, 32));
|
||||
std.mem.set(u8, utf8, 0);
|
||||
@@ -571,6 +609,7 @@ pub const Module = struct {
|
||||
var node_module_global_class_def = js.kJSClassDefinitionEmpty;
|
||||
node_module_global_class_def.staticValues = static_properties.ptr;
|
||||
node_module_global_class_def.className = node_module_global_class_name[0.. :0];
|
||||
node_module_global_class_def.staticFunctions = GlobalObject.GlobalClass.definition.staticFunctions;
|
||||
// node_module_global_class_def.parentClass = vm.global.global_class;
|
||||
|
||||
var property_getters = try vm.allocator.alloc(js.JSObjectRef, bundle.bundle.modules.len);
|
||||
@@ -1145,6 +1184,142 @@ pub const Module = struct {
|
||||
pub const RequireObject = struct {};
|
||||
};
|
||||
|
||||
pub const EventListenerMixin = struct {
|
||||
threadlocal var event_listener_names_buf: [128]u8 = undefined;
|
||||
pub const List = std.ArrayList(js.JSObjectRef);
|
||||
pub const Map = std.AutoHashMap(EventListenerMixin.EventType, EventListenerMixin.List);
|
||||
|
||||
pub const EventType = enum {
|
||||
fetch,
|
||||
|
||||
pub fn match(str: string) ?EventType {
|
||||
if (strings.eqlComptime(str, "fetch")) {
|
||||
return EventType.fetch;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
pub fn emitFetchEventError(
|
||||
request: *http.RequestContext,
|
||||
comptime fmt: string,
|
||||
args: anytype,
|
||||
) void {
|
||||
Output.prettyErrorln(fmt, args);
|
||||
request.sendInternalError(error.FetchEventError) catch {};
|
||||
}
|
||||
|
||||
pub fn emitFetchEvent(
|
||||
vm: *VirtualMachine,
|
||||
request_context: *http.RequestContext,
|
||||
) !void {
|
||||
var listeners = vm.event_listeners.get(EventType.fetch) orelse return emitFetchEventError(
|
||||
request_context,
|
||||
"Missing \"fetch\" handler. Did you run \"addEventListener(\"fetch\", (event) => {{}})\"?",
|
||||
.{},
|
||||
);
|
||||
if (listeners.items.len == 0) return emitFetchEventError(
|
||||
request_context,
|
||||
"Missing \"fetch\" handler. Did you run \"addEventListener(\"fetch\", (event) => {{}})\"?",
|
||||
.{},
|
||||
);
|
||||
|
||||
var exception: js.JSValueRef = null;
|
||||
var fetch_event = try vm.allocator.create(FetchEvent);
|
||||
fetch_event.* = FetchEvent{
|
||||
.request_context = request_context,
|
||||
.request = Request{ .request_context = request_context },
|
||||
};
|
||||
|
||||
var fetch_args: [1]js.JSObjectRef = undefined;
|
||||
for (listeners.items) |listener| {
|
||||
fetch_args[0] = js.JSObjectMake(
|
||||
vm.ctx,
|
||||
FetchEvent.Class.get().*,
|
||||
fetch_event,
|
||||
);
|
||||
|
||||
_ = js.JSObjectCallAsFunction(
|
||||
vm.ctx,
|
||||
listener,
|
||||
js.JSContextGetGlobalObject(vm.ctx),
|
||||
1,
|
||||
&fetch_args,
|
||||
&exception,
|
||||
);
|
||||
if (request_context.has_called_done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exception != null) {
|
||||
var message = js.JSValueToStringCopy(vm.ctx, exception, null);
|
||||
defer js.JSStringRelease(message);
|
||||
var buf = vm.allocator.alloc(u8, js.JSStringGetLength(message) + 1) catch unreachable;
|
||||
defer vm.allocator.free(buf);
|
||||
var note = buf[0 .. js.JSStringGetUTF8CString(message, buf.ptr, buf.len) - 1];
|
||||
|
||||
Output.prettyErrorln("<r><red>error<r>: <b>{s}<r>", .{note});
|
||||
Output.flush();
|
||||
|
||||
if (!request_context.has_called_done) {
|
||||
request_context.sendInternalError(error.JavaScriptError) catch {};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!request_context.has_called_done) {
|
||||
return emitFetchEventError(
|
||||
request_context,
|
||||
"\"fetch\" handler never called event.respondWith()",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addEventListener(
|
||||
comptime Struct: type,
|
||||
) type {
|
||||
const Handler = struct {
|
||||
pub fn addListener(
|
||||
ptr: *Struct,
|
||||
ctx: js.JSContextRef,
|
||||
function: js.JSObjectRef,
|
||||
thisObject: js.JSObjectRef,
|
||||
arguments: []const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
if (arguments.len == 0 or arguments.len == 1 or !js.JSValueIsString(ctx, arguments[0]) or !js.JSValueIsObject(ctx, arguments[arguments.len - 1]) or !js.JSObjectIsFunction(ctx, arguments[arguments.len - 1])) {
|
||||
return js.JSValueMakeUndefined(ctx);
|
||||
}
|
||||
|
||||
const name_len = js.JSStringGetLength(arguments[0]);
|
||||
if (name_len > event_listener_names_buf.len) {
|
||||
return js.JSValueMakeUndefined(ctx);
|
||||
}
|
||||
|
||||
const name_used_len = js.JSStringGetUTF8CString(arguments[0], &event_listener_names_buf, event_listener_names_buf.len);
|
||||
const name = event_listener_names_buf[0 .. name_used_len - 1];
|
||||
const event = EventType.match(name) orelse return js.JSValueMakeUndefined(ctx);
|
||||
var entry = VirtualMachine.instance.event_listeners.getOrPut(event) catch unreachable;
|
||||
|
||||
if (!entry.found_existing) {
|
||||
entry.value_ptr.* = List.initCapacity(VirtualMachine.instance.allocator, 1) catch unreachable;
|
||||
}
|
||||
|
||||
var callback = arguments[arguments.len - 1];
|
||||
js.JSValueProtect(ctx, callback);
|
||||
entry.value_ptr.append(callback) catch unreachable;
|
||||
|
||||
return js.JSValueMakeUndefined(ctx);
|
||||
}
|
||||
};
|
||||
|
||||
return Handler;
|
||||
}
|
||||
};
|
||||
|
||||
pub const GlobalObject = struct {
|
||||
ref: js.JSObjectRef = undefined,
|
||||
vm: *VirtualMachine,
|
||||
@@ -1176,9 +1351,14 @@ pub const GlobalObject = struct {
|
||||
pub const GlobalClass = NewClass(
|
||||
GlobalObject,
|
||||
"Global",
|
||||
.{},
|
||||
.{
|
||||
.@"addEventListener" = EventListenerMixin.addEventListener(GlobalObject).addListener,
|
||||
},
|
||||
.{
|
||||
.@"console" = getConsole,
|
||||
.@"Request" = Request.Class.GetClass(GlobalObject).getter,
|
||||
.@"Response" = Response.Class.GetClass(GlobalObject).getter,
|
||||
.@"Headers" = Headers.Class.GetClass(GlobalObject).getter,
|
||||
},
|
||||
false,
|
||||
false,
|
||||
@@ -1195,18 +1375,11 @@ pub const GlobalObject = struct {
|
||||
// js.JSValueProtect(js.JSContextGetGlobalContext(ctx), global.console);
|
||||
// }
|
||||
|
||||
return js.JSObjectMake(js.JSContextGetGlobalContext(ctx), global.console_class, global);
|
||||
return js.JSObjectMake(js.JSContextGetGlobalContext(ctx), ConsoleClass.get().*, global);
|
||||
}
|
||||
|
||||
pub fn boot(global: *GlobalObject) !void {
|
||||
global.console_definition = ConsoleClass.define();
|
||||
global.console_class = js.JSClassRetain(js.JSClassCreate(&global.console_definition));
|
||||
|
||||
global.global_class_def = GlobalClass.define();
|
||||
global.global_class = js.JSClassRetain(js.JSClassCreate(&global.global_class_def));
|
||||
|
||||
global.ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(global.vm.group, global.global_class));
|
||||
|
||||
global.ctx = js.JSGlobalContextRetain(js.JSGlobalContextCreateInGroup(global.vm.group, GlobalObject.GlobalClass.get().*));
|
||||
std.debug.assert(js.JSObjectSetPrivate(js.JSContextGetGlobalObject(global.ctx), global));
|
||||
|
||||
if (!printer_buf_loaded) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -367,6 +367,15 @@ pub fn containsNonBmpCodePoint(text: string) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
// this is std.mem.trim except it doesn't forcibly change the slice to be const
|
||||
pub fn trim(slice: anytype, values_to_strip: []const u8) @TypeOf(slice) {
|
||||
var begin: usize = 0;
|
||||
var end: usize = slice.len;
|
||||
while (begin < end and std.mem.indexOfScalar(u8, values_to_strip, slice[begin]) != null) : (begin += 1) {}
|
||||
while (end > begin and std.mem.indexOfScalar(u8, values_to_strip, slice[end - 1]) != null) : (end -= 1) {}
|
||||
return slice[begin..end];
|
||||
}
|
||||
|
||||
pub fn containsNonBmpCodePointUTF16(_text: JavascriptString) bool {
|
||||
const n = _text.len;
|
||||
if (n > 0) {
|
||||
|
||||
@@ -465,7 +465,7 @@ pub fn Channel(
|
||||
if (self.is_closed)
|
||||
return error.Closed;
|
||||
|
||||
self.buffer.writeItem(item) catch |err| {
|
||||
self.buffer.write(items) catch |err| {
|
||||
if (buffer_type == .Dynamic)
|
||||
return err;
|
||||
break :blk false;
|
||||
|
||||
Reference in New Issue
Block a user