lunchboxjs 0.1.4001 → 0.1.4005

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,16 +1,11 @@
1
1
  import { h, defineComponent } from 'vue'
2
- // import Gltf from './Gltf'
3
- // import { Lunchbox } from '../types'
4
2
  import { LunchboxWrapper } from './LunchboxWrapper/LunchboxWrapper'
3
+ import { autoGeneratedComponents } from './autoGeneratedComponents'
5
4
 
6
5
  import { catalogue } from './catalogue'
7
6
  export { catalogue }
8
7
 
9
- export const lunchboxDomComponentNames = [
10
- 'canvas',
11
- 'div',
12
- 'LunchboxWrapper',
13
- ]
8
+ export const lunchboxDomComponentNames = ['canvas', 'div', 'LunchboxWrapper']
14
9
 
15
10
  // component creation utility
16
11
  const createComponent = (tag: string) =>
@@ -22,190 +17,12 @@ const createComponent = (tag: string) =>
22
17
  },
23
18
  })
24
19
 
25
- // list of all components to register out of the box
26
- const autoGeneratedComponents = [
27
-
28
- // ThreeJS basics
29
- 'mesh',
30
- 'instancedMesh',
31
- 'scene',
32
- 'sprite',
33
- 'object3D',
34
-
35
- // geometry
36
- 'instancedBufferGeometry',
37
- 'bufferGeometry',
38
- 'boxBufferGeometry',
39
- 'circleBufferGeometry',
40
- 'coneBufferGeometry',
41
- 'cylinderBufferGeometry',
42
- 'dodecahedronBufferGeometry',
43
- 'extrudeBufferGeometry',
44
- 'icosahedronBufferGeometry',
45
- 'latheBufferGeometry',
46
- 'octahedronBufferGeometry',
47
- 'parametricBufferGeometry',
48
- 'planeBufferGeometry',
49
- 'polyhedronBufferGeometry',
50
- 'ringBufferGeometry',
51
- 'shapeBufferGeometry',
52
- 'sphereBufferGeometry',
53
- 'tetrahedronBufferGeometry',
54
- 'textBufferGeometry',
55
- 'torusBufferGeometry',
56
- 'torusKnotBufferGeometry',
57
- 'tubeBufferGeometry',
58
- 'wireframeGeometry',
59
- 'parametricGeometry',
60
- 'tetrahedronGeometry',
61
- 'octahedronGeometry',
62
- 'icosahedronGeometry',
63
- 'dodecahedronGeometry',
64
- 'polyhedronGeometry',
65
- 'tubeGeometry',
66
- 'torusKnotGeometry',
67
- 'torusGeometry',
68
- // textgeometry has been moved to /examples/jsm/geometries/TextGeometry
69
- // 'textGeometry',
70
- 'sphereGeometry',
71
- 'ringGeometry',
72
- 'planeGeometry',
73
- 'latheGeometry',
74
- 'shapeGeometry',
75
- 'extrudeGeometry',
76
- 'edgesGeometry',
77
- 'coneGeometry',
78
- 'cylinderGeometry',
79
- 'circleGeometry',
80
- 'boxGeometry',
81
-
82
- // materials
83
- 'material',
84
- 'shadowMaterial',
85
- 'spriteMaterial',
86
- 'rawShaderMaterial',
87
- 'shaderMaterial',
88
- 'pointsMaterial',
89
- 'meshPhysicalMaterial',
90
- 'meshStandardMaterial',
91
- 'meshPhongMaterial',
92
- 'meshToonMaterial',
93
- 'meshNormalMaterial',
94
- 'meshLambertMaterial',
95
- 'meshDepthMaterial',
96
- 'meshDistanceMaterial',
97
- 'meshBasicMaterial',
98
- 'meshMatcapMaterial',
99
- 'lineDashedMaterial',
100
- 'lineBasicMaterial',
101
-
102
- // lights
103
- 'light',
104
- 'spotLightShadow',
105
- 'spotLight',
106
- 'pointLight',
107
- 'rectAreaLight',
108
- 'hemisphereLight',
109
- 'directionalLightShadow',
110
- 'directionalLight',
111
- 'ambientLight',
112
- 'lightShadow',
113
- 'ambientLightProbe',
114
- 'hemisphereLightProbe',
115
- 'lightProbe',
116
-
117
- // textures
118
- 'texture',
119
- 'videoTexture',
120
- 'dataTexture',
121
- 'dataTexture3D',
122
- 'compressedTexture',
123
- 'cubeTexture',
124
- 'canvasTexture',
125
- 'depthTexture',
126
-
127
- // Texture loaders
128
- 'textureLoader',
129
-
130
- // misc
131
- 'group',
132
- 'catmullRomCurve3',
133
- 'points',
134
-
135
- // helpers
136
- 'cameraHelper',
137
-
138
- // cameras
139
- 'camera',
140
- 'perspectiveCamera',
141
- 'orthographicCamera',
142
- 'cubeCamera',
143
- 'arrayCamera',
144
-
145
- // renderers
146
- 'webGLRenderer',
147
- ].map(createComponent).reduce((acc, curr) => {
148
- ; (acc as any)[curr.name] = curr
20
+ autoGeneratedComponents.map(createComponent).reduce((acc, curr) => {
21
+ ;(acc as any)[curr.name] = curr
149
22
  return acc
150
23
  })
151
24
 
152
25
  export const components = {
153
26
  ...autoGeneratedComponents,
154
- 'Lunchbox': LunchboxWrapper,
155
- // Gltf,
27
+ Lunchbox: LunchboxWrapper,
156
28
  }
157
-
158
- // console.log(components, Gltf)
159
-
160
- /*
161
- // List copied from r3f
162
- // https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
163
-
164
- // NOT IMPLEMENTED:
165
- audioListener: AudioListenerProps
166
- positionalAudio: PositionalAudioProps
167
-
168
- lOD: LODProps
169
- skinnedMesh: SkinnedMeshProps
170
- skeleton: SkeletonProps
171
- bone: BoneProps
172
- lineSegments: LineSegmentsProps
173
- lineLoop: LineLoopProps
174
- // see `audio`
175
- // line: LineProps
176
- immediateRenderObject: ImmediateRenderObjectProps
177
-
178
- // primitive
179
- primitive: PrimitiveProps
180
-
181
- // helpers
182
- spotLightHelper: SpotLightHelperProps
183
- skeletonHelper: SkeletonHelperProps
184
- pointLightHelper: PointLightHelperProps
185
- hemisphereLightHelper: HemisphereLightHelperProps
186
- gridHelper: GridHelperProps
187
- polarGridHelper: PolarGridHelperProps
188
- directionalLightHelper: DirectionalLightHelperProps
189
- boxHelper: BoxHelperProps
190
- box3Helper: Box3HelperProps
191
- planeHelper: PlaneHelperProps
192
- arrowHelper: ArrowHelperProps
193
- axesHelper: AxesHelperProps
194
-
195
-
196
- // misc
197
- raycaster: RaycasterProps
198
- vector2: Vector2Props
199
- vector3: Vector3Props
200
- vector4: Vector4Props
201
- euler: EulerProps
202
- matrix3: Matrix3Props
203
- matrix4: Matrix4Props
204
- quaternion: QuaternionProps
205
- bufferAttribute: BufferAttributeProps
206
- instancedBufferAttribute: InstancedBufferAttributeProps
207
- color: ColorProps
208
- fog: FogProps
209
- fogExp2: FogExp2Props
210
- shape: ShapeProps
211
- */
@@ -1,11 +1,11 @@
1
1
  import { isLunchboxRootNode } from '../utils'
2
- import { instantiateThreeObject, MiniDom } from '.'
2
+ import { instantiateThreeObject, MiniDom, ensuredScene } from '.'
3
3
  import { Lunch } from '..'
4
4
 
5
5
  /** Create a new Lunchbox comment node. */
6
6
  export function createCommentNode(options: Partial<Lunch.CommentMeta> = {}) {
7
7
  const defaults: Omit<Lunch.CommentMeta, keyof Lunch.MetaBase> = {
8
- text: options.text ?? ''
8
+ text: options.text ?? '',
9
9
  }
10
10
  return new MiniDom.RendererCommentNode({
11
11
  ...defaults,
@@ -29,11 +29,10 @@ export function createDomNode(options: Partial<Lunch.DomMeta> = {}) {
29
29
  return node
30
30
  }
31
31
 
32
-
33
32
  /** Create a new Lunchbox text node. */
34
33
  export function createTextNode(options: Partial<Lunch.TextMeta> = {}) {
35
34
  const defaults: Omit<Lunch.CommentMeta, keyof Lunch.MetaBase> = {
36
- text: options.text ?? ''
35
+ text: options.text ?? '',
37
36
  }
38
37
  return new MiniDom.RendererTextNode({
39
38
  ...options,
@@ -45,13 +44,12 @@ export function createTextNode(options: Partial<Lunch.TextMeta> = {}) {
45
44
  /** Create a new Lunchbox standard node. */
46
45
  export function createNode<T extends object = THREE.Object3D>(
47
46
  options: Partial<Lunch.StandardMeta<T>> = {},
48
- props: Lunch.LunchboxMetaProps = {},
47
+ props: Lunch.LunchboxMetaProps = {}
49
48
  ) {
50
-
51
49
  const defaults: Omit<Lunch.StandardMeta<T>, keyof Lunch.MetaBase> = {
52
50
  attached: options.attached ?? [],
53
51
  attachedArray: options.attachedArray ?? {},
54
- instance: options.instance ?? null
52
+ instance: options.instance ?? null,
55
53
  }
56
54
  const node = new MiniDom.RendererStandardNode<T>({
57
55
  ...options,
@@ -60,14 +58,26 @@ export function createNode<T extends object = THREE.Object3D>(
60
58
  })
61
59
 
62
60
  if (node.type && !isLunchboxRootNode(node) && !node.instance) {
61
+ // if (node.type.includes('Camera')) {
62
+ // console.log(node.type, {
63
+ // ...node.props,
64
+ // ...props,
65
+ // })
66
+ // console.trace()
67
+ // }
63
68
  node.instance = instantiateThreeObject({
64
69
  ...node,
65
70
  props: {
66
71
  ...node.props,
67
72
  ...props,
68
- }
73
+ },
69
74
  })
70
75
  }
71
76
 
77
+ if (node.type === 'scene') {
78
+ // manually set scene override
79
+ ensuredScene.value = node as Lunch.Node<THREE.Scene>
80
+ }
81
+
72
82
  return node
73
- }
83
+ }
@@ -1,6 +1,6 @@
1
1
  import { allNodes, createNode, MiniDom } from '.'
2
2
  import { setupAutoRaycaster } from './interaction/setupAutoRaycaster'
3
- import { ref } from 'vue'
3
+ import { computed, reactive, ref, WritableComputedRef } from 'vue'
4
4
  import { Lunch } from '..'
5
5
 
6
6
  // ENSURE ROOT
@@ -14,151 +14,187 @@ export function ensureRootNode(options: Partial<Lunch.RootMeta> = {}) {
14
14
  return lunchboxRootNode
15
15
  }
16
16
 
17
- // ENSURE CAMERA
18
- // ====================
19
- export const fallbackCameraUuid = 'FALLBACK_CAMERA'
20
- export const createdCamera = ref<Lunch.Node<THREE.Camera> | null>(null)
21
- export const ensureCamera = () => {
22
- // look for cameras
23
- // TODO: does this need to be more robust?
24
- const foundCamera = allNodes.find((node) =>
25
- (node as MiniDom.RendererBaseNode).type
26
- ?.toLowerCase()
27
- .includes('camera')
28
- )
29
-
30
- // if we have one, return
31
- if (foundCamera) {
32
- const cameraAsStandardNode =
33
- foundCamera as MiniDom.RendererStandardNode<THREE.Camera>
34
- createdCamera.value = cameraAsStandardNode
35
- return cameraAsStandardNode
17
+ // This is used in `buildEnsured` below and `LunchboxWrapper`
18
+ /** Search the overrides record and the node tree for a node in the given types */
19
+ export function tryGetNodeWithInstanceType<T extends THREE.Object3D>(
20
+ pascalCaseTypes: string | string[]
21
+ ) {
22
+ if (!Array.isArray(pascalCaseTypes)) {
23
+ pascalCaseTypes = [pascalCaseTypes]
36
24
  }
37
25
 
38
- // otherwise, create a new camera
39
- const root = ensureRootNode()
40
- const cameraNode = createNode<THREE.Camera>({
41
- type: 'PerspectiveCamera',
42
- uuid: fallbackCameraUuid,
43
- props: {
44
- args: [45, 0.5625, 1, 1000],
45
- },
46
- })
47
- root.addChild(cameraNode)
48
- createdCamera.value = cameraNode
26
+ // default to override if we have one
27
+ for (let singleType of pascalCaseTypes) {
28
+ if (overrides[singleType]) return overrides[singleType] as Lunch.Node<T>
29
+ }
30
+
31
+ // look for auto-created node
32
+ for (let singleType of pascalCaseTypes) {
33
+ const found =
34
+ autoCreated[singleType] ||
35
+ allNodes.find(
36
+ (node) =>
37
+ (node as MiniDom.RendererBaseNode).type?.toLowerCase() ===
38
+ singleType.toLowerCase()
39
+ )
40
+
41
+ // if we have one, save and return
42
+ if (found) {
43
+ const createdAsNode = found as MiniDom.RendererStandardNode<T>
44
+ autoCreated[singleType] = createdAsNode
45
+ return createdAsNode
46
+ }
47
+ }
49
48
 
50
- // add camera to scene
51
- ensureScene().instance?.add(cameraNode.instance!)
52
- return cameraNode
49
+ return null
53
50
  }
54
51
 
55
- // ENSURE RENDERER
52
+ // GENERIC ENSURE FUNCTION
56
53
  // ====================
57
- export const fallbackRendererUuid = 'FALLBACK_RENDERER'
58
- export const createdRenderer = ref<Lunch.Node<THREE.Renderer> | null>(null)
59
- export const ensureRenderer = (
60
- fallbackArgs: Array<THREE.WebGLRendererParameters> = [],
61
- sugar: {
62
- shadow?: Lunch.ShadowSugar
63
- } = {}
64
- ) => {
65
- // look for renderers
66
- // TODO: does this need to be more robust?
67
- const foundRenderer = allNodes.find((node) =>
68
- (node as MiniDom.RendererBaseNode).type
69
- ?.toLowerCase()
70
- .includes('renderer')
71
- )
72
-
73
- // if we have one, return
74
- if (foundRenderer) {
75
- const rendererAsStandardNode =
76
- foundRenderer as MiniDom.RendererStandardNode<THREE.WebGLRenderer>
77
- createdRenderer.value = rendererAsStandardNode
78
- return rendererAsStandardNode
54
+ // Problem:
55
+ // I want to make sure an object of type Xyz exists in my Lunchbox app.
56
+ // If it doesn't exist, I want to create it and add it to the root node.
57
+ //
58
+ // Solution:
59
+ // export const ensuredXyz = buildEnsured<Xyz>('Xyz', 'FALLBACK_XYZ')
60
+ //
61
+ // Now in other components, you can do both:
62
+ // import { ensuredXyz }
63
+ // ensuredXyz.value (...)
64
+ // and:
65
+ // ensuredXyz.value = ...
66
+ export const autoCreated: Record<string, Lunch.Node | null> = reactive({})
67
+ export const overrides: Record<string, Lunch.Node | null> = reactive({})
68
+
69
+ /**
70
+ * Build a computed ensured value with a getter and setter.
71
+ * @param pascalCaseTypes List of types this can be. Will autocreate first type if array provided.
72
+ * @param fallbackUuid Fallback UUID to use.
73
+ * @param props Props to pass to autocreated element
74
+ * @returns Computed getter/setter for ensured object.
75
+ */
76
+ function buildEnsured<T extends THREE.Object3D>(
77
+ pascalCaseTypes: string | string[],
78
+ fallbackUuid: string,
79
+ props: Record<string, any> = {},
80
+ callback: ((node: MiniDom.RendererStandardNode<T>) => void) | null = null
81
+ ) {
82
+ // make sure we've got an array
83
+ if (!Array.isArray(pascalCaseTypes)) {
84
+ pascalCaseTypes = [pascalCaseTypes]
79
85
  }
80
86
 
81
- // otherwise, create a new renderer
82
- const root = ensureRootNode()
83
- const rendererNode = createNode<THREE.WebGLRenderer>(
84
- {
85
- type: 'WebGLRenderer',
86
- uuid: fallbackRendererUuid,
87
- },
88
- { args: fallbackArgs }
89
- )
90
-
91
- // shadow sugar
92
- if (sugar?.shadow) {
93
- rendererNode.instance!.shadowMap.enabled = true
94
- if (typeof sugar.shadow === 'object') {
95
- rendererNode.instance!.shadowMap.type = sugar.shadow.type
87
+ // add type for autoCreated and overrides
88
+ for (let singleType of pascalCaseTypes) {
89
+ if (!autoCreated[singleType]) {
90
+ autoCreated[singleType] = null
91
+ }
92
+ if (!overrides[singleType]) {
93
+ overrides[singleType] = null
96
94
  }
97
95
  }
98
96
 
99
- root.addChild(rendererNode)
100
- createdRenderer.value = rendererNode
101
-
102
- // return created node
103
- return rendererNode
97
+ return computed({
98
+ get(): MiniDom.RendererStandardNode<T> {
99
+ // try to get existing type
100
+ const existing = tryGetNodeWithInstanceType<T>(
101
+ pascalCaseTypes as string[]
102
+ )
103
+ if (existing) return existing
104
+
105
+ // otherwise, create a new node
106
+ const root = ensureRootNode()
107
+ const node = createNode<T>({
108
+ type: pascalCaseTypes[0],
109
+ uuid: fallbackUuid,
110
+ props,
111
+ })
112
+ root.addChild(node)
113
+ autoCreated[pascalCaseTypes[0]] = node
114
+ if (callback) {
115
+ callback(node)
116
+ }
117
+ return node
118
+ },
119
+ set(val: MiniDom.RendererStandardNode<T>) {
120
+ const t = val.type ?? ''
121
+ const pascalType = t[0].toUpperCase() + t.slice(1)
122
+ overrides[pascalType] = val
123
+ },
124
+ })
104
125
  }
105
126
 
127
+ // ENSURE CAMERA
128
+ // ====================
129
+ export const fallbackCameraUuid = 'FALLBACK_CAMERA'
130
+ export const defaultCamera = buildEnsured(
131
+ ['PerspectiveCamera', 'OrthographicCamera'],
132
+ fallbackCameraUuid,
133
+ { args: [45, 0.5625, 1, 1000] }
134
+ ) as unknown as WritableComputedRef<Lunch.Node<THREE.Camera>>
135
+ /** Special value to be changed ONLY in `LunchboxWrapper`.
136
+ * Functions waiting for a Camera need to wait for this to be true. */
137
+ export const cameraReady = ref(false)
138
+
139
+ export const ensuredCamera = computed<Lunch.Node<THREE.Camera> | null>({
140
+ get() {
141
+ return (
142
+ cameraReady.value ? (defaultCamera.value as any) : (null as any)
143
+ ) as any
144
+ },
145
+ set(val: any) {
146
+ const t = val.type ?? ''
147
+ const pascalType = t[0].toUpperCase() + t.slice(1)
148
+ overrides[pascalType] = val as any
149
+ },
150
+ })
151
+
152
+ // export const ensuredCamera = buildEnsured<THREE.Camera>(
153
+ // ['PerspectiveCamera', 'OrthographicCamera'],
154
+ // fallbackCameraUuid,
155
+ // {
156
+ // args: [45, 0.5625, 1, 1000],
157
+ // }
158
+ // )
159
+
160
+ // ENSURE RENDERER
161
+ // ====================
162
+ export const fallbackRendererUuid = 'FALLBACK_RENDERER'
163
+ export const v = buildEnsured(
164
+ // TODO: ensure support for css/svg renderers
165
+ ['WebGLRenderer'], //, 'CSS2DRenderer', 'CSS3DRenderer', 'SVGRenderer'],
166
+ fallbackRendererUuid,
167
+ {}
168
+ ) as unknown as WritableComputedRef<Lunch.Node<THREE.WebGLRenderer>>
169
+ /** Special value to be changed ONLY in `LunchboxWrapper`.
170
+ * Functions waiting for a Renderer need to wait for this to be true. */
171
+ export const rendererReady = ref(false)
172
+
173
+ export const ensureRenderer = computed<Lunch.Node<THREE.WebGLRenderer> | null>({
174
+ get() {
175
+ return (rendererReady.value ? (v.value as any) : (null as any)) as any
176
+ },
177
+ set(val: any) {
178
+ const t = val.type ?? ''
179
+ const pascalType = t[0].toUpperCase() + t.slice(1)
180
+ overrides[pascalType] = val as any
181
+ },
182
+ })
183
+
106
184
  // ENSURE SCENE
107
185
  // ====================
108
186
  export const fallbackSceneUuid = 'FALLBACK_SCENE'
109
- export const createdScene = ref<Lunch.Node<THREE.Scene>>()
110
- export const ensureScene = () => {
111
- // look for scenes
112
- const foundScene = allNodes.find(
113
- (node) =>
114
- (node as MiniDom.RendererBaseNode).type?.toLowerCase() === 'scene'
115
- )
116
- // if we have one, return
117
- if (foundScene) {
118
- const sceneAsLunchboxNode =
119
- foundScene as MiniDom.RendererStandardNode<THREE.Scene>
120
- createdScene.value = sceneAsLunchboxNode
121
- return sceneAsLunchboxNode
122
- }
123
-
124
- // otherwise, create a new scene
125
- const root = ensureRootNode()
126
- const sceneNode = createNode<THREE.Scene>({
127
- type: 'Scene',
128
- uuid: fallbackSceneUuid,
129
- })
130
- root.addChild(sceneNode)
131
- createdScene.value = sceneNode
132
- return sceneNode
133
- }
187
+ export const ensuredScene = buildEnsured<THREE.Scene>(
188
+ 'Scene',
189
+ fallbackSceneUuid
190
+ )
134
191
 
135
192
  // ENSURE AUTO-RAYCASTER
136
193
  export const autoRaycasterUuid = 'AUTO_RAYCASTER'
137
- export const createdRaycaster = ref<Lunch.Node<THREE.Raycaster> | null>(null)
138
- export const ensureRaycaster = () => {
139
- // look for autoraycaster
140
- const found = allNodes.find(
141
- (node) => (node as Lunch.Node).uuid === autoRaycasterUuid
142
- )
143
- // if we have one, return
144
- if (found) {
145
- const foundAsNode = found as Lunch.Node<THREE.Raycaster>
146
- createdRaycaster.value = foundAsNode
147
- return foundAsNode
148
- }
149
-
150
- // otherwise, create raycaster
151
- const root = ensureRootNode()
152
- const raycasterNode = createNode<THREE.Raycaster>({
153
- type: 'Raycaster',
154
- uuid: autoRaycasterUuid,
155
- })
156
- root.addChild(raycasterNode)
157
- createdRaycaster.value = raycasterNode
158
-
159
- // finish auto-raycaster setup
160
- setupAutoRaycaster(raycasterNode)
161
-
162
- // done with raycaster
163
- return raycasterNode
164
- }
194
+ // `unknown` is intentional here - we need to typecast the node since Raycaster isn't an Object3D
195
+ export const ensuredRaycaster = buildEnsured(
196
+ 'Raycaster',
197
+ autoRaycasterUuid,
198
+ {},
199
+ (node) => setupAutoRaycaster(node as unknown as Lunch.Node<THREE.Raycaster>)
200
+ ) as unknown as WritableComputedRef<Lunch.Node<THREE.Raycaster>>
@@ -9,7 +9,8 @@ export function instantiateThreeObject<T>(node: Lunch.StandardMeta<T>) {
9
9
  // what class will we be instantiating?
10
10
  const uppercaseType = node.type[0].toUpperCase() + node.type.slice(1)
11
11
  const targetClass = catalogue[node.type] || (THREE as any)[uppercaseType]
12
- if (!targetClass) throw `${uppercaseType} is not part of the THREE namespace! Did you forget to extend? import {extend} from 'lunchbox'; extend({app, YourComponent, ...})`
12
+ if (!targetClass)
13
+ throw `${uppercaseType} is not part of the THREE namespace! Did you forget to extend? import {extend} from 'lunchbox'; extend({app, YourComponent, ...})`
13
14
 
14
15
  // what args have we been provided?
15
16
  const args: Array<any> = node.props.args ?? []
@@ -17,9 +18,11 @@ export function instantiateThreeObject<T>(node: Lunch.StandardMeta<T>) {
17
18
  // replace $attached values with their instances
18
19
  // we need to guarantee everything comes back as an array so we can spread $attachedArrays,
19
20
  // so we'll use processPropAsArray
20
- const argsWrappedInArrays = args.map((arg: any) => { return processPropAsArray({ node, prop: arg }) })
21
+ const argsWrappedInArrays = args.map((arg: any) => {
22
+ return processPropAsArray({ node, prop: arg })
23
+ })
21
24
  let processedArgs = [] as Array<any>
22
- argsWrappedInArrays.forEach(arr => {
25
+ argsWrappedInArrays.forEach((arr) => {
23
26
  processedArgs = processedArgs.concat(arr)
24
27
  })
25
28
 
@@ -27,4 +30,3 @@ export function instantiateThreeObject<T>(node: Lunch.StandardMeta<T>) {
27
30
 
28
31
  return instance as T
29
32
  }
30
-
@@ -4,7 +4,7 @@ import {
4
4
  interactables,
5
5
  removeInteractable,
6
6
  } from './interactables'
7
- import { ensureRaycaster } from '..'
7
+ import { ensuredRaycaster } from '..'
8
8
  import { inputActive } from './input'
9
9
  import { currentIntersections } from '.'
10
10
  import { Lunch } from '../..'
@@ -36,7 +36,9 @@ export function addEventListener({
36
36
 
37
37
  // if we need it, let's get/create the main raycaster
38
38
  if (interactionsRequiringRaycaster.includes(key)) {
39
- ensureRaycaster()
39
+ // we're not using `v` here, we're just making sure the raycaster has been created
40
+ // TODO: is this necessary?
41
+ const v = ensuredRaycaster.value
40
42
 
41
43
  if (node.instance && !interactables.includes(node)) {
42
44
  addInteractable(node)