From 573771d7f47e44525fd6dfbace7924d6300947e2 Mon Sep 17 00:00:00 2001 From: Ib Green Date: Sun, 28 Apr 2024 07:33:50 -0400 Subject: [PATCH] chore(core): Convert luma object to singleton --- docs/api-reference/core/luma.md | 11 + modules/core/src/adapter/device.ts | 9 + modules/core/src/adapter/luma.ts | 204 +++++++++---------- modules/core/test/adapter/luma.spec.ts | 14 ++ modules/test-utils/src/create-test-device.ts | 4 +- modules/webgl/src/adapter/webgl-device.ts | 12 +- modules/webgpu/src/adapter/webgpu-device.ts | 8 +- yarn.lock | 174 ++++++++-------- 8 files changed, 232 insertions(+), 204 deletions(-) diff --git a/docs/api-reference/core/luma.md b/docs/api-reference/core/luma.md index 7128062d4f..0882f578a9 100644 --- a/docs/api-reference/core/luma.md +++ b/docs/api-reference/core/luma.md @@ -96,6 +96,17 @@ const webgpuDevice = luma.createDevice({ }); ``` +## Types + +### `CreateDeviceProps` + +```ts +type CreateDeviceProps = DeviceProps & { + /** Selects the type of device. `best-available` uses webgpu if available, then webgl. */ + type?: 'webgl' | 'webgpu' | 'unknown' | 'best-available'; +} +``` + ## Methods ### `luma.registerDevices()` diff --git a/modules/core/src/adapter/device.ts b/modules/core/src/adapter/device.ts index 5d5eeba902..4fce2dab40 100644 --- a/modules/core/src/adapter/device.ts +++ b/modules/core/src/adapter/device.ts @@ -241,6 +241,15 @@ export type DeviceProps = { _factoryDestroyPolicy?: 'unused' | 'never'; }; +/** Used by Device registration */ +export interface DeviceConstructor { + // new (props: DeviceProps): Device; Constructor isn't used + type: string; + isSupported(): boolean; + create(props: DeviceProps): Promise; + attach?(handle: unknown): Device; +} + /** * WebGPU Device/WebGL context abstraction */ diff --git a/modules/core/src/adapter/luma.ts b/modules/core/src/adapter/luma.ts index 4a58497f42..3d8c3f1b97 100644 --- a/modules/core/src/adapter/luma.ts +++ b/modules/core/src/adapter/luma.ts @@ -4,25 +4,26 @@ import type {Log} from '@probe.gl/log'; import type {DeviceProps} from './device'; -import {Device} from './device'; +import {Device, DeviceConstructor} from './device'; import {StatsManager} from '../utils/stats-manager'; import {lumaStats} from '../utils/stats-manager'; import {log} from '../utils/log'; -const deviceMap = new Map(); +const ERROR_MESSAGE = + 'No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.'; /** Properties for creating a new device */ export type CreateDeviceProps = DeviceProps & { /** Selects the type of device. `best-available` uses webgpu if available, then webgl. */ type?: 'webgl' | 'webgpu' | 'unknown' | 'best-available'; - devices?: any[]; + devices?: DeviceConstructor[]; }; /** Properties for attaching an existing WebGL context or WebGPU device to a new luma Device */ export type AttachDeviceProps = DeviceProps & { /** Externally created WebGL context or WebGPU device */ - handle: WebGL2RenderingContext; // | GPUDevice; - devices?: any[]; + handle: unknown; // WebGL2RenderingContext | GPUDevice | null; + devices?: DeviceConstructor[]; }; /** @@ -30,7 +31,7 @@ export type AttachDeviceProps = DeviceProps & { * Register WebGPU and/or WebGL devices (controls application bundle size) * Run-time selection of the first available Device */ -export class luma { +export class Luma { static defaultProps: Required = { ...Device.defaultProps, type: 'best-available', @@ -38,119 +39,108 @@ export class luma { }; /** Global stats for all devices */ - static stats: StatsManager = lumaStats; + readonly stats: StatsManager = lumaStats; /** Global log */ - static log: Log = log; + readonly log: Log = log; - static registerDevices(deviceClasses: any[] /* : typeof Device */): void { + protected deviceMap = new Map(); + + registerDevices(deviceClasses: DeviceConstructor[]): void { for (const deviceClass of deviceClasses) { - deviceMap.set(deviceClass.type, deviceClass); + this.deviceMap.set(deviceClass.type, deviceClass); } } - static getAvailableDevices(): string[] { - // @ts-expect-error - return Array.from(deviceMap).map(Device => Device.type); + /** Get type strings for supported Devices */ + getSupportedDeviceTypes(devices: DeviceConstructor[] = []): string[] { + const deviceMap = this.getDeviceMap(devices); + return Array.from(deviceMap) + .map(([, Device]) => Device) + .filter(Device => Device.isSupported?.()) + .map(Device => Device.type); } - static getSupportedDevices(): string[] { - return ( - Array.from(deviceMap) - // @ts-expect-error - .filter(Device => Device.isSupported()) - // @ts-expect-error - .map(Device => Device.type) - ); + /** Get type strings for best available Device */ + getBestAvailableDeviceType(devices: DeviceConstructor[] = []): 'webgpu' | 'webgl' | null { + const deviceMap = this.getDeviceMap(devices); + if (deviceMap.get('webgpu')?.isSupported?.()) { + return 'webgpu'; + } + if (deviceMap.get('webgl')?.isSupported?.()) { + return 'webgl'; + } + return null; } - static setDefaultDeviceProps(props: CreateDeviceProps): void { - Object.assign(luma.defaultProps, props); + setDefaultDeviceProps(props: CreateDeviceProps): void { + Object.assign(Luma.defaultProps, props); } - /** Attach to an existing GPU API handle (WebGL2RenderingContext or GPUDevice). */ - static async attachDevice(props: AttachDeviceProps): Promise { - const devices = getDeviceMap(props.devices) || deviceMap; - - // WebGL - if (props.handle instanceof WebGL2RenderingContext) { - const WebGLDevice = devices.get('webgl') as any; - if (WebGLDevice) { - return (await WebGLDevice.attach(props.handle)) as Device; - } - } + /** Creates a device. Asynchronously. */ + async createDevice(props: CreateDeviceProps = {}): Promise { + props = {...Luma.defaultProps, ...props}; - // TODO - WebGPU does not yet have a stable API - // if (props.handle instanceof GPUDevice) { - // const WebGPUDevice = devices.get('webgpu') as any; - // if (WebGPUDevice) { - // return (await WebGPUDevice.attach(props.handle)) as Device; - // } + // Should be handled by attach device + // if (props.gl) { + // props.type = 'webgl'; // } - // null - if (props.handle === null) { - const UnknownDevice = devices.get('unknown') as any; - if (UnknownDevice) { - return (await UnknownDevice.attach(null)) as Device; - } + const deviceMap = this.getDeviceMap(props.devices); + + let type: string = props.type || ''; + if (type === 'best-available') { + type = this.getBestAvailableDeviceType(props.devices) || type; } - throw new Error( - 'Failed to attach device. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.' - ); + const Device = deviceMap.get(type); + if (Device) { + return await Device.create(props); + } + + throw new Error(ERROR_MESSAGE); } - /** Creates a device. Asynchronously. */ - static async createDevice(props: CreateDeviceProps = {}): Promise { - props = {...luma.defaultProps, ...props}; - if (props.gl) { - props.type = 'webgl'; + /** Attach to an existing GPU API handle (WebGL2RenderingContext or GPUDevice). */ + async attachDevice(props: AttachDeviceProps): Promise { + const deviceMap = this.getDeviceMap(props.devices); + + let deviceType; + + // WebGPU sniffing + // eslint-disable-next-line GPUDevice type isn't generally available, we avoid enabling it in core + if (typeof GPUDevice !== 'undefined' && props.handle instanceof GPUDevice) { + deviceType = 'webgpu'; + } + // WebGL + else if ( + typeof WebGL2RenderingContext !== 'undefined' && + props.handle instanceof WebGL2RenderingContext + ) { + deviceType = 'webgl'; + } + // NullDevice + else if (props.handle === null) { + deviceType = 'unknown'; } - const devices = getDeviceMap(props.devices) || deviceMap; - - let WebGPUDevice; - let WebGLDevice; - switch (props.type) { - case 'webgpu': - WebGPUDevice = devices.get('webgpu') as any; - if (WebGPUDevice) { - return await WebGPUDevice.create(props); - } - break; - - case 'webgl': - WebGLDevice = devices.get('webgl') as any; - if (WebGLDevice) { - return await WebGLDevice.create(props); - } - break; - - case 'unknown': - const UnknownDevice = devices.get('unknown') as any; - if (UnknownDevice) { - return await UnknownDevice.create(props); - } - break; - - case 'best-available': - WebGPUDevice = devices.get('webgpu') as any; - if (WebGPUDevice?.isSupported?.()) { - return await WebGPUDevice.create(props); - } - WebGLDevice = devices.get('webgl') as any; - if (WebGLDevice?.isSupported?.()) { - return await WebGLDevice.create(props); - } - break; + if (deviceType) { + const Device = deviceMap.get(deviceType); + const device = Device?.attach?.(props.handle); + if (device) { + return device; + } } - throw new Error( - 'No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.' - ); + + throw new Error(ERROR_MESSAGE); } - static enforceWebGL2(enforce: boolean = true): void { + /** + * Override `HTMLCanvasContext.getCanvas()` to always create WebGL2 contexts. + * Used when attaching luma to a context from an external library does not support creating WebGL2 contexts. + * (luma can only attach to WebGL2 contexts). + */ + enforceWebGL2(enforce: boolean = true): void { const prototype = HTMLCanvasElement.prototype as any; if (!enforce && prototype.originalGetContext) { // Reset the original getContext function @@ -166,25 +156,23 @@ export class luma { prototype.getContext = function (contextId: string, options?: WebGLContextAttributes) { // Attempt to force WebGL2 for all WebGL1 contexts if (contextId === 'webgl' || contextId === 'experimental-webgl') { - return this.originalGetContext('webgl2', options); + const context = this.originalGetContext('webgl2', options); + return context; } // For any other type, return the original context return this.originalGetContext(contextId, options); }; } -} -/** Convert a list of devices to a map */ -function getDeviceMap( - deviceClasses?: any[] /* : typeof Device */ -): Map | null { - if (!deviceClasses || deviceClasses?.length === 0) { - return null; - } - const map = new Map(); - for (const deviceClass of deviceClasses) { - // assert(deviceClass.type && deviceClass.isSupported && deviceClass.create); - map.set(deviceClass.type, deviceClass); + /** Convert a list of devices to a map */ + protected getDeviceMap(deviceClasses: DeviceConstructor[] = []): Map { + const map = new Map(this.deviceMap); + for (const deviceClass of deviceClasses) { + map.set(deviceClass.type, deviceClass); + } + return map; } - return map; } + +/** Singleton */ +export const luma = new Luma(); diff --git a/modules/core/test/adapter/luma.spec.ts b/modules/core/test/adapter/luma.spec.ts index 8588d4b8a5..b8384a218e 100644 --- a/modules/core/test/adapter/luma.spec.ts +++ b/modules/core/test/adapter/luma.spec.ts @@ -31,6 +31,20 @@ test('luma#registerDevices', async t => { t.end(); }); +test('luma#getSupportedDevices', async t => { + luma.registerDevices([NullDevice]); + const types = luma.getSupportedDeviceTypes(); + t.ok(types.includes('unknown'), 'null device is supported'); +}); + +test('luma#getBestAvailableDeviceType', async t => { + luma.registerDevices([NullDevice]); + // Somewhat dummy test, as tests rely on test utils registering webgl and webgpu devices + // But they might not be supported on all devices. + const types = luma.getBestAvailableDeviceType(); + t.ok(typeof types === 'string', 'doesnt crash'); +}); + // To suppress @typescript-eslint/unbound-method interface TestHTMLCanvasElement { getContext: (contextId: any, options?: unknown) => string; diff --git a/modules/test-utils/src/create-test-device.ts b/modules/test-utils/src/create-test-device.ts index e8acacf507..e7baf3f0ad 100644 --- a/modules/test-utils/src/create-test-device.ts +++ b/modules/test-utils/src/create-test-device.ts @@ -23,8 +23,8 @@ export function createTestContext(opts: Record = {}): WebGL2Renderi export function createTestDevice(props: DeviceProps = {}): WebGLDevice | null { try { props = {...CONTEXT_DEFAULTS, ...props, debug: true}; - // We dont use luma.createDevice since this tests current expect this context to be created synchronously - return new WebGLDevice(props); + // TODO - We dont use luma.createDevice since this function currently expect the context to be created synchronously + return WebGLDevice.createSync(props); } catch (error) { // eslint-disable-next-line no-console console.error(`Failed to created device '${props.id}': ${(error as Error).message}`); diff --git a/modules/webgl/src/adapter/webgl-device.ts b/modules/webgl/src/adapter/webgl-device.ts index 49d755a635..1abeb7d0c9 100644 --- a/modules/webgl/src/adapter/webgl-device.ts +++ b/modules/webgl/src/adapter/webgl-device.ts @@ -158,6 +158,14 @@ export class WebGLDevice extends Device { log.probe(LOG_LEVEL + 1, 'DOM is loaded')(); + const device = WebGLDevice.createSync(props); + log.groupEnd(LOG_LEVEL)(); + + return device; + } + + /** Create or attach device synchronously. Not supported for all devices. */ + static createSync(props: DeviceProps = {}): WebGLDevice { // @ts-expect-error if (props.gl?.device) { log.warn('reattaching existing device')(); @@ -173,8 +181,6 @@ ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContex log.probe(LOG_LEVEL, message)(); log.table(LOG_LEVEL, device.info)(); - log.groupEnd(LOG_LEVEL)(); - return device; } @@ -182,7 +188,7 @@ ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContex // Public API // - constructor(props: DeviceProps) { + protected constructor(props: DeviceProps) { super({...props, id: props.id || 'webgl-device'}); // If attaching to an already attached context, return the attached device diff --git a/modules/webgpu/src/adapter/webgpu-device.ts b/modules/webgpu/src/adapter/webgpu-device.ts index 2f4a85d570..2e3de46499 100644 --- a/modules/webgpu/src/adapter/webgpu-device.ts +++ b/modules/webgpu/src/adapter/webgpu-device.ts @@ -128,7 +128,7 @@ export class WebGPUDevice extends Device { log.probe(1, 'DOM is loaded')(); } - const device = new WebGPUDevice(gpuDevice, adapter, adapterInfo, props); + const device = new WebGPUDevice(props, gpuDevice, adapter, adapterInfo); log.probe( 1, @@ -139,11 +139,11 @@ export class WebGPUDevice extends Device { return device; } - constructor( + protected constructor( + props: DeviceProps, device: GPUDevice, adapter: GPUAdapter, - adapterInfo: GPUAdapterInfo, - props: DeviceProps + adapterInfo: GPUAdapterInfo ) { super({...props, id: props.id || 'webgpu-device'}); this.handle = device; diff --git a/yarn.lock b/yarn.lock index 5c10f3e0b4..3b648d0106 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3205,13 +3205,13 @@ __metadata: languageName: node linkType: hard -"@luma.gl/constants@npm:9.1.0-alpha.1, @luma.gl/constants@workspace:modules/constants": +"@luma.gl/constants@npm:9.1.0-alpha.2, @luma.gl/constants@workspace:modules/constants": version: 0.0.0-use.local resolution: "@luma.gl/constants@workspace:modules/constants" languageName: unknown linkType: soft -"@luma.gl/core@npm:9.1.0-alpha.1, @luma.gl/core@workspace:modules/core": +"@luma.gl/core@npm:9.1.0-alpha.2, @luma.gl/core@workspace:modules/core": version: 0.0.0-use.local resolution: "@luma.gl/core@workspace:modules/core" dependencies: @@ -3223,11 +3223,11 @@ __metadata: languageName: unknown linkType: soft -"@luma.gl/engine@npm:9.1.0-alpha.1, @luma.gl/engine@workspace:modules/engine": +"@luma.gl/engine@npm:9.1.0-alpha.2, @luma.gl/engine@workspace:modules/engine": version: 0.0.0-use.local resolution: "@luma.gl/engine@workspace:modules/engine" dependencies: - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" "@math.gl/types": "npm:^4.0.0" "@probe.gl/log": "npm:^4.0.8" @@ -3237,12 +3237,12 @@ __metadata: languageName: unknown linkType: soft -"@luma.gl/gltf@npm:9.1.0-alpha.1, @luma.gl/gltf@workspace:modules/gltf": +"@luma.gl/gltf@npm:9.1.0-alpha.2, @luma.gl/gltf@workspace:modules/gltf": version: 0.0.0-use.local resolution: "@luma.gl/gltf@workspace:modules/gltf" dependencies: "@loaders.gl/textures": "npm:^4.2.0" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" peerDependencies: "@luma.gl/core": ^9.0.0-beta @@ -3250,7 +3250,7 @@ __metadata: languageName: unknown linkType: soft -"@luma.gl/shadertools@npm:9.1.0-alpha.1, @luma.gl/shadertools@workspace:modules/shadertools": +"@luma.gl/shadertools@npm:9.1.0-alpha.2, @luma.gl/shadertools@workspace:modules/shadertools": version: 0.0.0-use.local resolution: "@luma.gl/shadertools@workspace:modules/shadertools" dependencies: @@ -3277,11 +3277,11 @@ __metadata: languageName: unknown linkType: soft -"@luma.gl/webgl@npm:9.1.0-alpha.1, @luma.gl/webgl@workspace:modules/webgl": +"@luma.gl/webgl@npm:9.1.0-alpha.2, @luma.gl/webgl@workspace:modules/webgl": version: 0.0.0-use.local resolution: "@luma.gl/webgl@workspace:modules/webgl" dependencies: - "@luma.gl/constants": "npm:9.1.0-alpha.1" + "@luma.gl/constants": "npm:9.1.0-alpha.2" "@math.gl/types": "npm:^4.0.0" "@probe.gl/env": "npm:^4.0.8" peerDependencies: @@ -3289,7 +3289,7 @@ __metadata: languageName: unknown linkType: soft -"@luma.gl/webgpu@npm:9.1.0-alpha.1, @luma.gl/webgpu@workspace:modules/webgpu": +"@luma.gl/webgpu@npm:9.1.0-alpha.2, @luma.gl/webgpu@workspace:modules/webgpu": version: 0.0.0-use.local resolution: "@luma.gl/webgpu@workspace:modules/webgpu" dependencies: @@ -9800,10 +9800,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-animation@workspace:examples/api/animation" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9814,11 +9814,11 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-cubemap@workspace:examples/api/cubemap" dependencies: - "@luma.gl/constants": "npm:9.1.0-alpha.1" - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/constants": "npm:9.1.0-alpha.2" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9829,10 +9829,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-hello-cube@workspace:examples/tutorials/hello-cube" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9845,12 +9845,12 @@ __metadata: dependencies: "@loaders.gl/core": "npm:^4.2.0" "@loaders.gl/gltf": "npm:^4.2.0" - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/gltf": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/gltf": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9861,10 +9861,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-hello-instancing-high@workspace:examples/tutorials/hello-instancing" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" languageName: unknown @@ -9874,11 +9874,11 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-hello-triangle@workspace:examples/tutorials/hello-triangle-geometry" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" languageName: unknown @@ -9888,11 +9888,11 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-instancing@workspace:examples/showcase/instancing" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9903,10 +9903,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-lighting@workspace:examples/tutorials/lighting" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9917,10 +9917,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-persistence@workspace:examples/showcase/persistence" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9931,10 +9931,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-shader-hooks@workspace:examples/tutorials/shader-hooks" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" languageName: unknown @@ -9944,10 +9944,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-shader-modules@workspace:examples/tutorials/shader-modules" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" languageName: unknown @@ -9957,10 +9957,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-texture-3d@workspace:examples/api/texture-3d" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgl": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgl": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9971,10 +9971,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-webgpu-computeboids@workspace:examples/webgpu/computeboids" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -9986,10 +9986,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-webgpu-hello-triangle@workspace:examples/tutorials/hello-triangle" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -10000,10 +10000,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-webgpu-instance-uniforms@workspace:examples/tutorials/hello-instanced-cubes" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -10014,10 +10014,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-webgpu-rotating-cube@workspace:examples/wip/rotating-cube" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -10028,10 +10028,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-webgpu-textured-cube@workspace:examples/webgpu/textured-cube" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0" @@ -10042,10 +10042,10 @@ __metadata: version: 0.0.0-use.local resolution: "luma.gl-examples-webgpu-two-cubes@workspace:examples/tutorials/hello-two-cubes" dependencies: - "@luma.gl/core": "npm:9.1.0-alpha.1" - "@luma.gl/engine": "npm:9.1.0-alpha.1" - "@luma.gl/shadertools": "npm:9.1.0-alpha.1" - "@luma.gl/webgpu": "npm:9.1.0-alpha.1" + "@luma.gl/core": "npm:9.1.0-alpha.2" + "@luma.gl/engine": "npm:9.1.0-alpha.2" + "@luma.gl/shadertools": "npm:9.1.0-alpha.2" + "@luma.gl/webgpu": "npm:9.1.0-alpha.2" "@math.gl/core": "npm:^4.0.0" typescript: "npm:^5.3.0" vite: "npm:^5.0.0"