@threlte/xr 1.0.2 → 1.0.5

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.
@@ -14,7 +14,7 @@
14
14
  import XRButton from './XRButton.svelte'
15
15
  import { defaultFeatures } from '../internal/defaultFeatures'
16
16
 
17
- type Props = Omit<ComponentProps<XRButton>, 'mode' | 'sessionInit'> & {
17
+ type Props = Omit<ComponentProps<typeof XRButton>, 'mode' | 'sessionInit'> & {
18
18
  sessionInit?: XRSessionInit & { domOverlay?: { root: HTMLElement } | undefined }
19
19
  }
20
20
 
@@ -28,6 +28,4 @@
28
28
  }}
29
29
  {...props}
30
30
  mode="immersive-ar"
31
- >
32
- {@render children?.()}
33
- </XRButton>
31
+ />
@@ -8,7 +8,24 @@
8
8
  * />
9
9
  * ```
10
10
  */
11
- declare const ArButton: import("svelte").Component<Omit<Record<string, any>, "mode" | "sessionInit"> & {
11
+ declare const ArButton: import("svelte").Component<Omit<import("svelte/elements").HTMLButtonAttributes & {
12
+ mode: XRSessionMode;
13
+ sessionInit?: XRSessionInit & {
14
+ domOverlay?: {
15
+ root: HTMLElement;
16
+ } | undefined;
17
+ };
18
+ force?: "enter" | "exit";
19
+ styled?: boolean;
20
+ children?: import("svelte").Snippet<[{
21
+ state: "unsupported" | "insecure" | "blocked" | "supported";
22
+ }]>;
23
+ onclick?: (event: {
24
+ state: "unsupported" | "insecure" | "blocked" | "supported";
25
+ nativeEvent: MouseEvent;
26
+ }) => void;
27
+ onerror?: (error: Error) => void;
28
+ }, "mode" | "sessionInit"> & {
12
29
  sessionInit?: XRSessionInit & {
13
30
  domOverlay?: {
14
31
  root: HTMLElement;
@@ -3,7 +3,7 @@
3
3
  -->
4
4
  <script
5
5
  lang="ts"
6
- context="module"
6
+ module
7
7
  >
8
8
  import { writable } from 'svelte/store'
9
9
  import { T } from '@threlte/core'
@@ -1,6 +1,6 @@
1
1
  <script
2
2
  lang="ts"
3
- context="module"
3
+ module
4
4
  >
5
5
  import { Group } from 'three'
6
6
  import { T, useThrelte, useTask } from '@threlte/core'
@@ -86,7 +86,7 @@
86
86
  const { start, stop } = useTask(
87
87
  () => {
88
88
  const frame = xr.getFrame()
89
- const joint = inputSource?.get('wrist' as unknown as number)
89
+ const joint = inputSource?.get('wrist')
90
90
 
91
91
  if (joint === undefined || space === null) return
92
92
 
@@ -14,7 +14,7 @@
14
14
  import XRButton from './XRButton.svelte'
15
15
  import { defaultFeatures } from '../internal/defaultFeatures'
16
16
 
17
- type Props = Omit<ComponentProps<XRButton>, 'mode' | 'sessionInit'>
17
+ type Props = Omit<ComponentProps<typeof XRButton>, 'mode' | 'sessionInit'>
18
18
 
19
19
  let { ...props }: Props = $props()
20
20
  </script>
@@ -8,5 +8,22 @@
8
8
  * />
9
9
  * ```
10
10
  */
11
- declare const VrButton: import("svelte").Component<Omit<Record<string, any>, "mode" | "sessionInit">, {}, "">;
11
+ declare const VrButton: import("svelte").Component<Omit<import("svelte/elements").HTMLButtonAttributes & {
12
+ mode: XRSessionMode;
13
+ sessionInit?: XRSessionInit & {
14
+ domOverlay?: {
15
+ root: HTMLElement;
16
+ } | undefined;
17
+ };
18
+ force?: "enter" | "exit";
19
+ styled?: boolean;
20
+ children?: import("svelte").Snippet<[{
21
+ state: "unsupported" | "insecure" | "blocked" | "supported";
22
+ }]>;
23
+ onclick?: (event: {
24
+ state: "unsupported" | "insecure" | "blocked" | "supported";
25
+ nativeEvent: MouseEvent;
26
+ }) => void;
27
+ onerror?: (error: Error) => void;
28
+ }, "mode" | "sessionInit">, {}, "">;
12
29
  export default VrButton;
@@ -18,7 +18,7 @@ This should be placed within a Threlte `<Canvas />`.
18
18
 
19
19
  -->
20
20
  <script lang="ts">
21
- import { onMount, type Snippet } from 'svelte'
21
+ import { onDestroy, onMount, type Snippet } from 'svelte'
22
22
  import { useThrelte, watch } from '@threlte/core'
23
23
  import type { XRSessionEvent } from '../types'
24
24
  import {
@@ -96,11 +96,11 @@ This should be placed within a Threlte `<Canvas />`.
96
96
 
97
97
  const handleSessionStart = () => {
98
98
  isPresenting.set(true)
99
- onsessionstart?.({ type: 'sessionstart', target: $session! })
99
+ onsessionstart?.({ type: 'sessionstart', target: $session } as any)
100
100
  }
101
101
 
102
102
  const handleSessionEnd = () => {
103
- onsessionend?.({ type: 'sessionend', target: $session! })
103
+ onsessionend?.({ type: 'sessionend', target: $session } as any)
104
104
  isPresenting.set(false)
105
105
  session.set(undefined)
106
106
  }
@@ -109,7 +109,7 @@ This should be placed within a Threlte `<Canvas />`.
109
109
  onvisibilitychange?.({ ...event, target: $session! })
110
110
  }
111
111
 
112
- const handleInputSourcesChange = (event: XRInputSourceChangeEvent) => {
112
+ const handleInputSourcesChange = (event: XRInputSourcesChangeEvent) => {
113
113
  $isHandTracking = Object.values(event.session.inputSources).some((source) => source.hand)
114
114
  oninputsourceschange?.({ ...event, target: $session! })
115
115
  }
@@ -168,6 +168,12 @@ This should be placed within a Threlte `<Canvas />`.
168
168
  xr.removeEventListener('sessionend', handleSessionEnd)
169
169
  }
170
170
  })
171
+ onDestroy(() => {
172
+ // if unmounted while presenting (e.g. due to sveltekit navigation), end the session
173
+ if (session.current) {
174
+ session.current.end()
175
+ }
176
+ })
171
177
 
172
178
  $effect.pre(() => updateTargetFrameRate(frameRate))
173
179
  $effect.pre(() => xr.setFoveation(foveation))
@@ -35,10 +35,10 @@ declare const XrButton: import("svelte").Component<HTMLButtonAttributes & {
35
35
  /** Whether to apply automatic styling to the button. Set false to apply custom styles. Default is true. */
36
36
  styled?: boolean;
37
37
  children?: Snippet<[{
38
- state: "blocked" | "unsupported" | "insecure" | "supported";
38
+ state: "unsupported" | "insecure" | "blocked" | "supported";
39
39
  }]>;
40
40
  onclick?: (event: {
41
- state: "blocked" | "unsupported" | "insecure" | "supported";
41
+ state: "unsupported" | "insecure" | "blocked" | "supported";
42
42
  nativeEvent: MouseEvent;
43
43
  }) => void;
44
44
  onerror?: (error: Error) => void;
@@ -27,12 +27,11 @@ export const setupHands = () => {
27
27
  handEvents[handedness]?.current?.[`on${event.type}`]?.(event);
28
28
  };
29
29
  function handleConnected(event) {
30
- const hand = this;
31
30
  const { model, targetRay } = map.get(this);
32
31
  const { data } = event;
33
32
  const { handedness, hand: inputSource } = data;
34
33
  stores[handedness].set({
35
- hand,
34
+ hand: this,
36
35
  model,
37
36
  inputSource,
38
37
  targetRay
@@ -1,5 +1,4 @@
1
1
  import { onDestroy } from 'svelte';
2
- // @ts-expect-error untyped internal import, when have you ever done me wrong?
3
2
  import { raf } from 'svelte/internal/client';
4
3
  import { watch } from '@threlte/core';
5
4
  import { session } from './stores';
@@ -6,7 +6,7 @@ import { useTask } from '@threlte/core';
6
6
  */
7
7
  export const useFixed = (fn, options) => {
8
8
  let fixedStepTimeAccumulator = 0;
9
- let fixedStep = options.fixedStep ?? 1 / 60;
9
+ const fixedStep = options.fixedStep ?? 1 / 60;
10
10
  return useTask((delta) => {
11
11
  fixedStepTimeAccumulator += delta;
12
12
  while (fixedStepTimeAccumulator >= fixedStep) {
@@ -1,5 +1,4 @@
1
1
  import { injectPlugin, isInstanceOf, observe } from '@threlte/core';
2
- import { untrack } from 'svelte';
3
2
  import { usePointerControls } from './hook';
4
3
  import { events } from './types';
5
4
  export const injectPointerControlsPlugin = () => {
@@ -16,7 +16,7 @@ export const setupPointerControls = (context, handContext, fixedStep = 1 / 40) =
16
16
  const hand = useHand(handedness);
17
17
  const { dispatchers } = getInternalContext();
18
18
  let hits = [];
19
- let lastPosition = new Vector3();
19
+ const lastPosition = new Vector3();
20
20
  const handlePointerDown = (event) => {
21
21
  // Save initial coordinates on pointer-down
22
22
  const [hit] = hits;
@@ -4,7 +4,7 @@ import type { ComputeFunction } from './compute';
4
4
  export type Properties<T> = Pick<T, {
5
5
  [K in keyof T]: T[K] extends (_: any) => any ? never : K;
6
6
  }[keyof T]>;
7
- export interface Intersection extends ThreeIntersection {
7
+ export interface Intersection<T extends Object3D = Object3D> extends ThreeIntersection<T> {
8
8
  /** The event source (the object which registered the handler) */
9
9
  eventObject: Object3D;
10
10
  }
@@ -2,7 +2,7 @@ import { type Mesh, Raycaster, type Intersection } from 'three';
2
2
  import type { CurrentWritable } from '@threlte/core';
3
3
  import type { TeleportControlsOptions } from '.';
4
4
  export type ComputeFunction = (context: Context, handContext: HandContext) => void;
5
- export type TeleportEvents = {};
5
+ export type TeleportEvents = Record<string, (arg: unknown) => void>;
6
6
  export interface Context {
7
7
  interactiveObjects: Mesh[];
8
8
  surfaces: Map<string, Mesh>;
@@ -15,7 +15,7 @@ export const injectTeleportControlsPlugin = () => {
15
15
  $effect(() => {
16
16
  if (!ref)
17
17
  return;
18
- let mesh = ref;
18
+ const mesh = ref;
19
19
  if (isSurface) {
20
20
  addSurface(mesh, args.props);
21
21
  }
@@ -48,7 +48,7 @@ export const injectTeleportControlsPlugin = () => {
48
48
  $effect(() => {
49
49
  if (!ref)
50
50
  return;
51
- let mesh = ref;
51
+ const mesh = ref;
52
52
  if (isBlocker) {
53
53
  addBlocker(mesh);
54
54
  }
package/package.json CHANGED
@@ -1,30 +1,32 @@
1
1
  {
2
2
  "name": "@threlte/xr",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "author": "Micheal Parks <michealparks1989@gmail.com> (https://parks.lol)",
5
5
  "license": "MIT",
6
6
  "description": "Tools to more easily create VR and AR experiences with Threlte",
7
7
  "devDependencies": {
8
+ "@eslint/js": "^9.26.0",
8
9
  "@sveltejs/adapter-auto": "^3.3.1",
9
10
  "@sveltejs/kit": "^2.7.7",
10
11
  "@sveltejs/package": "^2.3.7",
11
12
  "@sveltejs/vite-plugin-svelte": "^4.0.0",
12
13
  "@types/three": "^0.175.0",
13
- "@typescript-eslint/eslint-plugin": "^7.6.0",
14
- "@typescript-eslint/parser": "^7.6.0",
14
+ "@types/webxr": "^0.5.22",
15
15
  "autoprefixer": "^10.4.19",
16
- "eslint": "^9.0.0",
17
- "eslint-plugin-svelte": "^2.36.0",
16
+ "eslint": "^9.26.0",
17
+ "eslint-plugin-svelte": "^3.5.1",
18
+ "globals": "^16.1.0",
18
19
  "postcss": "^8.4.38",
19
20
  "publint": "^0.2.7",
20
21
  "svelte": "^5.26.2",
21
- "svelte-check": "^3.6.9",
22
+ "svelte-check": "^4.1.7",
22
23
  "three": "^0.175.0",
23
24
  "tslib": "^2.6.2",
24
25
  "typescript": "^5.6.3",
26
+ "typescript-eslint": "^8.32.0",
25
27
  "vite": "^5.2.8",
26
28
  "vite-plugin-mkcert": "^1.17.5",
27
- "@threlte/core": "8.0.2"
29
+ "@threlte/core": "8.0.4"
28
30
  },
29
31
  "peerDependencies": {
30
32
  "svelte": ">=5",
@@ -68,7 +70,7 @@
68
70
  "package": "svelte-kit sync && svelte-package && node ./scripts/cleanupPackage.js && publint",
69
71
  "check": "svelte-check --tsconfig ./tsconfig.json",
70
72
  "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
71
- "lint": "prettier --check .",
73
+ "lint": "prettier --check . && eslint .",
72
74
  "format": "prettier --write .",
73
75
  "cleanup": "rimraf node_modules .svelte-kit dist"
74
76
  }