@xiboplayer/schedule 0.4.0 → 0.4.1

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/timeline.js +13 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiboplayer/schedule",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Complete scheduling solution: campaigns, dayparting, interrupts, and overlays",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -11,7 +11,7 @@
11
11
  "./overlays": "./src/overlays.js"
12
12
  },
13
13
  "dependencies": {
14
- "@xiboplayer/utils": "0.4.0"
14
+ "@xiboplayer/utils": "0.4.1"
15
15
  },
16
16
  "devDependencies": {
17
17
  "vitest": "^2.0.0"
package/src/timeline.js CHANGED
@@ -153,6 +153,7 @@ function getPlayableLayouts(allLayouts, simPlays, timeMs) {
153
153
  * @param {Date} [options.from] - Start time (default: now)
154
154
  * @param {number} [options.hours] - Hours to simulate (default: 2)
155
155
  * @param {number} [options.defaultDuration] - Fallback duration in seconds (default: 60)
156
+ * @param {Date} [options.currentLayoutStartedAt] - When current layout started (adjusts first entry to remaining time)
156
157
  * @returns {Array<{layoutFile: string, startTime: Date, endTime: Date, duration: number, isDefault: boolean}>}
157
158
  */
158
159
  export function calculateTimeline(schedule, durations, options = {}) {
@@ -160,8 +161,10 @@ export function calculateTimeline(schedule, durations, options = {}) {
160
161
  const hours = options.hours || 2;
161
162
  const to = new Date(from.getTime() + hours * 3600000);
162
163
  const defaultDuration = options.defaultDuration || 60;
164
+ const currentLayoutStartedAt = options.currentLayoutStartedAt || null;
163
165
  const timeline = [];
164
166
  let currentTime = new Date(from);
167
+ let isFirstEntry = true;
165
168
 
166
169
  // Use getAllLayoutsAtTime if available (new API), fall back to getLayoutsAtTime (old API)
167
170
  const hasFullApi = typeof schedule.getAllLayoutsAtTime === 'function';
@@ -216,7 +219,16 @@ export function calculateTimeline(schedule, durations, options = {}) {
216
219
  // Round-robin through playable layouts
217
220
  for (let i = 0; i < playable.length && currentTime < to && timeline.length < maxEntries; i++) {
218
221
  const file = playable[i];
219
- const dur = durations.get(file) || defaultDuration;
222
+ let dur = durations.get(file) || defaultDuration;
223
+
224
+ // First entry: use remaining duration if we know when the current layout started
225
+ if (isFirstEntry && currentLayoutStartedAt) {
226
+ const elapsedSec = (from.getTime() - currentLayoutStartedAt.getTime()) / 1000;
227
+ const remaining = Math.max(1, Math.round(dur - elapsedSec));
228
+ dur = remaining;
229
+ isFirstEntry = false;
230
+ }
231
+
220
232
  const endMs = currentTime.getTime() + dur * 1000;
221
233
 
222
234
  const entry = {