@suifei/dsh-market-lens 0.29.2 → 0.30.0
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/README.md +4 -0
- package/client.js +94 -56
- package/index.js +1 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -204,6 +204,10 @@ node scripts/release.mjs <x.y.z> --msg "..." --token <npm granular token> [--hos
|
|
|
204
204
|
- Yahoo 在部分区域返回 403:美股自动落到腾讯,K 线历史长度可能缩短。
|
|
205
205
|
- 分时图未进首版;详情页暂以 K 线为主视图。
|
|
206
206
|
|
|
207
|
+
## 安全
|
|
208
|
+
|
|
209
|
+
本包只读公开行情、无交易无用户数据出口;npm 扫描器告警的逐条处置与证据见 **`SECURITY.md`**(zod 内存 DoS 已在 0.29.3 修复,其余 eval/URL 等为误报或职责所需)。
|
|
210
|
+
|
|
207
211
|
## License
|
|
208
212
|
|
|
209
213
|
MIT · 图标为本仓库原创绘制。
|
package/client.js
CHANGED
|
@@ -382,7 +382,7 @@ window.__ModuleLoader__.load({
|
|
|
382
382
|
}
|
|
383
383
|
|
|
384
384
|
// ---------- diagnostic reporting (batched POST /market-lens/diag) ----------
|
|
385
|
-
const CLIENT_REV = '0.
|
|
385
|
+
const CLIENT_REV = '0.30.0';
|
|
386
386
|
const diagQueue = [];
|
|
387
387
|
let diagTimer = 0;
|
|
388
388
|
// the host meta tells the real level; until then assume the shipped 'errors' default
|
|
@@ -2086,49 +2086,63 @@ window.__ModuleLoader__.load({
|
|
|
2086
2086
|
const SCROLL_VPX = 28; // wall px/s (~8 lamp rows/s): uniform scroll, smooth and cheap
|
|
2087
2087
|
const VERT_SRC = 'attribute vec2 aPos; void main() { gl_Position = vec4(aPos, 0.0, 1.0); }';
|
|
2088
2088
|
const FRAG_SRC = [
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2089
|
+
'precision highp float;',
|
|
2090
|
+
'uniform vec2 iRes; uniform vec4 uGeo; uniform vec4 uBand; uniform vec4 uPx; uniform vec2 uSzT;',
|
|
2091
|
+
'uniform float uScroll; uniform float uTime;',
|
|
2092
|
+
'uniform sampler2D uStatic; uniform sampler2D uTape;',
|
|
2093
|
+
'vec3 tap5(sampler2D s, vec2 sz, vec2 wp) {',
|
|
2094
|
+
' vec2 uv = wp / sz; vec2 pu = 1.0 / sz; vec3 c = texture2D(s, uv).rgb;',
|
|
2095
|
+
' c = max(c, texture2D(s, uv + vec2(pu.x, 0.0)).rgb);',
|
|
2096
|
+
' c = max(c, texture2D(s, uv - vec2(pu.x, 0.0)).rgb);',
|
|
2097
|
+
' c = max(c, texture2D(s, uv + vec2(0.0, pu.y)).rgb);',
|
|
2098
|
+
' c = max(c, texture2D(s, uv - vec2(0.0, pu.y)).rgb);',
|
|
2099
|
+
' return c;',
|
|
2100
|
+
'}',
|
|
2101
|
+
'void main() {',
|
|
2102
|
+
' vec2 f = vec2(gl_FragCoord.x, iRes.y - gl_FragCoord.y);',
|
|
2103
|
+
' vec2 w = (f - uGeo.xy) / uGeo.z;',
|
|
2104
|
+
' if (w.x < 0.0 || w.y < 0.0 || w.x >= uPx.z || w.y >= uPx.w) { gl_FragColor = vec4(0.016, 0.027, 0.051, 1.0); return; }',
|
|
2105
|
+
' vec2 qn = w / uPx.zw - 0.5;',
|
|
2106
|
+
' float r2 = dot(qn, qn);',
|
|
2107
|
+
' vec2 wd = clamp((qn * (1.0 + 0.045 * r2) + 0.5) * uPx.zw, vec2(0.0), uPx.zw - vec2(0.01));',
|
|
2108
|
+
' vec2 cell = floor(wd / uPx.x);',
|
|
2109
|
+
' vec2 ctr = (cell + 0.5) * uPx.x;',
|
|
2110
|
+
' float half_ = max(0.5 * uPx.y * uGeo.z, 0.5) - 0.3;',
|
|
2111
|
+
' vec2 rr = f - uGeo.xy - cell * uPx.x * uGeo.z;',
|
|
2112
|
+
' vec2 qq = abs(rr - 0.5 * uPx.x * uGeo.z) - max(half_, 0.12);',
|
|
2113
|
+
' float d = length(max(qq, 0.0)) + min(max(qq.x, qq.y), 0.0);',
|
|
2114
|
+
' float mask = smoothstep(0.45, -0.05, d);',
|
|
2115
|
+
' float inBand = step(uBand.x, ctr.y) * step(ctr.y, uBand.x + uBand.y);',
|
|
2116
|
+
' vec2 tp = vec2(ctr.x, mod(ctr.y - uBand.x + uScroll, uBand.z));',
|
|
2117
|
+
' vec3 lit = mix(tap5(uStatic, uPx.zw, ctr), tap5(uTape, uSzT, tp), inBand);',
|
|
2118
|
+
' float lum = max(lit.r, max(lit.g, lit.b));',
|
|
2119
|
+
' float breath = 0.94 + 0.06 * sin(uTime * 1.1);',
|
|
2120
|
+
' vec3 base = mix(vec3(0.016, 0.024, 0.043), vec3(0.05, 0.1, 0.17), mask);',
|
|
2121
|
+
' vec3 col = mix(base, lit * breath, mask * smoothstep(0.1, 0.3, lum));',
|
|
2122
|
+
' vec2 bwn = vec2(wd.x, mod(wd.y - uBand.x + uScroll, uBand.z)) / uSzT;',
|
|
2123
|
+
' vec3 bleed = mix(texture2D(uStatic, wd / uPx.zw).rgb, texture2D(uTape, bwn).rgb, inBand);',
|
|
2124
|
+
' col += bleed * 0.16;',
|
|
2125
|
+
' float ca = 0.002 + 0.010 * r2;',
|
|
2126
|
+
' vec2 wR = wd + (wd - uPx.zw * 0.5) * ca;',
|
|
2127
|
+
' float inBR = step(uBand.x, wR.y) * step(wR.y, uBand.x + uBand.y);',
|
|
2128
|
+
' vec2 tpR = vec2(wR.x, mod(wR.y - uBand.x + uScroll, uBand.z));',
|
|
2129
|
+
' float red = mix(texture2D(uStatic, wR / uPx.zw).r, texture2D(uTape, tpR / uSzT).r, inBR);',
|
|
2130
|
+
' col.r = mix(col.r, red, 0.55);',
|
|
2131
|
+
' float hh = fract(sin(dot(cell + vec2(floor(uTime * 3.0) * 17.0, floor(uTime * 2.0) * 31.0), vec2(127.1, 311.7))) * 43758.545);',
|
|
2132
|
+
' col *= mix(0.93, 1.05, hh);',
|
|
2133
|
+
' col *= mix(1.0, 0.15, step(hh, 0.002));',
|
|
2134
|
+
' col *= mix(1.0, 1.5, step(0.9978, hh));',
|
|
2135
|
+
' float wave = 0.5 + 0.5 * sin(cell.y * 0.35 - uTime * 1.7);',
|
|
2136
|
+
' col *= 0.985 + 0.015 * wave;',
|
|
2137
|
+
' float sy = fract(uTime * 0.07) * (uPx.w + 240.0) - 120.0;',
|
|
2138
|
+
' col += vec3(0.05, 0.085, 0.12) * exp(-pow((w.y - sy) * 0.018, 2.0)) * (0.4 + 0.6 * mask);',
|
|
2139
|
+
' float refl = 0.5 + 0.5 * sin(dot(wd, vec2(0.9, 1.4)) - uTime * 0.31);',
|
|
2140
|
+
' col += vec3(0.10, 0.14, 0.20) * smoothstep(0.98, 1.0, refl) * 0.35;',
|
|
2141
|
+
' vec2 vq = w / uPx.zw - 0.5;',
|
|
2142
|
+
' col *= 1.0 - dot(vq, vq) * 0.62;',
|
|
2143
|
+
' gl_FragColor = vec4(min(col, vec3(1.0)), 1.0);',
|
|
2144
|
+
'}',
|
|
2145
|
+
].join('\n');
|
|
2132
2146
|
function wallGL(gl) {
|
|
2133
2147
|
const sh = (type, s) => { const o = gl.createShader(type); gl.shaderSource(o, s); gl.compileShader(o); return o; };
|
|
2134
2148
|
const prog = gl.createProgram();
|
|
@@ -2147,7 +2161,7 @@ window.__ModuleLoader__.load({
|
|
|
2147
2161
|
['iRes', 'uGeo', 'uBand', 'uPx', 'uSzT', 'uScroll', 'uTime', 'uStatic', 'uTape'].forEach((n) => { U[n] = gl.getUniformLocation(prog, n); });
|
|
2148
2162
|
gl.uniform1i(U.uStatic, 0);
|
|
2149
2163
|
gl.uniform1i(U.uTape, 1);
|
|
2150
|
-
return { prog, U };
|
|
2164
|
+
return { prog, U, buf };
|
|
2151
2165
|
}
|
|
2152
2166
|
|
|
2153
2167
|
/**
|
|
@@ -2326,6 +2340,7 @@ window.__ModuleLoader__.load({
|
|
|
2326
2340
|
const staticRef = React.useRef(null);
|
|
2327
2341
|
const tapeCvRef = React.useRef(null);
|
|
2328
2342
|
const dirtyRef = React.useRef(false);
|
|
2343
|
+
const glResRef = React.useRef(null);
|
|
2329
2344
|
const geoPlanRef = React.useRef(null);
|
|
2330
2345
|
const pitchRef = React.useRef(0);
|
|
2331
2346
|
const topRef = React.useRef(0);
|
|
@@ -2554,18 +2569,27 @@ window.__ModuleLoader__.load({
|
|
|
2554
2569
|
cv.height = size.h;
|
|
2555
2570
|
const gl = typeof WebGL2RenderingContext === 'undefined' ? null : cv.getContext('webgl2', { alpha: false, antialias: false });
|
|
2556
2571
|
const x2d = gl === null ? cv.getContext('2d') : null;
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
gl.
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2572
|
+
// GL program + textures are created once per context and reused across
|
|
2573
|
+
// resizes; the old effect recompiled the shader and leaked two textures,
|
|
2574
|
+
// a program and a buffer on every [size] change
|
|
2575
|
+
let res = glResRef.current;
|
|
2576
|
+
if (gl !== null && (res === null || res.gl !== gl)) {
|
|
2577
|
+
const W = wallGL(gl);
|
|
2578
|
+
if (W === null) { res = null; } else {
|
|
2579
|
+
const tex = { s: gl.createTexture(), t: gl.createTexture() };
|
|
2580
|
+
[tex.s, tex.t].forEach((tt) => {
|
|
2581
|
+
gl.bindTexture(gl.TEXTURE_2D, tt);
|
|
2582
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
2583
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
2584
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
2585
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
2586
|
+
});
|
|
2587
|
+
res = { gl, W, tex };
|
|
2588
|
+
}
|
|
2589
|
+
glResRef.current = res;
|
|
2568
2590
|
}
|
|
2591
|
+
const W = res === null ? null : res.W;
|
|
2592
|
+
const tex = res === null ? null : res.tex;
|
|
2569
2593
|
const sc = Math.min(size.w / WALL_W_PX, size.h / WALL_H_PX);
|
|
2570
2594
|
const dw = Math.round(WALL_W_PX * sc);
|
|
2571
2595
|
const dh = Math.round(WALL_H_PX * sc);
|
|
@@ -2584,6 +2608,7 @@ window.__ModuleLoader__.load({
|
|
|
2584
2608
|
const tC = tapeCvRef.current;
|
|
2585
2609
|
if (gp === null || sC === null || tC === null) return;
|
|
2586
2610
|
if (W === null) {
|
|
2611
|
+
if (x2d === null) return; // webgl2 present but shader failed: no 2d context is available on the same canvas
|
|
2587
2612
|
x2d.fillStyle = '#04070d';
|
|
2588
2613
|
x2d.fillRect(0, 0, size.w, size.h);
|
|
2589
2614
|
x2d.drawImage(sC, ox, oy, dw, dh);
|
|
@@ -2621,6 +2646,19 @@ window.__ModuleLoader__.load({
|
|
|
2621
2646
|
raf = window.requestAnimationFrame(step);
|
|
2622
2647
|
return () => window.cancelAnimationFrame(raf);
|
|
2623
2648
|
}, [size]);
|
|
2649
|
+
// release GPU objects once when the board unmounts (resizes reuse them)
|
|
2650
|
+
React.useEffect(() => () => {
|
|
2651
|
+
const r = glResRef.current;
|
|
2652
|
+
if (r !== null && r.gl !== null) {
|
|
2653
|
+
try {
|
|
2654
|
+
r.gl.deleteTexture(r.tex.s);
|
|
2655
|
+
r.gl.deleteTexture(r.tex.t);
|
|
2656
|
+
r.gl.deleteProgram(r.W.prog);
|
|
2657
|
+
r.gl.deleteBuffer(r.W.buf);
|
|
2658
|
+
} catch (e) { /* context already lost */ }
|
|
2659
|
+
glResRef.current = null;
|
|
2660
|
+
}
|
|
2661
|
+
}, []);
|
|
2624
2662
|
const hit = (event) => {
|
|
2625
2663
|
const rect = canvasRef.current.getBoundingClientRect();
|
|
2626
2664
|
const { ox, oy, sc } = geoRef.current;
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suifei/dsh-market-lens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -45,6 +45,14 @@
|
|
|
45
45
|
"@deepseek-ai/dsh-tools": "0.2.2-rc.1",
|
|
46
46
|
"@deepseek-ai/schemastery": "~3.19.0"
|
|
47
47
|
},
|
|
48
|
+
"overrides": {
|
|
49
|
+
"zod": "^4.6.6"
|
|
50
|
+
},
|
|
51
|
+
"pnpm": {
|
|
52
|
+
"overrides": {
|
|
53
|
+
"zod": "^4.6.6"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
48
56
|
"peerDependencies": {
|
|
49
57
|
"@deepseek-ai/cordis": "~4.1.0"
|
|
50
58
|
},
|