@patterkit/play-helpers 0.3.3 → 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
@@ -28,7 +28,7 @@ __export(index_exports, {
28
28
  createPropertyInspector: () => createPropertyInspector,
29
29
  createStateLogger: () => createStateLogger,
30
30
  deserializeState: () => deserializeState,
31
- diffState: () => diffState,
31
+ diffState: () => import_scoperegistry.diffState,
32
32
  getProperty: () => getProperty,
33
33
  loadState: () => loadState,
34
34
  saveState: () => saveState,
@@ -69,7 +69,7 @@ function setProperties(engine, values) {
69
69
  }
70
70
 
71
71
  // src/logger.ts
72
- var eq = (a, b) => JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
72
+ var import_scoperegistry = require("@wildwinter/scoperegistry");
73
73
  function snapshotState(engine) {
74
74
  const save = engine.saveGame();
75
75
  const out = {};
@@ -85,16 +85,6 @@ function snapshotState(engine) {
85
85
  }
86
86
  return out;
87
87
  }
88
- function diffState(prev, next) {
89
- const changes = [];
90
- const keys = [.../* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)])].sort();
91
- for (const path of keys) {
92
- const from = prev[path], to = next[path];
93
- if (!eq(from, to)) changes.push({ path, ...from !== void 0 ? { from } : {}, ...to !== void 0 ? { to } : {} });
94
- }
95
- return changes;
96
- }
97
- var fmt = (v) => v === void 0 ? "<unset>" : JSON.stringify(v);
98
88
  function describeStep(step) {
99
89
  switch (step.type) {
100
90
  case "line":
@@ -110,21 +100,29 @@ function describeStep(step) {
110
100
  }
111
101
  }
112
102
  var gd = (data) => data ? ` gameData=${JSON.stringify(data)}` : "";
103
+ function visitState(engine) {
104
+ const save = engine.saveGame();
105
+ const out = {};
106
+ for (const [id, n] of Object.entries(save.sharedVisits)) out[`visit:${id}`] = n;
107
+ for (const [fid, snap] of Object.entries(save.flows)) {
108
+ for (const [id, n] of Object.entries(snap.visits)) out[`${fid}/visit:${id}`] = n;
109
+ }
110
+ return out;
111
+ }
113
112
  function createStateLogger(engine, opts = {}) {
114
- const sink = opts.sink ?? ((line) => console.log(line));
115
113
  const tag = opts.label ? `[${opts.label}] ` : "";
116
- let baseline = snapshotState(engine);
114
+ const kernel = (0, import_scoperegistry.createStateLogger)({
115
+ // Re-read on every capture: openFlow and loadGame both replace bags, and the kernel
116
+ // re-mounts whatever it is handed.
117
+ mounts: () => [...engine.listBags(), ...engine.flows().flatMap((f) => f.listBags())],
118
+ extra: () => visitState(engine)
119
+ }, { sink: opts.sink, label: tag });
117
120
  return {
118
121
  snapshot: () => snapshotState(engine),
119
- capture() {
120
- const next = snapshotState(engine);
121
- const changes = diffState(baseline, next);
122
- baseline = next;
123
- for (const c of changes) sink(`${tag}${c.path}: ${fmt(c.from)} -> ${fmt(c.to)}`);
124
- return changes;
125
- },
122
+ capture: () => kernel.capture(),
123
+ dispose: () => kernel.dispose(),
126
124
  logStep(step) {
127
- sink(`${tag}${describeStep(step)}`);
125
+ (opts.sink ?? ((l) => console.log(l)))(`${tag}${describeStep(step)}`);
128
126
  }
129
127
  };
130
128
  }
@@ -315,8 +313,8 @@ function createPropertyInspector(engine, opts = {}) {
315
313
  r.className = "pp-insp-row";
316
314
  const label = doc.createElement("span");
317
315
  label.className = "pp-insp-ref";
318
- label.textContent = row2.ref;
319
- label.title = row2.ref;
316
+ label.textContent = row2.path;
317
+ label.title = row2.path;
320
318
  const ctl = doc.createElement("div");
321
319
  ctl.className = "pp-insp-ctl";
322
320
  const reset = doc.createElement("button");
@@ -328,15 +326,15 @@ function createPropertyInspector(engine, opts = {}) {
328
326
  list.appendChild(r);
329
327
  let read;
330
328
  const commit = (v) => {
331
- engine.setProperty(row2.ref, v);
329
+ engine.setProperty(row2.path, v);
332
330
  syncReset();
333
331
  };
334
332
  const focused = (node) => doc.activeElement === node;
335
333
  function syncReset() {
336
- reset.disabled = sameValue(engine.getProperty(row2.ref), row2.default);
334
+ reset.disabled = sameValue(engine.getProperty(row2.path), row2.default);
337
335
  }
338
336
  reset.addEventListener("click", () => {
339
- engine.setProperty(row2.ref, row2.default);
337
+ engine.setProperty(row2.path, row2.default);
340
338
  read();
341
339
  syncReset();
342
340
  });
@@ -346,7 +344,7 @@ function createPropertyInspector(engine, opts = {}) {
346
344
  cb.addEventListener("change", () => commit(cb.checked));
347
345
  ctl.appendChild(cb);
348
346
  read = () => {
349
- if (!focused(cb)) cb.checked = engine.getProperty(row2.ref) === true;
347
+ if (!focused(cb)) cb.checked = engine.getProperty(row2.path) === true;
350
348
  };
351
349
  } else if (row2.type === "number") {
352
350
  const inp = doc.createElement("input");
@@ -354,7 +352,7 @@ function createPropertyInspector(engine, opts = {}) {
354
352
  inp.addEventListener("change", () => commit(Number(inp.value)));
355
353
  ctl.appendChild(inp);
356
354
  read = () => {
357
- if (!focused(inp)) inp.value = String(engine.getProperty(row2.ref) ?? "");
355
+ if (!focused(inp)) inp.value = String(engine.getProperty(row2.path) ?? "");
358
356
  };
359
357
  } else if (row2.type === "enum" || row2.type === "quality") {
360
358
  const sel = doc.createElement("select");
@@ -367,7 +365,7 @@ function createPropertyInspector(engine, opts = {}) {
367
365
  sel.addEventListener("change", () => commit(sel.value));
368
366
  ctl.appendChild(sel);
369
367
  read = () => {
370
- if (!focused(sel)) sel.value = String(engine.getProperty(row2.ref) ?? "");
368
+ if (!focused(sel)) sel.value = String(engine.getProperty(row2.path) ?? "");
371
369
  };
372
370
  } else if (row2.type === "flags") {
373
371
  const inp = doc.createElement("input");
@@ -377,7 +375,7 @@ function createPropertyInspector(engine, opts = {}) {
377
375
  ctl.appendChild(inp);
378
376
  read = () => {
379
377
  if (!focused(inp)) {
380
- const v = engine.getProperty(row2.ref);
378
+ const v = engine.getProperty(row2.path);
381
379
  inp.value = Array.isArray(v) ? v.join(", ") : "";
382
380
  }
383
381
  };
@@ -387,7 +385,7 @@ function createPropertyInspector(engine, opts = {}) {
387
385
  inp.addEventListener("change", () => commit(inp.value));
388
386
  ctl.appendChild(inp);
389
387
  read = () => {
390
- if (!focused(inp)) inp.value = String(engine.getProperty(row2.ref) ?? "");
388
+ if (!focused(inp)) inp.value = String(engine.getProperty(row2.path) ?? "");
391
389
  };
392
390
  }
393
391
  read();
package/dist/index.d.cts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { SaveGame, Engine, StepResult, Bundle as Bundle$1, BundleDescription } from '@patterkit/runtime';
2
+ import { StateSnapshot, StateChange, ScalarValue as ScalarValue$1 } from '@wildwinter/scoperegistry';
3
+ export { StateChange, StateSnapshot, diffState } from '@wildwinter/scoperegistry';
2
4
 
3
5
  declare const SAVE_SCHEMA = "patter/save@0";
4
6
  interface SaveEnvelope {
@@ -24,20 +26,14 @@ declare function setProperty(engine: Engine, ref: string, value: PropertyValue):
24
26
  /** Set many at once, e.g. `setProperties(engine, { "@hp": 10, "@scene.locked": false })`. */
25
27
  declare function setProperties(engine: Engine, values: Record<string, PropertyValue>): void;
26
28
 
27
- /** A flattened runtime-state value (a Patter scalar: number / boolean / string / string[] flags). */
28
- type StateValue = NonNullable<ReturnType<Engine["getProperty"]>>;
29
- /** A flattened snapshot: dotted path -> value. Paths: `@patter.x`, `@scene:scene.x`, `visit:nodeId`,
30
- * and `flow/...` for a flow's not-shared locals. */
31
- type StateSnapshot = Record<string, StateValue>;
32
- interface StateChange {
33
- path: string;
34
- from?: StateValue;
35
- to?: StateValue;
36
- }
37
- /** Flatten the engine's whole-game state into a path -> value map (shared scopes + every live flow). */
29
+ /** A flattened runtime-state value: a Patter scalar. The kernel calls this `ScalarValue`;
30
+ * the alias stays because it is exported API and reads in Patter's own vocabulary. */
31
+ type StateValue = ScalarValue$1;
32
+ /** Flatten the engine's whole-game state into a path -> value map (shared scopes + every live
33
+ * flow), off `saveGame()`. The logger no longer diffs this - it mounts the bags directly - but
34
+ * it stays as the public "what is the state right now" call, and as the definition of the path
35
+ * space the mounts compose. */
38
36
  declare function snapshotState(engine: Engine): StateSnapshot;
39
- /** The sorted set of paths that differ between two snapshots (added / removed / changed). */
40
- declare function diffState(prev: StateSnapshot, next: StateSnapshot): StateChange[];
41
37
  interface StateLoggerOptions {
42
38
  /** Where lines go; defaults to `console.log`. */
43
39
  sink?: (line: string) => void;
@@ -47,12 +43,16 @@ interface StateLoggerOptions {
47
43
  interface StateLogger {
48
44
  /** The current flattened state (no logging). */
49
45
  snapshot(): StateSnapshot;
50
- /** Diff since the last capture, log each change, and re-baseline. Returns the changes. */
46
+ /** Everything since the last capture: the property writes already logged as they landed,
47
+ * plus the visit counts, diffed and re-baselined. */
51
48
  capture(): StateChange[];
52
49
  /** Trace one played step (line / text / game-event / choice / end), including any `gameData`. */
53
50
  logStep(step: StepResult): void;
51
+ /** Unhook the bag auditors. The logger is inert afterwards. */
52
+ dispose(): void;
54
53
  }
55
- /** Create a state logger over an engine. Call `capture()` after each `advance`/`choose` to log mutations. */
54
+ /** Create a state logger over an engine. Property writes log as they land; call `capture()`
55
+ * after each `advance`/`choose` to pick up the visit counts and re-baseline. */
56
56
  declare function createStateLogger(engine: Engine, opts?: StateLoggerOptions): StateLogger;
57
57
 
58
58
  /** A minimal structural type for a WebSocket implementation (browsers + Node 21+ have a global one). */
@@ -490,4 +490,4 @@ interface AudioResolver {
490
490
  */
491
491
  declare function createAudioResolver(manifestJson: string, basePath: string): AudioResolver;
492
492
 
493
- export { type AudioResolver, type BundleInspector, type BundleInspectorOptions, type BundleSection, type DebugLink, type DebugLinkOptions, type DebugSocketLike, type LiveBundleResult, type PropertyInspector, type PropertyInspectorOptions, type PropertyValue, SAVE_SCHEMA, type SaveEnvelope, type StateChange, type StateLogger, type StateLoggerOptions, type StateSnapshot, type StateValue, applyLiveBundle, createAudioResolver, createBundleInspector, createDebugLink, createPropertyInspector, createStateLogger, deserializeState, diffState, getProperty, loadState, saveState, serializeState, setProperties, setProperty, snapshotState };
493
+ export { type AudioResolver, type BundleInspector, type BundleInspectorOptions, type BundleSection, type DebugLink, type DebugLinkOptions, type DebugSocketLike, type LiveBundleResult, type PropertyInspector, type PropertyInspectorOptions, type PropertyValue, SAVE_SCHEMA, type SaveEnvelope, type StateLogger, type StateLoggerOptions, type StateValue, applyLiveBundle, createAudioResolver, createBundleInspector, createDebugLink, createPropertyInspector, createStateLogger, deserializeState, getProperty, loadState, saveState, serializeState, setProperties, setProperty, snapshotState };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { SaveGame, Engine, StepResult, Bundle as Bundle$1, BundleDescription } from '@patterkit/runtime';
2
+ import { StateSnapshot, StateChange, ScalarValue as ScalarValue$1 } from '@wildwinter/scoperegistry';
3
+ export { StateChange, StateSnapshot, diffState } from '@wildwinter/scoperegistry';
2
4
 
3
5
  declare const SAVE_SCHEMA = "patter/save@0";
4
6
  interface SaveEnvelope {
@@ -24,20 +26,14 @@ declare function setProperty(engine: Engine, ref: string, value: PropertyValue):
24
26
  /** Set many at once, e.g. `setProperties(engine, { "@hp": 10, "@scene.locked": false })`. */
25
27
  declare function setProperties(engine: Engine, values: Record<string, PropertyValue>): void;
26
28
 
27
- /** A flattened runtime-state value (a Patter scalar: number / boolean / string / string[] flags). */
28
- type StateValue = NonNullable<ReturnType<Engine["getProperty"]>>;
29
- /** A flattened snapshot: dotted path -> value. Paths: `@patter.x`, `@scene:scene.x`, `visit:nodeId`,
30
- * and `flow/...` for a flow's not-shared locals. */
31
- type StateSnapshot = Record<string, StateValue>;
32
- interface StateChange {
33
- path: string;
34
- from?: StateValue;
35
- to?: StateValue;
36
- }
37
- /** Flatten the engine's whole-game state into a path -> value map (shared scopes + every live flow). */
29
+ /** A flattened runtime-state value: a Patter scalar. The kernel calls this `ScalarValue`;
30
+ * the alias stays because it is exported API and reads in Patter's own vocabulary. */
31
+ type StateValue = ScalarValue$1;
32
+ /** Flatten the engine's whole-game state into a path -> value map (shared scopes + every live
33
+ * flow), off `saveGame()`. The logger no longer diffs this - it mounts the bags directly - but
34
+ * it stays as the public "what is the state right now" call, and as the definition of the path
35
+ * space the mounts compose. */
38
36
  declare function snapshotState(engine: Engine): StateSnapshot;
39
- /** The sorted set of paths that differ between two snapshots (added / removed / changed). */
40
- declare function diffState(prev: StateSnapshot, next: StateSnapshot): StateChange[];
41
37
  interface StateLoggerOptions {
42
38
  /** Where lines go; defaults to `console.log`. */
43
39
  sink?: (line: string) => void;
@@ -47,12 +43,16 @@ interface StateLoggerOptions {
47
43
  interface StateLogger {
48
44
  /** The current flattened state (no logging). */
49
45
  snapshot(): StateSnapshot;
50
- /** Diff since the last capture, log each change, and re-baseline. Returns the changes. */
46
+ /** Everything since the last capture: the property writes already logged as they landed,
47
+ * plus the visit counts, diffed and re-baselined. */
51
48
  capture(): StateChange[];
52
49
  /** Trace one played step (line / text / game-event / choice / end), including any `gameData`. */
53
50
  logStep(step: StepResult): void;
51
+ /** Unhook the bag auditors. The logger is inert afterwards. */
52
+ dispose(): void;
54
53
  }
55
- /** Create a state logger over an engine. Call `capture()` after each `advance`/`choose` to log mutations. */
54
+ /** Create a state logger over an engine. Property writes log as they land; call `capture()`
55
+ * after each `advance`/`choose` to pick up the visit counts and re-baseline. */
56
56
  declare function createStateLogger(engine: Engine, opts?: StateLoggerOptions): StateLogger;
57
57
 
58
58
  /** A minimal structural type for a WebSocket implementation (browsers + Node 21+ have a global one). */
@@ -490,4 +490,4 @@ interface AudioResolver {
490
490
  */
491
491
  declare function createAudioResolver(manifestJson: string, basePath: string): AudioResolver;
492
492
 
493
- export { type AudioResolver, type BundleInspector, type BundleInspectorOptions, type BundleSection, type DebugLink, type DebugLinkOptions, type DebugSocketLike, type LiveBundleResult, type PropertyInspector, type PropertyInspectorOptions, type PropertyValue, SAVE_SCHEMA, type SaveEnvelope, type StateChange, type StateLogger, type StateLoggerOptions, type StateSnapshot, type StateValue, applyLiveBundle, createAudioResolver, createBundleInspector, createDebugLink, createPropertyInspector, createStateLogger, deserializeState, diffState, getProperty, loadState, saveState, serializeState, setProperties, setProperty, snapshotState };
493
+ export { type AudioResolver, type BundleInspector, type BundleInspectorOptions, type BundleSection, type DebugLink, type DebugLinkOptions, type DebugSocketLike, type LiveBundleResult, type PropertyInspector, type PropertyInspectorOptions, type PropertyValue, SAVE_SCHEMA, type SaveEnvelope, type StateLogger, type StateLoggerOptions, type StateValue, applyLiveBundle, createAudioResolver, createBundleInspector, createDebugLink, createPropertyInspector, createStateLogger, deserializeState, getProperty, loadState, saveState, serializeState, setProperties, setProperty, snapshotState };
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ function setProperties(engine, values) {
28
28
  }
29
29
 
30
30
  // src/logger.ts
31
- var eq = (a, b) => JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
31
+ import { createStateLogger as createKernelStateLogger, diffState } from "@wildwinter/scoperegistry";
32
32
  function snapshotState(engine) {
33
33
  const save = engine.saveGame();
34
34
  const out = {};
@@ -44,16 +44,6 @@ function snapshotState(engine) {
44
44
  }
45
45
  return out;
46
46
  }
47
- function diffState(prev, next) {
48
- const changes = [];
49
- const keys = [.../* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)])].sort();
50
- for (const path of keys) {
51
- const from = prev[path], to = next[path];
52
- if (!eq(from, to)) changes.push({ path, ...from !== void 0 ? { from } : {}, ...to !== void 0 ? { to } : {} });
53
- }
54
- return changes;
55
- }
56
- var fmt = (v) => v === void 0 ? "<unset>" : JSON.stringify(v);
57
47
  function describeStep(step) {
58
48
  switch (step.type) {
59
49
  case "line":
@@ -69,21 +59,29 @@ function describeStep(step) {
69
59
  }
70
60
  }
71
61
  var gd = (data) => data ? ` gameData=${JSON.stringify(data)}` : "";
62
+ function visitState(engine) {
63
+ const save = engine.saveGame();
64
+ const out = {};
65
+ for (const [id, n] of Object.entries(save.sharedVisits)) out[`visit:${id}`] = n;
66
+ for (const [fid, snap] of Object.entries(save.flows)) {
67
+ for (const [id, n] of Object.entries(snap.visits)) out[`${fid}/visit:${id}`] = n;
68
+ }
69
+ return out;
70
+ }
72
71
  function createStateLogger(engine, opts = {}) {
73
- const sink = opts.sink ?? ((line) => console.log(line));
74
72
  const tag = opts.label ? `[${opts.label}] ` : "";
75
- let baseline = snapshotState(engine);
73
+ const kernel = createKernelStateLogger({
74
+ // Re-read on every capture: openFlow and loadGame both replace bags, and the kernel
75
+ // re-mounts whatever it is handed.
76
+ mounts: () => [...engine.listBags(), ...engine.flows().flatMap((f) => f.listBags())],
77
+ extra: () => visitState(engine)
78
+ }, { sink: opts.sink, label: tag });
76
79
  return {
77
80
  snapshot: () => snapshotState(engine),
78
- capture() {
79
- const next = snapshotState(engine);
80
- const changes = diffState(baseline, next);
81
- baseline = next;
82
- for (const c of changes) sink(`${tag}${c.path}: ${fmt(c.from)} -> ${fmt(c.to)}`);
83
- return changes;
84
- },
81
+ capture: () => kernel.capture(),
82
+ dispose: () => kernel.dispose(),
85
83
  logStep(step) {
86
- sink(`${tag}${describeStep(step)}`);
84
+ (opts.sink ?? ((l) => console.log(l)))(`${tag}${describeStep(step)}`);
87
85
  }
88
86
  };
89
87
  }
@@ -274,8 +272,8 @@ function createPropertyInspector(engine, opts = {}) {
274
272
  r.className = "pp-insp-row";
275
273
  const label = doc.createElement("span");
276
274
  label.className = "pp-insp-ref";
277
- label.textContent = row2.ref;
278
- label.title = row2.ref;
275
+ label.textContent = row2.path;
276
+ label.title = row2.path;
279
277
  const ctl = doc.createElement("div");
280
278
  ctl.className = "pp-insp-ctl";
281
279
  const reset = doc.createElement("button");
@@ -287,15 +285,15 @@ function createPropertyInspector(engine, opts = {}) {
287
285
  list.appendChild(r);
288
286
  let read;
289
287
  const commit = (v) => {
290
- engine.setProperty(row2.ref, v);
288
+ engine.setProperty(row2.path, v);
291
289
  syncReset();
292
290
  };
293
291
  const focused = (node) => doc.activeElement === node;
294
292
  function syncReset() {
295
- reset.disabled = sameValue(engine.getProperty(row2.ref), row2.default);
293
+ reset.disabled = sameValue(engine.getProperty(row2.path), row2.default);
296
294
  }
297
295
  reset.addEventListener("click", () => {
298
- engine.setProperty(row2.ref, row2.default);
296
+ engine.setProperty(row2.path, row2.default);
299
297
  read();
300
298
  syncReset();
301
299
  });
@@ -305,7 +303,7 @@ function createPropertyInspector(engine, opts = {}) {
305
303
  cb.addEventListener("change", () => commit(cb.checked));
306
304
  ctl.appendChild(cb);
307
305
  read = () => {
308
- if (!focused(cb)) cb.checked = engine.getProperty(row2.ref) === true;
306
+ if (!focused(cb)) cb.checked = engine.getProperty(row2.path) === true;
309
307
  };
310
308
  } else if (row2.type === "number") {
311
309
  const inp = doc.createElement("input");
@@ -313,7 +311,7 @@ function createPropertyInspector(engine, opts = {}) {
313
311
  inp.addEventListener("change", () => commit(Number(inp.value)));
314
312
  ctl.appendChild(inp);
315
313
  read = () => {
316
- if (!focused(inp)) inp.value = String(engine.getProperty(row2.ref) ?? "");
314
+ if (!focused(inp)) inp.value = String(engine.getProperty(row2.path) ?? "");
317
315
  };
318
316
  } else if (row2.type === "enum" || row2.type === "quality") {
319
317
  const sel = doc.createElement("select");
@@ -326,7 +324,7 @@ function createPropertyInspector(engine, opts = {}) {
326
324
  sel.addEventListener("change", () => commit(sel.value));
327
325
  ctl.appendChild(sel);
328
326
  read = () => {
329
- if (!focused(sel)) sel.value = String(engine.getProperty(row2.ref) ?? "");
327
+ if (!focused(sel)) sel.value = String(engine.getProperty(row2.path) ?? "");
330
328
  };
331
329
  } else if (row2.type === "flags") {
332
330
  const inp = doc.createElement("input");
@@ -336,7 +334,7 @@ function createPropertyInspector(engine, opts = {}) {
336
334
  ctl.appendChild(inp);
337
335
  read = () => {
338
336
  if (!focused(inp)) {
339
- const v = engine.getProperty(row2.ref);
337
+ const v = engine.getProperty(row2.path);
340
338
  inp.value = Array.isArray(v) ? v.join(", ") : "";
341
339
  }
342
340
  };
@@ -346,7 +344,7 @@ function createPropertyInspector(engine, opts = {}) {
346
344
  inp.addEventListener("change", () => commit(inp.value));
347
345
  ctl.appendChild(inp);
348
346
  read = () => {
349
- if (!focused(inp)) inp.value = String(engine.getProperty(row2.ref) ?? "");
347
+ if (!focused(inp)) inp.value = String(engine.getProperty(row2.path) ?? "");
350
348
  };
351
349
  }
352
350
  read();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/play-helpers",
3
- "version": "0.3.3",
3
+ "version": "0.5.0",
4
4
  "description": "Thin game-integration helpers around @patterkit/runtime: save/load serialisation, runtime property setters, a state logger, the Patterpad Live Link client + hot reload, a property inspector, and audio resolution. The Patterplay JS companion.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,6 +34,7 @@
34
34
  "build": "tsup src/index.ts --format esm,cjs --dts --clean"
35
35
  },
36
36
  "dependencies": {
37
- "@patterkit/runtime": "0.8.0"
37
+ "@patterkit/runtime": "0.10.0",
38
+ "@wildwinter/scoperegistry": "^0.5.0"
38
39
  }
39
40
  }