@m4l/gclick 0.24.1 → 0.25.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 (86) hide show
  1. package/components/CameraStream/defaults/DefaultPhaseStreaming.d.ts +4 -0
  2. package/components/CameraStream/defaults/DefaultPhaseStreaming.d.ts.map +1 -1
  3. package/components/CameraStream/defaults/DefaultPhaseStreaming.js +35 -33
  4. package/components/CameraStreams/CameraStreamsProvider.d.ts +5 -0
  5. package/components/CameraStreams/CameraStreamsProvider.d.ts.map +1 -1
  6. package/components/CameraStreams/CameraStreamsProvider.js +10 -11
  7. package/components/CameraStreams/contexts/CameraStreamPlayersContext.d.ts +7 -3
  8. package/components/CameraStreams/contexts/CameraStreamPlayersContext.d.ts.map +1 -1
  9. package/components/CameraStreams/contexts/CameraStreamsSuspensionContext.d.ts +15 -0
  10. package/components/CameraStreams/contexts/CameraStreamsSuspensionContext.d.ts.map +1 -0
  11. package/components/CameraStreams/contexts/CameraStreamsSuspensionContext.js +5 -0
  12. package/components/CameraStreams/hooks/useCameraStreamsSuspended.d.ts +7 -0
  13. package/components/CameraStreams/hooks/useCameraStreamsSuspended.d.ts.map +1 -0
  14. package/components/CameraStreams/hooks/useCameraStreamsSuspended.js +8 -0
  15. package/components/CameraStreams/hooks/useStreamPolling.d.ts +1 -11
  16. package/components/CameraStreams/hooks/useStreamPolling.d.ts.map +1 -1
  17. package/components/CameraStreams/hooks/useStreamPolling.js +84 -89
  18. package/components/CameraStreams/hooks/useStreamRequest.d.ts +7 -8
  19. package/components/CameraStreams/hooks/useStreamRequest.d.ts.map +1 -1
  20. package/components/CameraStreams/hooks/useStreamRequest.js +34 -50
  21. package/components/CameraStreams/index.d.ts +2 -0
  22. package/components/CameraStreams/index.d.ts.map +1 -1
  23. package/components/CameraStreams/types.d.ts +23 -10
  24. package/components/CameraStreams/types.d.ts.map +1 -1
  25. package/components/VideoPlayer/VideoPlayer.d.ts +3 -3
  26. package/components/VideoPlayer/VideoPlayer.d.ts.map +1 -1
  27. package/components/VideoPlayer/VideoPlayer.js +29 -25
  28. package/components/VideoPlayer/VideoPlayer.styles.d.ts.map +1 -1
  29. package/components/VideoPlayer/VideoPlayer.styles.js +32 -6
  30. package/components/VideoPlayer/VideojsDefaultSkin.styles.d.ts.map +1 -1
  31. package/components/VideoPlayer/VideojsDefaultSkin.styles.js +936 -807
  32. package/components/VideoPlayer/VideojsMinimalSkin.styles.d.ts.map +1 -1
  33. package/components/VideoPlayer/VideojsMinimalSkin.styles.js +901 -809
  34. package/components/VideoPlayer/constants.d.ts +16 -0
  35. package/components/VideoPlayer/constants.d.ts.map +1 -1
  36. package/components/VideoPlayer/constants.js +27 -8
  37. package/components/VideoPlayer/hlsSource.d.ts +41 -0
  38. package/components/VideoPlayer/hlsSource.d.ts.map +1 -0
  39. package/components/VideoPlayer/hlsSource.js +35 -0
  40. package/components/VideoPlayer/hooks/useMediaReadiness.d.ts +22 -0
  41. package/components/VideoPlayer/hooks/useMediaReadiness.d.ts.map +1 -0
  42. package/components/VideoPlayer/hooks/useMediaReadiness.js +21 -0
  43. package/components/VideoPlayer/hooks/usePlaybackIntent.d.ts +14 -0
  44. package/components/VideoPlayer/hooks/usePlaybackIntent.d.ts.map +1 -0
  45. package/components/VideoPlayer/hooks/usePlaybackIntent.js +33 -0
  46. package/components/VideoPlayer/hooks/usePlayerControl.d.ts +6 -0
  47. package/components/VideoPlayer/hooks/usePlayerControl.d.ts.map +1 -1
  48. package/components/VideoPlayer/hooks/usePlayerControl.js +34 -25
  49. package/components/VideoPlayer/hooks/usePlayerEvents.d.ts +5 -1
  50. package/components/VideoPlayer/hooks/usePlayerEvents.d.ts.map +1 -1
  51. package/components/VideoPlayer/hooks/usePlayerEvents.js +10 -11
  52. package/components/VideoPlayer/player.factory.d.ts +24 -17
  53. package/components/VideoPlayer/player.factory.d.ts.map +1 -1
  54. package/components/VideoPlayer/storeSafety.d.ts +15 -0
  55. package/components/VideoPlayer/storeSafety.d.ts.map +1 -0
  56. package/components/VideoPlayer/storeSafety.js +25 -0
  57. package/components/VideoPlayer/subcomponents/GclickVideoSkin.d.ts +4 -2
  58. package/components/VideoPlayer/subcomponents/GclickVideoSkin.d.ts.map +1 -1
  59. package/components/VideoPlayer/subcomponents/GclickVideoSkin.js +36 -24
  60. package/components/VideoPlayer/subcomponents/VideoPlayerStage.d.ts +5 -3
  61. package/components/VideoPlayer/subcomponents/VideoPlayerStage.d.ts.map +1 -1
  62. package/components/VideoPlayer/subcomponents/VideoPlayerStage.js +64 -49
  63. package/components/VideoPlayer/subcomponents/skin/VideoControlBar.d.ts +14 -2
  64. package/components/VideoPlayer/subcomponents/skin/VideoControlBar.d.ts.map +1 -1
  65. package/components/VideoPlayer/subcomponents/skin/VideoControlBar.js +90 -62
  66. package/components/VideoPlayer/subcomponents/skin/VideoErrorDialog.d.ts +11 -0
  67. package/components/VideoPlayer/subcomponents/skin/VideoErrorDialog.d.ts.map +1 -1
  68. package/components/VideoPlayer/subcomponents/skin/VideoErrorDialog.js +16 -13
  69. package/components/VideoPlayer/subcomponents/skin/VideoInputIndicators.d.ts +15 -0
  70. package/components/VideoPlayer/subcomponents/skin/VideoInputIndicators.d.ts.map +1 -0
  71. package/components/VideoPlayer/subcomponents/skin/VideoInputIndicators.js +57 -0
  72. package/components/VideoPlayer/subcomponents/skin/VideoSettingsMenu.d.ts.map +1 -1
  73. package/components/VideoPlayer/subcomponents/skin/VideoSettingsMenu.js +10 -12
  74. package/components/VideoPlayer/subcomponents/skin/primitives.d.ts +11 -2
  75. package/components/VideoPlayer/subcomponents/skin/primitives.d.ts.map +1 -1
  76. package/components/VideoPlayer/subcomponents/skin/primitives.js +74 -72
  77. package/components/VideoPlayer/types.d.ts +43 -5
  78. package/components/VideoPlayer/types.d.ts.map +1 -1
  79. package/index.js +149 -145
  80. package/package.json +4 -2
  81. package/components/CameraStreams/subcomponents/CameraStreamsSuspensionController.d.ts +0 -18
  82. package/components/CameraStreams/subcomponents/CameraStreamsSuspensionController.d.ts.map +0 -1
  83. package/components/CameraStreams/subcomponents/CameraStreamsSuspensionController.js +0 -35
  84. package/components/VideoPlayer/hlsConfig.d.ts +0 -30
  85. package/components/VideoPlayer/hlsConfig.d.ts.map +0 -1
  86. package/components/VideoPlayer/hlsConfig.js +0 -33
@@ -27,6 +27,10 @@ import { CameraStreamPhaseStreamingSlotProps } from '../types';
27
27
  * (pause / mute / fullscreen / snapshot) from outside the slot. The
28
28
  * registration is null-safe: if the slot is rendered without a provider (e.g.
29
29
  * an isolated test), it simply skips registering.
30
+ *
31
+ * Forwards the provider's suspension flag to the player. A custom
32
+ * `phaseStreaming` slot must do the same, or its clips keep decoding behind a
33
+ * hidden tab.
30
34
  */
31
35
  export declare function DefaultPhaseStreaming({ playerKey, hlsUrl, ended, onEnded, onReplay, replayLabel, onDurationChange, variant, LiveBadgeSlot, ReplayBadgeSlot, SharedBadgeSlot, attached, endsAt, sharedLabel, sharedRemainingLabel, }: CameraStreamPhaseStreamingSlotProps): import("@emotion/react/jsx-runtime").JSX.Element;
32
36
  //# sourceMappingURL=DefaultPhaseStreaming.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultPhaseStreaming.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStream/defaults/DefaultPhaseStreaming.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,UAAU,CAAC;AAcpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,MAAM,EACN,KAAK,EACL,OAAO,EACP,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,EACN,WAAW,EACX,oBAAoB,GACrB,EAAE,mCAAmC,oDAqGrC"}
1
+ {"version":3,"file":"DefaultPhaseStreaming.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStream/defaults/DefaultPhaseStreaming.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,UAAU,CAAC;AAcpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,MAAM,EACN,KAAK,EACL,OAAO,EACP,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,EACN,WAAW,EACX,oBAAoB,GACrB,EAAE,mCAAmC,oDA0GrC"}
@@ -1,14 +1,15 @@
1
- import { jsxs as N, jsx as c } from "@emotion/react/jsx-runtime";
2
- import { useState as C, useRef as u, useContext as j, useEffect as l, useCallback as E } from "react";
3
- import { CameraStreamPlayersContext as k } from "../../CameraStreams/contexts/CameraStreamPlayersContext.js";
4
- import { VideoPlayer as v } from "../../VideoPlayer/VideoPlayer.js";
5
- const B = 3, V = 2, U = 2500;
6
- function G({
1
+ import { jsxs as j, jsx as c } from "@emotion/react/jsx-runtime";
2
+ import { useState as C, useRef as u, useContext as k, useEffect as l, useCallback as A } from "react";
3
+ import { CameraStreamPlayersContext as v } from "../../CameraStreams/contexts/CameraStreamPlayersContext.js";
4
+ import { useCameraStreamsSuspended as B } from "../../CameraStreams/hooks/useCameraStreamsSuspended.js";
5
+ import { VideoPlayer as V } from "../../VideoPlayer/VideoPlayer.js";
6
+ const U = 3, X = 2, Y = 2500;
7
+ function Q({
7
8
  playerKey: t,
8
- hlsUrl: f,
9
- ended: m,
10
- onEnded: d,
11
- onReplay: p,
9
+ hlsUrl: m,
10
+ ended: d,
11
+ onEnded: f,
12
+ onReplay: E,
12
13
  replayLabel: _,
13
14
  onDurationChange: R,
14
15
  variant: g,
@@ -20,30 +21,30 @@ function G({
20
21
  sharedLabel: M,
21
22
  sharedRemainingLabel: T
22
23
  }) {
23
- const [b, r] = C(!0), [h, S] = C(0), A = u(null), n = j(k), o = u(0), a = u(0), i = u(null);
24
+ const [b, r] = C(!0), [S, h] = C(0), p = u(null), n = k(v), F = B(), s = u(0), a = u(0), i = u(null);
24
25
  l(() => {
25
- r(!0), S(0), o.current = 0, a.current = 0;
26
- }, [f]), l(() => () => {
26
+ r(!0), h(0), s.current = 0, a.current = 0;
27
+ }, [m]), l(() => () => {
27
28
  i.current && clearTimeout(i.current);
28
29
  }, []), l(() => {
29
- const e = A.current;
30
+ const e = p.current;
30
31
  if (!(!n || !e))
31
32
  return n.register(t, e), () => n.unregister(t);
32
- }, [n, t, h]);
33
- const F = E((e, s) => {
34
- r(s), !s && Number.isFinite(e) && (o.current = e), R(e, s);
35
- }, [R]), O = E(() => {
36
- if (o.current < B && a.current < V) {
33
+ }, [n, t, S]);
34
+ const O = A((e, o) => {
35
+ r(o), !o && Number.isFinite(e) && (s.current = e), R(e, o);
36
+ }, [R]), I = A(() => {
37
+ if (s.current < U && a.current < X) {
37
38
  a.current += 1, r(!0), i.current = setTimeout(() => {
38
- o.current = 0, S((I) => I + 1);
39
- }, U);
39
+ s.current = 0, h((N) => N + 1);
40
+ }, Y);
40
41
  return;
41
42
  }
42
- r(!1), d();
43
- }, [d]);
44
- return /* @__PURE__ */ N("div", { "data-stream-player-key": t, style: { width: "100%", height: "100%" }, children: [
45
- b && !m && /* @__PURE__ */ c(D, {}),
46
- m && /* @__PURE__ */ c(P, { onReplay: p, replayLabel: _ }),
43
+ r(!1), f();
44
+ }, [f]);
45
+ return /* @__PURE__ */ j("div", { "data-stream-player-key": t, style: { width: "100%", height: "100%" }, children: [
46
+ b && !d && /* @__PURE__ */ c(D, {}),
47
+ d && /* @__PURE__ */ c(P, { onReplay: E, replayLabel: _ }),
47
48
  y && /* @__PURE__ */ c(
48
49
  x,
49
50
  {
@@ -53,18 +54,19 @@ function G({
53
54
  }
54
55
  ),
55
56
  /* @__PURE__ */ c(
56
- v,
57
+ V,
57
58
  {
58
- ref: A,
59
- src: f,
59
+ ref: p,
60
+ src: m,
61
+ suspended: F,
60
62
  variant: g,
61
- onDurationChange: F,
62
- onEnded: O
63
+ onDurationChange: O,
64
+ onEnded: I
63
65
  },
64
- h
66
+ S
65
67
  )
66
68
  ] });
67
69
  }
68
70
  export {
69
- G as DefaultPhaseStreaming
71
+ Q as DefaultPhaseStreaming
70
72
  };
@@ -12,6 +12,11 @@ import { CameraStreamsProviderProps } from './types';
12
12
  * ref-based map of live `VideoPlayerControl`s). The default `phaseStreaming`
13
13
  * slot registers into it, so `useCameraStreamPlayers()` can drive the video
14
14
  * transport (pause / mute / fullscreen / snapshot) from outside the slot.
15
+ *
16
+ * The third seam is `CameraStreamsSuspensionContext`, which publishes the
17
+ * `suspended` flag so each player synchronizes its own playback instead of
18
+ * being driven through the registry. See that context for why suspension is
19
+ * declared rather than pushed.
15
20
  */
16
21
  export declare function CameraStreamsProvider(props: CameraStreamsProviderProps): import("@emotion/react/jsx-runtime").JSX.Element;
17
22
  //# sourceMappingURL=CameraStreamsProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CameraStreamsProvider.d.ts","sourceRoot":"","sources":["../../../../../../packages/gclick/src/components/CameraStreams/CameraStreamsProvider.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,oDAkCtE"}
1
+ {"version":3,"file":"CameraStreamsProvider.d.ts","sourceRoot":"","sources":["../../../../../../packages/gclick/src/components/CameraStreams/CameraStreamsProvider.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,oDAmCtE"}
@@ -1,28 +1,27 @@
1
1
  import { jsx as t, jsxs as c } from "@emotion/react/jsx-runtime";
2
2
  import { useRef as o } from "react";
3
- import { useModuleDictionary as f } from "@m4l/core";
4
- import { resolveCameraStreamsDictionaryLabels as u } from "./dictionary.js";
3
+ import { useModuleDictionary as u } from "@m4l/core";
4
+ import { resolveCameraStreamsDictionaryLabels as f } from "./dictionary.js";
5
5
  import { CameraStreamsContext as p } from "./contexts/CameraStreamsContext.js";
6
- import { CameraStreamPlayersContext as C } from "./contexts/CameraStreamPlayersContext.js";
6
+ import { CameraStreamPlayersContext as d } from "./contexts/CameraStreamPlayersContext.js";
7
+ import { CameraStreamsSuspensionContext as C } from "./contexts/CameraStreamsSuspensionContext.js";
7
8
  import { createCameraStreamsStore as S } from "./store.js";
8
- import { createCameraStreamPlayersRegistry as d } from "./helpers/createCameraStreamPlayersRegistry.js";
9
+ import { createCameraStreamPlayersRegistry as v } from "./helpers/createCameraStreamPlayersRegistry.js";
9
10
  import { CameraStreamsEngine as y } from "./subcomponents/CameraStreamsEngine.js";
10
- import { CameraStreamsSuspensionController as v } from "./subcomponents/CameraStreamsSuspensionController.js";
11
11
  function M(a) {
12
- const { children: m, labels: s, suspended: i = !1, ...n } = a, { getLabel: l } = f(), r = o(null);
12
+ const { children: m, labels: i, suspended: s = !1, ...n } = a, { getLabel: l } = u(), r = o(null);
13
13
  r.current || (r.current = S({
14
14
  ...n,
15
15
  labels: {
16
- ...u(l),
17
- ...s ?? {}
16
+ ...f(l),
17
+ ...i ?? {}
18
18
  }
19
19
  }));
20
20
  const e = o(null);
21
- return e.current || (e.current = d()), /* @__PURE__ */ t(p.Provider, { value: r.current, children: /* @__PURE__ */ c(C.Provider, { value: e.current, children: [
21
+ return e.current || (e.current = v()), /* @__PURE__ */ t(p.Provider, { value: r.current, children: /* @__PURE__ */ t(d.Provider, { value: e.current, children: /* @__PURE__ */ c(C.Provider, { value: s, children: [
22
22
  /* @__PURE__ */ t(y, {}),
23
- /* @__PURE__ */ t(v, { suspended: i }),
24
23
  m
25
- ] }) });
24
+ ] }) }) });
26
25
  }
27
26
  export {
28
27
  M as CameraStreamsProvider
@@ -24,9 +24,13 @@ export interface CameraStreamPlayersRegistry {
24
24
  keys(): PlayerKey[];
25
25
  /**
26
26
  * Subscribe to registration changes (a control registered or unregistered).
27
- * Returns an unsubscribe function. Lets the suspension coordinator catch
28
- * players that start streaming *after* the subtree was already suspended (an
29
- * in-flight request resolving while hidden), which a one-shot snapshot misses.
27
+ * Returns an unsubscribe function, so a consumer holding a snapshot of the
28
+ * registry can keep it current as players mount and unmount.
29
+ *
30
+ * Note that listeners run SYNCHRONOUSLY inside `register` / `unregister`,
31
+ * which means inside the registering component's own effect. Anything a
32
+ * listener does then runs against a player that has only just committed —
33
+ * which is why suspension no longer travels this way.
30
34
  */
31
35
  subscribe(listener: () => void): () => void;
32
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CameraStreamPlayersContext.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/contexts/CameraStreamPlayersContext.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,2BAA2B;IAC1C,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC5D,+DAA+D;IAC/D,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC,2EAA2E;IAC3E,GAAG,CAAC,GAAG,EAAE,SAAS,GAAG,kBAAkB,GAAG,IAAI,CAAC;IAC/C,6CAA6C;IAC7C,IAAI,IAAI,SAAS,EAAE,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC7C;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,6DACkB,CAAC"}
1
+ {"version":3,"file":"CameraStreamPlayersContext.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/contexts/CameraStreamPlayersContext.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,2BAA2B;IAC1C,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC5D,+DAA+D;IAC/D,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IACjC,2EAA2E;IAC3E,GAAG,CAAC,GAAG,EAAE,SAAS,GAAG,kBAAkB,GAAG,IAAI,CAAC;IAC/C,6CAA6C;IAC7C,IAAI,IAAI,SAAS,EAAE,CAAC;IACpB;;;;;;;;;OASG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC7C;AAED;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,6DACkB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Context carrying the provider's soft-suspension flag down to the streaming
3
+ * slots.
4
+ *
5
+ * Deliberately separate from {@link CameraStreamPlayersContext}: this is desired
6
+ * STATE, not an imperative seam. A slot reads it and lets its own player
7
+ * synchronize, instead of being handed a `pause()` it may not be able to honour
8
+ * yet — the v10 store has no media element attached on its first commit, so an
9
+ * order pushed in at registration time is both a crash and a no-op.
10
+ *
11
+ * Defaults to `false` so a slot rendered outside a provider (an isolated test,
12
+ * a story) still plays normally.
13
+ */
14
+ export declare const CameraStreamsSuspensionContext: import('react').Context<boolean>;
15
+ //# sourceMappingURL=CameraStreamsSuspensionContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CameraStreamsSuspensionContext.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/contexts/CameraStreamsSuspensionContext.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,8BAA8B,kCAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { createContext as e } from "react";
2
+ const o = e(!1);
3
+ export {
4
+ o as CameraStreamsSuspensionContext
5
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Read whether the enclosing `<CameraStreamsProvider>` is currently suspended.
3
+ * A custom `phaseStreaming` slot must forward this to its `<VideoPlayer>` to
4
+ * keep the suspension semantics.
5
+ */
6
+ export declare function useCameraStreamsSuspended(): boolean;
7
+ //# sourceMappingURL=useCameraStreamsSuspended.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCameraStreamsSuspended.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/hooks/useCameraStreamsSuspended.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD"}
@@ -0,0 +1,8 @@
1
+ import { useContext as e } from "react";
2
+ import { CameraStreamsSuspensionContext as r } from "../contexts/CameraStreamsSuspensionContext.js";
3
+ function m() {
4
+ return e(r);
5
+ }
6
+ export {
7
+ m as useCameraStreamsSuspended
8
+ };
@@ -1,16 +1,6 @@
1
1
  import { PlayerKey } from '../types';
2
2
  interface UseStreamPollingArgs {
3
3
  playerKey: PlayerKey;
4
- /**
5
- * Command to poll for; `undefined` while the player is not `polling` — and
6
- * also while it polls a session it joined, which has no command of ours.
7
- */
8
- commandUuid: string | undefined;
9
- /** Command coordinates captured from the POST response. */
10
- deviceId: number | null;
11
- createdAt: string | null;
12
- /** Release the host progress indicator on a terminal transition. */
13
- endProgress: () => void;
14
4
  }
15
5
  /**
16
6
  * Poll for one player until its stream settles, publishing both the outcome
@@ -23,6 +13,6 @@ interface UseStreamPollingArgs {
23
13
  * owns the wait: they have different lifetimes (the POST fires once, the poll
24
14
  * runs for minutes) and different failure modes.
25
15
  */
26
- export declare function useStreamPolling({ playerKey, commandUuid, deviceId, createdAt, endProgress, }: UseStreamPollingArgs): void;
16
+ export declare function useStreamPolling({ playerKey }: UseStreamPollingArgs): void;
27
17
  export {};
28
18
  //# sourceMappingURL=useStreamPolling.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamPolling.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/hooks/useStreamPolling.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA4B1C,UAAU,oBAAoB;IAC5B,SAAS,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oEAAoE;IACpE,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,EAAE,oBAAoB,GAAG,IAAI,CA2T7B"}
1
+ {"version":3,"file":"useStreamPolling.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/hooks/useStreamPolling.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AA4B1C,UAAU,oBAAoB;IAC5B,SAAS,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE,oBAAoB,GAAG,IAAI,CA0T1E"}
@@ -1,67 +1,65 @@
1
- import { useRef as x, useEffect as k } from "react";
2
- import { useQuery as A } from "@tanstack/react-query";
1
+ import { useRef as R, useEffect as k } from "react";
2
+ import { useQuery as b } from "@tanstack/react-query";
3
3
  import { useNetwork as D } from "@m4l/core";
4
- import { extractHlsUrlFromResponse as F, safeParseJson as q, resolveCommandErrorMessage as B, extractErrorMessage as M } from "../helpers/commandError.js";
5
- import { resolvePollInterval as R } from "../helpers/pollSchedule.js";
6
- import { pendingStageBoundaries as P } from "../helpers/waitingStages.js";
7
- import { useCameraStreamsStore as f } from "./useCameraStreamsStore.js";
8
- import { useCloudFrontCookieManager as N } from "./useCloudFrontCookie.js";
9
- const G = /* @__PURE__ */ new Set([
4
+ import { extractHlsUrlFromResponse as O, safeParseJson as _, resolveCommandErrorMessage as x, extractErrorMessage as F } from "../helpers/commandError.js";
5
+ import { resolvePollInterval as T } from "../helpers/pollSchedule.js";
6
+ import { pendingStageBoundaries as q } from "../helpers/waitingStages.js";
7
+ import { useCameraStreamsStore as h } from "./useCameraStreamsStore.js";
8
+ import { useCloudFrontCookieManager as B } from "./useCloudFrontCookie.js";
9
+ const M = /* @__PURE__ */ new Set([
10
10
  "executed",
11
11
  "error",
12
12
  "error_retries_max",
13
13
  "channel_busy"
14
14
  ]);
15
- function V(t) {
15
+ function N(t) {
16
16
  return !!t.hlsUrl || t.status === "error";
17
17
  }
18
- function W({ createdAt: t, requestedDuration: c }) {
19
- if (typeof c != "number")
18
+ function G({ createdAt: t, requestedDuration: p }) {
19
+ if (typeof p != "number")
20
20
  return;
21
- const h = new Date(t).getTime() + c * 1e3;
22
- return Number.isFinite(h) ? new Date(h).toISOString() : void 0;
21
+ const i = new Date(t).getTime() + p * 1e3;
22
+ return Number.isFinite(i) ? new Date(i).toISOString() : void 0;
23
23
  }
24
- function X({
25
- playerKey: t,
26
- commandUuid: c,
27
- deviceId: h,
28
- createdAt: v,
29
- endProgress: o
30
- }) {
31
- const { networkOperation: U } = D(), { ensureCookies: g } = N(), i = f((e) => e.players[t]), u = f((e) => e.labels), O = f((e) => e.config.endpointDevicesCommand), _ = f((e) => e.config.endpointVideoStreams), d = f((e) => e.config.pollBudgetSeconds), n = f((e) => e.actions.setPhase), l = x(i);
32
- l.current = i;
33
- const S = i?.phase.kind === "polling", I = S && i.phase.kind === "polling" ? i.phase.startedAt : null, E = i?.phase.kind === "polling" && !i.phase.commandUuid ? i.phase.streamUuid : void 0, { data: b, error: T } = A({
34
- queryKey: ["cameraStreamRequest", t, c],
24
+ function y({ playerKey: t }) {
25
+ const { networkOperation: p } = D(), { ensureCookies: i } = B(), o = h((e) => e.players[t]), c = h((e) => e.labels), C = h((e) => e.config.endpointDevicesCommand), w = h((e) => e.config.endpointVideoStreams), l = h((e) => e.config.pollBudgetSeconds), n = h((e) => e.actions.setPhase), d = R(o);
26
+ d.current = o;
27
+ const m = o?.phase.kind === "polling", I = m && o.phase.kind === "polling" ? o.phase.startedAt : null, u = m && o.phase.kind === "polling" ? {
28
+ uuid: o.phase.commandUuid,
29
+ deviceId: o.phase.commandDeviceId,
30
+ createdAt: o.phase.commandCreatedAt
31
+ } : void 0, S = u?.uuid, v = m && o.phase.kind === "polling" && !S ? o.phase.streamUuid : void 0, { data: E, error: U } = b({
32
+ queryKey: ["cameraStreamRequest", t, S],
35
33
  /**
36
34
  * Poll `devices/command` until the command associated with this player's
37
35
  * `commandUuid` reaches a terminal status.
38
36
  */
39
- queryFn: async () => !c || h === null || !v ? null : U({
37
+ queryFn: async () => !u?.uuid || u.deviceId === void 0 || !u.createdAt ? null : p({
40
38
  method: "GET",
41
- endPoint: O,
39
+ endPoint: C,
42
40
  parms: {
43
- deviceId: h,
44
- createdAt: v,
45
- uuid: c
41
+ deviceId: u.deviceId,
42
+ createdAt: u.createdAt,
43
+ uuid: u.uuid
46
44
  },
47
45
  toastError: !1,
48
46
  toastSuccess: !1,
49
47
  responseToCamelCase: !0
50
48
  }),
51
- enabled: !!c && S,
49
+ enabled: !!S && m,
52
50
  /**
53
51
  * Staged interval from `helpers/pollSchedule.ts`. Returns `false` once the
54
52
  * backend reports a terminal status or the budget is spent.
55
53
  */
56
54
  refetchInterval: (e) => {
57
55
  const r = e.state.data?.data?.statusId ?? "";
58
- if (G.has(r))
56
+ if (M.has(r))
59
57
  return !1;
60
- const s = l.current;
58
+ const s = d.current;
61
59
  if (s?.phase.kind !== "polling")
62
60
  return !1;
63
61
  const a = s.phase.startedAt;
64
- return R((Date.now() - a) / 1e3, d);
62
+ return T((Date.now() - a) / 1e3, l);
65
63
  },
66
64
  retry: !1,
67
65
  refetchOnWindowFocus: !1,
@@ -72,24 +70,24 @@ function X({
72
70
  // and the tile comes back frozen on a stale phase.
73
71
  refetchIntervalInBackground: !0,
74
72
  staleTime: 1 / 0
75
- }), { data: w, error: C } = A({
76
- queryKey: ["cameraStreamAttached", t, E],
73
+ }), { data: P, error: A } = b({
74
+ queryKey: ["cameraStreamAttached", t, v],
77
75
  /** Read the joined stream until it exposes an `hlsUrl` or fails. */
78
- queryFn: async () => E ? U({
76
+ queryFn: async () => v ? p({
79
77
  method: "GET",
80
- endPoint: `${_}/${E}`,
78
+ endPoint: `${w}/${v}`,
81
79
  toastError: !1,
82
80
  toastSuccess: !1,
83
81
  responseToCamelCase: !0
84
82
  }) : null,
85
- enabled: !!E,
83
+ enabled: !!v,
86
84
  /** Same staged cadence and budget cut-off as the command poll. */
87
85
  refetchInterval: (e) => {
88
86
  const r = e.state.data?.data;
89
- if (r && V(r))
87
+ if (r && N(r))
90
88
  return !1;
91
- const s = l.current;
92
- return s?.phase.kind !== "polling" ? !1 : R((Date.now() - s.phase.startedAt) / 1e3, d);
89
+ const s = d.current;
90
+ return s?.phase.kind !== "polling" ? !1 : T((Date.now() - s.phase.startedAt) / 1e3, l);
93
91
  },
94
92
  retry: !1,
95
93
  refetchOnWindowFocus: !1,
@@ -99,118 +97,115 @@ function X({
99
97
  staleTime: 1 / 0
100
98
  });
101
99
  k(() => {
102
- if (!S)
100
+ if (!m)
103
101
  return;
104
102
  const e = setTimeout(() => {
105
- l.current?.phase.kind === "polling" && (n(t, { kind: "timeout" }), o());
106
- }, d * 1e3);
103
+ d.current?.phase.kind === "polling" && n(t, { kind: "timeout" });
104
+ }, l * 1e3);
107
105
  return () => {
108
106
  clearTimeout(e);
109
107
  };
110
- }, [S, t, d, n, o]), k(() => {
108
+ }, [m, t, l, n]), k(() => {
111
109
  if (I === null)
112
110
  return;
113
- const e = (Date.now() - I) / 1e3, r = P(e, d).map(
111
+ const e = (Date.now() - I) / 1e3, r = q(e, l).map(
114
112
  ({ stage: s, delayMs: a }) => setTimeout(() => {
115
- const m = l.current;
116
- m?.phase.kind === "polling" && n(t, { ...m.phase, stage: s });
113
+ const f = d.current;
114
+ f?.phase.kind === "polling" && n(t, { ...f.phase, stage: s });
117
115
  }, a)
118
116
  );
119
117
  return () => {
120
118
  r.forEach(clearTimeout);
121
119
  };
122
- }, [I, t, d, n]), k(() => {
123
- const e = b?.data;
120
+ }, [I, t, l, n]), k(() => {
121
+ const e = E?.data;
124
122
  if (!e)
125
123
  return;
126
- const r = l.current;
124
+ const r = d.current;
127
125
  if (!(!r || r.phase.kind !== "polling")) {
128
126
  if (e.statusId === "executed") {
129
- const s = F(e.response);
127
+ const s = O(e.response);
130
128
  if (!s) {
131
- n(t, { kind: "error", code: "missing-hls-url", message: u.playerErrorPlayback }), o();
129
+ n(t, { kind: "error", code: "missing-hls-url", message: c.playerErrorPlayback });
132
130
  return;
133
131
  }
134
- const { commandUuid: a, streamUuid: m } = r.phase, p = () => {
132
+ const { commandUuid: a, streamUuid: f } = r.phase, g = () => {
135
133
  n(t, {
136
134
  kind: "streaming",
137
135
  commandUuid: a,
138
- streamUuid: m,
136
+ streamUuid: f,
139
137
  hlsUrl: s
140
- }), o();
138
+ });
141
139
  };
142
- g().then(p).catch(p);
140
+ i().then(g).catch(g);
143
141
  return;
144
142
  }
145
143
  if (e.statusId === "channel_busy") {
146
- n(t, { kind: "channelBusy" }), o();
144
+ n(t, { kind: "channelBusy" });
147
145
  return;
148
146
  }
149
147
  if (e.statusId === "error") {
150
- const s = q(e.response, {
148
+ const s = _(e.response, {
151
149
  error: { origin: "", message: "", status: 0, agent: "" },
152
150
  body: ""
153
- }), a = B(s, u.playerErrorPlayback);
151
+ }), a = x(s, c.playerErrorPlayback);
154
152
  n(t, {
155
153
  kind: "error",
156
154
  code: "remote-error",
157
155
  message: a
158
- }), o();
156
+ });
159
157
  return;
160
158
  }
161
159
  if (e.statusId === "error_retries_max") {
162
- n(t, { kind: "timeout" }), o();
160
+ n(t, { kind: "timeout" });
163
161
  return;
164
162
  }
165
163
  }
166
164
  }, [
167
- b,
165
+ E,
168
166
  t,
169
- u.playerErrorPlayback,
170
- g,
171
- n,
172
- o
167
+ c.playerErrorPlayback,
168
+ i,
169
+ n
173
170
  ]), k(() => {
174
- const e = w?.data;
171
+ const e = P?.data;
175
172
  if (!e)
176
173
  return;
177
- const r = l.current;
174
+ const r = d.current;
178
175
  if (!(!r || r.phase.kind !== "polling")) {
179
176
  if (e.hlsUrl) {
180
- const { streamUuid: s } = r.phase, { hlsUrl: a } = e, m = W(e), p = () => {
181
- n(t, { kind: "streaming", streamUuid: s, hlsUrl: a, attached: !0, endsAt: m }), o();
177
+ const { streamUuid: s } = r.phase, { hlsUrl: a } = e, f = G(e), g = () => {
178
+ n(t, { kind: "streaming", streamUuid: s, hlsUrl: a, attached: !0, endsAt: f });
182
179
  };
183
- g().then(p).catch(p);
180
+ i().then(g).catch(g);
184
181
  return;
185
182
  }
186
- e.status === "error" && (n(t, {
183
+ e.status === "error" && n(t, {
187
184
  kind: "error",
188
185
  code: "attached-stream-failed",
189
- message: u.playerErrorPlayback
190
- }), o());
186
+ message: c.playerErrorPlayback
187
+ });
191
188
  }
192
189
  }, [
193
- w,
190
+ P,
194
191
  t,
195
- u.playerErrorPlayback,
196
- g,
197
- n,
198
- o
192
+ c.playerErrorPlayback,
193
+ i,
194
+ n
199
195
  ]), k(() => {
200
- const e = T ?? C;
196
+ const e = U ?? A;
201
197
  if (!e)
202
198
  return;
203
- const r = M(e, u.requestErrorUnknownPolling);
204
- n(t, { kind: "error", code: "polling-failed", message: r }), o();
199
+ const r = F(e, c.requestErrorUnknownPolling);
200
+ n(t, { kind: "error", code: "polling-failed", message: r });
205
201
  }, [
206
- T,
207
- C,
202
+ U,
203
+ A,
208
204
  t,
209
- u.requestErrorUnknownPolling,
210
- n,
211
- o
205
+ c.requestErrorUnknownPolling,
206
+ n
212
207
  ]);
213
208
  }
214
209
  export {
215
- X as useStreamPolling
210
+ y as useStreamPolling
216
211
  };
@@ -1,4 +1,4 @@
1
- import { PlayerKey, StreamPhase } from '../types';
1
+ import { PlayerKey } from '../types';
2
2
  /**
3
3
  * Engine hook that opens a single player's stream lifecycle: POST to obtain
4
4
  * the command/stream UUIDs and move the FSM into `polling`, then delegate the
@@ -6,16 +6,15 @@ import { PlayerKey, StreamPhase } from '../types';
6
6
  * poll budget, mode, and duration are all read from the scoped Zustand store
7
7
  * so the hook stays agnostic of any MF-specific config.
8
8
  *
9
- * The request/poll busy indicator is driven through the mounting window's tools
10
- * (`useWindowToolsMF`), so the spinner renders inside the owning module panel
11
- * (omm / gps_devices) instead of the global host shell. Requires the subtree to
12
- * live under a `WindowToolsMFProvider`, which both consumers already mount.
9
+ * One instance per `playerKey`, mounted by `<CameraStreamsEngine>` for as long
10
+ * as the player slice exists — including while it sits `idle`. No network work
11
+ * happens outside `requesting` / `polling`.
13
12
  *
14
- * One instance per `playerKey` — mounted by `<CameraStreamsEngine>` only
15
- * while the player's `phase.kind === 'requesting'` or `'polling'`.
13
+ * It deliberately owns no module-level busy indicator; the tile's own
14
+ * `requesting` / `polling` phases are the wait. See the README gotcha for why
15
+ * an engine-owned indicator cannot be released reliably.
16
16
  */
17
17
  export declare function useStreamRequest({ playerKey }: {
18
18
  playerKey: PlayerKey;
19
19
  }): void;
20
- export type { StreamPhase };
21
20
  //# sourceMappingURL=useStreamRequest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamRequest.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/hooks/useStreamRequest.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,QAqLvE;AAGD,YAAY,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"useStreamRequest.d.ts","sourceRoot":"","sources":["../../../../../../../packages/gclick/src/components/CameraStreams/hooks/useStreamRequest.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,GAAG,IAAI,CAgI9E"}