@linxin666/dsh-pet 0.2.7 → 0.2.8

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/lib/index.js CHANGED
@@ -2481,109 +2481,113 @@ function assetUrl(prefix, id, file) {
2481
2481
  const path = file.split("/").filter((segment) => segment !== "").join("/");
2482
2482
  return prefix + "/" + encodeURIComponent(id) + "/" + path;
2483
2483
  }
2484
- /** Default per-track rhythm (hatch-pet contract table). */
2484
+ /**
2485
+ * Default per-track rhythm — the shared slow baseline every sprite2d pet
2486
+ * plays unless its manifest overrides a track (user request: all pets were
2487
+ * too fast at the legacy hatch-pet contract pace).
2488
+ */
2485
2489
  const DEFAULT_TRACK_PATTERNS = {
2486
2490
  idle: {
2487
2491
  durations: [
2488
- 280,
2489
- 110,
2490
- 110,
2491
- 140,
2492
- 140,
2493
- 320
2492
+ 500,
2493
+ 500,
2494
+ 600,
2495
+ 500,
2496
+ 500,
2497
+ 600
2494
2498
  ],
2495
2499
  loop: true
2496
2500
  },
2497
2501
  "running-right": {
2498
2502
  durations: [
2499
- 120,
2500
- 120,
2501
- 120,
2502
- 120,
2503
- 120,
2504
- 120,
2505
- 120,
2506
- 220
2503
+ 300,
2504
+ 300,
2505
+ 300,
2506
+ 300,
2507
+ 300,
2508
+ 300,
2509
+ 300,
2510
+ 400
2507
2511
  ],
2508
2512
  loop: true
2509
2513
  },
2510
2514
  "running-left": {
2511
2515
  durations: [
2512
- 120,
2513
- 120,
2514
- 120,
2515
- 120,
2516
- 120,
2517
- 120,
2518
- 120,
2519
- 220
2516
+ 300,
2517
+ 300,
2518
+ 300,
2519
+ 300,
2520
+ 300,
2521
+ 300,
2522
+ 300,
2523
+ 400
2520
2524
  ],
2521
2525
  loop: true
2522
2526
  },
2523
2527
  waving: {
2524
2528
  durations: [
2525
- 140,
2526
- 140,
2527
- 140,
2528
- 280
2529
+ 450,
2530
+ 450,
2531
+ 450,
2532
+ 450
2529
2533
  ],
2530
2534
  loop: true
2531
2535
  },
2532
2536
  jumping: {
2533
2537
  durations: [
2534
- 140,
2535
- 140,
2536
- 140,
2537
- 140,
2538
- 280
2538
+ 400,
2539
+ 400,
2540
+ 400,
2541
+ 450,
2542
+ 450
2539
2543
  ],
2540
2544
  loop: false,
2541
2545
  fallback: "idle"
2542
2546
  },
2543
2547
  failed: {
2544
2548
  durations: [
2545
- 140,
2546
- 140,
2547
- 140,
2548
- 140,
2549
- 140,
2550
- 140,
2551
- 140,
2552
- 240
2549
+ 550,
2550
+ 550,
2551
+ 550,
2552
+ 600,
2553
+ 650,
2554
+ 700,
2555
+ 550,
2556
+ 550
2553
2557
  ],
2554
2558
  loop: false,
2555
2559
  fallback: "idle"
2556
2560
  },
2557
2561
  waiting: {
2558
2562
  durations: [
2559
- 150,
2560
- 150,
2561
- 150,
2562
- 150,
2563
- 150,
2564
- 260
2563
+ 550,
2564
+ 550,
2565
+ 600,
2566
+ 550,
2567
+ 550,
2568
+ 600
2565
2569
  ],
2566
2570
  loop: true
2567
2571
  },
2568
2572
  running: {
2569
2573
  durations: [
2570
- 120,
2571
- 120,
2572
- 120,
2573
- 120,
2574
- 120,
2575
- 220
2574
+ 330,
2575
+ 330,
2576
+ 330,
2577
+ 330,
2578
+ 330,
2579
+ 400
2576
2580
  ],
2577
2581
  loop: true
2578
2582
  },
2579
2583
  review: {
2580
2584
  durations: [
2581
- 150,
2582
- 150,
2583
- 150,
2584
- 150,
2585
- 150,
2586
- 280
2585
+ 650,
2586
+ 650,
2587
+ 650,
2588
+ 650,
2589
+ 650,
2590
+ 650
2587
2591
  ],
2588
2592
  loop: true
2589
2593
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PetSprite.d.ts","sourceRoot":"","sources":["../../../src/client/PetSprite.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAkE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,aAAa,CAAA;IACzB,qDAAqD;IACrD,OAAO,EAAE,gBAAgB,CAAA;IACzB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,uDAAuD;IACvD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,4DAA4D;IAC5D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,2DAA2D;IAC3D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,+CAA+C;IAC/C,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;CAC1B;AA0FD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAygB5D"}
1
+ {"version":3,"file":"PetSprite.d.ts","sourceRoot":"","sources":["../../../src/client/PetSprite.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAkE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGnH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAIjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;IAC7B,8EAA8E;IAC9E,UAAU,EAAE,aAAa,CAAA;IACzB,qDAAqD;IACrD,OAAO,EAAE,gBAAgB,CAAA;IACzB,sCAAsC;IACtC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5B,8BAA8B;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,sCAAsC;IACtC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,+BAA+B;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClD,uDAAuD;IACvD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,4DAA4D;IAC5D,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,2DAA2D;IAC3D,cAAc,EAAE,MAAM,IAAI,CAAA;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,+CAA+C;IAC/C,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;CAC1B;AAgGD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,WAAW,CAygB5D"}
@@ -57,35 +57,41 @@ function StatusOrnament(props) {
57
57
  // frame instead — same as the reduced-motion static hold.
58
58
  if (reduceMotion || segment.from === segment.to)
59
59
  return;
60
- let raf = 0;
60
+ let timer = 0;
61
61
  let index = segment.from;
62
62
  let elapsed = 0;
63
63
  let last = performance.now();
64
- const tick = (ts) => {
65
- const delta = ts - last;
66
- last = ts;
64
+ const tick = () => {
65
+ const now = performance.now();
66
+ const delta = now - last;
67
+ last = now;
67
68
  elapsed += delta;
68
- const duration = decoration.durations[index] ?? 160;
69
+ const duration = decoration.durations[index] ?? 120;
70
+ // The segment's frame rate (duration ms, typically 90-160) is far
71
+ // below the rAF cadence, so a 60fps loop would spend ~90% of its
72
+ // ticks doing nothing. Schedule by the remaining time to the next
73
+ // frame instead — the ornament wakes once per frame, not once per
74
+ // screen refresh. A late wake (background tab, jank) carries extra
75
+ // elapsed time, so catch up every due frame like the sprite loop.
69
76
  if (elapsed >= duration) {
70
- elapsed = 0;
71
- if (index < segment.to)
72
- index += 1;
73
- else if (decoration.loop)
74
- index = segment.from;
75
- // Only advance the background when the frame actually changes:
76
- // the segment's frame rate (duration ms, typically 90-160) is far
77
- // below the rAF cadence, so writing the same position every frame
78
- // would churn style recalculations for no visual change.
77
+ do {
78
+ elapsed -= duration;
79
+ if (index < segment.to)
80
+ index += 1;
81
+ else if (decoration.loop)
82
+ index = segment.from;
83
+ } while (elapsed >= duration);
84
+ // Only advance the background when the frame actually changes.
79
85
  el.style.backgroundPosition = position(index);
80
86
  }
81
87
  // A non-looping segment settles on its last frame; stop scheduling
82
88
  // instead of repainting the same position every frame.
83
89
  if (!decoration.loop && index === segment.to)
84
90
  return;
85
- raf = requestAnimationFrame(tick);
91
+ timer = window.setTimeout(tick, Math.max(1, duration - elapsed));
86
92
  };
87
- raf = requestAnimationFrame(tick);
88
- return () => cancelAnimationFrame(raf);
93
+ timer = window.setTimeout(tick, 0);
94
+ return () => window.clearTimeout(timer);
89
95
  }, [shown, segmentKey, frameWidth, decoration.loop, durationsKey]);
90
96
  if (!shown)
91
97
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,aAAa,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AA+DnI,wEAAwE;AACxE,eAAO,MAAM,MAAM,UAA2E,CAAA;AAE9F,qEAAqE;AACrE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACtF,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf;;;;WAIG;QACH,aAAa,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;SAAE,CAAA;KAC1E;CACF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAsN9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,aAAa,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAgEnI,wEAAwE;AACxE,eAAO,MAAM,MAAM,UAA2E,CAAA;AAE9F,qEAAqE;AACrE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC7D,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AACtF,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf;;;;WAIG;QACH,aAAa,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;SAAE,CAAA;KAC1E;CACF;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAqQ9C"}
@@ -16,6 +16,7 @@ import { createPetStore } from "./pet-store.js";
16
16
  import { PetDockEntry } from "./PetDockEntry.js";
17
17
  import { defaultPetRendererRegistry } from "./renderers/registry.js";
18
18
  import { live2dRenderer } from "./renderers/live2d.js";
19
+ import { registerPetUiTeardown, takeoverPetUiTeardown } from "./ui-teardown.js";
19
20
  import { PetSettingsSection, PetSettingsCardController } from "./PetSettingsCard.js";
20
21
  import { NS, en, zh, t } from "./locales.js";
21
22
  /** Same-origin JSON fetch helper (GET without body, POST with JSON body). */
@@ -87,9 +88,23 @@ export function apply(ctx) {
87
88
  });
88
89
  // The global pet entry, its store, and the poll loop live while the plugin
89
90
  // is enabled; toggling the setting off hides the pet and stops polling.
91
+ // 'uiDead' marks a terminal teardown (takeover by a later bundle instance
92
+ // or fiber disposal): a taken-over or disposed instance must never remount
93
+ // from a late settings callback (issue #785).
90
94
  let disposeUi;
95
+ let clearUiTeardown;
96
+ let uiDead = false;
97
+ const killUi = () => {
98
+ if (uiDead)
99
+ return;
100
+ uiDead = true;
101
+ clearUiTeardown?.();
102
+ clearUiTeardown = undefined;
103
+ disposeUi?.();
104
+ disposeUi = undefined;
105
+ };
91
106
  const syncUi = () => {
92
- if (enabled() && disposeUi === undefined) {
107
+ if (!uiDead && enabled() && disposeUi === undefined) {
93
108
  // ONE store instance for the whole app, owned by this apply body. The
94
109
  // pet is host-global (state/display/interactions are /api/pet/*
95
110
  // endpoints with no session dimension), so the slot system's per-session
@@ -244,24 +259,56 @@ export function apply(ctx) {
244
259
  // The entry therefore mounts straight onto document.body via a single
245
260
  // React root for the page lifetime: PetSprite portals itself to body
246
261
  // when visible, and the hidden-state summon button is fixed-positioned.
262
+ //
263
+ // Cross-instance single-mount guard (issue #785): take over the
264
+ // page-global slot first — the previous bundle instance's fiber may
265
+ // still be draining during a client reload, so unmount its React root
266
+ // and remove its container — then sweep containers left behind by
267
+ // instances that predate the teardown registry, so this mount is the
268
+ // page's only [data-dsh-pet-root].
269
+ takeoverPetUiTeardown();
270
+ for (const stale of Array.from(document.querySelectorAll('div[data-dsh-pet-root]'))) {
271
+ stale.remove();
272
+ }
247
273
  const container = document.createElement('div');
248
274
  container.dataset.dshPetRoot = '';
249
275
  container.dataset.dshPlugin = 'pet';
250
276
  document.body.appendChild(container);
251
277
  const petRoot = createRoot(container);
252
278
  petRoot.render(createElement(PetDockEntry, { ...injected(), t }));
279
+ let uiGone = false;
253
280
  disposeUi = () => {
281
+ if (uiGone)
282
+ return;
283
+ uiGone = true;
284
+ clearUiTeardown?.();
285
+ clearUiTeardown = undefined;
254
286
  petRoot.unmount();
255
287
  container.remove();
256
288
  disposePoll();
257
289
  disposeUi = undefined;
258
290
  };
291
+ // The slot teardown is the takeover hook a later apply body runs; it
292
+ // marks this instance terminal so a late settings callback from the
293
+ // still-draining instance cannot remount a second pet.
294
+ clearUiTeardown = registerPetUiTeardown(() => {
295
+ uiDead = true;
296
+ disposeUi?.();
297
+ });
259
298
  }
260
- else if (!enabled() && disposeUi !== undefined) {
299
+ else if (!uiDead && !enabled() && disposeUi !== undefined) {
261
300
  disposeUi();
262
301
  disposeUi = undefined;
263
302
  }
264
303
  };
265
- settingsScope.subscribe(syncUi);
304
+ // The settings subscription and the pet UI lifetime follow the fiber
305
+ // (issue #785): disposal drops the subscription and tears the UI down
306
+ // (terminal), so a hot-reloaded or re-injected bundle never leaves the
307
+ // previous React root, container, or poll loop behind on document.body.
308
+ const unsubscribeSettings = settingsScope.subscribe(syncUi);
309
+ ctx.effect(() => () => {
310
+ unsubscribeSettings();
311
+ killUi();
312
+ }, 'pet: client lifecycle');
266
313
  syncUi();
267
314
  }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Cross-bundle-instance teardown slot for the page-global pet root
3
+ * (issue #785).
4
+ *
5
+ * A client bundle swap (HMR rebuilt frame, plugin update, duplicate
6
+ * injection) runs a new apply body while the previous instance's fiber
7
+ * may still be draining. Module state does not survive the swap, so a
8
+ * closure guard only sees one apply body and the previous instance's
9
+ * container keeps sitting on document.body: the page shows two pets
10
+ * until a full refresh. The slot rides globalThis (which does survive)
11
+ * so a re-apply can find the previous instance and unmount its React
12
+ * root cleanly before mounting its own; the previous fiber's later
13
+ * disposal stays a no-op through the idempotent teardowns.
14
+ */
15
+ /**
16
+ * Claim the page-global pet UI slot with the current instance's teardown
17
+ * (React root unmount + container removal + poll stop).
18
+ * @param teardown - what a later instance runs to take the slot over.
19
+ * @returns a disposer that clears the slot when the current instance's
20
+ * UI is torn down (settings toggle, takeover, or fiber disposal).
21
+ */
22
+ export declare function registerPetUiTeardown(teardown: () => void): () => void;
23
+ /**
24
+ * Run the previous instance's teardown if one is registered, so the
25
+ * re-applying instance becomes the sole owner of the page-global pet
26
+ * root. No-op when the previous fiber already tore down cleanly.
27
+ */
28
+ export declare function takeoverPetUiTeardown(): void;
29
+ //# sourceMappingURL=ui-teardown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-teardown.d.ts","sourceRoot":"","sources":["../../../src/client/ui-teardown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAMtE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Cross-bundle-instance teardown slot for the page-global pet root
3
+ * (issue #785).
4
+ *
5
+ * A client bundle swap (HMR rebuilt frame, plugin update, duplicate
6
+ * injection) runs a new apply body while the previous instance's fiber
7
+ * may still be draining. Module state does not survive the swap, so a
8
+ * closure guard only sees one apply body and the previous instance's
9
+ * container keeps sitting on document.body: the page shows two pets
10
+ * until a full refresh. The slot rides globalThis (which does survive)
11
+ * so a re-apply can find the previous instance and unmount its React
12
+ * root cleanly before mounting its own; the previous fiber's later
13
+ * disposal stays a no-op through the idempotent teardowns.
14
+ */
15
+ const SLOT = Symbol.for('dsh-pet.client-ui-teardown');
16
+ /**
17
+ * Claim the page-global pet UI slot with the current instance's teardown
18
+ * (React root unmount + container removal + poll stop).
19
+ * @param teardown - what a later instance runs to take the slot over.
20
+ * @returns a disposer that clears the slot when the current instance's
21
+ * UI is torn down (settings toggle, takeover, or fiber disposal).
22
+ */
23
+ export function registerPetUiTeardown(teardown) {
24
+ const slot = globalThis;
25
+ slot[SLOT] = teardown;
26
+ return () => {
27
+ if (slot[SLOT] === teardown)
28
+ slot[SLOT] = undefined;
29
+ };
30
+ }
31
+ /**
32
+ * Run the previous instance's teardown if one is registered, so the
33
+ * re-applying instance becomes the sole owner of the page-global pet
34
+ * root. No-op when the previous fiber already tore down cleanly.
35
+ */
36
+ export function takeoverPetUiTeardown() {
37
+ const slot = globalThis;
38
+ const teardown = slot[SLOT];
39
+ slot[SLOT] = undefined;
40
+ teardown?.();
41
+ }
@@ -64,7 +64,11 @@ export interface PetTrackDef {
64
64
  /** Track to switch to after a non-looping track finishes. */
65
65
  fallback?: PetAnimation;
66
66
  }
67
- /** Default per-track rhythm (hatch-pet contract table). */
67
+ /**
68
+ * Default per-track rhythm — the shared slow baseline every sprite2d pet
69
+ * plays unless its manifest overrides a track (user request: all pets were
70
+ * too fast at the legacy hatch-pet contract pace).
71
+ */
68
72
  export declare const DEFAULT_TRACK_PATTERNS: Record<PetAnimation, {
69
73
  durations: number[];
70
74
  loop: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"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"}
@@ -86,17 +86,21 @@ function assetUrl(prefix, id, file) {
86
86
  const path = file.split('/').filter(segment => segment !== '').join('/');
87
87
  return prefix + '/' + encodeURIComponent(id) + '/' + path;
88
88
  }
89
- /** Default per-track rhythm (hatch-pet contract table). */
89
+ /**
90
+ * Default per-track rhythm — the shared slow baseline every sprite2d pet
91
+ * plays unless its manifest overrides a track (user request: all pets were
92
+ * too fast at the legacy hatch-pet contract pace).
93
+ */
90
94
  export const DEFAULT_TRACK_PATTERNS = {
91
- idle: { durations: [280, 110, 110, 140, 140, 320], loop: true },
92
- 'running-right': { durations: [120, 120, 120, 120, 120, 120, 120, 220], loop: true },
93
- 'running-left': { durations: [120, 120, 120, 120, 120, 120, 120, 220], loop: true },
94
- waving: { durations: [140, 140, 140, 280], loop: true },
95
- jumping: { durations: [140, 140, 140, 140, 280], loop: false, fallback: 'idle' },
96
- failed: { durations: [140, 140, 140, 140, 140, 140, 140, 240], loop: false, fallback: 'idle' },
97
- waiting: { durations: [150, 150, 150, 150, 150, 260], loop: true },
98
- running: { durations: [120, 120, 120, 120, 120, 220], loop: true },
99
- review: { durations: [150, 150, 150, 150, 150, 280], loop: true },
95
+ idle: { durations: [500, 500, 600, 500, 500, 600], loop: true },
96
+ 'running-right': { durations: [300, 300, 300, 300, 300, 300, 300, 400], loop: true },
97
+ 'running-left': { durations: [300, 300, 300, 300, 300, 300, 300, 400], loop: true },
98
+ waving: { durations: [450, 450, 450, 450], loop: true },
99
+ jumping: { durations: [400, 400, 400, 450, 450], loop: false, fallback: 'idle' },
100
+ failed: { durations: [550, 550, 550, 600, 650, 700, 550, 550], loop: false, fallback: 'idle' },
101
+ waiting: { durations: [550, 550, 600, 550, 550, 600], loop: true },
102
+ running: { durations: [330, 330, 330, 330, 330, 400], loop: true },
103
+ review: { durations: [650, 650, 650, 650, 650, 650], loop: true },
100
104
  };
101
105
  /** Stable id charset: keeps asset URLs plain and filesystem-safe. */
102
106
  const PET_ID_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@linxin666/dsh-pet",
3
3
  "description": "Multi-pet companion plugin for the dsh web GUI: a registry-driven floating pet that reacts to model activity, with per-pet naming, petting/feeding interactions and an affinity score",
4
- "version": "0.2.7",
4
+ "version": "0.2.8",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": "^22.19.0 || >=24.0.0"
@@ -36,6 +36,9 @@
36
36
  ],
37
37
  "license": "Apache-2.0",
38
38
  "dsh": {
39
+ "engines": {
40
+ "dsh": ">=0.1.1-rc.1"
41
+ },
39
42
  "bundle": {
40
43
  "patch": "./cordis.patch.yml"
41
44
  },
@@ -59,14 +62,14 @@
59
62
  },
60
63
  "devDependencies": {
61
64
  "@deepseek-ai/cordis": "^4.0.1",
62
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.1",
63
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
64
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.1-rc.1",
65
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
66
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.1",
67
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
68
- "@deepseek-ai/dsh-session": "^0.1.1-rc.1",
69
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
65
+ "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
66
+ "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
67
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.1-rc.2",
68
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
69
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
70
+ "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
71
+ "@deepseek-ai/dsh-session": "^0.1.1-rc.2",
72
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
70
73
  "@testing-library/dom": "^10.4.1",
71
74
  "@testing-library/react": "^16.3.2",
72
75
  "@types/node": "^22.20.0",