angular-three 2.1.0 → 2.2.1

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,11 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { untracked, computed, signal, ElementRef, input, inject, ViewContainerRef, NgZone, TemplateRef, afterNextRender, DestroyRef, Directive, effect, InjectionToken, DebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, Component, EnvironmentInjector, Injector, booleanAttribute, output, viewChild, createEnvironmentInjector, ChangeDetectionStrategy, Pipe, CUSTOM_ELEMENTS_SCHEMA, contentChild, model, Renderer2 } from '@angular/core';
3
- import { takeUntilDestroyed, outputFromObservable, toObservable } from '@angular/core/rxjs-interop';
4
- import { injectAutoEffect } from 'ngxtension/auto-effect';
2
+ import { untracked, computed, signal, ElementRef, input, inject, ViewContainerRef, TemplateRef, effect, DestroyRef, Directive, InjectionToken, DebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, Component, NgZone, EnvironmentInjector, Injector, booleanAttribute, output, viewChild, afterNextRender, createEnvironmentInjector, ChangeDetectionStrategy, Pipe, CUSTOM_ELEMENTS_SCHEMA, contentChild, model, Renderer2 } from '@angular/core';
3
+ import { takeUntilDestroyed, outputFromObservable } from '@angular/core/rxjs-interop';
5
4
  import { provideResizeOptions, NgxResize } from 'ngxtension/resize';
6
5
  import { MathUtils, WebGLRenderer, OrthographicCamera, PerspectiveCamera, Vector3, Vector2, Clock, Layers, Color, ColorManagement, Texture, RGBAFormat, UnsignedByteType, EventDispatcher, Raycaster, Scene, PCFSoftShadowMap, BasicShadowMap, PCFShadowMap, VSMShadowMap, NoToneMapping, ACESFilmicToneMapping, Vector4 } from 'three';
7
6
  import { DOCUMENT } from '@angular/common';
8
- import { Subject, filter, map } from 'rxjs';
7
+ import { Subject, filter } from 'rxjs';
9
8
  import { createInjectionToken } from 'ngxtension/create-injection-token';
10
9
  import { assertInjector } from 'ngxtension/assert-injector';
11
10
  import * as i1 from '@angular/router';
@@ -211,7 +210,14 @@ function prepare(object, localState) {
211
210
  parent: null,
212
211
  objects: [],
213
212
  nonObjects: [],
213
+ geometryStamp: Date.now(),
214
214
  }), ...rest } = localState || {};
215
+ const nonObjects = instanceStore.select('nonObjects');
216
+ const geometryStamp = instanceStore.select('geometryStamp');
217
+ const nonObjectsChanged = computed(() => {
218
+ const [_nonObjects] = [nonObjects(), geometryStamp()];
219
+ return _nonObjects;
220
+ });
215
221
  instance.__ngt__ = {
216
222
  previousAttach: null,
217
223
  store: null,
@@ -221,7 +227,7 @@ function prepare(object, localState) {
221
227
  instanceStore,
222
228
  parent: instanceStore.select('parent'),
223
229
  objects: instanceStore.select('objects'),
224
- nonObjects: instanceStore.select('nonObjects'),
230
+ nonObjects: nonObjectsChanged,
225
231
  add(object, type) {
226
232
  const current = instance.__ngt__.instanceStore.snapshot[type];
227
233
  const foundIndex = current.indexOf((node) => object === node);
@@ -232,29 +238,32 @@ function prepare(object, localState) {
232
238
  else {
233
239
  instance.__ngt__.instanceStore.update((prev) => ({ [type]: [...prev[type], object] }));
234
240
  }
235
- notifyAncestors(instance.__ngt__.instanceStore.snapshot.parent);
241
+ notifyAncestors(instance.__ngt__.instanceStore.snapshot.parent, type);
236
242
  },
237
243
  remove(object, type) {
238
244
  instance.__ngt__.instanceStore.update((prev) => ({ [type]: prev[type].filter((node) => node !== object) }));
239
- notifyAncestors(instance.__ngt__.instanceStore.snapshot.parent);
245
+ notifyAncestors(instance.__ngt__.instanceStore.snapshot.parent, type);
240
246
  },
241
247
  setParent(parent) {
242
248
  instance.__ngt__.instanceStore.update({ parent });
243
249
  },
250
+ updateGeometryStamp() {
251
+ instance.__ngt__.instanceStore.update({ geometryStamp: Date.now() });
252
+ },
244
253
  ...rest,
245
254
  };
246
255
  }
247
256
  return instance;
248
257
  }
249
- function notifyAncestors(instance) {
258
+ function notifyAncestors(instance, type) {
250
259
  if (!instance)
251
260
  return;
252
261
  const localState = getLocalState(instance);
253
262
  if (!localState)
254
263
  return;
255
- const { parent, objects, nonObjects } = localState.instanceStore.snapshot;
256
- localState.instanceStore.update({ objects: (objects || []).slice(), nonObjects: (nonObjects || []).slice() });
257
- notifyAncestors(parent);
264
+ const { parent } = localState.instanceStore.snapshot;
265
+ localState.instanceStore.update({ [type]: (localState.instanceStore.snapshot[type] || []).slice() });
266
+ notifyAncestors(parent, type);
258
267
  }
259
268
 
260
269
  const idCache = {};
@@ -739,6 +748,7 @@ function createPointerEvents(store) {
739
748
 
740
749
  const ROUTED_SCENE = '__ngt_renderer_is_routed_scene__';
741
750
  const HTML = '__ngt_renderer_is_html';
751
+ const NON_ROOT = '__ngt_renderer_is_non_root__';
742
752
  const SPECIAL_INTERNAL_ADD_COMMENT = '__ngt_renderer_add_comment__';
743
753
  const SPECIAL_DOM_TAG = {
744
754
  NGT_PORTAL: 'ngt-portal',
@@ -762,9 +772,7 @@ class NgtArgs {
762
772
  constructor() {
763
773
  this.args = input.required();
764
774
  this.vcr = inject(ViewContainerRef);
765
- this.zone = inject(NgZone);
766
775
  this.template = inject(TemplateRef);
767
- this.autoEffect = injectAutoEffect();
768
776
  this.injected = false;
769
777
  this.injectedArgs = null;
770
778
  const commentNode = this.vcr.element.nativeElement;
@@ -772,16 +780,14 @@ class NgtArgs {
772
780
  commentNode[SPECIAL_INTERNAL_ADD_COMMENT]('args');
773
781
  delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
774
782
  }
775
- afterNextRender(() => {
776
- this.autoEffect(() => {
777
- const value = this.args();
778
- if (value == null || !Array.isArray(value) || (value.length === 1 && value[0] === null))
779
- return;
780
- this.injected = false;
781
- this.injectedArgs = value;
782
- untracked(() => {
783
- this.createView();
784
- });
783
+ effect(() => {
784
+ const value = this.args();
785
+ if (value == null || !Array.isArray(value) || (value.length === 1 && value[0] === null))
786
+ return;
787
+ this.injected = false;
788
+ this.injectedArgs = value;
789
+ untracked(() => {
790
+ this.createView();
785
791
  });
786
792
  });
787
793
  inject(DestroyRef).onDestroy(() => {
@@ -799,18 +805,15 @@ class NgtArgs {
799
805
  return !this.injected && !!this.injectedArgs?.length;
800
806
  }
801
807
  createView() {
802
- this.zone.runOutsideAngular(() => {
803
- if (this.view && !this.view.destroyed) {
804
- this.view.destroy();
805
- }
806
- this.view = this.vcr.createEmbeddedView(this.template);
807
- this.view.detectChanges();
808
- });
808
+ if (this.view && !this.view.destroyed)
809
+ this.view.destroy();
810
+ this.view = this.vcr.createEmbeddedView(this.template);
811
+ this.view.detectChanges();
809
812
  }
810
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtArgs, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
811
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.0", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: { classPropertyName: "args", publicName: "args", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
813
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtArgs, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
814
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.4", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: { classPropertyName: "args", publicName: "args", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
812
815
  }
813
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtArgs, decorators: [{
816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtArgs, decorators: [{
814
817
  type: Directive,
815
818
  args: [{ selector: 'ng-template[args]', standalone: true }]
816
819
  }], ctorParameters: () => [] });
@@ -1446,7 +1449,9 @@ function attachThreeChild(parent, child) {
1446
1449
  parent.add(child);
1447
1450
  added = true;
1448
1451
  }
1449
- pLS.add(child, added ? 'objects' : 'nonObjects');
1452
+ if (pLS.add) {
1453
+ pLS.add(child, added ? 'objects' : 'nonObjects');
1454
+ }
1450
1455
  if (cLS.parent && untracked(cLS.parent) !== parent) {
1451
1456
  cLS.setParent(parent);
1452
1457
  }
@@ -1588,18 +1593,19 @@ class NgtRendererFactory {
1588
1593
  if (type['type'][ROUTED_SCENE]) {
1589
1594
  this.routedSet.add(type.id);
1590
1595
  }
1596
+ const isNonRoot = type['type'][NON_ROOT];
1591
1597
  let renderer = this.rendererMap.get(type.id);
1592
1598
  if (!renderer) {
1593
1599
  this.rendererMap.set(type.id, (renderer = new NgtRenderer(delegateRenderer, this.rootStore, this.document, this.portalCommentsNodes, this.catalogue,
1594
1600
  // setting root scene if there's no routed scene OR this component is the routed Scene
1595
- !hostElement && (this.routedSet.size === 0 || this.routedSet.has(type.id)))));
1601
+ !hostElement && !isNonRoot && (this.routedSet.size === 0 || this.routedSet.has(type.id)))));
1596
1602
  }
1597
1603
  return renderer;
1598
1604
  }
1599
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1600
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtRendererFactory }); }
1605
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1606
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtRendererFactory }); }
1601
1607
  }
1602
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtRendererFactory, decorators: [{
1608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtRendererFactory, decorators: [{
1603
1609
  type: Injectable
1604
1610
  }] });
1605
1611
  class NgtRenderer {
@@ -1899,6 +1905,7 @@ class NgtRenderer {
1899
1905
  const rS = el.__ngt_renderer__;
1900
1906
  if (!rS || rS[3 /* NgtRendererClassId.destroyed */])
1901
1907
  return;
1908
+ const localState = getLocalState(el);
1902
1909
  if (rS[0 /* NgtRendererClassId.type */] === 'three') {
1903
1910
  if (name === SPECIAL_PROPERTIES.PARAMETERS) {
1904
1911
  // NOTE: short-cut for null raycast to prevent upstream from creating a nullRaycast property
@@ -1906,9 +1913,11 @@ class NgtRenderer {
1906
1913
  value['raycast'] = () => null;
1907
1914
  }
1908
1915
  applyProps(el, value);
1916
+ if ('geometry' in value && value['geometry'].isBufferGeometry) {
1917
+ localState?.updateGeometryStamp();
1918
+ }
1909
1919
  return;
1910
1920
  }
1911
- const localState = getLocalState(el);
1912
1921
  const parent = localState?.instanceStore.get('parent') || rS[1 /* NgtRendererClassId.parent */];
1913
1922
  // [rawValue]
1914
1923
  if (localState?.isRaw && name === SPECIAL_PROPERTIES.RAW_VALUE) {
@@ -1936,6 +1945,9 @@ class NgtRenderer {
1936
1945
  value = () => null;
1937
1946
  }
1938
1947
  applyProps(el, { [name]: value });
1948
+ if (name === 'geometry' && value.isBufferGeometry) {
1949
+ localState?.updateGeometryStamp();
1950
+ }
1939
1951
  return;
1940
1952
  }
1941
1953
  return this.delegate.setProperty(el, name, value);
@@ -2372,12 +2384,12 @@ class NgtRoutedScene {
2372
2384
  .pipe(filter((event) => event instanceof ActivationEnd), takeUntilDestroyed())
2373
2385
  .subscribe(cdr.detectChanges.bind(cdr));
2374
2386
  }
2375
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2376
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.0", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
2387
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2388
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.4", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
2377
2389
  <router-outlet />
2378
2390
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); }
2379
2391
  }
2380
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtRoutedScene, decorators: [{
2392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtRoutedScene, decorators: [{
2381
2393
  type: Component,
2382
2394
  args: [{
2383
2395
  standalone: true,
@@ -2393,7 +2405,6 @@ class NgtCanvas {
2393
2405
  constructor() {
2394
2406
  this.store = injectStore();
2395
2407
  this.initRoot = injectCanvasRootInitializer();
2396
- this.autoEffect = injectAutoEffect();
2397
2408
  this.host = inject(ElementRef);
2398
2409
  this.zone = inject(NgZone);
2399
2410
  this.environmentInjector = inject(EnvironmentInjector);
@@ -2438,7 +2449,9 @@ class NgtCanvas {
2438
2449
  afterNextRender(() => {
2439
2450
  this.zone.runOutsideAngular(() => {
2440
2451
  this.configurator = this.initRoot(this.glCanvas().nativeElement);
2441
- this.noZoneResizeEffect();
2452
+ effect(() => {
2453
+ this.noZoneResizeEffect();
2454
+ }, { injector: this.injector });
2442
2455
  });
2443
2456
  });
2444
2457
  inject(DestroyRef).onDestroy(() => {
@@ -2448,40 +2461,38 @@ class NgtCanvas {
2448
2461
  });
2449
2462
  }
2450
2463
  noZoneResizeEffect() {
2451
- this.autoEffect(() => {
2452
- const resizeResult = this.resizeResult();
2453
- if (resizeResult.width > 0 && resizeResult.height > 0) {
2454
- if (!this.configurator)
2455
- this.configurator = this.initRoot(this.glCanvas().nativeElement);
2456
- this.configurator.configure({
2457
- gl: this.gl(),
2458
- shadows: this.shadows(),
2459
- legacy: this.legacy(),
2460
- linear: this.linear(),
2461
- flat: this.flat(),
2462
- orthographic: this.orthographic(),
2463
- frameloop: this.frameloop(),
2464
- performance: this.performance(),
2465
- dpr: this.dpr(),
2466
- raycaster: this.raycaster(),
2467
- scene: this.scene(),
2468
- camera: this.camera(),
2469
- events: this.events(),
2470
- eventSource: this.eventSource(),
2471
- eventPrefix: this.eventPrefix(),
2472
- lookAt: this.lookAt(),
2473
- size: resizeResult,
2474
- });
2475
- untracked(() => {
2476
- if (this.glRef) {
2477
- this.glRef.changeDetectorRef.detectChanges();
2478
- }
2479
- else {
2480
- this.noZoneRender();
2481
- }
2482
- });
2483
- }
2484
- });
2464
+ const resizeResult = this.resizeResult();
2465
+ if (resizeResult.width > 0 && resizeResult.height > 0) {
2466
+ if (!this.configurator)
2467
+ this.configurator = this.initRoot(this.glCanvas().nativeElement);
2468
+ this.configurator.configure({
2469
+ gl: this.gl(),
2470
+ shadows: this.shadows(),
2471
+ legacy: this.legacy(),
2472
+ linear: this.linear(),
2473
+ flat: this.flat(),
2474
+ orthographic: this.orthographic(),
2475
+ frameloop: this.frameloop(),
2476
+ performance: this.performance(),
2477
+ dpr: this.dpr(),
2478
+ raycaster: this.raycaster(),
2479
+ scene: this.scene(),
2480
+ camera: this.camera(),
2481
+ events: this.events(),
2482
+ eventSource: this.eventSource(),
2483
+ eventPrefix: this.eventPrefix(),
2484
+ lookAt: this.lookAt(),
2485
+ size: resizeResult,
2486
+ });
2487
+ untracked(() => {
2488
+ if (this.glRef) {
2489
+ this.glRef.changeDetectorRef.detectChanges();
2490
+ }
2491
+ else {
2492
+ this.noZoneRender();
2493
+ }
2494
+ });
2495
+ }
2485
2496
  }
2486
2497
  noZoneRender() {
2487
2498
  // NOTE: destroy previous instances if existed
@@ -2520,8 +2531,8 @@ class NgtCanvas {
2520
2531
  });
2521
2532
  this.glRef.changeDetectorRef.detectChanges();
2522
2533
  }
2523
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2524
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.0", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: { classPropertyName: "sceneGraph", publicName: "sceneGraph", isSignal: true, isRequired: true, transformFunction: null }, gl: { classPropertyName: "gl", publicName: "gl", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shadows: { classPropertyName: "shadows", publicName: "shadows", isSignal: true, isRequired: false, transformFunction: null }, legacy: { classPropertyName: "legacy", publicName: "legacy", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, orthographic: { classPropertyName: "orthographic", publicName: "orthographic", isSignal: true, isRequired: false, transformFunction: null }, frameloop: { classPropertyName: "frameloop", publicName: "frameloop", isSignal: true, isRequired: false, transformFunction: null }, performance: { classPropertyName: "performance", publicName: "performance", isSignal: true, isRequired: false, transformFunction: null }, dpr: { classPropertyName: "dpr", publicName: "dpr", isSignal: true, isRequired: false, transformFunction: null }, raycaster: { classPropertyName: "raycaster", publicName: "raycaster", isSignal: true, isRequired: false, transformFunction: null }, scene: { classPropertyName: "scene", publicName: "scene", isSignal: true, isRequired: false, transformFunction: null }, camera: { classPropertyName: "camera", publicName: "camera", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, eventSource: { classPropertyName: "eventSource", publicName: "eventSource", isSignal: true, isRequired: false, transformFunction: null }, eventPrefix: { classPropertyName: "eventPrefix", publicName: "eventPrefix", isSignal: true, isRequired: false, transformFunction: null }, lookAt: { classPropertyName: "lookAt", publicName: "lookAt", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { created: "created", pointerMissed: "pointerMissed" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
2534
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2535
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.4", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: { classPropertyName: "sceneGraph", publicName: "sceneGraph", isSignal: true, isRequired: true, transformFunction: null }, gl: { classPropertyName: "gl", publicName: "gl", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shadows: { classPropertyName: "shadows", publicName: "shadows", isSignal: true, isRequired: false, transformFunction: null }, legacy: { classPropertyName: "legacy", publicName: "legacy", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, orthographic: { classPropertyName: "orthographic", publicName: "orthographic", isSignal: true, isRequired: false, transformFunction: null }, frameloop: { classPropertyName: "frameloop", publicName: "frameloop", isSignal: true, isRequired: false, transformFunction: null }, performance: { classPropertyName: "performance", publicName: "performance", isSignal: true, isRequired: false, transformFunction: null }, dpr: { classPropertyName: "dpr", publicName: "dpr", isSignal: true, isRequired: false, transformFunction: null }, raycaster: { classPropertyName: "raycaster", publicName: "raycaster", isSignal: true, isRequired: false, transformFunction: null }, scene: { classPropertyName: "scene", publicName: "scene", isSignal: true, isRequired: false, transformFunction: null }, camera: { classPropertyName: "camera", publicName: "camera", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, eventSource: { classPropertyName: "eventSource", publicName: "eventSource", isSignal: true, isRequired: false, transformFunction: null }, eventPrefix: { classPropertyName: "eventPrefix", publicName: "eventPrefix", isSignal: true, isRequired: false, transformFunction: null }, lookAt: { classPropertyName: "lookAt", publicName: "lookAt", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { created: "created", pointerMissed: "pointerMissed" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
2525
2536
  provideResizeOptions({
2526
2537
  emitInZone: false,
2527
2538
  emitInitialResult: true,
@@ -2534,7 +2545,7 @@ class NgtCanvas {
2534
2545
  </div>
2535
2546
  `, isInline: true, dependencies: [{ kind: "directive", type: NgxResize, selector: "[ngxResize]", inputs: ["ngxResizeOptions"], outputs: ["ngxResize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2536
2547
  }
2537
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtCanvas, decorators: [{
2548
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtCanvas, decorators: [{
2538
2549
  type: Component,
2539
2550
  args: [{
2540
2551
  selector: 'ngt-canvas',
@@ -2566,12 +2577,16 @@ class NgtSelection {
2566
2577
  this.enabled = input(true, { alias: 'ngtSelection', transform: booleanAttribute });
2567
2578
  this.source = signal([]);
2568
2579
  this.selected = this.source.asReadonly();
2569
- this.update = this.source.update.bind(this.source);
2570
2580
  }
2571
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtSelection, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2572
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.0", type: NgtSelection, isStandalone: true, selector: "[ngtSelection]", inputs: { enabled: { classPropertyName: "enabled", publicName: "ngtSelection", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
2581
+ update(...args) {
2582
+ if (!this.enabled())
2583
+ return;
2584
+ this.source.update(...args);
2585
+ }
2586
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtSelection, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2587
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.4", type: NgtSelection, isStandalone: true, selector: "[ngtSelection]", inputs: { enabled: { classPropertyName: "enabled", publicName: "ngtSelection", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
2573
2588
  }
2574
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtSelection, decorators: [{
2589
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtSelection, decorators: [{
2575
2590
  type: Directive,
2576
2591
  args: [{ standalone: true, selector: '[ngtSelection]' }]
2577
2592
  }] });
@@ -2580,44 +2595,45 @@ class NgtSelect {
2580
2595
  this.enabled = input(false, { transform: booleanAttribute, alias: 'ngtSelect' });
2581
2596
  const elementRef = inject(ElementRef);
2582
2597
  const selection = inject(NgtSelection);
2583
- const autoEffect = injectAutoEffect();
2584
- afterNextRender(() => {
2585
- autoEffect(() => {
2586
- const enabled = this.enabled();
2587
- if (!enabled)
2588
- return;
2589
- const host = elementRef.nativeElement;
2590
- if (!host)
2591
- return;
2592
- const localState = getLocalState(host);
2593
- if (!localState)
2594
- return;
2595
- // ngt-mesh[ngtSelect]
2596
- if (host.type === 'Mesh') {
2597
- selection.update((prev) => [...prev, host]);
2598
- return () => selection.update((prev) => prev.filter((el) => el !== host));
2599
- }
2600
- const [collection] = [untracked(selection.selected), localState.objects()];
2601
- let changed = false;
2602
- const current = [];
2603
- host.traverse((child) => {
2604
- child.type === 'Mesh' && current.push(child);
2605
- if (collection.indexOf(child) === -1)
2606
- changed = true;
2607
- });
2608
- if (!changed)
2609
- return;
2610
- selection.update((prev) => [...prev, ...current]);
2611
- return () => {
2612
- selection.update((prev) => prev.filter((el) => !current.includes(el)));
2613
- };
2614
- }, { allowSignalWrites: true });
2615
- });
2598
+ effect((onCleanup) => {
2599
+ const selectionEnabled = selection.enabled();
2600
+ if (!selectionEnabled)
2601
+ return;
2602
+ const enabled = this.enabled();
2603
+ if (!enabled)
2604
+ return;
2605
+ const host = elementRef.nativeElement;
2606
+ if (!host)
2607
+ return;
2608
+ const localState = getLocalState(host);
2609
+ if (!localState)
2610
+ return;
2611
+ // ngt-mesh[ngtSelect]
2612
+ if (host.type === 'Mesh') {
2613
+ selection.update((prev) => [...prev, host]);
2614
+ onCleanup(() => selection.update((prev) => prev.filter((el) => el !== host)));
2615
+ return;
2616
+ }
2617
+ const [collection] = [untracked(selection.selected), localState.objects()];
2618
+ let changed = false;
2619
+ const current = [];
2620
+ host.traverse((child) => {
2621
+ child.type === 'Mesh' && current.push(child);
2622
+ if (collection.indexOf(child) === -1)
2623
+ changed = true;
2624
+ });
2625
+ if (!changed)
2626
+ return;
2627
+ selection.update((prev) => [...prev, ...current]);
2628
+ onCleanup(() => {
2629
+ selection.update((prev) => prev.filter((el) => !current.includes(el)));
2630
+ });
2631
+ }, { allowSignalWrites: true });
2616
2632
  }
2617
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtSelect, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2618
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.0", type: NgtSelect, isStandalone: true, selector: "ngt-group[ngtSelect], ngt-mesh[ngtSelect]", inputs: { enabled: { classPropertyName: "enabled", publicName: "ngtSelect", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
2633
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtSelect, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2634
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.4", type: NgtSelect, isStandalone: true, selector: "ngt-group[ngtSelect], ngt-mesh[ngtSelect]", inputs: { enabled: { classPropertyName: "enabled", publicName: "ngtSelect", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
2619
2635
  }
2620
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtSelect, decorators: [{
2636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtSelect, decorators: [{
2621
2637
  type: Directive,
2622
2638
  args: [{ standalone: true, selector: 'ngt-group[ngtSelect], ngt-mesh[ngtSelect]' }]
2623
2639
  }], ctorParameters: () => [] });
@@ -2651,10 +2667,10 @@ class NgtHTML {
2651
2667
  delete this.host.nativeElement['__ngt_dom_parent__'];
2652
2668
  });
2653
2669
  }
2654
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtHTML, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2655
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0", type: NgtHTML, ngImport: i0 }); }
2670
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtHTML, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2671
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.4", type: NgtHTML, ngImport: i0 }); }
2656
2672
  }
2657
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtHTML, decorators: [{
2673
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtHTML, decorators: [{
2658
2674
  type: Directive
2659
2675
  }], ctorParameters: () => [] });
2660
2676
 
@@ -2671,9 +2687,7 @@ function normalizeInputs(input) {
2671
2687
  else {
2672
2688
  urls = Object.values(input);
2673
2689
  }
2674
- return urls.map((url) => {
2675
- return url.includes('undefined') || url.includes('null') || !url ? '' : url;
2676
- });
2690
+ return urls.map((url) => (url.includes('undefined') || url.includes('null') || !url ? '' : url));
2677
2691
  }
2678
2692
  function load(loaderConstructorFactory, inputs, { extensions, onLoad, onProgress, } = {}) {
2679
2693
  return () => {
@@ -2685,11 +2699,9 @@ function load(loaderConstructorFactory, inputs, { extensions, onLoad, onProgress
2685
2699
  }
2686
2700
  if (extensions)
2687
2701
  extensions(loader);
2688
- // TODO: reevaluate this
2689
2702
  return urls.map((url) => {
2690
- if (url === '') {
2691
- return null;
2692
- }
2703
+ if (url === '')
2704
+ return Promise.resolve(null);
2693
2705
  if (!cached.has(url)) {
2694
2706
  cached.set(url, new Promise((resolve, reject) => {
2695
2707
  loader.load(url, (data) => {
@@ -2718,25 +2730,20 @@ function _injectLoader(loaderConstructorFactory, inputs, { extensions, onProgres
2718
2730
  effect(() => {
2719
2731
  const originalUrls = inputs();
2720
2732
  const cachedEffect = effector();
2721
- if (cachedEffect === null && untracked(response) !== null) {
2722
- response.set(null);
2723
- }
2724
- else if (cachedEffect !== null) {
2725
- Promise.all(cachedEffect).then((results) => {
2726
- response.update(() => {
2727
- if (Array.isArray(originalUrls))
2728
- return results;
2729
- if (typeof originalUrls === 'string')
2730
- return results[0];
2731
- const keys = Object.keys(originalUrls);
2732
- return keys.reduce((result, key) => {
2733
- result[key] = results[keys.indexOf(key)];
2734
- return result;
2735
- }, {});
2736
- });
2733
+ Promise.all(cachedEffect).then((results) => {
2734
+ response.update(() => {
2735
+ if (Array.isArray(originalUrls))
2736
+ return results;
2737
+ if (typeof originalUrls === 'string')
2738
+ return results[0];
2739
+ const keys = Object.keys(originalUrls);
2740
+ return keys.reduce((result, key) => {
2741
+ result[key] = results[keys.indexOf(key)];
2742
+ return result;
2743
+ }, {});
2737
2744
  });
2738
- }
2739
- }, { allowSignalWrites: true });
2745
+ });
2746
+ });
2740
2747
  return response.asReadonly();
2741
2748
  });
2742
2749
  }
@@ -2813,61 +2820,52 @@ class NgtHexify {
2813
2820
  const hex = component.toString(16);
2814
2821
  return hex.length === 1 ? '0' + hex : hex;
2815
2822
  }
2816
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtHexify, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2817
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.0", ngImport: i0, type: NgtHexify, isStandalone: true, name: "hexify" }); }
2823
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtHexify, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
2824
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.4", ngImport: i0, type: NgtHexify, isStandalone: true, name: "hexify" }); }
2818
2825
  }
2819
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtHexify, decorators: [{
2826
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtHexify, decorators: [{
2820
2827
  type: Pipe,
2821
2828
  args: [{ name: 'hexify', pure: true, standalone: true }]
2822
2829
  }] });
2823
2830
 
2824
- function injectBeforeRender(cb, { priority = 0, injector } = {}) {
2825
- return assertInjector(injectBeforeRender, injector, () => {
2826
- const store = injectStore();
2827
- const sub = store.get('internal').subscribe(cb, priority, store);
2828
- inject(DestroyRef).onDestroy(() => void sub());
2829
- return sub;
2830
- });
2831
- }
2832
-
2833
2831
  class NgtPortalBeforeRender {
2834
2832
  constructor() {
2835
2833
  this.portalStore = injectStore();
2836
2834
  this.renderPriority = input(1);
2837
2835
  this.parentScene = input.required();
2838
2836
  this.parentCamera = input.required();
2839
- injectAutoEffect()((injector) => {
2837
+ effect((onCleanup) => {
2840
2838
  // track state
2841
- this.portalStore.state();
2842
- const priority = this.renderPriority();
2843
- let oldClear;
2844
- return injectBeforeRender(() => {
2845
- const { gl, scene, camera } = this.portalStore.snapshot;
2846
- oldClear = gl.autoClear;
2847
- if (this.renderPriority() === 1) {
2839
+ const [renderPriority, { internal }] = [this.renderPriority(), this.portalStore.state()];
2840
+ let oldClean;
2841
+ const cleanup = internal.subscribe(({ gl, scene, camera }) => {
2842
+ const [parentScene, parentCamera] = [untracked(this.parentScene), untracked(this.parentCamera)];
2843
+ oldClean = gl.autoClear;
2844
+ if (renderPriority === 1) {
2848
2845
  // clear scene and render with default
2849
2846
  gl.autoClear = true;
2850
- gl.render(this.parentScene(), this.parentCamera());
2847
+ gl.render(parentScene, parentCamera);
2851
2848
  }
2852
2849
  // disable cleaning
2853
2850
  gl.autoClear = false;
2854
2851
  gl.clearDepth();
2855
2852
  gl.render(scene, camera);
2856
2853
  // restore
2857
- gl.autoClear = oldClear;
2858
- }, { priority, injector });
2854
+ gl.autoClear = oldClean;
2855
+ }, renderPriority, this.portalStore);
2856
+ onCleanup(() => cleanup());
2859
2857
  });
2860
2858
  }
2861
2859
  onPointerOver() {
2862
2860
  /* noop */
2863
2861
  }
2864
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2865
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.0", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: { classPropertyName: "renderPriority", publicName: "renderPriority", isSignal: true, isRequired: false, transformFunction: null }, parentScene: { classPropertyName: "parentScene", publicName: "parentScene", isSignal: true, isRequired: true, transformFunction: null }, parentCamera: { classPropertyName: "parentCamera", publicName: "parentCamera", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
2862
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2863
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.4", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: { classPropertyName: "renderPriority", publicName: "renderPriority", isSignal: true, isRequired: false, transformFunction: null }, parentScene: { classPropertyName: "parentScene", publicName: "parentScene", isSignal: true, isRequired: true, transformFunction: null }, parentCamera: { classPropertyName: "parentCamera", publicName: "parentCamera", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
2866
2864
  <!-- Without an element that receives pointer events state.pointer will always be 0/0 -->
2867
2865
  <ngt-group (pointerover)="onPointerOver()" attach="none" />
2868
2866
  `, isInline: true }); }
2869
2867
  }
2870
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
2868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
2871
2869
  type: Component,
2872
2870
  args: [{
2873
2871
  selector: 'ngt-portal-before-render',
@@ -2892,10 +2890,10 @@ class NgtPortalContent {
2892
2890
  static ngTemplateContextGuard(_, ctx) {
2893
2891
  return true;
2894
2892
  }
2895
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtPortalContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2896
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0", type: NgtPortalContent, isStandalone: true, selector: "ng-template[portalContent]", ngImport: i0 }); }
2893
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtPortalContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2894
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.4", type: NgtPortalContent, isStandalone: true, selector: "ng-template[portalContent]", ngImport: i0 }); }
2897
2895
  }
2898
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtPortalContent, decorators: [{
2896
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtPortalContent, decorators: [{
2899
2897
  type: Directive,
2900
2898
  args: [{ selector: 'ng-template[portalContent]', standalone: true }]
2901
2899
  }], ctorParameters: () => [] });
@@ -2931,8 +2929,8 @@ class NgtPortal {
2931
2929
  this.pointer = new Vector2();
2932
2930
  this.portalRendered = signal(false);
2933
2931
  this.renderAutoBeforeRender = computed(() => this.portalRendered() && this.autoRender());
2934
- const autoEffect = injectAutoEffect();
2935
2932
  const parentState = this.parentStore.select();
2933
+ // NOTE: we run this in afterNextRender for inputs to resolve
2936
2934
  afterNextRender(() => {
2937
2935
  const previousState = this.parentStore.snapshot;
2938
2936
  const { events = {}, size = {}, ...rest } = this.state();
@@ -2955,7 +2953,7 @@ class NgtPortal {
2955
2953
  ...rest,
2956
2954
  setEvents: (events) => this.portalStore.update((state) => ({ ...state, events: { ...state.events, ...events } })),
2957
2955
  });
2958
- autoEffect(() => {
2956
+ effect(() => {
2959
2957
  const state = this.state();
2960
2958
  const _parentState = parentState();
2961
2959
  this.portalStore.update((prev) => this.inject(_parentState, prev, state, untracked(this.container)));
@@ -2968,7 +2966,7 @@ class NgtPortal {
2968
2966
  this.portalView.detectChanges();
2969
2967
  this.portalRendered.set(true);
2970
2968
  });
2971
- });
2969
+ }, { injector: this.injector });
2972
2970
  });
2973
2971
  inject(DestroyRef).onDestroy(() => {
2974
2972
  this.portalView?.destroy();
@@ -3005,8 +3003,8 @@ class NgtPortal {
3005
3003
  ...rest,
3006
3004
  };
3007
3005
  }
3008
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3009
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: true, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, autoRender: { classPropertyName: "autoRender", publicName: "autoRender", isSignal: true, isRequired: false, transformFunction: null }, autoRenderPriority: { classPropertyName: "autoRenderPriority", publicName: "autoRenderPriority", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideStore(() => signalStore({}))], queries: [{ propertyName: "portalContent", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "portalAnchor", first: true, predicate: ["anchor"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
3006
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3007
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.4", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: true, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, autoRender: { classPropertyName: "autoRender", publicName: "autoRender", isSignal: true, isRequired: false, transformFunction: null }, autoRenderPriority: { classPropertyName: "autoRenderPriority", publicName: "autoRenderPriority", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideStore(() => signalStore({}))], queries: [{ propertyName: "portalContent", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "portalAnchor", first: true, predicate: ["anchor"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: `
3010
3008
  <ng-container #anchor />
3011
3009
 
3012
3010
  @if (renderAutoBeforeRender()) {
@@ -3018,7 +3016,7 @@ class NgtPortal {
3018
3016
  }
3019
3017
  `, isInline: true, dependencies: [{ kind: "component", type: NgtPortalBeforeRender, selector: "ngt-portal-before-render", inputs: ["renderPriority", "parentScene", "parentCamera"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3020
3018
  }
3021
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtPortal, decorators: [{
3019
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtPortal, decorators: [{
3022
3020
  type: Component,
3023
3021
  args: [{
3024
3022
  selector: 'ngt-portal',
@@ -3041,8 +3039,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImpor
3041
3039
  }]
3042
3040
  }], ctorParameters: () => [] });
3043
3041
 
3044
- function injectNonNullish$(sig, { injector } = {}) {
3045
- return assertInjector(injectNonNullish$, injector, () => toObservable(sig).pipe(map((val) => val != null)));
3042
+ function injectBeforeRender(cb, { priority = 0, injector } = {}) {
3043
+ return assertInjector(injectBeforeRender, injector, () => {
3044
+ const store = injectStore();
3045
+ const sub = store.get('internal').subscribe(cb, priority, store);
3046
+ inject(DestroyRef).onDestroy(() => void sub());
3047
+ return sub;
3048
+ });
3046
3049
  }
3047
3050
 
3048
3051
  function resolveRef(ref) {
@@ -3069,32 +3072,29 @@ class NgtObjectEvents {
3069
3072
  this.wheel = output();
3070
3073
  // NOTE: we use model here to allow for the hostDirective host to set this value
3071
3074
  this.ngtObjectEvents = model();
3072
- const injector = inject(Injector);
3073
- afterNextRender(() => {
3074
- injectObjectEvents(this.ngtObjectEvents, {
3075
- click: this.emitEvent('click'),
3076
- dblclick: this.emitEvent('dblclick'),
3077
- contextmenu: this.emitEvent('contextmenu'),
3078
- pointerup: this.emitEvent('pointerup'),
3079
- pointerdown: this.emitEvent('pointerdown'),
3080
- pointerover: this.emitEvent('pointerover'),
3081
- pointerout: this.emitEvent('pointerout'),
3082
- pointerenter: this.emitEvent('pointerenter'),
3083
- pointerleave: this.emitEvent('pointerleave'),
3084
- pointermove: this.emitEvent('pointermove'),
3085
- pointermissed: this.emitEvent('pointermissed'),
3086
- pointercancel: this.emitEvent('pointercancel'),
3087
- wheel: this.emitEvent('wheel'),
3088
- }, { injector });
3075
+ injectObjectEvents(this.ngtObjectEvents, {
3076
+ click: this.emitEvent('click'),
3077
+ dblclick: this.emitEvent('dblclick'),
3078
+ contextmenu: this.emitEvent('contextmenu'),
3079
+ pointerup: this.emitEvent('pointerup'),
3080
+ pointerdown: this.emitEvent('pointerdown'),
3081
+ pointerover: this.emitEvent('pointerover'),
3082
+ pointerout: this.emitEvent('pointerout'),
3083
+ pointerenter: this.emitEvent('pointerenter'),
3084
+ pointerleave: this.emitEvent('pointerleave'),
3085
+ pointermove: this.emitEvent('pointermove'),
3086
+ pointermissed: this.emitEvent('pointermissed'),
3087
+ pointercancel: this.emitEvent('pointercancel'),
3088
+ wheel: this.emitEvent('wheel'),
3089
3089
  });
3090
3090
  }
3091
3091
  emitEvent(eventName) {
3092
3092
  return this[eventName].emit.bind(this[eventName]);
3093
3093
  }
3094
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtObjectEvents, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3095
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.0", type: NgtObjectEvents, isStandalone: true, selector: "[ngtObjectEvents]", inputs: { ngtObjectEvents: { classPropertyName: "ngtObjectEvents", publicName: "ngtObjectEvents", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { click: "click", dblclick: "dblclick", contextmenu: "contextmenu", pointerup: "pointerup", pointerdown: "pointerdown", pointerover: "pointerover", pointerout: "pointerout", pointerenter: "pointerenter", pointerleave: "pointerleave", pointermove: "pointermove", pointermissed: "pointermissed", pointercancel: "pointercancel", wheel: "wheel", ngtObjectEvents: "ngtObjectEventsChange" }, ngImport: i0 }); }
3094
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtObjectEvents, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3095
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.4", type: NgtObjectEvents, isStandalone: true, selector: "[ngtObjectEvents]", inputs: { ngtObjectEvents: { classPropertyName: "ngtObjectEvents", publicName: "ngtObjectEvents", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { click: "click", dblclick: "dblclick", contextmenu: "contextmenu", pointerup: "pointerup", pointerdown: "pointerdown", pointerover: "pointerover", pointerout: "pointerout", pointerenter: "pointerenter", pointerleave: "pointerleave", pointermove: "pointermove", pointermissed: "pointermissed", pointercancel: "pointercancel", wheel: "wheel", ngtObjectEvents: "ngtObjectEventsChange" }, ngImport: i0 }); }
3096
3096
  }
3097
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtObjectEvents, decorators: [{
3097
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.4", ngImport: i0, type: NgtObjectEvents, decorators: [{
3098
3098
  type: Directive,
3099
3099
  args: [{ standalone: true, selector: '[ngtObjectEvents]' }]
3100
3100
  }], ctorParameters: () => [] });
@@ -3139,6 +3139,15 @@ function injectObjectEvents(target, events, { injector } = {}) {
3139
3139
  });
3140
3140
  }
3141
3141
 
3142
+ function getEmitter(emitterRef) {
3143
+ if (!emitterRef || !emitterRef['listeners'] || emitterRef['destroyed'])
3144
+ return undefined;
3145
+ return emitterRef.emit.bind(emitterRef);
3146
+ }
3147
+ function hasListener(...emitterRefs) {
3148
+ return emitterRefs.some((emitterRef) => emitterRef && !emitterRef['destroyed'] && emitterRef['listeners'] && emitterRef['listeners'].length > 0);
3149
+ }
3150
+
3142
3151
  function omit(objFn, keysToOmit) {
3143
3152
  return computed(() => {
3144
3153
  const obj = objFn();
@@ -3211,5 +3220,5 @@ const vector4 = createVectorComputed(Vector4);
3211
3220
  * Generated bundle index. Do not edit.
3212
3221
  */
3213
3222
 
3214
- export { HTML, NGT_APPLY_PROPS, NGT_STORE, NgtArgs, NgtCanvas, NgtHTML, NgtHexify, NgtObjectEvents, NgtObjectEventsHostDirective, NgtPortal, NgtPortalBeforeRender, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, NgtSelect, NgtSelection, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, attach, checkNeedsUpdate, checkUpdate, createAttachFunction, detach, dispose, extend, flushGlobalEffects, getLocalState, injectBeforeRender, injectCanvasRootInitializer, injectLoader, injectLoop, injectNonNullish$, injectObjectEvents, injectStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, merge, omit, pick, prepare, privateKeys, provideHTMLDomElement, provideNgtRenderer, provideStore, resolveRef, roots, signalStore, updateCamera, vector2, vector3, vector4 };
3223
+ export { HTML, NGT_APPLY_PROPS, NGT_STORE, NON_ROOT, NgtArgs, NgtCanvas, NgtHTML, NgtHexify, NgtObjectEvents, NgtObjectEventsHostDirective, NgtPortal, NgtPortalBeforeRender, NgtPortalContent, NgtRenderer, NgtRendererFactory, NgtRoutedScene, NgtSelect, NgtSelection, ROUTED_SCENE, addAfterEffect, addEffect, addTail, applyProps, attach, checkNeedsUpdate, checkUpdate, createAttachFunction, detach, dispose, extend, flushGlobalEffects, getEmitter, getLocalState, hasListener, injectBeforeRender, injectCanvasRootInitializer, injectLoader, injectLoop, injectObjectEvents, injectStore, invalidateInstance, is, makeCameraInstance, makeDpr, makeId, makeObjectGraph, makeRendererInstance, merge, omit, pick, prepare, privateKeys, provideHTMLDomElement, provideNgtRenderer, provideStore, resolveRef, roots, signalStore, updateCamera, vector2, vector3, vector4 };
3215
3224
  //# sourceMappingURL=angular-three.mjs.map