@clockworkdog/cogs-client 3.0.0-alpha.8 → 3.0.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.
Files changed (42) hide show
  1. package/README.md +20 -9
  2. package/dist/CogsConnection.d.ts +0 -4
  3. package/dist/CogsConnection.js +0 -10
  4. package/dist/browser/index.mjs +1871 -2773
  5. package/dist/browser/index.umd.js +13 -13
  6. package/dist/index.d.ts +1 -7
  7. package/dist/index.js +1 -5
  8. package/dist/state-based/MediaClipManager.d.ts +66 -0
  9. package/dist/state-based/MediaClipManager.js +420 -0
  10. package/dist/state-based/MediaPreloader.d.ts +2 -2
  11. package/dist/state-based/MediaPreloader.js +10 -3
  12. package/dist/state-based/SurfaceManager.d.ts +5 -1
  13. package/dist/state-based/SurfaceManager.js +31 -10
  14. package/dist/types/MediaSchema.d.ts +19 -13
  15. package/dist/types/MediaSchema.js +3 -1
  16. package/dist/utils/device.d.ts +2 -0
  17. package/dist/utils/device.js +4 -0
  18. package/dist/utils/getStateAtTime.d.ts +12 -2
  19. package/dist/utils/getStateAtTime.js +6 -1
  20. package/dist/utils/modulo.d.ts +6 -0
  21. package/dist/utils/modulo.js +17 -0
  22. package/package.json +3 -6
  23. package/dist/AudioPlayer.d.ts +0 -49
  24. package/dist/AudioPlayer.js +0 -474
  25. package/dist/VideoPlayer.d.ts +0 -49
  26. package/dist/VideoPlayer.js +0 -385
  27. package/dist/state-based/AudioManager.d.ts +0 -17
  28. package/dist/state-based/AudioManager.js +0 -114
  29. package/dist/state-based/ClipManager.d.ts +0 -23
  30. package/dist/state-based/ClipManager.js +0 -60
  31. package/dist/state-based/ImageManager.d.ts +0 -9
  32. package/dist/state-based/ImageManager.js +0 -54
  33. package/dist/state-based/VideoManager.d.ts +0 -19
  34. package/dist/state-based/VideoManager.js +0 -215
  35. package/dist/types/AllMediaClipStatesMessage.d.ts +0 -5
  36. package/dist/types/AllMediaClipStatesMessage.js +0 -1
  37. package/dist/types/AudioState.d.ts +0 -39
  38. package/dist/types/AudioState.js +0 -1
  39. package/dist/types/MediaClipStateMessage.d.ts +0 -7
  40. package/dist/types/MediaClipStateMessage.js +0 -1
  41. package/dist/types/VideoState.d.ts +0 -26
  42. package/dist/types/VideoState.js +0 -5
@@ -7,7 +7,7 @@ declare const TemporalProperties: z.ZodObject<{
7
7
  export type VisualProperties = z.infer<typeof VisualProperties>;
8
8
  declare const VisualProperties: z.ZodObject<{
9
9
  opacity: z.ZodNumber;
10
- zIndex: z.ZodNumber;
10
+ zIndex: z.ZodDefault<z.ZodNumber>;
11
11
  }, z.core.$strip>;
12
12
  export type AudialProperties = z.infer<typeof AudialProperties>;
13
13
  declare const AudialProperties: z.ZodObject<{
@@ -24,12 +24,14 @@ declare const AudioMetadata: z.ZodObject<{
24
24
  type: z.ZodLiteral<"audio">;
25
25
  file: z.ZodString;
26
26
  audioOutput: z.ZodString;
27
+ enablePlaybackRateAdjustment: z.ZodBoolean;
27
28
  }, z.core.$strip>;
28
29
  export type VideoMetadata = z.infer<typeof VideoMetadata>;
29
30
  declare const VideoMetadata: z.ZodObject<{
30
31
  type: z.ZodLiteral<"video">;
31
32
  file: z.ZodString;
32
33
  audioOutput: z.ZodString;
34
+ enablePlaybackRateAdjustment: z.ZodBoolean;
33
35
  fit: z.ZodUnion<readonly [z.ZodLiteral<"contain">, z.ZodLiteral<"cover">, z.ZodLiteral<"none">]>;
34
36
  }, z.core.$strip>;
35
37
  export type NullKeyframe = z.infer<typeof NullKeyframe>;
@@ -41,7 +43,7 @@ export type InitialImageKeyframe = z.infer<typeof InitialImageKeyframe>;
41
43
  declare const InitialImageKeyframe: z.ZodTuple<[z.ZodNumber, z.ZodObject<{
42
44
  set: z.ZodOptional<z.ZodObject<{
43
45
  opacity: z.ZodOptional<z.ZodNumber>;
44
- zIndex: z.ZodOptional<z.ZodNumber>;
46
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
45
47
  }, z.core.$strip>>;
46
48
  }, z.core.$strip>], null>;
47
49
  /**
@@ -51,11 +53,11 @@ export type ImageKeyframe = z.infer<typeof ImageKeyframe>;
51
53
  declare const ImageKeyframe: z.ZodTuple<[z.ZodNumber, z.ZodObject<{
52
54
  set: z.ZodOptional<z.ZodObject<{
53
55
  opacity: z.ZodOptional<z.ZodNumber>;
54
- zIndex: z.ZodOptional<z.ZodNumber>;
56
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
55
57
  }, z.core.$strip>>;
56
58
  lerp: z.ZodOptional<z.ZodObject<{
57
59
  opacity: z.ZodOptional<z.ZodNumber>;
58
- zIndex: z.ZodOptional<z.ZodNumber>;
60
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
59
61
  }, z.core.$strip>>;
60
62
  }, z.core.$strip>], null>;
61
63
  /**
@@ -90,7 +92,7 @@ export type InitialVideoKeyframe = z.infer<typeof InitialVideoKeyframe>;
90
92
  declare const InitialVideoKeyframe: z.ZodTuple<[z.ZodNumber, z.ZodObject<{
91
93
  set: z.ZodOptional<z.ZodObject<{
92
94
  opacity: z.ZodOptional<z.ZodNumber>;
93
- zIndex: z.ZodOptional<z.ZodNumber>;
95
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
94
96
  volume: z.ZodOptional<z.ZodNumber>;
95
97
  t: z.ZodOptional<z.ZodNumber>;
96
98
  rate: z.ZodOptional<z.ZodNumber>;
@@ -103,14 +105,14 @@ export type VideoKeyframe = z.infer<typeof VideoKeyframe>;
103
105
  declare const VideoKeyframe: z.ZodTuple<[z.ZodNumber, z.ZodObject<{
104
106
  set: z.ZodOptional<z.ZodObject<{
105
107
  opacity: z.ZodOptional<z.ZodNumber>;
106
- zIndex: z.ZodOptional<z.ZodNumber>;
108
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
107
109
  volume: z.ZodOptional<z.ZodNumber>;
108
110
  t: z.ZodOptional<z.ZodNumber>;
109
111
  rate: z.ZodOptional<z.ZodNumber>;
110
112
  }, z.core.$strip>>;
111
113
  lerp: z.ZodOptional<z.ZodObject<{
112
114
  opacity: z.ZodOptional<z.ZodNumber>;
113
- zIndex: z.ZodOptional<z.ZodNumber>;
115
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
114
116
  volume: z.ZodOptional<z.ZodNumber>;
115
117
  }, z.core.$strip>>;
116
118
  }, z.core.$strip>], null>;
@@ -118,16 +120,16 @@ export declare const MediaSurfaceStateSchema: z.ZodRecord<z.ZodString, z.ZodUnio
118
120
  keyframes: z.ZodTuple<[z.ZodTuple<[z.ZodNumber, z.ZodObject<{
119
121
  set: z.ZodOptional<z.ZodObject<{
120
122
  opacity: z.ZodOptional<z.ZodNumber>;
121
- zIndex: z.ZodOptional<z.ZodNumber>;
123
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
122
124
  }, z.core.$strip>>;
123
125
  lerp: z.ZodOptional<z.ZodObject<{
124
126
  opacity: z.ZodOptional<z.ZodNumber>;
125
- zIndex: z.ZodOptional<z.ZodNumber>;
127
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
126
128
  }, z.core.$strip>>;
127
129
  }, z.core.$strip>], null>], z.ZodUnion<readonly [z.ZodTuple<[z.ZodNumber, z.ZodObject<{
128
130
  set: z.ZodOptional<z.ZodObject<{
129
131
  opacity: z.ZodOptional<z.ZodNumber>;
130
- zIndex: z.ZodOptional<z.ZodNumber>;
132
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
131
133
  }, z.core.$strip>>;
132
134
  }, z.core.$strip>], null>, z.ZodTuple<[z.ZodNumber, z.ZodNull], null>]>>;
133
135
  type: z.ZodLiteral<"image">;
@@ -153,24 +155,25 @@ export declare const MediaSurfaceStateSchema: z.ZodRecord<z.ZodString, z.ZodUnio
153
155
  type: z.ZodLiteral<"audio">;
154
156
  file: z.ZodString;
155
157
  audioOutput: z.ZodString;
158
+ enablePlaybackRateAdjustment: z.ZodBoolean;
156
159
  }, z.core.$strip>, z.ZodObject<{
157
160
  keyframes: z.ZodTuple<[z.ZodTuple<[z.ZodNumber, z.ZodObject<{
158
161
  set: z.ZodOptional<z.ZodObject<{
159
162
  opacity: z.ZodOptional<z.ZodNumber>;
160
- zIndex: z.ZodOptional<z.ZodNumber>;
163
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
161
164
  volume: z.ZodOptional<z.ZodNumber>;
162
165
  t: z.ZodOptional<z.ZodNumber>;
163
166
  rate: z.ZodOptional<z.ZodNumber>;
164
167
  }, z.core.$strip>>;
165
168
  lerp: z.ZodOptional<z.ZodObject<{
166
169
  opacity: z.ZodOptional<z.ZodNumber>;
167
- zIndex: z.ZodOptional<z.ZodNumber>;
170
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
168
171
  volume: z.ZodOptional<z.ZodNumber>;
169
172
  }, z.core.$strip>>;
170
173
  }, z.core.$strip>], null>], z.ZodUnion<readonly [z.ZodTuple<[z.ZodNumber, z.ZodObject<{
171
174
  set: z.ZodOptional<z.ZodObject<{
172
175
  opacity: z.ZodOptional<z.ZodNumber>;
173
- zIndex: z.ZodOptional<z.ZodNumber>;
176
+ zIndex: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
174
177
  volume: z.ZodOptional<z.ZodNumber>;
175
178
  t: z.ZodOptional<z.ZodNumber>;
176
179
  rate: z.ZodOptional<z.ZodNumber>;
@@ -179,6 +182,7 @@ export declare const MediaSurfaceStateSchema: z.ZodRecord<z.ZodString, z.ZodUnio
179
182
  type: z.ZodLiteral<"video">;
180
183
  file: z.ZodString;
181
184
  audioOutput: z.ZodString;
185
+ enablePlaybackRateAdjustment: z.ZodBoolean;
182
186
  fit: z.ZodUnion<readonly [z.ZodLiteral<"contain">, z.ZodLiteral<"cover">, z.ZodLiteral<"none">]>;
183
187
  }, z.core.$strip>]>>;
184
188
  export type ImageOptions = VisualProperties;
@@ -194,6 +198,7 @@ export type AudioState = {
194
198
  type: 'audio';
195
199
  file: string;
196
200
  audioOutput: string;
201
+ enablePlaybackRateAdjustment: boolean;
197
202
  keyframes: [InitialAudioKeyframe, ...Array<AudioKeyframe | NullKeyframe>];
198
203
  };
199
204
  export type VideoState = {
@@ -201,6 +206,7 @@ export type VideoState = {
201
206
  file: string;
202
207
  fit: 'cover' | 'contain' | 'none';
203
208
  audioOutput: string;
209
+ enablePlaybackRateAdjustment: boolean;
204
210
  keyframes: [InitialVideoKeyframe, ...Array<VideoKeyframe | NullKeyframe>];
205
211
  };
206
212
  export type MediaClipState = ImageState | AudioState | VideoState;
@@ -5,7 +5,7 @@ const TemporalProperties = z.object({
5
5
  });
6
6
  const VisualProperties = z.object({
7
7
  opacity: z.number().gte(0).lte(1),
8
- zIndex: z.number(),
8
+ zIndex: z.number().default(0),
9
9
  });
10
10
  const AudialProperties = z.object({
11
11
  volume: z.number().gte(0).lte(1),
@@ -19,11 +19,13 @@ const AudioMetadata = z.object({
19
19
  type: z.literal('audio'),
20
20
  file: z.string(),
21
21
  audioOutput: z.string(),
22
+ enablePlaybackRateAdjustment: z.boolean(),
22
23
  });
23
24
  const VideoMetadata = z.object({
24
25
  type: z.literal('video'),
25
26
  file: z.string(),
26
27
  audioOutput: z.string(),
28
+ enablePlaybackRateAdjustment: z.boolean(),
27
29
  fit: z.union([z.literal('contain'), z.literal('cover'), z.literal('none')]),
28
30
  });
29
31
  const NullKeyframe = z.tuple([z.number(), z.null()]);
@@ -0,0 +1,2 @@
1
+ export declare const IS_IOS: boolean;
2
+ export declare const IS_WEBKIT: boolean;
@@ -0,0 +1,4 @@
1
+ // Check an iOS-only property (See https://developer.mozilla.org/en-US/docs/Web/API/Navigator#non-standard_properties)
2
+ export const IS_IOS = typeof navigator !== 'undefined' && typeof navigator.standalone !== 'undefined';
3
+ // https://evilmartians.com/chronicles/how-to-detect-safari-and-ios-versions-with-ease
4
+ export const IS_WEBKIT = 'GestureEvent' in window;
@@ -1,5 +1,15 @@
1
- import { MediaClipState, TemporalProperties } from '../types/MediaSchema';
2
- export declare function getStateAtTime<State extends MediaClipState>(state: State, time: number): State['keyframes'][0][1]['set'] | undefined;
1
+ import { AudioState, ImageState, TemporalProperties, VideoState } from '../types/MediaSchema';
2
+ export type MinimalClipState = {
3
+ type: 'image';
4
+ keyframes: ImageState['keyframes'];
5
+ } | {
6
+ type: 'audio';
7
+ keyframes: AudioState['keyframes'];
8
+ } | {
9
+ type: 'video';
10
+ keyframes: VideoState['keyframes'];
11
+ };
12
+ export declare function getStateAtTime<State extends MinimalClipState>(state: State, time: number): State['keyframes'][0][1]['set'] | undefined;
3
13
  /**
4
14
  * Goes through all keyframes to lerp between many different properties
5
15
  * Note: This has no specific logic regarding types of properties
@@ -1,5 +1,10 @@
1
- import { defaultAudioOptions, defaultImageOptions, defaultVideoOptions } from '../types/MediaSchema';
1
+ import { defaultAudioOptions, defaultImageOptions, defaultVideoOptions, } from '../types/MediaSchema';
2
2
  export function getStateAtTime(state, time) {
3
+ //If there are any null keyframes the clip has been terminated
4
+ const nullKeyframes = state.keyframes.filter((kf) => kf[1] === null);
5
+ if (nullKeyframes.some((kf) => kf[0] <= time)) {
6
+ return undefined;
7
+ }
3
8
  switch (state.type) {
4
9
  case 'image': {
5
10
  const firstTimestamp = state.keyframes[0][0];
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Correct modulo operator
3
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder#description
4
+ */
5
+ export declare function modulo(n: number, divisor: number): number;
6
+ export declare function moduloDiff(n: number, m: number, divisor: number): number;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Correct modulo operator
3
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Remainder#description
4
+ */
5
+ export function modulo(n, divisor) {
6
+ return ((n % divisor) + divisor) % divisor;
7
+ }
8
+ export function moduloDiff(n, m, divisor) {
9
+ n = modulo(n, divisor);
10
+ m = modulo(m, divisor);
11
+ if (Math.abs(n - m) < divisor / 2) {
12
+ return n - m;
13
+ }
14
+ else {
15
+ return n < m ? n + divisor - m : n - (m + divisor);
16
+ }
17
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Connect to COGS to build a custom Media Master",
4
4
  "author": "Clockwork Dog <info@clockwork.dog>",
5
5
  "homepage": "https://github.com/clockwork-dog/cogs-sdk/tree/main/packages/javascript",
6
- "version": "3.0.0-alpha.8",
6
+ "version": "3.0.0",
7
7
  "keywords": [],
8
8
  "license": "MIT",
9
9
  "repository": {
@@ -37,15 +37,13 @@
37
37
  "cy:generate": "cypress run --e2e"
38
38
  },
39
39
  "dependencies": {
40
- "@clockworkdog/timesync": "^3.0.0-alpha.8",
41
- "howler": "clockwork-dog/howler.js#fix-looping-clips",
40
+ "@clockworkdog/timesync": "^3.0.0",
42
41
  "reconnecting-websocket": "^4.4.0",
43
42
  "zod": "^4.1.13"
44
43
  },
45
44
  "devDependencies": {
46
45
  "@cypress/mount-utils": "^4.1.2",
47
46
  "@eslint/js": "^9.17.0",
48
- "@types/howler": "2.2.12",
49
47
  "@types/jsdom": "^27",
50
48
  "@types/node": "^22.10.2",
51
49
  "cypress": "^14.5.4",
@@ -62,6 +60,5 @@
62
60
  "typescript-eslint": "^8.18.1",
63
61
  "vite": "^7.1.12",
64
62
  "vitest": "^4.0.6"
65
- },
66
- "stableVersion": "0.0.0"
63
+ }
67
64
  }
@@ -1,49 +0,0 @@
1
- import CogsConnection from './CogsConnection';
2
- import { AudioState } from './types/AudioState';
3
- import MediaClipStateMessage from './types/MediaClipStateMessage';
4
- type EventTypes = {
5
- state: AudioState;
6
- audioClipState: MediaClipStateMessage;
7
- };
8
- export default class AudioPlayer {
9
- private cogsConnection;
10
- private eventTarget;
11
- private globalVolume;
12
- private audioClipPlayers;
13
- private sinkId;
14
- constructor(cogsConnection: CogsConnection<any>);
15
- setGlobalVolume(volume: number): void;
16
- playAudioClip(path: string, { playId, volume, fade, loop }: {
17
- playId: string;
18
- volume: number;
19
- fade?: number;
20
- loop: boolean;
21
- }): void;
22
- pauseAudioClip(path: string, { fade }: {
23
- fade?: number;
24
- }, onlySoundId?: number, allowIfPauseRequested?: boolean): void;
25
- stopAudioClip(path: string, { fade }: {
26
- fade?: number;
27
- }, onlySoundId?: number, allowIfStopRequested?: boolean): void;
28
- stopAllAudioClips(options: {
29
- fade?: number;
30
- }): void;
31
- setAudioClipVolume(path: string, { volume, fade }: {
32
- volume: number;
33
- fade?: number;
34
- }): void;
35
- private handleStoppedClip;
36
- private updateActiveAudioClip;
37
- private updateAudioClipPlayer;
38
- setAudioSink(sinkId: string): void;
39
- private updateConfig;
40
- private notifyStateListeners;
41
- private notifyClipStateListeners;
42
- addEventListener<EventName extends keyof EventTypes>(type: EventName, listener: (ev: CustomEvent<EventTypes[EventName]>) => void, options?: boolean | AddEventListenerOptions): void;
43
- removeEventListener<EventName extends keyof EventTypes>(type: EventName, listener: (ev: CustomEvent<EventTypes[EventName]>) => void, options?: boolean | EventListenerOptions): void;
44
- private dispatchEvent;
45
- private createPlayer;
46
- private createClip;
47
- private updatedClip;
48
- }
49
- export {};