@linxin666/dsh-pet 0.3.2 → 0.3.3

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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # node scripts/verify-docs.mjs --write <dir>
5
- README.md: 02e682f7c14dee40461f177660a3c976fc4bb05d
6
- README.zh.md: d263d62d64cde1cd14a4e8656646166b944c4c0c
5
+ README.md: ffeff4808b44845783cb85423a6bf8a1cacdcd84
6
+ README.zh.md: 8cf46c60798a6711696bde433abcecae2dbe2b76
package/README.md CHANGED
@@ -192,7 +192,7 @@ A status bubble can carry a small ornament ahead of its text (built-in: the spou
192
192
  | `whale-girl` | 鲸鱼娘(原版) | The repository's original whale-girl atlas |
193
193
  | `whale-girl-refined` | 鲸鱼娘(精致版) | An AI-assisted derivative with repaired and refined details, based on the whale-girl design direction |
194
194
 
195
- The refined variant references DreamSkin's “DeepSeek-Whale” theme. The historical source record identifies `powerdog996` as the original theme author and marks the theme as MIT: [DreamSkin](https://dreamskin.cc), [repository source record](https://github.com/zhu1090093659/dsh-web-ui/commit/87edd7ff4800dffd40bc93fb76e4ae450390facd). This attribution records the source and derivative relationship; it does not present the refined variant as an official work of the original author or redefine the original artwork's licensing scope.
195
+ The refined variant references DreamSkin's “DeepSeek-Whale” theme. The historical source record identifies `powerdog996` as the original theme author and marks the theme as MIT: [DreamSkin](https://dreamskin.cc), [repository source record](https://github.com/zhu1090093659/dsh-web/commit/87edd7ff4800dffd40bc93fb76e4ae450390facd). This attribution records the source and derivative relationship; it does not present the refined variant as an official work of the original author or redefine the original artwork's licensing scope.
196
196
 
197
197
  ## Animation preview
198
198
 
@@ -255,15 +255,15 @@ global React root (createRoot → document.body) <-- polling 2s -- pet-client (b
255
255
 
256
256
  ## Install
257
257
 
258
- Install the family aggregate package `@linxin666/dsh-web-ui-all` (all plugins and skins in one) or this plugin alone:
258
+ Install the family aggregate package `@linxin666/dsh-web-all` (all plugins and skins in one) or this plugin alone:
259
259
 
260
260
  ```sh
261
261
  ### From npm (recommended)
262
262
  dsh plugin --profile web add @linxin666/dsh-pet@latest
263
263
 
264
264
  ### From the repository (development)
265
- git clone https://github.com/zhu1090093659/dsh-web-ui.git
266
- cd dsh-web-ui
265
+ git clone https://github.com/zhu1090093659/dsh-web.git
266
+ cd dsh-web
267
267
  pnpm install && pnpm -r build
268
268
  dsh plugin --profile web add link:$(pwd)/packages/dsh-pet
269
269
 
@@ -294,6 +294,10 @@ The two built-in whale-girl atlases use the same 9-state × 8-column contract: `
294
294
  - The plugin never downloads executables and never bundles the Live2D Cubism Core.
295
295
  - Manifests are fail-closed on structure: unknown fields or renderers reject the entry with a diagnostic shown in settings.
296
296
 
297
+ ## Telemetry
298
+
299
+ The browser half sends one anonymous install heartbeat per UTC day to dsh-market.com: a random localStorage id plus this package's name, nothing else. The server stores only a salted hash of that id, never IP addresses, and exposes aggregate counts only. See [docs/telemetry.md](../../docs/telemetry.md) for the full contract.
300
+
297
301
  ## License
298
302
 
299
303
  [BSD-3-Clause](LICENSE)
package/README.zh.md CHANGED
@@ -192,7 +192,7 @@ Live2D 清单把七个活动相位映射到模型的动作组:
192
192
  | `whale-girl` | 鲸鱼娘(原版) | 仓库原有的鲸鱼娘图集 |
193
193
  | `whale-girl-refined` | 鲸鱼娘(精致版) | 以鲸鱼娘设计方向为基础,经 AI 辅助二次创作、修复和细节精修的衍生版本 |
194
194
 
195
- 精致版参考了 DreamSkin 的「DeepSeek-鲸鱼娘」主题。历史来源记录标注原主题作者为 `powerdog996`,并标注主题为 MIT:[DreamSkin](https://dreamskin.cc)、[仓库来源记录](https://github.com/zhu1090093659/dsh-web-ui/commit/87edd7ff4800dffd40bc93fb76e4ae450390facd)。此处用于记录素材来源与衍生关系;精致版不表述为原作者的官方作品,也不重新定义原始美术作品的授权范围。
195
+ 精致版参考了 DreamSkin 的「DeepSeek-鲸鱼娘」主题。历史来源记录标注原主题作者为 `powerdog996`,并标注主题为 MIT:[DreamSkin](https://dreamskin.cc)、[仓库来源记录](https://github.com/zhu1090093659/dsh-web/commit/87edd7ff4800dffd40bc93fb76e4ae450390facd)。此处用于记录素材来源与衍生关系;精致版不表述为原作者的官方作品,也不重新定义原始美术作品的授权范围。
196
196
 
197
197
  ## 动画预览
198
198
 
@@ -255,15 +255,15 @@ dsh-pet/
255
255
 
256
256
  ## 安装
257
257
 
258
- 安装聚合全家桶 `@linxin666/dsh-web-ui-all`(全部插件与皮肤一次到位),或单独安装本插件:
258
+ 安装聚合全家桶 `@linxin666/dsh-web-all`(全部插件与皮肤一次到位),或单独安装本插件:
259
259
 
260
260
  ```sh
261
261
  ### 从 npm 安装(推荐)
262
262
  dsh plugin --profile web add @linxin666/dsh-pet@latest
263
263
 
264
264
  ### 从仓库安装(开发调试)
265
- git clone https://github.com/zhu1090093659/dsh-web-ui.git
266
- cd dsh-web-ui
265
+ git clone https://github.com/zhu1090093659/dsh-web.git
266
+ cd dsh-web
267
267
  pnpm install && pnpm -r build
268
268
  dsh plugin --profile web add link:$(pwd)/packages/dsh-pet
269
269
 
@@ -294,6 +294,10 @@ pnpm typecheck # 仅类型检查
294
294
  - 插件从不下载可执行文件,也从不内置 Live2D Cubism Core。
295
295
  - 清单结构 fail-closed:未知字段或未知渲染器直接拒载,并在设置中给出诊断。
296
296
 
297
+ ## 数据遥测
298
+
299
+ 浏览器半区每个 UTC 日向 dsh-market.com 发送一次匿名安装心跳:仅含一个 localStorage 随机 ID 与本包名,无其他数据。服务端只存储该 ID 的加盐哈希,不存 IP,且只暴露聚合计数。完整契约见 [docs/telemetry.md](../../docs/telemetry.md)。
300
+
297
301
  ## 许可证
298
302
 
299
303
  [BSD-3-Clause](LICENSE)
package/lib/client.js CHANGED
@@ -1964,7 +1964,7 @@ window.__ModuleLoader__.load({
1964
1964
  /**
1965
1965
  * Write every staged edit, then re-seed from what the Host accepted.
1966
1966
  *
1967
- * When the scope carries the optional batch surface (the dsh-web-ui
1967
+ * When the scope carries the optional batch surface (the dsh-web
1968
1968
  * bridge scope), every planned write rides one mutation so cross-field
1969
1969
  * validate hooks (baseURL+model) judge the batch as a unit instead of
1970
1970
  * deadlocking on per-field writes. Otherwise the per-field loop runs.
@@ -2514,6 +2514,76 @@ window.__ModuleLoader__.load({
2514
2514
  return text;
2515
2515
  }
2516
2516
  //#endregion
2517
+ //#region src/client/telemetry.ts
2518
+ const VISITOR_KEY = "dsh-web-ui-telemetry-visitor";
2519
+ const DAY_KEY_PREFIX = "dsh-web-ui-telemetry-day:";
2520
+ const ENDPOINT = "https://dsh-market.com/api/telemetry/event";
2521
+ /** The building package's version, when the bundle carries it. */
2522
+ function bakedVersion() {
2523
+ try {
2524
+ return "0.3.3";
2525
+ } catch {
2526
+ return;
2527
+ }
2528
+ }
2529
+ /** Read or lazily create the anonymous visitor id; null when storage is unavailable. */
2530
+ function visitorId() {
2531
+ try {
2532
+ const existing = localStorage.getItem(VISITOR_KEY);
2533
+ if (existing && /^[A-Za-z0-9_-]{16,64}$/.test(existing)) return existing;
2534
+ const fresh = crypto.randomUUID().replaceAll("-", "");
2535
+ localStorage.setItem(VISITOR_KEY, fresh);
2536
+ return fresh;
2537
+ } catch {
2538
+ return null;
2539
+ }
2540
+ }
2541
+ /** Drop stale per-day dedup keys so localStorage does not grow forever. */
2542
+ function pruneDayKeys(today) {
2543
+ try {
2544
+ for (let index = localStorage.length - 1; index >= 0; index -= 1) {
2545
+ const key = localStorage.key(index);
2546
+ if (key !== null && key.startsWith(DAY_KEY_PREFIX) && key !== DAY_KEY_PREFIX + today) localStorage.removeItem(key);
2547
+ }
2548
+ } catch {}
2549
+ }
2550
+ /**
2551
+ * Fire the daily heartbeat for the given items at most once per UTC day per
2552
+ * browser. Never throws and never blocks the caller. Items without an explicit
2553
+ * version inherit the bundle's baked build version.
2554
+ */
2555
+ function reportDailyHeartbeat(items) {
2556
+ try {
2557
+ if (items.length === 0) return;
2558
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2559
+ if (navigator.webdriver) return;
2560
+ if (localStorage.getItem(DAY_KEY_PREFIX + today) !== null) return;
2561
+ const visitor = visitorId();
2562
+ if (visitor === null) return;
2563
+ pruneDayKeys(today);
2564
+ const payloadItems = items.map((item) => {
2565
+ const out = { name: item.name };
2566
+ const version = item.version ?? bakedVersion();
2567
+ if (version !== void 0) out.version = version;
2568
+ if (item.channel !== void 0) out.channel = item.channel;
2569
+ return out;
2570
+ });
2571
+ const body = JSON.stringify({
2572
+ kind: "heartbeat",
2573
+ visitor,
2574
+ items: payloadItems
2575
+ });
2576
+ fetch(ENDPOINT, {
2577
+ method: "POST",
2578
+ headers: { "content-type": "application/json" },
2579
+ body,
2580
+ keepalive: true
2581
+ }).then((response) => {
2582
+ if (response.ok) localStorage.setItem(DAY_KEY_PREFIX + today, "1");
2583
+ }).catch(() => {});
2584
+ } catch {}
2585
+ }
2586
+ //#endregion
2517
2587
  //#region src/client/index.ts
2518
2588
  /** Same-origin JSON fetch helper (GET without body, POST with JSON body). */
2519
2589
  async function petFetch(path, body) {
@@ -2555,6 +2625,7 @@ window.__ModuleLoader__.load({
2555
2625
  * @param ctx - client root context.
2556
2626
  */
2557
2627
  function apply(ctx) {
2628
+ reportDailyHeartbeat([{ name: "@linxin666/dsh-pet" }]);
2558
2629
  ctx.effect(() => {
2559
2630
  try {
2560
2631
  return ctx.locale.register("pet", {