pixelkiln 0.44.0 → 0.46.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
@@ -389,7 +389,7 @@ var MIRRORED_DIRECTION = {
389
389
  west: "east",
390
390
  "south-west": "south-east"
391
391
  };
392
- var CharacterModeSchema = import_zod.z.enum(["standard", "v3", "pro"]);
392
+ var CharacterModeSchema = import_zod.z.enum(["standard", "v3", "pro", "pro-flash"]);
393
393
  var CHARACTER_PROPORTION_PRESETS = ["default", "chibi", "cartoon", "stylized", "realistic_male", "realistic_female", "heroic"];
394
394
  var CharacterProportionsSchema = import_zod.z.union([
395
395
  import_zod.z.enum(CHARACTER_PROPORTION_PRESETS),
@@ -585,14 +585,27 @@ var StyleObjectSchema = import_zod.z.object({
585
585
  /**
586
586
  * `character` only. `standard` draws from a skeleton template for 1
587
587
  * generation; `v3` is the highest quality at 2 to 9 by size; `pro` is a
588
- * reference-based engine at 20 to 40 by size. States inherit the
589
- * parent's engine; animations choose their own.
588
+ * reference-based engine at 20 to 40 by size; `pro-flash` draws a
589
+ * south sprite with PixelLab's newest image model and rotates it with
590
+ * v3, 6 to 17 by size, or the rotations alone (1 at 64px) from a
591
+ * `reference`. States inherit the parent's engine; animations choose
592
+ * their own.
590
593
  */
591
594
  mode: CharacterModeSchema.optional(),
592
- /** `character` only. Rotations per base or state. `v3` and `pro` always draw 8. */
595
+ /** `character` only. Rotations per base or state. Every engine but `standard` draws 8. */
593
596
  directions: import_zod.z.union([import_zod.z.literal(4), import_zod.z.literal(8)]).optional(),
594
- /** `character` only. Body template: `mannequin` (default) or a quadruped (`bear`, `cat`, `dog`, `horse`, `lion`). */
597
+ /** `character` only. Body template: `mannequin` (default), a quadruped (`bear`, `cat`, `dog`, `horse`, `lion`), or `custom` for `pro-flash`. */
595
598
  template: import_zod.z.string().min(1).optional(),
599
+ /**
600
+ * `character` only, `pro-flash` bases with a style image: which traits
601
+ * the style image lends. Each defaults to true.
602
+ */
603
+ styleTraits: import_zod.z.object({
604
+ palette: import_zod.z.boolean().optional(),
605
+ outline: import_zod.z.boolean().optional(),
606
+ detail: import_zod.z.boolean().optional(),
607
+ shading: import_zod.z.boolean().optional()
608
+ }).strict().optional(),
596
609
  /** `character` only, `standard` humanoid bases. A preset or multipliers; an asset may override it. */
597
610
  proportions: CharacterProportionsSchema.optional(),
598
611
  /**
@@ -605,6 +618,12 @@ var StyleObjectSchema = import_zod.z.object({
605
618
  isometric: import_zod.z.boolean().optional(),
606
619
  /** `character` only, `v3` bases: let PixelLab expand the prompt into a fuller one before drawing. */
607
620
  enhancePrompt: import_zod.z.boolean().optional(),
621
+ /**
622
+ * `character` only, `pro` bases: the asset id of a generated 8-direction
623
+ * character in this style whose look every base drawn from text or a
624
+ * concept follows. An asset may override it; the anchor itself ignores it.
625
+ */
626
+ styleCharacter: import_zod.z.string().min(1).optional(),
608
627
  /** Fixed seed for reproducibility where the endpoint supports it. */
609
628
  seed: import_zod.z.number().int().optional(),
610
629
  /**
@@ -777,6 +796,15 @@ var AssetSchema = import_zod.z.object({
777
796
  * still guides the result.
778
797
  */
779
798
  reference: import_zod.z.union([import_zod.z.string().min(1), import_zod.z.record(CharacterDirectionSchema, import_zod.z.string().min(1))]).optional(),
799
+ /**
800
+ * `character` styles, `pro` bases only: a manifest-relative concept
801
+ * image (a painting, a photo, a sketch; up to 1024px) that seeds the
802
+ * design instead of the prompt alone. A style image or `styleCharacter`
803
+ * may still anchor the look.
804
+ */
805
+ concept: import_zod.z.string().min(1).optional(),
806
+ /** `character` styles, `pro` bases: this base's style anchor, over the style's. */
807
+ styleCharacter: import_zod.z.string().min(1).optional(),
780
808
  /**
781
809
  * Another asset of the same style flipped left to right, made locally
782
810
  * from that asset's downloaded files at no generation cost.
@@ -858,6 +886,20 @@ var AssetSchema = import_zod.z.object({
858
886
  path: ["reference"]
859
887
  });
860
888
  }
889
+ if (asset.concept && (asset.state || asset.animation || asset.mirror)) {
890
+ context.addIssue({
891
+ code: import_zod.z.ZodIssueCode.custom,
892
+ message: "a concept image belongs on a base; a state, animation, or mirror takes its look from its parent",
893
+ path: ["concept"]
894
+ });
895
+ }
896
+ if (asset.concept && asset.reference) {
897
+ context.addIssue({
898
+ code: import_zod.z.ZodIssueCode.custom,
899
+ message: "concept and reference are mutually exclusive: a concept seeds a new design, a reference is the sprite to rotate",
900
+ path: ["concept"]
901
+ });
902
+ }
861
903
  if (typeof asset.reference === "object" && !Object.keys(asset.reference).length) {
862
904
  context.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: "a reference needs at least a south image", path: ["reference"] });
863
905
  }
@@ -1532,6 +1574,29 @@ var PixelLabClient = class {
1532
1574
  ...south ? { reference_image: encode(south) } : {},
1533
1575
  ...args.enhancePrompt ? { enhance_prompt: true } : {}
1534
1576
  };
1577
+ } else if (args.mode === "pro-flash") {
1578
+ path33 = "/create-character-pro-flash";
1579
+ const traits = args.styleTraits;
1580
+ body = {
1581
+ description: args.description,
1582
+ template_id: args.template,
1583
+ n_directions: 8,
1584
+ // The author's sprite sets the canvas; a size only applies to text creation.
1585
+ ...south ? { first_frame: encode(south) } : { image_size: imageSize },
1586
+ ...args.view ? { view: args.view } : {},
1587
+ ...args.seed != null ? { seed: args.seed } : {},
1588
+ ...args.styleReference && args.styleReferenceSize ? {
1589
+ style_image: { image: encode(args.styleReference), size: args.styleReferenceSize },
1590
+ ...traits ? {
1591
+ style_options: {
1592
+ ...traits.palette !== void 0 ? { color_palette: traits.palette } : {},
1593
+ ...traits.outline !== void 0 ? { outline: traits.outline } : {},
1594
+ ...traits.detail !== void 0 ? { detail: traits.detail } : {},
1595
+ ...traits.shading !== void 0 ? { shading: traits.shading } : {}
1596
+ }
1597
+ } : {}
1598
+ } : {}
1599
+ };
1535
1600
  } else if (args.mode === "pro") {
1536
1601
  path33 = "/create-character-pro";
1537
1602
  body = {
@@ -1539,10 +1604,12 @@ var PixelLabClient = class {
1539
1604
  image_size: imageSize,
1540
1605
  template_id: args.template,
1541
1606
  no_background: args.noBackground ?? true,
1542
- method: south ? "rotate_character" : "create_with_style",
1607
+ method: south ? "rotate_character" : args.concept ? "create_from_concept" : "create_with_style",
1543
1608
  ...args.view ? { view: args.view } : {},
1544
1609
  ...args.seed != null ? { seed: args.seed } : {},
1545
- ...south ? { reference_image: encode(south) } : args.styleReference ? { reference_image: encode(args.styleReference) } : {}
1610
+ ...south ? { reference_image: encode(south) } : args.styleReference ? { reference_image: encode(args.styleReference) } : {},
1611
+ ...!south && args.concept ? { concept_image: encode(args.concept) } : {},
1612
+ ...!south && args.styleCharacterId ? { style_character_id: args.styleCharacterId } : {}
1546
1613
  };
1547
1614
  } else {
1548
1615
  path33 = args.directions === 4 ? "/create-character-with-4-directions" : "/create-character-with-8-directions";
@@ -2304,7 +2371,10 @@ function specHash(spec, styleImageHashes, providerOptionIdentity = spec.provider
2304
2371
  textGuidanceScale: spec.character.textGuidanceScale,
2305
2372
  isometric: spec.character.isometric,
2306
2373
  enhancePrompt: spec.character.enhancePrompt,
2307
- reference: spec.character.reference ? Object.fromEntries(Object.entries(spec.character.reference).map(([direction, image]) => [direction, image.sha256])) : void 0
2374
+ styleTraits: spec.character.styleTraits,
2375
+ reference: spec.character.reference ? Object.fromEntries(Object.entries(spec.character.reference).map(([direction, image]) => [direction, image.sha256])) : void 0,
2376
+ concept: spec.character.concept?.sha256,
2377
+ styleAnchor: spec.character.styleAnchor ? { of: spec.character.styleAnchor.assetId, sha256: spec.character.styleAnchor.sha256 } : void 0
2308
2378
  } : void 0,
2309
2379
  // A mirror's bytes come from its source's recorded outputs; the plan
2310
2380
  // compares those directly, so only the choice of source is identity.
@@ -2345,12 +2415,24 @@ function characterCost(spec) {
2345
2415
  if (character.kind === "state") return generationCost(spec.width, spec.height, "1dir");
2346
2416
  if (character.mode === "standard") return 1;
2347
2417
  if (character.mode === "v3") return 1 + Math.max(1, Math.ceil(px * 8 / 65536));
2418
+ if (character.mode === "pro-flash") {
2419
+ const south = character.reference?.south;
2420
+ return south ? proFlashCharacterCost(south.width, south.height, true) : proFlashCharacterCost(spec.width, spec.height, false);
2421
+ }
2348
2422
  return generationCost(spec.width, spec.height, "1dir");
2349
2423
  }
2424
+ function proFlashCharacterCost(width, height, fromReference) {
2425
+ const side = Math.max(32, Math.ceil(Math.max(width, height) / 4) * 4);
2426
+ const rotations = Math.max(1, Math.ceil(side * side * 8 / 65536));
2427
+ if (fromReference) return rotations;
2428
+ const image = side <= 96 ? 5 : side <= 208 ? 6 : 9;
2429
+ return image + rotations;
2430
+ }
2350
2431
  function characterAnimationName(spec) {
2351
2432
  return `pixelkiln:${spec.styleId}/${spec.assetId}`;
2352
2433
  }
2353
2434
  var CHARACTER_TEMPLATES = ["mannequin", "bear", "cat", "dog", "horse", "lion"];
2435
+ var PRO_FLASH_TEMPLATES = [...CHARACTER_TEMPLATES, "custom"];
2354
2436
  function encodeAnimationJob(job) {
2355
2437
  return `character-animation:${Buffer.from(JSON.stringify(job)).toString("base64url")}`;
2356
2438
  }
@@ -2491,12 +2573,25 @@ var PixelLabProvider = class _PixelLabProvider {
2491
2573
  }
2492
2574
  }
2493
2575
  }
2576
+ if (character.concept) {
2577
+ if (character.mode !== "pro") throw new Error(`${label}: a concept image is a pro input; the ${character.mode} engine draws from text or a reference`);
2578
+ if (character.concept.width > 1024 || character.concept.height > 1024) {
2579
+ throw new Error(`${label}: concept image is ${character.concept.width}x${character.concept.height}; PixelLab pro takes up to 1024px`);
2580
+ }
2581
+ }
2582
+ if (character.styleAnchor) {
2583
+ if (character.mode !== "pro") throw new Error(`${label}: styleCharacter is a pro input; the ${character.mode} engine has no style anchor`);
2584
+ if (character.reference) throw new Error(`${label}: a pro base rotating its own reference takes no styleCharacter`);
2585
+ if (character.styleAnchor.spec.character?.directions !== 8) {
2586
+ throw new Error(`${label}: styleCharacter ${character.styleAnchor.assetId} has ${character.styleAnchor.spec.character?.directions} directions; PixelLab wants an 8-direction anchor`);
2587
+ }
2588
+ }
2494
2589
  if (character.reference) {
2495
2590
  const given = Object.keys(character.reference);
2496
2591
  if (!character.reference.south) throw new Error(`${label}: a reference needs a south-facing sprite`);
2497
2592
  if (character.mode !== "standard") {
2498
2593
  if (given.length > 1) throw new Error(`${label}: PixelLab ${character.mode} rotates one south-facing reference; drop the other directions`);
2499
- const limit = character.mode === "v3" ? 256 : 168;
2594
+ const limit = character.mode === "pro" ? 168 : 256;
2500
2595
  const south = character.reference.south;
2501
2596
  if (south.width > limit || south.height > limit) {
2502
2597
  throw new Error(`${label}: reference is ${south.width}x${south.height}; PixelLab ${character.mode} takes up to ${limit}px`);
@@ -2520,26 +2615,39 @@ var PixelLabProvider = class _PixelLabProvider {
2520
2615
  }
2521
2616
  }
2522
2617
  if (styleImages.length) {
2523
- if (character.mode !== "pro") {
2618
+ if (character.mode !== "pro" && character.mode !== "pro-flash") {
2524
2619
  throw new Error(
2525
- `PixelLab ${character.mode} characters take no style images; give a base its own sprite with \`reference\`, or use mode pro for a style anchor`
2620
+ `PixelLab ${character.mode} characters take no style images; give a base its own sprite with \`reference\`, or use mode pro or pro-flash for a style anchor`
2526
2621
  );
2527
2622
  }
2528
- if (styleImages.length > 1) throw new Error("PixelLab pro characters take one style image");
2623
+ if (styleImages.length > 1) throw new Error(`PixelLab ${character.mode} characters take one style image`);
2529
2624
  if (character.kind === "base" && character.reference) {
2530
- throw new Error(`${label}: a pro base rotating its own reference takes no style image`);
2625
+ throw new Error(`${label}: a ${character.mode} base rotating its own reference takes no style image`);
2531
2626
  }
2532
2627
  const image = styleImages[0];
2533
- if (image.width > 168 || image.height > 168) {
2534
- throw new Error(`PixelLab pro character style image is ${image.width}x${image.height}; the limit is 168px`);
2628
+ const limit = character.mode === "pro" ? 168 : 256;
2629
+ if (image.width > limit || image.height > limit) {
2630
+ throw new Error(`PixelLab ${character.mode} character style image is ${image.width}x${image.height}; the limit is ${limit}px`);
2631
+ }
2632
+ if (character.mode === "pro-flash" && (image.width > spec.width || image.height > spec.height)) {
2633
+ throw new Error(
2634
+ `PixelLab pro-flash style image is ${image.width}x${image.height} but the character is ${spec.width}x${spec.height}; crop the image to its subject or raise the style's size`
2635
+ );
2535
2636
  }
2536
2637
  }
2537
- const maxSize = character.mode === "v3" ? 256 : 128;
2638
+ if (character.styleTraits && character.mode !== "pro-flash") {
2639
+ throw new Error(`${label}: styleTraits choose what a pro-flash style image lends; the ${character.mode} engine does not take them`);
2640
+ }
2641
+ const maxSize = character.mode === "v3" || character.mode === "pro-flash" ? 256 : 128;
2538
2642
  if (spec.width < 16 || spec.height < 16 || spec.width > maxSize || spec.height > maxSize) {
2539
2643
  throw new Error(`PixelLab ${character.mode} characters must be between 16 and ${maxSize} pixels`);
2540
2644
  }
2541
- if (!CHARACTER_TEMPLATES.includes(character.template)) {
2542
- throw new Error(`PixelLab character template must be one of: ${CHARACTER_TEMPLATES.join(", ")}`);
2645
+ if (character.mode === "pro-flash" && character.kind === "base" && (spec.width % 4 || spec.height % 4)) {
2646
+ throw new Error(`PixelLab pro-flash characters are sized in multiples of 4 pixels; ${spec.width}x${spec.height} is not`);
2647
+ }
2648
+ const templates = character.mode === "pro-flash" ? PRO_FLASH_TEMPLATES : CHARACTER_TEMPLATES;
2649
+ if (!templates.includes(character.template)) {
2650
+ throw new Error(`PixelLab ${character.mode} character template must be one of: ${templates.join(", ")}`);
2543
2651
  }
2544
2652
  const views = character.mode === "standard" ? ["low top-down", "high top-down", "side", "perspective", "oblique"] : ["low top-down", "high top-down", "side"];
2545
2653
  if (!views.includes(spec.view)) {
@@ -2592,7 +2700,11 @@ var PixelLabProvider = class _PixelLabProvider {
2592
2700
  isometric: character.isometric,
2593
2701
  reference: character.reference ? readReference(spec, character.reference) : void 0,
2594
2702
  styleReference: styleImage ? { base64: styleImage.base64, format: styleImage.format } : void 0,
2595
- enhancePrompt: character.enhancePrompt
2703
+ enhancePrompt: character.enhancePrompt,
2704
+ concept: character.concept ? readPose(spec, "concept image", character.concept) : void 0,
2705
+ styleCharacterId: character.styleAnchor ? requireStyleObjectId(spec, context) : void 0,
2706
+ styleReferenceSize: styleImage ? { width: styleImage.width, height: styleImage.height } : void 0,
2707
+ styleTraits: character.styleTraits
2596
2708
  });
2597
2709
  return { jobId: res2.character_id, metadata: { character: { kind: "base", characterId: res2.character_id, mode: character.mode, directions: character.directions, backgroundJobId: res2.background_job_id } } };
2598
2710
  }
@@ -3012,6 +3124,14 @@ function readReference(spec, reference) {
3012
3124
  }
3013
3125
  return images;
3014
3126
  }
3127
+ function requireStyleObjectId(spec, context) {
3128
+ if (!context?.styleObjectId) {
3129
+ throw new Error(
3130
+ `${spec.styleId}/${spec.assetId} anchors its style on ${spec.character.styleAnchor.assetId}, which has no PixelLab character id in the lockfile yet; generate the anchor first`
3131
+ );
3132
+ }
3133
+ return context.styleObjectId;
3134
+ }
3015
3135
  function readPose(spec, what, image) {
3016
3136
  const bytes = (0, import_node_fs2.readFileSync)(image.path);
3017
3137
  if (sha256(bytes) !== image.sha256) {
@@ -5711,6 +5831,18 @@ async function resolveSpecs(loaded, filter) {
5711
5831
  finalized.add(assetId);
5712
5832
  return resolved;
5713
5833
  }
5834
+ const anchorId = asset.styleCharacter ?? style.styleCharacter;
5835
+ if (resolved.character?.kind === "base" && anchorId && anchorId !== assetId) {
5836
+ const anchorSpec = await finalize(anchorId);
5837
+ if (!anchorSpec.character || anchorSpec.character.kind === "animation") {
5838
+ throw new Error(`assets.${assetId}: styleCharacter ${anchorId} is not a character base or state`);
5839
+ }
5840
+ const file = memberPath(anchorSpec.outFile, "south", 0, anchorSpec.character.directions, MediaType.PNG);
5841
+ resolved.character = {
5842
+ ...resolved.character,
5843
+ styleAnchor: { assetId: anchorId, spec: anchorSpec, file, sha256: (0, import_node_fs5.existsSync)(file) ? await sha256File(file) : null }
5844
+ };
5845
+ }
5714
5846
  const characterParent = asset.state?.of ?? asset.animation?.of;
5715
5847
  if (resolved.character && characterParent) {
5716
5848
  const parentSpec = await finalize(characterParent);
@@ -5861,8 +5993,13 @@ async function resolveCharacterShape(asset, style, kind, files) {
5861
5993
  ...proportions !== void 0 ? { proportions } : {},
5862
5994
  ...style.textGuidanceScale !== void 0 ? { textGuidanceScale: style.textGuidanceScale } : {},
5863
5995
  ...style.isometric !== void 0 ? { isometric: style.isometric } : {},
5864
- ...style.enhancePrompt !== void 0 ? { enhancePrompt: style.enhancePrompt } : {}
5996
+ ...style.enhancePrompt !== void 0 ? { enhancePrompt: style.enhancePrompt } : {},
5997
+ ...style.styleTraits ? { styleTraits: style.styleTraits } : {}
5865
5998
  };
5999
+ if (asset.concept) {
6000
+ const image = await files.load(asset.concept, "Concept image");
6001
+ shape.concept = { path: import_node_path5.default.resolve(files.root, asset.concept), sha256: image.hash, width: image.width, height: image.height, format: image.format };
6002
+ }
5866
6003
  if (asset.reference) {
5867
6004
  const byDirection = typeof asset.reference === "string" ? { south: asset.reference } : asset.reference;
5868
6005
  shape.reference = {};
@@ -7382,9 +7519,24 @@ var import_node_path11 = __toESM(require("path"), 1);
7382
7519
  async function inspectRevisionReadiness(spec, lock) {
7383
7520
  if (spec.mirror) return inspectMirror(spec, lock, /* @__PURE__ */ new Set());
7384
7521
  if (spec.character?.parentSpec) return inspectCharacterParent(spec, lock, /* @__PURE__ */ new Set());
7522
+ if (spec.character?.styleAnchor) return inspectStyleAnchor(spec, lock, /* @__PURE__ */ new Set());
7385
7523
  if (!spec.revision) return null;
7386
7524
  return inspectRevision(spec, lock, /* @__PURE__ */ new Set());
7387
7525
  }
7526
+ async function inspectStyleAnchor(spec, lock, seen) {
7527
+ const anchor = spec.character.styleAnchor;
7528
+ const label = `style anchor ${spec.styleId}/${anchor.assetId}`;
7529
+ const dependency = await inspectParent(anchor.spec, lock, seen);
7530
+ if (!dependency.ready) return { ready: false, reason: `${label} is not ready: ${dependency.reason}` };
7531
+ if (!anchor.sha256 || !(0, import_node_fs8.existsSync)(anchor.file)) return { ready: false, reason: `${label} has no generated south-facing file yet` };
7532
+ if (await sha256File(anchor.file) !== anchor.sha256) {
7533
+ return { ready: false, reason: `${label} changed after the manifest was resolved` };
7534
+ }
7535
+ if (!lock.entries[lockKey(anchor.spec.styleId, anchor.spec.assetId)]?.objectId) {
7536
+ return { ready: false, reason: `${label} has no PixelLab character id recorded` };
7537
+ }
7538
+ return { ready: true, reason: `${label} is current` };
7539
+ }
7388
7540
  async function inspectMirror(spec, lock, seen) {
7389
7541
  const source = spec.mirror.sourceSpec;
7390
7542
  const label = `mirror source ${spec.styleId}/${spec.mirror.sourceAssetId}`;
@@ -7456,6 +7608,10 @@ async function inspectParent(spec, lock, seen) {
7456
7608
  const inputs = await inspectCharacterParent(spec, lock, nextSeen);
7457
7609
  if (!inputs.ready) return inputs;
7458
7610
  }
7611
+ if (spec.character?.styleAnchor) {
7612
+ const inputs = await inspectStyleAnchor(spec, lock, nextSeen);
7613
+ if (!inputs.ready) return inputs;
7614
+ }
7459
7615
  if (spec.quality) {
7460
7616
  const quality = await inspectQualityProfile(spec, lock);
7461
7617
  return quality?.state === "approved" ? { ready: true, reason: "approved quality output is current" } : {
@@ -7495,6 +7651,14 @@ async function anyOutputModified(entry, spec) {
7495
7651
  }
7496
7652
  return false;
7497
7653
  }
7654
+ function dependencies(spec) {
7655
+ return [
7656
+ spec.mirror?.sourceSpec,
7657
+ spec.revision?.sourceSpec,
7658
+ spec.character?.parentSpec,
7659
+ spec.character?.styleAnchor?.spec
7660
+ ].filter((parent) => Boolean(parent));
7661
+ }
7498
7662
  function resumeCommandForStatus(status) {
7499
7663
  if (status === "pending" || status === "processing") return "poll";
7500
7664
  if (status === "review") return "pick";
@@ -7603,16 +7767,19 @@ async function buildPlan(specs, lock, opts = {}) {
7603
7767
  const stateOf = new Map(items.map((i) => [i.key, i.state]));
7604
7768
  for (const item of items) {
7605
7769
  if (!isActionable(item)) continue;
7606
- const parent = item.spec.mirror?.sourceSpec ?? item.spec.revision?.sourceSpec ?? item.spec.character?.parentSpec;
7607
- if (!parent) continue;
7608
- const parentKey = lockKey(parent.styleId, parent.assetId);
7609
- const parentState = stateOf.get(parentKey);
7610
- if (parentState && isActionable({ state: parentState })) {
7611
- item.state = "blocked";
7612
- item.reason = `parent ${parentKey} is being generated in this run; this follows in the next wave`;
7613
- } else if (item.spec.mirror && (parentState === "recoverable" || parentState === "in-flight")) {
7614
- item.state = "blocked";
7615
- item.reason = `mirror source ${parentKey} is ${parentState}; this follows in the next wave`;
7770
+ for (const parent of dependencies(item.spec)) {
7771
+ const parentKey = lockKey(parent.styleId, parent.assetId);
7772
+ const parentState = stateOf.get(parentKey);
7773
+ if (parentState && isActionable({ state: parentState })) {
7774
+ item.state = "blocked";
7775
+ item.reason = `parent ${parentKey} is being generated in this run; this follows in the next wave`;
7776
+ break;
7777
+ }
7778
+ if (item.spec.mirror && (parentState === "recoverable" || parentState === "in-flight")) {
7779
+ item.state = "blocked";
7780
+ item.reason = `mirror source ${parentKey} is ${parentState}; this follows in the next wave`;
7781
+ break;
7782
+ }
7616
7783
  }
7617
7784
  }
7618
7785
  const actionable = items.filter(isActionable);
@@ -10091,10 +10258,13 @@ async function submit(provider, loaded, items, lock, lockPath, opts = {}) {
10091
10258
  try {
10092
10259
  const refs = styleImages.get(spec.styleId) ?? [];
10093
10260
  const parentEntry = spec.character?.parentSpec ? lock.entries[lockKey(spec.character.parentSpec.styleId, spec.character.parentSpec.assetId)] : void 0;
10261
+ const anchor = spec.character?.styleAnchor;
10262
+ const anchorEntry = anchor ? lock.entries[lockKey(anchor.spec.styleId, anchor.spec.assetId)] : void 0;
10094
10263
  const replacedMetadata = previousEntry?.providerMetadata?.[provider.id];
10095
10264
  const { jobId, metadata } = await provider.submit(spec, refs, {
10096
10265
  ...previousJobId ? { previousJobId } : {},
10097
10266
  ...parentEntry?.objectId ? { parentObjectId: parentEntry.objectId } : {},
10267
+ ...anchorEntry?.objectId ? { styleObjectId: anchorEntry.objectId } : {},
10098
10268
  ...replacedMetadata ? { replacedMetadata } : {},
10099
10269
  ...previousMetadata ? { previousMetadata } : {},
10100
10270
  checkpoint: async (checkpoint) => {
@@ -12703,7 +12873,7 @@ var pin_default = {
12703
12873
  godot: "4.7.2",
12704
12874
  extensionsApi: 9,
12705
12875
  protocol: 4,
12706
- release: "editor-pixelorama-v1.2.2-pk.18",
12876
+ release: "editor-pixelorama-v1.2.2-pk.26",
12707
12877
  files: {
12708
12878
  "index.apple-touch-icon.png": {
12709
12879
  sha256: "ee5434873e0fed91e9a888c3ea5a8b79beac25999308be7a6eb41bf4ce640d27",
@@ -12718,7 +12888,7 @@ var pin_default = {
12718
12888
  bytes: 7298
12719
12889
  },
12720
12890
  "index.html": {
12721
- sha256: "d9adf06036660c4b76ef5386e872bc03dc0d5b0628fd6ac660d480893ee1f47a",
12891
+ sha256: "326101ab02bb4a29a7964214c9307c7dff26e9d66b8ebaaf6e7a3987e84a05b2",
12722
12892
  bytes: 5442
12723
12893
  },
12724
12894
  "index.icon.png": {
@@ -12730,8 +12900,8 @@ var pin_default = {
12730
12900
  bytes: 279815
12731
12901
  },
12732
12902
  "index.pck": {
12733
- sha256: "a41d9c3a39aa99ea5ee49ddcedfeb8b092006aa75c0de67139f13297c17f42e4",
12734
- bytes: 6431692
12903
+ sha256: "e26292650bb996965acd1ba70e74d2b4020b063d14f1276701312c1d34cb0a83",
12904
+ bytes: 6431932
12735
12905
  },
12736
12906
  "index.png": {
12737
12907
  sha256: "6e3ca3eb4a99e4c07bdd89ebc873b440ec0ffd66ce1955160da9e7ed80d538d7",