New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@luma.gl/core

Package Overview
Dependencies
Maintainers
7
Versions
253
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@luma.gl/core - npm Package Compare versions

Comparing version 9.0.0-alpha.33 to 9.0.0-alpha.34

dist/adapter/types/buffer-layout.d.ts

7

dist/adapter/attribute-utils/get-attribute-from-layouts.d.ts

@@ -1,2 +0,3 @@

import type { ShaderLayout, BufferLayout } from '../types/shader-layout';
import type { ShaderLayout } from '../types/shader-layout';
import type { BufferLayout } from '../types/buffer-layout';
import type { ShaderDataType, ShaderAttributeType } from '../types/shader-formats';

@@ -7,3 +8,3 @@ import type { VertexFormat, VertexType } from '../types/vertex-formats';

/** Attribute name */
name: string;
attributeName: string;
/** Location in shader */

@@ -20,3 +21,3 @@ location: number;

/** BufferName */
bufferName: String;
bufferName: string;
/** Format of buffer data */

@@ -23,0 +24,0 @@ vertexFormat: VertexFormat;

@@ -21,4 +21,4 @@ import { log } from "../../lib/utils/log.js";

return {
name,
bufferName: (bufferMapping === null || bufferMapping === void 0 ? void 0 : bufferMapping.name) || name,
attributeName: (bufferMapping === null || bufferMapping === void 0 ? void 0 : bufferMapping.attributeName) || shaderDeclaration.name,
bufferName: (bufferMapping === null || bufferMapping === void 0 ? void 0 : bufferMapping.bufferName) || shaderDeclaration.name,
location: shaderDeclaration.location,

@@ -41,38 +41,63 @@ shaderType: shaderDeclaration.type,

if (!attribute) {
log.warn("shader layout attribute \"".concat(name, "\" not present in shader"));
log.warn(`shader layout attribute "${name}" not present in shader`);
}
return attribute || null;
}
function getAttributeFromBufferLayout(bufferLayout, name) {
for (const bufferMapping of bufferLayout) {
if (bufferMapping.name === name) {
function getAttributeFromBufferLayout(bufferLayouts, name) {
checkBufferLayouts(bufferLayouts);
let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name);
if (bufferLayoutInfo) {
return bufferLayoutInfo;
}
bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name);
if (bufferLayoutInfo) {
return bufferLayoutInfo;
}
log.warn(`layout for attribute "${name}" not present in buffer layout`);
return null;
}
function checkBufferLayouts(bufferLayouts) {
for (const bufferLayout of bufferLayouts) {
if (bufferLayout.attributes && bufferLayout.format || !bufferLayout.attributes && !bufferLayout.format) {
log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`);
}
}
}
function getAttributeFromShortHand(bufferLayouts, name) {
for (const bufferLayout of bufferLayouts) {
if (bufferLayout.format && bufferLayout.name === name) {
return {
name: bufferMapping.name,
attributeName: bufferLayout.name,
bufferName: name,
vertexFormat: bufferMapping.format,
byteOffset: bufferMapping.byteOffset || 0,
byteStride: bufferMapping.byteStride || 0
stepMode: bufferLayout.stepMode,
vertexFormat: bufferLayout.format,
byteOffset: 0,
byteStride: bufferLayout.byteStride || 0
};
}
let nextByteOffset = bufferMapping.byteOffset || 0;
let byteStride = 0;
for (const interleavedMapping of bufferMapping.attributes || []) {
const info = decodeVertexFormat(interleavedMapping.format);
byteStride += info.byteLength;
}
for (const interleavedMapping of bufferMapping.attributes || []) {
const byteOffset = nextByteOffset;
nextByteOffset += (interleavedMapping === null || interleavedMapping === void 0 ? void 0 : interleavedMapping.byteStrideOffset) || decodeVertexFormat(interleavedMapping.format).byteLength;
if (interleavedMapping.name === name) {
return {
name: bufferMapping.name,
bufferName: name,
vertexFormat: interleavedMapping.format,
byteOffset,
byteStride: bufferMapping.byteStride || byteStride
};
}
return null;
}
function getAttributeFromAttributesList(bufferLayouts, name) {
for (const bufferLayout of bufferLayouts) {
var _bufferLayout$attribu;
let byteStride = bufferLayout.byteStride;
if (typeof bufferLayout.byteStride !== 'number') {
for (const attributeMapping of bufferLayout.attributes || []) {
const info = decodeVertexFormat(attributeMapping.format);
byteStride += info.byteLength;
}
}
const attributeMapping = (_bufferLayout$attribu = bufferLayout.attributes) === null || _bufferLayout$attribu === void 0 ? void 0 : _bufferLayout$attribu.find(mapping => mapping.attribute === name);
if (attributeMapping) {
return {
attributeName: attributeMapping.attribute,
bufferName: bufferLayout.name,
stepMode: bufferLayout.stepMode,
vertexFormat: attributeMapping.format,
byteOffset: attributeMapping.byteOffset,
byteStride
};
}
}
log.warn("layout for attribute \"".concat(name, "\" not present in buffer layout"));
return null;

@@ -90,3 +115,3 @@ }

if (!baseAttribute) {
log.warn("shader layout attribute ".concat(attribute.name, " not present in shader"));
log.warn(`shader layout attribute ${attribute.name} not present in shader`);
} else {

@@ -93,0 +118,0 @@ baseAttribute.type = attribute.type || baseAttribute.type;

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { isBrowser } from '@probe.gl/env';

@@ -22,17 +21,17 @@ import { log } from "../lib/utils/log.js";

constructor(props) {
_defineProperty(this, "device", void 0);
_defineProperty(this, "id", void 0);
_defineProperty(this, "props", void 0);
_defineProperty(this, "canvas", void 0);
_defineProperty(this, "htmlCanvas", void 0);
_defineProperty(this, "offscreenCanvas", void 0);
_defineProperty(this, "type", void 0);
_defineProperty(this, "width", 1);
_defineProperty(this, "height", 1);
_defineProperty(this, "resizeObserver", void 0);
_defineProperty(this, "_canvasSizeInfo", {
this.device = void 0;
this.id = void 0;
this.props = void 0;
this.canvas = void 0;
this.htmlCanvas = void 0;
this.offscreenCanvas = void 0;
this.type = void 0;
this.width = 1;
this.height = 1;
this.resizeObserver = void 0;
this._canvasSizeInfo = {
clientWidth: 0,
clientHeight: 0,
devicePixelRatio: 1
});
};
this.props = {

@@ -180,3 +179,3 @@ ...DEFAULT_CANVAS_CONTEXT_PROPS,

}
_defineProperty(CanvasContext, "pageLoaded", getPageLoadPromise());
CanvasContext.pageLoaded = getPageLoadPromise();
function getPageLoadPromise() {

@@ -194,6 +193,6 @@ if (isPageLoaded() || typeof window === 'undefined') {

if (!element && !isPageLoaded()) {
throw new Error("Accessing '".concat(container, "' before page was loaded"));
throw new Error(`Accessing '${container}' before page was loaded`);
}
if (!element) {
throw new Error("".concat(container, " is not an HTML element"));
throw new Error(`${container} is not an HTML element`);
}

@@ -209,6 +208,6 @@ return element;

if (!canvas && !isPageLoaded()) {
throw new Error("Accessing '".concat(canvasId, "' before page was loaded"));
throw new Error(`Accessing '${canvasId}' before page was loaded`);
}
if (!(canvas instanceof HTMLCanvasElement)) {
throw new Error("'".concat(canvas, "' is not a canvas element"));
throw new Error(`'${canvas}' is not a canvas element`);
}

@@ -226,4 +225,4 @@ return canvas;

targetCanvas.height = height || 1;
targetCanvas.style.width = Number.isFinite(width) ? "".concat(width, "px") : '100%';
targetCanvas.style.height = Number.isFinite(height) ? "".concat(height, "px") : '100%';
targetCanvas.style.width = Number.isFinite(width) ? `${width}px` : '100%';
targetCanvas.style.height = Number.isFinite(height) ? `${height}px` : '100%';
return targetCanvas;

@@ -230,0 +229,0 @@ }

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -28,10 +27,10 @@ import { VERSION } from "../init.js";

constructor(props) {
_defineProperty(this, "id", void 0);
_defineProperty(this, "statsManager", lumaStats);
_defineProperty(this, "props", void 0);
_defineProperty(this, "userData", {});
_defineProperty(this, "_lumaData", {});
_defineProperty(this, "info", void 0);
_defineProperty(this, "lost", void 0);
_defineProperty(this, "canvasContext", void 0);
this.id = void 0;
this.statsManager = lumaStats;
this.props = void 0;
this.userData = {};
this._lumaData = {};
this.info = void 0;
this.lost = void 0;
this.canvasContext = void 0;
this.props = {

@@ -60,3 +59,3 @@ ...DEFAULT_DEVICE_PROPS,

if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
return {
props = {
data: props

@@ -73,2 +72,4 @@ };

newProps.indexType = 'uint16';
} else {
log.warn('indices buffer content must be of integer type')();
}

@@ -79,3 +80,3 @@ }

}
_defineProperty(Device, "VERSION", VERSION);
Device.VERSION = VERSION;
//# sourceMappingURL=device.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -21,5 +20,5 @@ import { Resource } from "./resource.js";

super(device, deducedProps, Buffer.defaultProps);
_defineProperty(this, "usage", void 0);
_defineProperty(this, "indexType", void 0);
_defineProperty(this, "byteLength", void 0);
this.usage = void 0;
this.indexType = void 0;
this.byteLength = void 0;
this.usage = props.usage || 0;

@@ -38,3 +37,3 @@ this.indexType = deducedProps.indexType;

}
_defineProperty(Buffer, "defaultProps", {
Buffer.defaultProps = {
...Resource.defaultProps,

@@ -47,13 +46,13 @@ usage: 0,

mappedAtCreation: false
});
_defineProperty(Buffer, "MAP_READ", 0x01);
_defineProperty(Buffer, "MAP_WRITE", 0x02);
_defineProperty(Buffer, "COPY_SRC", 0x0004);
_defineProperty(Buffer, "COPY_DST", 0x0008);
_defineProperty(Buffer, "INDEX", 0x0010);
_defineProperty(Buffer, "VERTEX", 0x0020);
_defineProperty(Buffer, "UNIFORM", 0x0040);
_defineProperty(Buffer, "STORAGE", 0x0080);
_defineProperty(Buffer, "INDIRECT", 0x0100);
_defineProperty(Buffer, "QUERY_RESOLVE", 0x0200);
};
Buffer.MAP_READ = 0x01;
Buffer.MAP_WRITE = 0x02;
Buffer.COPY_SRC = 0x0004;
Buffer.COPY_DST = 0x0008;
Buffer.INDEX = 0x0010;
Buffer.VERTEX = 0x0020;
Buffer.UNIFORM = 0x0040;
Buffer.STORAGE = 0x0080;
Buffer.INDIRECT = 0x0100;
Buffer.QUERY_RESOLVE = 0x0200;
//# sourceMappingURL=buffer.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -13,5 +12,5 @@ import { Resource } from "./resource.js";

}
_defineProperty(CommandBuffer, "defaultProps", {
CommandBuffer.defaultProps = {
...Resource.defaultProps
});
};
//# sourceMappingURL=command-buffer.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -16,6 +15,6 @@ import { Resource } from "./resource.js";

}
_defineProperty(CommandEncoder, "defaultProps", {
CommandEncoder.defaultProps = {
...Resource.defaultProps,
measureExecutionTime: undefined
});
};
//# sourceMappingURL=command-encoder.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -13,5 +12,5 @@ import { Resource } from "./resource.js";

}
_defineProperty(ComputePass, "defaultProps", {
ComputePass.defaultProps = {
...Resource.defaultProps
});
};
//# sourceMappingURL=compute-pass.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -11,6 +10,6 @@ import { Resource } from "./resource.js";

super(device, props, ComputePipeline.defaultProps);
_defineProperty(this, "hash", '');
this.hash = '';
}
}
_defineProperty(ComputePipeline, "defaultProps", {
ComputePipeline.defaultProps = {
...Resource.defaultProps,

@@ -21,3 +20,3 @@ cs: undefined,

shaderLayout: []
});
};
//# sourceMappingURL=compute-pipeline.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -13,7 +12,7 @@ import { Resource } from "./resource.js";

}
_defineProperty(ExternalTexture, "defaultProps", {
ExternalTexture.defaultProps = {
...Resource.defaultProps,
source: null,
colorSpace: 'srgb'
});
};
//# sourceMappingURL=external-texture.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -14,6 +13,6 @@ import { Resource } from "./resource.js";

super(device, props, Framebuffer.defaultProps);
_defineProperty(this, "width", void 0);
_defineProperty(this, "height", void 0);
_defineProperty(this, "colorAttachments", []);
_defineProperty(this, "depthStencilAttachment", null);
this.width = void 0;
this.height = void 0;
this.colorAttachments = [];
this.depthStencilAttachment = null;
this.width = this.props.width;

@@ -31,3 +30,3 @@ this.height = this.props.height;

if (updateSize) {
log.log(2, "Resizing framebuffer ".concat(this.id, " to ").concat(this.width, "x").concat(this.height))();
log.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)();
this.resizeAttachments(this.width, this.height);

@@ -98,3 +97,3 @@ }

}
_defineProperty(Framebuffer, "defaultProps", {
Framebuffer.defaultProps = {
...Resource.defaultProps,

@@ -105,3 +104,3 @@ width: 1,

depthStencilAttachment: null
});
};
//# sourceMappingURL=framebuffer.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -13,3 +12,3 @@ import { Resource } from "./resource.js";

}
_defineProperty(RenderPass, "defaultProps", {
RenderPass.defaultProps = {
...Resource.defaultProps,

@@ -24,3 +23,3 @@ framebuffer: null,

discard: false
});
};
//# sourceMappingURL=render-pass.js.map

@@ -5,3 +5,4 @@ import type { Device } from '../device';

import type { PrimitiveTopology, RenderPipelineParameters } from '../types/parameters';
import type { ShaderLayout, BufferLayout, Binding } from '../types/shader-layout';
import type { ShaderLayout, Binding } from '../types/shader-layout';
import type { BufferLayout } from '../types/buffer-layout';
import { Resource, ResourceProps } from './resource';

@@ -8,0 +9,0 @@ import type { Buffer } from './buffer';

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -11,8 +10,8 @@ import { Resource } from "./resource.js";

super(device, props, RenderPipeline.defaultProps);
_defineProperty(this, "hash", '');
_defineProperty(this, "vs", void 0);
_defineProperty(this, "fs", void 0);
this.hash = '';
this.vs = void 0;
this.fs = void 0;
}
}
_defineProperty(RenderPipeline, "defaultProps", {
RenderPipeline.defaultProps = {
...Resource.defaultProps,

@@ -35,3 +34,3 @@ vs: null,

uniforms: {}
});
};
//# sourceMappingURL=render-pipeline.js.map

@@ -1,13 +0,12 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { uid } from "../../lib/utils/utils.js";
export class Resource {
constructor(device, props, defaultProps) {
_defineProperty(this, "id", void 0);
_defineProperty(this, "props", void 0);
_defineProperty(this, "userData", {});
_defineProperty(this, "device", void 0);
_defineProperty(this, "_device", void 0);
_defineProperty(this, "destroyed", false);
_defineProperty(this, "allocatedBytes", 0);
_defineProperty(this, "_attachedResources", new Set());
this.id = void 0;
this.props = void 0;
this.userData = {};
this.device = void 0;
this._device = void 0;
this.destroyed = false;
this.allocatedBytes = 0;
this._attachedResources = new Set();
if (!device) {

@@ -32,3 +31,3 @@ throw new Error('no device');

toString() {
return "".concat(this[Symbol.toStringTag] || this.constructor.name, "(").concat(this.id, ")");
return `${this[Symbol.toStringTag] || this.constructor.name}(${this.id})`;
}

@@ -63,3 +62,3 @@ getProps() {

const name = this[Symbol.toStringTag];
stats.get("".concat(name, "s Active")).decrementCount();
stats.get(`${name}s Active`).decrementCount();
}

@@ -70,3 +69,3 @@ trackAllocatedMemory(bytes) {

stats.get('GPU Memory').addCount(bytes);
stats.get("".concat(name, " Memory")).addCount(bytes);
stats.get(`${name} Memory`).addCount(bytes);
this.allocatedBytes = bytes;

@@ -78,3 +77,3 @@ }

stats.get('GPU Memory').subtractCount(this.allocatedBytes);
stats.get("".concat(name, " Memory")).subtractCount(this.allocatedBytes);
stats.get(`${name} Memory`).subtractCount(this.allocatedBytes);
this.allocatedBytes = 0;

@@ -86,11 +85,11 @@ }

stats.get('Resources Created').incrementCount();
stats.get("".concat(name, "s Created")).incrementCount();
stats.get("".concat(name, "s Active")).incrementCount();
stats.get(`${name}s Created`).incrementCount();
stats.get(`${name}s Active`).incrementCount();
}
}
_defineProperty(Resource, "defaultProps", {
Resource.defaultProps = {
id: 'undefined',
handle: undefined,
userData: undefined
});
};
function selectivelyMerge(props, defaultProps) {

@@ -97,0 +96,0 @@ const mergedProps = {

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -13,3 +12,3 @@ import { Resource } from "./resource.js";

}
_defineProperty(Sampler, "defaultProps", {
Sampler.defaultProps = {
...Resource.defaultProps,

@@ -27,3 +26,3 @@ type: 'color-sampler',

maxAnisotropy: 1
});
};
//# sourceMappingURL=sampler.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -11,4 +10,4 @@ import { Resource } from "./resource.js";

super(device, props, Shader.defaultProps);
_defineProperty(this, "stage", void 0);
_defineProperty(this, "source", void 0);
this.stage = void 0;
this.source = void 0;
this.stage = this.props.stage;

@@ -18,3 +17,3 @@ this.source = this.props.source;

}
_defineProperty(Shader, "defaultProps", {
Shader.defaultProps = {
...Resource.defaultProps,

@@ -26,3 +25,3 @@ stage: 'vertex',

shaderType: 0
});
};
//# sourceMappingURL=shader.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
let _Symbol$toStringTag;

@@ -12,8 +11,8 @@ import { Resource } from "./resource.js";

super(device, props, defaultProps);
_defineProperty(this, "dimension", void 0);
_defineProperty(this, "format", void 0);
_defineProperty(this, "width", void 0);
_defineProperty(this, "height", void 0);
_defineProperty(this, "depth", void 0);
_defineProperty(this, "sampler", void 0);
this.dimension = void 0;
this.format = void 0;
this.width = void 0;
this.height = void 0;
this.depth = void 0;
this.sampler = void 0;
this.dimension = this.props.dimension;

@@ -26,3 +25,3 @@ this.format = this.props.format;

}
_defineProperty(Texture, "defaultProps", {
Texture.defaultProps = {
...Resource.defaultProps,

@@ -42,8 +41,8 @@ data: null,

type: undefined
});
_defineProperty(Texture, "COPY_SRC", 0x01);
_defineProperty(Texture, "COPY_DST", 0x02);
_defineProperty(Texture, "TEXTURE_BINDING", 0x04);
_defineProperty(Texture, "STORAGE_BINDING", 0x08);
_defineProperty(Texture, "RENDER_ATTACHMENT", 0x10);
};
Texture.COPY_SRC = 0x01;
Texture.COPY_DST = 0x02;
Texture.TEXTURE_BINDING = 0x04;
Texture.STORAGE_BINDING = 0x08;
Texture.RENDER_ATTACHMENT = 0x10;
//# sourceMappingURL=texture.js.map

@@ -34,3 +34,3 @@ export function decodeShaderAttributeType(attributeType) {

}
return "".concat(vertexType, "x").concat(components);
return `${vertexType}x${components}`;
}

@@ -37,0 +37,0 @@ const TYPE_INFO = {

@@ -8,3 +8,3 @@ import { decodeVertexType } from "./decode-data-type.js";

if (format) {
const dataType = "".concat(type).concat(length);
const dataType = `${type}${length}`;
const decodedType = decodeVertexType(dataType);

@@ -91,3 +91,3 @@ return {

if (!data) {
throw new Error("Unknown format ".concat(format));
throw new Error(`Unknown format ${format}`);
}

@@ -94,0 +94,0 @@ return {

import type { TextureFormat } from '../types/texture-formats';
import type { VertexFormat } from './vertex-formats';
import type { ShaderUniformType, ShaderAttributeType } from './shader-formats';

@@ -21,5 +20,5 @@ import { AccessorObject } from '../types/accessor';

attributes: [
{name: 'instancePositions', location: 0, format: 'float32x2', stepMode: 'instance'},
{name: 'instanceVelocities', location: 1, format: 'float32x2', stepMode: 'instance'},
{name: 'vertexPositions', location: 2, format: 'float32x2', stepMode: 'vertex'}
{name: 'instancePositions', location: 0, format: 'vec3<f32>', stepMode: 'instance'},
{name: 'instanceVelocities', location: 1, format: 'vec3<f32>', stepMode: 'instance'},
{name: 'vertexPositions', location: 2, format: 'vec3<f32>', stepMode: 'vertex'}
],

@@ -54,68 +53,2 @@ bindings: [...]

};
/**
* A BufferLayout complements the static structure in a ShaderLayout with information
* about the dynamic memory layout of the buffers that will be used with the pipeline.
*
* Provides specific details about the memory layout of the actual buffers
* that will be provided to a `RenderPipeline`.
*/
export type SingleBufferLayout = BufferLayout;
/**
* Specify memory layout for a buffer that is only used by one attribute
* @note Specifies format, stride, offset and step mode
* @note The buffer can be set using the attribute name.
*/
export type BufferLayout = {
/** Name of attribute to adjust */
name: string;
/** vertex format. Auto calculated. @note Needs to match type/components of the ShaderLayout ('f32', 'i32', 's32') */
format?: VertexFormat;
/** offset into buffer. Defaults to `0` */
byteOffset?: number;
/** bytes between successive elements. If omitted, stride is set to reflect a "packed" buffer */
byteStride?: number;
/** Whether the attribute is instanced. @note Only needs to be provided if auto deduction failed. */
stepMode?: 'vertex' | 'instance';
/** Optional: interleaved attributes that read from this buffer */
attributes?: InterleavedAttributeLayout[];
};
/** */
export type InterleavedAttributeLayout = {
/** Name of attribute that maps to an interleaved "view" of this buffer */
name: string;
/** vertex format override, when using formats other than float32 (& uint32, sint32) */
format?: VertexFormat;
/**
* offset into one stride.
* @note additive to the parent's buffer byteOffset
* @note if not supplied, offset for each attribute is auto calculated starting from zero assuming aligned packing
*/
byteStrideOffset?: number;
};
/**
* Map an interleaved buffer whose values
* @note The buffer can be set using the defined buffer name.
*/
/**
* A buffer map is used to specify "non-standard" buffer layouts (buffers with offsets, interleaved buffers etc)
*
* @example
* ```
device.createRenderPipeline({
shaderLayout: shaderLayout,
// interleaved bindings, auto offset
bufferLayout: [
{name: 'interleavedPositions', attributes: [...]}
{name: 'position', byteOffset: 1024}
// single buffer per binding
{name: 'vertexPositions', location: 2, accessor: {format: 'float32x2'}}
// interleaved bindings, auto offset
{name: 'particles', stepMode: 'instance', fields: [
{name: 'instancePositions', location: 0, format: 'float32x4'},
{name: 'instanceVelocities', location: 1, format: 'float32x4'}
]},
]
];
```
*/
/** ShaderLayout for bindings */

@@ -122,0 +55,0 @@ export type BindingDeclaration = UniformBufferBindingLayout | BufferBindingLayout | TextureBindingLayout | SamplerBindingLayout | StorageTextureBindingLayout;

@@ -42,3 +42,3 @@ export { VERSION } from './init';

export type { ShaderLayout, AttributeDeclaration, BindingDeclaration, Binding } from './adapter/types/shader-layout';
export type { BufferLayout } from './adapter/types/shader-layout';
export type { BufferLayout, BufferAttributeLayout } from './adapter/types/buffer-layout';
export type { AttributeBinding, UniformBinding, UniformBlockBinding, VaryingBinding } from './adapter/types/shader-layout';

@@ -45,0 +45,0 @@ export type { UniformValue } from './adapter/types/types';

@@ -39,3 +39,3 @@ export { VERSION } from "./init.js";

export { requestAnimationFrame, cancelAnimationFrame } from "./lib/request-animation-frame.js";
export const glsl = x => "".concat(x);
export const glsl = x => `${x}`;
//# sourceMappingURL=index.js.map

@@ -8,7 +8,7 @@ import { isBrowser } from '@probe.gl/env';

if (globalThis.luma && globalThis.luma.VERSION !== VERSION) {
throw new Error("luma.gl - multiple VERSIONs detected: ".concat(globalThis.luma.VERSION, " vs ").concat(VERSION));
throw new Error(`luma.gl - multiple VERSIONs detected: ${globalThis.luma.VERSION} vs ${VERSION}`);
}
if (!globalThis.luma) {
if (isBrowser()) {
log.log(1, "luma.gl ".concat(VERSION, " - ").concat(STARTUP_MESSAGE))();
log.log(1, `luma.gl ${VERSION} - ${STARTUP_MESSAGE}`)();
}

@@ -15,0 +15,0 @@ globalThis.luma = globalThis.luma || {

@@ -11,7 +11,10 @@ export function formatCompilerLog(shaderLog, source, options) {

if (options !== null && options !== void 0 && options.showSourceCode) {
const positionIndicator = message.linePos > 0 ? "".concat(' '.repeat(message.linePos + 5), "^^^\n") : '';
const positionIndicator = message.linePos > 0 ? `${' '.repeat(message.linePos + 5)}^^^\n` : '';
const numberedLines = getNumberedLines(lines, lineNum);
return "".concat(numberedLines).concat(positionIndicator).concat(message.type.toUpperCase(), ": ").concat(message.message, "\n\n");
return `\
${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.message}
`;
}
return "".concat(message.type.toUpperCase(), ": ").concat(message.message, "\n");
return `${message.type.toUpperCase()}: ${message.message}\n`;
}

@@ -23,3 +26,3 @@ function getNumberedLines(lines, lineNum) {

if (sourceLine !== undefined) {
numberedLines += "".concat(padLeft(String(line), 4), ": ").concat(sourceLine, "\n");
numberedLines += `${padLeft(String(line), 4)}: ${sourceLine}\n`;
}

@@ -26,0 +29,0 @@ }

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { DEFAULT_DEVICE_PROPS } from "../adapter/device.js";

@@ -58,4 +57,4 @@ import { lumaStats } from "./utils/stats-manager.js";

}
_defineProperty(luma, "stats", lumaStats);
_defineProperty(luma, "log", log);
luma.stats = lumaStats;
luma.log = log;
//# sourceMappingURL=luma.js.map

@@ -1,2 +0,1 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { assert } from "./utils/assert.js";

@@ -6,7 +5,7 @@ import { log } from "./utils/log.js";

constructor(layout, blockName) {
_defineProperty(this, "layout", {});
_defineProperty(this, "uniforms", {});
_defineProperty(this, "size", void 0);
_defineProperty(this, "data", void 0);
_defineProperty(this, "typedArray", void 0);
this.layout = {};
this.uniforms = {};
this.size = void 0;
this.data = void 0;
this.typedArray = void 0;
const binding = layout.bindings.find(binding => binding.type === 'uniform' && binding.name === blockName);

@@ -33,3 +32,3 @@ if (!binding) {

} else {
log.warn("Unknown uniform ".concat(key));
log.warn(`Unknown uniform ${key}`);
}

@@ -36,0 +35,0 @@ }

@@ -1,7 +0,6 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { decodeShaderUniformType, alignTo } from "../adapter/type-utils/decode-uniform-type.js";
export class UniformBufferLayout {
constructor(uniforms) {
_defineProperty(this, "layout", {});
_defineProperty(this, "size", 0);
this.layout = {};
this.size = 0;
for (const [key, uniformType] of Object.entries(uniforms)) {

@@ -8,0 +7,0 @@ const typeAndComponents = decodeShaderUniformType(uniformType);

@@ -11,4 +11,4 @@ import { log } from "./log.js";

const replacementProp = removedProps[propName];
const replacement = replacementProp ? "".concat(className, ".").concat(removedProps[propName]) : 'N/A';
log.removed("".concat(className, ".").concat(propName), replacement)();
const replacement = replacementProp ? `${className}.${removedProps[propName]}` : 'N/A';
log.removed(`${className}.${propName}`, replacement)();
}

@@ -19,3 +19,3 @@ }

const replacementProp = deprecatedProps[propName];
log.deprecated("".concat(className, ".").concat(propName), "".concat(className, ".").concat(replacementProp))();
log.deprecated(`${className}.${propName}`, `${className}.${replacementProp}`)();
}

@@ -26,3 +26,3 @@ }

if (propName in props) {
log.deprecated("".concat(className, ".").concat(propName), "".concat(className, ".").concat(replacementProp))();
log.deprecated(`${className}.${propName}`, `${className}.${replacementProp}`)();
newProps = newProps || Object.assign({}, props);

@@ -29,0 +29,0 @@ newProps[replacementProp] = props[propName];

@@ -10,3 +10,3 @@ function formatArrayValue(v) {

if (i > 0) {
string += ",".concat(i % size === 0 ? ' ' : '');
string += `,${i % size === 0 ? ' ' : ''}`;
}

@@ -16,3 +16,3 @@ string += formatValue(v[i], opts);

const terminator = v.length > maxElts ? '...' : ']';
return "".concat(string).concat(terminator);
return `${string}${terminator}`;
}

@@ -19,0 +19,0 @@ export function formatValue(v) {

@@ -23,3 +23,3 @@ let pathPrefix = '';

image.onload = () => resolve(image);
image.onerror = () => reject(new Error("Could not load image ".concat(url, ".")));
image.onerror = () => reject(new Error(`Could not load image ${url}.`));
image.crossOrigin = (opts === null || opts === void 0 ? void 0 : opts.crossOrigin) || 'anonymous';

@@ -45,3 +45,3 @@ image.src = url.startsWith('http') ? url : pathPrefix + url;

script.onload = resolve;
script.onerror = error => reject(new Error("Unable to load script '".concat(scriptUrl, "': ").concat(error)));
script.onerror = error => reject(new Error(`Unable to load script '${scriptUrl}': ${error}`));
head.appendChild(script);

@@ -48,0 +48,0 @@ });

@@ -1,6 +0,5 @@

import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import { Stats } from '@probe.gl/stats';
export class StatsManager {
constructor() {
_defineProperty(this, "stats", new Map());
this.stats = new Map();
}

@@ -7,0 +6,0 @@ getStats(name) {

import { log } from "./log.js";
export function stubRemovedMethods(instance, className, version, methodNames) {
const upgradeMessage = "See luma.gl ".concat(version, " Upgrade Guide at https://luma.gl/docs/upgrade-guide");
const upgradeMessage = `See luma.gl ${version} Upgrade Guide at \
https://luma.gl/docs/upgrade-guide`;
const prototype = Object.getPrototypeOf(instance);

@@ -10,3 +11,3 @@ methodNames.forEach(methodName => {

prototype[methodName] = () => {
log.removed("Calling removed method ".concat(className, ".").concat(methodName, ": "), upgradeMessage)();
log.removed(`Calling removed method ${className}.${methodName}: `, upgradeMessage)();
throw new Error(methodName);

@@ -13,0 +14,0 @@ };

@@ -6,3 +6,3 @@ const uidCounters = {};

const count = uidCounters[id]++;
return "".concat(id, "-").concat(count);
return `${id}-${count}`;
}

@@ -9,0 +9,0 @@ export function isPowerOfTwo(n) {

{
"name": "@luma.gl/core",
"version": "9.0.0-alpha.33",
"version": "9.0.0-alpha.34",
"description": "luma.gl API",

@@ -45,3 +45,3 @@ "license": "MIT",

},
"gitHead": "65a38ac7ed371767303b5ded6cc3d34373e904e3"
"gitHead": "66ab5fe7caa59ef83224a0b7c892e00bd43cbefd"
}
// luma.gl, MIT license
import {log} from '../../lib/utils/log';
import type {ShaderLayout, AttributeDeclaration, BufferLayout} from '../types/shader-layout';
import type {ShaderLayout, AttributeDeclaration} from '../types/shader-layout';
import type {BufferLayout} from '../types/buffer-layout';
import type {ShaderDataType, ShaderAttributeType} from '../types/shader-formats';

@@ -13,3 +14,3 @@ import {decodeShaderAttributeType} from '../type-utils/decode-attribute-type';

/** Attribute name */
name: string;
attributeName: string;
/** Location in shader */

@@ -27,3 +28,3 @@ location: number;

/** BufferName */
bufferName: String;
bufferName: string;
/** Format of buffer data */

@@ -47,2 +48,11 @@ vertexFormat: VertexFormat;

type BufferAttributeInfo = {
attributeName: string;
bufferName: string;
stepMode?: 'vertex' | 'instance';
vertexFormat: VertexFormat;
byteOffset: number;
byteStride: number;
};
export function getAttributeInfosFromLayouts(

@@ -72,3 +82,3 @@ shaderLayout: ShaderLayout,

const shaderDeclaration = getAttributeFromShaderLayout(shaderLayout, name);
const bufferMapping: Partial<AttributeInfo> = getAttributeFromBufferLayout(bufferLayout, name);
const bufferMapping: BufferAttributeInfo = getAttributeFromBufferLayout(bufferLayout, name);

@@ -86,4 +96,4 @@ // TODO should no longer happen

return {
name,
bufferName: bufferMapping?.name || name,
attributeName: bufferMapping?.attributeName || shaderDeclaration.name,
bufferName: bufferMapping?.bufferName || shaderDeclaration.name,
location: shaderDeclaration.location,

@@ -118,44 +128,88 @@ shaderType: shaderDeclaration.type,

function getAttributeFromBufferLayout(
bufferLayout: BufferLayout[],
bufferLayouts: BufferLayout[],
name: string
): Partial<AttributeInfo> | null {
for (const bufferMapping of bufferLayout) {
// If this is the mapping return
if (bufferMapping.name === name) {
): BufferAttributeInfo | null {
// Check that bufferLayouts are valid (each either has format or attribute)
checkBufferLayouts(bufferLayouts);
let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name);
if (bufferLayoutInfo) {
return bufferLayoutInfo;
}
bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name);
if (bufferLayoutInfo) {
return bufferLayoutInfo;
}
// Didn't find...
log.warn(`layout for attribute "${name}" not present in buffer layout`);
return null;
}
/** Check that bufferLayouts are valid (each either has format or attribute) */
function checkBufferLayouts(bufferLayouts: BufferLayout[]) {
for (const bufferLayout of bufferLayouts) {
if (
(bufferLayout.attributes && bufferLayout.format) ||
(!bufferLayout.attributes && !bufferLayout.format)
) {
log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`);
}
}
}
/** Get attribute from format shorthand if specified */
function getAttributeFromShortHand(
bufferLayouts: BufferLayout[],
name: string
): BufferAttributeInfo | null {
for (const bufferLayout of bufferLayouts) {
if (bufferLayout.format && bufferLayout.name === name) {
return {
name: bufferMapping.name,
attributeName: bufferLayout.name,
bufferName: name,
vertexFormat: bufferMapping.format,
byteOffset: bufferMapping.byteOffset || 0,
byteStride: bufferMapping.byteStride || 0
stepMode: bufferLayout.stepMode,
vertexFormat: bufferLayout.format,
// If offset is needed, use `attributes` field.
byteOffset: 0,
byteStride: bufferLayout.byteStride || 0
};
}
}
return null;
}
// Search interleaved attributes for buffer mapping
let nextByteOffset = bufferMapping.byteOffset || 0;
let byteStride = 0;
for (const interleavedMapping of bufferMapping.attributes || []) {
const info = decodeVertexFormat(interleavedMapping.format);
byteStride += info.byteLength;
}
for (const interleavedMapping of bufferMapping.attributes || []) {
const byteOffset = nextByteOffset;
nextByteOffset +=
interleavedMapping?.byteStrideOffset ||
decodeVertexFormat(interleavedMapping.format).byteLength;
// const interleavedMapping = bufferMapping.attributes?.find(attr => attr.name === name);
if (interleavedMapping.name === name) {
return {
name: bufferMapping.name,
bufferName: name,
vertexFormat: interleavedMapping.format,
byteOffset,
byteStride: bufferMapping.byteStride || byteStride
};
/**
* Search attribute mappings (e.g. interleaved attributes) for buffer mapping.
* Not the name of the buffer might be the same as one of the interleaved attributes.
*/
function getAttributeFromAttributesList(
bufferLayouts: BufferLayout[],
name: string
): BufferAttributeInfo | null {
for (const bufferLayout of bufferLayouts) {
let byteStride: number | undefined = bufferLayout.byteStride;
// Calculate a default byte stride if not provided
if (typeof bufferLayout.byteStride !== 'number') {
for (const attributeMapping of bufferLayout.attributes || []) {
const info = decodeVertexFormat(attributeMapping.format);
byteStride += info.byteLength;
}
}
const attributeMapping = bufferLayout.attributes?.find(mapping => mapping.attribute === name);
if (attributeMapping) {
return {
attributeName: attributeMapping.attribute,
bufferName: bufferLayout.name,
stepMode: bufferLayout.stepMode,
vertexFormat: attributeMapping.format,
byteOffset: attributeMapping.byteOffset,
byteStride
};
}
}
// Didn't return...
log.warn(`layout for attribute "${name}" not present in buffer layout`);
return null;

@@ -162,0 +216,0 @@ }

@@ -329,3 +329,3 @@ // luma.gl, MIT license

if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
return {data: props};
props = {data: props};
}

@@ -343,2 +343,4 @@

newProps.indexType = 'uint16';
} else {
log.warn('indices buffer content must be of integer type')();
}

@@ -345,0 +347,0 @@ }

@@ -6,3 +6,4 @@ // luma.gl, MIT license

import type {PrimitiveTopology, RenderPipelineParameters} from '../types/parameters';
import type {ShaderLayout, BufferLayout, Binding} from '../types/shader-layout';
import type {ShaderLayout, Binding} from '../types/shader-layout';
import type {BufferLayout} from '../types/buffer-layout';
// import {normalizeAttributeMap} from '../helpers/attribute-bindings';

@@ -9,0 +10,0 @@ import {Resource, ResourceProps} from './resource';

// luma.gl, MIT license
import type {TextureFormat} from '../types/texture-formats';
import type {VertexFormat} from './vertex-formats';
import type {ShaderUniformType, ShaderAttributeType} from './shader-formats';

@@ -23,5 +22,5 @@ import {AccessorObject} from '../types/accessor';

attributes: [
{name: 'instancePositions', location: 0, format: 'float32x2', stepMode: 'instance'},
{name: 'instanceVelocities', location: 1, format: 'float32x2', stepMode: 'instance'},
{name: 'vertexPositions', location: 2, format: 'float32x2', stepMode: 'vertex'}
{name: 'instancePositions', location: 0, format: 'vec3<f32>', stepMode: 'instance'},
{name: 'instanceVelocities', location: 1, format: 'vec3<f32>', stepMode: 'instance'},
{name: 'vertexPositions', location: 2, format: 'vec3<f32>', stepMode: 'vertex'}
],

@@ -58,136 +57,2 @@ bindings: [...]

// BUFFER LAYOUT
/**
* A BufferLayout complements the static structure in a ShaderLayout with information
* about the dynamic memory layout of the buffers that will be used with the pipeline.
*
* Provides specific details about the memory layout of the actual buffers
* that will be provided to a `RenderPipeline`.
*/
export type SingleBufferLayout = BufferLayout;
/**
* Specify memory layout for a buffer that is only used by one attribute
* @note Specifies format, stride, offset and step mode
* @note The buffer can be set using the attribute name.
*/
export type BufferLayout = {
/** Name of attribute to adjust */
name: string;
/** vertex format. Auto calculated. @note Needs to match type/components of the ShaderLayout ('f32', 'i32', 's32') */
format?: VertexFormat;
/** offset into buffer. Defaults to `0` */
byteOffset?: number;
/** bytes between successive elements. If omitted, stride is set to reflect a "packed" buffer */
byteStride?: number;
/** Whether the attribute is instanced. @note Only needs to be provided if auto deduction failed. */
stepMode?: 'vertex' | 'instance';
/** Optional: interleaved attributes that read from this buffer */
attributes?: InterleavedAttributeLayout[];
};
/** */
export type InterleavedAttributeLayout = {
/** Name of attribute that maps to an interleaved "view" of this buffer */
name: string;
/** vertex format override, when using formats other than float32 (& uint32, sint32) */
format?: VertexFormat;
/**
* offset into one stride.
* @note additive to the parent's buffer byteOffset
* @note if not supplied, offset for each attribute is auto calculated starting from zero assuming aligned packing
*/
byteStrideOffset?: number;
};
/**
* Map an interleaved buffer whose values
* @note The buffer can be set using the defined buffer name.
*/
// export type InterleavedBufferLayout = {
// /** Mark this as interleaved */
// type: 'interleave';
// /** Name of buffer (to which the multiple attributes are to be bound) */
// name: string;
// /** bytes between successive elements. Assumes tight packing if omitted */
// byteStride?: number;
// /** offset into buffer Defaults to `0` */
// byteOffset?: number;
// /** Attributes that read from this buffer */
// attributes: InterleavedAttribute[];
// /** @deprecated Dummy for typing */
// format?: VertexFormat;
// };
/**
* A buffer map is used to specify "non-standard" buffer layouts (buffers with offsets, interleaved buffers etc)
*
* @example
* ```
device.createRenderPipeline({
shaderLayout: shaderLayout,
// interleaved bindings, auto offset
bufferLayout: [
{name: 'interleavedPositions', attributes: [...]}
{name: 'position', byteOffset: 1024}
// single buffer per binding
{name: 'vertexPositions', location: 2, accessor: {format: 'float32x2'}}
// interleaved bindings, auto offset
{name: 'particles', stepMode: 'instance', fields: [
{name: 'instancePositions', location: 0, format: 'float32x4'},
{name: 'instanceVelocities', location: 1, format: 'float32x4'}
]},
]
];
```
*/
// export type BufferLayout = SingleBufferLayout | InterleavedBufferLayout;
// /** Specify stride and offset for a buffer that only handles one attribute*/
// export type SingleBufferLayout = {
// /** Mark this as interleaved */
// type?: 'override';
// /** Name of attribute to adjust */
// name: string;
// /** vertex format override, when using formats other than float32, uint32, sint32 */
// format: VertexFormat;
// /** bytes between successive elements @note `stride` is auto calculated if omitted */
// byteStride?: number;
// /** offset into buffer. Defaults to `0` */
// byteOffset?: number;
// };
// /** Map an interleaved buffer */
// export type InterleavedBufferLayout = {
// /** Mark this as interleaved */
// type: 'interleave';
// /** Name of buffer (to which the multiple attributes are to be bound) */
// name: string;
// /** bytes between successive elements. Assumes tight packing if omitted */
// byteStride?: number;
// /** offset into buffer Defaults to `0` */
// byteOffset?: number;
// /** Attributes that read from this buffer */
// attributes: InterleavedAttribute[];
// /** @deprecated Dummy for typing */
// format?: VertexFormat;
// };
// /** @note Not public: not exported outside of api module */
// export type InterleavedAttribute = {
// /** Name of attribute that maps to an interleaved "view" of this buffer */
// name: string;
// /** vertex format override, when using formats other than float32 (& uint32, sint32) */
// format?: VertexFormat;
// /**
// * offset into one stride.
// * @note additive to the parent's buffer byteOffset
// * @note if not supplied, offset for each attribute is auto calculated starting
// * from zero assuming aligned packing
// */
// byteOffset?: number;
// };
// BINDING LAYOUTS

@@ -194,0 +59,0 @@

@@ -97,3 +97,3 @@ // luma.gl, MIT license

} from './adapter/types/shader-layout';
export type {BufferLayout} from './adapter/types/shader-layout';
export type {BufferLayout, BufferAttributeLayout} from './adapter/types/buffer-layout';
export type {

@@ -100,0 +100,0 @@ // Deprecated, todo

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc