@lingjingai/scriptctl 0.10.1 → 0.10.3

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.
@@ -2929,6 +2929,7 @@ export function mergeEpisodeResults(results, title) {
2929
2929
  };
2930
2930
  const sortedResults = [...results].sort((a, b) => Number(a["episode"] ?? 0) - Number(b["episode"] ?? 0));
2931
2931
  const episodes = [];
2932
+ const usedEpisodeIds = new Set();
2932
2933
  let sceneCounter = 0;
2933
2934
  for (const result of sortedResults) {
2934
2935
  const scenes = [];
@@ -3031,8 +3032,22 @@ export function mergeEpisodeResults(results, title) {
3031
3032
  actions,
3032
3033
  });
3033
3034
  }
3035
+ // episode_id is normally derived from the parsed source number (第N集), but
3036
+ // that number is NOT guaranteed unique — ambiguous/duplicate headers (two
3037
+ // "第1集", a recap, etc.) can parse to the same number and would otherwise
3038
+ // emit two ep_001, which violates the DB's unique episode constraint on push.
3039
+ // Keep the number-based id when free; on collision, fall back to the next
3040
+ // free sequential slot. The title still carries the original number.
3041
+ let episodeId = fmtId("ep", Number(result["episode"] ?? episodes.length + 1));
3042
+ if (usedEpisodeIds.has(episodeId)) {
3043
+ let n = episodes.length + 1;
3044
+ while (usedEpisodeIds.has(fmtId("ep", n)))
3045
+ n++;
3046
+ episodeId = fmtId("ep", n);
3047
+ }
3048
+ usedEpisodeIds.add(episodeId);
3034
3049
  episodes.push({
3035
- episode_id: fmtId("ep", Number(result["episode"] ?? episodes.length + 1)),
3050
+ episode_id: episodeId,
3036
3051
  title: result["title"],
3037
3052
  scenes,
3038
3053
  });