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
package/src/keys.ts DELETED
@@ -1,31 +0,0 @@
1
- // These keys originally used Symbols per Vue instructions,
2
- // but differing dev/build values made dev difficult.
3
- // These strings have some risk of namespace collision,
4
- // but that's a low enough risk that they're worth hardcoding
5
- // as strings, in my opinion.
6
-
7
- export const globalsInjectionKey = 'lunchbox-globals' // Symbol()
8
- export const updateGlobalsInjectionKey = 'lunchbox-updateGlobals' // Symbol()
9
-
10
- export const setCustomRenderKey = 'lunchbox-setCustomRender' // Symbol()
11
- export const clearCustomRenderKey = 'lunchbox-clearCustomRender' //Symbol()
12
-
13
- export const beforeRenderKey = 'lunchbox-beforeRender' // Symbol()
14
- export const onBeforeRenderKey = 'lunchbox-onBeforeRender' //Symbol()
15
- export const offBeforeRenderKey = 'lunchbox-offBeforeRender' // Symbol()
16
-
17
- export const afterRenderKey = 'lunchbox-afterRender' // Symbol()
18
- export const onAfterRenderKey = 'lunchbox-onAfterRender' // Symbol()
19
- export const offAfterRenderKey = 'lunchbox-offAfterRender' // Symbol()
20
-
21
- export const frameIdKey = 'lunchbox-frameId' // Symbol()
22
- export const watchStopHandleKey = 'lunchbox-watchStopHandle' // Symbol()
23
-
24
- export const appRootNodeKey = 'lunchbox-appRootNode' // Symbol()
25
- export const appKey = 'lunchbox-appKey' // Symbol()
26
- export const appRenderersKey = 'lunchbox-renderer' //Symbol()
27
- export const appSceneKey = 'lunchbox-scene' // Symbol()
28
- export const appCameraKey = 'lunchbox-camera' //Symbol()
29
- export const lunchboxInteractables = 'lunchbox-interactables' // Symbol()
30
-
31
- export const startCallbackKey = 'lunchbox-startCallback' // Symbol()
@@ -1,34 +0,0 @@
1
- import { createDomNode, createNode } from '../core'
2
- import { isLunchboxDomComponent } from '../utils'
3
- import { Lunch } from '..'
4
-
5
- const autoAttach = ['geometry', 'material']
6
-
7
- export const createElement = (
8
- type: string,
9
- isSVG?: boolean,
10
- isCustomizedBuiltin?: string,
11
- vnodeProps?: Lunch.LunchboxMetaProps
12
- ) => {
13
- const options: Partial<Lunch.MetaBase> = { type, props: vnodeProps }
14
-
15
- // handle dom node
16
- const isDomNode = isLunchboxDomComponent(options)
17
- if (isDomNode) {
18
- const node = createDomNode(options)
19
- return node
20
- }
21
-
22
- // handle standard node
23
- const node = createNode(options)
24
-
25
- // autoattach
26
- autoAttach.forEach((key) => {
27
- if (type.toLowerCase().endsWith(key)) {
28
- node.props.attach = key
29
- }
30
- })
31
- // TODO: array autoattach
32
-
33
- return node
34
- }
@@ -1,83 +0,0 @@
1
- import { RendererOptions, ref } from 'vue'
2
- import { createElement } from './createElement'
3
- import { insert } from './insert'
4
- import { remove } from './remove'
5
- import { isLunchboxDomComponent, isLunchboxRootNode } from '../utils'
6
- import { createCommentNode, createTextNode, updateObjectProp } from '../core'
7
- import type { MiniDom } from '../core'
8
- import type { Lunch } from '..'
9
-
10
- /*
11
- Elements are `create`d from the outside in, then `insert`ed from the inside out.
12
- */
13
-
14
- export const createNodeOps = () => {
15
- // APP-LEVEL GLOBALS
16
- // ====================
17
- // These need to exist at the app level in a place where the node ops can access them.
18
- // It'd be better to set these via `app.provide` at app creation, but the node ops need access
19
- // to these values before the app is instantiated, so this is the next-best place for them to exist.
20
- const interactables = ref([] as Lunch.Node[])
21
-
22
- // NODE OPS
23
- // ====================
24
- const nodeOps: RendererOptions<
25
- MiniDom.RendererBaseNode,
26
- MiniDom.RendererBaseNode
27
- > = {
28
- createElement,
29
- createText(text) {
30
- return createTextNode({ text })
31
- },
32
- createComment(text) {
33
- return createCommentNode({ text })
34
- },
35
- insert,
36
- nextSibling(node) {
37
- const result = node.nextSibling
38
- if (!result) return null
39
- return result as MiniDom.RendererBaseNode
40
- },
41
- parentNode(node) {
42
- const result = node.parentNode
43
- if (!result) return null
44
- return result as MiniDom.RendererBaseNode
45
- },
46
- patchProp(node, key, prevValue, nextValue) {
47
- if (isLunchboxDomComponent(node)) {
48
- // handle DOM node
49
- if (key === 'style') {
50
- // special handling for style
51
- Object.keys(nextValue).forEach((k) => {
52
- ;(node.domElement.style as any)[k] = nextValue[k]
53
- })
54
- } else {
55
- node.domElement.setAttribute(key, nextValue)
56
- }
57
- return
58
- }
59
-
60
- // ignore if root node, or Lunchbox internal prop
61
- if (isLunchboxRootNode(node) || key.startsWith('$')) {
62
- return
63
- }
64
-
65
- // otherwise, update prop
66
- updateObjectProp({
67
- node: node as Lunch.Node,
68
- key,
69
- interactables,
70
- value: nextValue,
71
- })
72
- },
73
- remove,
74
- setElementText() {
75
- // noop
76
- },
77
- setText() {
78
- // noop
79
- },
80
- }
81
-
82
- return { nodeOps, interactables }
83
- }
@@ -1,165 +0,0 @@
1
- import {
2
- isLunchboxDomComponent,
3
- isLunchboxRootNode,
4
- isLunchboxStandardNode,
5
- } from '../utils'
6
- import { MiniDom } from '../core/minidom'
7
- import { Lunch } from '..'
8
-
9
- export const insert = (
10
- child: MiniDom.RendererBaseNode,
11
- parent: MiniDom.RendererBaseNode | null,
12
- anchor?: MiniDom.RendererBaseNode | null
13
- ) => {
14
- if (!parent) {
15
- throw new Error('missing parent')
16
- }
17
- // add to parent tree node if we have one
18
- // let effectiveParent = parent ?? ensureRootNode()
19
- parent.insertBefore(child, anchor)
20
-
21
- // handle comment & text nodes
22
- if (child.metaType === 'commentMeta' || child.metaType === 'textMeta') {
23
- return
24
- }
25
-
26
- // handle dom element
27
- if (isLunchboxDomComponent(child)) {
28
- if (isLunchboxDomComponent(parent) || isLunchboxRootNode(parent)) {
29
- parent.domElement.appendChild(child.domElement)
30
- } else {
31
- // TODO: handle dom nodes as children of Lunchbox nodes
32
- }
33
- }
34
-
35
- // handle standard nodes
36
- if (isLunchboxStandardNode(child)) {
37
- // let effectiveParent = parent
38
- let effectiveParentNodeType = parent.metaType
39
-
40
- if (
41
- effectiveParentNodeType === 'textMeta' ||
42
- effectiveParentNodeType === 'commentMeta'
43
- ) {
44
- const path = parent.getPath() as MiniDom.RendererBaseNode[]
45
- for (let i = path.length - 1; i >= 0; i--) {
46
- if (
47
- path[i].metaType !== 'textMeta' &&
48
- path[i].metaType !== 'commentMeta'
49
- ) {
50
- parent = path[i]
51
- break
52
- }
53
- }
54
- }
55
-
56
- if (
57
- isLunchboxStandardNode(child) &&
58
- child.instance?.isObject3D &&
59
- isLunchboxStandardNode(parent) &&
60
- parent.instance?.isObject3D
61
- ) {
62
- parent.instance?.add?.(child.instance)
63
- }
64
-
65
- // add attached props
66
- if (
67
- child?.props?.attach &&
68
- isLunchboxStandardNode(parent) &&
69
- parent?.instance
70
- ) {
71
- // if this element is a loader and the `src` attribute is being used,
72
- // let's assume we want to create the loader and run `load`
73
- const isUsingLoaderSugar =
74
- child.type?.toLowerCase().endsWith('loader') &&
75
- child.props.src &&
76
- (child.props.attach || child.props.attachArray)
77
-
78
- // run special loader behavior
79
- if (isUsingLoaderSugar) {
80
- runLoader(child, parent)
81
- } else {
82
- // update attached normally
83
- attachToParentInstance(child, parent, child.props.attach)
84
- }
85
- }
86
-
87
- // fire onAdded event
88
- if (child.props?.onAdded) {
89
- child.props.onAdded({
90
- instance: child.instance,
91
- })
92
- }
93
- }
94
- }
95
-
96
- function runLoader<T>(
97
- child: MiniDom.RendererStandardNode<T>,
98
- parent: MiniDom.RendererStandardNode
99
- ) {
100
- const loader = child.instance as any as Lunch.GenericThreeLoader
101
- // ensure parent has attached spaces ready
102
- parent.attached = parent.attached || {}
103
- parent.attachedArray = parent.attachedArray || {}
104
-
105
- // this should never be true, but just in case
106
- if (!child.props.attach) return
107
-
108
- if (child.type?.toLowerCase() === 'textureloader') {
109
- // if this is a texture loader, immediately pass
110
- // load function to parent attachment
111
- const textureLoader = loader as any as THREE.TextureLoader
112
- const inProgressTexture = textureLoader.load(child.props.src)
113
-
114
- attachToParentInstance(
115
- child,
116
- parent,
117
- child.props.attach,
118
- inProgressTexture
119
- )
120
- } else {
121
- // use a standard callback-based loader
122
- loader.load(
123
- child.props.src,
124
- (loadedData) => {
125
- attachToParentInstance(
126
- child,
127
- parent,
128
- child.props.attach!,
129
- loadedData
130
- )
131
- },
132
- null,
133
- (err) => {
134
- throw new Error(err)
135
- }
136
- )
137
- }
138
- }
139
-
140
- function attachToParentInstance<T>(
141
- child: MiniDom.RendererStandardNode<T>,
142
- parent: MiniDom.RendererStandardNode,
143
- key: string,
144
- value?: any
145
- ) {
146
- const finalValueToAttach = value ?? child.instance
147
- const parentInstanceAsAny = parent.instance as any
148
-
149
- if (child.props.attach === key) {
150
- parent.attached = {
151
- [key]: finalValueToAttach,
152
- ...(parent.attached || {}),
153
- }
154
- parentInstanceAsAny[key] = value ?? child.instance
155
- }
156
-
157
- if (child.props.attachArray === key) {
158
- if (!parent.attachedArray[child.props.attachArray]) {
159
- parent.attachedArray[child.props.attachArray] = []
160
- }
161
- parent.attachedArray[child.props.attachArray].push(finalValueToAttach)
162
- // TODO: implement auto-attaching array
163
- parentInstanceAsAny[key] = [parentInstanceAsAny[key]]
164
- }
165
- }
@@ -1,32 +0,0 @@
1
- import { MiniDom } from '../core'
2
- import { isLunchboxStandardNode } from '../utils'
3
-
4
- export const remove = (node: MiniDom.RendererBaseNode) => {
5
- if (!node) return
6
- // prep subtree
7
- const subtree: MiniDom.BaseNode[] = []
8
- node.walk((descendant) => {
9
- subtree.push(descendant)
10
- return true
11
- })
12
-
13
- // clean up subtree
14
- subtree.forEach((n) => {
15
- if (isLunchboxStandardNode(n)) {
16
- // try to remove three object
17
- n.instance?.removeFromParent?.()
18
-
19
- // try to dispose three object
20
- const dispose =
21
- // calling `dispose` on a scene triggers an error,
22
- // so let's ignore if this node is a scene
23
- n.type !== 'scene' &&
24
- ((n.instance as any)?.dispose as (() => void) | null)
25
- if (dispose) dispose.bind(n.instance)()
26
- n.instance = null
27
- }
28
-
29
- // drop tree node
30
- n.drop()
31
- })
32
- }
@@ -1,60 +0,0 @@
1
- import {
2
- Component,
3
- defineComponent,
4
- getCurrentInstance,
5
- inject,
6
- onMounted,
7
- onUnmounted,
8
- PropType,
9
- ref,
10
- } from 'vue'
11
- import { createApp, Lunch } from '../..'
12
-
13
- export const BridgeComponent = defineComponent({
14
- name: 'BridgeComponent',
15
- props: {
16
- app: {
17
- type: Object as PropType<Lunch.App>,
18
- },
19
- root: {
20
- type: Object as PropType<Component>,
21
- },
22
- appSetup: {
23
- type: Function as PropType<(app: Lunch.App) => Lunch.App>,
24
- default: (app: Lunch.App) => app,
25
- },
26
- },
27
- setup(props, ctx) {
28
- // we need an app or root to mount
29
- if (!props.app && !props.root) {
30
- throw new Error('app or root required as <bridge> prop')
31
- }
32
-
33
- // prep container
34
- const container = ref<HTMLDivElement>()
35
- // create app
36
- let app: Lunch.App | null = props.appSetup(
37
- props.app ?? createApp(props.root!, ctx.attrs)
38
- )
39
-
40
- // get all provided values - this isn't in the types or docs, so it may be unstable
41
- const provides = (getCurrentInstance() as any)?.provides ?? {}
42
- // provide values
43
- Object.keys(provides).forEach((key) => {
44
- app?.provide(key, inject(key))
45
- })
46
-
47
- // mount
48
- onMounted(() => {
49
- app?.mount(container.value)
50
- })
51
-
52
- // unmount
53
- onUnmounted(() => {
54
- app?.unmount()
55
- app = null
56
- })
57
-
58
- return () => <div ref={container} />
59
- },
60
- })
@@ -1,9 +0,0 @@
1
- import { Plugin } from 'vue'
2
- import { BridgeComponent } from './BridgeComponent'
3
-
4
- export const bridge: Plugin = {
5
- install(app) {
6
- // register wrapper component
7
- app.component('lunchbox', BridgeComponent)
8
- },
9
- }
package/src/types.ts DELETED
@@ -1,186 +0,0 @@
1
- type RendererStandardNode<T = THREE.Object3D> =
2
- import('./core').MiniDom.RendererStandardNode<T>
3
- type RootNode = import('./core/minidom').MiniDom.RendererRootNode
4
- type VNodeProps = import('vue').VNodeProps
5
- type VueApp<T> = import('vue').App<T>
6
- type WatchSource = import('vue').WatchSource
7
- type WatchStopHandle = import('vue').WatchStopHandle
8
- type ThreeCamera = import('three').Camera
9
- type ThreeRenderer = import('three').Renderer
10
- type ThreeScene = import('three').Scene
11
-
12
- export declare namespace Lunch {
13
- /** Lunchbox app. */
14
- type App = Omit<VueApp<any>, 'config'> & {
15
- clearCustomRender: () => void
16
- config: Omit<VueApp<any>['config'], 'globalProperties'> & {
17
- globalProperties: {
18
- lunchbox: {
19
- afterRender: Lunch.UpdateCallback[]
20
- beforeRender: Lunch.UpdateCallback[]
21
- camera: ThreeCamera | null
22
- dpr: number
23
- frameId: number
24
- renderer: ThreeRenderer | null
25
- scene: ThreeScene | null
26
- watchStopHandle: WatchStopHandle | null
27
- }
28
- } & Record<string, any>
29
- }
30
- customRender: ((opts: UpdateCallbackProperties) => void) | null
31
- extend: (v: Record<string, any>) => App
32
- rootNode: RootNode
33
- setCustomRender: (
34
- update: (opts: UpdateCallbackProperties) => void
35
- ) => void
36
- update: UpdateCallback
37
- }
38
-
39
- type AppGlobals = App['config']['globalProperties']['lunchbox']
40
-
41
- type AppGlobalsUpdate = (newValue: Partial<AppGlobals>) => void
42
-
43
- interface CanvasProps {
44
- dpr?: number
45
- wrapperProps?: WrapperProps
46
- }
47
-
48
- /** Lunchbox component catalogue. */
49
- interface Catalogue {
50
- [key: string]: {
51
- new (...args: any): { [key: string]: any }
52
- }
53
- }
54
-
55
- interface CommentMeta extends MetaBase {
56
- text: string
57
- }
58
-
59
- type CustomRenderFunctionSetter = (
60
- render: (opts: Lunch.UpdateCallbackProperties) => void
61
- ) => void
62
-
63
- interface DomMeta extends MetaBase {
64
- domElement: HTMLElement
65
- }
66
-
67
- type EventCallback = (options: {
68
- intersection: THREE.Intersection<any>
69
- }) => void
70
-
71
- // MAKE SURE THESE MATCH VALUES IN lib.isEventKey
72
- type EventKey =
73
- | 'onClick'
74
- | 'onContextMenu'
75
- | 'onDoubleClick'
76
- | 'onPointerUp'
77
- | 'onPointerDown'
78
- | 'onPointerOver'
79
- | 'onPointerOut'
80
- | 'onPointerEnter'
81
- | 'onPointerLeave'
82
- | 'onPointerMove'
83
- // | 'onPointerMissed'
84
- // 'onUpdate' |
85
- | 'onWheel'
86
-
87
- interface GenericThreeLoader<T = any> {
88
- load(
89
- src: string,
90
- onLoad: (data: T) => void,
91
- onProgress: null,
92
- onError: (error: any) => void
93
- ): void
94
- }
95
-
96
- /** Meta info needed on a standard Lunchbox node. */
97
- interface StandardMeta<T = THREE.Object3D> extends MetaBase {
98
- attached: { [key: string]: any }
99
- attachedArray: { [key: string]: Array<any> }
100
- instance: T | null
101
- }
102
-
103
- /** Meta info that every node needs. */
104
- interface MetaBase {
105
- name: string | null | undefined
106
- metaType: MetaType
107
- props: LunchboxMetaProps
108
- type: string | null
109
- uuid: Uuid
110
- }
111
-
112
- type MetaType =
113
- | 'commentMeta'
114
- | 'domMeta'
115
- | 'standardMeta'
116
- | 'metaBase'
117
- | 'rootMeta'
118
- | 'textMeta'
119
-
120
- interface RootMeta extends MetaBase {
121
- domElement: HTMLElement
122
- isLunchboxRootNode: boolean
123
- }
124
-
125
- type ShadowSugar =
126
- | boolean
127
- | {
128
- type: THREE.ShadowMapType
129
- }
130
-
131
- interface TextMeta extends MetaBase {
132
- text: string
133
- }
134
-
135
- /** Props that can be passed to any Lunchbox meta. */
136
- type LunchboxMetaProps = VNodeProps & {
137
- args?: Array<any>
138
- attach?: string
139
- onAdded?<T>(opts: { instance: T | null }): void
140
-
141
- [key: string]: any
142
- }
143
-
144
- type LunchboxComponent<T = THREE.Object3D> = {
145
- $el: Node<T>
146
- }
147
-
148
- type Node<T = THREE.Object3D> = RendererStandardNode<T>
149
-
150
- type UpdateCallback = (properties: UpdateCallbackProperties) => void
151
-
152
- interface UpdateCallbackProperties {
153
- app: App
154
- scene?: THREE.Scene | null
155
- renderer?: THREE.Renderer | null
156
- camera?: THREE.Camera | null
157
- updateSource?: WatchSource | null
158
- }
159
-
160
- /** Universally unique identifier. */
161
- type Uuid = string
162
-
163
- type SizePolicy = 'full' | 'container'
164
-
165
- type Vector3AsArray = [number, number, number]
166
-
167
- interface WrapperProps {
168
- background?: string
169
- cameraArgs?: any[]
170
- cameraLook?: Vector3AsArray
171
- cameraLookAt?: Vector3AsArray
172
- cameraPosition?: Vector3AsArray
173
- dpr?: number
174
- ortho?: boolean
175
- orthographic?: boolean
176
- r3f?: boolean
177
- // TODO: Why doesn't ConstructorParameters<THREE.WebGLRenderer> work here?
178
- rendererArguments?: object
179
- rendererProperties?: Partial<THREE.WebGLRenderer>
180
- sizePolicy?: SizePolicy
181
- shadow?: ShadowSugar
182
- transparent?: boolean
183
- zoom?: number
184
- updateSource?: WatchSource | null
185
- }
186
- }
package/src/utils/find.ts DELETED
@@ -1,24 +0,0 @@
1
- import { Lunch } from '..'
2
- import { isLunchboxComponent, isLunchboxStandardNode } from '.'
3
- import { isRef, isVNode } from 'vue'
4
-
5
- export function find<T extends object>(target: any) {
6
- target = isRef(target) ? target.value : target
7
-
8
- // handle standard lunchbox node
9
- if (isLunchboxStandardNode(target)) {
10
- return (target as Lunch.Node<T>)?.instance
11
- }
12
-
13
- // handle component
14
- if (isLunchboxComponent(target)) {
15
- return (target as Lunch.LunchboxComponent<T>)?.$el?.instance
16
- }
17
-
18
- // handle vnode
19
- if (isVNode(target)) {
20
- return (target.el as Lunch.Node<T>)?.instance
21
- }
22
-
23
- return null
24
- }
package/src/utils/get.ts DELETED
@@ -1,18 +0,0 @@
1
- export const get = <T = unknown>(
2
- obj: Record<string, any>,
3
- path: string | string[],
4
- defValue?: T
5
- ) => {
6
- // If path is not defined or it has false value
7
- if (!path) return undefined
8
- // Check if path is string or array. Regex : ensure that we do not have '.' and brackets.
9
- // Regex explained: https://regexr.com/58j0k
10
- const pathArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g)
11
- // Find value
12
- const result = pathArray?.reduce(
13
- (prevObj: Record<string, any>, key: string) => prevObj && prevObj[key],
14
- obj
15
- )
16
- // If found value is undefined return default value; otherwise return the value
17
- return result === undefined ? defValue : result
18
- }