@tresjs/core 5.3.2 → 5.4.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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * name: @tresjs/core
3
- * version: v5.3.2
3
+ * version: v5.4.0
4
4
  * (c) 2026
5
5
  * description: Declarative ThreeJS using Vue Components
6
6
  * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * name: @tresjs/core
3
- * version: v5.3.2
3
+ * version: v5.4.0
4
4
  * (c) 2026
5
5
  * description: Declarative ThreeJS using Vue Components
6
6
  * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)
package/dist/tres.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * name: @tresjs/core
3
- * version: v5.3.2
3
+ * version: v5.4.0
4
4
  * (c) 2026
5
5
  * description: Declarative ThreeJS using Vue Components
6
6
  * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)
7
7
  */
8
- import * as vue0 from "vue";
8
+ import * as vue6 from "vue";
9
9
  import { App, ComputedRef, DefineComponent, MaybeRef, MaybeRefOrGetter, Reactive, Ref, ShallowRef, VNode, VNodeRef } from "vue";
10
10
  import * as THREE from "three";
11
11
  import { BufferGeometry, Camera, Color, ColorRepresentation, ColorSpace, Event, Fog, Group, Layers, Light, Loader, LoadingManager, Material, Mesh, Object3D, Object3DEventMap, OrthographicCamera, PerspectiveCamera, Scene, ShadowMapType, ToneMapping, Vector3, WebGLRenderer } from "three";
@@ -321,11 +321,11 @@ declare function useRendererManager({
321
321
  onRender: _vueuse_core0.EventHookOn<TresRenderer>;
322
322
  onError: _vueuse_core0.EventHookOn<TresRendererError>;
323
323
  invalidate: (amountOfFramesToInvalidate?: number) => void;
324
- canBeInvalidated: vue0.ComputedRef<boolean>;
324
+ canBeInvalidated: vue6.ComputedRef<boolean>;
325
325
  mode: "always" | "on-demand" | "manual" | undefined;
326
326
  replaceRenderFunction: (fn: RenderFunction) => void;
327
- isInitialized: vue0.Ref<boolean, boolean>;
328
- error: vue0.Ref<TresRendererError | null, TresRendererError | null>;
327
+ isInitialized: vue6.Ref<boolean, boolean>;
328
+ error: vue6.Ref<TresRendererError | null, TresRendererError | null>;
329
329
  };
330
330
  type UseRendererManagerReturn = ReturnType<typeof useRendererManager>;
331
331
  //#endregion
@@ -437,6 +437,8 @@ type TresPrimitive = TresInstance & {
437
437
  interface TresScene extends THREE.Scene {
438
438
  __tres: {
439
439
  root: TresContext;
440
+ objects: TresObject[];
441
+ isUnmounting: boolean;
440
442
  };
441
443
  }
442
444
  interface MathRepresentation {
@@ -510,7 +512,7 @@ declare function buildGraph(object: Object3D | TresObject): TresObjectMap;
510
512
  //#endregion
511
513
  //#region src/composables/useLoader/component.vue.d.ts
512
514
  declare const __VLS_export$1: <T extends TresObjectMap>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
513
- props: vue0.PublicProps & __VLS_PrettifyLocal<{
515
+ props: vue6.PublicProps & __VLS_PrettifyLocal<{
514
516
  /**
515
517
  * The THREE.js loader to use
516
518
  */
@@ -533,20 +535,20 @@ declare const __VLS_export$1: <T extends TresObjectMap>(__VLS_props: NonNullable
533
535
  attrs: any;
534
536
  slots: {
535
537
  default?: (props: {
536
- state: vue0.UnwrapRef<T>;
538
+ state: vue6.UnwrapRef<T>;
537
539
  isLoading: boolean;
538
540
  error: unknown;
539
541
  }) => any;
540
542
  };
541
543
  emit: ((evt: "error", error: unknown) => void) & ((evt: "loaded", result: T) => void);
542
- }>) => vue0.VNode & {
544
+ }>) => vue6.VNode & {
543
545
  __ctx?: Awaited<typeof __VLS_setup>;
544
546
  };
545
547
  declare const _default$1: typeof __VLS_export$1;
546
548
  type __VLS_PrettifyLocal<T> = (T extends any ? { [K in keyof T]: T[K] } : { [K in keyof T as K]: T[K] }) & {};
547
549
  //#endregion
548
550
  //#region src/composables/useGraph/index.d.ts
549
- declare const useGraph: (object: MaybeRef$1<TresObject | undefined>) => vue0.ComputedRef<TresObjectMap | undefined>;
551
+ declare const useGraph: (object: MaybeRef$1<TresObject | undefined>) => vue6.ComputedRef<TresObjectMap | undefined>;
550
552
  //#endregion
551
553
  //#region src/utils/createPriorityEventHook.d.ts
552
554
  type Callback<T> = Parameters<EventHookOff<T>>[0];
@@ -597,7 +599,7 @@ type LoopContext = RafLoopContext & TresPartialContext;
597
599
  declare const useLoop: () => {
598
600
  stop: () => void;
599
601
  start: () => void;
600
- isActive: Readonly<vue0.ShallowRef<boolean>>;
602
+ isActive: Readonly<vue6.ShallowRef<boolean>>;
601
603
  onBeforeRender: PriorityEventHookOn<LoopContext>;
602
604
  onRender: PriorityEventHookOn<LoopContext>;
603
605
  render: (fn: RenderFunction) => void;
@@ -704,7 +706,7 @@ interface TresCanvasInstance {
704
706
  type __VLS_Slots = {
705
707
  default: () => any;
706
708
  };
707
- declare const __VLS_base: vue0.DefineComponent<ContextProps, TresCanvasInstance, {}, {}, {}, vue0.ComponentOptionsMixin, vue0.ComponentOptionsMixin, {
709
+ declare const __VLS_base: vue6.DefineComponent<ContextProps, TresCanvasInstance, {}, {}, {}, vue6.ComponentOptionsMixin, vue6.ComponentOptionsMixin, {
708
710
  click: (event: TresPointerEvent) => any;
709
711
  contextmenu: (event: TresPointerEvent) => any;
710
712
  pointermove: (event: TresPointerEvent) => any;
@@ -724,7 +726,7 @@ declare const __VLS_base: vue0.DefineComponent<ContextProps, TresCanvasInstance,
724
726
  render: (context: TresContext) => any;
725
727
  beforeLoop: (context: TresContextWithClock) => any;
726
728
  loop: (context: TresContextWithClock) => any;
727
- }, string, vue0.PublicProps, Readonly<ContextProps> & Readonly<{
729
+ }, string, vue6.PublicProps, Readonly<ContextProps> & Readonly<{
728
730
  onClick?: ((event: TresPointerEvent) => any) | undefined;
729
731
  onContextmenu?: ((event: TresPointerEvent) => any) | undefined;
730
732
  onPointermove?: ((event: TresPointerEvent) => any) | undefined;
@@ -746,6 +748,7 @@ declare const __VLS_base: vue0.DefineComponent<ContextProps, TresCanvasInstance,
746
748
  onLoop?: ((context: TresContextWithClock) => any) | undefined;
747
749
  }>, {
748
750
  windowSize: boolean;
751
+ enableProvideBridge: boolean;
749
752
  antialias: boolean;
750
753
  stencil: boolean;
751
754
  depth: boolean;
@@ -760,8 +763,7 @@ declare const __VLS_base: vue0.DefineComponent<ContextProps, TresCanvasInstance,
760
763
  shadowMapType: THREE.ShadowMapType;
761
764
  useLegacyLights: boolean;
762
765
  renderMode: "always" | "on-demand" | "manual";
763
- enableProvideBridge: boolean;
764
- }, {}, {}, {}, string, vue0.ComponentProvideOptions, false, {}, any>;
766
+ }, {}, {}, {}, string, vue6.ComponentProvideOptions, false, {}, any>;
765
767
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
766
768
  declare const _default: typeof __VLS_export;
767
769
  type __VLS_WithSlots<T, S> = T & {
package/dist/tres.js CHANGED
@@ -1,20 +1,20 @@
1
1
  /**
2
2
  * name: @tresjs/core
3
- * version: v5.3.2
3
+ * version: v5.4.0
4
4
  * (c) 2026
5
5
  * description: Declarative ThreeJS using Vue Components
6
6
  * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)
7
7
  */
8
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createRenderer, defineComponent, getCurrentInstance, h, isRef, mergeProps, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, reactive, readonly, ref, renderSlot, shallowRef, toValue, unref, useSlots, watch, watchEffect, withCtx } from "vue";
8
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createRenderer, defineComponent, getCurrentInstance, h, isRef, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, reactive, readonly, ref, renderSlot, shallowRef, toValue, unref, useSlots, watch, watchEffect, withCtx } from "vue";
9
9
  import * as THREE from "three";
10
- import { ACESFilmicToneMapping, ArrowHelper, BackSide, BufferAttribute, BufferGeometry, Clock, Color, DirectionalLightHelper, DoubleSide, Float32BufferAttribute, HemisphereLightHelper, Layers, Line, LineBasicMaterial, Material, MathUtils, Mesh, MeshBasicMaterial, Object3D, PCFSoftShadowMap, PerspectiveCamera, PointLightHelper, Scene, SpotLightHelper, Vector3, WebGLRenderer } from "three";
10
+ import { ACESFilmicToneMapping, ArrowHelper, BackSide, BufferAttribute, BufferGeometry, Clock, Color, DirectionalLightHelper, DoubleSide, Float32BufferAttribute, HemisphereLightHelper, Layers, Line, LineBasicMaterial, Material, MathUtils, Mesh, MeshBasicMaterial, PCFSoftShadowMap, PerspectiveCamera, PointLightHelper, Scene, SpotLightHelper, Vector3, WebGLRenderer } from "three";
11
11
  import { createEventHook, createInjectionState, promiseTimeout, refDebounced, tryOnScopeDispose, unrefElement, useAsyncState, useDevicePixelRatio, useElementSize, useFps, useMemory, useRafFn, useTimeout, useWindowSize, whenever } from "@vueuse/core";
12
12
  import { camel, isEqual, isFunction, isNumber, isObject, isString, isUndefined } from "radashi";
13
13
  import { forwardHtmlEvents, getVoidObject } from "@pmndrs/pointer-events";
14
14
  import { setupDevtoolsPlugin } from "@vue/devtools-api";
15
15
 
16
16
  //#region package.json
17
- var version = "5.3.2";
17
+ var version = "5.4.0";
18
18
 
19
19
  //#endregion
20
20
  //#region src/utils/makeMap.ts
@@ -824,7 +824,6 @@ Error details: ${rendererError.message}`, rendererError);
824
824
  errorEventHook.trigger(rendererError);
825
825
  }
826
826
  };
827
- initializeRenderer();
828
827
  const renderEventHook = createEventHook();
829
828
  const notifyFrameRendered = () => {
830
829
  frames.value = isModeAlways.value ? 1 : Math.max(0, frames.value - 1);
@@ -853,8 +852,10 @@ Error details: ${rendererError.message}`, rendererError);
853
852
  if (!isInitialized.value) return;
854
853
  renderer.setSize(sizes.width.value, sizes.height.value);
855
854
  if (!hasTriggeredReady && renderer.domElement.width && renderer.domElement.height) {
856
- readyEventHook.trigger(renderer);
857
855
  hasTriggeredReady = true;
856
+ nextTick(() => {
857
+ readyEventHook.trigger(renderer);
858
+ });
858
859
  }
859
860
  invalidateOnDemand();
860
861
  }, { immediate: true });
@@ -862,6 +863,7 @@ Error details: ${rendererError.message}`, rendererError);
862
863
  if (!isInitialized.value) return;
863
864
  setPixelRatio(renderer, sizes.pixelRatio.value, toValue(options.dpr));
864
865
  });
866
+ initializeRenderer();
865
867
  if (toValue(options.renderMode) === "on-demand") invalidate();
866
868
  if (toValue(options.renderMode) === "manual") useTimeout(100, { callback: advance });
867
869
  const clearColorAndAlpha = computed(() => {
@@ -994,7 +996,11 @@ const [useTresContextProvider, _useTresContext] = createInjectionState(({ scene,
994
996
  extend,
995
997
  events
996
998
  };
997
- ctx.scene.value.__tres = { root: ctx };
999
+ ctx.scene.value.__tres = {
1000
+ root: ctx,
1001
+ objects: [],
1002
+ isUnmounting: false
1003
+ };
998
1004
  return ctx;
999
1005
  }, { injectionKey: "useTres" });
1000
1006
  const useTresContext = () => {
@@ -1114,9 +1120,24 @@ const isSupportedPointerEvent = (event) => supportedPointerEvents.includes(event
1114
1120
 
1115
1121
  //#endregion
1116
1122
  //#region src/core/nodeOps.ts
1123
+ const textNodeSymbol = Symbol("tresTextNode");
1124
+ const commentNodeSymbol = Symbol("tresComment");
1117
1125
  const nodeOps = ({ context, options = { primitivePrefix: "" } }) => {
1118
1126
  const scene = context.scene.value;
1119
- function createElement(tag, _isSVG, _anchor, props) {
1127
+ const createTextNode = () => {
1128
+ if (scene?.__tres?.isUnmounting) return;
1129
+ return {
1130
+ [textNodeSymbol]: true,
1131
+ __tres: { parent: null }
1132
+ };
1133
+ };
1134
+ const createCommentNode = () => ({
1135
+ [commentNodeSymbol]: true,
1136
+ __tres: { parent: null }
1137
+ });
1138
+ const isTextNode = (node) => !!node && typeof node === "object" && textNodeSymbol in node;
1139
+ const isCommentNode = (node) => !!node && typeof node === "object" && commentNodeSymbol in node;
1140
+ function createElement(tag, _namespace, _isCustomizedBuiltIn, props) {
1120
1141
  if (!props) props = {};
1121
1142
  if (!props.args) props.args = [];
1122
1143
  if (isHTMLTag(tag)) return null;
@@ -1162,9 +1183,19 @@ const nodeOps = ({ context, options = { primitivePrefix: "" } }) => {
1162
1183
  }, context);
1163
1184
  return obj;
1164
1185
  }
1165
- function insert(child, parent) {
1186
+ function insert(child, parent, anchor) {
1166
1187
  if (!child) return;
1167
1188
  parent = parent || scene;
1189
+ if (isTextNode(child) || isCommentNode(child)) {
1190
+ const parentInstance$1 = parent.__tres ? parent : prepareTresInstance(parent, {}, context);
1191
+ child.__tres.parent = parentInstance$1;
1192
+ if (parentInstance$1.__tres.objects) {
1193
+ const insertIndex = anchor ? parentInstance$1.__tres.objects.findIndex((obj) => obj === anchor) : -1;
1194
+ if (insertIndex >= 0) parentInstance$1.__tres.objects.splice(insertIndex, 0, child);
1195
+ else parentInstance$1.__tres.objects.push(child);
1196
+ }
1197
+ return;
1198
+ }
1168
1199
  const childInstance = child.__tres ? child : prepareTresInstance(child, {}, context);
1169
1200
  const parentInstance = parent.__tres ? parent : prepareTresInstance(parent, {}, context);
1170
1201
  child = unboxTresPrimitive(childInstance);
@@ -1176,7 +1207,11 @@ const nodeOps = ({ context, options = { primitivePrefix: "" } }) => {
1176
1207
  child.dispatchEvent({ type: "added" });
1177
1208
  }
1178
1209
  childInstance.__tres.parent = parentInstance;
1179
- if (parentInstance.__tres.objects && !parentInstance.__tres.objects.includes(childInstance)) parentInstance.__tres.objects.push(childInstance);
1210
+ if (parentInstance.__tres.objects && !parentInstance.__tres.objects.includes(childInstance)) {
1211
+ const insertIndex = anchor ? parentInstance.__tres.objects.findIndex((obj) => obj === anchor) : -1;
1212
+ if (~insertIndex) parentInstance.__tres.objects.splice(insertIndex, 0, childInstance);
1213
+ else parentInstance.__tres.objects.push(childInstance);
1214
+ }
1180
1215
  }
1181
1216
  /**
1182
1217
  * @param node – the node root to remove
@@ -1184,6 +1219,12 @@ const nodeOps = ({ context, options = { primitivePrefix: "" } }) => {
1184
1219
  */
1185
1220
  function remove(node, dispose) {
1186
1221
  if (!node) return;
1222
+ if (isTextNode(node) || isCommentNode(node)) {
1223
+ const parent = node.__tres.parent;
1224
+ if (parent?.__tres?.objects) filterInPlace(parent.__tres.objects, (obj) => obj !== node);
1225
+ node.__tres.parent = null;
1226
+ return;
1227
+ }
1187
1228
  dispose = isUndefined(dispose) ? "default" : dispose;
1188
1229
  const userDispose = node.__tres?.dispose;
1189
1230
  if (!isUndefined(userDispose)) if (userDispose === null) dispose = false;
@@ -1283,23 +1324,10 @@ const nodeOps = ({ context, options = { primitivePrefix: "" } }) => {
1283
1324
  function parentNode(node) {
1284
1325
  return node?.__tres?.parent || null;
1285
1326
  }
1286
- /**
1287
- * createComment
1288
- *
1289
- * Creates a comment object that can be used to represent a commented out string in a vue template
1290
- * Used by Vue's internal runtime as a placeholder for v-if'd elements
1291
- *
1292
- * @param comment Any commented out string contaiend in a vue template, typically this is `v-if`
1293
- * @returns TresObject
1294
- */
1295
- function createComment(comment) {
1296
- const commentObj = prepareTresInstance(new Object3D(), { type: "Comment" }, context);
1297
- commentObj.name = comment;
1298
- return commentObj;
1299
- }
1300
1327
  function nextSibling(node) {
1328
+ if (!node || !("__tres" in node)) return null;
1301
1329
  const siblings = parentNode(node)?.__tres?.objects || [];
1302
- const index = siblings.indexOf(node);
1330
+ const index = siblings.findIndex((sibling) => sibling === node);
1303
1331
  if (index < 0 || index >= siblings.length - 1) return null;
1304
1332
  return siblings[index + 1];
1305
1333
  }
@@ -1310,8 +1338,8 @@ const nodeOps = ({ context, options = { primitivePrefix: "" } }) => {
1310
1338
  createElement,
1311
1339
  patchProp,
1312
1340
  parentNode,
1313
- createText: noop,
1314
- createComment,
1341
+ createText: createTextNode,
1342
+ createComment: createCommentNode,
1315
1343
  setText: noop,
1316
1344
  setElementText: noop,
1317
1345
  nextSibling,
@@ -2029,7 +2057,11 @@ var Context_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
2029
2057
  context$1.renderer.instance.forceContextLoss();
2030
2058
  }
2031
2059
  }
2032
- scene.value.__tres = { root: context$1 };
2060
+ scene.value.__tres = {
2061
+ root: context$1,
2062
+ objects: [],
2063
+ isUnmounting: true
2064
+ };
2033
2065
  };
2034
2066
  const context = shallowRef(useTresContextProvider({
2035
2067
  scene: scene.value,
@@ -2042,12 +2074,13 @@ var Context_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
2042
2074
  dispose: () => dispose(context.value, true)
2043
2075
  });
2044
2076
  const handleHMR = (context$1) => {
2045
- dispose(context$1);
2046
2077
  mountCustomRenderer(context$1);
2047
2078
  };
2048
2079
  const unmountCanvas = () => {
2049
- dispose(context.value);
2080
+ const isTresScene = (value) => isScene(value) && "__tres" in value;
2081
+ if (isTresScene(scene.value)) scene.value.__tres.isUnmounting = true;
2050
2082
  mountCustomRenderer(context.value, true);
2083
+ dispose(context.value);
2051
2084
  };
2052
2085
  const { camera, renderer } = context.value;
2053
2086
  const { registerCamera, cameras, activeCamera, deregisterCamera } = camera;
@@ -2393,7 +2426,7 @@ const vDistanceTo = {
2393
2426
  };
2394
2427
 
2395
2428
  //#endregion
2396
- //#region ../../node_modules/.pnpm/three-stdlib@2.36.1_three@0.181.2/node_modules/three-stdlib/helpers/RectAreaLightHelper.js
2429
+ //#region ../../node_modules/.pnpm/three-stdlib@2.36.1_three@0.182.0/node_modules/three-stdlib/helpers/RectAreaLightHelper.js
2397
2430
  var RectAreaLightHelper = class extends Line {
2398
2431
  constructor(light, color) {
2399
2432
  const positions = [
@@ -2493,7 +2526,7 @@ const vLightHelper = {
2493
2526
  el.parent?.add(new CurrentHelper(el, 1, el.color.getHex()));
2494
2527
  },
2495
2528
  updated: (el) => {
2496
- currentInstance = el.parent.children.find((child) => child instanceof CurrentHelper);
2529
+ currentInstance = el.parent?.children.find((child) => child instanceof CurrentHelper);
2497
2530
  if (currentInstance instanceof RectAreaLightHelper) return;
2498
2531
  currentInstance.update();
2499
2532
  },
@@ -2502,7 +2535,7 @@ const vLightHelper = {
2502
2535
  logWarning(`${el.type} is not a light`);
2503
2536
  return;
2504
2537
  }
2505
- currentInstance = el.parent.children.find((child) => child instanceof CurrentHelper);
2538
+ currentInstance = el.parent?.children.find((child) => child instanceof CurrentHelper);
2506
2539
  if (currentInstance && currentInstance.dispose) currentInstance.dispose();
2507
2540
  if (el.parent) el.parent.remove(currentInstance);
2508
2541
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tresjs/core",
3
3
  "type": "module",
4
- "version": "5.3.2",
4
+ "version": "5.4.0",
5
5
  "description": "Declarative ThreeJS using Vue Components",
6
6
  "author": "Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/)",
7
7
  "license": "MIT",
@@ -51,7 +51,7 @@
51
51
  "radashi": "^12.6.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@types/three": "^0.181.0",
54
+ "@types/three": "^0.182.0",
55
55
  "@typescript-eslint/eslint-plugin": "^8.42.0",
56
56
  "@typescript-eslint/parser": "^8.42.0",
57
57
  "@vitejs/plugin-vue": "^6.0.1",
@@ -66,7 +66,7 @@
66
66
  "rollup-plugin-analyzer": "^4.0.0",
67
67
  "rollup-plugin-copy": "^3.5.0",
68
68
  "rollup-plugin-visualizer": "^6.0.3",
69
- "three": "^0.181.0",
69
+ "three": "^0.182.0",
70
70
  "tsdown": "0.18.3",
71
71
  "typescript": "^5.8.3",
72
72
  "vite": "^7.1.9",