@patterkit/play-helpers 0.1.1 → 0.2.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
@@ -240,7 +240,9 @@ var CSS = `
240
240
  .pp-insp{font:13px/1.4 ui-sans-serif,system-ui,sans-serif;color:#15201e;background:#f4efe6;border:1px solid #cfc7b8;border-radius:10px;padding:.6rem .7rem;max-width:22rem;box-shadow:0 6px 20px rgba(21,32,30,.12)}
241
241
  .pp-insp h4{margin:0 0 .4rem;font:600 .72rem/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase;color:#5c6b62}
242
242
  .pp-insp-empty{color:#8a9691;font-style:italic}
243
- .pp-insp-row{display:flex;align-items:center;gap:.4rem;margin:.18rem 0}
243
+ .pp-insp-io { display: flex; gap: 6px; margin: 0 0 8px; }
244
+ .pp-insp-io button { font: inherit; padding: 2px 8px; cursor: pointer; }
245
+ .pp-insp-row{display:flex;align-items:center;gap:.4rem;margin:.18rem 0}
244
246
  .pp-insp-ref{flex:0 0 8rem;font-family:ui-monospace,monospace;font-size:.78rem;color:#214f4b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
245
247
  .pp-insp-ctl{flex:1;min-width:0;display:flex}
246
248
  .pp-insp-ctl input[type=text],.pp-insp-ctl input[type=number],.pp-insp-ctl select{width:100%;box-sizing:border-box;font:inherit;padding:.15rem .3rem;border:1px solid #cfc7b8;border-radius:6px;background:#fff;color:inherit}
@@ -266,7 +268,42 @@ function createPropertyInspector(engine, opts = {}) {
266
268
  const heading = doc.createElement("h4");
267
269
  heading.textContent = opts.title ?? "Runtime state";
268
270
  const list = doc.createElement("div");
269
- el.append(heading, list);
271
+ const io = doc.createElement("div");
272
+ io.className = "pp-insp-io";
273
+ const saveBtn = doc.createElement("button");
274
+ saveBtn.type = "button";
275
+ saveBtn.textContent = "Save state\u2026";
276
+ saveBtn.addEventListener("click", () => {
277
+ const blob = new Blob([serializeState(engine)], { type: "application/json" });
278
+ const a = doc.createElement("a");
279
+ a.href = URL.createObjectURL(blob);
280
+ a.download = "save.patterstate";
281
+ a.click();
282
+ URL.revokeObjectURL(a.href);
283
+ });
284
+ const loadBtn = doc.createElement("button");
285
+ loadBtn.type = "button";
286
+ loadBtn.textContent = "Load state\u2026";
287
+ loadBtn.addEventListener("click", () => {
288
+ const input = doc.createElement("input");
289
+ input.type = "file";
290
+ input.accept = ".patterstate,application/json";
291
+ input.addEventListener("change", () => {
292
+ const file = input.files?.[0];
293
+ if (!file) return;
294
+ void file.text().then((text) => {
295
+ try {
296
+ deserializeState(engine, text);
297
+ refresh();
298
+ } catch (err) {
299
+ console.error("Load state failed:", err instanceof Error ? err.message : err);
300
+ }
301
+ });
302
+ });
303
+ input.click();
304
+ });
305
+ io.append(saveBtn, loadBtn);
306
+ el.append(heading, io, list);
270
307
  const rowRefreshers = [];
271
308
  const buildRow = (row) => {
272
309
  const r = doc.createElement("div");
package/dist/index.js CHANGED
@@ -200,7 +200,9 @@ var CSS = `
200
200
  .pp-insp{font:13px/1.4 ui-sans-serif,system-ui,sans-serif;color:#15201e;background:#f4efe6;border:1px solid #cfc7b8;border-radius:10px;padding:.6rem .7rem;max-width:22rem;box-shadow:0 6px 20px rgba(21,32,30,.12)}
201
201
  .pp-insp h4{margin:0 0 .4rem;font:600 .72rem/1 ui-sans-serif,system-ui,sans-serif;letter-spacing:.08em;text-transform:uppercase;color:#5c6b62}
202
202
  .pp-insp-empty{color:#8a9691;font-style:italic}
203
- .pp-insp-row{display:flex;align-items:center;gap:.4rem;margin:.18rem 0}
203
+ .pp-insp-io { display: flex; gap: 6px; margin: 0 0 8px; }
204
+ .pp-insp-io button { font: inherit; padding: 2px 8px; cursor: pointer; }
205
+ .pp-insp-row{display:flex;align-items:center;gap:.4rem;margin:.18rem 0}
204
206
  .pp-insp-ref{flex:0 0 8rem;font-family:ui-monospace,monospace;font-size:.78rem;color:#214f4b;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
205
207
  .pp-insp-ctl{flex:1;min-width:0;display:flex}
206
208
  .pp-insp-ctl input[type=text],.pp-insp-ctl input[type=number],.pp-insp-ctl select{width:100%;box-sizing:border-box;font:inherit;padding:.15rem .3rem;border:1px solid #cfc7b8;border-radius:6px;background:#fff;color:inherit}
@@ -226,7 +228,42 @@ function createPropertyInspector(engine, opts = {}) {
226
228
  const heading = doc.createElement("h4");
227
229
  heading.textContent = opts.title ?? "Runtime state";
228
230
  const list = doc.createElement("div");
229
- el.append(heading, list);
231
+ const io = doc.createElement("div");
232
+ io.className = "pp-insp-io";
233
+ const saveBtn = doc.createElement("button");
234
+ saveBtn.type = "button";
235
+ saveBtn.textContent = "Save state\u2026";
236
+ saveBtn.addEventListener("click", () => {
237
+ const blob = new Blob([serializeState(engine)], { type: "application/json" });
238
+ const a = doc.createElement("a");
239
+ a.href = URL.createObjectURL(blob);
240
+ a.download = "save.patterstate";
241
+ a.click();
242
+ URL.revokeObjectURL(a.href);
243
+ });
244
+ const loadBtn = doc.createElement("button");
245
+ loadBtn.type = "button";
246
+ loadBtn.textContent = "Load state\u2026";
247
+ loadBtn.addEventListener("click", () => {
248
+ const input = doc.createElement("input");
249
+ input.type = "file";
250
+ input.accept = ".patterstate,application/json";
251
+ input.addEventListener("change", () => {
252
+ const file = input.files?.[0];
253
+ if (!file) return;
254
+ void file.text().then((text) => {
255
+ try {
256
+ deserializeState(engine, text);
257
+ refresh();
258
+ } catch (err) {
259
+ console.error("Load state failed:", err instanceof Error ? err.message : err);
260
+ }
261
+ });
262
+ });
263
+ input.click();
264
+ });
265
+ io.append(saveBtn, loadBtn);
266
+ el.append(heading, io, list);
230
267
  const rowRefreshers = [];
231
268
  const buildRow = (row) => {
232
269
  const r = doc.createElement("div");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patterkit/play-helpers",
3
- "version": "0.1.1",
3
+ "version": "0.2.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,6 @@
34
34
  "build": "tsup src/index.ts --format esm,cjs --dts --clean"
35
35
  },
36
36
  "dependencies": {
37
- "@patterkit/runtime": "0.2.1"
37
+ "@patterkit/runtime": "0.4.0"
38
38
  }
39
39
  }