@storylet-studio/play-helpers 0.7.0 → 0.8.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.d.cts CHANGED
@@ -210,18 +210,17 @@ type LiveBundleResult =
210
210
  error: string;
211
211
  };
212
212
  /**
213
- * Apply a bundle the editor pushed over the Live Link: `new Engine(parsed,
214
- * opts)` then `loadGame(engine.saveGame())`, returning the new engine. Never
215
- * throws; a failure (unparseable JSON, a bundle the runtime rejects, a
216
- * different project) comes back as `{ ok: false, error }` and the old engine
217
- * is untouched.
213
+ * Apply a bundle the editor pushed over the Live Link through the engine's own
214
+ * `hotSwap`, returning the replacement. Never throws; a failure (unparseable
215
+ * JSON, a bundle the runtime rejects, a different project) comes back as
216
+ * `{ ok: false, error }` and the old engine is left as it was.
218
217
  *
219
- * `opts` are the options the old engine was created with. An engine does
220
- * not expose its seed, and it does not matter here: the save envelope carries
221
- * each flow's PRNG state, so `loadGame` resumes the draw sequences exactly
222
- * where they were and `seed` only shapes fresh flows. `log` does matter (the
223
- * retained log is per flow), and so does `world` (the host's binding does not
224
- * ride the envelope), so pass them if you had them.
218
+ * Works whether the engine made its own registry or was given the game's: on
219
+ * the game's registry the old engine hands its keys to the replacement, which a
220
+ * plain save and load into a second engine cannot do (the two would clash).
221
+ *
222
+ * The engine remembers the options it was built with (seed, log, world,
223
+ * registry), so `opts` is only for overriding one of them for the replacement.
225
224
  */
226
225
  declare function applyLiveBundle(engine: Engine, bundleJson: string, opts?: EngineOptions): LiveBundleResult;
227
226
 
package/dist/index.d.ts CHANGED
@@ -210,18 +210,17 @@ type LiveBundleResult =
210
210
  error: string;
211
211
  };
212
212
  /**
213
- * Apply a bundle the editor pushed over the Live Link: `new Engine(parsed,
214
- * opts)` then `loadGame(engine.saveGame())`, returning the new engine. Never
215
- * throws; a failure (unparseable JSON, a bundle the runtime rejects, a
216
- * different project) comes back as `{ ok: false, error }` and the old engine
217
- * is untouched.
213
+ * Apply a bundle the editor pushed over the Live Link through the engine's own
214
+ * `hotSwap`, returning the replacement. Never throws; a failure (unparseable
215
+ * JSON, a bundle the runtime rejects, a different project) comes back as
216
+ * `{ ok: false, error }` and the old engine is left as it was.
218
217
  *
219
- * `opts` are the options the old engine was created with. An engine does
220
- * not expose its seed, and it does not matter here: the save envelope carries
221
- * each flow's PRNG state, so `loadGame` resumes the draw sequences exactly
222
- * where they were and `seed` only shapes fresh flows. `log` does matter (the
223
- * retained log is per flow), and so does `world` (the host's binding does not
224
- * ride the envelope), so pass them if you had them.
218
+ * Works whether the engine made its own registry or was given the game's: on
219
+ * the game's registry the old engine hands its keys to the replacement, which a
220
+ * plain save and load into a second engine cannot do (the two would clash).
221
+ *
222
+ * The engine remembers the options it was built with (seed, log, world,
223
+ * registry), so `opts` is only for overriding one of them for the replacement.
225
224
  */
226
225
  declare function applyLiveBundle(engine: Engine, bundleJson: string, opts?: EngineOptions): LiveBundleResult;
227
226
 
package/dist/index.js CHANGED
@@ -93,6 +93,13 @@ var PropertyBag = class _PropertyBag {
93
93
  get(name) {
94
94
  return this.values[this.norm(name)];
95
95
  }
96
+ /** A name as this bag keys it: its normalisation policy applied. The registry
97
+ * uses it to key quality ladders and the validation schema the bag's own way,
98
+ * so a case-significant (identity) bag is not quietly folded to lower case
99
+ * one layer up. */
100
+ normalise(name) {
101
+ return this.norm(name);
102
+ }
96
103
  /** Write a property. Engine writes (the default) notify subscribers;
97
104
  * pass `silent: true` for a host write, which reaches only the audit
98
105
  * hook. Throws on a read-only property unless the caller says it is the
@@ -234,7 +241,8 @@ function createStateLogger2(engine, flow, opts = {}) {
234
241
  }
235
242
 
236
243
  // ../model/src/index.ts
237
- var SAVE_SCHEMA = "storylets/save@1";
244
+ var SAVE_SCHEMA = "storylets/save@2";
245
+ var SAVE_SCHEMA_V1 = "storylets/save@1";
238
246
  var SAVEFILE_SCHEMA = "storylets/savefile@1";
239
247
 
240
248
  // src/save.ts
@@ -249,7 +257,7 @@ function saveState(engine, world) {
249
257
  };
250
258
  }
251
259
  function loadState(engine, file) {
252
- if (!file || typeof file !== "object" || file.schema !== SAVEFILE_SCHEMA || file.engine?.schema !== SAVE_SCHEMA) {
260
+ if (!file || typeof file !== "object" || file.schema !== SAVEFILE_SCHEMA || file.engine?.schema !== SAVE_SCHEMA && file.engine?.schema !== SAVE_SCHEMA_V1) {
253
261
  throw new Error(`not a storylets save (expected schema "${SAVEFILE_SCHEMA}")`);
254
262
  }
255
263
  engine.loadGame(file.engine);
@@ -945,7 +953,7 @@ function createLiveLink(opts) {
945
953
  }
946
954
 
947
955
  // src/refresh.ts
948
- import { Engine } from "@storylet-studio/runtime";
956
+ import "@storylet-studio/runtime";
949
957
  function applyLiveBundle(engine, bundleJson, opts = {}) {
950
958
  let bundle;
951
959
  try {
@@ -954,8 +962,7 @@ function applyLiveBundle(engine, bundleJson, opts = {}) {
954
962
  return { ok: false, error: "pushed bundle is not valid JSON" };
955
963
  }
956
964
  try {
957
- const next = new Engine(bundle, opts);
958
- next.loadGame(engine.saveGame());
965
+ const { engine: next } = engine.hotSwap(bundle, opts);
959
966
  return { ok: true, engine: next, bundle };
960
967
  } catch (e) {
961
968
  return { ok: false, error: e instanceof Error ? e.message : String(e) };