@react-three/fiber 9.0.0-rc.5 → 9.0.0-rc.6

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 (31) hide show
  1. package/CHANGELOG.md +1088 -1076
  2. package/dist/declarations/src/core/events.d.ts +91 -91
  3. package/dist/declarations/src/core/hooks.d.ts +51 -51
  4. package/dist/declarations/src/core/index.d.ts +13 -13
  5. package/dist/declarations/src/core/loop.d.ts +31 -31
  6. package/dist/declarations/src/core/reconciler.d.ts +52 -52
  7. package/dist/declarations/src/core/renderer.d.ts +89 -89
  8. package/dist/declarations/src/core/store.d.ts +130 -130
  9. package/dist/declarations/src/core/utils.d.ts +186 -186
  10. package/dist/declarations/src/index.d.ts +6 -6
  11. package/dist/declarations/src/native/Canvas.d.ts +13 -13
  12. package/dist/declarations/src/native/events.d.ts +4 -4
  13. package/dist/declarations/src/native.d.ts +6 -6
  14. package/dist/declarations/src/three-types.d.ts +62 -62
  15. package/dist/declarations/src/web/Canvas.d.ts +23 -23
  16. package/dist/declarations/src/web/events.d.ts +4 -4
  17. package/dist/{events-a7b08b1a.esm.js → events-06bc1550.esm.js} +84 -88
  18. package/dist/{events-b4061ace.cjs.dev.js → events-4464c9d4.cjs.dev.js} +84 -88
  19. package/dist/{events-60ed2d7b.cjs.prod.js → events-79ccf613.cjs.prod.js} +84 -88
  20. package/dist/react-three-fiber.cjs.dev.js +7 -201
  21. package/dist/react-three-fiber.cjs.prod.js +7 -201
  22. package/dist/react-three-fiber.esm.js +6 -201
  23. package/native/dist/react-three-fiber-native.cjs.d.ts +2 -0
  24. package/native/dist/react-three-fiber-native.cjs.dev.js +554 -0
  25. package/native/dist/react-three-fiber-native.cjs.js +7 -0
  26. package/native/dist/react-three-fiber-native.cjs.prod.js +554 -0
  27. package/native/dist/react-three-fiber-native.esm.js +502 -0
  28. package/native/package.json +5 -5
  29. package/package.json +87 -88
  30. package/readme.md +253 -253
  31. package/dist/declarations/src/web/use-measure.d.ts +0 -34
@@ -0,0 +1,554 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var events = require('../../dist/events-79ccf613.cjs.prod.js');
6
+ var React = require('react');
7
+ var THREE = require('three');
8
+ var reactNative = require('react-native');
9
+ var expoGl = require('expo-gl');
10
+ var itsFine = require('its-fine');
11
+ var jsxRuntime = require('react/jsx-runtime');
12
+ var expoAsset = require('expo-asset');
13
+ var fs = require('expo-file-system');
14
+ var base64Js = require('base64-js');
15
+ var buffer = require('buffer');
16
+ require('react-reconciler/constants');
17
+ require('zustand/traditional');
18
+ require('react-reconciler');
19
+ require('scheduler');
20
+ require('suspend-react');
21
+
22
+ function _interopNamespace(e) {
23
+ if (e && e.__esModule) return e;
24
+ var n = Object.create(null);
25
+ if (e) {
26
+ Object.keys(e).forEach(function (k) {
27
+ if (k !== 'default') {
28
+ var d = Object.getOwnPropertyDescriptor(e, k);
29
+ Object.defineProperty(n, k, d.get ? d : {
30
+ enumerable: true,
31
+ get: function () { return e[k]; }
32
+ });
33
+ }
34
+ });
35
+ }
36
+ n["default"] = e;
37
+ return Object.freeze(n);
38
+ }
39
+
40
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
41
+ var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
42
+ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
43
+
44
+ // TODO: React 19 needs support from react-native
45
+ const _View = reactNative.View;
46
+ function CanvasImpl({
47
+ children,
48
+ style,
49
+ gl,
50
+ events: events$1 = events.createPointerEvents,
51
+ shadows,
52
+ linear,
53
+ flat,
54
+ legacy,
55
+ orthographic,
56
+ frameloop,
57
+ performance,
58
+ raycaster,
59
+ camera,
60
+ scene,
61
+ onPointerMissed,
62
+ onCreated,
63
+ ref,
64
+ ...props
65
+ }) {
66
+ // Create a known catalogue of Threejs-native elements
67
+ // This will include the entire THREE namespace by default, users can extend
68
+ // their own elements by using the createRoot API instead
69
+ React__namespace.useMemo(() => events.extend(THREE__namespace), []);
70
+ const Bridge = events.useBridge();
71
+ const [{
72
+ width,
73
+ height,
74
+ top,
75
+ left
76
+ }, setSize] = React__namespace.useState({
77
+ width: 0,
78
+ height: 0,
79
+ top: 0,
80
+ left: 0
81
+ });
82
+ const [canvas, setCanvas] = React__namespace.useState(null);
83
+ const [bind, setBind] = React__namespace.useState();
84
+ React__namespace.useImperativeHandle(ref, () => viewRef.current);
85
+ const handlePointerMissed = events.useMutableCallback(onPointerMissed);
86
+ const [block, setBlock] = React__namespace.useState(false);
87
+ const [error, setError] = React__namespace.useState(undefined);
88
+
89
+ // Suspend this component if block is a promise (2nd run)
90
+ if (block) throw block;
91
+ // Throw exception outwards if anything within canvas throws
92
+ if (error) throw error;
93
+ const viewRef = React__namespace.useRef(null);
94
+ const root = React__namespace.useRef(null);
95
+ const [antialias, setAntialias] = React__namespace.useState(true);
96
+ const onLayout = React__namespace.useCallback(e => {
97
+ const {
98
+ width,
99
+ height,
100
+ x,
101
+ y
102
+ } = e.nativeEvent.layout;
103
+ setSize({
104
+ width,
105
+ height,
106
+ top: y,
107
+ left: x
108
+ });
109
+ }, []);
110
+
111
+ // Called on context create or swap
112
+ // https://github.com/pmndrs/react-three-fiber/pull/2297
113
+ const onContextCreate = React__namespace.useCallback(context => {
114
+ const listeners = new Map();
115
+ const canvas = {
116
+ style: {},
117
+ width: context.drawingBufferWidth,
118
+ height: context.drawingBufferHeight,
119
+ clientWidth: context.drawingBufferWidth,
120
+ clientHeight: context.drawingBufferHeight,
121
+ getContext: (_, {
122
+ antialias = false
123
+ }) => {
124
+ setAntialias(antialias);
125
+ return context;
126
+ },
127
+ addEventListener(type, listener) {
128
+ let callbacks = listeners.get(type);
129
+ if (!callbacks) {
130
+ callbacks = [];
131
+ listeners.set(type, callbacks);
132
+ }
133
+ callbacks.push(listener);
134
+ },
135
+ removeEventListener(type, listener) {
136
+ const callbacks = listeners.get(type);
137
+ if (callbacks) {
138
+ const index = callbacks.indexOf(listener);
139
+ if (index !== -1) callbacks.splice(index, 1);
140
+ }
141
+ },
142
+ dispatchEvent(event) {
143
+ Object.assign(event, {
144
+ target: this
145
+ });
146
+ const callbacks = listeners.get(event.type);
147
+ if (callbacks) {
148
+ for (const callback of callbacks) {
149
+ callback(event);
150
+ }
151
+ }
152
+ },
153
+ setPointerCapture() {
154
+ // TODO
155
+ },
156
+ releasePointerCapture() {
157
+ // TODO
158
+ }
159
+ };
160
+
161
+ // TODO: this is wrong but necessary to trick controls
162
+ // @ts-ignore
163
+ canvas.ownerDocument = canvas;
164
+ canvas.getRootNode = () => canvas;
165
+ root.current = events.createRoot(canvas);
166
+ setCanvas(canvas);
167
+ function handleTouch(gestureEvent, type) {
168
+ gestureEvent.persist();
169
+ canvas.dispatchEvent(Object.assign(gestureEvent.nativeEvent, {
170
+ type,
171
+ offsetX: gestureEvent.nativeEvent.locationX,
172
+ offsetY: gestureEvent.nativeEvent.locationY,
173
+ pointerType: 'touch',
174
+ pointerId: gestureEvent.nativeEvent.identifier
175
+ }));
176
+ return true;
177
+ }
178
+ const responder = reactNative.PanResponder.create({
179
+ onStartShouldSetPanResponder: () => true,
180
+ onMoveShouldSetPanResponder: () => true,
181
+ onMoveShouldSetPanResponderCapture: () => true,
182
+ onPanResponderTerminationRequest: () => true,
183
+ onStartShouldSetPanResponderCapture: e => handleTouch(e, 'pointercapture'),
184
+ onPanResponderStart: e => handleTouch(e, 'pointerdown'),
185
+ onPanResponderMove: e => handleTouch(e, 'pointermove'),
186
+ onPanResponderEnd: (e, state) => {
187
+ handleTouch(e, 'pointerup');
188
+ if (Math.hypot(state.dx, state.dy) < 20) handleTouch(e, 'click');
189
+ },
190
+ onPanResponderRelease: e => handleTouch(e, 'pointerleave'),
191
+ onPanResponderTerminate: e => handleTouch(e, 'lostpointercapture'),
192
+ onPanResponderReject: e => handleTouch(e, 'lostpointercapture')
193
+ });
194
+ setBind(responder.panHandlers);
195
+ }, []);
196
+ events.useIsomorphicLayoutEffect(() => {
197
+ if (root.current && width > 0 && height > 0) {
198
+ async function run() {
199
+ await root.current.configure({
200
+ gl,
201
+ events: events$1,
202
+ shadows,
203
+ linear,
204
+ flat,
205
+ legacy,
206
+ orthographic,
207
+ frameloop,
208
+ performance,
209
+ raycaster,
210
+ camera,
211
+ scene,
212
+ // expo-gl can only render at native dpr/resolution
213
+ // https://github.com/expo/expo-three/issues/39
214
+ dpr: reactNative.PixelRatio.get(),
215
+ size: {
216
+ width,
217
+ height,
218
+ top,
219
+ left
220
+ },
221
+ // Pass mutable reference to onPointerMissed so it's free to update
222
+ onPointerMissed: (...args) => handlePointerMissed.current == null ? void 0 : handlePointerMissed.current(...args),
223
+ // Overwrite onCreated to apply RN bindings
224
+ onCreated: state => {
225
+ // Bind render to RN bridge
226
+ const context = state.gl.getContext();
227
+ const renderFrame = state.gl.render.bind(state.gl);
228
+ state.gl.render = (scene, camera) => {
229
+ renderFrame(scene, camera);
230
+ context.endFrameEXP();
231
+ };
232
+ return onCreated == null ? void 0 : onCreated(state);
233
+ }
234
+ });
235
+ root.current.render( /*#__PURE__*/jsxRuntime.jsx(Bridge, {
236
+ children: /*#__PURE__*/jsxRuntime.jsx(events.ErrorBoundary, {
237
+ set: setError,
238
+ children: /*#__PURE__*/jsxRuntime.jsx(React__namespace.Suspense, {
239
+ fallback: /*#__PURE__*/jsxRuntime.jsx(events.Block, {
240
+ set: setBlock
241
+ }),
242
+ children: children
243
+ })
244
+ })
245
+ }));
246
+ }
247
+ run();
248
+ }
249
+ });
250
+ React__namespace.useEffect(() => {
251
+ if (canvas) {
252
+ return () => events.unmountComponentAtNode(canvas);
253
+ }
254
+ }, [canvas]);
255
+ return /*#__PURE__*/jsxRuntime.jsx(_View, {
256
+ ...props,
257
+ ref: viewRef,
258
+ onLayout: onLayout,
259
+ style: {
260
+ flex: 1,
261
+ ...style
262
+ },
263
+ ...bind,
264
+ children: width > 0 && /*#__PURE__*/jsxRuntime.jsx(expoGl.GLView, {
265
+ msaaSamples: antialias ? 4 : 0,
266
+ onContextCreate: onContextCreate,
267
+ style: reactNative.StyleSheet.absoluteFill
268
+ })
269
+ });
270
+ }
271
+
272
+ /**
273
+ * A native canvas which accepts threejs elements as children.
274
+ * @see https://docs.pmnd.rs/react-three-fiber/api/canvas
275
+ */
276
+ function Canvas(props) {
277
+ return /*#__PURE__*/jsxRuntime.jsx(itsFine.FiberProvider, {
278
+ children: /*#__PURE__*/jsxRuntime.jsx(CanvasImpl, {
279
+ ...props
280
+ })
281
+ });
282
+ }
283
+
284
+ /** Default R3F event manager for react-native */
285
+ function createTouchEvents(store) {
286
+ const {
287
+ handlePointer
288
+ } = events.createEvents(store);
289
+ const handleTouch = (event, name) => {
290
+ event.persist()
291
+
292
+ // Apply offset
293
+ ;
294
+ event.nativeEvent.offsetX = event.nativeEvent.locationX;
295
+ event.nativeEvent.offsetY = event.nativeEvent.locationY;
296
+
297
+ // Emulate DOM event
298
+ const callback = handlePointer(name);
299
+ callback(event.nativeEvent);
300
+ return true;
301
+ };
302
+ const responder = reactNative.PanResponder.create({
303
+ onStartShouldSetPanResponder: () => true,
304
+ onMoveShouldSetPanResponder: () => true,
305
+ onMoveShouldSetPanResponderCapture: () => true,
306
+ onPanResponderTerminationRequest: () => true,
307
+ onStartShouldSetPanResponderCapture: e => handleTouch(e, 'onPointerCapture'),
308
+ onPanResponderStart: e => handleTouch(e, 'onPointerDown'),
309
+ onPanResponderMove: e => handleTouch(e, 'onPointerMove'),
310
+ onPanResponderEnd: (e, state) => {
311
+ handleTouch(e, 'onPointerUp');
312
+ if (Math.hypot(state.dx, state.dy) < 20) handleTouch(e, 'onClick');
313
+ },
314
+ onPanResponderRelease: e => handleTouch(e, 'onPointerLeave'),
315
+ onPanResponderTerminate: e => handleTouch(e, 'onLostPointerCapture'),
316
+ onPanResponderReject: e => handleTouch(e, 'onLostPointerCapture')
317
+ });
318
+ return {
319
+ priority: 1,
320
+ enabled: true,
321
+ compute(event, state, previous) {
322
+ // https://github.com/pmndrs/react-three-fiber/pull/782
323
+ // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
324
+ state.pointer.set(event.offsetX / state.size.width * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
325
+ state.raycaster.setFromCamera(state.pointer, state.camera);
326
+ },
327
+ connected: undefined,
328
+ handlers: responder.panHandlers,
329
+ update: () => {
330
+ var _internal$lastEvent;
331
+ const {
332
+ events,
333
+ internal
334
+ } = store.getState();
335
+ if ((_internal$lastEvent = internal.lastEvent) != null && _internal$lastEvent.current && events.handlers) {
336
+ handlePointer('onPointerMove')(internal.lastEvent.current);
337
+ }
338
+ },
339
+ connect: () => {
340
+ const {
341
+ set,
342
+ events
343
+ } = store.getState();
344
+ events.disconnect == null ? void 0 : events.disconnect();
345
+ set(state => ({
346
+ events: {
347
+ ...state.events,
348
+ connected: true
349
+ }
350
+ }));
351
+ },
352
+ disconnect: () => {
353
+ const {
354
+ set
355
+ } = store.getState();
356
+ set(state => ({
357
+ events: {
358
+ ...state.events,
359
+ connected: false
360
+ }
361
+ }));
362
+ }
363
+ };
364
+ }
365
+
366
+ // http://stackoverflow.com/questions/105034
367
+ function uuidv4() {
368
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
369
+ const r = Math.random() * 16 | 0,
370
+ v = c == 'x' ? r : r & 0x3 | 0x8;
371
+ return v.toString(16);
372
+ });
373
+ }
374
+ async function getAsset(input) {
375
+ if (typeof input === 'string') {
376
+ var _NativeModules$BlobMo;
377
+ // Don't process storage
378
+ if (input.startsWith('file:')) return input;
379
+
380
+ // Unpack Blobs from react-native BlobManager
381
+ // https://github.com/facebook/react-native/issues/22681#issuecomment-523258955
382
+ if (input.startsWith('blob:') || input.startsWith((_NativeModules$BlobMo = reactNative.NativeModules.BlobModule) == null ? void 0 : _NativeModules$BlobMo.BLOB_URI_SCHEME)) {
383
+ const blob = await new Promise((res, rej) => {
384
+ const xhr = new XMLHttpRequest();
385
+ xhr.open('GET', input);
386
+ xhr.responseType = 'blob';
387
+ xhr.onload = () => res(xhr.response);
388
+ xhr.onerror = rej;
389
+ xhr.send();
390
+ });
391
+ const data = await new Promise((res, rej) => {
392
+ const reader = new FileReader();
393
+ reader.onload = () => res(reader.result);
394
+ reader.onerror = rej;
395
+ reader.readAsText(blob);
396
+ });
397
+ input = `data:${blob.type};base64,${data}`;
398
+ }
399
+
400
+ // Create safe URI for JSI serialization
401
+ if (input.startsWith('data:')) {
402
+ const [header, data] = input.split(';base64,');
403
+ const [, type] = header.split('/');
404
+ const uri = fs__namespace.cacheDirectory + uuidv4() + `.${type}`;
405
+ await fs__namespace.writeAsStringAsync(uri, data, {
406
+ encoding: fs__namespace.EncodingType.Base64
407
+ });
408
+ return uri;
409
+ }
410
+ }
411
+
412
+ // Download bundler module or external URL
413
+ const asset = await expoAsset.Asset.fromModule(input).downloadAsync();
414
+ let uri = asset.localUri || asset.uri;
415
+
416
+ // Unpack assets in Android Release Mode
417
+ if (!uri.includes(':')) {
418
+ const file = `${fs__namespace.cacheDirectory}ExponentAsset-${asset.hash}.${asset.type}`;
419
+ await fs__namespace.copyAsync({
420
+ from: uri,
421
+ to: file
422
+ });
423
+ uri = file;
424
+ }
425
+ return uri;
426
+ }
427
+ function polyfills() {
428
+ // Patch Blob for ArrayBuffer and URL if unsupported
429
+ // https://github.com/facebook/react-native/pull/39276
430
+ // https://github.com/pmndrs/react-three-fiber/issues/3058
431
+ if (reactNative.Platform.OS !== 'web') {
432
+ try {
433
+ const blob = new Blob([new ArrayBuffer(4)]);
434
+ const url = URL.createObjectURL(blob);
435
+ URL.revokeObjectURL(url);
436
+ } catch (_) {
437
+ const BlobManager = require('react-native/Libraries/Blob/BlobManager.js');
438
+ const createObjectURL = URL.createObjectURL;
439
+ URL.createObjectURL = function (blob) {
440
+ if (blob.data._base64) {
441
+ return `data:${blob.type};base64,${blob.data._base64}`;
442
+ }
443
+ return createObjectURL(blob);
444
+ };
445
+ const createFromParts = BlobManager.createFromParts;
446
+ BlobManager.createFromParts = function (parts, options) {
447
+ parts = parts.map(part => {
448
+ if (part instanceof ArrayBuffer || ArrayBuffer.isView(part)) {
449
+ part = base64Js.fromByteArray(new Uint8Array(part));
450
+ }
451
+ return part;
452
+ });
453
+ const blob = createFromParts(parts, options);
454
+
455
+ // Always enable slow but safe path for iOS (previously for Android unauth)
456
+ // https://github.com/pmndrs/react-three-fiber/issues/3075
457
+ // if (!NativeModules.BlobModule?.BLOB_URI_SCHEME) {
458
+ blob.data._base64 = '';
459
+ for (const part of parts) {
460
+ var _data$_base, _data;
461
+ blob.data._base64 += (_data$_base = (_data = part.data) == null ? void 0 : _data._base64) != null ? _data$_base : part;
462
+ }
463
+ // }
464
+
465
+ return blob;
466
+ };
467
+ }
468
+ }
469
+
470
+ // Don't pre-process urls, let expo-asset generate an absolute URL
471
+ const extractUrlBase = THREE__namespace.LoaderUtils.extractUrlBase.bind(THREE__namespace.LoaderUtils);
472
+ THREE__namespace.LoaderUtils.extractUrlBase = url => typeof url === 'string' ? extractUrlBase(url) : './';
473
+
474
+ // There's no Image in native, so create a data texture instead
475
+ THREE__namespace.TextureLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
476
+ if (this.path && typeof url === 'string') url = this.path + url;
477
+ const texture = new THREE__namespace.Texture();
478
+ getAsset(url).then(async uri => {
479
+ // https://github.com/expo/expo-three/pull/266
480
+ const {
481
+ width,
482
+ height
483
+ } = await new Promise((res, rej) => reactNative.Image.getSize(uri, (width, height) => res({
484
+ width,
485
+ height
486
+ }), rej));
487
+ texture.image = {
488
+ // Special case for EXGLImageUtils::loadImage
489
+ data: {
490
+ localUri: uri
491
+ },
492
+ width,
493
+ height
494
+ };
495
+ texture.flipY = true; // Since expo-gl@12.4.0
496
+ texture.needsUpdate = true;
497
+
498
+ // Force non-DOM upload for EXGL texImage2D
499
+ // @ts-expect-error
500
+ texture.isDataTexture = true;
501
+ onLoad == null ? void 0 : onLoad(texture);
502
+ }).catch(onError);
503
+ return texture;
504
+ };
505
+
506
+ // Fetches assets via FS
507
+ THREE__namespace.FileLoader.prototype.load = function load(url, onLoad, onProgress, onError) {
508
+ if (this.path && typeof url === 'string') url = this.path + url;
509
+ this.manager.itemStart(url);
510
+ getAsset(url).then(async uri => {
511
+ const base64 = await fs__namespace.readAsStringAsync(uri, {
512
+ encoding: fs__namespace.EncodingType.Base64
513
+ });
514
+ const data = buffer.Buffer.from(base64, 'base64');
515
+ onLoad == null ? void 0 : onLoad(data.buffer);
516
+ }).catch(error => {
517
+ onError == null ? void 0 : onError(error);
518
+ this.manager.itemError(url);
519
+ }).finally(() => {
520
+ this.manager.itemEnd(url);
521
+ });
522
+ };
523
+ }
524
+
525
+ if (reactNative.Platform.OS !== 'web') polyfills();
526
+
527
+ exports.ReactThreeFiber = events.threeTypes;
528
+ exports._roots = events._roots;
529
+ exports.act = events.act;
530
+ exports.addAfterEffect = events.addAfterEffect;
531
+ exports.addEffect = events.addEffect;
532
+ exports.addTail = events.addTail;
533
+ exports.advance = events.advance;
534
+ exports.applyProps = events.applyProps;
535
+ exports.buildGraph = events.buildGraph;
536
+ exports.context = events.context;
537
+ exports.createEvents = events.createEvents;
538
+ exports.createPortal = events.createPortal;
539
+ exports.createRoot = events.createRoot;
540
+ exports.dispose = events.dispose;
541
+ exports.extend = events.extend;
542
+ exports.flushGlobalEffects = events.flushGlobalEffects;
543
+ exports.getRootState = events.getRootState;
544
+ exports.invalidate = events.invalidate;
545
+ exports.reconciler = events.reconciler;
546
+ exports.unmountComponentAtNode = events.unmountComponentAtNode;
547
+ exports.useFrame = events.useFrame;
548
+ exports.useGraph = events.useGraph;
549
+ exports.useInstanceHandle = events.useInstanceHandle;
550
+ exports.useLoader = events.useLoader;
551
+ exports.useStore = events.useStore;
552
+ exports.useThree = events.useThree;
553
+ exports.Canvas = Canvas;
554
+ exports.events = createTouchEvents;