lunchboxjs 0.2.1020 → 2.0.0-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.cjs +46 -0
  2. package/dist/lunchboxjs.d.ts +1 -0
  3. package/dist/lunchboxjs.js +1632 -1962
  4. package/dist/lunchboxjs.umd.cjs +46 -0
  5. package/package.json +36 -81
  6. package/LICENSE.md +0 -7
  7. package/README.md +0 -17
  8. package/dist/lunchboxjs.es.d.ts +0 -1
  9. package/dist/lunchboxjs.min.js +0 -1
  10. package/dist/lunchboxjs.module.js +0 -1924
  11. package/dist/lunchboxjs.umd.d.ts +0 -1
  12. package/src/components/LunchboxEventHandlers.tsx +0 -237
  13. package/src/components/LunchboxWrapper/LunchboxScene.tsx +0 -8
  14. package/src/components/LunchboxWrapper/LunchboxWrapper.tsx +0 -341
  15. package/src/components/LunchboxWrapper/prepCanvas.ts +0 -55
  16. package/src/components/LunchboxWrapper/resizeCanvas.ts +0 -41
  17. package/src/components/autoGeneratedComponents.ts +0 -175
  18. package/src/components/index.ts +0 -31
  19. package/src/core/createNode.ts +0 -71
  20. package/src/core/extend.ts +0 -25
  21. package/src/core/index.ts +0 -7
  22. package/src/core/instantiateThreeObject/index.ts +0 -37
  23. package/src/core/instantiateThreeObject/processProps.ts +0 -40
  24. package/src/core/interaction.ts +0 -55
  25. package/src/core/minidom.ts +0 -256
  26. package/src/core/update.ts +0 -149
  27. package/src/core/updateObjectProp.ts +0 -153
  28. package/src/index.ts +0 -400
  29. package/src/keys.ts +0 -31
  30. package/src/nodeOps/createElement.ts +0 -34
  31. package/src/nodeOps/index.ts +0 -83
  32. package/src/nodeOps/insert.ts +0 -165
  33. package/src/nodeOps/remove.ts +0 -32
  34. package/src/plugins/bridge/BridgeComponent.tsx +0 -60
  35. package/src/plugins/bridge/bridge.ts +0 -9
  36. package/src/types.ts +0 -186
  37. package/src/utils/find.ts +0 -24
  38. package/src/utils/get.ts +0 -18
  39. package/src/utils/index.ts +0 -60
  40. package/src/utils/isNumber.ts +0 -87
  41. package/src/utils/set.ts +0 -14
@@ -1,149 +0,0 @@
1
- import type { Lunch } from '..'
2
- import { inject, toRaw, watch } from 'vue'
3
- import * as Keys from '../keys'
4
-
5
- const requestUpdate = (opts: Lunch.UpdateCallbackProperties) => {
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
- })
18
- )
19
- }
20
-
21
- export const update: Lunch.UpdateCallback = (opts) => {
22
- if (opts.updateSource) {
23
- if (!opts.app.config.globalProperties.lunchbox.watchStopHandle) {
24
- // request next frame only when state changes
25
- opts.app.config.globalProperties.lunchbox.watchStopHandle = watch(
26
- opts.updateSource,
27
- () => {
28
- requestUpdate(opts)
29
- },
30
- {
31
- deep: true,
32
- }
33
- )
34
- }
35
- } else {
36
- // request next frame on a continuous loop
37
- requestUpdate(opts)
38
- }
39
-
40
- // prep options
41
- const { app, renderer, scene } = opts
42
-
43
- // BEFORE RENDER
44
- app.config.globalProperties.lunchbox.beforeRender.forEach((cb) => {
45
- cb?.(opts)
46
- })
47
-
48
- // RENDER
49
- if (renderer && scene && opts.app.config.globalProperties.lunchbox.camera) {
50
- if (app.customRender) {
51
- app.customRender(opts)
52
- } else {
53
- renderer.render(
54
- toRaw(scene),
55
- opts.app.config.globalProperties.lunchbox.camera
56
- // toRaw(camera)
57
- )
58
- }
59
- }
60
-
61
- // AFTER RENDER
62
- app.config.globalProperties.lunchbox.afterRender.forEach((cb) => {
63
- cb?.(opts)
64
- })
65
- }
66
-
67
- // before render
68
- // ====================
69
- /** Obtain callback methods for `onBeforeRender` and `offBeforeRender`. Usually used internally by Lunchbox. */
70
- export const useBeforeRender = () => {
71
- return {
72
- onBeforeRender: inject<typeof onBeforeRender>(Keys.onBeforeRenderKey),
73
- offBeforeRender: inject<typeof offBeforeRender>(
74
- Keys.offBeforeRenderKey
75
- ),
76
- }
77
- }
78
-
79
- /** Run a function before every render.
80
- *
81
- * Note that if `updateSource` is set in the Lunchbox wrapper component, this will **only** run
82
- * before a render triggered by that `updateSource`. Normally, the function should run every frame.
83
- */
84
- export const onBeforeRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
85
- useBeforeRender().onBeforeRender?.(cb, index)
86
- }
87
-
88
- /** Remove a function from the `beforeRender` callback list. Useful for tearing down functions added
89
- * by `onBeforeRender`.
90
- */
91
- export const offBeforeRender = (cb: Lunch.UpdateCallback | number) => {
92
- useBeforeRender().offBeforeRender?.(cb)
93
- }
94
-
95
- // after render
96
- // ====================
97
- /** Obtain callback methods for `onAfterRender` and `offAfterRender`. Usually used internally by Lunchbox. */
98
- export const useAfterRender = () => {
99
- return {
100
- onAfterRender: inject<typeof onAfterRender>(Keys.onBeforeRenderKey),
101
- offAfterRender: inject<typeof offAfterRender>(Keys.offBeforeRenderKey),
102
- }
103
- }
104
-
105
- /** Run a function after every render.
106
- *
107
- * Note that if `updateSource` is set in the Lunchbox wrapper component, this will **only** run
108
- * after a render triggered by that `updateSource`. Normally, the function should run every frame.
109
- */
110
- export const onAfterRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
111
- useBeforeRender().onBeforeRender?.(cb, index)
112
- }
113
-
114
- /** Remove a function from the `afterRender` callback list. Useful for tearing down functions added
115
- * by `onAfterRender`.
116
- */
117
- export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
118
- useBeforeRender().offBeforeRender?.(cb)
119
- }
120
-
121
- /** Obtain a function used to cancel the current update frame. Use `cancelUpdate` if you wish
122
- * to immediately invoke the cancellation function. Usually used internally by Lunchbox.
123
- */
124
- export const useCancelUpdate = () => {
125
- const frameId = inject<number>(Keys.frameIdKey)
126
- return () => {
127
- if (frameId !== undefined) cancelAnimationFrame(frameId)
128
- }
129
- }
130
-
131
- /** Cancel the current update frame. Usually used internally by Lunchbox. */
132
- export const cancelUpdate = () => {
133
- useCancelUpdate()?.()
134
- }
135
-
136
- /** Obtain a function used to cancel an update source. Use `cancelUpdateSource` if you wish to
137
- * immediately invoke the cancellation function. Usually used internally by Lunchbox.
138
- */
139
- export const useCancelUpdateSource = () => {
140
- const cancel = inject<
141
- Lunch.App['config']['globalProperties']['watchStopHandle']
142
- >(Keys.watchStopHandleKey)
143
- return () => cancel?.()
144
- }
145
-
146
- /** Cancel an update source. Usually used internally by Lunchbox. */
147
- export const cancelUpdateSource = () => {
148
- useCancelUpdateSource()?.()
149
- }
@@ -1,153 +0,0 @@
1
- import {
2
- get,
3
- isEventKey,
4
- isLunchboxStandardNode,
5
- isNumber,
6
- set,
7
- } from '../utils'
8
- import { addEventListener } from './interaction'
9
- import type { Lunch } from '..'
10
- import type { Ref } from 'vue'
11
-
12
- /** Update a single prop on a given node. */
13
- export function updateObjectProp({
14
- node,
15
- key,
16
- interactables,
17
- value,
18
- }: {
19
- node: Lunch.Node
20
- key: string
21
- interactables: Ref<Lunch.Node[]>
22
- value: any
23
- }) {
24
- // handle and return early if prop is an event
25
- // (event list from react-three-fiber)
26
- if (isEventKey(key)) {
27
- return addEventListener({ node, key, interactables, value })
28
- }
29
-
30
- // update THREE property
31
- // get final key
32
- const camelKey = key.replace(/-/g, '.')
33
- const finalKey = propertyShortcuts[camelKey] || camelKey
34
-
35
- // handle and return early if prop is specific to Vue/Lunchbox
36
- if (
37
- internalLunchboxVueKeys.includes(key) ||
38
- internalLunchboxVueKeys.includes(finalKey)
39
- )
40
- return node
41
-
42
- // everything else should be Three-specific, so let's cancel if this isn't a standard node
43
- if (!isLunchboxStandardNode(node)) return node
44
-
45
- // parse $attached values
46
- if (typeof value === 'string' && value.startsWith('$attached')) {
47
- const attachedName = value.replace('$attached.', '')
48
- value = get(node.attached, attachedName, null)
49
- }
50
-
51
- // save instance
52
- const target = node.instance
53
-
54
- // cancel if no target
55
- if (!target) return node
56
-
57
- // burrow down until we get property to change
58
- let liveProperty: any
59
- for (let i = 0; i < nestedPropertiesToCheck.length && !liveProperty; i++) {
60
- const nestedProperty = nestedPropertiesToCheck[i]
61
- const fullPath = [nestedProperty, finalKey].filter(Boolean).join('.')
62
- liveProperty = liveProperty = get(target, fullPath)
63
- }
64
-
65
- // change property
66
- // first, save as array in case we need to spread it
67
- if (liveProperty && isNumber(value) && liveProperty?.setScalar) {
68
- // if value is a number and the property has a `setScalar` method, use that
69
- liveProperty.setScalar(value)
70
- } else if (liveProperty && liveProperty.set) {
71
- // if property has `set` method, use that (https://github.com/pmndrs/react-three-fiber/blob/master/markdown/api.md#shortcuts)
72
- const nextValueAsArray = Array.isArray(value) ? value : [value]
73
- ;(target as any)[finalKey].set(...nextValueAsArray)
74
- } else if (typeof liveProperty === 'function') {
75
- // some function properties are set rather than called, so let's handle them
76
- if (
77
- finalKey.toLowerCase() === 'onbeforerender' ||
78
- finalKey.toLowerCase() === 'onafterrender'
79
- ) {
80
- ;(target as any)[finalKey] = value
81
- } else {
82
- if (!Array.isArray(value)) {
83
- throw new Error(
84
- 'Arguments on a declarative method must be wrapped in an array.\nWorks:\n<example :methodCall="[256]" />\nDoesn\'t work:\n<example :methodCall="256" />'
85
- )
86
- }
87
- // if property is a function, let's try calling it
88
- liveProperty.bind(node.instance)(...value)
89
- }
90
-
91
- // pass the result to the parent
92
- // const parent = node.parentNode
93
- // if (parent) {
94
- // const parentAsLunchboxNode = parent as Lunchbox.Node
95
- // parentAsLunchboxNode.attached[finalKey] = result
96
- // ; (parentAsLunchboxNode.instance as any)[finalKey] = result
97
- // }
98
- } else if (get(target, finalKey, undefined) !== undefined) {
99
- // blank strings evaluate to `true`
100
- // <mesh castShadow receiveShadow /> will work the same as
101
- // <mesh :castShadow="true" :receiveShadow="true" />
102
- set(target, finalKey, value === '' ? true : value)
103
- } else {
104
- // if you see this error in production, you might need to add `finalKey`
105
- // to `internalLunchboxVueKeys` below
106
- console.log(`No property ${finalKey} found on ${target}`)
107
- }
108
-
109
- // mark that we need to update if needed
110
- const targetTypeRaw =
111
- (target as any)?.texture?.type || (target as any)?.type
112
- if (typeof targetTypeRaw === 'string') {
113
- const targetType = targetTypeRaw.toLowerCase()
114
-
115
- switch (true) {
116
- case targetType.includes('material'):
117
- ;(target as unknown as THREE.Material).needsUpdate = true
118
- break
119
- case targetType.includes('camera') &&
120
- (target as any).updateProjectionMatrix:
121
- ;(
122
- target as unknown as
123
- | THREE.PerspectiveCamera
124
- | THREE.OrthographicCamera
125
- ).updateProjectionMatrix()
126
- break
127
- }
128
- }
129
-
130
- return node
131
- }
132
-
133
- const propertyShortcuts: { [key: string]: string } = {
134
- x: 'position.x',
135
- y: 'position.y',
136
- z: 'position.z',
137
- }
138
-
139
- export const nestedPropertiesToCheck = ['', 'parameters']
140
-
141
- /** props that Lunchbox intercepts and prevents passing to created instances */
142
- const internalLunchboxVueKeys = [
143
- 'args',
144
- 'attach',
145
- 'attachArray',
146
- 'is.default',
147
- 'isDefault',
148
- 'key',
149
- 'onAdded',
150
- // 'onReady',
151
- 'ref',
152
- 'src',
153
- ]
package/src/index.ts DELETED
@@ -1,400 +0,0 @@
1
- import {
2
- computed,
3
- createRenderer,
4
- Component,
5
- ComputedRef,
6
- inject,
7
- watch,
8
- reactive,
9
- Ref,
10
- WatchStopHandle,
11
- toRaw,
12
- } from 'vue'
13
- import { createNodeOps } from './nodeOps'
14
- import { extend, MiniDom } from './core'
15
- import { components } from './components'
16
- import { Lunch } from './types'
17
-
18
- export * from './core'
19
- export * from './types'
20
-
21
- import * as Keys from './keys'
22
- export * from './keys'
23
-
24
- // Utilities
25
- export * from './utils/find'
26
-
27
- /** The current camera as a computed value. */
28
- export const useCamera = <T extends THREE.Camera = THREE.Camera>() =>
29
- inject<ComputedRef<T>>(Keys.appCameraKey)!
30
- /** Run a function using the current camera when it's present. */
31
- export const onCameraReady = <T extends THREE.Camera = THREE.Camera>(
32
- cb: (camera?: T) => void
33
- ) => {
34
- const existing = useCamera<T>()
35
- if (existing.value) {
36
- cb(existing.value)
37
- return
38
- }
39
-
40
- let stopWatch: WatchStopHandle | null = null
41
- stopWatch = watch(useCamera<T>(), (newVal) => {
42
- if (newVal) {
43
- cb(newVal)
44
- stopWatch?.()
45
- }
46
- })
47
- }
48
-
49
- /** The current renderer as a computed value. */
50
- export const useRenderer = <T extends THREE.Renderer = THREE.WebGLRenderer>() =>
51
- inject<ComputedRef<T>>(Keys.appRenderersKey)!
52
- /** Run a function using the current renderer when it's present. */
53
- export const onRendererReady = <T extends THREE.Renderer = THREE.Renderer>(
54
- cb: (renderer?: T) => void
55
- ) => {
56
- const existing = useRenderer<T>()
57
- if (existing.value) {
58
- cb(existing.value)
59
- return
60
- }
61
-
62
- let stopWatch: WatchStopHandle | null = null
63
- stopWatch = watch(
64
- useRenderer<T>(),
65
- (newVal) => {
66
- if (newVal) {
67
- cb(newVal)
68
- stopWatch?.()
69
- }
70
- },
71
- { immediate: true }
72
- )
73
- }
74
-
75
- /** The current scene as a computed value. */
76
- export const useScene = <T extends THREE.Scene = THREE.Scene>() =>
77
- inject<ComputedRef<T>>(Keys.appSceneKey)!
78
- /** Run a function using the current scene when it's present. */
79
- export const onSceneReady = <T extends THREE.Scene = THREE.Scene>(
80
- cb: (scene?: T) => void
81
- ) => {
82
- const existing = useScene<T>()
83
- if (existing.value) {
84
- cb(existing.value)
85
- return
86
- }
87
-
88
- let stopWatch: WatchStopHandle | null = null
89
- stopWatch = watch(
90
- useScene<T>(),
91
- (newVal) => {
92
- if (newVal) {
93
- cb(newVal)
94
- stopWatch?.()
95
- }
96
- },
97
- { immediate: true }
98
- )
99
- }
100
-
101
- // CUSTOM RENDER SUPPORT
102
- // ====================
103
- /** Set a custom render function, overriding the Lunchbox app's default render function.
104
- * Changing this requires the user to manually render their scene.
105
- *
106
- * Invokes immediately - use `useCustomRender().setCustomRender`
107
- * if you need to call somewhere outside of `setup`.
108
- */
109
- export const setCustomRender = (
110
- render: (opts: Lunch.UpdateCallbackProperties) => void
111
- ) => {
112
- useCustomRender()?.setCustomRender?.(render)
113
- }
114
-
115
- /** Clear the active app's custom render function.
116
- *
117
- * Invokes immediately - use `useCustomRender().clearCustomRender`
118
- * if you need to call somewhere outside of `setup`.
119
- */
120
- export const clearCustomRender = () => {
121
- useCustomRender()?.clearCustomRender?.()
122
- }
123
-
124
- /** Provides `setCustomRender` and `clearCustomRender` functions to be called in a non-`setup` context. */
125
- export const useCustomRender = () => {
126
- return {
127
- /** Set a custom render function, overriding the Lunchbox app's default render function.
128
- * Changing this requires the user to manually render their scene. */
129
- setCustomRender: inject<Lunch.CustomRenderFunctionSetter>(
130
- Keys.setCustomRenderKey
131
- ),
132
- /** Clear the active app's custom render function. */
133
- clearCustomRender: inject<() => void>(Keys.clearCustomRenderKey),
134
- }
135
- }
136
-
137
- /** Use app-level globals. */
138
- export const useGlobals = () =>
139
- inject<Lunch.AppGlobals>(Keys.globalsInjectionKey)!
140
-
141
- /** Construct a function to update your app-level globals.
142
- *
143
- * ```js
144
- * // in setup():
145
- * const updateGlobals = useUpdateGlobals()
146
- *
147
- * // ...later, to update the device pixel resolution...
148
- * updateGlobals({ dpr: 2 })
149
- * ```
150
- */
151
- export const useUpdateGlobals = () =>
152
- inject<Lunch.AppGlobalsUpdate>(Keys.updateGlobalsInjectionKey)
153
-
154
- /** Update app-level globals.
155
- *
156
- * Invokes immediately - use `useUpdateGlobals`
157
- * if you need to call somewhere outside of `setup`.
158
- */
159
- export const updateGlobals = (newValue: Partial<Lunch.AppGlobals>) => {
160
- useUpdateGlobals()?.(newValue)
161
- }
162
-
163
- /** Use the current Lunchbox app. Usually used internally by Lunchbox. */
164
- export const useApp = () => inject<Lunch.App>(Keys.appKey)
165
-
166
- /** Obtain a list of the start callback functions. Usually used internally by Lunchbox. */
167
- export const useStartCallbacks = () =>
168
- inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey)
169
-
170
- /** Run a given callback once when the Lunchbox app starts. Include an index to
171
- * splice the callback at that index in the callback queue. */
172
- export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
173
- const callbacks = useStartCallbacks()
174
- if (index === Infinity) {
175
- callbacks?.push(cb)
176
- } else {
177
- callbacks?.splice(index, 0, cb)
178
- }
179
- }
180
-
181
- /** Obtain a list of interactable objects (registered via onClick, onHover, etc events). Usually used internally by Lunchbox. */
182
- export const useLunchboxInteractables = () =>
183
- inject<Ref<Lunch.Node[]>>(Keys.lunchboxInteractables)
184
-
185
- /** Build a computed instance-getter from a specified ref. Defaults to a `toRaw`'d result. */
186
- export const getInstance = <T = unknown>(
187
- target: Ref<Lunch.LunchboxComponent<T> | Lunch.Node<T> | null>,
188
- raw = true
189
- ) =>
190
- computed(() => {
191
- const output =
192
- (target.value as Lunch.LunchboxComponent<T>)?.$el?.instance ??
193
- (target.value as Lunch.Node<T>)?.instance ??
194
- null
195
- if (output && raw) return toRaw(output)
196
- return output
197
- })
198
-
199
- // CREATE APP
200
- // ====================
201
- export const createApp = (
202
- root: Component,
203
- rootProps: Record<string, any> = {}
204
- ) => {
205
- const { nodeOps, interactables } = createNodeOps()
206
- const app = createRenderer(nodeOps).createApp(root, rootProps) as Lunch.App
207
-
208
- // provide Lunchbox interaction handlers flag (modified when user references events via
209
- // @click, etc)
210
- app.provide(Keys.lunchboxInteractables, interactables)
211
-
212
- // register all components
213
- // ====================
214
- Object.keys(components).forEach((key) => {
215
- app?.component(key, (components as any)[key])
216
- })
217
-
218
- // provide custom renderer functions
219
- // ====================
220
- app.provide(
221
- Keys.setCustomRenderKey,
222
- (render: (opts: Lunch.UpdateCallbackProperties) => void) => {
223
- app.setCustomRender(render)
224
- }
225
- )
226
- app.provide(Keys.clearCustomRenderKey, () => {
227
- app.clearCustomRender()
228
- })
229
-
230
- // before render
231
- // ====================
232
- const beforeRender = [] as Lunch.UpdateCallback[]
233
- app.provide(Keys.beforeRenderKey, beforeRender)
234
- app.provide(
235
- Keys.onBeforeRenderKey,
236
- (cb: Lunch.UpdateCallback, index = Infinity) => {
237
- if (index === Infinity) {
238
- beforeRender.push(cb)
239
- } else {
240
- beforeRender.splice(index, 0, cb)
241
- }
242
- }
243
- )
244
- app.provide(
245
- Keys.offBeforeRenderKey,
246
- (cb: Lunch.UpdateCallback | number) => {
247
- if (isFinite(cb as number)) {
248
- beforeRender.splice(cb as number, 1)
249
- } else {
250
- const idx = beforeRender.findIndex((v) => v == cb)
251
- if (idx !== -1) {
252
- beforeRender.splice(idx, 1)
253
- }
254
- }
255
- }
256
- )
257
-
258
- // after render
259
- // ====================
260
- const afterRender = [] as Lunch.UpdateCallback[]
261
- app.provide(Keys.afterRenderKey, afterRender)
262
- app.provide(
263
- Keys.onAfterRenderKey,
264
- (cb: Lunch.UpdateCallback, index = Infinity) => {
265
- if (index === Infinity) {
266
- afterRender.push(cb)
267
- } else {
268
- afterRender.splice(index, 0, cb)
269
- }
270
- }
271
- )
272
- app.provide(Keys.offAfterRenderKey, (cb: Lunch.UpdateCallback | number) => {
273
- if (isFinite(cb as number)) {
274
- afterRender.splice(cb as number, 1)
275
- } else {
276
- const idx = afterRender.findIndex((v) => v == cb)
277
- if (idx !== -1) {
278
- afterRender.splice(idx, 1)
279
- }
280
- }
281
- })
282
-
283
- // save app-level components
284
- // ====================
285
- app.config.globalProperties.lunchbox = reactive({
286
- afterRender,
287
- beforeRender,
288
- camera: null,
289
- dpr: 1,
290
- frameId: -1,
291
- renderer: null,
292
- scene: null,
293
- watchStopHandle: null,
294
-
295
- // TODO: inputActive, mousePos
296
- })
297
-
298
- // provide app-level globals & globals update method
299
- // ====================
300
- app.provide(Keys.globalsInjectionKey, app.config.globalProperties.lunchbox)
301
- app.provide<Lunch.AppGlobalsUpdate>(
302
- Keys.updateGlobalsInjectionKey,
303
- (newGlobals: Partial<Lunch.AppGlobals>) => {
304
- Object.keys(newGlobals).forEach((key) => {
305
- const typedKey = key as keyof Lunch.AppGlobals
306
- // TODO: fix
307
- app.config.globalProperties.lunchbox[typedKey] = newGlobals[
308
- typedKey
309
- ] as any
310
- })
311
- }
312
- )
313
-
314
- // frame ID (used for update functions)
315
- // ====================
316
- app.provide(Keys.frameIdKey, app.config.globalProperties.lunchbox.frameId)
317
-
318
- // watch stop handler (used for conditional update loop)
319
- // ====================
320
- app.provide(
321
- Keys.watchStopHandleKey,
322
- app.config.globalProperties.lunchbox.watchStopHandle
323
- )
324
-
325
- // update mount function to match Lunchbox.Node
326
- // ====================
327
- const { mount } = app
328
- app.mount = (root, ...args) => {
329
- // find DOM element to use as app root
330
- const domElement = (
331
- typeof root === 'string' ? document.querySelector(root) : root
332
- ) as HTMLElement
333
- // create or find root node
334
- const rootNode = new MiniDom.RendererRootNode({
335
- domElement,
336
- isLunchboxRootNode: true,
337
- name: 'root',
338
- metaType: 'rootMeta',
339
- type: 'root',
340
- uuid: 'LUNCHBOX_ROOT',
341
- })
342
- app.rootNode = rootNode
343
- app.provide(Keys.appRootNodeKey, rootNode)
344
- const mounted = mount(rootNode, ...args)
345
- return mounted
346
- }
347
-
348
- // embed .extend function
349
- // ====================
350
- app.extend = (targets: Record<string, any>) => {
351
- extend({ app: app!, ...targets })
352
- return app!
353
- }
354
-
355
- // start callback functions
356
- // ====================
357
- const startCallbacks: Lunch.UpdateCallback[] = []
358
- app.provide(Keys.startCallbackKey, startCallbacks)
359
-
360
- // prep for custom render support
361
- // ====================
362
- app.setCustomRender = (
363
- newRender: (opts: Lunch.UpdateCallbackProperties) => void
364
- ) => {
365
- if (app) {
366
- app.customRender = newRender
367
- }
368
- }
369
-
370
- // add custom render removal
371
- app.clearCustomRender = () => {
372
- if (app) {
373
- app.customRender = null
374
- }
375
- }
376
-
377
- // provide app
378
- // ====================
379
- app.provide(Keys.appKey, app)
380
- app.provide(
381
- Keys.appRenderersKey,
382
- computed(() => app.config.globalProperties.lunchbox.renderer)
383
- )
384
- app.provide(
385
- Keys.appSceneKey,
386
- computed(() => app.config.globalProperties.lunchbox.scene)
387
- )
388
- app.provide(
389
- Keys.appCameraKey,
390
- computed(() => app.config.globalProperties.lunchbox.camera)
391
- )
392
-
393
- app._props
394
-
395
- // done
396
- return app
397
- }
398
-
399
- /** Use this plugin to add a <lunchbox> component in your HTML app. */
400
- export { bridge as lunchbox } from './plugins/bridge/bridge'