lunchboxjs 0.1.4017 → 0.2.1001-beta.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.
Files changed (41) hide show
  1. package/dist/lunchboxjs.js +1666 -1659
  2. package/dist/lunchboxjs.min.js +1 -1
  3. package/dist/lunchboxjs.module.js +1620 -1659
  4. package/extras/OrbitControlsWrapper.vue +12 -4
  5. package/package.json +12 -4
  6. package/src/components/LunchboxEventHandlers.tsx +239 -0
  7. package/src/components/LunchboxWrapper/LunchboxScene.tsx +8 -0
  8. package/src/components/LunchboxWrapper/LunchboxWrapper.tsx +300 -0
  9. package/src/components/LunchboxWrapper/prepCanvas.ts +27 -21
  10. package/src/components/LunchboxWrapper/resizeCanvas.ts +13 -12
  11. package/src/components/autoGeneratedComponents.ts +1 -1
  12. package/src/components/index.ts +2 -4
  13. package/src/core/createNode.ts +2 -18
  14. package/src/core/ensure.ts +9 -196
  15. package/src/core/extend.ts +1 -1
  16. package/src/core/index.ts +0 -2
  17. package/src/core/instantiateThreeObject/index.ts +7 -2
  18. package/src/core/instantiateThreeObject/processProps.ts +1 -1
  19. package/src/core/interaction.ts +55 -0
  20. package/src/core/minidom.ts +5 -9
  21. package/src/core/update.ts +74 -51
  22. package/src/core/updateObjectProp.ts +5 -14
  23. package/src/index.ts +248 -76
  24. package/src/keys.ts +25 -0
  25. package/src/nodeOps/createElement.ts +2 -5
  26. package/src/nodeOps/index.ts +70 -57
  27. package/src/nodeOps/insert.ts +11 -32
  28. package/src/nodeOps/remove.ts +1 -17
  29. package/src/types.ts +34 -10
  30. package/src/utils/index.ts +1 -4
  31. package/dist/.DS_Store +0 -0
  32. package/src/.DS_Store +0 -0
  33. package/src/components/LunchboxWrapper/LunchboxWrapper.ts +0 -312
  34. package/src/components/catalogue.ts +0 -3
  35. package/src/core/.DS_Store +0 -0
  36. package/src/core/allNodes.ts +0 -4
  37. package/src/core/interaction/index.ts +0 -102
  38. package/src/core/interaction/input.ts +0 -4
  39. package/src/core/interaction/interactables.ts +0 -14
  40. package/src/core/interaction/setupAutoRaycaster.ts +0 -224
  41. package/src/core/start.ts +0 -11
@@ -1,31 +1,28 @@
1
- import { ensureRenderer, ensuredScene, ensuredCamera } from '.'
2
- import { Lunch } from '..'
3
- import { toRaw, watch, WatchStopHandle } from 'vue'
4
-
5
- let frameID: number
6
- let watchStopHandle: WatchStopHandle
7
-
8
- export const beforeRender = [] as Lunch.UpdateCallback[]
9
- export const afterRender = [] as Lunch.UpdateCallback[]
1
+ import type { Lunch } from '..'
2
+ import { inject, toRaw, watch } from 'vue'
3
+ import * as Keys from '../keys'
10
4
 
11
5
  const requestUpdate = (opts: Lunch.UpdateCallbackProperties) => {
12
- cancelUpdate()
13
- frameID = requestAnimationFrame(() =>
14
- update({
15
- app: opts.app,
16
- renderer: ensureRenderer.value?.instance,
17
- scene: ensuredScene.value.instance,
18
- camera: ensuredCamera.value?.instance,
19
- updateSource: opts.updateSource,
20
- })
6
+ if (typeof opts.app.config.globalProperties.lunchbox.frameId === 'number') {
7
+ cancelAnimationFrame(opts.app.config.globalProperties.lunchbox.frameId)
8
+ }
9
+ opts.app.config.globalProperties.lunchbox.frameId = requestAnimationFrame(
10
+ () =>
11
+ update({
12
+ app: opts.app,
13
+ renderer: opts.renderer,
14
+ scene: opts.scene,
15
+ camera: opts.camera,
16
+ updateSource: opts.updateSource,
17
+ })
21
18
  )
22
19
  }
23
20
 
24
21
  export const update: Lunch.UpdateCallback = (opts) => {
25
22
  if (opts.updateSource) {
26
- if (!watchStopHandle) {
23
+ if (!opts.app.config.globalProperties.lunchbox.watchStopHandle) {
27
24
  // request next frame only when state changes
28
- watchStopHandle = watch(
25
+ opts.app.config.globalProperties.lunchbox.watchStopHandle = watch(
29
26
  opts.updateSource,
30
27
  () => {
31
28
  requestUpdate(opts)
@@ -44,10 +41,8 @@ export const update: Lunch.UpdateCallback = (opts) => {
44
41
  const { app, renderer, scene, camera } = opts
45
42
 
46
43
  // BEFORE RENDER
47
- beforeRender.forEach((cb: Lunch.UpdateCallback | undefined) => {
48
- if (cb) {
49
- cb(opts)
50
- }
44
+ app.config.globalProperties.lunchbox.beforeRender.forEach((cb) => {
45
+ cb?.(opts)
51
46
  })
52
47
 
53
48
  // RENDER
@@ -55,56 +50,84 @@ export const update: Lunch.UpdateCallback = (opts) => {
55
50
  if (app.customRender) {
56
51
  app.customRender(opts)
57
52
  } else {
58
- renderer.render(toRaw(scene), toRaw(camera))
53
+ renderer.render(
54
+ toRaw(scene),
55
+ // opts.app.config.globalProperties.lunchbox.camera!
56
+ toRaw(camera)
57
+ )
59
58
  }
60
59
  }
61
60
 
62
61
  // AFTER RENDER
63
- afterRender.forEach((cb: Lunch.UpdateCallback | undefined) => {
64
- if (cb) {
65
- cb(opts)
66
- }
62
+ app.config.globalProperties.lunchbox.afterRender.forEach((cb) => {
63
+ cb?.(opts)
67
64
  })
68
65
  }
69
66
 
70
- export const onBeforeRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
71
- if (index === Infinity) {
72
- beforeRender.push(cb)
73
- } else {
74
- beforeRender.splice(index, 0, cb)
67
+ // before render
68
+ // ====================
69
+ // TODO: document
70
+ export const useBeforeRender = () => {
71
+ return {
72
+ onBeforeRender: inject<typeof onBeforeRender>(Keys.onBeforeRenderKey),
73
+ offBeforeRender: inject<typeof offBeforeRender>(
74
+ Keys.offBeforeRenderKey
75
+ ),
75
76
  }
76
77
  }
77
78
 
79
+ // TODO: document
80
+ export const onBeforeRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
81
+ useBeforeRender().onBeforeRender?.(cb, index)
82
+ }
83
+
84
+ // TODO: document
78
85
  export const offBeforeRender = (cb: Lunch.UpdateCallback | number) => {
79
- if (isFinite(cb as number)) {
80
- beforeRender.splice(cb as number, 1)
81
- } else {
82
- const idx = beforeRender.findIndex((v) => v == cb)
83
- beforeRender.splice(idx, 1)
86
+ useBeforeRender().offBeforeRender?.(cb)
87
+ }
88
+
89
+ // after render
90
+ // ====================
91
+ // TODO: document
92
+ export const useAfterRender = () => {
93
+ return {
94
+ onAfterRender: inject<typeof onAfterRender>(Keys.onBeforeRenderKey),
95
+ offAfterRender: inject<typeof offAfterRender>(Keys.offBeforeRenderKey),
84
96
  }
85
97
  }
86
98
 
99
+ // TODO: document
87
100
  export const onAfterRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
88
- if (index === Infinity) {
89
- afterRender.push(cb)
90
- } else {
91
- afterRender.splice(index, 0, cb)
92
- }
101
+ useBeforeRender().onBeforeRender?.(cb, index)
93
102
  }
94
103
 
104
+ // TODO: document
95
105
  export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
96
- if (isFinite(cb as number)) {
97
- afterRender.splice(cb as number, 1)
98
- } else {
99
- const idx = afterRender.findIndex((v) => v == cb)
100
- afterRender.splice(idx, 1)
106
+ useBeforeRender().offBeforeRender?.(cb)
107
+ }
108
+
109
+ // TODO: document
110
+ export const useCancelUpdate = () => {
111
+ const frameId = inject<number>(Keys.frameIdKey)
112
+ return () => {
113
+ if (frameId !== undefined) cancelAnimationFrame(frameId)
101
114
  }
102
115
  }
103
116
 
117
+ // TODO: document
104
118
  export const cancelUpdate = () => {
105
- if (frameID) cancelAnimationFrame(frameID)
119
+ useCancelUpdate()?.()
120
+ }
121
+
122
+ // TODO: document
123
+ export const useCancelUpdateSource = () => {
124
+ const cancel = inject<
125
+ Lunch.App['config']['globalProperties']['watchStopHandle']
126
+ >(Keys.watchStopHandleKey)
127
+ return () => cancel?.()
106
128
  }
107
129
 
130
+ // TODO: document
108
131
  export const cancelUpdateSource = () => {
109
- if (watchStopHandle) watchStopHandle()
132
+ useCancelUpdateSource()?.()
110
133
  }
@@ -1,34 +1,25 @@
1
1
  import { isEventKey, isLunchboxStandardNode } from '../utils'
2
2
  import { addEventListener } from './interaction'
3
3
  import { get, isNumber, set } from 'lodash'
4
- import { Lunch } from '..'
5
-
6
- /** Update the given node so all of its props are current. */
7
- export function updateAllObjectProps({ node }: { node: Lunch.Node }) {
8
- // set props
9
- const props = node.props || {}
10
- let output = node
11
- Object.keys(props).forEach((key) => {
12
- output = updateObjectProp({ node, key, value: props[key] })
13
- })
14
-
15
- return output
16
- }
4
+ import type { Lunch } from '..'
5
+ import type { Ref } from 'vue'
17
6
 
18
7
  /** Update a single prop on a given node. */
19
8
  export function updateObjectProp({
20
9
  node,
21
10
  key,
11
+ interactables,
22
12
  value,
23
13
  }: {
24
14
  node: Lunch.Node
25
15
  key: string
16
+ interactables: Ref<Lunch.Node[]>
26
17
  value: any
27
18
  }) {
28
19
  // handle and return early if prop is an event
29
20
  // (event list from react-three-fiber)
30
21
  if (isEventKey(key)) {
31
- return addEventListener({ node, key, value })
22
+ return addEventListener({ node, key, interactables, value })
32
23
  }
33
24
 
34
25
  // update THREE property
package/src/index.ts CHANGED
@@ -1,82 +1,54 @@
1
- import { computed, createRenderer, Component, ref, watch } from 'vue'
2
- import { nodeOps } from './nodeOps'
3
1
  import {
4
- // createdCamera,
5
- // createdRenderer,
6
- // autoScene,
2
+ computed,
3
+ createRenderer,
4
+ Component,
5
+ inject,
6
+ watch,
7
+ reactive,
8
+ Ref,
9
+ } from 'vue'
10
+ import { createNodeOps } from './nodeOps'
11
+ import {
7
12
  ensuredCamera,
8
13
  ensureRenderer,
9
14
  ensuredScene,
10
- ensureRootNode,
11
15
  extend,
12
- inputActive,
13
- mousePos,
14
- rootUuid,
16
+ MiniDom,
15
17
  } from './core'
16
18
  import { components } from './components'
17
19
  import { Lunch } from './types'
18
20
 
19
- export { lunchboxRootNode as lunchboxTree } from './core'
20
- export {
21
- offAfterRender,
22
- offBeforeRender,
23
- onAfterRender,
24
- onBeforeRender,
25
- onStart,
26
- } from './core'
21
+ export * from './core'
27
22
  export * from './types'
28
23
 
24
+ import * as Keys from './keys'
25
+ export * from './keys'
26
+
29
27
  // Utilities
30
28
  export * from './utils/find'
31
29
 
32
- /** Useful globals. */
33
- export const globals = {
34
- dpr: ref(1),
35
- inputActive,
36
- mousePos,
37
- }
38
-
39
30
  /** The current camera. Often easier to use `useCamera` instead of this. */
40
- export const camera = computed(() => ensuredCamera.value?.instance ?? null)
41
- /** Run a function using the current camera when it's present. */
42
- export function useCamera<T extends THREE.Camera = THREE.PerspectiveCamera>(
43
- callback: (cam: T) => void
44
- ) {
45
- return watch(
46
- camera,
47
- (newVal) => {
48
- if (!newVal) return
49
- callback(newVal as unknown as T)
50
- },
51
- { immediate: true }
52
- )
53
- }
31
+ // TODO: update docs
32
+ export const camera = ensuredCamera
33
+ // TODO: update docs
34
+ export const useCamera = () => ensuredCamera()
54
35
 
55
- /** The current renderer. Often easier to use `useRenderer` instead of this. */
56
- export const renderer = computed(() => ensureRenderer.value?.instance ?? null)
36
+ /** The current renderer as a computed value. Often easier to use `useRenderer` instead of this. */
37
+ export const renderer = ensureRenderer
57
38
  /** Run a function using the current renderer when it's present. */
58
- export function useRenderer<T extends THREE.Renderer = THREE.WebGLRenderer>(
59
- callback: (rend: T) => void
60
- ) {
61
- return watch(
62
- renderer,
63
- (newVal) => {
64
- if (!newVal) return
65
- callback(newVal as unknown as T)
66
- },
67
- { immediate: true }
68
- )
69
- }
39
+ export const useRenderer = () => ensureRenderer()!
70
40
 
71
41
  /** The current scene. Often easier to use `useScene` instead of this. */
72
- export const scene = computed(() => ensuredScene.value.instance)
42
+ // TODO: update docs
43
+ export const scene = ensuredScene
73
44
  /** Run a function using the current scene when it's present. */
45
+ // TODO: update docs
74
46
  export function useScene(callback: (newScene: THREE.Scene) => void) {
75
47
  return watch(
76
48
  scene,
77
49
  (newVal) => {
78
50
  if (!newVal) return
79
- callback(newVal as any)
51
+ callback(newVal.value as THREE.Scene)
80
52
  },
81
53
  { immediate: true }
82
54
  )
@@ -84,38 +56,216 @@ export function useScene(callback: (newScene: THREE.Scene) => void) {
84
56
 
85
57
  // CUSTOM RENDER SUPPORT
86
58
  // ====================
87
- let app: Lunch.App | null = null
88
- let queuedCustomRenderFunction:
89
- | ((opts: Lunch.UpdateCallbackProperties) => void)
90
- | null = null
91
-
92
59
  /** Set a custom render function, overriding the Lunchbox app's default render function.
93
60
  * Changing this requires the user to manually render their scene.
61
+ *
62
+ * Invokes immediately - use `useCustomRender().setCustomRender`
63
+ * if you need to call somewhere outside of `setup`.
94
64
  */
95
65
  export const setCustomRender = (
96
66
  render: (opts: Lunch.UpdateCallbackProperties) => void
97
67
  ) => {
98
- if (app) app.setCustomRender(render)
99
- else queuedCustomRenderFunction = render
68
+ useCustomRender()?.setCustomRender?.(render)
100
69
  }
101
70
 
102
- /** Clear the active app's custom render function. */
71
+ /** Clear the active app's custom render function.
72
+ *
73
+ * Invokes immediately - use `useCustomRender().clearCustomRender`
74
+ * if you need to call somewhere outside of `setup`.
75
+ */
103
76
  export const clearCustomRender = () => {
104
- if (app) app.clearCustomRender()
105
- else queuedCustomRenderFunction = null
77
+ useCustomRender()?.clearCustomRender?.()
78
+ }
79
+
80
+ /** Provides `setCustomRender` and `clearCustomRender` functions to be called in a non-`setup` context. */
81
+ export const useCustomRender = () => {
82
+ return {
83
+ /** Set a custom render function, overriding the Lunchbox app's default render function.
84
+ * Changing this requires the user to manually render their scene. */
85
+ setCustomRender: inject<Lunch.CustomRenderFunctionSetter>(
86
+ Keys.setCustomRenderKey
87
+ ),
88
+ /** Clear the active app's custom render function. */
89
+ clearCustomRender: inject<() => void>(Keys.clearCustomRenderKey),
90
+ }
91
+ }
92
+
93
+ /** Use app-level globals. */
94
+ export const useGlobals = () =>
95
+ inject<Lunch.AppGlobals>(Keys.globalsInjectionKey)!
96
+
97
+ /** Construct a function to update your app-level globals.
98
+ *
99
+ * ```js
100
+ * // in setup():
101
+ * const updateGlobals = useUpdateGlobals()
102
+ *
103
+ * // ...later, to update the device pixel resolution...
104
+ * updateGlobals({ dpr: 2 })
105
+ * ```
106
+ */
107
+ export const useUpdateGlobals = () =>
108
+ inject<Lunch.AppGlobalsUpdate>(Keys.updateGlobalsInjectionKey)
109
+
110
+ /** Update app-level globals.
111
+ *
112
+ * Invokes immediately - use `useUpdateGlobals`
113
+ * if you need to call somewhere outside of `setup`.
114
+ */
115
+ export const updateGlobals = (newValue: Partial<Lunch.AppGlobals>) => {
116
+ useUpdateGlobals()?.(newValue)
117
+ }
118
+
119
+ // TODO: document
120
+ export const useRootNode = () =>
121
+ inject<MiniDom.RendererRootNode>(Keys.appRootNodeKey)
122
+
123
+ // TODO: document
124
+ export const useApp = () => inject<Lunch.App>(Keys.appKey)
125
+
126
+ // TODO: document
127
+ export const useStartCallbacks = () =>
128
+ inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey) //[] as Lunch.UpdateCallback[]
129
+
130
+ // TODO: document
131
+ export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
132
+ const callbacks = useStartCallbacks()
133
+ if (index === Infinity) {
134
+ callbacks?.push(cb)
135
+ } else {
136
+ callbacks?.splice(index, 0, cb)
137
+ }
106
138
  }
107
139
 
140
+ // TODO: document
141
+ export const useLunchboxInteractables = () =>
142
+ inject<Ref<Lunch.Node[]>>(Keys.lunchboxInteractables)
143
+
108
144
  // CREATE APP
109
145
  // ====================
110
146
  export const createApp = (root: Component) => {
111
- app = createRenderer(nodeOps).createApp(root) as Lunch.App
147
+ const { nodeOps, interactables } = createNodeOps()
148
+ const app = createRenderer(nodeOps).createApp(root) as Lunch.App
149
+
150
+ // provide Lunchbox interaction handlers flag (modified when user references events via
151
+ // @click, etc)
152
+ app.provide(Keys.lunchboxInteractables, interactables)
112
153
 
113
154
  // register all components
155
+ // ====================
114
156
  Object.keys(components).forEach((key) => {
115
157
  app?.component(key, (components as any)[key])
116
158
  })
117
159
 
160
+ // provide custom renderer functions
161
+ // ====================
162
+ app.provide(
163
+ Keys.setCustomRenderKey,
164
+ (render: (opts: Lunch.UpdateCallbackProperties) => void) => {
165
+ app.setCustomRender(render)
166
+ }
167
+ )
168
+ app.provide(Keys.clearCustomRenderKey, () => {
169
+ app.clearCustomRender()
170
+ })
171
+
172
+ // before render
173
+ // ====================
174
+ const beforeRender = [] as Lunch.UpdateCallback[]
175
+ app.provide(Keys.beforeRenderKey, beforeRender)
176
+ app.provide(
177
+ Keys.onBeforeRenderKey,
178
+ (cb: Lunch.UpdateCallback, index = Infinity) => {
179
+ if (index === Infinity) {
180
+ beforeRender.push(cb)
181
+ } else {
182
+ beforeRender.splice(index, 0, cb)
183
+ }
184
+ }
185
+ )
186
+ app.provide(
187
+ Keys.offBeforeRenderKey,
188
+ (cb: Lunch.UpdateCallback | number) => {
189
+ if (isFinite(cb as number)) {
190
+ beforeRender.splice(cb as number, 1)
191
+ } else {
192
+ const idx = beforeRender.findIndex((v) => v == cb)
193
+ if (idx !== -1) {
194
+ beforeRender.splice(idx, 1)
195
+ }
196
+ }
197
+ }
198
+ )
199
+
200
+ // after render
201
+ // ====================
202
+ const afterRender = [] as Lunch.UpdateCallback[]
203
+ app.provide(Keys.afterRenderKey, afterRender)
204
+ app.provide(
205
+ Keys.onAfterRenderKey,
206
+ (cb: Lunch.UpdateCallback, index = Infinity) => {
207
+ if (index === Infinity) {
208
+ afterRender.push(cb)
209
+ } else {
210
+ afterRender.splice(index, 0, cb)
211
+ }
212
+ }
213
+ )
214
+ app.provide(Keys.offAfterRenderKey, (cb: Lunch.UpdateCallback | number) => {
215
+ if (isFinite(cb as number)) {
216
+ afterRender.splice(cb as number, 1)
217
+ } else {
218
+ const idx = afterRender.findIndex((v) => v == cb)
219
+ if (idx !== -1) {
220
+ afterRender.splice(idx, 1)
221
+ }
222
+ }
223
+ })
224
+
225
+ // save app-level components
226
+ // ====================
227
+ app.config.globalProperties.lunchbox = reactive({
228
+ afterRender,
229
+ beforeRender,
230
+ camera: null,
231
+ dpr: 1,
232
+ frameId: -1,
233
+ renderer: null,
234
+ scene: null,
235
+ watchStopHandle: null,
236
+
237
+ // TODO: inputActive, mousePos
238
+ })
239
+
240
+ // provide app-level globals & globals update method
241
+ // ====================
242
+ app.provide(Keys.globalsInjectionKey, app.config.globalProperties.lunchbox)
243
+ app.provide<Lunch.AppGlobalsUpdate>(
244
+ Keys.updateGlobalsInjectionKey,
245
+ (newGlobals: Partial<Lunch.AppGlobals>) => {
246
+ Object.keys(newGlobals).forEach((key) => {
247
+ const typedKey = key as keyof Lunch.AppGlobals
248
+ // TODO: fix
249
+ app.config.globalProperties.lunchbox[typedKey] = newGlobals[
250
+ typedKey
251
+ ] as any
252
+ })
253
+ }
254
+ )
255
+
256
+ // frame ID (used for update functions)
257
+ // ====================
258
+ app.provide(Keys.frameIdKey, app.config.globalProperties.lunchbox.frameId)
259
+
260
+ // watch stop handler (used for conditional update loop)
261
+ // ====================
262
+ app.provide(
263
+ Keys.watchStopHandleKey,
264
+ app.config.globalProperties.lunchbox.watchStopHandle
265
+ )
266
+
118
267
  // update mount function to match Lunchbox.Node
268
+ // ====================
119
269
  const { mount } = app
120
270
  app.mount = (root, ...args) => {
121
271
  // find DOM element to use as app root
@@ -123,43 +273,65 @@ export const createApp = (root: Component) => {
123
273
  typeof root === 'string' ? document.querySelector(root) : root
124
274
  ) as HTMLElement
125
275
  // create or find root node
126
- const rootNode = ensureRootNode({
276
+ const rootNode = new MiniDom.RendererRootNode({
127
277
  domElement,
128
278
  isLunchboxRootNode: true,
129
279
  name: 'root',
130
280
  metaType: 'rootMeta',
131
281
  type: 'root',
132
- uuid: rootUuid,
282
+ uuid: 'LUNCHBOX_ROOT',
133
283
  })
134
- app!.rootNode = rootNode
284
+ app.rootNode = rootNode
285
+ app.provide(Keys.appRootNodeKey, rootNode)
135
286
  const mounted = mount(rootNode, ...args)
136
287
  return mounted
137
288
  }
138
289
 
139
290
  // embed .extend function
291
+ // ====================
140
292
  app.extend = (targets: Record<string, any>) => {
141
293
  extend({ app: app!, ...targets })
142
294
  return app!
143
295
  }
144
296
 
297
+ // start callback functions
298
+ // ====================
299
+ const startCallbacks: Lunch.UpdateCallback[] = []
300
+ app.provide(Keys.startCallbackKey, startCallbacks)
301
+
145
302
  // prep for custom render support
303
+ // ====================
146
304
  app.setCustomRender = (
147
305
  newRender: (opts: Lunch.UpdateCallbackProperties) => void
148
306
  ) => {
149
- app!.customRender = newRender
150
- }
151
-
152
- // add queued custom render if we have one
153
- if (queuedCustomRenderFunction) {
154
- app.setCustomRender(queuedCustomRenderFunction)
155
- queuedCustomRenderFunction = null
307
+ if (app) {
308
+ app.customRender = newRender
309
+ }
156
310
  }
157
311
 
158
312
  // add custom render removal
159
313
  app.clearCustomRender = () => {
160
- app!.customRender = null
314
+ if (app) {
315
+ app.customRender = null
316
+ }
161
317
  }
162
318
 
319
+ // provide app
320
+ // ====================
321
+ app.provide(Keys.appKey, app)
322
+ app.provide(
323
+ Keys.appRenderersKey,
324
+ computed(() => app.config.globalProperties.lunchbox.renderer)
325
+ )
326
+ app.provide(
327
+ Keys.appSceneKey,
328
+ computed(() => app.config.globalProperties.lunchbox.scene)
329
+ )
330
+ app.provide(
331
+ Keys.appCameraKey,
332
+ computed(() => app.config.globalProperties.lunchbox.camera)
333
+ )
334
+
163
335
  // done
164
336
  return app
165
337
  }
package/src/keys.ts ADDED
@@ -0,0 +1,25 @@
1
+ export const globalsInjectionKey = Symbol()
2
+ export const updateGlobalsInjectionKey = Symbol()
3
+
4
+ export const setCustomRenderKey = Symbol()
5
+ export const clearCustomRenderKey = Symbol()
6
+
7
+ export const beforeRenderKey = Symbol()
8
+ export const onBeforeRenderKey = Symbol()
9
+ export const offBeforeRenderKey = Symbol()
10
+
11
+ export const afterRenderKey = Symbol()
12
+ export const onAfterRenderKey = Symbol()
13
+ export const offAfterRenderKey = Symbol()
14
+
15
+ export const frameIdKey = Symbol()
16
+ export const watchStopHandleKey = Symbol()
17
+
18
+ export const appRootNodeKey = Symbol()
19
+ export const appKey = Symbol()
20
+ export const appRenderersKey = Symbol()
21
+ export const appSceneKey = Symbol()
22
+ export const appCameraKey = Symbol()
23
+ export const lunchboxInteractables = Symbol()
24
+
25
+ export const startCallbackKey = Symbol()
@@ -10,13 +10,10 @@ export const createElement = (
10
10
  isCustomizedBuiltin?: string,
11
11
  vnodeProps?: Lunch.LunchboxMetaProps
12
12
  ) => {
13
- const options = { type } as Partial<Lunch.MetaBase>
14
- if (vnodeProps) {
15
- options.props = vnodeProps
16
- }
13
+ const options: Partial<Lunch.MetaBase> = { type, props: vnodeProps }
17
14
 
18
15
  // handle dom node
19
- const isDomNode = isLunchboxDomComponent(type)
16
+ const isDomNode = isLunchboxDomComponent(options)
20
17
  if (isDomNode) {
21
18
  const node = createDomNode(options)
22
19
  return node