@oxyhq/bloom 1.2.2 → 1.3.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 (82) hide show
  1. package/docs/media-flight.mdx +87 -0
  2. package/lib/commonjs/media-flight/MediaFlightHost.js +56 -0
  3. package/lib/commonjs/media-flight/MediaFlightHost.js.map +1 -0
  4. package/lib/commonjs/media-flight/MediaFlightHost.web.js +85 -0
  5. package/lib/commonjs/media-flight/MediaFlightHost.web.js.map +1 -0
  6. package/lib/commonjs/media-flight/MediaFlightLayer.js +4 -2
  7. package/lib/commonjs/media-flight/MediaFlightLayer.js.map +1 -1
  8. package/lib/commonjs/media-flight/MediaFlightLayer.web.js +212 -0
  9. package/lib/commonjs/media-flight/MediaFlightLayer.web.js.map +1 -0
  10. package/lib/commonjs/media-flight/MediaSurface.js.map +1 -1
  11. package/lib/commonjs/media-flight/index.js +8 -1
  12. package/lib/commonjs/media-flight/index.js.map +1 -1
  13. package/lib/commonjs/media-flight/index.web.js +115 -0
  14. package/lib/commonjs/media-flight/index.web.js.map +1 -0
  15. package/lib/commonjs/media-flight/media-node.web.js +291 -0
  16. package/lib/commonjs/media-flight/media-node.web.js.map +1 -0
  17. package/lib/commonjs/media-flight/store.js +19 -4
  18. package/lib/commonjs/media-flight/store.js.map +1 -1
  19. package/lib/module/media-flight/MediaFlightHost.js +51 -0
  20. package/lib/module/media-flight/MediaFlightHost.js.map +1 -0
  21. package/lib/module/media-flight/MediaFlightHost.web.js +80 -0
  22. package/lib/module/media-flight/MediaFlightHost.web.js.map +1 -0
  23. package/lib/module/media-flight/MediaFlightLayer.js +4 -2
  24. package/lib/module/media-flight/MediaFlightLayer.js.map +1 -1
  25. package/lib/module/media-flight/MediaFlightLayer.web.js +206 -0
  26. package/lib/module/media-flight/MediaFlightLayer.web.js.map +1 -0
  27. package/lib/module/media-flight/MediaSurface.js.map +1 -1
  28. package/lib/module/media-flight/index.js +2 -1
  29. package/lib/module/media-flight/index.js.map +1 -1
  30. package/lib/module/media-flight/index.web.js +19 -0
  31. package/lib/module/media-flight/index.web.js.map +1 -0
  32. package/lib/module/media-flight/media-node.web.js +281 -0
  33. package/lib/module/media-flight/media-node.web.js.map +1 -0
  34. package/lib/module/media-flight/store.js +19 -4
  35. package/lib/module/media-flight/store.js.map +1 -1
  36. package/lib/typescript/commonjs/media-flight/MediaFlightHost.d.ts +6 -0
  37. package/lib/typescript/commonjs/media-flight/MediaFlightHost.d.ts.map +1 -0
  38. package/lib/typescript/commonjs/media-flight/MediaFlightHost.web.d.ts +6 -0
  39. package/lib/typescript/commonjs/media-flight/MediaFlightHost.web.d.ts.map +1 -0
  40. package/lib/typescript/commonjs/media-flight/MediaFlightLayer.web.d.ts +5 -0
  41. package/lib/typescript/commonjs/media-flight/MediaFlightLayer.web.d.ts.map +1 -0
  42. package/lib/typescript/commonjs/media-flight/MediaSurface.d.ts +10 -6
  43. package/lib/typescript/commonjs/media-flight/MediaSurface.d.ts.map +1 -1
  44. package/lib/typescript/commonjs/media-flight/index.d.ts +2 -1
  45. package/lib/typescript/commonjs/media-flight/index.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/media-flight/index.web.d.ts +19 -0
  47. package/lib/typescript/commonjs/media-flight/index.web.d.ts.map +1 -0
  48. package/lib/typescript/commonjs/media-flight/media-node.web.d.ts +79 -0
  49. package/lib/typescript/commonjs/media-flight/media-node.web.d.ts.map +1 -0
  50. package/lib/typescript/commonjs/media-flight/store.d.ts +19 -4
  51. package/lib/typescript/commonjs/media-flight/store.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/media-flight/types.d.ts +44 -0
  53. package/lib/typescript/commonjs/media-flight/types.d.ts.map +1 -1
  54. package/lib/typescript/module/media-flight/MediaFlightHost.d.ts +6 -0
  55. package/lib/typescript/module/media-flight/MediaFlightHost.d.ts.map +1 -0
  56. package/lib/typescript/module/media-flight/MediaFlightHost.web.d.ts +6 -0
  57. package/lib/typescript/module/media-flight/MediaFlightHost.web.d.ts.map +1 -0
  58. package/lib/typescript/module/media-flight/MediaFlightLayer.web.d.ts +5 -0
  59. package/lib/typescript/module/media-flight/MediaFlightLayer.web.d.ts.map +1 -0
  60. package/lib/typescript/module/media-flight/MediaSurface.d.ts +10 -6
  61. package/lib/typescript/module/media-flight/MediaSurface.d.ts.map +1 -1
  62. package/lib/typescript/module/media-flight/index.d.ts +2 -1
  63. package/lib/typescript/module/media-flight/index.d.ts.map +1 -1
  64. package/lib/typescript/module/media-flight/index.web.d.ts +19 -0
  65. package/lib/typescript/module/media-flight/index.web.d.ts.map +1 -0
  66. package/lib/typescript/module/media-flight/media-node.web.d.ts +79 -0
  67. package/lib/typescript/module/media-flight/media-node.web.d.ts.map +1 -0
  68. package/lib/typescript/module/media-flight/store.d.ts +19 -4
  69. package/lib/typescript/module/media-flight/store.d.ts.map +1 -1
  70. package/lib/typescript/module/media-flight/types.d.ts +44 -0
  71. package/lib/typescript/module/media-flight/types.d.ts.map +1 -1
  72. package/package.json +6 -1
  73. package/src/media-flight/MediaFlightHost.tsx +54 -0
  74. package/src/media-flight/MediaFlightHost.web.tsx +84 -0
  75. package/src/media-flight/MediaFlightLayer.tsx +4 -2
  76. package/src/media-flight/MediaFlightLayer.web.tsx +219 -0
  77. package/src/media-flight/MediaSurface.tsx +10 -6
  78. package/src/media-flight/index.ts +2 -0
  79. package/src/media-flight/index.web.ts +45 -0
  80. package/src/media-flight/media-node.web.ts +335 -0
  81. package/src/media-flight/store.ts +19 -4
  82. package/src/media-flight/types.ts +45 -0
@@ -128,8 +128,10 @@ function MediaFlightSurface({
128
128
  contentFit: contentFit,
129
129
  surfaceType: surfaceType
130
130
  // One commit with no player before this node leaves the DOM — see
131
- // `releaseFlight`. Without it the dying element's auto-pause mirrors
132
- // through expo-video and stops the video the viewer just landed on.
131
+ // `releaseFlight`, and note there that what it buys is expo-video
132
+ // emptying the source, not the unbind. Without it the dying element's
133
+ // auto-pause mirrors through expo-video and stops the video the viewer
134
+ // just landed on.
133
135
  ,
134
136
  detached: unbinding
135
137
  // A flying surface is a picture, never a control: it must not intercept
@@ -1 +1 @@
1
- {"version":3,"names":["useEffect","useSyncExternalStore","StyleSheet","interpolate","useAnimatedStyle","OverlayRoot","Portal","MediaSurface","getFlights","notifySurfaceMounted","subscribeToFlights","jsx","_jsx","MediaFlightLayer","flights","length","children","map","flight","MediaFlightSurface","id","displayName","from","to","progress","content","cornerRadius","contentFit","surfaceType","unbinding","originX","x","originY","y","boxStyle","transform","translateX","value","translateY","width","height","detached","pointerEvents","style","styles","box","left","top","borderRadius","create","position","overflow"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightLayer.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useEffect","useSyncExternalStore","StyleSheet","interpolate","useAnimatedStyle","OverlayRoot","Portal","MediaSurface","getFlights","notifySurfaceMounted","subscribeToFlights","jsx","_jsx","MediaFlightLayer","flights","length","children","map","flight","MediaFlightSurface","id","displayName","from","to","progress","content","cornerRadius","contentFit","surfaceType","unbinding","originX","x","originY","y","boxStyle","transform","translateX","value","translateY","width","height","detached","pointerEvents","style","styles","box","left","top","borderRadius","create","position","overflow"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightLayer.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The layer that survives navigation — WEB, where it also OWNS the media.
5
+ *
6
+ * Everything in `MediaFlightLayer.tsx` still holds: mounted once at the app
7
+ * root, painting through `Portal` so a flying surface belongs to neither route.
8
+ * What this fork adds is the other half of the web story.
9
+ *
10
+ * ## It paints each shared node exactly once, forever
11
+ *
12
+ * `createPortal(<MediaSurface …/>, wrapper)` for every id a host has claimed.
13
+ * The wrapper is a plain `<div>` created OUTSIDE React by `media-node.web.ts`,
14
+ * so React reconciles the media against a container whose identity never
15
+ * changes while the registry moves that container between hosts with
16
+ * `appendChild`. React never sees the move; the browser never sees a removal;
17
+ * the video never loses its element, its decoder or its position.
18
+ *
19
+ * That is why the layer, and not the host, renders the media on web: the media
20
+ * has to be rendered by a tree that outlives every host, and the app root is
21
+ * the only such tree.
22
+ *
23
+ * ## A flying surface with a shared node paints nothing itself
24
+ *
25
+ * It becomes a positioned, animated BOX that claims the node — one more host,
26
+ * outranking the others for the length of the leg. A flight for an id with no
27
+ * shared node (an image gallery, any consumer that has not adopted a host)
28
+ * falls back to painting its own `MediaSurface`, which is what every flight did
29
+ * before hosts existed.
30
+ */
31
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
32
+ import { StyleSheet } from 'react-native';
33
+ import { createPortal } from 'react-dom';
34
+ import Animated, { interpolate, useAnimatedStyle } from 'react-native-reanimated';
35
+ import { OverlayRoot } from "../overlay/index.js";
36
+ import { Portal } from "../portal/index.web.js";
37
+ import { MediaSurface } from "./MediaSurface.js";
38
+ import { FLIGHT_RANK, claimMediaNode, getMediaNodes, releaseMediaNode, subscribeToMediaNodes } from "./media-node.web.js";
39
+ import { getFlights, notifySurfaceMounted, subscribeToFlights } from "./store.js";
40
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
41
+ export function MediaFlightLayer() {
42
+ const flights = useSyncExternalStore(subscribeToFlights, getFlights, getFlights);
43
+ const nodes = useSyncExternalStore(subscribeToMediaNodes, getMediaNodes, getMediaNodes);
44
+ if (flights.length === 0 && nodes.length === 0) return null;
45
+ return /*#__PURE__*/_jsxs(_Fragment, {
46
+ children: [nodes.map(node => /*#__PURE__*/_jsx(SharedMediaNode, {
47
+ node: node
48
+ }, node.id)), flights.length === 0 ? null : /*#__PURE__*/_jsx(Portal, {
49
+ children: /*#__PURE__*/_jsx(OverlayRoot, {
50
+ children: flights.map(flight => /*#__PURE__*/_jsx(MediaFlightSurface, {
51
+ flight: flight
52
+ // Read from the SNAPSHOT, never from the registry: a lookup
53
+ // during render is external mutable state in a memoized
54
+ // position, which the React Compiler is allowed to freeze.
55
+ ,
56
+ shared: nodes.some(node => node.id === flight.id)
57
+ }, flight.id))
58
+ })
59
+ })]
60
+ });
61
+ }
62
+ MediaFlightLayer.displayName = 'MediaFlightLayer';
63
+
64
+ /** One media element, painted into the wrapper its id owns, and never again. */
65
+ function SharedMediaNode({
66
+ node
67
+ }) {
68
+ const {
69
+ content,
70
+ contentFit,
71
+ nativeControls,
72
+ accessibilityLabel,
73
+ flightId
74
+ } = node.render;
75
+ return /*#__PURE__*/createPortal(/*#__PURE__*/_jsx(MediaSurface, {
76
+ content: content,
77
+ contentFit: contentFit,
78
+ nativeControls: nativeControls,
79
+ accessibilityLabel: accessibilityLabel,
80
+ flightId: flightId,
81
+ style: StyleSheet.absoluteFill
82
+ }), node.wrapper);
83
+ }
84
+
85
+ /**
86
+ * One flying surface. See `MediaFlightLayer.tsx` for why the size is animated
87
+ * rather than scaled.
88
+ */
89
+ function MediaFlightSurface({
90
+ flight,
91
+ shared
92
+ }) {
93
+ const {
94
+ id,
95
+ from,
96
+ to,
97
+ progress,
98
+ content,
99
+ cornerRadius,
100
+ contentFit,
101
+ surfaceType,
102
+ unbinding
103
+ } = flight;
104
+ useEffect(() => {
105
+ notifySurfaceMounted(id);
106
+ }, [id]);
107
+ const originX = from.x - to.x;
108
+ const originY = from.y - to.y;
109
+
110
+ // CRITICAL — every shared value a mapper READS must be listed in its deps.
111
+ // On web WITHOUT the react-native-worklets babel plugin, reanimated drives a
112
+ // mapper off its deps array rather than off the reads it detects: with none,
113
+ // it runs ONCE and freezes at the opening frame. See `MediaFlightLayer.tsx`.
114
+ const boxStyle = useAnimatedStyle(() => ({
115
+ transform: [{
116
+ translateX: interpolate(progress.value, [0, 1], [originX, 0])
117
+ }, {
118
+ translateY: interpolate(progress.value, [0, 1], [originY, 0])
119
+ }],
120
+ width: interpolate(progress.value, [0, 1], [from.width, to.width]),
121
+ height: interpolate(progress.value, [0, 1], [from.height, to.height])
122
+ }), [progress, originX, originY, from.width, from.height, to.width, to.height]);
123
+ const box = [styles.box, {
124
+ left: to.x,
125
+ top: to.y,
126
+ borderRadius: cornerRadius
127
+ }, boxStyle];
128
+ const render = useMemo(() => ({
129
+ content,
130
+ contentFit,
131
+ nativeControls: false,
132
+ accessibilityLabel: undefined,
133
+ // A flying surface never hands off to itself.
134
+ flightId: undefined
135
+ }), [content, contentFit]);
136
+
137
+ // The shared node is already painting this media. The flight is then a BOX
138
+ // that borrows it for the length of the leg, never a second copy.
139
+ if (shared) return /*#__PURE__*/_jsx(FlyingSharedNode, {
140
+ id: id,
141
+ style: box,
142
+ render: render
143
+ });
144
+ return /*#__PURE__*/_jsx(MediaSurface, {
145
+ content: content,
146
+ contentFit: contentFit,
147
+ surfaceType: surfaceType
148
+ // One commit with no player before this node leaves the DOM — see
149
+ // `releaseFlight`. Only the no-shared-node path can need it: a shared
150
+ // node is never removed, which is the point of the whole mechanism.
151
+ ,
152
+ detached: unbinding
153
+ // A flying surface is a picture, never a control.
154
+ ,
155
+ pointerEvents: "none",
156
+ style: box
157
+ });
158
+ }
159
+
160
+ /**
161
+ * The flight's own claim on a shared node.
162
+ *
163
+ * `pointerEvents` stays `none` on the BOX: a flying surface must not take the
164
+ * press travelling to whatever is underneath it. The wrapper inside sets
165
+ * `pointer-events: auto` for the media's sake, which is what a host needs and
166
+ * is inert here — a descendant asking for `auto` does not override a `none`
167
+ * ancestor.
168
+ */
169
+ function FlyingSharedNode({
170
+ id,
171
+ style,
172
+ render
173
+ }) {
174
+ const [node, setNode] = useState(null);
175
+ const setBox = useCallback(next => setNode(next), []);
176
+ const renderRef = useRef(render);
177
+
178
+ // Declared first so it runs first on mount, and afterwards is what pushes
179
+ // prop changes into a live claim IN PLACE — releasing and re-claiming would
180
+ // move the node away and back, and a move away is a removal.
181
+ useLayoutEffect(() => {
182
+ renderRef.current = render;
183
+ const el = node;
184
+ if (el !== null) claimMediaNode(id, el, FLIGHT_RANK, render);
185
+ }, [id, node, render]);
186
+
187
+ // Owns the claim's LIFETIME, and only that.
188
+ useLayoutEffect(() => {
189
+ const el = node;
190
+ if (el === null) return undefined;
191
+ claimMediaNode(id, el, FLIGHT_RANK, renderRef.current);
192
+ return () => releaseMediaNode(id, el, FLIGHT_RANK);
193
+ }, [id, node]);
194
+ return /*#__PURE__*/_jsx(Animated.View, {
195
+ ref: setBox,
196
+ style: style,
197
+ pointerEvents: "none"
198
+ });
199
+ }
200
+ const styles = StyleSheet.create({
201
+ box: {
202
+ position: 'absolute',
203
+ overflow: 'hidden'
204
+ }
205
+ });
206
+ //# sourceMappingURL=MediaFlightLayer.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useCallback","useEffect","useLayoutEffect","useMemo","useRef","useState","useSyncExternalStore","StyleSheet","createPortal","Animated","interpolate","useAnimatedStyle","OverlayRoot","Portal","MediaSurface","FLIGHT_RANK","claimMediaNode","getMediaNodes","releaseMediaNode","subscribeToMediaNodes","getFlights","notifySurfaceMounted","subscribeToFlights","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","MediaFlightLayer","flights","nodes","length","children","map","node","SharedMediaNode","id","flight","MediaFlightSurface","shared","some","displayName","content","contentFit","nativeControls","accessibilityLabel","flightId","render","style","absoluteFill","wrapper","from","to","progress","cornerRadius","surfaceType","unbinding","originX","x","originY","y","boxStyle","transform","translateX","value","translateY","width","height","box","styles","left","top","borderRadius","undefined","FlyingSharedNode","detached","pointerEvents","setNode","setBox","next","renderRef","current","el","View","ref","create","position","overflow"],"sourceRoot":"../../../src","sources":["media-flight/MediaFlightLayer.web.tsx"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["memo","useCallback","useState","Platform","StyleSheet","View","Image","Animated","handOffFlight","loadExpoVideo","warnExpoVideoUnavailable","jsx","_jsx","jsxs","_jsxs","webDraggableProps","OS","draggable","MediaSurface","content","style","contentFit","surfaceType","nativeControls","accessibilityLabel","pointerEvents","flightId","detached","mountedSurfaceType","reportLive","undefined","still","kind","poster","uri","expoVideo","styles","box","children","source","absoluteFill","transition","onLoad","VideoView","player","fillReplaced","onFirstFrameRender","displayName","MediaPoster","EmptyMediaSurface","empty","create","width","height","overflow","backgroundColor"],"sourceRoot":"../../../src","sources":["media-flight/MediaSurface.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["memo","useCallback","useState","Platform","StyleSheet","View","Image","Animated","handOffFlight","loadExpoVideo","warnExpoVideoUnavailable","jsx","_jsx","jsxs","_jsxs","webDraggableProps","OS","draggable","MediaSurface","content","style","contentFit","surfaceType","nativeControls","accessibilityLabel","pointerEvents","flightId","detached","mountedSurfaceType","reportLive","undefined","still","kind","poster","uri","expoVideo","styles","box","children","source","absoluteFill","transition","onLoad","VideoView","player","fillReplaced","onFirstFrameRender","displayName","MediaPoster","EmptyMediaSurface","empty","create","width","height","overflow","backgroundColor"],"sourceRoot":"../../../src","sources":["media-flight/MediaSurface.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
- export { MediaFlightLayer } from "./MediaFlightLayer.js";
3
+ export { MediaFlightLayer } from './MediaFlightLayer';
4
+ export { MediaFlightHost } from './MediaFlightHost';
4
5
  export { MediaSurface, MediaPoster, EmptyMediaSurface } from "./MediaSurface.js";
5
6
  export { useMediaFlight } from "./use-media-flight.js";
6
7
  export { DEFAULT_FLIGHT_CORNER_RADIUS, flightProgress, handOffFlight, hasFlight, releaseFlight, resetMediaFlight } from "./store.js";
@@ -1 +1 @@
1
- {"version":3,"names":["MediaFlightLayer","MediaSurface","MediaPoster","EmptyMediaSurface","useMediaFlight","DEFAULT_FLIGHT_CORNER_RADIUS","flightProgress","handOffFlight","hasFlight","releaseFlight","resetMediaFlight","SURFACE_MOUNT_TIMEOUT_MS","loadExpoVideo","warnExpoVideoUnavailable","provideExpoVideo","resetExpoVideoModule"],"sourceRoot":"../../../src","sources":["media-flight/index.ts"],"mappings":";;AAAA,SAASA,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,YAAY,EAAEC,WAAW,EAAEC,iBAAiB,QAAQ,mBAAgB;AAC7E,SAASC,cAAc,QAAQ,uBAAoB;AACnD,SACEC,4BAA4B,EAC5BC,cAAc,EACdC,aAAa,EACbC,SAAS,EACTC,aAAa,EACbC,gBAAgB,QACX,YAAS;AAChB,SAASC,wBAAwB,QAAQ,gBAAa;AACtD,SACEC,aAAa,EACbC,wBAAwB,EACxBC,gBAAgB,EAChBC,oBAAoB,QAMf,wBAAqB","ignoreList":[]}
1
+ {"version":3,"names":["MediaFlightLayer","MediaFlightHost","MediaSurface","MediaPoster","EmptyMediaSurface","useMediaFlight","DEFAULT_FLIGHT_CORNER_RADIUS","flightProgress","handOffFlight","hasFlight","releaseFlight","resetMediaFlight","SURFACE_MOUNT_TIMEOUT_MS","loadExpoVideo","warnExpoVideoUnavailable","provideExpoVideo","resetExpoVideoModule"],"sourceRoot":"../../../src","sources":["media-flight/index.ts"],"mappings":";;AAAA,SAASA,gBAAgB,QAAQ,oBAAoB;AACrD,SAASC,eAAe,QAAQ,mBAAmB;AACnD,SAASC,YAAY,EAAEC,WAAW,EAAEC,iBAAiB,QAAQ,mBAAgB;AAC7E,SAASC,cAAc,QAAQ,uBAAoB;AACnD,SACEC,4BAA4B,EAC5BC,cAAc,EACdC,aAAa,EACbC,SAAS,EACTC,aAAa,EACbC,gBAAgB,QACX,YAAS;AAChB,SAASC,wBAAwB,QAAQ,gBAAa;AACtD,SACEC,aAAa,EACbC,wBAAwB,EACxBC,gBAAgB,EAChBC,oBAAoB,QAMf,wBAAqB","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The web barrel, which exists to NAME the `.web` siblings.
5
+ *
6
+ * Export conditions do not apply to relative specifiers, so a bundler that is
7
+ * not Metro reaches `MediaFlightLayer.web.tsx` and `MediaFlightHost.web.tsx`
8
+ * only because this file spells them out. Those two are the whole web fork of
9
+ * this family: the layer that paints each shared media node once, and the host
10
+ * that claims it. Everything else below is the same module on both platforms.
11
+ */
12
+ export { MediaFlightLayer } from "./MediaFlightLayer.web.js";
13
+ export { MediaFlightHost } from "./MediaFlightHost.web.js";
14
+ export { MediaSurface, MediaPoster, EmptyMediaSurface } from "./MediaSurface.js";
15
+ export { useMediaFlight } from "./use-media-flight.js";
16
+ export { DEFAULT_FLIGHT_CORNER_RADIUS, flightProgress, handOffFlight, hasFlight, releaseFlight, resetMediaFlight } from "./store.js";
17
+ export { SURFACE_MOUNT_TIMEOUT_MS } from "./constants.js";
18
+ export { loadExpoVideo, warnExpoVideoUnavailable, provideExpoVideo, resetExpoVideoModule } from "./expo-video-module.js";
19
+ //# sourceMappingURL=index.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["MediaFlightLayer","MediaFlightHost","MediaSurface","MediaPoster","EmptyMediaSurface","useMediaFlight","DEFAULT_FLIGHT_CORNER_RADIUS","flightProgress","handOffFlight","hasFlight","releaseFlight","resetMediaFlight","SURFACE_MOUNT_TIMEOUT_MS","loadExpoVideo","warnExpoVideoUnavailable","provideExpoVideo","resetExpoVideoModule"],"sourceRoot":"../../../src","sources":["media-flight/index.web.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,gBAAgB,QAAQ,2BAAwB;AACzD,SAASC,eAAe,QAAQ,0BAAuB;AACvD,SAASC,YAAY,EAAEC,WAAW,EAAEC,iBAAiB,QAAQ,mBAAgB;AAC7E,SAASC,cAAc,QAAQ,uBAAoB;AACnD,SACEC,4BAA4B,EAC5BC,cAAc,EACdC,aAAa,EACbC,SAAS,EACTC,aAAa,EACbC,gBAAgB,QACX,YAAS;AAChB,SAASC,wBAAwB,QAAQ,gBAAa;AACtD,SACEC,aAAa,EACbC,wBAAwB,EACxBC,gBAAgB,EAChBC,oBAAoB,QAMf,wBAAqB","ignoreList":[]}
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * ONE DOM node per media id, for its whole life.
5
+ *
6
+ * ## Why this exists
7
+ *
8
+ * expo-video's web player keeps a SET of mounted `<video>` elements and keeps
9
+ * them in step: `mountVideoView` adds an element and then copies play state and
10
+ * `currentTime` onto it from `[...set][0]`, and `_addListeners` gives every
11
+ * element an `onpause` that pauses all the OTHERS. `unmountVideoView` deletes
12
+ * the element from the set and nothing more — the handlers it installed are
13
+ * never removed by anything in the package.
14
+ *
15
+ * So an element on its way out still governs the player. The browser pauses a
16
+ * `<video>` the moment it leaves the document, that pause runs the dead
17
+ * element's handler, and the handler stops the element the viewer is watching.
18
+ *
19
+ * Measured against the real `VideoPlayerWeb` (expo-video 57.0.2), across every
20
+ * topology a consumer can produce on one shared player:
21
+ *
22
+ * ```
23
+ * origin dies BEFORE the destination mounts ct=0 playing (restarts)
24
+ * origin dies AFTER the destination mounts ct=4.28 paused (freezes)
25
+ * one element, re-parented ct=4.28 playing
26
+ * ```
27
+ *
28
+ * TWO ELEMENTS GIVE THE POSITION OR THE PLAYBACK, NEVER BOTH. That is not a
29
+ * property of the flight layer — the first two rows have no Bloom surface in
30
+ * them at all — it is a property of two elements sharing one player. The only
31
+ * topology that gives both is one element that is never unmounted and never
32
+ * removed from the document.
33
+ *
34
+ * ## How a node survives its host
35
+ *
36
+ * A `<video>` React renders belongs to React: when the host unmounts, React
37
+ * removes it, and if anything has moved it in the meantime React's
38
+ * `parent.removeChild(node)` throws. So the node cannot be owned by either end.
39
+ *
40
+ * Instead Bloom creates a WRAPPER outside React (`document.createElement`) and
41
+ * the layer renders the media into it with `createPortal`. A portal's container
42
+ * is not part of React's tree — React reconciles the media against the wrapper
43
+ * and never against the document — so moving the wrapper between hosts with
44
+ * `appendChild` is invisible to React. The container's IDENTITY never changes,
45
+ * which is the whole trick: `createPortal` to a container that CHANGES unmounts
46
+ * and remounts, which is exactly what we are avoiding.
47
+ *
48
+ * And a synchronous move does not pause the video. HTML's removal steps for a
49
+ * media element await a stable state and then abort if the element is back in a
50
+ * document — so `appendChild` from one parent to another is not a removal as
51
+ * far as playback is concerned. (This is why re-parenting a `<video>` works and
52
+ * re-parenting an `<iframe>` does not: an iframe reloads.)
53
+ *
54
+ * ## Claims
55
+ *
56
+ * Hosts do not move the node themselves; they CLAIM the id and the registry
57
+ * decides. A flight outranks a host, so the layer keeps the node for the whole
58
+ * leg even though the destination has already mounted and claimed it — and the
59
+ * frame the flight lets go is the frame the destination takes it, with no gap
60
+ * and no second element. With no claim at all the node parks in a holder that
61
+ * is attached to the document but invisible, because a parked node that was
62
+ * DETACHED would pause.
63
+ */
64
+ import { hasFlight } from "./store.js";
65
+
66
+ /** What the layer paints into a shared node, as its current holder wants it. */
67
+
68
+ /** A flight outranks a host: the layer holds the node until the leg ends. */
69
+ export const HOST_RANK = 0;
70
+ export const FLIGHT_RANK = 1;
71
+
72
+ /** What the layer needs in order to paint one shared node. */
73
+
74
+ function registry() {
75
+ globalThis.__oxyhq_bloom_media_nodes__ ??= {
76
+ nodes: new Map(),
77
+ listeners: new Set(),
78
+ snapshot: [],
79
+ holder: null,
80
+ seq: 0
81
+ };
82
+ return globalThis.__oxyhq_bloom_media_nodes__;
83
+ }
84
+
85
+ /** Where a node with no holder waits: in the document, and not on screen. */
86
+ const HOLDER_ID = 'bloom-media-holder';
87
+ function holder(reg) {
88
+ if (typeof document === 'undefined') return null;
89
+ if (reg.holder !== null && reg.holder.isConnected) return reg.holder;
90
+ const existing = document.getElementById(HOLDER_ID);
91
+ if (existing !== null) {
92
+ reg.holder = existing;
93
+ return existing;
94
+ }
95
+ const created = document.createElement('div');
96
+ created.id = HOLDER_ID;
97
+ // Attached, so nothing pauses; 1x1 and transparent, so nothing shows. NOT
98
+ // `display: none` — a video in a `display: none` subtree keeps playing in
99
+ // every browser that matters, but it also stops presenting frames, and the
100
+ // point of parking is that the media survives untouched.
101
+ created.style.cssText = 'position:fixed;top:0;left:0;width:1px;height:1px;overflow:hidden;opacity:0;pointer-events:none;';
102
+ created.setAttribute('aria-hidden', 'true');
103
+ document.body.appendChild(created);
104
+ reg.holder = created;
105
+ return created;
106
+ }
107
+ function makeWrapper() {
108
+ const wrapper = document.createElement('div');
109
+ // Fills whichever box currently hosts it. `pointer-events: auto` is explicit
110
+ // and load-bearing: a host may sit inside a `pointer-events: none` layer (a
111
+ // poster overlay, a flying surface), and the media inside this wrapper is
112
+ // the one thing in there that a viewer may need to press.
113
+ wrapper.style.cssText = 'position:absolute;top:0;left:0;right:0;bottom:0;pointer-events:auto;';
114
+ wrapper.setAttribute('data-bloom-media-node', '');
115
+ return wrapper;
116
+ }
117
+ function recordFor(id, render) {
118
+ const reg = registry();
119
+ let record = reg.nodes.get(id);
120
+ if (!record) {
121
+ record = {
122
+ wrapper: makeWrapper(),
123
+ claims: [],
124
+ render
125
+ };
126
+ reg.nodes.set(id, record);
127
+ }
128
+ return record;
129
+ }
130
+
131
+ /** The claim that currently holds the node: highest rank, then most recent. */
132
+ function topClaim(record) {
133
+ let best = null;
134
+ for (const claim of record.claims) {
135
+ if (best === null || claim.rank > best.rank || claim.rank === best.rank && claim.seq > best.seq) {
136
+ best = claim;
137
+ }
138
+ }
139
+ return best;
140
+ }
141
+
142
+ /**
143
+ * Put the wrapper where its top claim says, in ONE synchronous move.
144
+ *
145
+ * The `parentElement` check is not an optimisation: re-appending to the same
146
+ * parent is a remove-then-insert, and doing that per render would put the media
147
+ * through the removal path it exists to avoid.
148
+ */
149
+ function place(record) {
150
+ const reg = registry();
151
+ const target = topClaim(record)?.el ?? holder(reg);
152
+ if (target === null) return;
153
+ if (record.wrapper.parentElement === target) return;
154
+ target.appendChild(record.wrapper);
155
+ }
156
+ function sameRender(a, b) {
157
+ if (a.contentFit !== b.contentFit) return false;
158
+ if (a.nativeControls !== b.nativeControls) return false;
159
+ if (a.accessibilityLabel !== b.accessibilityLabel) return false;
160
+ if (a.flightId !== b.flightId) return false;
161
+ const x = a.content;
162
+ const y = b.content;
163
+ if (x.kind !== y.kind) return false;
164
+ if (x.kind === 'video' && y.kind === 'video') {
165
+ return x.player === y.player && x.poster === y.poster;
166
+ }
167
+ return x.kind !== 'video' && y.kind !== 'video' && x.uri === y.uri;
168
+ }
169
+ function publish(reg) {
170
+ const next = [];
171
+ for (const [id, record] of reg.nodes) {
172
+ record.render = topClaim(record)?.render ?? record.render;
173
+ next.push({
174
+ id,
175
+ wrapper: record.wrapper,
176
+ render: record.render
177
+ });
178
+ }
179
+ const previous = reg.snapshot;
180
+ const unchanged = previous.length === next.length && previous.every((view, i) => {
181
+ const candidate = next[i];
182
+ return candidate !== undefined && candidate.id === view.id && candidate.wrapper === view.wrapper && sameRender(candidate.render, view.render);
183
+ });
184
+ // Identity is the signal `useSyncExternalStore` reads. Publishing a fresh
185
+ // array for an unchanged set renders the layer forever.
186
+ if (unchanged) {
187
+ for (const listener of reg.listeners) listener();
188
+ return;
189
+ }
190
+ reg.snapshot = next;
191
+ for (const listener of reg.listeners) listener();
192
+ }
193
+
194
+ /**
195
+ * Claim the shared node for `id` into `el`.
196
+ *
197
+ * Idempotent for an unchanged claim: called from a layout effect on every
198
+ * render, it moves the node once and publishes nothing afterwards.
199
+ */
200
+ export function claimMediaNode(id, el, rank, render) {
201
+ const reg = registry();
202
+ const record = recordFor(id, render);
203
+ const existing = record.claims.find(claim => claim.el === el && claim.rank === rank);
204
+ if (existing !== undefined) {
205
+ if (sameRender(existing.render, render) && record.wrapper.parentElement === topClaim(record)?.el) {
206
+ return;
207
+ }
208
+ existing.render = render;
209
+ } else {
210
+ reg.seq += 1;
211
+ record.claims.push({
212
+ el,
213
+ rank,
214
+ seq: reg.seq,
215
+ render
216
+ });
217
+ }
218
+ place(record);
219
+ publish(reg);
220
+ }
221
+
222
+ /**
223
+ * Drop a claim. The node goes to the next claim, or parks — or is DISPOSED, if
224
+ * nothing is going to want it back.
225
+ *
226
+ * "Nothing is going to want it back" is a fact the registry can read rather
227
+ * than a timeout it has to guess: no claim left AND no flight live for this id.
228
+ * During a navigation there IS a flight live — that is what a flight IS — so
229
+ * the node survives the gap between the origin unmounting and the destination
230
+ * mounting. Without a flight, an unmounted host is just a host that went away.
231
+ */
232
+ export function releaseMediaNode(id, el, rank) {
233
+ const reg = registry();
234
+ const record = reg.nodes.get(id);
235
+ if (record === undefined) return;
236
+ const before = record.claims.length;
237
+ record.claims = record.claims.filter(claim => !(claim.el === el && claim.rank === rank));
238
+ if (record.claims.length === before) return;
239
+ if (record.claims.length === 0 && !hasFlight(id)) {
240
+ reg.nodes.delete(id);
241
+ record.wrapper.remove();
242
+ publish(reg);
243
+ return;
244
+ }
245
+ place(record);
246
+ publish(reg);
247
+ }
248
+
249
+ /** Whether anything holds a shared node for this id. */
250
+ export function hasMediaNode(id) {
251
+ const record = registry().nodes.get(id);
252
+ return record !== undefined && record.claims.length > 0;
253
+ }
254
+
255
+ /** Subscribe to the shared-node set. The layer's `useSyncExternalStore` half. */
256
+ export function subscribeToMediaNodes(listener) {
257
+ const reg = registry();
258
+ reg.listeners.add(listener);
259
+ return () => {
260
+ reg.listeners.delete(listener);
261
+ };
262
+ }
263
+
264
+ /** Every shared node that something is currently holding. Stable identity. */
265
+ export function getMediaNodes() {
266
+ return registry().snapshot;
267
+ }
268
+
269
+ /** Test seam: drop every node and take its wrapper out of the document. */
270
+ export function resetMediaNodes() {
271
+ const reg = registry();
272
+ for (const record of reg.nodes.values()) record.wrapper.remove();
273
+ reg.nodes.clear();
274
+ reg.snapshot = [];
275
+ if (reg.holder !== null) {
276
+ reg.holder.remove();
277
+ reg.holder = null;
278
+ }
279
+ for (const listener of reg.listeners) listener();
280
+ }
281
+ //# sourceMappingURL=media-node.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["hasFlight","HOST_RANK","FLIGHT_RANK","registry","globalThis","__oxyhq_bloom_media_nodes__","nodes","Map","listeners","Set","snapshot","holder","seq","HOLDER_ID","reg","document","isConnected","existing","getElementById","created","createElement","id","style","cssText","setAttribute","body","appendChild","makeWrapper","wrapper","recordFor","render","record","get","claims","set","topClaim","best","claim","rank","place","target","el","parentElement","sameRender","a","b","contentFit","nativeControls","accessibilityLabel","flightId","x","content","y","kind","player","poster","uri","publish","next","push","previous","unchanged","length","every","view","i","candidate","undefined","listener","claimMediaNode","find","releaseMediaNode","before","filter","delete","remove","hasMediaNode","subscribeToMediaNodes","add","getMediaNodes","resetMediaNodes","values","clear"],"sourceRoot":"../../../src","sources":["media-flight/media-node.web.ts"],"mappings":"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","ignoreList":[]}
@@ -355,10 +355,25 @@ export function flyBack(id) {
355
355
  * nobody having called `pause()`.
356
356
  *
357
357
  * Rendering `player={null}` for one commit runs expo-video's own `[props.player]`
358
- * effect while the node is STILL in the DOM: its cleanup calls
359
- * `unmountVideoView`, the element leaves `_mountedVideos`, and its later pause
360
- * reaches nobody. That is the documented mount/unmount pair, not a patch of
361
- * somebody else's module.
358
+ * effect while the node is STILL in the DOM, and the operative part of that is
359
+ * NOT the unbind. `unmountVideoView` takes the element out of `_mountedVideos`
360
+ * and leaves the `onpause` handler `_addListeners` installed, so unbinding
361
+ * alone would still mirror. What saves it is the other half of the same
362
+ * branch: `removeAttribute('src'); load()` (`VideoView.web.js:206`). The media
363
+ * element load algorithm sets `paused` to true WITHOUT firing `pause`, so the
364
+ * element goes quiet, and its later removal fires nothing either because it is
365
+ * already paused.
366
+ *
367
+ * Measured in real Chrome, with controls: a playing element put through
368
+ * `removeAttribute('src') + load()` reports events `["play"]` and nothing more,
369
+ * while the same element paused by hand, or removed from the DOM while
370
+ * playing, reports `["play","pause"]`. Against real builds: without this commit
371
+ * the destination ends STOPPED (5/5), with it PLAYING (6/6) and the position
372
+ * carried.
373
+ *
374
+ * DO NOT replace this with a direct `unmountVideoView` call. It looks
375
+ * equivalent, it is the half that does not matter, and the fix would disappear
376
+ * silently. `MediaFlight.test.tsx` makes that substitution its control.
362
377
  *
363
378
  * The cost is one frame in which the outgoing surface shows its poster instead
364
379
  * of video. It is already on its way out and the destination is live by then —