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:
Jarred Sumner
2021-07-01 05:12:15 -07:00
parent a8536a7337
commit 88aad6aeb1
21 changed files with 1547 additions and 485 deletions

7
.vscode/launch.json vendored
View File

@@ -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
View File

View File

@@ -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| {

View 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 {};

View File

@@ -27,6 +27,7 @@
}
},
"devDependencies": {
"@microsoft/fetch-event-source": "^2.0.1",
"@snowpack/plugin-react-refresh": "^2.5.0",
"typescript": "^4.3.4"
}

View File

@@ -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 };

View File

@@ -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
View File

@@ -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
View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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();
}

View File

@@ -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,
};
}
};

View File

@@ -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();

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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).?),
);
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;