This commit is contained in:
Robin Appelman 2021-07-26 23:39:13 +02:00
commit a47bd90a75
6 changed files with 518 additions and 313 deletions

View file

@ -3,6 +3,50 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Hello wasm-pack!</title> <title>Hello wasm-pack!</title>
<style>
span.tick {
display: inline-block;
width: 50px;
text-align: right;
padding-right: 5px;
}
span.type {
vertical-align: top;
word-wrap: break-word;
}
div.details {
display: inline-block;
width: calc(100vw - 210px);
height: 100vh;
overflow: auto;
}
div.list {
display: inline-block;
}
#root {
display: flex;
flex-direction: row;
}
table {
table-layout: fixed;
}
tr {
height: 30px;
}
td.type {
vertical-align: top;
width: 160px;
}
p {
margin: 8px 0;
}
html, body, #root {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
</head> </head>
<body> <body>
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript> <noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>

346
www/package-lock.json generated
View file

@ -11,7 +11,9 @@
"demo-inspector": "file:../pkg", "demo-inspector": "file:../pkg",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-dropzone": "^11.3.4" "react-dropzone": "^11.3.4",
"react-virtualized-auto-sizer": "^1.0.5",
"react-window": "^1.8.6"
}, },
"bin": { "bin": {
"create-wasm-app": ".bin/create-wasm-app.js" "create-wasm-app": ".bin/create-wasm-app.js"
@ -19,19 +21,31 @@
"devDependencies": { "devDependencies": {
"@types/react": "^17.0.15", "@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.4",
"copy-webpack-plugin": "^9.0.1", "copy-webpack-plugin": "^9.0.1",
"ts-loader": "^9.2.4", "ts-loader": "^9.2.4",
"typescript": "^4.3.5", "typescript": "^4.3.5",
"webpack": "^5.46.0", "webpack": "^5.46.0",
"webpack-cli": "^4.7.2", "webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2", "webpack-dev-server": "^3.11.2"
"worker-loader": "^3.0.8"
} }
}, },
"../pkg": { "../pkg": {
"name": "demo-inspector", "name": "demo-inspector",
"version": "0.1.0" "version": "0.1.0"
}, },
"node_modules/@babel/runtime": {
"version": "7.14.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
"integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@discoveryjs/json-ext": { "node_modules/@discoveryjs/json-ext": {
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz",
@ -163,6 +177,24 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/react-virtualized-auto-sizer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz",
"integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/react-window": {
"version": "1.8.4",
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.4.tgz",
"integrity": "sha512-rFJ0h1nYffFBNi6N80CFORAQNNr+440RtGCAmKyn81U99pXRoxS2goi/fkYnUJtk+LcvWCp8cmP16M8loJJsjw==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@ -664,15 +696,6 @@
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
"dev": true "dev": true
}, },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true,
"engines": {
"node": "*"
}
},
"node_modules/binary-extensions": { "node_modules/binary-extensions": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
@ -1517,15 +1540,6 @@
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true "dev": true
}, },
"node_modules/emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/encodeurl": { "node_modules/encodeurl": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -3262,43 +3276,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/import-local/node_modules/find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"dependencies": {
"locate-path": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/import-local/node_modules/locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"dependencies": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/import-local/node_modules/p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"dependencies": {
"p-limit": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/import-local/node_modules/pkg-dir": { "node_modules/import-local/node_modules/pkg-dir": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
@ -3751,27 +3728,6 @@
"integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
"dev": true "dev": true
}, },
"node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/json5/node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"node_modules/killable": { "node_modules/killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -3796,20 +3752,6 @@
"node": ">=6.11.5" "node": ">=6.11.5"
} }
}, },
"node_modules/loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/locate-path": { "node_modules/locate-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@ -3879,6 +3821,11 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
},
"node_modules/memory-fs": { "node_modules/memory-fs": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@ -4787,6 +4734,34 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"node_modules/react-virtualized-auto-sizer": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.5.tgz",
"integrity": "sha512-kivjYVWX15TX2IUrm8F1jaCEX8EXrpy3DD+u41WGqJ1ZqbljWpiwscV+VxOM1l7sSIM1jwi2LADjhhAJkJ9dxA==",
"engines": {
"node": ">8.0.0"
},
"peerDependencies": {
"react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0",
"react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0"
}
},
"node_modules/react-window": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.6.tgz",
"integrity": "sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==",
"dependencies": {
"@babel/runtime": "^7.0.0",
"memoize-one": ">=3.1.1 <6"
},
"engines": {
"node": ">8.0.0"
},
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0 || ^17.0.0",
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/readable-stream": { "node_modules/readable-stream": {
"version": "2.3.6", "version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
@ -4828,6 +4803,11 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"node_modules/regex-not": { "node_modules/regex-not": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@ -6755,44 +6735,6 @@
"integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
"dev": true "dev": true
}, },
"node_modules/worker-loader": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz",
"integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==",
"dev": true,
"dependencies": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
}
},
"node_modules/worker-loader/node_modules/schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
"integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
},
"engines": {
"node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/wrap-ansi": { "node_modules/wrap-ansi": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
@ -6891,6 +6833,14 @@
} }
}, },
"dependencies": { "dependencies": {
"@babel/runtime": {
"version": "7.14.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
"integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
},
"@discoveryjs/json-ext": { "@discoveryjs/json-ext": {
"version": "0.5.3", "version": "0.5.3",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz",
@ -7010,6 +6960,24 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/react-virtualized-auto-sizer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz",
"integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/react-window": {
"version": "1.8.4",
"resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.4.tgz",
"integrity": "sha512-rFJ0h1nYffFBNi6N80CFORAQNNr+440RtGCAmKyn81U99pXRoxS2goi/fkYnUJtk+LcvWCp8cmP16M8loJJsjw==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/scheduler": { "@types/scheduler": {
"version": "0.16.2", "version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@ -7425,12 +7393,6 @@
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
"dev": true "dev": true
}, },
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"binary-extensions": { "binary-extensions": {
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
@ -8126,12 +8088,6 @@
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true "dev": true
}, },
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"encodeurl": { "encodeurl": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@ -9541,34 +9497,6 @@
"resolve-cwd": "^2.0.0" "resolve-cwd": "^2.0.0"
}, },
"dependencies": { "dependencies": {
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
"locate-path": "^3.0.0"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
"p-locate": "^3.0.0",
"path-exists": "^3.0.0"
}
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
"p-limit": "^2.0.0"
}
},
"pkg-dir": { "pkg-dir": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
@ -9922,23 +9850,6 @@
"integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
"dev": true "dev": true
}, },
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
},
"dependencies": {
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
}
}
},
"killable": { "killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -9957,17 +9868,6 @@
"integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
"dev": true "dev": true
}, },
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"locate-path": { "locate-path": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@ -10019,6 +9919,11 @@
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
"dev": true "dev": true
}, },
"memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
},
"memory-fs": { "memory-fs": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
@ -10722,6 +10627,21 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}, },
"react-virtualized-auto-sizer": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.5.tgz",
"integrity": "sha512-kivjYVWX15TX2IUrm8F1jaCEX8EXrpy3DD+u41WGqJ1ZqbljWpiwscV+VxOM1l7sSIM1jwi2LADjhhAJkJ9dxA==",
"requires": {}
},
"react-window": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.6.tgz",
"integrity": "sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg==",
"requires": {
"@babel/runtime": "^7.0.0",
"memoize-one": ">=3.1.1 <6"
}
},
"readable-stream": { "readable-stream": {
"version": "2.3.6", "version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
@ -10757,6 +10677,11 @@
"resolve": "^1.9.0" "resolve": "^1.9.0"
} }
}, },
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
},
"regex-not": { "regex-not": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@ -12271,29 +12196,6 @@
"integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
"dev": true "dev": true
}, },
"worker-loader": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz",
"integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
"schema-utils": "^3.0.0"
},
"dependencies": {
"schema-utils": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
"integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
}
}
},
"wrap-ansi": { "wrap-ansi": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",

View file

@ -14,11 +14,15 @@
"demo-inspector": "file:../pkg", "demo-inspector": "file:../pkg",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-dropzone": "^11.3.4" "react-dropzone": "^11.3.4",
"react-virtualized-auto-sizer": "^1.0.5",
"react-window": "^1.8.6"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^17.0.15", "@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.4",
"copy-webpack-plugin": "^9.0.1", "copy-webpack-plugin": "^9.0.1",
"ts-loader": "^9.2.4", "ts-loader": "^9.2.4",
"typescript": "^4.3.5", "typescript": "^4.3.5",

View file

@ -3,20 +3,25 @@ import React, {useCallback, Component} from 'react'
import {useDropzone} from 'react-dropzone' import {useDropzone} from 'react-dropzone'
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import {Header} from "./header"; import {Header} from "./header";
import {PacketDetails, PacketTable} from "./table";
class App extends Component<{}, { interface AppState {
loading: boolean, loading: boolean,
header: Header | null, header: Header | null,
packets: Packet[] packets: Packet[],
}> { prop_names: Map<number, { table: String, prop: String }>,
state: { class_names: Map<number, String>,
loading: boolean, active: Packet | null,
header: Header | null, }
packets: Packet[]
} = { class App extends Component<{}, AppState> {
state: AppState = {
loading: false, loading: false,
header: null, header: null,
packets: [] packets: [],
prop_names: new Map(),
class_names: new Map(),
active: null,
} }
load(data: ArrayBuffer) { load(data: ArrayBuffer) {
@ -33,6 +38,19 @@ class App extends Component<{}, {
let packets = this.state.packets; let packets = this.state.packets;
packets.push(packet); packets.push(packet);
this.setState({packets}); this.setState({packets});
if (packet.type == "DataTables") {
let prop_names = this.state.prop_names;
let class_names = this.state.class_names;
for (let table of packet.tables) {
for (let prop of table.props) {
prop_names.set(prop.identifier, {table: table.name, prop: prop.name});
}
}
for (let server_class of packet.server_classes) {
class_names.set(server_class.id, server_class.name);
}
this.setState({class_names, prop_names});
}
break; break;
case "done": case "done":
this.setState({loading: false}); this.setState({loading: false});
@ -46,58 +64,78 @@ class App extends Component<{}, {
render() { render() {
if (this.state.loading && this.state.header && this.state.packets.length) { if (this.state.loading && this.state.header && this.state.packets.length) {
return ( return (
<div> <>
<h1>Loading</h1> <h1>Loading</h1>
<p>{this.state.packets.slice(-1)[0].tick}/{this.state.header.ticks}</p> <p>{this.state.packets.slice(-1)[0].tick}/{this.state.header.ticks}</p>
</div> </>
) )
} else if (this.state.loading) { } else if (this.state.loading) {
return ( return (
<div> <>
<h1>Loading</h1> <h1>Loading</h1>
</div> </>
) )
} else if (this.state.packets.length) { } else if (this.state.packets.length) {
let active = <></>;
if (this.state.active) {
active = <div className="details"><PacketDetails packet={this.state.active}
prop_names={this.state.prop_names}
class_names={this.state.class_names}/></div>
}
return ( return (
<div> <>
<h1>{this.state.packets.length}</h1> <PacketTable packets={this.state.packets} class_names={this.state.class_names}
</div> prop_names={this.state.prop_names} onClick={active => this.setState({active})}/>
{active}
</>
) )
} else { }
else
{
return ( return (
<div> <>
<DemoDropzone onDrop={(data) => this.load(data)}/> <DemoDropzone onDrop={(data) => this.load(data)}/>
</div> </>
) )
} }
} }
} }
ReactDOM.render( ReactDOM.render(
<App/>, <App/>
,
document.getElementById("root") document.getElementById("root")
); );
function DemoDropzone({onDrop}: { onDrop: (data: ArrayBuffer) => void }) { function DemoDropzone(
const onDropCb = useCallback(acceptedFiles => { {
let reader = new FileReader(); onDrop
reader.readAsArrayBuffer(acceptedFiles[0]); }
reader.addEventListener('load', () => { :
let result = reader.result as ArrayBuffer; {
onDrop(result) onDrop: (data: ArrayBuffer) => void
}); }
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop: onDropCb})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
) )
} {
const onDropCb = useCallback(acceptedFiles => {
let reader = new FileReader();
reader.readAsArrayBuffer(acceptedFiles[0]);
reader.addEventListener('load', () => {
let result = reader.result as ArrayBuffer;
onDrop(result)
});
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop: onDropCb})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}

79
www/src/parser.d.ts vendored
View file

@ -204,25 +204,51 @@ export type Message =
} }
| ( | (
| { | {
SayText2: SayText2Message; client: number;
from?: string | null;
kind: ChatMessageKind;
raw: number;
text: string;
type: "SayText2";
[k: string]: unknown;
} }
| { | {
Text: TextMessage; location: HudTextLocation;
substitute: [string, string, string, string];
text: string;
type: "Text";
[k: string]: unknown;
} }
| { | {
ResetHUD: ResetHudMessage; data: number;
type: "ResetHUD";
[k: string]: unknown;
} }
| { | {
Train: TrainMessage; data: number;
type: "Train";
[k: string]: unknown;
} }
| { | {
VoiceSubtitle: VoiceSubtitleMessage; client: number;
item: number;
menu: number;
type: "VoiceSubtitle";
[k: string]: unknown;
} }
| { | {
Shake: ShakeMessage; amplitude: number;
command: number;
duration: number;
frequency: number;
type: "Shake";
[k: string]: unknown;
} }
| { | {
Unknown: [number, UnknownUserMessage]; data: BitReadStream;
raw_type: number;
type: "Unknown";
[k: string]: unknown;
} }
) )
| { | {
@ -3251,45 +3277,6 @@ export interface Vector {
z: number; z: number;
[k: string]: unknown; [k: string]: unknown;
} }
export interface SayText2Message {
client: number;
from?: string | null;
kind: ChatMessageKind;
raw: number;
text: string;
[k: string]: unknown;
}
export interface TextMessage {
location: HudTextLocation;
substitute: [string, string, string, string];
text: string;
[k: string]: unknown;
}
export interface ResetHudMessage {
data: number;
[k: string]: unknown;
}
export interface TrainMessage {
data: number;
[k: string]: unknown;
}
export interface VoiceSubtitleMessage {
client: number;
item: number;
menu: number;
[k: string]: unknown;
}
export interface ShakeMessage {
amplitude: number;
command: number;
duration: number;
frequency: number;
[k: string]: unknown;
}
export interface UnknownUserMessage {
data: BitReadStream;
[k: string]: unknown;
}
export interface PacketEntity { export interface PacketEntity {
delay?: number | null; delay?: number | null;
entity_index: EntityId; entity_index: EntityId;

230
www/src/table.tsx Normal file
View file

@ -0,0 +1,230 @@
import React, {CSSProperties, JSXElementConstructor, ReactElement} from 'react';
import {GameEventDefinition, Message, Packet, PacketEntity, SendPropValue, UserCmd} from "./parser";
import {FixedSizeList as List} from 'react-window';
interface TableProps {
packets: Packet[],
prop_names: Map<number, { table: String, prop: String }>,
class_names: Map<number, String>,
onClick: (packet: Packet) => void,
}
export function PacketTable({packets, prop_names, class_names, onClick}: TableProps) {
const Row: (props: { index: number, style: CSSProperties }) => any = ({index, style}) => (
<PacketRowMemo style={style} key={index} i={index} packet={packets[index]} class_names={class_names}
prop_names={prop_names}
onClick={onClick}
expanded={false}/>
);
return (
<>
<List className="list" height={window.innerHeight} itemCount={packets.length} itemSize={30} width={210}>
{Row}
</List>
</>
)
}
interface RowProps {
style: CSSProperties,
i: number,
packet: Packet,
prop_names: Map<number, { table: String, prop: String }>,
class_names: Map<number, String>,
expanded: boolean,
onClick: (packet: Packet) => void,
}
export function PacketRow({style, i, packet, onClick}: RowProps) {
switch (packet.type) {
case "Sigon":
case "Message":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>
case "SyncTick":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>;
case "ConsoleCmd":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>;
case "UserCmd":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>;
case "DataTables":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>;
case "Stop":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>;
case "StringTables":
return <div onClick={() => {
onClick(packet)
}} style={style} key={`packet-${i}`}>
<span className="tick">{packet.tick}</span>
<span className="type">{packet.type}</span>
</div>;
}
}
interface DetailProps {
packet: Packet,
prop_names: Map<number, { table: String, prop: String }>,
class_names: Map<number, String>,
}
export function PacketDetails({packet, prop_names, class_names}: DetailProps) {
switch (packet.type) {
case "Sigon":
case "Message":
let rows = packet.messages.map((message, y) => <tr key={y}>
<td className="type">{message.type}</td>
<td>{messageInfoText(message, prop_names, class_names)}</td>
</tr>)
return (
<table>
<tbody>
{rows}
</tbody>
</table>
)
case "SyncTick":
return <></>
case "ConsoleCmd":
return <>{packet.command}</>
case "UserCmd":
return <>{formatUserCmd(packet.cmd)}</>
case "DataTables":
return <>{packet.tables.length}</>
case "Stop":
return <></>
case "StringTables":
return <>{packet.tables.length}</>
}
}
const PacketRowMemo = React.memo(PacketRow, (a, b) => a.i == b.i);
function messageInfoText(msg: Message, prop_names: Map<number, { table: String, prop: String }>, class_names: Map<number, String>) {
switch (msg.type) {
case "Print":
return <>msg.value</>
case "ServerInfo":
return <>stv: {msg.stv ? 'true' : 'false'}, map: {msg.map}, player count: {msg.player_count},
map: {msg.map}</>
case "NetTick":
return <>Tick {msg.tick}, frame time: {msg.frame_time}, std_dev: {msg.std_dev}</>
case "ParseSounds":
return <>{msg.reliable ? 'reliable' : 'unreliable'} {msg.num} sounds: {msg.length} bits</>
case "VoiceInit":
return <>{msg.codec} at quality {msg.quality} and sampling rage {msg.sampling_rate}</>
case "SigOnState":
return <>state: {msg.state}, count: {msg.count}</>
case "SetConVar":
return <>{msg.vars.map(cvar => `${cvar.key}=${cvar.value}`).join(', ')}</>
case "SetView":
return <>set view to entity {msg.index}</>
case "GameEventList":
return <>{msg.event_list.map(formatEventDefinition).map((str, i) => (<p key={i}>{str}</p>))}</>
case "PacketEntities":
let entities = msg.entities.map(entity => formatEntity(entity, prop_names, class_names)).map((str, i) => <p
key={i}>{str}</p>);
let deleted = <></>
if (msg.removed_entities.length > 0) {
deleted = <>deleted: {msg.removed_entities.join(', ')}</>
}
return <>
{entities}
{deleted}
</>
default:
let json = msg;
delete json.type;
return <>{JSON.stringify(json)}</>
}
}
function formatUserCmd(cmd: UserCmd): string {
let out = `${cmd.command_number} - tick ${cmd.tick_count}: `;
const formatOptionNum = (x: number | null) => x === null ? 0 : x;
const anyNonNull = (xs: (number | null)[]) => xs.findIndex(x => x !== null) != -1;
let parts = [];
if (anyNonNull(cmd.view_angles)) {
parts.push(`view angles: ${cmd.view_angles.map(formatOptionNum).join(',')}`);
}
if (anyNonNull(cmd.movement)) {
parts.push(`movement: ${cmd.movement.map(formatOptionNum).join(',')}`);
}
if (cmd.mouse_dx !== null || cmd.mouse_dy !== null) {
parts.push(`mouse: ${[cmd.mouse_dx, cmd.mouse_dy].map(formatOptionNum).join(',')}`);
}
if (cmd.impulse) {
parts.push(`impulse ${cmd.impulse}`)
}
if (cmd.buttons) {
parts.push(`buttons ${cmd.buttons}`)
}
if (cmd.weapon_select) {
parts.push(`weapon ${cmd.weapon_select.select}(${cmd.weapon_select.subtype})`)
}
if (parts.length == 0) {
parts.push(`no data`)
}
return out + parts.join(', ');
}
function formatPropValue(value: SendPropValue): string {
if (Array.isArray(value)) {
return '[' + value.map(formatPropValue).join(',') + ']'
} else if (typeof value === "number" || typeof value === "string") {
return `${value}`
} else {
return JSON.stringify(value)
}
}
function formatEntity(entity: PacketEntity, prop_names: Map<number, { table: String, prop: String }>, class_names: Map<number, String>,): string {
let class_name = class_names.get(entity.server_class);
let props = entity.props.map(prop => {
let names = prop_names.get(prop.identifier);
if (names) {
return `${names.table}.${names.prop}=${formatPropValue(prop.value)}`;
} else {
return `[unknown prop]=${prop.value}`;
}
})
return `entity ${entity.entity_index}(${class_name}) ${entity.pvs}: ` + props.join(', ');
}
function formatEventDefinition(event: GameEventDefinition): string {
let values = event.entries.map(entry => `${entry.name}: ${entry.kind}`);
return `${event.event_type}{${values.join(', ')}}`;
}