@maas/vue-equipment 1.0.0-beta.33 → 1.0.0-beta.35

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 (98) hide show
  1. package/dist/composables/useCountdown/index.d.ts +23 -0
  2. package/dist/composables/useCountdown/index.js +133 -0
  3. package/dist/composables/useCountdown/index.js.map +1 -0
  4. package/dist/composables/useEasings/index.d.ts +21 -0
  5. package/dist/composables/useEasings/index.js +40 -0
  6. package/dist/composables/useEasings/index.js.map +1 -0
  7. package/dist/composables/useMetaViewport/index.d.ts +9 -0
  8. package/dist/composables/useMetaViewport/index.js +29 -0
  9. package/dist/composables/useMetaViewport/index.js.map +1 -0
  10. package/dist/composables/useScrollTo/index.d.ts +49 -0
  11. package/dist/composables/useScrollTo/index.js +148 -0
  12. package/dist/composables/useScrollTo/index.js.map +1 -0
  13. package/dist/nuxt/module.json +1 -1
  14. package/dist/nuxt/module.mjs +22 -9
  15. package/dist/plugins/.turbo/turbo-lint.log +92 -1
  16. package/dist/plugins/MagicAccordion/src/components/MagicAccordionContent.vue +15 -6
  17. package/dist/plugins/MagicAccordion/src/components/MagicAccordionTrigger.vue +15 -10
  18. package/dist/plugins/MagicAccordion/src/components/MagicAccordionView.vue +11 -5
  19. package/dist/plugins/MagicAccordion/src/composables/private/useAccordionCallback.mjs +1 -1
  20. package/dist/plugins/MagicCommand/src/components/MagicCommandContent.vue +15 -8
  21. package/dist/plugins/MagicCommand/src/components/MagicCommandDrawer.vue +13 -7
  22. package/dist/plugins/MagicCommand/src/components/MagicCommandItem.vue +19 -9
  23. package/dist/plugins/MagicCommand/src/components/MagicCommandModal.vue +2 -2
  24. package/dist/plugins/MagicCommand/src/components/MagicCommandRenderer.vue +12 -6
  25. package/dist/plugins/MagicCommand/src/components/MagicCommandTrigger.vue +15 -10
  26. package/dist/plugins/MagicCommand/src/components/MagicCommandView.vue +11 -3
  27. package/dist/plugins/MagicCommand/src/composables/private/useCommandCallback.mjs +1 -1
  28. package/dist/plugins/MagicCommand/src/composables/private/useCommandView.d.ts +1 -1
  29. package/dist/plugins/MagicCommand/src/composables/private/useCommandView.mjs +42 -37
  30. package/dist/plugins/MagicCommand/src/composables/useMagicCommand.mjs +21 -4
  31. package/dist/plugins/MagicCookie/src/components/MagicCookieItem.vue +12 -3
  32. package/dist/plugins/MagicCookie/src/components/MagicCookieView.vue +11 -5
  33. package/dist/plugins/MagicCookie/src/composables/private/useCookieCallback.mjs +1 -1
  34. package/dist/plugins/MagicCookie/src/composables/private/useCookieItem.mjs +6 -1
  35. package/dist/plugins/MagicCookie/src/composables/useMagicCookie.mjs +1 -1
  36. package/dist/plugins/MagicDraggable/src/components/MagicDraggable.vue +11 -1
  37. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableDrag.mjs +9 -4
  38. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableSnap.mjs +8 -3
  39. package/dist/plugins/MagicDraggable/src/composables/useMagicDraggable.mjs +1 -1
  40. package/dist/plugins/MagicDrawer/src/components/MagicDrawer.vue +7 -2
  41. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerCallback.mjs +2 -2
  42. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +7 -2
  43. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerProgress.mjs +1 -1
  44. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerSnap.mjs +1 -1
  45. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerWheel.mjs +6 -1
  46. package/dist/plugins/MagicDrawer/src/composables/useMagicDrawer.mjs +1 -1
  47. package/dist/plugins/MagicError/index.d.ts +5 -0
  48. package/dist/plugins/MagicError/index.mjs +3 -0
  49. package/dist/plugins/MagicError/nuxt.d.ts +2 -0
  50. package/dist/plugins/MagicError/nuxt.mjs +12 -0
  51. package/dist/plugins/MagicError/package.json +40 -0
  52. package/dist/plugins/MagicError/src/MagicError.d.ts +0 -0
  53. package/dist/plugins/MagicError/src/MagicError.mjs +0 -0
  54. package/dist/plugins/MagicError/src/class/MagicError.d.ts +6 -0
  55. package/dist/plugins/MagicError/src/class/MagicError.mjs +15 -0
  56. package/dist/plugins/MagicError/src/composables/useMagicError.d.ts +18 -0
  57. package/dist/plugins/MagicError/src/composables/useMagicError.mjs +31 -0
  58. package/dist/plugins/MagicMenu/src/components/MagicMenuChannel.vue +22 -10
  59. package/dist/plugins/MagicMenu/src/components/MagicMenuContent.vue +15 -6
  60. package/dist/plugins/MagicMenu/src/components/MagicMenuItem.vue +19 -9
  61. package/dist/plugins/MagicMenu/src/components/MagicMenuRemote.vue +19 -13
  62. package/dist/plugins/MagicMenu/src/components/MagicMenuTrigger.vue +15 -10
  63. package/dist/plugins/MagicMenu/src/components/MagicMenuView.vue +11 -3
  64. package/dist/plugins/MagicMenu/src/composables/private/useMenuCallback.mjs +1 -1
  65. package/dist/plugins/MagicMenu/src/composables/private/useMenuItem.mjs +9 -1
  66. package/dist/plugins/MagicMenu/src/composables/private/useMenuKeyListener.mjs +16 -8
  67. package/dist/plugins/MagicMenu/src/composables/private/useMenuView.mjs +7 -2
  68. package/dist/plugins/MagicModal/src/composables/private/useModalCallback.mjs +1 -1
  69. package/dist/plugins/MagicPie/src/components/MagicPie.vue +15 -2
  70. package/dist/plugins/MagicPlayer/src/components/MagicPlayerAudio.vue +17 -7
  71. package/dist/plugins/MagicPlayer/src/components/MagicPlayerAudioControls.vue +11 -5
  72. package/dist/plugins/MagicPlayer/src/components/MagicPlayerDisplayTime.vue +11 -5
  73. package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue +29 -14
  74. package/dist/plugins/MagicPlayer/src/components/MagicPlayerOverlay.vue +11 -5
  75. package/dist/plugins/MagicPlayer/src/components/MagicPlayerPoster.vue +11 -5
  76. package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue +11 -5
  77. package/dist/plugins/MagicPlayer/src/components/MagicPlayerVideo.vue +17 -7
  78. package/dist/plugins/MagicPlayer/src/components/MagicPlayerVideoControls.vue +11 -5
  79. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerEmitter.mjs +1 -1
  80. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerMediaApi.mjs +65 -11
  81. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.d.ts +1 -0
  82. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.mjs +96 -16
  83. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerVideoApi.mjs +7 -2
  84. package/dist/plugins/MagicPlayer/src/types/index.d.ts +2 -0
  85. package/dist/plugins/MagicPlayer/src/utils/defaultOptions.mjs +1 -0
  86. package/dist/plugins/MagicScroll/src/components/MagicScrollCollision.vue +12 -6
  87. package/dist/plugins/MagicScroll/src/components/MagicScrollScene.vue +11 -3
  88. package/dist/plugins/MagicScroll/src/composables/private/useCollisionDetection.mjs +1 -1
  89. package/dist/plugins/MagicToast/src/components/MagicToastView.vue +11 -3
  90. package/dist/plugins/MagicToast/src/composables/private/useToastCallback.d.ts +2 -2
  91. package/dist/plugins/MagicToast/src/composables/private/useToastCallback.mjs +8 -6
  92. package/dist/plugins/MagicToast/src/composables/private/useToastDrag.mjs +1 -1
  93. package/package.json +20 -13
  94. package/dist/composables/index.d.ts +0 -97
  95. package/dist/composables/index.js +0 -344
  96. package/dist/composables/index.js.map +0 -1
  97. package/dist/plugins/index.d.ts +0 -14
  98. package/dist/plugins/index.mjs +0 -14
@@ -25,18 +25,28 @@ import {
25
25
  useTemplateRef
26
26
  } from "vue";
27
27
  import { useDevicePixelRatio } from "@vueuse/core";
28
+ import {
29
+ useMagicError
30
+ } from "@maas/vue-equipment/plugins/MagicError";
28
31
  import { usePlayerState } from "../composables/private/usePlayerState";
29
32
  import { MagicPlayerInstanceId, MagicPlayerOptionsKey } from "../symbols";
30
33
  const { playbackId } = defineProps({
31
34
  playbackId: { type: String, required: false }
32
35
  });
36
+ const magicError = useMagicError({
37
+ prefix: "MagicPlayer",
38
+ source: "MagicPlayerMuxPopover"
39
+ });
33
40
  const instanceId = inject(MagicPlayerInstanceId, void 0);
34
41
  const injectedOptions = inject(MagicPlayerOptionsKey, void 0);
35
- if (!instanceId || !injectedOptions) {
36
- throw new Error(
37
- "MagicPlayerMuxPopover must be nested inside MagicPlayerVideoControls."
38
- );
39
- }
42
+ magicError.assert(instanceId, {
43
+ message: "MagicPlayerMuxPopover must be nested inside MagicPlayerVideoControls",
44
+ errorCode: "missing_instance_id"
45
+ });
46
+ magicError.assert(injectedOptions, {
47
+ message: "MagicPlayerMuxPopover must be nested inside MagicPlayerVideoControls",
48
+ errorCode: "missing_options"
49
+ });
40
50
  const { initializeState } = usePlayerState(instanceId);
41
51
  const state = initializeState();
42
52
  const { seekedTime } = toRefs(state);
@@ -93,25 +103,30 @@ async function initialize() {
93
103
  const parsedPlaybackId = getMuxId(injectedOptions?.src);
94
104
  const mappedPlaybackId = playbackId ?? parsedPlaybackId;
95
105
  if (!mappedPlaybackId) {
96
- console.error(
97
- "MagicPlayerMuxPopover must be nested inside MagicPlayerProvider or a playbackId must be provided"
98
- );
99
- return;
106
+ magicError.throwError({
107
+ errorCode: "missing_instance_id",
108
+ message: "MagicPlayerMuxPopover must be nested inside MagicPlayerProvider or a playbackId must be provided"
109
+ });
100
110
  }
101
111
  try {
102
112
  storyboard.value = await fetch(
103
113
  `https://image.mux.com/${mappedPlaybackId}/storyboard.json`
104
114
  ).then((res) => res.json());
105
- if (!storyboard.value) {
106
- throw new Error();
107
- }
115
+ magicError.assert(storyboard.value, {
116
+ message: "Failed to fetch timeline preview",
117
+ errorCode: "fetch_timeline_error"
118
+ });
108
119
  image = new Image();
109
120
  image.src = storyboard.value.url;
110
121
  await image.decode();
111
122
  context = canvasRef.value?.getContext("2d");
112
123
  drawFrame(seekedTime.value);
113
- } catch (e) {
114
- console.error("Can not initialize timeline preview", e);
124
+ } catch (error) {
125
+ magicError.throwError({
126
+ errorCode: "initialize_timeline_error",
127
+ message: "Can not initialize timeline preview",
128
+ cause: error
129
+ });
115
130
  }
116
131
  }
117
132
  onMounted(() => {
@@ -50,6 +50,9 @@
50
50
  <script setup>
51
51
  import { watch, ref, computed, inject, toRefs } from "vue";
52
52
  import { useIdle } from "@vueuse/core";
53
+ import {
54
+ useMagicError
55
+ } from "@maas/vue-equipment/plugins/MagicError";
53
56
  import IconPlay from "./icons/Play.vue";
54
57
  import IconPause from "./icons/Pause.vue";
55
58
  import IconWaiting from "./icons/Waiting.vue";
@@ -59,13 +62,16 @@ import { MagicPlayerInstanceId, MagicPlayerOptionsKey } from "../symbols";
59
62
  const { transition } = defineProps({
60
63
  transition: { type: Object, required: false }
61
64
  });
65
+ const magicError = useMagicError({
66
+ prefix: "MagicPlayer",
67
+ source: "MagicPlayerOverlay"
68
+ });
62
69
  const instanceId = inject(MagicPlayerInstanceId, void 0);
63
70
  const injectedOptions = inject(MagicPlayerOptionsKey, void 0);
64
- if (!instanceId) {
65
- throw new Error(
66
- "MagicPlayerOverlay must be nested inside MagicPlayerProvider."
67
- );
68
- }
71
+ magicError.assert(instanceId, {
72
+ message: "MagicPlayerOverlay must be nested inside MagicPlayerProvider",
73
+ errorCode: "missing_instance_id"
74
+ });
69
75
  const { initializeState } = usePlayerState(instanceId);
70
76
  const state = initializeState();
71
77
  const {
@@ -6,14 +6,20 @@
6
6
 
7
7
  <script setup>
8
8
  import { inject, toRefs, computed } from "vue";
9
+ import {
10
+ useMagicError
11
+ } from "@maas/vue-equipment/plugins/MagicError";
9
12
  import { usePlayerState } from "../composables/private/usePlayerState";
10
13
  import { MagicPlayerInstanceId } from "../symbols";
14
+ const magicError = useMagicError({
15
+ prefix: "MagicPlayer",
16
+ source: "MagicPlayerPoster"
17
+ });
11
18
  const instanceId = inject(MagicPlayerInstanceId, void 0);
12
- if (!instanceId) {
13
- throw new Error(
14
- "MagicPlayerPoster must be nested inside MagicPlayerProvider."
15
- );
16
- }
19
+ magicError.assert(instanceId, {
20
+ message: "MagicPlayerPoster must be nested inside MagicPlayerProvider",
21
+ errorCode: "missing_instance_id"
22
+ });
17
23
  const { initializeState } = usePlayerState(instanceId);
18
24
  const state = initializeState();
19
25
  const { loaded, started } = toRefs(state);
@@ -34,6 +34,9 @@
34
34
 
35
35
  <script setup>
36
36
  import { inject, toRefs } from "vue";
37
+ import {
38
+ useMagicError
39
+ } from "@maas/vue-equipment/plugins/MagicError";
37
40
  import { usePlayerControlsApi } from "../composables/private/usePlayerControlsApi";
38
41
  import { usePlayerState } from "../composables/private/usePlayerState";
39
42
  import {
@@ -42,12 +45,15 @@ import {
42
45
  MagicPlayerPopoverRef,
43
46
  MagicPlayerBarRef
44
47
  } from "../symbols";
48
+ const magicError = useMagicError({
49
+ prefix: "MagicPlayer",
50
+ source: "MagicPlayerTimeline"
51
+ });
45
52
  const instanceId = inject(MagicPlayerInstanceId, void 0);
46
- if (!instanceId) {
47
- throw new Error(
48
- "MagicPlayerTimeline must be nested inside MagicPlayerVideoControls or MagicPlayerAudioControls."
49
- );
50
- }
53
+ magicError.assert(instanceId, {
54
+ message: "MagicPlayerTimeline must be nested inside MagicPlayerVideoControls or MagicPlayerAudioControls",
55
+ errorCode: "missing_instance_id"
56
+ });
51
57
  const { initializeState } = usePlayerState(instanceId);
52
58
  const state = initializeState();
53
59
  const { controlsMouseEntered, seekedPercentage, scrubbedPercentage } = toRefs(state);
@@ -26,6 +26,9 @@ import {
26
26
  useEventListener,
27
27
  defaultWindow
28
28
  } from "@vueuse/core";
29
+ import {
30
+ useMagicError
31
+ } from "@maas/vue-equipment/plugins/MagicError";
29
32
  import { usePlayerVideoApi } from "../composables/private/usePlayerVideoApi";
30
33
  import { usePlayerMediaApi } from "../composables/private/usePlayerMediaApi";
31
34
  import { usePlayerRuntime } from "../composables/private/usePlayerRuntime";
@@ -36,21 +39,28 @@ import {
36
39
  MagicPlayerOptionsKey,
37
40
  MagicPlayerRef
38
41
  } from "../symbols";
42
+ const magicError = useMagicError({
43
+ prefix: "MagicPlayer",
44
+ source: "MagicPlayerVideo"
45
+ });
39
46
  const injectedInstanceId = inject(MagicPlayerInstanceId, void 0);
40
47
  const injectedOptions = inject(MagicPlayerOptionsKey, void 0);
41
48
  const injectedPlayerRef = inject(MagicPlayerRef, void 0);
42
- if (!injectedInstanceId) {
43
- throw new Error("MagicPlayerVideo must be used within a MagicPlayerProvider");
44
- }
45
- if (!injectedOptions) {
46
- throw new Error("MagicPlayerVideo must be used within a MagicPlayerProvider");
47
- }
49
+ magicError.assert(injectedInstanceId, {
50
+ message: "MagicPlayerVideo must be used within a MagicPlayerProvider",
51
+ errorCode: "missing_instance_id"
52
+ });
53
+ magicError.assert(injectedOptions, {
54
+ message: "MagicPlayerVideo must be used within a MagicPlayerProvider",
55
+ errorCode: "missing_options"
56
+ });
48
57
  const elRef = useTemplateRef("el");
49
58
  const { initialize, destroy } = usePlayerRuntime({
50
59
  id: injectedInstanceId,
51
60
  mediaRef: elRef,
52
61
  src: injectedOptions.src,
53
- srcType: injectedOptions.srcType
62
+ srcType: injectedOptions.srcType,
63
+ debug: injectedOptions.debug
54
64
  });
55
65
  const { initializeState } = usePlayerState(injectedInstanceId);
56
66
  const state = initializeState();
@@ -93,6 +93,9 @@ import {
93
93
  onBeforeUnmount
94
94
  } from "vue";
95
95
  import { useIdle } from "@vueuse/core";
96
+ import {
97
+ useMagicError
98
+ } from "@maas/vue-equipment/plugins/MagicError";
96
99
  import IconPlay from "./icons/Play.vue";
97
100
  import IconPause from "./icons/Pause.vue";
98
101
  import IconVolumeOn from "./icons/VolumeOn.vue";
@@ -120,14 +123,17 @@ const {
120
123
  standalone: { type: Boolean, required: false },
121
124
  transition: { type: String, required: false }
122
125
  });
126
+ const magicError = useMagicError({
127
+ prefix: "MagicPlayer",
128
+ source: "MagicPlayerVideoControls"
129
+ });
123
130
  const injectedInstanceId = inject(MagicPlayerInstanceId, void 0);
124
131
  const injectedOptions = inject(MagicPlayerOptionsKey, void 0);
125
132
  const mappedInstanceId = computed(() => id ?? injectedInstanceId);
126
- if (!mappedInstanceId.value) {
127
- throw new Error(
128
- "MagicPlayerVideoControls must be nested inside MagicPlayerProvider or be passed an id as a prop."
129
- );
130
- }
133
+ magicError.assert(mappedInstanceId.value, {
134
+ message: "MagicPlayerVideoControls must be nested inside MagicPlayerProvider or be passed an id as a prop",
135
+ errorCode: "missing_instance_id"
136
+ });
131
137
  const mappedTransition = computed(
132
138
  () => transition ?? injectedOptions?.transition?.videoControls
133
139
  );
@@ -1,5 +1,5 @@
1
1
  import { toRefs, watch, toValue } from "vue";
2
- import { useMagicEmitter } from "@maas/vue-equipment/plugins";
2
+ import { useMagicEmitter } from "@maas/vue-equipment/plugins/MagicEmitter";
3
3
  import { usePlayerState } from "./usePlayerState.mjs";
4
4
  export function usePlayerEmitter(args) {
5
5
  const { id } = args;
@@ -1,26 +1,73 @@
1
1
  import { toRefs, watch, unref, toValue } from "vue";
2
2
  import { useEventListener, watchIgnorable } from "@vueuse/core";
3
+ import { useMagicError } from "@maas/vue-equipment/plugins/MagicError";
3
4
  import { usePlayerState } from "./usePlayerState.mjs";
4
5
  export function usePlayerMediaApi(args) {
5
- const { mediaRef, id } = args;
6
+ const { id, mediaRef } = args;
7
+ const { throwError } = useMagicError({
8
+ prefix: "MagicPlayer",
9
+ source: "usePlayerMediaApi"
10
+ });
6
11
  const { initializeState } = usePlayerState(toValue(id));
7
12
  const state = initializeState();
8
13
  const {
14
+ buffered,
9
15
  currentTime,
10
16
  duration,
11
- seeking,
12
- volume,
13
- rate,
14
- loaded,
15
- waiting,
16
- started,
17
17
  ended,
18
- playing,
18
+ loaded,
19
+ muted,
19
20
  paused,
21
+ playing,
22
+ rate,
23
+ seeking,
20
24
  stalled,
21
- buffered,
22
- muted
25
+ started,
26
+ volume,
27
+ waiting
23
28
  } = toRefs(state);
29
+ function handlePlayPromiseError(originalError) {
30
+ let message = "Play promise was rejected";
31
+ let errorCode = "play_promise_rejected";
32
+ switch (originalError.name) {
33
+ case "AbortError":
34
+ message = "The play() request was aborted";
35
+ errorCode = "play_promise_aborted";
36
+ break;
37
+ case "NotAllowedError":
38
+ message = "Autoplay was prevented, user interaction required";
39
+ errorCode = "play_promise_not_allowed";
40
+ break;
41
+ case "NotSupportedError":
42
+ message = "Media format not supported";
43
+ errorCode = "play_promise_not_supported";
44
+ break;
45
+ }
46
+ throwError({ message, errorCode, cause: originalError });
47
+ }
48
+ function handleMediaElementError(originalError) {
49
+ let message = "Media element error";
50
+ let errorCode = "media_element_error";
51
+ switch (originalError.code) {
52
+ case MediaError.MEDIA_ERR_ABORTED:
53
+ message = "Media loading was aborted by the user";
54
+ errorCode = "media_element_aborted";
55
+ break;
56
+ case MediaError.MEDIA_ERR_NETWORK:
57
+ message = "A network error occurred while loading the media";
58
+ errorCode = "media_element_network";
59
+ break;
60
+ case MediaError.MEDIA_ERR_DECODE:
61
+ message = "An error occurred while decoding the media";
62
+ errorCode = "media_element_decode";
63
+ break;
64
+ case MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED:
65
+ message = "The media source is not supported";
66
+ errorCode = "media_element_src_not_supported";
67
+ break;
68
+ }
69
+ throwError({ message, errorCode, cause: originalError });
70
+ }
24
71
  function timeRangeToArray(timeRanges) {
25
72
  let ranges = [];
26
73
  for (let i = 0; i < timeRanges.length; ++i)
@@ -81,8 +128,9 @@ export function usePlayerMediaApi(args) {
81
128
  }
82
129
  if (value) {
83
130
  const playPromise = el.play();
84
- playPromise?.catch(() => {
131
+ playPromise?.catch((error) => {
85
132
  playing.value = false;
133
+ handlePlayPromiseError(error);
86
134
  });
87
135
  } else {
88
136
  el.pause();
@@ -146,4 +194,10 @@ export function usePlayerMediaApi(args) {
146
194
  muted.value = el.muted;
147
195
  }
148
196
  });
197
+ useEventListener(mediaRef, "error", () => {
198
+ const el = toValue(mediaRef);
199
+ if (el?.error) {
200
+ handleMediaElementError(el.error);
201
+ }
202
+ });
149
203
  }
@@ -5,6 +5,7 @@ export type UsePlayerRuntimeArgs = {
5
5
  mediaRef?: Ref<HTMLVideoElement | HTMLAudioElement | null>;
6
6
  srcType?: MagicPlayerOptions['srcType'];
7
7
  src?: string;
8
+ debug?: boolean;
8
9
  };
9
10
  export declare function usePlayerRuntime(args: UsePlayerRuntimeArgs): {
10
11
  initialize: (autoplay?: boolean) => void;
@@ -1,26 +1,88 @@
1
1
  import { shallowRef, toRefs, toValue } from "vue";
2
2
  import { useEventListener } from "@vueuse/core";
3
+ import { useMagicError } from "@maas/vue-equipment/plugins/MagicError";
3
4
  import { usePlayerState } from "./usePlayerState.mjs";
4
5
  export function usePlayerRuntime(args) {
5
6
  let hls;
6
7
  const deferredLoading = shallowRef(false);
7
- const { id, mediaRef, srcType, src } = args;
8
+ const { id, mediaRef, srcType, src, debug = false } = args;
9
+ const { logWarning, throwError } = useMagicError({
10
+ prefix: "MagicPlayer",
11
+ source: "usePlayerRuntime"
12
+ });
8
13
  const { initializeState } = usePlayerState(toValue(id));
9
14
  const state = initializeState();
10
15
  const { loaded } = toRefs(state);
16
+ function handleHlsRuntimeError(args2) {
17
+ const { data, hls: hls2 } = args2;
18
+ const error = new Error(data.details || "HLS error");
19
+ if (!data.fatal) {
20
+ if (debug) {
21
+ logWarning(
22
+ `HLS Non-fatal error [${data.type}]: ${data.details || "Unknown"}`
23
+ );
24
+ }
25
+ return;
26
+ }
27
+ switch (data.type) {
28
+ case "networkError":
29
+ throwError({
30
+ message: "HLS network error",
31
+ errorCode: "hls_network_error",
32
+ cause: error
33
+ });
34
+ break;
35
+ case "mediaError":
36
+ try {
37
+ if (hls2) {
38
+ hls2.recoverMediaError();
39
+ if (debug) {
40
+ logWarning("HLS media error recovered");
41
+ }
42
+ return;
43
+ }
44
+ } catch (recoveryError) {
45
+ throwError({
46
+ message: "HLS media recovery failed",
47
+ errorCode: "hls_media_recovery_failed",
48
+ cause: recoveryError
49
+ });
50
+ }
51
+ throwError({
52
+ message: "HLS media error",
53
+ errorCode: "hls_media_error",
54
+ cause: error
55
+ });
56
+ break;
57
+ default:
58
+ throwError({
59
+ message: "HLS fatal error",
60
+ errorCode: "hls_fatal_error",
61
+ cause: error
62
+ });
63
+ }
64
+ }
11
65
  function useNative() {
12
66
  const el = toValue(mediaRef);
13
67
  if (!el || !src) {
14
68
  return;
15
69
  }
16
- el.src = src;
17
- el.addEventListener(
18
- "loadeddata",
19
- () => {
20
- loaded.value = true;
21
- },
22
- { once: true }
23
- );
70
+ try {
71
+ el.src = src;
72
+ el.addEventListener(
73
+ "loadeddata",
74
+ () => {
75
+ loaded.value = true;
76
+ },
77
+ { once: true }
78
+ );
79
+ } catch (error) {
80
+ throwError({
81
+ message: "Player initialization failed",
82
+ errorCode: "player_initialization_failed",
83
+ cause: error
84
+ });
85
+ }
24
86
  }
25
87
  async function useHlsJS(autoplay = false) {
26
88
  const el = toValue(mediaRef);
@@ -28,11 +90,16 @@ export function usePlayerRuntime(args) {
28
90
  return;
29
91
  }
30
92
  deferredLoading.value = autoplay;
31
- const { default: Hls } = await import("hls.js");
32
- hls = new Hls({ autoStartLoad: false });
33
- if (!Hls.isSupported()) {
34
- useNative();
35
- } else if (src) {
93
+ try {
94
+ const { default: Hls } = await import("hls.js");
95
+ hls = new Hls({ autoStartLoad: false });
96
+ if (!Hls.isSupported()) {
97
+ useNative();
98
+ return;
99
+ }
100
+ if (!src) {
101
+ return;
102
+ }
36
103
  hls.on(Hls.Events.FRAG_LOADED, () => {
37
104
  loaded.value = true;
38
105
  });
@@ -44,6 +111,9 @@ export function usePlayerRuntime(args) {
44
111
  hls?.startLoad();
45
112
  }
46
113
  });
114
+ hls.on(Hls.Events.ERROR, (_event, data) => {
115
+ handleHlsRuntimeError({ data, hls });
116
+ });
47
117
  useEventListener(mediaRef, "pause", () => {
48
118
  hls?.stopLoad();
49
119
  });
@@ -52,6 +122,12 @@ export function usePlayerRuntime(args) {
52
122
  });
53
123
  hls.loadSource(src);
54
124
  hls.attachMedia(el);
125
+ } catch (error) {
126
+ throwError({
127
+ message: "Player initialization failed",
128
+ errorCode: "player_initialization_failed",
129
+ cause: error
130
+ });
55
131
  }
56
132
  }
57
133
  function initialize(autoplay = false) {
@@ -62,8 +138,12 @@ export function usePlayerRuntime(args) {
62
138
  }
63
139
  }
64
140
  function destroy() {
65
- hls?.destroy();
66
- deferredLoading.value = false;
141
+ try {
142
+ hls?.destroy();
143
+ } finally {
144
+ hls = void 0;
145
+ deferredLoading.value = false;
146
+ }
67
147
  }
68
148
  return {
69
149
  initialize,
@@ -1,9 +1,14 @@
1
1
  import { toRefs, watch, toValue } from "vue";
2
2
  import { useFullscreen } from "@vueuse/core";
3
3
  import { isIOS } from "@maas/vue-equipment/utils";
4
+ import { useMagicError } from "@maas/vue-equipment/plugins/MagicError";
4
5
  import { usePlayerState } from "./usePlayerState.mjs";
5
6
  export function usePlayerVideoApi(args) {
6
7
  const { id, playerRef, videoRef } = args;
8
+ const { logError } = useMagicError({
9
+ prefix: "MagicPlayer",
10
+ source: "usePlayerVideoApi"
11
+ });
7
12
  const { initializeState } = usePlayerState(toValue(id));
8
13
  const state = initializeState();
9
14
  const { currentTime, playing, paused, muted, fullscreenTarget, fullscreen } = toRefs(state);
@@ -64,14 +69,14 @@ export function usePlayerVideoApi(args) {
64
69
  }
65
70
  function enterFullscreen() {
66
71
  if (!fullscreenTarget.value) {
67
- console.error("No fullscreen target found");
72
+ logError("No fullscreen target found");
68
73
  return;
69
74
  }
70
75
  enter();
71
76
  }
72
77
  function exitFullscreen() {
73
78
  if (!fullscreenTarget.value) {
74
- console.error("No fullscreen target found");
79
+ logError("No fullscreen target found");
75
80
  return;
76
81
  }
77
82
  exit();
@@ -7,6 +7,7 @@ export interface MagicPlayerOptions {
7
7
  autoplay?: boolean;
8
8
  playback?: ('viewport' | 'window')[] | false;
9
9
  loop?: boolean;
10
+ debug?: boolean;
10
11
  transition?: {
11
12
  videoControls?: string;
12
13
  overlay?: string;
@@ -23,6 +24,7 @@ export interface RequiredMagicPlayerOptions {
23
24
  preload: 'auto' | 'metadata' | 'none';
24
25
  autoplay: boolean;
25
26
  loop: boolean;
27
+ debug: boolean;
26
28
  transition: {
27
29
  videoControls: string;
28
30
  overlay: string;
@@ -5,6 +5,7 @@ const defaultOptions = {
5
5
  preload: "metadata",
6
6
  autoplay: false,
7
7
  loop: false,
8
+ debug: false,
8
9
  transition: {
9
10
  videoControls: "magic-player-video-controls",
10
11
  overlay: "magic-player-overlay",
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="el" class="magic-scroll-collision">
2
+ <div ref="el" :data-id="mappedId" class="magic-scroll-collision">
3
3
  <slot />
4
4
  </div>
5
5
  </template>
@@ -18,17 +18,23 @@ import {
18
18
  import { useCollisionDetection } from "../composables/private/useCollisionDetection";
19
19
  import { MagicScrollReturn, MagicScrollTarget } from "../symbols";
20
20
  import { useIntersectionObserver } from "@vueuse/core";
21
+ import {
22
+ useMagicError
23
+ } from "@maas/vue-equipment/plugins/MagicError";
21
24
  const { id, offset } = defineProps({
22
25
  id: { type: String, required: false },
23
26
  offset: { type: Object, required: false }
24
27
  });
28
+ const magicError = useMagicError({
29
+ prefix: "MagicScroll",
30
+ source: "MagicScrollCollision"
31
+ });
25
32
  const scrollReturn = inject(MagicScrollReturn, void 0);
26
33
  const scrollTarget = inject(MagicScrollTarget);
27
- if (!scrollTarget) {
28
- console.error(
29
- "MagicScrollCollision must be used within a MagicScrollProvider"
30
- );
31
- }
34
+ magicError.assert(scrollTarget, {
35
+ message: "MagicScrollCollision must be used within a MagicScrollProvider",
36
+ errorCode: "missing_scroll_target"
37
+ });
32
38
  const intersecting = shallowRef(false);
33
39
  const elRef = useTemplateRef("el");
34
40
  const scrollY = computed(() => toValue(scrollReturn?.y) || 0);
@@ -15,6 +15,9 @@ import {
15
15
  useTemplateRef
16
16
  } from "vue";
17
17
  import { useIntersectionObserver } from "@vueuse/core";
18
+ import {
19
+ useMagicError
20
+ } from "@maas/vue-equipment/plugins/MagicError";
18
21
  import { useScrollApi } from "../composables/private/useScrollApi";
19
22
  import {
20
23
  MagicScrollTarget,
@@ -25,11 +28,16 @@ const { from = "top-bottom", to = "bottom-top" } = defineProps({
25
28
  from: { type: String, required: false },
26
29
  to: { type: String, required: false }
27
30
  });
31
+ const magicError = useMagicError({
32
+ prefix: "MagicScroll",
33
+ source: "MagicScrollScene"
34
+ });
28
35
  const scrollReturn = inject(MagicScrollReturn, void 0);
29
36
  const scrollTarget = inject(MagicScrollTarget, void 0);
30
- if (!scrollTarget) {
31
- console.error("MagicScrollScene must be used within a MagicScrollProvider");
32
- }
37
+ magicError.assert(scrollTarget, {
38
+ message: "MagicScrollScene must be used within a MagicScrollProvider",
39
+ errorCode: "missing_scroll_target"
40
+ });
33
41
  const progress = shallowRef(0);
34
42
  const intersecting = shallowRef(false);
35
43
  const elRef = useTemplateRef("el");
@@ -1,6 +1,6 @@
1
1
  import { shallowRef, reactive, computed, toValue } from "vue";
2
2
  import { useElementBounding, useWindowSize } from "@vueuse/core";
3
- import { useMagicEmitter } from "@maas/vue-equipment/plugins";
3
+ import { useMagicEmitter } from "@maas/vue-equipment/plugins/MagicEmitter";
4
4
  export function useCollisionDetection(args) {
5
5
  const { id, scrollY, child, parent, offset } = args;
6
6
  const alerted = reactive({