@linxin666/dsh-pet 0.1.18 → 0.1.19
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 +12 -5
- package/README.zh.md +12 -5
- package/lib/client.js +48 -11
- package/lib/client.js.map +1 -1
- package/lib/index.js +100 -30
- package/lib/invariant.js +2 -2
- package/lib/state-Diiq8vjk.js +394 -0
- package/lib/types/affinity.d.ts +31 -3
- package/lib/types/affinity.d.ts.map +1 -1
- package/lib/types/affinity.js +21 -7
- package/lib/types/client/PetSettingsCard.d.ts +5 -0
- package/lib/types/client/PetSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PetSettingsCard.js +7 -0
- package/lib/types/client/PetSprite.d.ts.map +1 -1
- package/lib/types/client/PetSprite.js +8 -2
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +14 -8
- package/lib/types/client/settings-form.d.ts +8 -0
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/settings-form.js +15 -1
- package/lib/types/event-projection.d.ts.map +1 -1
- package/lib/types/event-projection.js +3 -1
- package/lib/types/index.d.ts +4 -2
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +2 -1
- package/lib/types/ledger.d.ts +16 -1
- package/lib/types/ledger.d.ts.map +1 -1
- package/lib/types/ledger.js +29 -4
- package/lib/types/registry.d.ts +10 -0
- package/lib/types/registry.d.ts.map +1 -1
- package/lib/types/registry.js +3 -0
- package/lib/types/remarks.d.ts +56 -0
- package/lib/types/remarks.d.ts.map +1 -0
- package/lib/types/remarks.js +157 -0
- package/lib/types/service.d.ts +40 -3
- package/lib/types/service.d.ts.map +1 -1
- package/lib/types/service.js +90 -18
- package/lib/types/state.js +5 -5
- package/lib/types/treats.d.ts +3 -0
- package/lib/types/treats.d.ts.map +1 -1
- package/lib/types/treats.js +5 -2
- package/package.json +1 -1
- package/src/affinity.test.ts +19 -0
- package/src/affinity.ts +22 -7
- package/src/client/PetSettingsCard.tsx +8 -0
- package/src/client/PetSprite.test.tsx +33 -0
- package/src/client/PetSprite.tsx +16 -1
- package/src/client/index.ts +14 -8
- package/src/client/pet.module.css +19 -0
- package/src/client/settings-form.ts +15 -1
- package/src/event-projection.ts +3 -1
- package/src/index.ts +12 -1
- package/src/ledger.test.ts +40 -9
- package/src/ledger.ts +33 -4
- package/src/persist.test.ts +1 -1
- package/src/registry.test.ts +27 -0
- package/src/registry.ts +12 -0
- package/src/remarks.test.ts +89 -0
- package/src/remarks.ts +177 -0
- package/src/service.ts +116 -18
- package/src/state.test.ts +9 -0
- package/src/state.ts +5 -5
- package/src/treats.test.ts +13 -11
- package/src/treats.ts +5 -2
- package/lib/state-CFyJv0sQ.js +0 -213
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as AFFINITY_MAX, c as applyInteraction, d as emptyAffinity, f as rankOf, i as rowOf, l as applyTurnReward, n as animationForPhase, o as AFFINITY_RANKS, r as defaultPetStateConfig, s as affinityViewOf, t as PetStateMachine, u as defaultAffinityConfig } from "./state-
|
|
1
|
+
import { _ as RemarkPicker, a as AFFINITY_MAX, c as applyInteraction, d as emptyAffinity, f as rankOf, g as REMARK_LINE_MAX, h as REMARK_LINES_MAX, i as rowOf, l as applyTurnReward, m as REMARK_KINDS, n as animationForPhase, o as AFFINITY_RANKS, p as BUILTIN_REMARKS, r as defaultPetStateConfig, s as affinityViewOf, t as PetStateMachine, u as defaultAffinityConfig, v as builtinRemark, y as normalizePetRemarks } from "./state-Diiq8vjk.js";
|
|
2
2
|
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
3
|
import z from "schemastery";
|
|
4
4
|
import { Service } from "@deepseek-ai/cordis";
|
|
@@ -117,10 +117,7 @@ function projectOfficialEvent(event, runtime) {
|
|
|
117
117
|
phase: "waiting",
|
|
118
118
|
line: "等待继续"
|
|
119
119
|
} };
|
|
120
|
-
case "aborted": return { input: {
|
|
121
|
-
phase: "idle",
|
|
122
|
-
line: "已停止"
|
|
123
|
-
} };
|
|
120
|
+
case "aborted": return { input: { phase: "idle" } };
|
|
124
121
|
default: return { input: { phase: "idle" } };
|
|
125
122
|
}
|
|
126
123
|
default: return;
|
|
@@ -129,8 +126,8 @@ function projectOfficialEvent(event, runtime) {
|
|
|
129
126
|
//#endregion
|
|
130
127
|
//#region src/treats.ts
|
|
131
128
|
const defaultTreatConfig = {
|
|
132
|
-
turnsPerTreat:
|
|
133
|
-
timeTreatMs:
|
|
129
|
+
turnsPerTreat: 30,
|
|
130
|
+
timeTreatMs: 300 * 6e4,
|
|
134
131
|
maxTreats: 20
|
|
135
132
|
};
|
|
136
133
|
function emptyTreatLedger() {
|
|
@@ -217,6 +214,8 @@ function consumeTreat(ledger) {
|
|
|
217
214
|
var PetLedger = class {
|
|
218
215
|
affinityConfig;
|
|
219
216
|
treatConfig;
|
|
217
|
+
/** Round-robin reaction picker; rebuilt when the selected pet changes. */
|
|
218
|
+
picker;
|
|
220
219
|
current;
|
|
221
220
|
/** Completed turns already rewarded, per session (turn numbers are per-session). */
|
|
222
221
|
rewardedTurns = /* @__PURE__ */ new Map();
|
|
@@ -231,6 +230,7 @@ var PetLedger = class {
|
|
|
231
230
|
...defaultTreatConfig,
|
|
232
231
|
...config.treats ?? {}
|
|
233
232
|
};
|
|
233
|
+
this.picker = new RemarkPicker(config.remarks);
|
|
234
234
|
this.current = persist;
|
|
235
235
|
}
|
|
236
236
|
/** Affinity cooldown/rank tuning (read-only). */
|
|
@@ -251,6 +251,13 @@ var PetLedger = class {
|
|
|
251
251
|
this.dirty = false;
|
|
252
252
|
return was;
|
|
253
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Drop a session's rewarded-turn bookkeeping once that session is disposed,
|
|
256
|
+
* so the per-session map does not grow without bound.
|
|
257
|
+
*/
|
|
258
|
+
forgetSession(sessionId) {
|
|
259
|
+
this.rewardedTurns.delete(sessionId);
|
|
260
|
+
}
|
|
254
261
|
/** Replace the display block (clamping stays a caller concern). */
|
|
255
262
|
setDisplay(display) {
|
|
256
263
|
this.current = {
|
|
@@ -280,9 +287,16 @@ var PetLedger = class {
|
|
|
280
287
|
this.dirty = true;
|
|
281
288
|
}
|
|
282
289
|
/**
|
|
290
|
+
* Swap the reaction pools to another pet's custom remarks (called on pet
|
|
291
|
+
* selection). Slots the pet does not declare fall back to built-ins.
|
|
292
|
+
*/
|
|
293
|
+
setRemarks(remarks) {
|
|
294
|
+
this.picker = new RemarkPicker(remarks);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
283
297
|
* Settle the treat economy (work + time output since the last settlement).
|
|
284
298
|
* A zero-gain first settlement still starts the time clock (anchor write),
|
|
285
|
-
* which is how the
|
|
299
|
+
* which is how the time output can ever accrue. Returns true when
|
|
286
300
|
* the in-memory ledger changed and should be persisted.
|
|
287
301
|
*/
|
|
288
302
|
settleTreats(nowMs) {
|
|
@@ -332,14 +346,14 @@ var PetLedger = class {
|
|
|
332
346
|
if (kind === "feed") this.settleTreats(nowMs);
|
|
333
347
|
const outcome = applyInteraction(this.current.affinity, kind, nowMs, this.affinityConfig);
|
|
334
348
|
if (kind === "feed" && !outcome.accepted) return {
|
|
335
|
-
reaction:
|
|
349
|
+
reaction: this.picker.pick("feedCooldown"),
|
|
336
350
|
delta: 0,
|
|
337
351
|
affinity: this.affinityView(nowMs)
|
|
338
352
|
};
|
|
339
353
|
if (kind === "feed") {
|
|
340
354
|
const consume = consumeTreat(this.current.treats);
|
|
341
355
|
if (!consume.ok) return {
|
|
342
|
-
reaction: "
|
|
356
|
+
reaction: this.picker.pick("noTreats"),
|
|
343
357
|
delta: 0,
|
|
344
358
|
affinity: this.affinityView(nowMs)
|
|
345
359
|
};
|
|
@@ -357,7 +371,7 @@ var PetLedger = class {
|
|
|
357
371
|
this.dirty = true;
|
|
358
372
|
}
|
|
359
373
|
return {
|
|
360
|
-
reaction: outcome.
|
|
374
|
+
reaction: this.picker.pick(outcome.accepted ? kind : "petCooldown"),
|
|
361
375
|
delta: outcome.delta,
|
|
362
376
|
affinity: this.affinityView(nowMs)
|
|
363
377
|
};
|
|
@@ -464,7 +478,7 @@ function loadPetPersist(dir = petHomeDir()) {
|
|
|
464
478
|
const base = emptyPersist();
|
|
465
479
|
const rawAffinity = parsed.affinity ?? {};
|
|
466
480
|
const affinity = {
|
|
467
|
-
points: clamp(finiteNum(rawAffinity.points, 0),
|
|
481
|
+
points: clamp(finiteNum(rawAffinity.points, 0), AFFINITY_MAX),
|
|
468
482
|
lastPetAt: clamp(finiteNum(rawAffinity.lastPetAt, 0), Number.MAX_SAFE_INTEGER),
|
|
469
483
|
lastFeedAt: clamp(finiteNum(rawAffinity.lastFeedAt, 0), Number.MAX_SAFE_INTEGER),
|
|
470
484
|
pets: clamp(finiteNum(rawAffinity.pets, 0), Number.MAX_SAFE_INTEGER),
|
|
@@ -728,6 +742,7 @@ function resolvePetManifest(raw, dir, options = {}) {
|
|
|
728
742
|
const rows = DEFAULT_FRAME_COUNTS.map((fallback, index) => {
|
|
729
743
|
return finiteInt(Array.isArray(source.frames) ? source.frames[index] : void 0, fallback, columns);
|
|
730
744
|
});
|
|
745
|
+
const remarks = normalizePetRemarks(source.remarks, (message) => warn("manifest " + id + ": " + message));
|
|
731
746
|
const trackOverrides = typeof source.tracks === "object" && source.tracks !== null ? source.tracks : {};
|
|
732
747
|
const tracks = {};
|
|
733
748
|
for (const [row, animation] of PET_ROW_ORDER.entries()) {
|
|
@@ -758,7 +773,8 @@ function resolvePetManifest(raw, dir, options = {}) {
|
|
|
758
773
|
atlasUrl: assetUrl(assetPrefix, id, spritesheet),
|
|
759
774
|
manifestUrl: assetUrl(assetPrefix, id, "pet.json"),
|
|
760
775
|
dir,
|
|
761
|
-
spritesheetPath: spritesheetPath.join("/")
|
|
776
|
+
spritesheetPath: spritesheetPath.join("/"),
|
|
777
|
+
...remarks === void 0 ? {} : { remarks }
|
|
762
778
|
};
|
|
763
779
|
}
|
|
764
780
|
/** Scan one directory of pet folders; entries come back in name order. */
|
|
@@ -852,6 +868,8 @@ function petEntryView(entry) {
|
|
|
852
868
|
manifestUrl: entry.manifestUrl
|
|
853
869
|
};
|
|
854
870
|
}
|
|
871
|
+
/** Hard cap on simultaneously displayed session bubbles (most recent first). */
|
|
872
|
+
const MAX_SESSION_BUBBLES = 12;
|
|
855
873
|
/**
|
|
856
874
|
* Cordis service exposing the pet RPC domain. Lazy: nothing is scanned or
|
|
857
875
|
* written until an economic event or interaction arrives; event listeners
|
|
@@ -861,6 +879,7 @@ function petEntryView(entry) {
|
|
|
861
879
|
var PetService = class extends Service {
|
|
862
880
|
static inject = [];
|
|
863
881
|
machine;
|
|
882
|
+
stateConfig;
|
|
864
883
|
ledger;
|
|
865
884
|
registry;
|
|
866
885
|
persistDir;
|
|
@@ -868,7 +887,12 @@ var PetService = class extends Service {
|
|
|
868
887
|
disposeActivity;
|
|
869
888
|
/** Session whose most recent meaningful event currently drives the global pet. */
|
|
870
889
|
displaySession;
|
|
871
|
-
|
|
890
|
+
/**
|
|
891
|
+
* Per-session activity, most recent last (Map insertion order). Bounded by
|
|
892
|
+
* MAX_SESSION_BUBBLES so a burst of sessions cannot grow it without bound;
|
|
893
|
+
* disposed sessions are removed by the 'session/disposed' listener.
|
|
894
|
+
*/
|
|
895
|
+
sessionActivity = /* @__PURE__ */ new Map();
|
|
872
896
|
constructor(ctx, config = {}) {
|
|
873
897
|
super(ctx, "pet");
|
|
874
898
|
this.persistDir = config.persistDir ?? petHomeDir();
|
|
@@ -882,15 +906,18 @@ var PetService = class extends Service {
|
|
|
882
906
|
...persist,
|
|
883
907
|
petId: this.registry.defaultEntry().id
|
|
884
908
|
};
|
|
909
|
+
const selected = this.registry.byId(persist.petId) ?? this.registry.defaultEntry();
|
|
885
910
|
const ledgerConfig = {
|
|
886
911
|
affinity: config.affinity,
|
|
887
|
-
treats: config.treats
|
|
912
|
+
treats: config.treats,
|
|
913
|
+
remarks: selected.remarks
|
|
888
914
|
};
|
|
889
915
|
this.ledger = new PetLedger(persist, ledgerConfig);
|
|
890
|
-
this.
|
|
916
|
+
this.stateConfig = {
|
|
891
917
|
...defaultPetStateConfig,
|
|
892
918
|
...config.state ?? {}
|
|
893
|
-
}
|
|
919
|
+
};
|
|
920
|
+
this.machine = new PetStateMachine(this.stateConfig);
|
|
894
921
|
this.enabled = config.enabled ?? true;
|
|
895
922
|
this.syncActivity();
|
|
896
923
|
}
|
|
@@ -936,6 +963,7 @@ var PetService = class extends Service {
|
|
|
936
963
|
error: "unknown-pet"
|
|
937
964
|
};
|
|
938
965
|
this.ledger.setPetId(entry.id);
|
|
966
|
+
this.ledger.setRemarks(entry.remarks);
|
|
939
967
|
this.flush();
|
|
940
968
|
this.syncSettingsFromPet();
|
|
941
969
|
return {
|
|
@@ -956,7 +984,7 @@ var PetService = class extends Service {
|
|
|
956
984
|
if (!this.enabled) return;
|
|
957
985
|
this.disposeActivity = (() => {
|
|
958
986
|
const disposers = [this.ctx.on("session/event", (session, event) => {
|
|
959
|
-
const runtime = this.
|
|
987
|
+
const runtime = this.activityOf(session).runtime;
|
|
960
988
|
if (event.type === "activity/status") {
|
|
961
989
|
const payload = event.data ?? {};
|
|
962
990
|
if (typeof payload.phase !== "string" || !isActivityPhase(payload.phase)) return;
|
|
@@ -974,26 +1002,52 @@ var PetService = class extends Service {
|
|
|
974
1002
|
this.applyActivity(session, transition.input);
|
|
975
1003
|
if (transition.completedTurn !== void 0) this.rewardTurn(String(session.id), transition.completedTurn);
|
|
976
1004
|
}), this.ctx.on("session/disposed", (session) => {
|
|
1005
|
+
this.ledger.forgetSession(String(session.id));
|
|
1006
|
+
this.sessionActivity.delete(session);
|
|
977
1007
|
if (session !== this.displaySession) return;
|
|
978
1008
|
this.displaySession = void 0;
|
|
979
|
-
this.
|
|
1009
|
+
const remaining = [...this.sessionActivity.entries()].at(-1);
|
|
1010
|
+
if (remaining !== void 0) {
|
|
1011
|
+
const [nextSession, activity] = remaining;
|
|
1012
|
+
this.displaySession = nextSession;
|
|
1013
|
+
if (activity.lastInput !== void 0) this.machine.onActivityStatus(activity.lastInput);
|
|
1014
|
+
this.machine.onSessionActive();
|
|
1015
|
+
} else this.machine.onSessionDisposed();
|
|
980
1016
|
})];
|
|
981
1017
|
return () => {
|
|
982
1018
|
for (const dispose of disposers) dispose();
|
|
983
1019
|
};
|
|
984
1020
|
})();
|
|
985
1021
|
}
|
|
986
|
-
/** Return the
|
|
987
|
-
|
|
988
|
-
let
|
|
989
|
-
if (
|
|
990
|
-
|
|
991
|
-
|
|
1022
|
+
/** Return the per-session activity record, creating it on first sight. */
|
|
1023
|
+
activityOf(session) {
|
|
1024
|
+
let activity = this.sessionActivity.get(session);
|
|
1025
|
+
if (activity === void 0) {
|
|
1026
|
+
activity = {
|
|
1027
|
+
runtime: emptyProjectionRuntime(),
|
|
1028
|
+
machine: new PetStateMachine(this.stateConfig)
|
|
1029
|
+
};
|
|
1030
|
+
this.sessionActivity.set(session, activity);
|
|
992
1031
|
}
|
|
993
|
-
return
|
|
1032
|
+
return activity;
|
|
994
1033
|
}
|
|
995
|
-
/**
|
|
1034
|
+
/**
|
|
1035
|
+
* Commit one activity: the session's own machine renders its bubble, and
|
|
1036
|
+
* the session becomes the host-global display session (most recent
|
|
1037
|
+
* meaningful event wins the sprite animation).
|
|
1038
|
+
*/
|
|
996
1039
|
applyActivity(session, input) {
|
|
1040
|
+
const activity = this.activityOf(session);
|
|
1041
|
+
activity.lastInput = input;
|
|
1042
|
+
activity.machine.onActivityStatus(input);
|
|
1043
|
+
activity.machine.onSessionActive();
|
|
1044
|
+
this.sessionActivity.delete(session);
|
|
1045
|
+
this.sessionActivity.set(session, activity);
|
|
1046
|
+
while (this.sessionActivity.size > 12) {
|
|
1047
|
+
const oldest = this.sessionActivity.keys().next().value;
|
|
1048
|
+
if (oldest === void 0) break;
|
|
1049
|
+
this.sessionActivity.delete(oldest);
|
|
1050
|
+
}
|
|
997
1051
|
this.displaySession = session;
|
|
998
1052
|
this.machine.onActivityStatus(input);
|
|
999
1053
|
this.machine.onSessionActive();
|
|
@@ -1060,8 +1114,11 @@ var PetService = class extends Service {
|
|
|
1060
1114
|
* @param section - the resolved settings section.
|
|
1061
1115
|
*/
|
|
1062
1116
|
applySettingsSection(section) {
|
|
1063
|
-
|
|
1064
|
-
|
|
1117
|
+
const selected = typeof section.petId === "string" ? this.registry.byId(section.petId) : void 0;
|
|
1118
|
+
if (selected !== void 0) {
|
|
1119
|
+
this.ledger.setPetId(selected.id);
|
|
1120
|
+
this.ledger.setRemarks(selected.remarks);
|
|
1121
|
+
} else if (section.petId !== void 0) this.syncSettingsFromPet();
|
|
1065
1122
|
const next = { ...this.ledger.snapshot.display };
|
|
1066
1123
|
next.visible = section.visible && (section.enabled ?? true);
|
|
1067
1124
|
next.size = Math.round(Math.min(512, Math.max(32, section.size)));
|
|
@@ -1094,11 +1151,24 @@ var PetService = class extends Service {
|
|
|
1094
1151
|
view() {
|
|
1095
1152
|
const snapshot = this.machine.render();
|
|
1096
1153
|
const entry = this.activeEntry();
|
|
1154
|
+
const sessions = [];
|
|
1155
|
+
for (const [session, activity] of [...this.sessionActivity.entries()].reverse()) {
|
|
1156
|
+
if (sessions.length >= 12) break;
|
|
1157
|
+
const perSession = activity.machine.render();
|
|
1158
|
+
if (perSession.bubble === void 0) continue;
|
|
1159
|
+
sessions.push({
|
|
1160
|
+
sessionId: String(session.id),
|
|
1161
|
+
animation: perSession.animation,
|
|
1162
|
+
bubble: perSession.bubble,
|
|
1163
|
+
phase: perSession.phase
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1097
1166
|
return {
|
|
1098
1167
|
animation: snapshot.animation,
|
|
1099
1168
|
...snapshot.bubble === void 0 ? {} : { bubble: snapshot.bubble },
|
|
1100
1169
|
phase: snapshot.phase,
|
|
1101
1170
|
sessionActive: snapshot.sessionActive,
|
|
1171
|
+
sessions,
|
|
1102
1172
|
affinity: this.ledger.affinityView(Date.now()),
|
|
1103
1173
|
display: { ...this.ledger.snapshot.display },
|
|
1104
1174
|
pet: {
|
|
@@ -1457,4 +1527,4 @@ function apply(ctx, config = {}) {
|
|
|
1457
1527
|
syncRoutes();
|
|
1458
1528
|
}
|
|
1459
1529
|
//#endregion
|
|
1460
|
-
export { AFFINITY_MAX, AFFINITY_RANKS, DEFAULT_FRAME_COUNTS, DEFAULT_PET_CELL, DEFAULT_PET_COLUMNS, DEFAULT_PET_ID, DEFAULT_PET_NAME, DEFAULT_PET_ROW_COUNT, DEFAULT_TRACK_PATTERNS, PET_API_PREFIX, PET_ASSET_PREFIX, PET_NAME_MAX_LENGTH, PET_ROW_ORDER, PetService, PetStateMachine, animationForPhase, apply, applyInteraction, applyTurnReward, codexPetsDir, consumeTreat, defaultDisplayConfig, defaultTreatConfig, emptyAffinity, emptyPersist, emptyTreatLedger, inject, loadPetPersist, loadPetRegistry, makePetRoutes, makePetSettingsSchema, name, petEntryView, petHomeDir, petPackageRoot, rankOf, resolvePetManifest, rowOf, savePetPersist, settleTreatGrants };
|
|
1530
|
+
export { AFFINITY_MAX, AFFINITY_RANKS, BUILTIN_REMARKS, DEFAULT_FRAME_COUNTS, DEFAULT_PET_CELL, DEFAULT_PET_COLUMNS, DEFAULT_PET_ID, DEFAULT_PET_NAME, DEFAULT_PET_ROW_COUNT, DEFAULT_TRACK_PATTERNS, MAX_SESSION_BUBBLES, PET_API_PREFIX, PET_ASSET_PREFIX, PET_NAME_MAX_LENGTH, PET_ROW_ORDER, PetService, PetStateMachine, REMARK_KINDS, REMARK_LINES_MAX, REMARK_LINE_MAX, RemarkPicker, animationForPhase, apply, applyInteraction, applyTurnReward, builtinRemark, codexPetsDir, consumeTreat, defaultDisplayConfig, defaultTreatConfig, emptyAffinity, emptyPersist, emptyTreatLedger, inject, loadPetPersist, loadPetRegistry, makePetRoutes, makePetSettingsSchema, name, normalizePetRemarks, petEntryView, petHomeDir, petPackageRoot, rankOf, resolvePetManifest, rowOf, savePetPersist, settleTreatGrants };
|
package/lib/invariant.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as animationForPhase, o as AFFINITY_RANKS, u as defaultAffinityConfig } from "./state-
|
|
1
|
+
import { a as AFFINITY_MAX, n as animationForPhase, o as AFFINITY_RANKS, u as defaultAffinityConfig } from "./state-Diiq8vjk.js";
|
|
2
2
|
//#region src/invariant.ts
|
|
3
3
|
/**
|
|
4
4
|
* Package invariants — cheap structural checks run at import time on the
|
|
@@ -11,7 +11,7 @@ function invariant(condition, message) {
|
|
|
11
11
|
}
|
|
12
12
|
/** Run every package invariant once; throws on the first violation. */
|
|
13
13
|
function runPetInvariants() {
|
|
14
|
-
invariant(
|
|
14
|
+
invariant(AFFINITY_MAX > 0, "AFFINITY_MAX must be positive");
|
|
15
15
|
invariant(AFFINITY_RANKS.length > 0 && AFFINITY_RANKS[0].min === 0, "AFFINITY_RANKS must start at 0");
|
|
16
16
|
invariant(defaultAffinityConfig.turnReward > 0, "turnReward must be positive");
|
|
17
17
|
invariant(defaultAffinityConfig.feedCooldownMs > defaultAffinityConfig.petCooldownMs, "feed cooldown must exceed pet cooldown");
|