angular-three 2.0.0-beta.41 → 2.0.0-beta.42

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { untracked, computed, signal, ElementRef, runInInjectionContext, inject, DestroyRef, effect, ChangeDetectorRef, InjectionToken, Injector, Optional, SkipSelf, ViewContainerRef, NgZone, TemplateRef, Directive, Input, EventEmitter, getDebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, provideZoneChangeDetection, EnvironmentInjector, createEnvironmentInjector, Component, ChangeDetectionStrategy, Output, ViewChild, ContentChild } from '@angular/core';
2
+ import { untracked, computed, signal, ElementRef, inject, Injector, DestroyRef, effect, runInInjectionContext, ChangeDetectorRef, InjectionToken, Optional, SkipSelf, ViewContainerRef, NgZone, TemplateRef, Directive, Input, EventEmitter, getDebugNode, RendererFactory2, Injectable, makeEnvironmentProviders, provideZoneChangeDetection, EnvironmentInjector, createEnvironmentInjector, Component, ChangeDetectionStrategy, Output, ViewChild, CUSTOM_ELEMENTS_SCHEMA, ContentChild, forwardRef } from '@angular/core';
3
3
  import { assertInjector } from 'ngxtension/assert-injector';
4
4
  import { DOCUMENT, NgIf } from '@angular/common';
5
5
  import { createInjectionToken } from 'ngxtension/create-injection-token';
@@ -58,7 +58,7 @@ const selector = (_state, computedCache) => (...keysAndOptions) => {
58
58
  }
59
59
  const [keys, options] = parseStoreOptions(keysAndOptions);
60
60
  const joinedKeys = keys.join('-');
61
- const cachedKeys = joinedKeys.concat(options ? JSON.stringify(options) : '');
61
+ const cachedKeys = joinedKeys.concat(JSON.stringify(options));
62
62
  if (!computedCache.has(cachedKeys)) {
63
63
  computedCache.set(cachedKeys, computed(() => keys.reduce((value, key) => value[key], _state()), options));
64
64
  }
@@ -95,7 +95,7 @@ function signalStore(initialState = {}, options) {
95
95
  const store = { select, get, set, patch, state };
96
96
  // NOTE: internal _snapshot to debug current state
97
97
  Object.defineProperty(store, '_snapshot', {
98
- get: state,
98
+ get: untracked.bind({}, state),
99
99
  configurable: false,
100
100
  enumerable: false,
101
101
  });
@@ -203,37 +203,41 @@ function invalidateInstance(instance) {
203
203
  function prepare(object, localState) {
204
204
  const instance = object;
205
205
  if (localState?.primitive || !instance.__ngt__) {
206
- const { objects = signal([]), nonObjects = signal([]), ...rest } = localState || {};
206
+ const { instanceStore = signalStore({
207
+ nativeProps: {},
208
+ parent: null,
209
+ objects: [],
210
+ nonObjects: [],
211
+ }), ...rest } = localState || {};
207
212
  instance.__ngt__ = {
208
213
  previousAttach: null,
209
214
  store: null,
210
- parent: signal(null),
211
215
  memoized: {},
212
216
  eventCount: 0,
213
217
  handlers: {},
214
- objects,
215
- nonObjects,
216
- nativeProps: signalStore(),
218
+ instanceStore,
217
219
  add: (object, type) => {
218
- untracked(() => {
219
- const current = instance.__ngt__[type]();
220
- const foundIndex = current.indexOf((obj) => obj === object);
221
- if (foundIndex > -1) {
222
- // if we add an object with the same reference, then we switch it out
223
- current.splice(foundIndex, 1, object);
224
- instance.__ngt__[type].set(current);
225
- }
226
- else {
227
- instance.__ngt__[type].update((prev) => [...prev, object]);
228
- }
229
- notifyAncestors(instance.__ngt__.parent());
230
- });
220
+ const current = instance.__ngt__.instanceStore.get(type);
221
+ const foundIndex = current.indexOf((obj) => obj === object);
222
+ if (foundIndex > -1) {
223
+ // if we add an object with the same reference, then we switch it out
224
+ current.splice(foundIndex, 1, object);
225
+ instance.__ngt__.instanceStore.set({ [type]: current });
226
+ }
227
+ else {
228
+ instance.__ngt__.instanceStore.set((prev) => ({ [type]: [...prev[type], object] }));
229
+ }
230
+ notifyAncestors(instance.__ngt__.instanceStore.get('parent'));
231
231
  },
232
232
  remove: (object, type) => {
233
- untracked(() => {
234
- instance.__ngt__[type].update((prev) => prev.filter((o) => o !== object));
235
- notifyAncestors(instance.__ngt__.parent());
236
- });
233
+ instance.__ngt__.instanceStore.set((prev) => ({ [type]: prev[type].filter((o) => o !== object) }));
234
+ notifyAncestors(instance.__ngt__.instanceStore.get('parent'));
235
+ },
236
+ setNativeProps: (key, value) => {
237
+ instance.__ngt__.instanceStore.set((prev) => ({ nativeProps: { ...prev.nativeProps, [key]: value } }));
238
+ },
239
+ setParent: (parent) => {
240
+ instance.__ngt__.instanceStore.set({ parent });
237
241
  },
238
242
  ...rest,
239
243
  };
@@ -244,11 +248,10 @@ function notifyAncestors(instance) {
244
248
  if (!instance)
245
249
  return;
246
250
  const localState = getLocalState(instance);
247
- if (localState.objects)
248
- localState.objects.update((prev) => prev);
249
- if (localState.nonObjects)
250
- localState.nonObjects.update((prev) => prev);
251
- notifyAncestors(localState.parent());
251
+ if (localState.instanceStore) {
252
+ localState.instanceStore.set((prev) => ({ objects: prev.objects, nonObjects: prev.nonObjects }));
253
+ notifyAncestors(localState.instanceStore.get('parent'));
254
+ }
252
255
  }
253
256
 
254
257
  // This function prepares a set of changes to be applied to the instance
@@ -276,8 +279,7 @@ function applyProps(instance, props) {
276
279
  // if props is empty
277
280
  if (!Object.keys(props).length)
278
281
  return instance;
279
- // Filter equals, events and reserved props
280
- // filter equals, events , and reserved props
282
+ // filter equals, and reserved props
281
283
  const localState = getLocalState(instance);
282
284
  const rootState = localState.store?.get();
283
285
  const changes = diffProps(instance, props);
@@ -356,9 +358,9 @@ function applyProps(instance, props) {
356
358
  checkUpdate(targetProp);
357
359
  invalidateInstance(instance);
358
360
  }
359
- const instanceHandlers = localState.eventCount;
360
- const parent = localState.parent ? untracked(localState.parent) : null;
361
- if (parent && rootState.internal && instance['raycast'] && instanceHandlers !== localState.eventCount) {
361
+ const instanceHandlersCount = localState.eventCount;
362
+ const parent = localState.instanceStore?.get('parent');
363
+ if (parent && rootState.internal && instance['raycast'] && instanceHandlersCount !== localState.eventCount) {
362
364
  // Pre-emptively remove the instance from the interaction manager
363
365
  const index = rootState.internal.interaction.indexOf(instance);
364
366
  if (index > -1)
@@ -425,8 +427,8 @@ function makeObjectGraph(object) {
425
427
  const shallowLoose = { objects: 'shallow', strict: false };
426
428
  const roots = new Map();
427
429
  function injectCanvasRootInitializer(injector) {
428
- injector = assertInjector(injectCanvasRootInitializer, injector);
429
- return runInInjectionContext(injector, () => {
430
+ return assertInjector(injectCanvasRootInitializer, injector, () => {
431
+ const assertedInjector = inject(Injector);
430
432
  const injectedStore = injectNgtStore();
431
433
  const loop = injectNgtLoop();
432
434
  const destroyRef = inject(DestroyRef);
@@ -636,8 +638,13 @@ function injectCanvasRootInitializer(injector) {
636
638
  if (state.frameloop !== frameloop)
637
639
  state.setFrameloop(frameloop);
638
640
  isConfigured = true;
639
- invalidateRef?.destroy();
640
- invalidateRef = effect(() => void store.state().invalidate(), { manualCleanup: true, injector });
641
+ queueMicrotask(() => {
642
+ invalidateRef?.destroy();
643
+ invalidateRef = effect(() => void store.state().invalidate(), {
644
+ manualCleanup: true,
645
+ injector: assertedInjector,
646
+ });
647
+ });
641
648
  },
642
649
  };
643
650
  };
@@ -1011,8 +1018,7 @@ const [injectNgtStore, provideNgtStore] = createInjectionToken(storeFactory, {
1011
1018
  });
1012
1019
 
1013
1020
  function injectBeforeRender(cb, { priority = 0, injector } = {}) {
1014
- injector = assertInjector(injectBeforeRender, injector);
1015
- return runInInjectionContext(injector, () => {
1021
+ return assertInjector(injectBeforeRender, injector, () => {
1016
1022
  const store = injectNgtStore();
1017
1023
  const sub = store.get('internal').subscribe(cb, priority, store);
1018
1024
  inject(DestroyRef).onDestroy(() => void sub());
@@ -1467,8 +1473,9 @@ function load(loaderConstructorFactory, inputs, { extensions, onProgress, } = {}
1467
1473
  if (!cached.has(url)) {
1468
1474
  cached.set(url, new Promise((resolve, reject) => {
1469
1475
  loader.load(url, (data) => {
1470
- if ('scene' in data)
1476
+ if ('scene' in data) {
1471
1477
  Object.assign(data, makeObjectGraph(data['scene']));
1478
+ }
1472
1479
  resolve(data);
1473
1480
  }, onProgress, (error) => reject(new Error(`[NGT] Could not load ${url}: ${error}`)));
1474
1481
  }));
@@ -1478,9 +1485,8 @@ function load(loaderConstructorFactory, inputs, { extensions, onProgress, } = {}
1478
1485
  };
1479
1486
  }
1480
1487
  function _injectNgtLoader(loaderConstructorFactory, inputs, { extensions, onProgress, injector, } = {}) {
1481
- injector = assertInjector(_injectNgtLoader, injector);
1482
- const response = signal(null);
1483
- return runInInjectionContext(injector, () => {
1488
+ return assertInjector(_injectNgtLoader, injector, () => {
1489
+ const response = signal(null);
1484
1490
  const cdr = inject(ChangeDetectorRef);
1485
1491
  const effector = load(loaderConstructorFactory, inputs, { extensions, onProgress });
1486
1492
  effect(() => {
@@ -1568,10 +1574,10 @@ class NgtCommonDirective {
1568
1574
  }
1569
1575
  });
1570
1576
  }
1571
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtCommonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1572
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtCommonDirective, ngImport: i0 }); }
1577
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtCommonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1578
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.9", type: NgtCommonDirective, ngImport: i0 }); }
1573
1579
  }
1574
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtCommonDirective, decorators: [{
1580
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtCommonDirective, decorators: [{
1575
1581
  type: Directive
1576
1582
  }], ctorParameters: function () { return []; } });
1577
1583
 
@@ -1597,10 +1603,10 @@ class NgtArgs extends NgtCommonDirective {
1597
1603
  validate() {
1598
1604
  return !this.injected && !!this.injectedArgs.length;
1599
1605
  }
1600
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtArgs, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1601
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: "args" }, usesInheritance: true, ngImport: i0 }); }
1606
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtArgs, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1607
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.9", type: NgtArgs, isStandalone: true, selector: "ng-template[args]", inputs: { args: "args" }, usesInheritance: true, ngImport: i0 }); }
1602
1608
  }
1603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtArgs, decorators: [{
1609
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtArgs, decorators: [{
1604
1610
  type: Directive,
1605
1611
  args: [{ selector: 'ng-template[args]', standalone: true }]
1606
1612
  }], propDecorators: { args: [{
@@ -1629,10 +1635,10 @@ class NgtParent extends NgtCommonDirective {
1629
1635
  validate() {
1630
1636
  return !this.injected && !!this.injectedParent;
1631
1637
  }
1632
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtParent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1633
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtParent, isStandalone: true, selector: "ng-template[parent]", inputs: { parent: "parent" }, usesInheritance: true, ngImport: i0 }); }
1638
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtParent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1639
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.9", type: NgtParent, isStandalone: true, selector: "ng-template[parent]", inputs: { parent: "parent" }, usesInheritance: true, ngImport: i0 }); }
1634
1640
  }
1635
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtParent, decorators: [{
1641
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtParent, decorators: [{
1636
1642
  type: Directive,
1637
1643
  args: [{ selector: 'ng-template[parent]', standalone: true }]
1638
1644
  }], propDecorators: { parent: [{
@@ -1737,10 +1743,8 @@ function attachThreeChild(parent, child) {
1737
1743
  }
1738
1744
  // attach
1739
1745
  if (cLS.isRaw) {
1740
- if (cLS.parent && cLS.parent() !== parent) {
1741
- untracked(() => {
1742
- cLS.parent.set(parent);
1743
- });
1746
+ if (cLS.instanceStore.get('parent') !== parent) {
1747
+ cLS.setParent(parent);
1744
1748
  }
1745
1749
  // at this point we don't have rawValue yet, so we bail and wait until the Renderer recalls attach
1746
1750
  if (child.__ngt_renderer__[NgtRendererClassId.rawValue] === undefined)
@@ -1759,10 +1763,8 @@ function attachThreeChild(parent, child) {
1759
1763
  added = true;
1760
1764
  }
1761
1765
  pLS.add(child, added ? 'objects' : 'nonObjects');
1762
- if (cLS.parent && cLS.parent() !== parent) {
1763
- untracked(() => {
1764
- cLS.parent.set(parent);
1765
- });
1766
+ if (cLS.instanceStore.get('parent') !== parent) {
1767
+ cLS.setParent(parent);
1766
1768
  }
1767
1769
  if (cLS.afterAttach)
1768
1770
  cLS.afterAttach.emit({ parent, node: child });
@@ -1773,14 +1775,10 @@ function removeThreeChild(parent, child, dispose) {
1773
1775
  const pLS = getLocalState(parent);
1774
1776
  const cLS = getLocalState(child);
1775
1777
  // clear parent ref
1776
- untracked(() => {
1777
- cLS.parent?.set(null);
1778
- });
1778
+ cLS.setParent?.(null);
1779
1779
  // remove child from parent
1780
- if (pLS.objects && untracked(pLS.objects))
1781
- pLS.remove(child, 'objects');
1782
- if (pLS.nonObjects && untracked(pLS.nonObjects))
1783
- pLS.remove(child, 'nonObjects');
1780
+ pLS.remove?.(child, 'objects');
1781
+ pLS.remove?.(child, 'nonObjects');
1784
1782
  if (cLS.attach) {
1785
1783
  detach(parent, child, cLS.attach);
1786
1784
  }
@@ -1790,7 +1788,7 @@ function removeThreeChild(parent, child, dispose) {
1790
1788
  }
1791
1789
  const isPrimitive = cLS.primitive;
1792
1790
  if (!isPrimitive) {
1793
- removeThreeRecursive(cLS.objects ? untracked(cLS.objects) : [], child, !!dispose);
1791
+ removeThreeRecursive(cLS.instanceStore?.get('objects') || [], child, !!dispose);
1794
1792
  removeThreeRecursive(child.children, child, !!dispose);
1795
1793
  }
1796
1794
  // dispose
@@ -2030,7 +2028,7 @@ class NgtRendererStore {
2030
2028
  value.nativeElement = node;
2031
2029
  return;
2032
2030
  }
2033
- const parent = getLocalState(node).parent() || rS[NgtRendererClassId.parent];
2031
+ const parent = getLocalState(node)?.instanceStore.get('parent') || rS[NgtRendererClassId.parent];
2034
2032
  // [rawValue]
2035
2033
  if (getLocalState(node).isRaw && name === SPECIAL_PROPERTIES.VALUE) {
2036
2034
  rS[NgtRendererClassId.rawValue] = value;
@@ -2119,11 +2117,9 @@ class NgtRendererStore {
2119
2117
  rS[NgtRendererClassId.compound] = undefined;
2120
2118
  rS[NgtRendererClassId.compoundParent] = undefined;
2121
2119
  const localState = getLocalState(node);
2122
- if (localState.objects) {
2123
- untracked(localState.objects).forEach((obj) => this.destroy(obj, parent));
2124
- }
2125
- if (localState.nonObjects) {
2126
- untracked(localState.nonObjects).forEach((obj) => this.destroy(obj, parent));
2120
+ if (localState.instanceStore) {
2121
+ localState.instanceStore.get('objects').forEach((obj) => this.destroy(obj, parent));
2122
+ localState.instanceStore.get('nonObjects').forEach((obj) => this.destroy(obj, parent));
2127
2123
  }
2128
2124
  if (localState.afterUpdate)
2129
2125
  localState.afterUpdate.complete();
@@ -2193,9 +2189,9 @@ class NgtRendererStore {
2193
2189
  }
2194
2190
  updateNativeProps(node, key, value) {
2195
2191
  const localState = getLocalState(node);
2196
- if (!localState || !localState.nativeProps)
2197
- return;
2198
- localState.nativeProps.set({ [key]: value });
2192
+ if (localState.instanceStore) {
2193
+ localState.setNativeProps(key, value);
2194
+ }
2199
2195
  }
2200
2196
  firstNonInjectedDirective(dir) {
2201
2197
  let directive;
@@ -2295,10 +2291,10 @@ class NgtRendererFactory {
2295
2291
  }
2296
2292
  return renderer;
2297
2293
  }
2298
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2299
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtRendererFactory }); }
2294
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtRendererFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2295
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtRendererFactory }); }
2300
2296
  }
2301
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtRendererFactory, decorators: [{
2297
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtRendererFactory, decorators: [{
2302
2298
  type: Injectable
2303
2299
  }] });
2304
2300
  /**
@@ -2464,7 +2460,7 @@ class NgtRenderer {
2464
2460
  // if both are three instances, straightforward case
2465
2461
  if (pRS[NgtRendererClassId.type] === 'three' && cRS?.[NgtRendererClassId.type] === 'three') {
2466
2462
  // if child already attached to a parent, skip
2467
- if (getLocalState(newChild).parent && untracked(getLocalState(newChild).parent))
2463
+ if (getLocalState(newChild).instanceStore?.get('parent'))
2468
2464
  return;
2469
2465
  // attach THREE child
2470
2466
  attachThreeChild(parent, newChild);
@@ -2599,7 +2595,13 @@ class NgtRenderer {
2599
2595
  // if the target doesn't have __ngt_renderer__, we delegate
2600
2596
  // if target is DOM node, then we pass that to delegate Renderer
2601
2597
  if (!rS || this.store.isDOM(target)) {
2602
- return this.delegate.listen(target, eventName, callback);
2598
+ const targetCdr = getDebugNode(target)?.injector.get(ChangeDetectorRef, null);
2599
+ const updatedCallback = (event) => {
2600
+ const callbackValue = callback(event);
2601
+ safeDetectChanges(targetCdr || this.cdr);
2602
+ return callbackValue;
2603
+ };
2604
+ return this.delegate.listen(target, eventName, updatedCallback);
2603
2605
  }
2604
2606
  if (rS[NgtRendererClassId.type] === 'three' ||
2605
2607
  (rS[NgtRendererClassId.type] === 'compound' && rS[NgtRendererClassId.compounded])) {
@@ -2636,7 +2638,7 @@ class NgtRenderer {
2636
2638
  const isParentCompounded = pRS[NgtRendererClassId.compounded];
2637
2639
  const isChildCompounded = cRS[NgtRendererClassId.compounded];
2638
2640
  // if child is three but haven't been attached to a parent yet
2639
- const isDanglingThreeChild = cType === 'three' && !untracked(getLocalState(child).parent);
2641
+ const isDanglingThreeChild = cType === 'three' && !getLocalState(child).instanceStore?.get('parent');
2640
2642
  // or both parent and child are DOM elements
2641
2643
  // or they are compound AND haven't had a THREE instance yet
2642
2644
  const isParentStillDOM = pType === 'dom' || (pType === 'compound' && !isParentCompounded);
@@ -2758,7 +2760,6 @@ class NgtCanvas {
2758
2760
  if (result.width > 0 && result.height > 0) {
2759
2761
  this.resizeEffectRef?.destroy();
2760
2762
  const inputs = this.inputs.select();
2761
- // NOTE: go back into zone so that effect runs
2762
2763
  // TODO: Double-check when effect is made not depended on zone
2763
2764
  this.resizeEffectRef = this.zone.run(() => effect(() => {
2764
2765
  this.zone.runOutsideAngular(() => {
@@ -2766,7 +2767,7 @@ class NgtCanvas {
2766
2767
  this.configurator = this.initRoot(this.glCanvas.nativeElement);
2767
2768
  this.configurator.configure({ ...inputs(), size: result });
2768
2769
  if (this.glRef) {
2769
- this.cdr.detectChanges();
2770
+ safeDetectChanges(this.cdr);
2770
2771
  }
2771
2772
  else {
2772
2773
  this.render();
@@ -2775,13 +2776,13 @@ class NgtCanvas {
2775
2776
  }, { manualCleanup: true, injector: this.injector }));
2776
2777
  }
2777
2778
  }
2779
+ // NOTE: render outside of zone
2778
2780
  render() {
2779
2781
  this.glEnvironmentInjector?.destroy();
2780
2782
  this.glRef?.destroy();
2781
2783
  // Flag the canvas active, rendering will now begin
2782
2784
  this.store.set((state) => ({ internal: { ...state.internal, active: true } }));
2783
- const inputs = this.inputs.get();
2784
- const state = this.store.get();
2785
+ const [inputs, state] = [this.inputs.get(), this.store.get()];
2785
2786
  // connect to event source
2786
2787
  state.events.connect?.(inputs.eventSource
2787
2788
  ? is.ref(inputs.eventSource)
@@ -2792,11 +2793,11 @@ class NgtCanvas {
2792
2793
  if (inputs.eventPrefix) {
2793
2794
  state.setEvents({
2794
2795
  compute: (event, store) => {
2795
- const innerState = store.get();
2796
+ const { pointer, raycaster, camera, size } = store.get();
2796
2797
  const x = event[(inputs.eventPrefix + 'X')];
2797
2798
  const y = event[(inputs.eventPrefix + 'Y')];
2798
- innerState.pointer.set((x / innerState.size.width) * 2 - 1, -(y / innerState.size.height) * 2 + 1);
2799
- innerState.raycaster.setFromCamera(innerState.pointer, innerState.camera);
2799
+ pointer.set((x / size.width) * 2 - 1, -(y / size.height) * 2 + 1);
2800
+ raycaster.setFromCamera(pointer, camera);
2800
2801
  },
2801
2802
  });
2802
2803
  }
@@ -2822,7 +2823,7 @@ class NgtCanvas {
2822
2823
  const originalDetectChanges = this.cdr.detectChanges.bind(this.cdr);
2823
2824
  this.cdr.detectChanges = () => {
2824
2825
  originalDetectChanges();
2825
- safeDetectChanges(this.glRef?.changeDetectorRef);
2826
+ this.glRef && safeDetectChanges(this.glRef.changeDetectorRef);
2826
2827
  };
2827
2828
  }
2828
2829
  setSceneGraphInputs() {
@@ -2831,12 +2832,12 @@ class NgtCanvas {
2831
2832
  for (const [key, value] of Object.entries(this.sceneGraphInputs)) {
2832
2833
  this.glRef.setInput(key, value);
2833
2834
  }
2834
- this.glRef.changeDetectorRef.detectChanges();
2835
+ safeDetectChanges(this.glRef.changeDetectorRef);
2835
2836
  }
2836
2837
  });
2837
2838
  }
2838
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2839
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: "sceneGraph", sceneGraphInputs: "sceneGraphInputs", compoundPrefixes: "compoundPrefixes", linear: "linear", legacy: "legacy", flat: "flat", orthographic: "orthographic", frameloop: "frameloop", dpr: "dpr", raycaster: "raycaster", shadows: "shadows", camera: "camera", scene: "scene", gl: "gl", eventSource: "eventSource", eventPrefix: "eventPrefix", lookAt: "lookAt", performance: "performance" }, outputs: { created: "created" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
2839
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtCanvas, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2840
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { sceneGraph: "sceneGraph", sceneGraphInputs: "sceneGraphInputs", compoundPrefixes: "compoundPrefixes", linear: "linear", legacy: "legacy", flat: "flat", orthographic: "orthographic", frameloop: "frameloop", dpr: "dpr", raycaster: "raycaster", shadows: "shadows", camera: "camera", scene: "scene", gl: "gl", eventSource: "eventSource", eventPrefix: "eventPrefix", lookAt: "lookAt", performance: "performance" }, outputs: { created: "created" }, host: { properties: { "style.pointerEvents": "hbPointerEvents()" }, styleAttribute: "display: block;position: relative;width: 100%;height: 100%;overflow: hidden;" }, providers: [
2840
2841
  provideResizeOptions({ emitInZone: false, emitInitialResult: true }),
2841
2842
  provideNgtStore(),
2842
2843
  ], viewQueries: [{ propertyName: "glCanvas", first: true, predicate: ["glCanvas"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
@@ -2845,7 +2846,7 @@ class NgtCanvas {
2845
2846
  </div>
2846
2847
  `, isInline: true, dependencies: [{ kind: "directive", type: NgxResize, selector: "[ngxResize]", inputs: ["ngxResizeOptions"], outputs: ["ngxResize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2847
2848
  }
2848
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtCanvas, decorators: [{
2849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtCanvas, decorators: [{
2849
2850
  type: Component,
2850
2851
  args: [{
2851
2852
  selector: 'ngt-canvas',
@@ -2926,10 +2927,10 @@ class NgtKey extends NgtCommonDirective {
2926
2927
  this.createView();
2927
2928
  }
2928
2929
  }
2929
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtKey, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2930
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtKey, isStandalone: true, selector: "ng-template[key]", inputs: { key: "key" }, usesInheritance: true, ngImport: i0 }); }
2930
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtKey, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2931
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.9", type: NgtKey, isStandalone: true, selector: "ng-template[key]", inputs: { key: "key" }, usesInheritance: true, ngImport: i0 }); }
2931
2932
  }
2932
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtKey, decorators: [{
2933
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtKey, decorators: [{
2933
2934
  type: Directive,
2934
2935
  args: [{ selector: 'ng-template[key]', standalone: true }]
2935
2936
  }], propDecorators: { key: [{
@@ -2937,12 +2938,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
2937
2938
  }] } });
2938
2939
 
2939
2940
  function injectNgtRef(initial = null, injector) {
2940
- injector = assertInjector(injectNgtRef, injector);
2941
- const ref = is.ref(initial) ? initial : new ElementRef(initial);
2942
- const refSignal = signal(ref.nativeElement);
2943
- const readonlyRef = refSignal.asReadonly();
2944
- const computedCached = new Map();
2945
- return runInInjectionContext(injector, () => {
2941
+ return assertInjector(injectNgtRef, injector, () => {
2942
+ const ref = is.ref(initial) ? initial : new ElementRef(initial);
2943
+ const refSignal = signal(ref.nativeElement);
2944
+ const readonlyRef = refSignal.asReadonly();
2945
+ const computedCached = new Map();
2946
2946
  inject(DestroyRef).onDestroy(() => void computedCached.clear());
2947
2947
  const children = (type = 'objects') => {
2948
2948
  if (!computedCached.has(type)) {
@@ -2951,13 +2951,17 @@ function injectNgtRef(initial = null, injector) {
2951
2951
  if (!instance)
2952
2952
  return [];
2953
2953
  const localState = getLocalState(instance);
2954
- if (!localState.objects || !localState.nonObjects)
2954
+ if (!localState.instanceStore)
2955
2955
  return [];
2956
+ const [objects, nonObjects] = [
2957
+ localState.instanceStore.select('objects'),
2958
+ localState.instanceStore.select('nonObjects'),
2959
+ ];
2956
2960
  if (type === 'objects')
2957
- return localState.objects();
2961
+ return objects();
2958
2962
  if (type === 'nonObjects')
2959
- return localState.nonObjects();
2960
- return [...localState.objects(), ...localState.nonObjects()];
2963
+ return nonObjects();
2964
+ return [...objects(), ...nonObjects()];
2961
2965
  }));
2962
2966
  }
2963
2967
  return computedCached.get(type);
@@ -2973,7 +2977,6 @@ function injectNgtRef(initial = null, injector) {
2973
2977
  },
2974
2978
  get: readonlyRef,
2975
2979
  },
2976
- untracked: { get: () => untracked(readonlyRef) },
2977
2980
  children: { get: () => children },
2978
2981
  });
2979
2982
  return ref;
@@ -2998,12 +3001,10 @@ class NgtPortalBeforeRender {
2998
3001
  this.portalStore = injectNgtStore();
2999
3002
  this.injector = inject(Injector);
3000
3003
  this.renderPriority = 1;
3001
- this.beforeRender = new EventEmitter();
3002
3004
  }
3003
3005
  ngOnInit() {
3004
3006
  let oldClear;
3005
- injectBeforeRender(({ delta, frame }) => {
3006
- this.beforeRender.emit({ ...this.portalStore.get(), delta, frame });
3007
+ injectBeforeRender(() => {
3007
3008
  const { gl, scene, camera } = this.portalStore.get();
3008
3009
  oldClear = gl.autoClear;
3009
3010
  if (this.renderPriority === 1) {
@@ -3019,12 +3020,26 @@ class NgtPortalBeforeRender {
3019
3020
  gl.autoClear = oldClear;
3020
3021
  }, { priority: this.renderPriority, injector: this.injector });
3021
3022
  }
3022
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3023
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtPortalBeforeRender, isStandalone: true, selector: "[ngtPortalBeforeRender]", inputs: { renderPriority: "renderPriority", parentScene: "parentScene", parentCamera: "parentCamera" }, outputs: { beforeRender: "beforeRender" }, ngImport: i0 }); }
3023
+ onPointerOver() {
3024
+ /* noop */
3025
+ }
3026
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtPortalBeforeRender, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3027
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: NgtPortalBeforeRender, isStandalone: true, selector: "ngt-portal-before-render", inputs: { renderPriority: "renderPriority", parentScene: "parentScene", parentCamera: "parentCamera" }, ngImport: i0, template: `
3028
+ <!-- Without an element that receives pointer events state.pointer will always be 0/0 -->
3029
+ <ngt-group (pointerover)="onPointerOver()" />
3030
+ `, isInline: true }); }
3024
3031
  }
3025
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
3026
- type: Directive,
3027
- args: [{ selector: '[ngtPortalBeforeRender]', standalone: true }]
3032
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtPortalBeforeRender, decorators: [{
3033
+ type: Component,
3034
+ args: [{
3035
+ selector: 'ngt-portal-before-render',
3036
+ standalone: true,
3037
+ template: `
3038
+ <!-- Without an element that receives pointer events state.pointer will always be 0/0 -->
3039
+ <ngt-group (pointerover)="onPointerOver()" />
3040
+ `,
3041
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
3042
+ }]
3028
3043
  }], propDecorators: { renderPriority: [{
3029
3044
  type: Input
3030
3045
  }], parentScene: [{
@@ -3033,8 +3048,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
3033
3048
  }], parentCamera: [{
3034
3049
  type: Input,
3035
3050
  args: [{ required: true }]
3036
- }], beforeRender: [{
3037
- type: Output
3038
3051
  }] } });
3039
3052
  class NgtPortalContent {
3040
3053
  constructor(vcr, parentVcr) {
@@ -3044,10 +3057,10 @@ class NgtPortalContent {
3044
3057
  delete commentNode[SPECIAL_INTERNAL_ADD_COMMENT];
3045
3058
  }
3046
3059
  }
3047
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtPortalContent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ViewContainerRef, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }
3048
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtPortalContent, isStandalone: true, selector: "ng-template[ngtPortalContent]", ngImport: i0 }); }
3060
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtPortalContent, deps: [{ token: i0.ViewContainerRef }, { token: i0.ViewContainerRef, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }
3061
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.9", type: NgtPortalContent, isStandalone: true, selector: "ng-template[ngtPortalContent]", ngImport: i0 }); }
3049
3062
  }
3050
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtPortalContent, decorators: [{
3063
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtPortalContent, decorators: [{
3051
3064
  type: Directive,
3052
3065
  args: [{ selector: 'ng-template[ngtPortalContent]', standalone: true }]
3053
3066
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ViewContainerRef, decorators: [{
@@ -3064,7 +3077,6 @@ class NgtPortal {
3064
3077
  this.inputs = signalStore({ container: injectNgtRef(prepare(new THREE.Scene())) });
3065
3078
  this.autoRender = true;
3066
3079
  this.autoRenderPriority = 1;
3067
- this.beforeRender = new EventEmitter();
3068
3080
  this.parentStore = injectNgtStore({ skipSelf: true });
3069
3081
  this.parentScene = this.parentStore.get('scene');
3070
3082
  this.parentCamera = this.parentStore.get('camera');
@@ -3121,12 +3133,6 @@ class NgtPortal {
3121
3133
  safeDetectChanges(this.portalContentView);
3122
3134
  this.portalContentRendered = true;
3123
3135
  }
3124
- onBeforeRender(portal) {
3125
- this.beforeRender.emit({
3126
- root: { ...this.parentStore.get(), delta: portal.delta, frame: portal.frame },
3127
- portal,
3128
- });
3129
- }
3130
3136
  inject(rootState, injectState) {
3131
3137
  const intersect = { ...rootState };
3132
3138
  Object.keys(intersect).forEach((key) => {
@@ -3156,39 +3162,35 @@ class NgtPortal {
3156
3162
  ...restInputsState,
3157
3163
  };
3158
3164
  }
3159
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3160
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { container: "container", portalState: ["state", "portalState"], autoRender: "autoRender", autoRenderPriority: "autoRenderPriority" }, outputs: { beforeRender: "beforeRender" }, providers: [{ provide: NGT_STORE, useFactory: () => signalStore({}) }], queries: [{ propertyName: "portalContentTemplate", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "portalContentAnchor", first: true, predicate: ["portalContentAnchor"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
3165
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3166
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: NgtPortal, isStandalone: true, selector: "ngt-portal", inputs: { container: "container", portalState: ["state", "portalState"], autoRender: "autoRender", autoRenderPriority: "autoRenderPriority" }, providers: [provideNgtStore(signalStore({}))], queries: [{ propertyName: "portalContentTemplate", first: true, predicate: NgtPortalContent, descendants: true, read: TemplateRef, static: true }], viewQueries: [{ propertyName: "portalContentAnchor", first: true, predicate: ["portalContentAnchor"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: `
3161
3167
  <ng-container #portalContentAnchor>
3162
- <ng-container
3168
+ <ngt-portal-before-render
3163
3169
  *ngIf="autoRender && portalContentRendered"
3164
- ngtPortalBeforeRender
3165
3170
  [renderPriority]="autoRenderPriority"
3166
3171
  [parentScene]="parentScene"
3167
3172
  [parentCamera]="parentCamera"
3168
- (beforeRender)="onBeforeRender($event)"
3169
3173
  />
3170
3174
  </ng-container>
3171
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgtPortalBeforeRender, selector: "[ngtPortalBeforeRender]", inputs: ["renderPriority", "parentScene", "parentCamera"], outputs: ["beforeRender"] }] }); }
3175
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgtPortalBeforeRender, selector: "ngt-portal-before-render", inputs: ["renderPriority", "parentScene", "parentCamera"] }] }); }
3172
3176
  }
3173
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtPortal, decorators: [{
3177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtPortal, decorators: [{
3174
3178
  type: Component,
3175
3179
  args: [{
3176
3180
  selector: 'ngt-portal',
3177
3181
  standalone: true,
3178
3182
  template: `
3179
3183
  <ng-container #portalContentAnchor>
3180
- <ng-container
3184
+ <ngt-portal-before-render
3181
3185
  *ngIf="autoRender && portalContentRendered"
3182
- ngtPortalBeforeRender
3183
3186
  [renderPriority]="autoRenderPriority"
3184
3187
  [parentScene]="parentScene"
3185
3188
  [parentCamera]="parentCamera"
3186
- (beforeRender)="onBeforeRender($event)"
3187
3189
  />
3188
3190
  </ng-container>
3189
3191
  `,
3190
3192
  imports: [NgIf, NgtPortalBeforeRender],
3191
- providers: [{ provide: NGT_STORE, useFactory: () => signalStore({}) }],
3193
+ providers: [provideNgtStore(signalStore({}))],
3192
3194
  }]
3193
3195
  }], ctorParameters: function () { return []; }, propDecorators: { container: [{
3194
3196
  type: Input
@@ -3199,8 +3201,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
3199
3201
  type: Input
3200
3202
  }], autoRenderPriority: [{
3201
3203
  type: Input
3202
- }], beforeRender: [{
3203
- type: Output
3204
3204
  }], portalContentTemplate: [{
3205
3205
  type: ContentChild,
3206
3206
  args: [NgtPortalContent, { read: TemplateRef, static: true }]
@@ -3218,12 +3218,12 @@ class NgtRoutedScene {
3218
3218
  .pipe(filter((event) => event instanceof ActivationEnd), takeUntilDestroyed())
3219
3219
  .subscribe(() => safeDetectChanges(cdr));
3220
3220
  }
3221
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3222
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
3221
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtRoutedScene, deps: [{ token: i1.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
3222
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.9", type: NgtRoutedScene, isStandalone: true, selector: "ngt-routed-scene", ngImport: i0, template: `
3223
3223
  <router-outlet />
3224
3224
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); }
3225
3225
  }
3226
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtRoutedScene, decorators: [{
3226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: NgtRoutedScene, decorators: [{
3227
3227
  type: Component,
3228
3228
  args: [{
3229
3229
  standalone: true,
@@ -3235,9 +3235,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
3235
3235
  }]
3236
3236
  }], ctorParameters: function () { return [{ type: i1.Router }, { type: i0.ChangeDetectorRef }]; } });
3237
3237
 
3238
+ function createApiToken(forwardedObject) {
3239
+ function apiFactory(obj) {
3240
+ return obj.api;
3241
+ }
3242
+ const [injectFn, provideFn] = createInjectionToken(apiFactory, {
3243
+ isRoot: false,
3244
+ deps: [forwardRef(forwardedObject)],
3245
+ });
3246
+ return [injectFn, () => provideFn()];
3247
+ }
3248
+
3238
3249
  /**
3239
3250
  * Generated bundle index. Do not edit.
3240
3251
  */
3241
3252
 
3242
- export { HTML, NGT_STORE, NgtArgs, NgtCanvas, NgtKey, NgtParent, NgtPortal, NgtPortalContent, NgtRoutedScene, addAfterEffect, addEffect, addTail, applyProps, checkNeedsUpdate, checkUpdate, createAttachFunction, diffProps, extend, getLocalState, injectBeforeRender, injectNgtLoader, injectNgtRef, injectNgtStore, invalidateInstance, is, makeDefaultCamera, makeDefaultRenderer, makeDpr, makeId, makeObjectGraph, prepare, provideNgtRenderer, provideNgtStore, safeDetectChanges, signalStore, updateCamera };
3253
+ export { HTML, NGT_STORE, NgtArgs, NgtCanvas, NgtKey, NgtParent, NgtPortal, NgtPortalContent, NgtRoutedScene, addAfterEffect, addEffect, addTail, applyProps, checkNeedsUpdate, checkUpdate, createApiToken, createAttachFunction, diffProps, extend, getLocalState, injectBeforeRender, injectNgtLoader, injectNgtRef, injectNgtStore, invalidateInstance, is, makeDefaultCamera, makeDefaultRenderer, makeDpr, makeId, makeObjectGraph, prepare, provideNgtRenderer, provideNgtStore, safeDetectChanges, signalStore, updateCamera };
3243
3254
  //# sourceMappingURL=angular-three.mjs.map