route-graphics 1.42.2 → 1.43.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.
@@ -3618,6 +3618,7 @@ var AUDIO_TRANSITION_PROPERTY_RANGES = {
3618
3618
  };
3619
3619
  var AUDIO_EASINGS = new Set(SUPPORTED_EASING_NAMES);
3620
3620
  var AUDIO_TRANSITION_PHASE_KEYS = /* @__PURE__ */ new Set(["initialValue", "keyframes"]);
3621
+ var AUDIO_BOUNDARY_EFFECT_KEYS = /* @__PURE__ */ new Set(["keyframes"]);
3621
3622
  var AUDIO_TRANSITION_KEYFRAME_KEYS = /* @__PURE__ */ new Set([
3622
3623
  "value",
3623
3624
  "startValue",
@@ -3754,11 +3755,23 @@ var validateSound = (node, path5, ids, flattenedSounds, channelId = null) => {
3754
3755
  );
3755
3756
  }
3756
3757
  const playback = node.playback === void 0 ? void 0 : normalizePlaybackCommand(node.playback, `${path5}.playback`);
3758
+ if (playback && (node.beginEffect || node.endEffect)) {
3759
+ throw new Error(
3760
+ `Input error: ${path5}.beginEffect and ${path5}.endEffect are not supported with transport-controlled playback.`
3761
+ );
3762
+ }
3757
3763
  if (node.transition !== void 0) {
3758
3764
  throw new Error(
3759
3765
  `Input error: ${path5}.transition is not supported. Use top-level audioEffects instead.`
3760
3766
  );
3761
3767
  }
3768
+ for (const field of ["beginEffect", "endEffect"]) {
3769
+ if (node[field] !== void 0) {
3770
+ validateSoundBoundaryEffect(node[field], `${path5}.${field}`, {
3771
+ endEffect: field === "endEffect"
3772
+ });
3773
+ }
3774
+ }
3762
3775
  flattenedSounds.push({
3763
3776
  id: node.id,
3764
3777
  type: "sound",
@@ -3772,7 +3785,9 @@ var validateSound = (node, path5, ids, flattenedSounds, channelId = null) => {
3772
3785
  startAt: node.startAt ?? 0,
3773
3786
  endAt: node.endAt ?? null,
3774
3787
  channelId,
3775
- ...playback ? { playback } : {}
3788
+ ...playback ? { playback } : {},
3789
+ ...node.beginEffect ? { beginEffect: structuredClone(node.beginEffect) } : {},
3790
+ ...node.endEffect ? { endEffect: structuredClone(node.endEffect) } : {}
3776
3791
  });
3777
3792
  };
3778
3793
  var validateChannel = (node, path5, ids, flattenedChannels, flattenedSounds) => {
@@ -3943,6 +3958,47 @@ var validateTransitionPhase = (phase, path5, propertyName) => {
3943
3958
  assertOptionalBoolean(keyframe.relative, `${keyframePath}.relative`);
3944
3959
  }
3945
3960
  };
3961
+ var getBoundaryTrackDurationMs = (track) => track.keyframes.reduce(
3962
+ (duration, keyframe) => duration + (keyframe.delay ?? 0) + keyframe.duration,
3963
+ 0
3964
+ );
3965
+ function validateSoundBoundaryEffect(effect, path5, { endEffect = false } = {}) {
3966
+ assertNonEmptyRecord(effect, path5);
3967
+ for (const [propertyName, track] of Object.entries(effect)) {
3968
+ if (!AUDIO_TRANSITION_PROPERTIES.has(propertyName)) {
3969
+ throw new Error(
3970
+ `Input error: unsupported sound boundary property "${propertyName}" at ${path5}.`
3971
+ );
3972
+ }
3973
+ assertRecord(track, `${path5}.${propertyName}`);
3974
+ for (const key of Object.keys(track)) {
3975
+ if (!AUDIO_BOUNDARY_EFFECT_KEYS.has(key)) {
3976
+ throw new Error(
3977
+ `Input error: unsupported sound boundary field "${key}" at ${path5}.${propertyName}.`
3978
+ );
3979
+ }
3980
+ }
3981
+ validateTransitionPhase(track, `${path5}.${propertyName}`, propertyName);
3982
+ if (track.keyframes.at(-1).relative === true) {
3983
+ throw new Error(
3984
+ `Input error: ${path5}.${propertyName}.keyframes must end with an absolute value.`
3985
+ );
3986
+ }
3987
+ }
3988
+ const playbackRateTrack = effect.playbackRate;
3989
+ if (!endEffect || playbackRateTrack?.keyframes.at(-1).value !== 0) {
3990
+ return;
3991
+ }
3992
+ const playbackRateDurationMs = getBoundaryTrackDurationMs(playbackRateTrack);
3993
+ const effectDurationMs = Math.max(
3994
+ ...Object.values(effect).map(getBoundaryTrackDurationMs)
3995
+ );
3996
+ if (playbackRateDurationMs < effectDurationMs) {
3997
+ throw new Error(
3998
+ `Input error: ${path5}.playbackRate cannot end at 0 before the other boundary tracks finish.`
3999
+ );
4000
+ }
4001
+ }
3946
4002
  var validateAudioTransition = (effect, path5) => {
3947
4003
  assertNonEmptyString3(effect.targetId, `${path5}.targetId`);
3948
4004
  assertNonEmptyRecord(effect.properties, `${path5}.properties`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "route-graphics",
3
- "version": "1.42.2",
3
+ "version": "1.43.0",
4
4
  "description": "A 2D graphics rendering interface that takes JSON input and renders pixels using PixiJS",
5
5
  "main": "dist/RouteGraphics.js",
6
6
  "type": "module",