pixelkiln 0.22.0 → 0.23.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/cli.js CHANGED
@@ -7985,7 +7985,11 @@ var ManifestEditSchema = z5.discriminatedUnion("action", [
7985
7985
  promptPrefix: z5.string().optional(),
7986
7986
  promptSuffix: z5.string().optional(),
7987
7987
  /** `#rrggbb` values; null or empty clears the style's own palette. */
7988
- palette: z5.array(z5.string().regex(/^#?[0-9a-f]{6}$/i, "expected a six-digit hex colour")).max(256).nullable().optional()
7988
+ palette: z5.array(z5.string().regex(/^#?[0-9a-f]{6}$/i, "expected a six-digit hex colour")).max(256).nullable().optional(),
7989
+ /** Provider view name (PixelLab: low top-down, high top-down, side); empty clears. */
7990
+ view: z5.string().max(64).nullable().optional(),
7991
+ /** pixflux only; null clears the style's own value. */
7992
+ noBackground: z5.boolean().nullable().optional()
7989
7993
  }).strict().refine((patch) => Object.keys(patch).length > 0, { message: "nothing to change" })
7990
7994
  }).strict()
7991
7995
  ]);
@@ -8043,6 +8047,8 @@ function applyEdit(raw, edit) {
8043
8047
  const colors = (patch2.palette ?? []).map((color) => "#" + color.replace(/^#/, "").toLowerCase());
8044
8048
  setOrDelete(style, "palette", colors.length ? colors : null);
8045
8049
  }
8050
+ if (patch2.view !== void 0) setOrDelete(style, "view", patch2.view?.trim() || null);
8051
+ if (patch2.noBackground !== void 0) setOrDelete(style, "noBackground", patch2.noBackground);
8046
8052
  return;
8047
8053
  }
8048
8054
  if (edit.action === "add-asset") {
@@ -8422,6 +8428,8 @@ async function buildGallerySnapshot(opts) {
8422
8428
  promptPrefix: style?.promptPrefix ?? "",
8423
8429
  promptSuffix: style?.promptSuffix ?? "",
8424
8430
  palette: style?.palette ?? [],
8431
+ view: style?.view ?? null,
8432
+ noBackground: style?.noBackground ?? true,
8425
8433
  quality: Boolean(style?.quality),
8426
8434
  tags: style?.tags ?? [],
8427
8435
  extends: typeof rawStyle?.extends === "string" ? rawStyle.extends : null,
@@ -8902,6 +8910,7 @@ function renderGallery(snapshot, opts = {}) {
8902
8910
  </footer>
8903
8911
  <div id="drawer-host"></div>
8904
8912
  <div id="dialog-host"></div>
8913
+ <datalist id="view-options"><option value="low top-down"><option value="high top-down"><option value="side"><option value="sidescroller"></datalist>
8905
8914
  <script>
8906
8915
  const INITIAL = ${data};
8907
8916
  const SESSION = ${session};
@@ -9693,9 +9702,18 @@ function inheritorsOf(style, field) {
9693
9702
  }
9694
9703
  return out;
9695
9704
  }
9705
+ // noBackground reaches the request only for pixflux and non-PixelLab
9706
+ // providers; elsewhere a change is recorded but alters nothing.
9707
+ const fieldReaches = (field, style) =>
9708
+ field !== 'noBackground' || style.generator === 'pixflux' || style.provider !== 'pixellab';
9696
9709
  function blastRadius(style, fields) {
9697
- const styleIds = new Set([style.id]);
9698
- for (const field of fields) for (const id of inheritorsOf(style, field)) styleIds.add(id);
9710
+ const byId = new Map(snap.styles.filter((x) => x.project === style.project).map((x) => [x.id, x]));
9711
+ const styleIds = new Set();
9712
+ for (const field of fields) {
9713
+ for (const id of [style.id, ...inheritorsOf(style, field)]) {
9714
+ if (fieldReaches(field, byId.get(id) || style)) styleIds.add(id);
9715
+ }
9716
+ }
9699
9717
  const affected = snap.items.filter((i) => i.project === style.project && i.declared && styleIds.has(i.styleId));
9700
9718
  const units = new Map();
9701
9719
  for (const i of affected) if (i.estimatedCost !== null) units.set(i.costUnit, (units.get(i.costUnit) || 0) + i.estimatedCost);
@@ -9720,6 +9738,11 @@ function styleForm(style) {
9720
9738
  const prefix = el('input'); prefix.type = 'text'; prefix.value = style.promptPrefix; prefix.placeholder = 'none';
9721
9739
  const suffix = el('input'); suffix.type = 'text'; suffix.value = style.promptSuffix; suffix.placeholder = 'none';
9722
9740
  const palette = el('input'); palette.type = 'text'; palette.value = style.palette.join(', '); palette.placeholder = '#rrggbb, #rrggbb \u2014 leave empty for no forced palette';
9741
+ const view = el('input'); view.type = 'text'; view.value = style.view || ''; view.placeholder = 'provider default';
9742
+ view.setAttribute('list', 'view-options');
9743
+ const noBg = el('select');
9744
+ noBg.append(new Option(style.extends ? 'inherit from ' + style.extends : 'default (on)', 'default'), new Option('on \u2014 strip the generated background', 'on'), new Option('off \u2014 keep the background (scenes, banners)', 'off'));
9745
+ noBg.value = own('noBackground') ? (style.noBackground ? 'on' : 'off') : 'default';
9723
9746
  const swatches = el('div', 'pal');
9724
9747
  const drawSwatches = () => {
9725
9748
  swatches.textContent = '';
@@ -9732,12 +9755,21 @@ function styleForm(style) {
9732
9755
  field('palette', palette, 'Forced colours where the provider supports them (pixflux). ' + provenance('palette')),
9733
9756
  swatches,
9734
9757
  );
9758
+ const row = el('div', 'row');
9759
+ row.append(
9760
+ field('view', view, 'PixelLab accepts low top-down, high top-down, side; Retro Diffusion reads sidescroller. ' + provenance('view')),
9761
+ field('background', noBg, (fieldReaches('noBackground', style) ? 'Sent for this style. ' : 'Not sent for ' + style.provider + ' ' + style.generator + '; recorded only. ') + provenance('noBackground')),
9762
+ );
9763
+ form.append(row);
9735
9764
  const blast = el('div', 'blast');
9736
9765
  const changed = () => {
9737
9766
  const out = [];
9738
9767
  if (prefix.value !== style.promptPrefix) out.push('promptPrefix');
9739
9768
  if (suffix.value !== style.promptSuffix) out.push('promptSuffix');
9740
9769
  if (parsePalette(palette.value).join(',') !== style.palette.map((c) => c.toLowerCase()).join(',')) out.push('palette');
9770
+ if (view.value.trim() !== (style.view || '')) out.push('view');
9771
+ const bgNow = own('noBackground') ? (style.noBackground ? 'on' : 'off') : 'default';
9772
+ if (noBg.value !== bgNow) out.push('noBackground');
9741
9773
  return out;
9742
9774
  };
9743
9775
  const updateBlast = () => {
@@ -9745,6 +9777,11 @@ function styleForm(style) {
9745
9777
  drawSwatches();
9746
9778
  if (!fields.length) { blast.className = 'blast'; blast.textContent = 'No changes yet. A style change alters the request for every asset that uses it.'; return; }
9747
9779
  const r = blastRadius(style, fields);
9780
+ if (!r.assets) {
9781
+ blast.className = 'blast';
9782
+ blast.textContent = 'Recorded in the manifest only: nothing in ' + style.id + ' sends this field, so no request changes.';
9783
+ return;
9784
+ }
9748
9785
  blast.className = 'blast hot';
9749
9786
  blast.textContent = '';
9750
9787
  const others = r.styles.filter((id) => id !== style.id);
@@ -9754,7 +9791,8 @@ function styleForm(style) {
9754
9791
  : ' in ' + style.id + '.'));
9755
9792
  blast.append(document.createTextNode(' Generated ones become stale; regenerating all of them is about ' + (r.cost || 'nothing') + '. Nothing is spent until you generate.'));
9756
9793
  };
9757
- for (const input of [prefix, suffix, palette]) input.addEventListener('input', updateBlast);
9794
+ for (const input of [prefix, suffix, palette, view]) input.addEventListener('input', updateBlast);
9795
+ noBg.addEventListener('change', updateBlast);
9758
9796
  updateBlast();
9759
9797
  form.append(blast);
9760
9798
  const actions = el('div', 'actions');
@@ -9773,6 +9811,8 @@ function styleForm(style) {
9773
9811
  if (fields.includes('promptPrefix')) patch.promptPrefix = prefix.value;
9774
9812
  if (fields.includes('promptSuffix')) patch.promptSuffix = suffix.value;
9775
9813
  if (fields.includes('palette')) patch.palette = colors;
9814
+ if (fields.includes('view')) patch.view = view.value.trim();
9815
+ if (fields.includes('noBackground')) patch.noBackground = noBg.value === 'default' ? null : noBg.value === 'on';
9776
9816
  save.disabled = true; msg.className = 'msg'; msg.textContent = 'saving\u2026';
9777
9817
  const r = blastRadius(style, fields);
9778
9818
  try {
@@ -9781,7 +9821,9 @@ function styleForm(style) {
9781
9821
  snap = await postEdit(body);
9782
9822
  ui.editing = null;
9783
9823
  ui.notice = { id: 'style:' + (style.project || '') + ':' + style.id,
9784
- text: 'Saved. The request for ' + r.assets + (r.assets === 1 ? ' asset' : ' assets') + ' changed' + (r.cost ? ' \u2014 about ' + r.cost + ' to regenerate.' : '.') + ' Nothing is spent until you generate.' };
9824
+ text: r.assets
9825
+ ? 'Saved. The request for ' + r.assets + (r.assets === 1 ? ' asset' : ' assets') + ' changed' + (r.cost ? ' \u2014 about ' + r.cost + ' to regenerate.' : '.') + ' Nothing is spent until you generate.'
9826
+ : 'Saved. Recorded in the manifest; no request changed.' };
9785
9827
  render();
9786
9828
  } catch (err) {
9787
9829
  save.disabled = false;