@linxin666/dsh-pet 0.2.6 → 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/README.i18n.yaml +2 -2
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/assets/whale/pet.json +54 -54
- package/assets/whale-refined/pet.json +96 -1
- package/lib/client.js +84 -14
- package/lib/client.js.map +1 -1
- package/lib/index.js +62 -58
- package/lib/types/access.js +1 -1
- package/lib/types/affinity.d.ts +18 -18
- package/lib/types/affinity.d.ts.map +1 -1
- package/lib/types/affinity.js +1 -1
- package/lib/types/chatter.d.ts.map +1 -1
- package/lib/types/client/PetDockEntry.js +2 -2
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PetSettingsCard.js +2 -2
- package/lib/types/client/PetSprite.d.ts.map +1 -1
- package/lib/types/client/PetSprite.js +27 -21
- package/lib/types/client/PluginSettingsCard.d.ts +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +56 -9
- package/lib/types/client/locales.d.ts +100 -100
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/renderers/PetRendererSwitch.js +2 -2
- package/lib/types/client/renderers/live2d/Live2dVisualMount.js +2 -2
- package/lib/types/client/renderers/live2d.js +2 -2
- package/lib/types/client/renderers/registry.d.ts.map +1 -1
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/spritesheet.js +1 -1
- package/lib/types/client/ui-teardown.d.ts +29 -0
- package/lib/types/client/ui-teardown.d.ts.map +1 -0
- package/lib/types/client/ui-teardown.js +41 -0
- package/lib/types/contracts/status-decoration.d.ts +1 -1
- package/lib/types/decoration.d.ts +1 -1
- package/lib/types/decoration.d.ts.map +1 -1
- package/lib/types/decoration.js +1 -1
- package/lib/types/event-projection.js +1 -1
- package/lib/types/index.js +13 -13
- package/lib/types/invariant.js +2 -2
- package/lib/types/ledger.d.ts.map +1 -1
- package/lib/types/ledger.js +3 -3
- package/lib/types/manifest-v2.d.ts +1 -1
- package/lib/types/manifest-v2.d.ts.map +1 -1
- package/lib/types/model3.js +1 -1
- package/lib/types/persist.js +3 -3
- package/lib/types/registry.d.ts +5 -1
- package/lib/types/registry.d.ts.map +1 -1
- package/lib/types/registry.js +22 -18
- package/lib/types/remarks.d.ts.map +1 -1
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +4 -4
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +7 -7
- package/lib/types/state.d.ts.map +1 -1
- package/lib/types/voice-pack.d.ts +3 -3
- package/lib/types/voice-pack.d.ts.map +1 -1
- package/lib/types/voice-pack.js +1 -1
- package/package.json +12 -9
- package/src/client/PetSprite.test.tsx +168 -26
- package/src/client/PetSprite.tsx +21 -15
- package/src/client/index.test.tsx +118 -11
- package/src/client/index.ts +51 -3
- package/src/client/ui-teardown.ts +47 -0
- package/src/registry.test.ts +14 -0
- package/src/registry.ts +14 -10
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
|
-
/**
|
|
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
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
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
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
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
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
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
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
+
450,
|
|
2530
|
+
450,
|
|
2531
|
+
450,
|
|
2532
|
+
450
|
|
2529
2533
|
],
|
|
2530
2534
|
loop: true
|
|
2531
2535
|
},
|
|
2532
2536
|
jumping: {
|
|
2533
2537
|
durations: [
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
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
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
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
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
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
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
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
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2585
|
+
650,
|
|
2586
|
+
650,
|
|
2587
|
+
650,
|
|
2588
|
+
650,
|
|
2589
|
+
650,
|
|
2590
|
+
650
|
|
2587
2591
|
],
|
|
2588
2592
|
loop: true
|
|
2589
2593
|
}
|
package/lib/types/access.js
CHANGED
package/lib/types/affinity.d.ts
CHANGED
|
@@ -40,40 +40,40 @@ export declare const AFFINITY_MAX = 999999999;
|
|
|
40
40
|
* characters); they read as a growing star trail alongside the rank name. */
|
|
41
41
|
export declare const AFFINITY_RANKS: readonly [{
|
|
42
42
|
readonly min: 0;
|
|
43
|
-
readonly name:
|
|
44
|
-
readonly emoji:
|
|
43
|
+
readonly name: "幼鲸";
|
|
44
|
+
readonly emoji: "*";
|
|
45
45
|
}, {
|
|
46
46
|
readonly min: 25;
|
|
47
|
-
readonly name:
|
|
48
|
-
readonly emoji:
|
|
47
|
+
readonly name: "伙伴";
|
|
48
|
+
readonly emoji: "**";
|
|
49
49
|
}, {
|
|
50
50
|
readonly min: 50;
|
|
51
|
-
readonly name:
|
|
52
|
-
readonly emoji:
|
|
51
|
+
readonly name: "挚友";
|
|
52
|
+
readonly emoji: "***";
|
|
53
53
|
}, {
|
|
54
54
|
readonly min: 80;
|
|
55
|
-
readonly name:
|
|
56
|
-
readonly emoji:
|
|
55
|
+
readonly name: "深海羁绊";
|
|
56
|
+
readonly emoji: "****";
|
|
57
57
|
}, {
|
|
58
58
|
readonly min: 200;
|
|
59
|
-
readonly name:
|
|
60
|
-
readonly emoji:
|
|
59
|
+
readonly name: "心有灵犀";
|
|
60
|
+
readonly emoji: "*****";
|
|
61
61
|
}, {
|
|
62
62
|
readonly min: 500;
|
|
63
|
-
readonly name:
|
|
64
|
-
readonly emoji:
|
|
63
|
+
readonly name: "传说羁绊";
|
|
64
|
+
readonly emoji: "******";
|
|
65
65
|
}, {
|
|
66
66
|
readonly min: 2000;
|
|
67
|
-
readonly name:
|
|
68
|
-
readonly emoji:
|
|
67
|
+
readonly name: "神话羁绊";
|
|
68
|
+
readonly emoji: "*******";
|
|
69
69
|
}, {
|
|
70
70
|
readonly min: 10000;
|
|
71
|
-
readonly name:
|
|
72
|
-
readonly emoji:
|
|
71
|
+
readonly name: "永恒之契";
|
|
72
|
+
readonly emoji: "********";
|
|
73
73
|
}, {
|
|
74
74
|
readonly min: 100000;
|
|
75
|
-
readonly name:
|
|
76
|
-
readonly emoji:
|
|
75
|
+
readonly name: "鲸生共渡";
|
|
76
|
+
readonly emoji: "*********";
|
|
77
77
|
}];
|
|
78
78
|
/** Interaction tuning (all in points / ms). */
|
|
79
79
|
export interface AffinityConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"affinity.d.ts","sourceRoot":"","sources":["../../src/affinity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAA;AAE3C,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,YAAc,CAAA;AAEvC;;;;8EAI8E;AAC9E,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"affinity.d.ts","sourceRoot":"","sources":["../../src/affinity.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,uDAAuD;AACvD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAA;AAE3C,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAA;IACd,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,YAAc,CAAA;AAEvC;;;;8EAI8E;AAC9E,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUjB,CAAA;AAEV,+CAA+C;AAC/C,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,aAAa,EAAE,MAAM,CAAA;IACrB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,qBAAqB,EAAE,cAMnC,CAAA;AAED,wBAAgB,aAAa,IAAI,aAAa,CAW7C;AAED,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,EAAE,aAAa,CAAA;IACvB,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAA;IAChB,iEAAiE;IACjE,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,8BAA8B;AAC9B,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAMtE;AAED,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,6DAA6D;IAC7D,WAAW,EAAE,OAAO,CAAA;IACpB,kDAAkD;IAClD,YAAY,EAAE,OAAO,CAAA;CACtB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,cAAsC,GAC7C,eAAe,CAYjB;AAYD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,cAAsC,GAC7C,kBAAkB,CA2CpB;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAC7B,KAAK,EAAE,aAAa,EACpB,MAAM,GAAE,cAAsC,GAC7C,aAAa,CAKf"}
|
package/lib/types/affinity.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* built-in pool); the ledger layers per-pet custom remarks on top.
|
|
8
8
|
* @module @linxin666/dsh-pet/affinity
|
|
9
9
|
*/
|
|
10
|
-
import { BUILTIN_REMARKS, builtinRemark } from
|
|
10
|
+
import { BUILTIN_REMARKS, builtinRemark } from "./remarks.js";
|
|
11
11
|
/**
|
|
12
12
|
* Affinity points cap. Historically 100; removed so long-term companions
|
|
13
13
|
* keep growing — the default limit is now the full 999,999,999 range.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chatter.d.ts","sourceRoot":"","sources":["../../src/chatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,uEAAuE;AACvE,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,SAAS,GACT,UAAU,GACV,QAAQ,GACR,YAAY,GACZ,MAAM,GACN,QAAQ,GACR,YAAY,GACZ,WAAW,GACX,aAAa,GACb,SAAS,CAAA;AAEb,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAEpC,uEAAuE;AACvE,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC,CAqIzE,CAAA;AAED,yDAAyD;AACzD,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,OAAO,GACP,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,IAAI,GACJ,WAAW,GACX,UAAU,GACV,KAAK,GACL,QAAQ,GACR,UAAU,GACV,MAAM,GACN,SAAS,GACT,KAAK,GACL,KAAK,GACL,SAAS,CAAA;AAEb,gFAAgF;AAChF,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAG/C,CAAA;AAED,+EAA+E;AAC/E,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAGlD,CAAA;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAkB3D;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC,CAyJxE,CAAA;AAED,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAMhD,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAkCvF;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAA2B;
|
|
1
|
+
{"version":3,"file":"chatter.d.ts","sourceRoot":"","sources":["../../src/chatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,8 +12,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
12
12
|
* @module @linxin666/dsh-pet/client/PetDockEntry
|
|
13
13
|
*/
|
|
14
14
|
import { useEffect, useSyncExternalStore } from 'react';
|
|
15
|
-
import { PetSprite } from
|
|
16
|
-
import { PetRendererSwitch } from
|
|
15
|
+
import { PetSprite } from "./PetSprite.js";
|
|
16
|
+
import { PetRendererSwitch } from "./renderers/PetRendererSwitch.js";
|
|
17
17
|
import styles from './pet.module.css';
|
|
18
18
|
const DEFAULT_DISPLAY = { visible: true, size: 160, right: 24, bottom: 20 };
|
|
19
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAC7F,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAI1F,OAAO,EAAoD,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,IAAI,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAG1J,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qBAAqB;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,4BAA4B;IAC5B,OAAO,EAAE,cAAc,CAAA;IACvB,qBAAqB;IACrB,OAAO,EAAE,cAAc,CAAA;IACvB,iBAAiB;IACjB,IAAI,EAAE,cAAc,CAAA;IACpB,mBAAmB;IACnB,KAAK,EAAE,cAAc,CAAA;IACrB,oBAAoB;IACpB,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB;IACpB,KAAK,EAAE,cAAc,CAAA;IACrB,uCAAuC;IACvC,iBAAiB,EAAE,cAAc,CAAA;IACjC,wEAAwE;IACxE,UAAU,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACvD,+EAA+E;IAC/E,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAC7C;AAED,gEAAgE;AAChE,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,KAAK,EAAE;QACL,iEAAiE;QACjE,eAAe,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;KACrD,CAAA;CACF;AAQD,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;CAChB;AAiBD,2DAA2D;AAC3D,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAI3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAI;IAEpB,uEAAuE;
|
|
1
|
+
{"version":3,"file":"PetSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PetSettingsCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { PluginSettingsCard, ValueField, BooleanField, ChoiceField } from
|
|
3
|
-
import { CardForm, booleanField, choiceField, numberField } from
|
|
2
|
+
import { PluginSettingsCard, ValueField, BooleanField, ChoiceField } from "./PluginSettingsCard.js";
|
|
3
|
+
import { CardForm, booleanField, choiceField, numberField } from "./settings-form.js";
|
|
4
4
|
import sectionCss from './settings-section.module.css';
|
|
5
5
|
/** Fetch the registry list (the same data the sprite renders from). */
|
|
6
6
|
async function fetchPetChoices() {
|
|
@@ -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;
|
|
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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* Pet sprite companion component — the browser half's centerpiece. Renders a
|
|
4
4
|
* fixed-position floating sprite (React portal onto document.body), plays
|
|
@@ -12,9 +12,9 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
12
12
|
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
13
13
|
import { createPortal } from 'react-dom';
|
|
14
14
|
import clsx from 'clsx';
|
|
15
|
-
import { framePosition, rowOfTrack, trimTrack } from
|
|
16
|
-
import { sequenceFrameAt } from
|
|
17
|
-
import { animationForPhase } from
|
|
15
|
+
import { framePosition, rowOfTrack, trimTrack } from "./spritesheet.js";
|
|
16
|
+
import { sequenceFrameAt } from "./sequences.js";
|
|
17
|
+
import { animationForPhase } from "../state.js";
|
|
18
18
|
import styles from './pet.module.css';
|
|
19
19
|
/** Clamp a drag offset inside the viewport with a margin. */
|
|
20
20
|
function clampOffset(value, max) {
|
|
@@ -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
|
|
60
|
+
let timer = 0;
|
|
61
61
|
let index = segment.from;
|
|
62
62
|
let elapsed = 0;
|
|
63
63
|
let last = performance.now();
|
|
64
|
-
const tick = (
|
|
65
|
-
const
|
|
66
|
-
|
|
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] ??
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
index
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
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
|
-
|
|
91
|
+
timer = window.setTimeout(tick, Math.max(1, duration - elapsed));
|
|
86
92
|
};
|
|
87
|
-
|
|
88
|
-
return () =>
|
|
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;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { type ReactNode } from 'react';
|
|
10
10
|
import type { CardShell } from './settings-form.ts';
|
|
11
11
|
/** Copy keys the card chrome itself reads; every consumer locale carries this shared vocabulary. */
|
|
12
|
-
export declare const CARD_COPY_KEYS: readonly [
|
|
12
|
+
export declare const CARD_COPY_KEYS: readonly ["settings.collapse", "settings.expand", "settings.notExposed", "settings.unsaved", "settings.readOnly", "settings.saveFailed", "settings.discard", "settings.save", "settings.saving"];
|
|
13
13
|
/** Copy key the card chrome itself reads. */
|
|
14
14
|
export type CardCopyKey = (typeof CARD_COPY_KEYS)[number];
|
|
15
15
|
/** Key domain for the plugin's own copy (inferred per consumer). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PluginSettingsCard.tsx"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,EAAiF,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACrH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAGnD,oGAAoG;AACpG,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"PluginSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PluginSettingsCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -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;
|
|
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"}
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { createElement } from 'react';
|
|
14
14
|
import { createRoot } from 'react-dom/client';
|
|
15
|
-
import { createPetStore } from
|
|
16
|
-
import { PetDockEntry } from
|
|
17
|
-
import { defaultPetRendererRegistry } from
|
|
18
|
-
import { live2dRenderer } from
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
15
|
+
import { createPetStore } from "./pet-store.js";
|
|
16
|
+
import { PetDockEntry } from "./PetDockEntry.js";
|
|
17
|
+
import { defaultPetRendererRegistry } from "./renderers/registry.js";
|
|
18
|
+
import { live2dRenderer } from "./renderers/live2d.js";
|
|
19
|
+
import { registerPetUiTeardown, takeoverPetUiTeardown } from "./ui-teardown.js";
|
|
20
|
+
import { PetSettingsSection, PetSettingsCardController } from "./PetSettingsCard.js";
|
|
21
|
+
import { NS, en, zh, t } from "./locales.js";
|
|
21
22
|
/** Same-origin JSON fetch helper (GET without body, POST with JSON body). */
|
|
22
23
|
async function petFetch(path, body) {
|
|
23
24
|
const response = await fetch(path, body === undefined
|
|
@@ -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
|
-
|
|
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
|
}
|