@xiboplayer/schedule 0.7.0 → 0.7.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiboplayer/schedule",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Complete scheduling solution: campaigns, dayparting, interrupts, and overlays",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -12,7 +12,7 @@
12
12
  "./overlays": "./src/overlays.js"
13
13
  },
14
14
  "dependencies": {
15
- "@xiboplayer/utils": "0.7.0"
15
+ "@xiboplayer/utils": "0.7.1"
16
16
  },
17
17
  "devDependencies": {
18
18
  "vitest": "^2.0.0"
package/src/index.d.ts CHANGED
@@ -17,5 +17,6 @@ export class ScheduleManager {
17
17
  export const scheduleManager: ScheduleManager;
18
18
 
19
19
  export function calculateTimeline(queue: Array<{layoutId: string, duration: number}>, queuePosition: number, options?: any): any[];
20
+ export function parseLayoutFile(f: string | number): number;
20
21
  export function parseLayoutDuration(xlf: string, videoDurations?: Map<string, number> | null): { duration: number; isDynamic: boolean };
21
22
  export function buildScheduleQueue(schedule: any, durations: Map<string, number>): any[];
package/src/index.js CHANGED
@@ -27,4 +27,4 @@ export { OverlayScheduler } from './overlays.js';
27
27
  * Offline timeline calculator — duration parser + timeline simulator
28
28
  * @module @xiboplayer/schedule/timeline
29
29
  */
30
- export { calculateTimeline, parseLayoutDuration, buildScheduleQueue } from './timeline.js';
30
+ export { calculateTimeline, parseLayoutDuration, parseLayoutFile, buildScheduleQueue } from './timeline.js';
package/src/schedule.js CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { createLogger } from '@xiboplayer/utils';
8
8
  import { evaluateCriteria } from './criteria.js';
9
- import { buildScheduleQueue } from './timeline.js';
9
+ import { buildScheduleQueue, parseLayoutFile } from './timeline.js';
10
10
 
11
11
  const log = createLogger('Schedule');
12
12
 
@@ -63,7 +63,7 @@ export class ScheduleManager {
63
63
  const globalDeps = this.schedule.dependants || [];
64
64
 
65
65
  const addLayout = (layout) => {
66
- const id = parseInt(String(layout.file || layout.id).replace('.xlf', ''), 10);
66
+ const id = parseLayoutFile(layout.file || layout.id);
67
67
  const deps = [...globalDeps, ...(layout.dependants || [])];
68
68
  if (deps.length > 0) map.set(id, deps);
69
69
  };
@@ -691,6 +691,31 @@ export class ScheduleManager {
691
691
  * @param {Object} [options]
692
692
  * @returns {{ layoutId: string, duration: number } | null}
693
693
  */
694
+ /**
695
+ * Get current queue position.
696
+ * @returns {number}
697
+ */
698
+ getQueuePosition() {
699
+ return this._queuePosition;
700
+ }
701
+
702
+ /**
703
+ * Rewind the queue by N positions (wraps around).
704
+ * Used by advanceToPreviousLayout to go back in the schedule.
705
+ * @param {number} steps - Number of positions to rewind
706
+ * @param {Map<string, number>} durations
707
+ * @param {Object} [options]
708
+ * @returns {{ layoutId: string, duration: number } | null}
709
+ */
710
+ rewindQueue(steps, durations, options = {}) {
711
+ const { queue } = this.getScheduleQueue(durations, options);
712
+ if (queue.length === 0) return null;
713
+ this._queuePosition = (this._queuePosition - steps + queue.length * steps) % queue.length;
714
+ const entry = queue[this._queuePosition];
715
+ this._queuePosition = (this._queuePosition + 1) % queue.length;
716
+ return entry;
717
+ }
718
+
694
719
  peekNextInQueue(durations, options = {}) {
695
720
  const { queue } = this.getScheduleQueue(durations, options);
696
721
  if (queue.length === 0) return null;
package/src/timeline.js CHANGED
@@ -27,6 +27,15 @@
27
27
  * @param {Map<string, number>|null} [videoDurations=null] - Optional map of fileId → probed duration in seconds
28
28
  * @returns {{ duration: number, isDynamic: boolean }} Duration in seconds and whether any widget has useDuration=0
29
29
  */
30
+ /**
31
+ * Extract numeric layout ID from a schedule filename like "123.xlf" or "123"
32
+ * @param {string|number} f - Layout file reference
33
+ * @returns {number}
34
+ */
35
+ export function parseLayoutFile(f) {
36
+ return parseInt(String(f).replace('.xlf', ''), 10);
37
+ }
38
+
30
39
  export function parseLayoutDuration(xlfXml, videoDurations = null) {
31
40
  const doc = new DOMParser().parseFromString(xlfXml, 'text/xml');
32
41
  const layoutEl = doc.querySelector('layout');