@pixui-dev/pxw 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/pxw.js +199 -199
- package/bin/wpbuild.js +10 -10
- package/config/default.conf +20 -20
- package/config/devops.js +372 -361
- package/config/h5es.js +10 -10
- package/config/index.html +183 -181
- package/config/pfbs.js +245 -245
- package/config/util.js +140 -140
- package/config/webpack.js +325 -309
- package/lib/assets/check.html +62 -62
- package/lib/assets/preact.js +4354 -4354
- package/lib/check/main.less +62 -62
- package/lib/check/main.tsx +41 -41
- package/lib/check/tool.js +3 -3
- package/lib/check/util.tsx +110 -110
- package/lib/grpc-web/dist/ChunkParser.js +117 -117
- package/lib/grpc-web/dist/Code.js +58 -58
- package/lib/grpc-web/dist/client.js +299 -299
- package/lib/grpc-web/dist/debug.js +16 -16
- package/lib/grpc-web/dist/detach.js +7 -7
- package/lib/grpc-web/dist/index.js +29 -29
- package/lib/grpc-web/dist/invoke.js +32 -32
- package/lib/grpc-web/dist/message.js +3 -3
- package/lib/grpc-web/dist/metadata.js +5 -5
- package/lib/grpc-web/dist/service.js +3 -3
- package/lib/grpc-web/dist/transports/Transport.js +15 -15
- package/lib/grpc-web/dist/transports/http/fetch.js +117 -117
- package/lib/grpc-web/dist/transports/http/http.js +15 -15
- package/lib/grpc-web/dist/transports/http/xhr.js +136 -136
- package/lib/grpc-web/dist/transports/http/xhrUtil.js +36 -36
- package/lib/grpc-web/dist/transports/websocket/websocket.js +95 -95
- package/lib/grpc-web/dist/typings/ChunkParser.d.ts +17 -17
- package/lib/grpc-web/dist/typings/Code.d.ts +20 -20
- package/lib/grpc-web/dist/typings/client.d.ts +25 -25
- package/lib/grpc-web/dist/typings/debug.d.ts +1 -1
- package/lib/grpc-web/dist/typings/detach.d.ts +1 -1
- package/lib/grpc-web/dist/typings/index.d.ts +45 -45
- package/lib/grpc-web/dist/typings/invoke.d.ts +20 -20
- package/lib/grpc-web/dist/typings/message.d.ts +8 -8
- package/lib/grpc-web/dist/typings/metadata.d.ts +2 -2
- package/lib/grpc-web/dist/typings/service.d.ts +16 -16
- package/lib/grpc-web/dist/typings/transports/Transport.d.ts +22 -22
- package/lib/grpc-web/dist/typings/transports/http/fetch.d.ts +6 -6
- package/lib/grpc-web/dist/typings/transports/http/http.d.ts +5 -5
- package/lib/grpc-web/dist/typings/transports/http/xhr.d.ts +27 -27
- package/lib/grpc-web/dist/typings/transports/http/xhrUtil.d.ts +3 -3
- package/lib/grpc-web/dist/typings/transports/websocket/websocket.d.ts +2 -2
- package/lib/grpc-web/dist/typings/unary.d.ts +23 -23
- package/lib/grpc-web/dist/typings/util.d.ts +2 -2
- package/lib/grpc-web/dist/unary.js +44 -44
- package/lib/grpc-web/dist/util.js +11 -11
- package/lib/grpcTransport/PixHttp2Transport.ts +107 -107
- package/lib/grpcTransport/PixLuaTransport.ts +82 -82
- package/lib/h5es-types/v1.9.2/h5es.d.ts +1698 -1698
- package/lib/h5es-types/v3.5.0/h5es.d.ts +1788 -1788
- package/lib/pi_component/tinyList/tinyList.js +483 -483
- package/lib/pi_component/tinyList/tinyList.tsx +517 -517
- package/lib/preact-router.js +395 -395
- package/lib/preact.js +4355 -4355
- package/lib/preact.tq.js +4385 -4385
- package/lib/react-window/src/FixedSizeGrid.js +172 -172
- package/lib/react-window/src/FixedSizeList.js +91 -91
- package/lib/react-window/src/VariableSizeGrid.js +329 -329
- package/lib/react-window/src/VariableSizeList.js +231 -231
- package/lib/react-window/src/__tests__/FixedSizeGrid.js +942 -942
- package/lib/react-window/src/__tests__/FixedSizeList.js +749 -749
- package/lib/react-window/src/__tests__/VariableSizeGrid.js +598 -598
- package/lib/react-window/src/__tests__/VariableSizeList.js +345 -345
- package/lib/react-window/src/__tests__/__snapshots__/FixedSizeGrid.js.snap +912 -912
- package/lib/react-window/src/__tests__/__snapshots__/FixedSizeList.js.snap +568 -568
- package/lib/react-window/src/__tests__/__snapshots__/VariableSizeGrid.js.snap +542 -542
- package/lib/react-window/src/__tests__/__snapshots__/VariableSizeList.js.snap +331 -331
- package/lib/react-window/src/__tests__/areEqual.js +28 -28
- package/lib/react-window/src/__tests__/shouldComponentUpdate.js +32 -32
- package/lib/react-window/src/areEqual.js +13 -13
- package/lib/react-window/src/createGridComponent.js +657 -657
- package/lib/react-window/src/createListComponent.js +574 -574
- package/lib/react-window/src/domHelpers.js +69 -69
- package/lib/react-window/src/index.js +9 -9
- package/lib/react-window/src/shallowDiffers.js +17 -17
- package/lib/react-window/src/shouldComponentUpdate.js +11 -11
- package/lib/react-window/src/test.js.flow +382 -382
- package/lib/react-window/src/timer.js +36 -36
- package/lib/types/dom.ts +17 -17
- package/lib/types/ext.d.ts +81 -81
- package/lib/types/preact/css.d.ts +7476 -7476
- package/lib/types/preact/index.d.ts +340 -340
- package/lib/types/preact/internal.d.ts +94 -94
- package/lib/types/preact/jsx.d.ts +309 -309
- package/lib/types/preact-router/index.d.ts +84 -84
- package/package.json +113 -113
- package/scripts/pack.js +40 -40
- package/scripts/postinstall.js +11 -11
- package/scripts/run-pxw.js +12 -12
- package/tsconfig.json +30 -30
package/config/pfbs.js
CHANGED
|
@@ -1,245 +1,245 @@
|
|
|
1
|
-
let fs = require('fs');
|
|
2
|
-
let path = require('path');
|
|
3
|
-
let cp = require('child_process');
|
|
4
|
-
const { isHeritageClause } = require('typescript');
|
|
5
|
-
|
|
6
|
-
function isBufferHeaderMatch(buffer, pattern, n = pattern.length) {
|
|
7
|
-
// 确保输入是 Buffer 类型
|
|
8
|
-
if (!Buffer.isBuffer(buffer) || !Buffer.isBuffer(pattern)) {
|
|
9
|
-
throw new TypeError('Both buffer and pattern must be of type Buffer');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// 如果 n 超过 buffer 或 pattern 的长度,返回 false
|
|
13
|
-
if (n > buffer.length || n > pattern.length) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// 比较前 n 个字节
|
|
18
|
-
for (let i = 0; i < n; i++) {
|
|
19
|
-
if (buffer[i] !== pattern[i]) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let suffix = '';
|
|
28
|
-
if (process.platform == 'win32') suffix = '.exe';
|
|
29
|
-
if (process.platform == 'linux') suffix = '-ubuntu';
|
|
30
|
-
let pfbsLatest = path.resolve(process.cwd(), `.cache/pfbs${suffix}`);
|
|
31
|
-
let pfbsConvert = async (ver, isJS, input, fn) => {
|
|
32
|
-
let pfbs = pfbsLatest;
|
|
33
|
-
if (ver[0] == '0') pfbs = pfbsLatest.replace('pfbs', 'pfbs-0.4');
|
|
34
|
-
console.log('use pfbs', pfbs);
|
|
35
|
-
if (!fs.existsSync(pfbs)) {
|
|
36
|
-
let url = process.env.PFBS_DOWNLOAD_SITE || 'http://9.134.150.252:8090/dev/tools/pfbs/';
|
|
37
|
-
url += path.basename(pfbs);
|
|
38
|
-
try {
|
|
39
|
-
let buffer;
|
|
40
|
-
if (typeof fetch !== 'undefined') {
|
|
41
|
-
let res = await fetch(url);
|
|
42
|
-
buffer = await res.arrayBuffer();
|
|
43
|
-
}
|
|
44
|
-
else if (typeof XMLHttpRequest !== 'undefined') {
|
|
45
|
-
buffer = await new Promise((resolve, reject) => {
|
|
46
|
-
const xhr = new XMLHttpRequest();
|
|
47
|
-
xhr.open('GET', url, true);
|
|
48
|
-
xhr.responseType = 'arraybuffer';
|
|
49
|
-
|
|
50
|
-
xhr.onload = () => {
|
|
51
|
-
if (xhr.status >= 200 && xhr.status < 300) {
|
|
52
|
-
resolve(xhr.response);
|
|
53
|
-
} else {
|
|
54
|
-
reject(new Error(`XHR failed with status ${xhr.status}`));
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
xhr.onerror = () => reject(new Error('Network Error'));
|
|
59
|
-
xhr.send();
|
|
60
|
-
});
|
|
61
|
-
}else if (typeof require !== 'undefined' && require('http')) {
|
|
62
|
-
const http = require('http');
|
|
63
|
-
console.log('http: ', url)
|
|
64
|
-
buffer = await new Promise((resolve, reject) => {
|
|
65
|
-
http.get(url, (res) => {
|
|
66
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
67
|
-
return resolve(this._fetchBuffer(res.headers.location));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const chunks = [];
|
|
71
|
-
res.on('data', (chunk) => chunks.push(chunk));
|
|
72
|
-
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
73
|
-
}).on('error', reject);
|
|
74
|
-
});
|
|
75
|
-
}else {
|
|
76
|
-
throw new Error('No supported HTTP client available');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!fs.existsSync(path.dirname(pfbs))) fs.mkdirSync(path.dirname(pfbs));
|
|
80
|
-
fs.writeFileSync(pfbs, new Uint8Array(buffer));
|
|
81
|
-
fs.chmodSync(pfbs, '755');
|
|
82
|
-
} catch (e) {
|
|
83
|
-
console.error('Request failed:', e);
|
|
84
|
-
fn(input);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
let buffers = [];
|
|
89
|
-
let addBuffer = (chunk, encoding) => {
|
|
90
|
-
if (chunk === undefined) return;
|
|
91
|
-
if (typeof chunk === 'string') {
|
|
92
|
-
chunk = Buffer.from(chunk, encoding);
|
|
93
|
-
}
|
|
94
|
-
buffers.push(chunk);
|
|
95
|
-
};
|
|
96
|
-
let opts = isJS ? ['--js'] : [];
|
|
97
|
-
let child = cp.spawn(pfbs, ['--src', 'stdin', ...opts], {
|
|
98
|
-
windowsHide: true,
|
|
99
|
-
});
|
|
100
|
-
child.stdout.on('data', (data) => {
|
|
101
|
-
// console.log('get data from fbs', data.byteLength);
|
|
102
|
-
addBuffer(data);
|
|
103
|
-
});
|
|
104
|
-
child.stdout.on('close', () => {
|
|
105
|
-
let output = Buffer.concat(buffers);
|
|
106
|
-
// console.log('get data from fbs finish!!', output.length);
|
|
107
|
-
fn(output);
|
|
108
|
-
});
|
|
109
|
-
child.stderr.on('data', (data) => {
|
|
110
|
-
console.log('get err from pfbs', data.toString());
|
|
111
|
-
});
|
|
112
|
-
child.stdin.write(input);
|
|
113
|
-
child.stdin.end();
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
module.exports.getMiddleware = () => {
|
|
117
|
-
let log = () => {};
|
|
118
|
-
log = console.log;
|
|
119
|
-
//拦截输出,当agent为PixUI且输出类型为html时,转换为fbs二进制数据再返回
|
|
120
|
-
return (req, res, next) => {
|
|
121
|
-
//去掉缓存标记,因为很可能源文件没变,但转换后的表示变了
|
|
122
|
-
delete req.headers['if-none-match'];
|
|
123
|
-
let ua = req.get('User-Agent');
|
|
124
|
-
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
|
125
|
-
let disablePFBS = req.headers['x-disable-http-pfbs'] == 'true';
|
|
126
|
-
log('req', req.url, ua, ip, `disablePFBS:${disablePFBS}`);
|
|
127
|
-
// log( JSON.stringify(req.headers));
|
|
128
|
-
|
|
129
|
-
let _write = res.write;
|
|
130
|
-
let _end = res.end;
|
|
131
|
-
let _send = res.send;
|
|
132
|
-
|
|
133
|
-
let buffers = [];
|
|
134
|
-
let addBuffer = (chunk, encoding) => {
|
|
135
|
-
if (chunk === undefined) return;
|
|
136
|
-
if (typeof chunk === 'string') {
|
|
137
|
-
chunk = Buffer.from(chunk, encoding);
|
|
138
|
-
}
|
|
139
|
-
buffers.push(chunk);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
let guessMime = (url) => {
|
|
143
|
-
if (url.endsWith('.js')) return 'text/javascript';
|
|
144
|
-
if (url.endsWith('.html')) return 'text/html';
|
|
145
|
-
return 'text/plain';
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
let mime = '';
|
|
149
|
-
let _setHeader = res.setHeader;
|
|
150
|
-
res.setHeader = function (k, v) {
|
|
151
|
-
console.log('hook set', k, v);
|
|
152
|
-
if (k == 'Content-Length') return; //不要显式设置长度,pfbs转换后可能会变小,导致客户端空等
|
|
153
|
-
if (k == 'Content-Type') mime = v;
|
|
154
|
-
_setHeader.call(res, k, v);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
//处理直接裸写的情况,一般见于发送静态文件
|
|
158
|
-
res.writeLog = 0;
|
|
159
|
-
res.write = function (chunk, encoding) {
|
|
160
|
-
let type = res.get('Content-Type');
|
|
161
|
-
if (++res.writeLog <= 10) {
|
|
162
|
-
log('hook write...', type, chunk.length);
|
|
163
|
-
if (res.writeLog == 10) {
|
|
164
|
-
log('hook write is too many, ignore next log');
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
addBuffer(chunk, encoding);
|
|
168
|
-
};
|
|
169
|
-
const pattern1 = Buffer.from([0x50, 0x49, 0x58, 0x32, 0x43, 0x42, 0x4a, 0x51]);
|
|
170
|
-
const pattern2 = Buffer.from([0x10, 0, 0, 0, 0x50, 0x49, 0x58, 0x30]);
|
|
171
|
-
res.end = function (chunk, encoding) {
|
|
172
|
-
res.write = _write;
|
|
173
|
-
res.end = _end;
|
|
174
|
-
let type = res.get('Content-Type') || mime;
|
|
175
|
-
if (chunk) addBuffer(chunk, encoding);
|
|
176
|
-
let data = Buffer.concat(buffers);
|
|
177
|
-
|
|
178
|
-
let isAlreadyPfbs = isBufferHeaderMatch(data, pattern1) || isBufferHeaderMatch(data, pattern2);
|
|
179
|
-
|
|
180
|
-
log('hook end...', type, data.length, req.url, 'isAlreadyPfbs', isAlreadyPfbs);
|
|
181
|
-
|
|
182
|
-
let isPixUI = /PixUI/.test(ua);
|
|
183
|
-
let isHTML = type.indexOf('text/html') >= 0;
|
|
184
|
-
let isJS = type.indexOf('javascript') >= 0;
|
|
185
|
-
let isCSS = type.indexOf('text/css') >= 0;
|
|
186
|
-
if (isHTML && !isAlreadyPfbs) {
|
|
187
|
-
let c1 = data.toString('utf-8');
|
|
188
|
-
let c2 = c1.replace(
|
|
189
|
-
'</body>',
|
|
190
|
-
`<script>
|
|
191
|
-
(function() {
|
|
192
|
-
var ws = new WebSocket('ws://' + window.location.host+ '/notify?reloadMode=RELOAD_ON_SAVE&referrer=' + encodeURIComponent(window.location.pathname))
|
|
193
|
-
ws.onmessage = function (msg) {
|
|
194
|
-
if (msg.data === 'reload') {
|
|
195
|
-
window.location.reload();
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
})();
|
|
199
|
-
</script></body>`,
|
|
200
|
-
);
|
|
201
|
-
console.log('insert hotreload to html', data.length, c1.length, c2.length);
|
|
202
|
-
// console.log(c1);
|
|
203
|
-
data = c2;
|
|
204
|
-
}
|
|
205
|
-
if (isPixUI && !isAlreadyPfbs && !disablePFBS && (isHTML || isJS)) {
|
|
206
|
-
let ver = /(\d)\.(\d)\.(\d+)/.exec(ua); // 0.2.*以上
|
|
207
|
-
pfbsConvert(ver.splice(1), isJS, data, (out) => {
|
|
208
|
-
console.log('pfbsconvert>>', req.url, data.length, out.length);
|
|
209
|
-
res.write = _write;
|
|
210
|
-
res.end = _end;
|
|
211
|
-
_end.call(this, out);
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
console.log('directly call end...', data.length, type, _end);
|
|
216
|
-
_end.call(this, data);
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
// 处理通过send发送的情况,如webpack合成的html
|
|
221
|
-
res.send = function (c) {
|
|
222
|
-
let isPixUI = /PixUI/.test(ua);
|
|
223
|
-
let type = res.get('Content-Type') || 'text/plain';
|
|
224
|
-
let isHTML = type.indexOf('text/html') >= 0;
|
|
225
|
-
let isJS = type.indexOf('javascript') >= 0;
|
|
226
|
-
let isCSS = type.indexOf('text/css') >= 0;
|
|
227
|
-
if (isPixUI && !disablePFBS && (isHTML || isJS)) {
|
|
228
|
-
log('hook send...', c.length, type);
|
|
229
|
-
let ver = /(\d)\.(\d)\.(\d+)/.exec(ua); // 0.2.*以上
|
|
230
|
-
pfbsConvert(ver.splice(1), isJS, c, (out) => {
|
|
231
|
-
res.send = _send;
|
|
232
|
-
res.end = _end;
|
|
233
|
-
res.setHeader = _setHeader;
|
|
234
|
-
res.setHeader('Content-Type', 'application/octet-stream');
|
|
235
|
-
_send.call(res, out);
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
console.log('directly call send...', c.length, type, _send);
|
|
240
|
-
_send.call(this, c);
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
next();
|
|
244
|
-
};
|
|
245
|
-
};
|
|
1
|
+
let fs = require('fs');
|
|
2
|
+
let path = require('path');
|
|
3
|
+
let cp = require('child_process');
|
|
4
|
+
const { isHeritageClause } = require('typescript');
|
|
5
|
+
|
|
6
|
+
function isBufferHeaderMatch(buffer, pattern, n = pattern.length) {
|
|
7
|
+
// 确保输入是 Buffer 类型
|
|
8
|
+
if (!Buffer.isBuffer(buffer) || !Buffer.isBuffer(pattern)) {
|
|
9
|
+
throw new TypeError('Both buffer and pattern must be of type Buffer');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 如果 n 超过 buffer 或 pattern 的长度,返回 false
|
|
13
|
+
if (n > buffer.length || n > pattern.length) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 比较前 n 个字节
|
|
18
|
+
for (let i = 0; i < n; i++) {
|
|
19
|
+
if (buffer[i] !== pattern[i]) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let suffix = '';
|
|
28
|
+
if (process.platform == 'win32') suffix = '.exe';
|
|
29
|
+
if (process.platform == 'linux') suffix = '-ubuntu';
|
|
30
|
+
let pfbsLatest = path.resolve(process.cwd(), `.cache/pfbs${suffix}`);
|
|
31
|
+
let pfbsConvert = async (ver, isJS, input, fn) => {
|
|
32
|
+
let pfbs = pfbsLatest;
|
|
33
|
+
if (ver[0] == '0') pfbs = pfbsLatest.replace('pfbs', 'pfbs-0.4');
|
|
34
|
+
console.log('use pfbs', pfbs);
|
|
35
|
+
if (!fs.existsSync(pfbs)) {
|
|
36
|
+
let url = process.env.PFBS_DOWNLOAD_SITE || 'http://9.134.150.252:8090/dev/tools/pfbs/';
|
|
37
|
+
url += path.basename(pfbs);
|
|
38
|
+
try {
|
|
39
|
+
let buffer;
|
|
40
|
+
if (typeof fetch !== 'undefined') {
|
|
41
|
+
let res = await fetch(url);
|
|
42
|
+
buffer = await res.arrayBuffer();
|
|
43
|
+
}
|
|
44
|
+
else if (typeof XMLHttpRequest !== 'undefined') {
|
|
45
|
+
buffer = await new Promise((resolve, reject) => {
|
|
46
|
+
const xhr = new XMLHttpRequest();
|
|
47
|
+
xhr.open('GET', url, true);
|
|
48
|
+
xhr.responseType = 'arraybuffer';
|
|
49
|
+
|
|
50
|
+
xhr.onload = () => {
|
|
51
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
52
|
+
resolve(xhr.response);
|
|
53
|
+
} else {
|
|
54
|
+
reject(new Error(`XHR failed with status ${xhr.status}`));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
xhr.onerror = () => reject(new Error('Network Error'));
|
|
59
|
+
xhr.send();
|
|
60
|
+
});
|
|
61
|
+
}else if (typeof require !== 'undefined' && require('http')) {
|
|
62
|
+
const http = require('http');
|
|
63
|
+
console.log('http: ', url)
|
|
64
|
+
buffer = await new Promise((resolve, reject) => {
|
|
65
|
+
http.get(url, (res) => {
|
|
66
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
67
|
+
return resolve(this._fetchBuffer(res.headers.location));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const chunks = [];
|
|
71
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
72
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
73
|
+
}).on('error', reject);
|
|
74
|
+
});
|
|
75
|
+
}else {
|
|
76
|
+
throw new Error('No supported HTTP client available');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!fs.existsSync(path.dirname(pfbs))) fs.mkdirSync(path.dirname(pfbs));
|
|
80
|
+
fs.writeFileSync(pfbs, new Uint8Array(buffer));
|
|
81
|
+
fs.chmodSync(pfbs, '755');
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error('Request failed:', e);
|
|
84
|
+
fn(input);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
let buffers = [];
|
|
89
|
+
let addBuffer = (chunk, encoding) => {
|
|
90
|
+
if (chunk === undefined) return;
|
|
91
|
+
if (typeof chunk === 'string') {
|
|
92
|
+
chunk = Buffer.from(chunk, encoding);
|
|
93
|
+
}
|
|
94
|
+
buffers.push(chunk);
|
|
95
|
+
};
|
|
96
|
+
let opts = isJS ? ['--js'] : [];
|
|
97
|
+
let child = cp.spawn(pfbs, ['--src', 'stdin', ...opts], {
|
|
98
|
+
windowsHide: true,
|
|
99
|
+
});
|
|
100
|
+
child.stdout.on('data', (data) => {
|
|
101
|
+
// console.log('get data from fbs', data.byteLength);
|
|
102
|
+
addBuffer(data);
|
|
103
|
+
});
|
|
104
|
+
child.stdout.on('close', () => {
|
|
105
|
+
let output = Buffer.concat(buffers);
|
|
106
|
+
// console.log('get data from fbs finish!!', output.length);
|
|
107
|
+
fn(output);
|
|
108
|
+
});
|
|
109
|
+
child.stderr.on('data', (data) => {
|
|
110
|
+
console.log('get err from pfbs', data.toString());
|
|
111
|
+
});
|
|
112
|
+
child.stdin.write(input);
|
|
113
|
+
child.stdin.end();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
module.exports.getMiddleware = () => {
|
|
117
|
+
let log = () => {};
|
|
118
|
+
log = console.log;
|
|
119
|
+
//拦截输出,当agent为PixUI且输出类型为html时,转换为fbs二进制数据再返回
|
|
120
|
+
return (req, res, next) => {
|
|
121
|
+
//去掉缓存标记,因为很可能源文件没变,但转换后的表示变了
|
|
122
|
+
delete req.headers['if-none-match'];
|
|
123
|
+
let ua = req.get('User-Agent');
|
|
124
|
+
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
|
125
|
+
let disablePFBS = req.headers['x-disable-http-pfbs'] == 'true';
|
|
126
|
+
log('req', req.url, ua, ip, `disablePFBS:${disablePFBS}`);
|
|
127
|
+
// log( JSON.stringify(req.headers));
|
|
128
|
+
|
|
129
|
+
let _write = res.write;
|
|
130
|
+
let _end = res.end;
|
|
131
|
+
let _send = res.send;
|
|
132
|
+
|
|
133
|
+
let buffers = [];
|
|
134
|
+
let addBuffer = (chunk, encoding) => {
|
|
135
|
+
if (chunk === undefined) return;
|
|
136
|
+
if (typeof chunk === 'string') {
|
|
137
|
+
chunk = Buffer.from(chunk, encoding);
|
|
138
|
+
}
|
|
139
|
+
buffers.push(chunk);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
let guessMime = (url) => {
|
|
143
|
+
if (url.endsWith('.js')) return 'text/javascript';
|
|
144
|
+
if (url.endsWith('.html')) return 'text/html';
|
|
145
|
+
return 'text/plain';
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
let mime = '';
|
|
149
|
+
let _setHeader = res.setHeader;
|
|
150
|
+
res.setHeader = function (k, v) {
|
|
151
|
+
console.log('hook set', k, v);
|
|
152
|
+
if (k == 'Content-Length') return; //不要显式设置长度,pfbs转换后可能会变小,导致客户端空等
|
|
153
|
+
if (k == 'Content-Type') mime = v;
|
|
154
|
+
_setHeader.call(res, k, v);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
//处理直接裸写的情况,一般见于发送静态文件
|
|
158
|
+
res.writeLog = 0;
|
|
159
|
+
res.write = function (chunk, encoding) {
|
|
160
|
+
let type = res.get('Content-Type');
|
|
161
|
+
if (++res.writeLog <= 10) {
|
|
162
|
+
log('hook write...', type, chunk.length);
|
|
163
|
+
if (res.writeLog == 10) {
|
|
164
|
+
log('hook write is too many, ignore next log');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
addBuffer(chunk, encoding);
|
|
168
|
+
};
|
|
169
|
+
const pattern1 = Buffer.from([0x50, 0x49, 0x58, 0x32, 0x43, 0x42, 0x4a, 0x51]);
|
|
170
|
+
const pattern2 = Buffer.from([0x10, 0, 0, 0, 0x50, 0x49, 0x58, 0x30]);
|
|
171
|
+
res.end = function (chunk, encoding) {
|
|
172
|
+
res.write = _write;
|
|
173
|
+
res.end = _end;
|
|
174
|
+
let type = res.get('Content-Type') || mime;
|
|
175
|
+
if (chunk) addBuffer(chunk, encoding);
|
|
176
|
+
let data = Buffer.concat(buffers);
|
|
177
|
+
|
|
178
|
+
let isAlreadyPfbs = isBufferHeaderMatch(data, pattern1) || isBufferHeaderMatch(data, pattern2);
|
|
179
|
+
|
|
180
|
+
log('hook end...', type, data.length, req.url, 'isAlreadyPfbs', isAlreadyPfbs);
|
|
181
|
+
|
|
182
|
+
let isPixUI = /PixUI/.test(ua);
|
|
183
|
+
let isHTML = type.indexOf('text/html') >= 0;
|
|
184
|
+
let isJS = type.indexOf('javascript') >= 0;
|
|
185
|
+
let isCSS = type.indexOf('text/css') >= 0;
|
|
186
|
+
if (isHTML && !isAlreadyPfbs) {
|
|
187
|
+
let c1 = data.toString('utf-8');
|
|
188
|
+
let c2 = c1.replace(
|
|
189
|
+
'</body>',
|
|
190
|
+
`<script>
|
|
191
|
+
(function() {
|
|
192
|
+
var ws = new WebSocket('ws://' + window.location.host+ '/notify?reloadMode=RELOAD_ON_SAVE&referrer=' + encodeURIComponent(window.location.pathname))
|
|
193
|
+
ws.onmessage = function (msg) {
|
|
194
|
+
if (msg.data === 'reload') {
|
|
195
|
+
window.location.reload();
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
})();
|
|
199
|
+
</script></body>`,
|
|
200
|
+
);
|
|
201
|
+
console.log('insert hotreload to html', data.length, c1.length, c2.length);
|
|
202
|
+
// console.log(c1);
|
|
203
|
+
data = c2;
|
|
204
|
+
}
|
|
205
|
+
if (isPixUI && !isAlreadyPfbs && !disablePFBS && (isHTML || isJS)) {
|
|
206
|
+
let ver = /(\d)\.(\d)\.(\d+)/.exec(ua); // 0.2.*以上
|
|
207
|
+
pfbsConvert(ver.splice(1), isJS, data, (out) => {
|
|
208
|
+
console.log('pfbsconvert>>', req.url, data.length, out.length);
|
|
209
|
+
res.write = _write;
|
|
210
|
+
res.end = _end;
|
|
211
|
+
_end.call(this, out);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
console.log('directly call end...', data.length, type, _end);
|
|
216
|
+
_end.call(this, data);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// 处理通过send发送的情况,如webpack合成的html
|
|
221
|
+
res.send = function (c) {
|
|
222
|
+
let isPixUI = /PixUI/.test(ua);
|
|
223
|
+
let type = res.get('Content-Type') || 'text/plain';
|
|
224
|
+
let isHTML = type.indexOf('text/html') >= 0;
|
|
225
|
+
let isJS = type.indexOf('javascript') >= 0;
|
|
226
|
+
let isCSS = type.indexOf('text/css') >= 0;
|
|
227
|
+
if (isPixUI && !disablePFBS && (isHTML || isJS)) {
|
|
228
|
+
log('hook send...', c.length, type);
|
|
229
|
+
let ver = /(\d)\.(\d)\.(\d+)/.exec(ua); // 0.2.*以上
|
|
230
|
+
pfbsConvert(ver.splice(1), isJS, c, (out) => {
|
|
231
|
+
res.send = _send;
|
|
232
|
+
res.end = _end;
|
|
233
|
+
res.setHeader = _setHeader;
|
|
234
|
+
res.setHeader('Content-Type', 'application/octet-stream');
|
|
235
|
+
_send.call(res, out);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
console.log('directly call send...', c.length, type, _send);
|
|
240
|
+
_send.call(this, c);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
next();
|
|
244
|
+
};
|
|
245
|
+
};
|