@linxin666/dsh-pet 0.3.5 → 0.3.6
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/contracts/voice-pack-v1.schema.json +30 -0
- package/cordis.patch.yml +1 -1
- package/lib/client.js +144 -16
- package/lib/client.js.map +1 -1
- package/lib/index.js +56 -17
- package/lib/invariant.js +1 -1
- package/lib/{state-DrMX22GL.js → state-NvDEoCln.js} +5 -2
- package/lib/types/access.d.ts +5 -4
- package/lib/types/access.d.ts.map +1 -1
- package/lib/types/access.js +2 -12
- package/lib/types/affinity.d.ts +2 -0
- package/lib/types/affinity.d.ts.map +1 -1
- package/lib/types/affinity.js +12 -0
- package/lib/types/client/PetSprite.d.ts.map +1 -1
- package/lib/types/client/PetSprite.js +7 -1
- package/lib/types/client/locales.d.ts +18 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +18 -0
- package/lib/types/client/renderers/frames2d.d.ts +12 -0
- package/lib/types/client/renderers/frames2d.d.ts.map +1 -1
- package/lib/types/client/renderers/frames2d.js +143 -18
- package/lib/types/ledger.d.ts +4 -2
- package/lib/types/ledger.d.ts.map +1 -1
- package/lib/types/ledger.js +4 -4
- package/lib/types/pair-access.d.ts +35 -0
- package/lib/types/pair-access.d.ts.map +1 -0
- package/lib/types/pair-access.js +19 -0
- package/lib/types/remarks.d.ts +1 -1
- package/lib/types/remarks.d.ts.map +1 -1
- package/lib/types/remarks.js +11 -2
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +4 -1
- package/lib/types/voice-pack.d.ts +5 -0
- package/lib/types/voice-pack.d.ts.map +1 -1
- package/lib/types/voice-pack.js +36 -2
- package/package.json +1 -1
- package/src/access.ts +7 -27
- package/src/affinity.ts +13 -0
- package/src/client/PetSprite.test.tsx +18 -0
- package/src/client/PetSprite.tsx +9 -1
- package/src/client/locales.ts +18 -0
- package/src/client/renderers/frames2d.test.ts +101 -0
- package/src/client/renderers/frames2d.ts +138 -18
- package/src/ledger.ts +6 -4
- package/src/pair-access.ts +49 -0
- package/src/remarks.test.ts +10 -0
- package/src/remarks.ts +9 -2
- package/src/service.ts +4 -1
- package/src/voice-pack.test.ts +39 -0
- package/src/voice-pack.ts +37 -2
|
@@ -206,6 +206,36 @@
|
|
|
206
206
|
"description": "Subset of actions to render in canonical order; absent = all three, [] = none."
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
|
+
},
|
|
210
|
+
"remarks": {
|
|
211
|
+
"type": "object",
|
|
212
|
+
"additionalProperties": false,
|
|
213
|
+
"description": "Pat/feed interaction remark pools (issue #1226). Keyed by pet/petCooldown/feed/feedCooldown/noTreats.",
|
|
214
|
+
"properties": {
|
|
215
|
+
"pet": {
|
|
216
|
+
"$ref": "#/definitions/pool"
|
|
217
|
+
},
|
|
218
|
+
"petCooldown": {
|
|
219
|
+
"$ref": "#/definitions/pool"
|
|
220
|
+
},
|
|
221
|
+
"feed": {
|
|
222
|
+
"$ref": "#/definitions/pool"
|
|
223
|
+
},
|
|
224
|
+
"feedCooldown": {
|
|
225
|
+
"$ref": "#/definitions/pool"
|
|
226
|
+
},
|
|
227
|
+
"noTreats": {
|
|
228
|
+
"$ref": "#/definitions/pool"
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
"ranks": {
|
|
233
|
+
"type": "object",
|
|
234
|
+
"additionalProperties": {
|
|
235
|
+
"type": "string",
|
|
236
|
+
"maxLength": 80
|
|
237
|
+
},
|
|
238
|
+
"description": "Affinity rank name overrides (issue #1226), keyed by tier minimum points or original rank name."
|
|
209
239
|
}
|
|
210
240
|
},
|
|
211
241
|
"definitions": {
|
package/cordis.patch.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dsh-pet bundle patch: inserts its plugin row into the web plugin roster.
|
|
2
2
|
# The bundle is the official dsh plugin shape — install it into a dsh profile
|
|
3
|
-
# (`dsh plugin --profile <name> add link:/Users/zcl/code/dsh-web
|
|
3
|
+
# (`dsh plugin --profile <name> add link:/Users/zcl/code/dsh-web/packages/dsh-pet`). The single
|
|
4
4
|
# row mounts BOTH halves: the host side (pet registry, state machine,
|
|
5
5
|
# affinity score, pet.* RPC service) and the browser side (the modules node
|
|
6
6
|
# half scans dsh.client packages into the web plugin roster, served from this
|
package/lib/client.js
CHANGED
|
@@ -712,7 +712,12 @@ window.__ModuleLoader__.load({
|
|
|
712
712
|
children: displayName
|
|
713
713
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
714
714
|
className: pet_module_css_default.statRank,
|
|
715
|
-
children:
|
|
715
|
+
children: (() => {
|
|
716
|
+
const rawRank = snapshot?.affinity.rank ?? "?";
|
|
717
|
+
const rankKey = `pet.rank.name.${rawRank}`;
|
|
718
|
+
const localized = props.t(rankKey);
|
|
719
|
+
return panelStat("rank", "pet.rank", { rank: localized !== rankKey ? localized : rawRank });
|
|
720
|
+
})()
|
|
716
721
|
})]
|
|
717
722
|
}),
|
|
718
723
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1811,6 +1816,18 @@ window.__ModuleLoader__.load({
|
|
|
1811
1816
|
* phase-mapped track. Rendering never throws: a broken track list degrades
|
|
1812
1817
|
* to the first decodable frame, and the 1.2 s stall watchdog re-kicks the
|
|
1813
1818
|
* playback chain after timer throttling.
|
|
1819
|
+
*
|
|
1820
|
+
* Frame presentation has two modes picked once at mount by capability
|
|
1821
|
+
* probing:
|
|
1822
|
+
* - Canvas bitmap buffer (default where createImageBitmap/fetch/2D context
|
|
1823
|
+
* exist): every frame is decoded exactly once into an ImageBitmap during
|
|
1824
|
+
* the warm pass and drawn onto one <canvas> - steady-state playback issues
|
|
1825
|
+
* zero DOM mutations and zero re-decodes (measured hotspot: swapping
|
|
1826
|
+
* <img>.src per frame drove image decode + invalidation every tick).
|
|
1827
|
+
* - Classic <img> fallback (jsdom/tests or missing APIs): identical to the
|
|
1828
|
+
* historical behavior - cache-warm Image elements plus guarded src swaps,
|
|
1829
|
+
* so environments without modern decoding keep working unchanged.
|
|
1830
|
+
*
|
|
1814
1831
|
* @module @linxin666/dsh-pet/client/renderers/frames2d
|
|
1815
1832
|
*/
|
|
1816
1833
|
/** Stall watchdog period: a looping track stuck longer re-kicks its chain. */
|
|
@@ -1844,19 +1861,79 @@ window.__ModuleLoader__.load({
|
|
|
1844
1861
|
validateConfig: validateFrames2dConfig,
|
|
1845
1862
|
mount(ctx, config) {
|
|
1846
1863
|
const reducedMotion = typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
img
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1864
|
+
let canvas = null;
|
|
1865
|
+
let context2d = null;
|
|
1866
|
+
let img = null;
|
|
1867
|
+
try {
|
|
1868
|
+
if (typeof createImageBitmap === "function" && typeof fetch === "function") {
|
|
1869
|
+
const probe = document.createElement("canvas");
|
|
1870
|
+
const c2d = probe.getContext("2d");
|
|
1871
|
+
if (c2d !== null) {
|
|
1872
|
+
canvas = probe;
|
|
1873
|
+
context2d = c2d;
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
} catch {
|
|
1877
|
+
canvas = null;
|
|
1878
|
+
context2d = null;
|
|
1859
1879
|
}
|
|
1880
|
+
if (canvas !== null && context2d !== null) {
|
|
1881
|
+
canvas.dataset.dshPetFrames2d = ctx.petId;
|
|
1882
|
+
canvas.draggable = false;
|
|
1883
|
+
canvas.style.width = "100%";
|
|
1884
|
+
canvas.style.height = "100%";
|
|
1885
|
+
canvas.style.objectFit = "contain";
|
|
1886
|
+
canvas.style.pointerEvents = "none";
|
|
1887
|
+
ctx.container.appendChild(canvas);
|
|
1888
|
+
} else {
|
|
1889
|
+
img = document.createElement("img");
|
|
1890
|
+
img.dataset.dshPetFrames2d = ctx.petId;
|
|
1891
|
+
img.alt = "";
|
|
1892
|
+
img.draggable = false;
|
|
1893
|
+
img.style.width = "100%";
|
|
1894
|
+
img.style.height = "100%";
|
|
1895
|
+
img.style.objectFit = "contain";
|
|
1896
|
+
img.style.pointerEvents = "none";
|
|
1897
|
+
ctx.container.appendChild(img);
|
|
1898
|
+
}
|
|
1899
|
+
const decoding = /* @__PURE__ */ new Map();
|
|
1900
|
+
const decodedAll = [];
|
|
1901
|
+
const loadFrame = (url) => {
|
|
1902
|
+
const cached = decoding.get(url);
|
|
1903
|
+
if (cached !== void 0) return cached;
|
|
1904
|
+
const job = (async () => {
|
|
1905
|
+
try {
|
|
1906
|
+
const response = await fetch(url);
|
|
1907
|
+
if (!response.ok) throw new Error("http " + response.status);
|
|
1908
|
+
const bitmap = await createImageBitmap(await response.blob());
|
|
1909
|
+
return {
|
|
1910
|
+
source: bitmap,
|
|
1911
|
+
width: bitmap.width,
|
|
1912
|
+
height: bitmap.height
|
|
1913
|
+
};
|
|
1914
|
+
} catch {
|
|
1915
|
+
return await new Promise((resolve) => {
|
|
1916
|
+
try {
|
|
1917
|
+
const pre = new Image();
|
|
1918
|
+
pre.onload = () => {
|
|
1919
|
+
resolve(pre.naturalWidth > 0 ? {
|
|
1920
|
+
source: pre,
|
|
1921
|
+
width: pre.naturalWidth,
|
|
1922
|
+
height: pre.naturalHeight
|
|
1923
|
+
} : void 0);
|
|
1924
|
+
};
|
|
1925
|
+
pre.onerror = () => resolve(void 0);
|
|
1926
|
+
pre.src = url;
|
|
1927
|
+
} catch {
|
|
1928
|
+
resolve(void 0);
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1931
|
+
}
|
|
1932
|
+
})();
|
|
1933
|
+
decoding.set(url, job);
|
|
1934
|
+
decodedAll.push(job.then(() => void 0, () => void 0));
|
|
1935
|
+
return job;
|
|
1936
|
+
};
|
|
1860
1937
|
let disposed = false;
|
|
1861
1938
|
let timer;
|
|
1862
1939
|
let watchdog;
|
|
@@ -1864,13 +1941,35 @@ window.__ModuleLoader__.load({
|
|
|
1864
1941
|
let frameIndex = 0;
|
|
1865
1942
|
let lastAdvance = Date.now();
|
|
1866
1943
|
let override;
|
|
1944
|
+
let drawToken = 0;
|
|
1945
|
+
let lastDrawnUrl;
|
|
1867
1946
|
const trackForPhase = (phase) => {
|
|
1868
1947
|
const mapped = config.phases[phase];
|
|
1869
1948
|
return mapped !== void 0 && config.tracks[mapped] !== void 0 ? mapped : config.phases.idle;
|
|
1870
1949
|
};
|
|
1950
|
+
/** Canvas path: paints the newest requested frame; stale draws drop out. */
|
|
1951
|
+
const paintCanvas = (url) => {
|
|
1952
|
+
if (context2d === null || canvas === null) return;
|
|
1953
|
+
const myToken = ++drawToken;
|
|
1954
|
+
loadFrame(url).then((frame) => {
|
|
1955
|
+
if (disposed || frame === void 0 || myToken !== drawToken) return;
|
|
1956
|
+
if (lastDrawnUrl === url) return;
|
|
1957
|
+
lastDrawnUrl = url;
|
|
1958
|
+
if (canvas.width !== frame.width || canvas.height !== frame.height) {
|
|
1959
|
+
canvas.width = frame.width;
|
|
1960
|
+
canvas.height = frame.height;
|
|
1961
|
+
} else context2d.clearRect(0, 0, canvas.width, canvas.height);
|
|
1962
|
+
context2d.drawImage(frame.source, 0, 0);
|
|
1963
|
+
}).catch(() => {});
|
|
1964
|
+
};
|
|
1871
1965
|
const show = (trackId, index) => {
|
|
1872
1966
|
const url = config.tracks[trackId]?.frames[index];
|
|
1873
|
-
if (url
|
|
1967
|
+
if (url === void 0) return;
|
|
1968
|
+
if (img !== null) {
|
|
1969
|
+
if (img.getAttribute("src") !== url) img.src = url;
|
|
1970
|
+
return;
|
|
1971
|
+
}
|
|
1972
|
+
paintCanvas(url);
|
|
1874
1973
|
};
|
|
1875
1974
|
const schedule = (ms) => {
|
|
1876
1975
|
if (disposed) return;
|
|
@@ -1922,6 +2021,7 @@ window.__ModuleLoader__.load({
|
|
|
1922
2021
|
const expected = (def.durations[frameIndex] ?? 200) + WATCHDOG_MS;
|
|
1923
2022
|
if (Date.now() - lastAdvance > expected) tick();
|
|
1924
2023
|
}, WATCHDOG_MS);
|
|
2024
|
+
for (const warmTrack of Object.values(config.tracks)) for (const warmUrl of warmTrack.frames) loadFrame(warmUrl);
|
|
1925
2025
|
play(track);
|
|
1926
2026
|
let disposedOnce = false;
|
|
1927
2027
|
const dispose = () => {
|
|
@@ -1931,7 +2031,17 @@ window.__ModuleLoader__.load({
|
|
|
1931
2031
|
unsubscribe();
|
|
1932
2032
|
if (timer !== void 0) clearTimeout(timer);
|
|
1933
2033
|
if (watchdog !== void 0) clearInterval(watchdog);
|
|
1934
|
-
|
|
2034
|
+
Promise.allSettled(decodedAll).then(() => {
|
|
2035
|
+
for (const job of decoding.values()) job.then((frame) => {
|
|
2036
|
+
try {
|
|
2037
|
+
const maybeClose = (frame?.source)?.close;
|
|
2038
|
+
if (typeof maybeClose === "function" && frame !== void 0) maybeClose.call(frame.source);
|
|
2039
|
+
} catch {}
|
|
2040
|
+
}).catch(() => {});
|
|
2041
|
+
decoding.clear();
|
|
2042
|
+
});
|
|
2043
|
+
canvas?.remove();
|
|
2044
|
+
img?.remove();
|
|
1935
2045
|
};
|
|
1936
2046
|
ctx.onCleanup(dispose);
|
|
1937
2047
|
return {
|
|
@@ -3081,6 +3191,15 @@ window.__ModuleLoader__.load({
|
|
|
3081
3191
|
"pet.namePlaceholder": "输入新名字",
|
|
3082
3192
|
"pet.summon": "召唤{name}",
|
|
3083
3193
|
"pet.rank": "亲密度 {rank}",
|
|
3194
|
+
"pet.rank.name.幼鲸": "幼鲸",
|
|
3195
|
+
"pet.rank.name.伙伴": "伙伴",
|
|
3196
|
+
"pet.rank.name.挚友": "挚友",
|
|
3197
|
+
"pet.rank.name.深海羁绊": "深海羁绊",
|
|
3198
|
+
"pet.rank.name.心有灵犀": "心有灵犀",
|
|
3199
|
+
"pet.rank.name.传说羁绊": "传说羁绊",
|
|
3200
|
+
"pet.rank.name.神话羁绊": "神话羁绊",
|
|
3201
|
+
"pet.rank.name.永恒之契": "永恒之契",
|
|
3202
|
+
"pet.rank.name.鲸生共渡": "鲸生共渡",
|
|
3084
3203
|
"pet.points": "{points} 点",
|
|
3085
3204
|
"pet.treats": "小鱼干 ×{n}",
|
|
3086
3205
|
"pet.state.loading": "宠物正在赶来…",
|
|
@@ -3151,6 +3270,15 @@ window.__ModuleLoader__.load({
|
|
|
3151
3270
|
"pet.namePlaceholder": "Enter a new name",
|
|
3152
3271
|
"pet.summon": "Summon {name}",
|
|
3153
3272
|
"pet.rank": "Affinity {rank}",
|
|
3273
|
+
"pet.rank.name.幼鲸": "Baby Whale",
|
|
3274
|
+
"pet.rank.name.伙伴": "Companion",
|
|
3275
|
+
"pet.rank.name.挚友": "Close Friend",
|
|
3276
|
+
"pet.rank.name.深海羁绊": "Deep Sea Bond",
|
|
3277
|
+
"pet.rank.name.心有灵犀": "Kindred Spirit",
|
|
3278
|
+
"pet.rank.name.传说羁绊": "Legendary Bond",
|
|
3279
|
+
"pet.rank.name.神话羁绊": "Mythic Bond",
|
|
3280
|
+
"pet.rank.name.永恒之契": "Eternal Covenant",
|
|
3281
|
+
"pet.rank.name.鲸生共渡": "Lifelong Companion",
|
|
3154
3282
|
"pet.points": "{points} pts",
|
|
3155
3283
|
"pet.treats": "Treats ×{n}",
|
|
3156
3284
|
"pet.state.loading": "The pet is on its way…",
|
|
@@ -3242,7 +3370,7 @@ window.__ModuleLoader__.load({
|
|
|
3242
3370
|
/** The building package's version, when the bundle carries it. */
|
|
3243
3371
|
function bakedVersion() {
|
|
3244
3372
|
try {
|
|
3245
|
-
return "0.3.
|
|
3373
|
+
return "0.3.6";
|
|
3246
3374
|
} catch {
|
|
3247
3375
|
return;
|
|
3248
3376
|
}
|