@storylet-studio/play-helpers 0.4.1 → 0.5.0

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/dist/index.cjs CHANGED
@@ -138,10 +138,14 @@ var PropertyBag = class _PropertyBag {
138
138
  }
139
139
  /** Write a property. Engine writes (the default) notify subscribers;
140
140
  * pass `silent: true` for a host write, which reaches only the audit
141
- * hook. Throws on a read-only property. Returns the change. */
141
+ * hook. Throws on a read-only property unless the caller says it is the
142
+ * HOST (`host: true`), for whom `writable: false` was never a rule - it is
143
+ * the story's promise, not the game's. `silent` and `host` are separate on
144
+ * purpose: one is about who hears the write, the other about who may make
145
+ * it. Returns the change. */
142
146
  set(name, value, opts) {
143
147
  const n = this.norm(name);
144
- if (this.decls.get(n)?.writable === false) throw new Error(`'${name}' is read-only`);
148
+ if (!opts?.host && this.decls.get(n)?.writable === false) throw new Error(`'${name}' is read-only`);
145
149
  const change = {
146
150
  name: n,
147
151
  prev: this.values[n],
@@ -243,19 +247,13 @@ function defaultFor(d) {
243
247
 
244
248
  // src/logger.ts
245
249
  function snapshotState(engine, flow) {
246
- const env = engine.saveGame();
247
- const flowSave = env.flows[flow.id];
248
250
  const out = {};
249
- const bag = (prefix, values) => {
250
- for (const [name, value] of Object.entries(values ?? {})) out[`${prefix}.${name}`] = value;
251
- };
252
- bag("story", env.shared.props.story);
253
- bag("story", flowSave?.props.story);
254
- for (const kind of ["box", "deck", "hand", "value"]) {
255
- for (const [id, values] of Object.entries(env.shared.props[kind])) bag(`${kind}.${id}`, values);
256
- for (const [id, values] of Object.entries(flowSave?.props[kind] ?? {})) bag(`${kind}.${id}`, values);
251
+ for (const { bag } of [...engine.listBags(), ...flow.listBags()]) {
252
+ for (const row of bag.rows()) {
253
+ if (row.value !== void 0) out[row.path] = row.value;
254
+ }
257
255
  }
258
- Object.assign(out, extraState(env.flows[flow.id]));
256
+ Object.assign(out, extraState(engine.saveGame().flows[flow.id]));
259
257
  return out;
260
258
  }
261
259
  function extraState(saved) {
@@ -709,7 +707,8 @@ var import_runtime = require("@storylet-studio/runtime");
709
707
  var showVal2 = (v) => v === void 0 ? "<unset>" : JSON.stringify(v);
710
708
  function formatPropertySummary(p) {
711
709
  const options = p.values !== void 0 && p.values.length > 0 ? ` [${p.values.join(", ")}]` : "";
712
- return `${p.name}: ${p.type} = ${showVal2(p.default)}${options}`;
710
+ const durable = p.durable === true ? " (durable)" : "";
711
+ return `${p.name}: ${p.type} = ${showVal2(p.default)}${options}${durable}`;
713
712
  }
714
713
  function formatScopeLabel(scope) {
715
714
  if (scope.scope === "world" || scope.scope === "story") return scope.scope;
@@ -765,7 +764,8 @@ function createBundleInspector(bundle, opts = {}) {
765
764
  }
766
765
  for (const hand of description.hands) {
767
766
  const template = hand.template !== void 0 ? `, template ${hand.template}` : "";
768
- line(handsBody, `${hand.gameId}: box ${hand.box}, slots ${hand.slots}${template}` + (hand.title !== void 0 ? ` - ${hand.title}` : ""));
767
+ const moves = hand.movable === void 0 ? "" : `, moves ${hand.movable.map((m) => `${m.group} from ${m.from}`).join(" and ")}`;
768
+ line(handsBody, `${hand.gameId}: box ${hand.box}, slots ${hand.slots}${template}${moves}` + (hand.title !== void 0 ? ` - ${hand.title}` : ""));
769
769
  }
770
770
  const tagsBody = fold(el, "Tags by box (peek criteria)", open);
771
771
  tagsBody.className = "sl-tags";
@@ -794,7 +794,7 @@ function createBundleInspector(bundle, opts = {}) {
794
794
  mapsBody.className = "sl-maps";
795
795
  line(mapsBody, "Geometry the build was asked to carry. The engine ignores it.", "sl-line sl-note");
796
796
  for (const map of description.maps) {
797
- line(mapsBody, `${map.box} - ${map.group}: zones ${map.zones}, pictures ${map.backgrounds}`);
797
+ line(mapsBody, `${map.box} - ${map.group}: zones ${map.zones}, pictures ${map.backgrounds}, sites ${map.sites}`);
798
798
  }
799
799
  }
800
800
  const countsBody = fold(el, "Counts", open);
@@ -802,7 +802,7 @@ function createBundleInspector(bundle, opts = {}) {
802
802
  line(countsBody, `boxes ${totals.boxes} - decks ${totals.decks} - cards ${totals.cards}`);
803
803
  line(countsBody, `hands ${totals.hands} - templates ${totals.templates} - tag groups ${totals.tagGroups}`);
804
804
  for (const box of description.boxes) {
805
- line(countsBody, `${box.gameId}: decks ${box.counts.decks}, cards ${box.counts.cards}, hands ${box.counts.hands}, templates ${box.counts.templates}, tag groups ${box.counts.tagGroups}, ranking.specificity ${box.ranking.specificity}`);
805
+ line(countsBody, `${box.gameId}: decks ${box.counts.decks}, cards ${box.counts.cards}, hands ${box.counts.hands}, templates ${box.counts.templates}, tag groups ${box.counts.tagGroups}, ranking.specificity ${box.ranking.specificity}` + (box.turn !== void 0 ? `, turn = ${box.turn.seconds}s` : "") + (box.durableCards !== void 0 ? `, durable cards ${box.durableCards}` : ""));
806
806
  }
807
807
  (opts.container ?? document.body).append(el);
808
808
  return {
@@ -1011,7 +1011,7 @@ function createWorldContainer(bundle) {
1011
1011
  resolver: {
1012
1012
  get: (n) => bag.get(n),
1013
1013
  set: (n, v) => {
1014
- bag.set(n, v);
1014
+ bag.set(n, v, { host: true });
1015
1015
  }
1016
1016
  },
1017
1017
  bag,