
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
@spatialpack/sdk
Advanced tools
TypeScript SDK for SpatialPack — analyze, optimize, and validate glTF / GLB / USDZ assets, dedup texture batches, round-trip USDA ↔ USDC, run safety-gated visual-diff, and ingest Gaussian splats.
TypeScript SDK for SpatialPack.
Wraps the @spatialpack/core pipeline so Node.js integrators can:
.glb.zip archive"type": "module"). Use dynamic import('@spatialpack/sdk')
from CommonJS, or run your project with "type": "module" and .mjs
/ TypeScript-with-ESM.pnpm add @spatialpack/sdk
# or
npm install @spatialpack/sdk
# or
yarn add @spatialpack/sdk
The SDK transparently depends on @spatialpack/core (installed
automatically). client.visualDiff(...) additionally requires the
optional @spatialpack/cli binary on PATH (or pass a custom
cliPath) — install it with pnpm add -D @spatialpack/cli if you
need it.
SpatialPackClient)import { SpatialPackClient } from '@spatialpack/sdk';
const client = new SpatialPackClient({ defaultPreset: 'web-mobile' });
// analyze
const report = await client.analyze('hero.glb');
// optimize with real-time progress (SPEC-0092)
const opt = await client.optimize('hero.glb', {
outPath: 'out.glb',
onProgress: (e) => console.log(e.kind, e),
});
// conformance vs USDZ delivery rules
const conf = await client.conformance('hero.glb', { target: 'apple-ar' });
The previous v0.1.0 named exports (analyze, optimize,
conformance, ...) remain fully supported. New code should prefer
SpatialPackClient because it gives you a single place to set
defaults (default preset, custom CLI path) without threading them
through every call site.
const report = await client.dedupTextures(
['a.glb', 'b.glb', 'c.glb'],
{ outDir: 'out', minOccurrences: 2 },
);
console.log(`saved ${report.savedBytes} bytes (${(report.ratio * 100).toFixed(1)}% of original)`);
const bundle = client.bundleGlbZip({
primaryPath: 'a.glb',
sidecarPaths: ['out/textures/abc123.png'],
outputPath: 'a.glb.zip',
});
const back = client.unbundleGlbZip({
bundlePath: 'a.glb.zip',
outDir: 'unpacked',
});
// USDC → USDA (mirrors `usdcat` from the Pixar USD toolkit).
const usda = client.usdcFileToUsda('asset.usdc');
// USDA → USDC.
const usdc = client.usdaToUsdc(usda);
// Compose a stage from a root layer + sublayer search roots.
const stage = client.composeStageFromFile('root.usda', {
layerRoots: ['layers/'],
});
console.log('layer stack (strongest first):', stage.layerStack);
import { AssetEmbeddingIndex } from '@spatialpack/sdk';
// 1. Embed one asset.
const emb = await client.embed('hero.glb');
// 2. Build an index across a directory tree.
const index = await client.buildEmbeddingIndex('corpus/', { recursive: true });
client.saveEmbeddingIndex(index, 'corpus/embedding-index.json');
// 3. Top-K nearest neighbors.
const similar = await client.findSimilar('hero.glb', index, {
k: 5,
excludeQueryFromResults: true,
});
// 4. Seed a recipe search from neighbors' cached winners.
const seeds = await client.seedRecipesFromNeighbors(
'hero.glb',
index,
(id) => recipeCache.get(id) ?? null, // host-provided lookup
{ k: 5 },
);
console.log(`${seeds.cacheHits}/${seeds.k} neighbors had cached recipes`);
const search = await client.recipeSearch('hero.glb', {
outPath: 'winner.glb',
searchStrategy: 'multi-fidelity-tpe',
seedRecipes: seeds.seedRecipes,
maxRecipes: 12,
});
import {
buildAssetVerdict,
gateAssetMetrics,
summarizeAssetVerdicts,
} from '@spatialpack/sdk';
// Score your own visual-diff metric bundle against cohort thresholds:
const verdict = buildAssetVerdict({
assetId: 'hero',
cohortTags: { textureCohort: 'textured', animationCohort: 'static', polyCohort: 'medium' },
metrics: { ssim: 0.98, deltaE94Mean: 0.7, edgeDelta: 0.02 },
});
// Or run the full CLI orchestrator (spawns nested `spatialpack` invocations):
const result = await client.safetyGate({
featureId: 'spec-foo',
cohort: 'static-props',
reportDir: 'reports/spec-foo',
});
if (result.exitCode !== 0) throw new Error('safety-gate failed');
Visual-diff requires Playwright. The SDK doesn't import Playwright
because @spatialpack/core MUST NOT depend on it (per the repo
CLAUDE.md). Instead, the SDK spawns the spatialpack CLI binary and
parses the JSON report:
const vd = await client.visualDiff({
beforePath: 'before.glb',
afterPath: 'after.glb',
outDir: 'visual-diff-out',
threshold: 0.05,
});
console.log(`exit ${vd.exitCode}`);
A JS-native renderer (headless three.js) is on the SPEC-0093 Phase 2
roadmap; until it lands, client.visualDiff(...) requires
spatialpack on PATH (or pass cliPath).
const sig = client.phashSignature(views); // views: [{ label, png }]
const baseline = parsePhashSignature(fs.readFileSync('phash-signature.json'));
const cmp = client.phashCompare(baseline, sig);
if (cmp.action === 'skip-diff') {
// ~50ms triage replaces a 10-20s visual-diff (200-400× speedup).
return { pass: true };
}
const splat = client.parseSplat('polycam-export.ply');
const glb = client.wrapSplat(splat, { center: true, shOrder: 2 });
fs.writeFileSync('splat.glb', glb);
The SDK re-exports every public type from @spatialpack/core so you
don't need to import from two packages:
AnalyzeReport, OptimizationReport, PresetId,
OptimizeProgressEvent, OptimizeProgressCallbackConformanceReport, ConformanceTargetSplatInput, SplatWrapOptions, ParsePlyOptionsFrameCostPredictionMultiViewPhashSignature, MultiViewPhashComparisonSourceTextureDedupReport, GlbZipManifest, BundleInput,
UnbundleResultComposedStageSafetyGateReport, SafetyGateAssetMetrics,
SafetyGateAssetVerdict, CohortTags, CohortConfig,
SafetyGateFeatureToggle, SafetyGateFeatureConfigAssetEmbedding, EmbeddingSource, SimilarAsset,
SimilarityResult, SeedRecipesFromNeighborsResult,
InheritedRecipeNeighbor, RecipeLookupRecipeSearchReport, RunRecipeSearchOptions,
RecipeCandidate, RecipeRunResult, RecipeWinnerStrategypackages/sdk/examples/ ships runnable scripts:
optimize-one.mjs — optimize a corpus GLB with progress eventsdedup-batch.mjs — dedup textures across the first 6 corpus assetsusdc-to-usda.mjs — USDC ↔ USDA round-triprecipe-search-with-inheritance.mjs — k-NN seed feedglb-zip-roundtrip.mjs — bundle + unbundlenode packages/sdk/examples/optimize-one.mjs
SpatialPackClient| Method | What it does |
|---|---|
analyze(input) | Full structured analyze report. |
optimize(input, opts) | Run the pipeline + return report + optimized GLB bytes (SPEC-0092). |
conformance(input, opts) | Web / Apple-AR conformance check (SPEC-0067). |
predictFrameCost(input) | SPEC-0068 frame-cost prediction. |
dedupTextures(paths, opts) | SPEC-0091 batch texture dedup. |
bundleGlbZip(input) | Bundle GLB + sidecars as .glb.zip. |
unbundleGlbZip(input) | Unbundle .glb.zip back to GLB + sidecars. |
usdcFileToUsda(path) | USDC → USDA (SPEC-0076 Phase G). |
usdaToUsdc(text) | USDA → USDC. |
composeStackFromFile(path, opt) | Compose a USD layer stack (SPEC-USD-Comp.1). |
embed(input, opts) | SPEC-0087 asset embedding. |
buildEmbeddingIndex(dir, opts) | Build a k-NN index across a directory. |
findSimilar(input, index, opts) | Top-K nearest neighbors. |
seedRecipesFromNeighbors(...) | Inherit recipe winners from neighbors. |
recipeSearch(input, opts) | SPEC-0072 recipe search with progress callbacks. |
safetyGate(opts) | SPEC-0090 orchestrator (spawns CLI subprocesses). |
visualDiff(opts) | SPEC-0093 visual-diff (requires @spatialpack/cli). |
phashSignature(views) | SPEC-0062 multi-view perceptual hash. |
phashCompare(baseline, sig) | Compare phash signatures for CI short-circuit. |
parseSplat(input, opts) | Parse Polycam / Luma / Niantic Gaussian-splat PLY. |
wrapSplat(input, opts) | Wrap a splat as glTF GLB. |
For pure-data work without instantiating a client:
buildAssetVerdict, gateAssetMetrics, summarizeAssetVerdicts,
expandCohort, validateFeatureToggle, renderSafetyGateMarkdown
(SPEC-0090)serializePhashSignature, parsePhashSignature (SPEC-0062)AssetEmbeddingIndex class (SPEC-0087)normalizeInput, withNormalizedInput, toBytes (shared)SDK_VERSION (string)See the source of packages/sdk/src/index.ts for the full re-export
manifest.
The SDK shape is locked by SPEC-0095.
The companion runtime SDK (@spatialpack/runtime, browser-side LOD +
progressive + imposter) is SPEC-0081.
SDK_VERSION is exported as a constant. The SDK and @spatialpack/core
ship together; pin both to the same minor version.
See CHANGELOG.md for the version-by-version surface delta.
The SDK lives in the SpatialPack monorepo
at packages/sdk/. To work on it locally:
git clone https://github.com/montabano1/SpatialPack.git
cd SpatialPack
pnpm install
pnpm --filter @spatialpack/core build
pnpm --filter @spatialpack/sdk build
pnpm --filter @spatialpack/sdk test
Open an issue at https://github.com/montabano1/SpatialPack/issues before sending non-trivial PRs so we can keep the spec catalog authoritative.
MIT © Michael Montalbano.
FAQs
TypeScript SDK for SpatialPack — analyze, optimize, and validate glTF / GLB / USDZ assets, dedup texture batches, round-trip USDA ↔ USDC, run safety-gated visual-diff, and ingest Gaussian splats.
The npm package @spatialpack/sdk receives a total of 11 weekly downloads. As such, @spatialpack/sdk popularity was classified as not popular.
We found that @spatialpack/sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.