From 1528983d642a39d63afeeada7b92dd954011f227 Mon Sep 17 00:00:00 2001
From: Garrett Johnson
Date: Sun, 15 Mar 2026 14:39:56 +0900
Subject: [PATCH 1/8] Update dts gen
---
package-lock.json | 34 ++-
package.json | 2 +
src/core/plugins/CesiumIonAuthPlugin.d.ts | 12 -
.../plugins/EnforceNonZeroErrorPlugin.d.ts | 1 -
src/core/plugins/GoogleCloudAuthPlugin.d.ts | 11 -
src/core/plugins/GoogleCloudAuthPlugin.js | 2 +-
src/core/plugins/ImplicitTilingPlugin.d.ts | 1 -
src/core/plugins/index.d.ts | 289 +++++++++++++++++-
tsconfig.core-plugins.json | 23 ++
utils/gen-dts.js | 160 ++++++++++
10 files changed, 502 insertions(+), 33 deletions(-)
delete mode 100644 src/core/plugins/CesiumIonAuthPlugin.d.ts
delete mode 100644 src/core/plugins/EnforceNonZeroErrorPlugin.d.ts
delete mode 100644 src/core/plugins/GoogleCloudAuthPlugin.d.ts
delete mode 100644 src/core/plugins/ImplicitTilingPlugin.d.ts
create mode 100644 tsconfig.core-plugins.json
create mode 100644 utils/gen-dts.js
diff --git a/package-lock.json b/package-lock.json
index fffc871ac..88ef90245 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -34,6 +34,8 @@
"leva": "^0.10.0",
"lil-gui": "^0.21.0",
"postprocessing": "^6.36.4",
+ "rollup": "^4.59.0",
+ "rollup-plugin-dts": "^6.4.0",
"three": "^0.170.0",
"typescript": "^5.6.0",
"typescript-eslint": "^8.48.1",
@@ -70,9 +72,9 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.28.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz",
- "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -7259,6 +7261,32 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/rollup-plugin-dts": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.4.0.tgz",
+ "integrity": "sha512-2i00A5UoPCoDecLEs13Eu105QegSGfrbp1sDeUj/54LKGmv6XFHDxWKC6Wsb4BobGUWYVCWWjmjAc8bXXbXH/Q==",
+ "dev": true,
+ "license": "LGPL-3.0-only",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "@jridgewell/sourcemap-codec": "^1.5.5",
+ "convert-source-map": "^2.0.0",
+ "magic-string": "^0.30.21"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/Swatinem"
+ },
+ "optionalDependencies": {
+ "@babel/code-frame": "^7.29.0"
+ },
+ "peerDependencies": {
+ "rollup": "^3.29.4 || ^4",
+ "typescript": "^4.5 || ^5.0 || ^6.0"
+ }
+ },
"node_modules/rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
diff --git a/package.json b/package.json
index 95b22bff4..2711a4617 100644
--- a/package.json
+++ b/package.json
@@ -107,6 +107,8 @@
"leva": "^0.10.0",
"lil-gui": "^0.21.0",
"postprocessing": "^6.36.4",
+ "rollup": "^4.59.0",
+ "rollup-plugin-dts": "^6.4.0",
"three": "^0.170.0",
"typescript": "^5.6.0",
"typescript-eslint": "^8.48.1",
diff --git a/src/core/plugins/CesiumIonAuthPlugin.d.ts b/src/core/plugins/CesiumIonAuthPlugin.d.ts
deleted file mode 100644
index adaeb0e54..000000000
--- a/src/core/plugins/CesiumIonAuthPlugin.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { TilesRendererBase } from '3d-tiles-renderer/core';
-
-export class CesiumIonAuthPlugin {
-
- constructor( options : {
- apiToken: string,
- assetId?: string | null,
- autoRefreshToken?: boolean,
- assetTypeHandler?: ( type: string, tiles: TilesRendererBase, asset: object ) => void,
- } );
-
-}
diff --git a/src/core/plugins/EnforceNonZeroErrorPlugin.d.ts b/src/core/plugins/EnforceNonZeroErrorPlugin.d.ts
deleted file mode 100644
index 2fda59b1b..000000000
--- a/src/core/plugins/EnforceNonZeroErrorPlugin.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export class EnforceNonZeroErrorPlugin {}
diff --git a/src/core/plugins/GoogleCloudAuthPlugin.d.ts b/src/core/plugins/GoogleCloudAuthPlugin.d.ts
deleted file mode 100644
index 803f8bb4a..000000000
--- a/src/core/plugins/GoogleCloudAuthPlugin.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export class GoogleCloudAuthPlugin {
-
- constructor( options: {
- apiToken: string,
- autoRefreshToken?: boolean,
- logoUrl?: string,
- useRecommendedSettings?: boolean;
- sessionOptions?: null | { mapType: string, language: string, region: string, [key: string]: any },
- } );
-
-}
diff --git a/src/core/plugins/GoogleCloudAuthPlugin.js b/src/core/plugins/GoogleCloudAuthPlugin.js
index 9a92999bb..4b38acd94 100644
--- a/src/core/plugins/GoogleCloudAuthPlugin.js
+++ b/src/core/plugins/GoogleCloudAuthPlugin.js
@@ -1,4 +1,4 @@
-import { GoogleCloudAuth } from '3d-tiles-renderer/core/plugins';
+import { GoogleCloudAuth } from './auth/GoogleCloudAuth.js';
import { GoogleAttributionsManager } from './GoogleAttributionsManager.js';
const TILES_3D_API = 'https://tile.googleapis.com/v1/3dtiles/root.json';
diff --git a/src/core/plugins/ImplicitTilingPlugin.d.ts b/src/core/plugins/ImplicitTilingPlugin.d.ts
deleted file mode 100644
index 4ee219bf9..000000000
--- a/src/core/plugins/ImplicitTilingPlugin.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export class ImplicitTilingPlugin {}
diff --git a/src/core/plugins/index.d.ts b/src/core/plugins/index.d.ts
index 84c01d3f2..007996745 100644
--- a/src/core/plugins/index.d.ts
+++ b/src/core/plugins/index.d.ts
@@ -1,4 +1,285 @@
-export * from './CesiumIonAuthPlugin.js';
-export * from './GoogleCloudAuthPlugin.js';
-export * from './ImplicitTilingPlugin.js';
-export * from './EnforceNonZeroErrorPlugin.js';
+import { LoaderBase } from '3d-tiles-renderer/core';
+
+/**
+ * @classdesc
+ * Authentication helper for Cesium Ion. Fetches and caches a bearer token from the
+ * Cesium Ion endpoint and injects it into outgoing requests. Supports optional
+ * automatic token refresh on 4xx responses.
+ */
+declare class CesiumIonAuth {
+ /**
+ * @param {Object} [options={}]
+ * @param {string} options.apiToken
+ * @param {boolean} [options.autoRefreshToken=false]
+ */
+ constructor(options?: {
+ apiToken: string;
+ autoRefreshToken?: boolean;
+ });
+ /**
+ * The Cesium Ion access token.
+ * @type {string}
+ */
+ apiToken: string;
+ /**
+ * Whether to automatically refresh the token on 4xx errors.
+ * @type {boolean}
+ */
+ autoRefreshToken: boolean;
+ /**
+ * The endpoint URL used to fetch the bearer token.
+ * @type {string|null}
+ */
+ authURL: string | null;
+ fetch(url: any, options: any): Promise;
+ refreshToken(options: any): any;
+}
+
+/**
+ * @callback AssetTypeHandlerCallback
+ * @param {string} type - The Cesium Ion asset type (e.g. `'TERRAIN'`, `'GLTF'`, `'CZML'`).
+ * @param {TilesRendererBase} tiles - The tiles renderer instance.
+ * @param {Object} asset - The full asset endpoint JSON response.
+ */
+/**
+ * @classdesc
+ * Plugin for authenticating requests to Cesium Ion. Handles token refresh, asset endpoint
+ * resolution, and attribution collection. Automatically registers a GoogleCloudAuthPlugin
+ * when the resolved asset is an external Google photorealistic tileset.
+ */
+declare class CesiumIonAuthPlugin {
+ /**
+ * @param {Object} options
+ * @param {string} options.apiToken
+ * @param {number|null} [options.assetId=null]
+ * @param {boolean} [options.autoRefreshToken=false]
+ * @param {boolean} [options.useRecommendedSettings=true]
+ * @param {AssetTypeHandlerCallback} [options.assetTypeHandler]
+ */
+ constructor(options?: {
+ apiToken: string;
+ assetId?: number | null;
+ autoRefreshToken?: boolean;
+ useRecommendedSettings?: boolean;
+ assetTypeHandler?: AssetTypeHandlerCallback;
+ });
+ set apiToken(v: string);
+ get apiToken(): string;
+ set autoRefreshToken(v: boolean);
+ get autoRefreshToken(): boolean;
+ name: string;
+ auth: CesiumIonAuth;
+ /**
+ * The Cesium Ion asset ID to load, or null if using an explicit root URL.
+ * @type {number|null}
+ */
+ assetId: number | null;
+ /**
+ * Whether to apply recommended renderer settings for Cesium Ion assets.
+ * @type {boolean}
+ */
+ useRecommendedSettings: boolean;
+ /**
+ * Callback invoked when the resolved Cesium Ion asset type is not `3DTILES`.
+ * @type {AssetTypeHandlerCallback}
+ */
+ assetTypeHandler: AssetTypeHandlerCallback;
+ /**
+ * The TilesRenderer instance this plugin is registered with.
+ * @type {Object|null}
+ */
+ tiles: any | null;
+ init(tiles: any): void;
+ loadRootTileset(): any;
+ preprocessURL(uri: any): any;
+ fetchData(uri: any, options: any): Promise;
+ getAttributions(target: any): void;
+}
+type AssetTypeHandlerCallback = (type: string, tiles: TilesRendererBase, asset: any) => any;
+
+/**
+ * @classdesc
+ * Authentication helper for Google Cloud Maps APIs. Manages session-token creation and
+ * renewal for both the Photorealistic 3D Tiles API and the 2D Map Tiles API, injecting
+ * the API key and session token into outgoing requests.
+ */
+declare class GoogleCloudAuth {
+ /**
+ * @param {Object} [options={}]
+ * @param {string} options.apiToken
+ * @param {Object|null} [options.sessionOptions=null]
+ * @param {boolean} [options.autoRefreshToken=false]
+ */
+ constructor(options?: {
+ apiToken: string;
+ sessionOptions?: any | null;
+ autoRefreshToken?: boolean;
+ });
+ get isMapTilesSession(): boolean;
+ /**
+ * The Google Cloud API key.
+ * @type {string}
+ */
+ apiToken: string;
+ /**
+ * Whether to automatically refresh the session token on 4xx errors.
+ * @type {boolean}
+ */
+ autoRefreshToken: boolean;
+ /**
+ * The endpoint URL used to create or refresh the session token.
+ * @type {string}
+ */
+ authURL: string;
+ /**
+ * The current session token, or null if not yet established.
+ * @type {string|null}
+ */
+ sessionToken: string | null;
+ /**
+ * Session options passed as the POST body when creating a Map Tiles session.
+ * @type {Object|null}
+ */
+ sessionOptions: any | null;
+ fetch(url: any, options: any): Promise;
+ refreshToken(options: any): any;
+}
+
+declare class GoogleAttributionsManager {
+ creditsCount: {};
+ addAttributions(line: any): void;
+ removeAttributions(line: any): void;
+ toString(): string;
+}
+
+/**
+ * @classdesc
+ * Plugin for authenticating requests to the Google Cloud Maps APIs, including the
+ * Photorealistic 3D Tiles and 2D Map Tiles APIs. Handles session-token management,
+ * per-tile attribution collection, and optional logo attribution.
+ */
+declare class GoogleCloudAuthPlugin {
+ /**
+ * @param {Object} options
+ * @param {string} options.apiToken
+ * @param {Object|null} [options.sessionOptions=null]
+ * @param {boolean} [options.autoRefreshToken=false]
+ * @param {string|null} [options.logoUrl=null]
+ * @param {boolean} [options.useRecommendedSettings=true]
+ */
+ constructor({ apiToken, sessionOptions, autoRefreshToken, logoUrl, useRecommendedSettings, }: {
+ apiToken: string;
+ sessionOptions?: any | null;
+ autoRefreshToken?: boolean;
+ logoUrl?: string | null;
+ useRecommendedSettings?: boolean;
+ });
+ name: string;
+ /**
+ * The Google Cloud API key.
+ * @type {string}
+ */
+ apiToken: string;
+ /**
+ * Whether to apply recommended renderer settings for photorealistic tiles.
+ * @type {boolean}
+ */
+ useRecommendedSettings: boolean;
+ /**
+ * URL of a logo image to include in attribution output, or null if not set.
+ * @type {string|null}
+ */
+ logoUrl: string | null;
+ auth: GoogleCloudAuth;
+ /**
+ * The TilesRenderer instance this plugin is registered with.
+ * @type {Object|null}
+ */
+ tiles: any | null;
+ init(tiles: any): void;
+ getAttributions(target: any): void;
+ dispose(): void;
+ fetchData(uri: any, options: any): Promise;
+}
+
+/**
+ * @classdesc
+ * Plugin that adds support for 3D Tiles 1.1 implicit tiling. Intercepts tiles that carry
+ * an `implicitTiling` field and expands them by loading and parsing `.subtree` files,
+ * generating child tiles according to the implicit subdivision scheme.
+ */
+declare class ImplicitTilingPlugin {
+ name: string;
+ init(tiles: any): void;
+ tiles: any;
+ preprocessNode(tile: any, tilesetDir: any, parentTile: any): void;
+ parseTile(buffer: any, tile: any, extension: any): Promise;
+ preprocessURL(url: any, tile: any): any;
+ disposeTile(tile: any): void;
+}
+
+/**
+ * @classdesc
+ * Plugin that ensures every tile has a non-zero geometric error. Tiles with a geometric
+ * error of zero are assigned a derived value based on the nearest ancestor with a non-zero
+ * error, halved once per level of depth below that ancestor.
+ */
+declare class EnforceNonZeroErrorPlugin {
+ name: string;
+ priority: number;
+ originalError: Map;
+ preprocessNode(tile: any): void;
+}
+
+/**
+ * @classdesc
+ * Base loader for quantized-mesh terrain tiles. Parses the binary quantized-mesh format
+ * into structured vertex, index, edge, and extension data. Sets the required `Accept`
+ * header automatically. Subclasses should implement geometry construction from the
+ * parsed result.
+ * @augments LoaderBase
+ */
+declare class QuantizedMeshLoaderBase extends LoaderBase> {
+ constructor(...args: any[]);
+ loadAsync(...args: any[]): Promise;
+ parse(buffer: any): {
+ header: {
+ center: number[];
+ minHeight: number;
+ maxHeight: number;
+ sphereCenter: number[];
+ sphereRadius: number;
+ horizonOcclusionPoint: number[];
+ };
+ indices: any;
+ vertexData: {
+ u: Float32Array;
+ v: Float32Array;
+ height: Float32Array;
+ };
+ edgeIndices: {
+ westIndices: any;
+ southIndices: any;
+ eastIndices: any;
+ northIndices: any;
+ };
+ extensions: {
+ octvertexnormals: {
+ extensionId: number;
+ normals: Float32Array;
+ };
+ watermask: {
+ extensionId: number;
+ mask: any;
+ size: number;
+ };
+ metadata: {
+ extensionId: number;
+ json: any;
+ };
+ };
+ };
+}
+
+export { CesiumIonAuth, CesiumIonAuthPlugin, EnforceNonZeroErrorPlugin, GoogleCloudAuth, GoogleCloudAuthPlugin, ImplicitTilingPlugin, QuantizedMeshLoaderBase };
+export type { AssetTypeHandlerCallback };
diff --git a/tsconfig.core-plugins.json b/tsconfig.core-plugins.json
new file mode 100644
index 000000000..be4e90378
--- /dev/null
+++ b/tsconfig.core-plugins.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "allowJs": true,
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "checkJs": false,
+ "skipLibCheck": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "rootDir": "src"
+ },
+ "files": [
+ "src/core/plugins/index.js",
+ "src/core/plugins/CesiumIonAuthPlugin.js",
+ "src/core/plugins/GoogleCloudAuthPlugin.js",
+ "src/core/plugins/ImplicitTilingPlugin.js",
+ "src/core/plugins/EnforceNonZeroErrorPlugin.js",
+ "src/core/plugins/auth/CesiumIonAuth.js",
+ "src/core/plugins/GoogleAttributionsManager.js",
+ "src/core/plugins/auth/GoogleCloudAuth.js",
+ "src/core/plugins/loaders/QuantizedMeshLoaderBase.js"
+ ]
+}
diff --git a/utils/gen-dts.js b/utils/gen-dts.js
new file mode 100644
index 000000000..fc5c9fb26
--- /dev/null
+++ b/utils/gen-dts.js
@@ -0,0 +1,160 @@
+/**
+ * Generates src/core/plugins/index.d.ts from JSDoc-annotated JS source.
+ *
+ * Steps:
+ * 1. Delete stale .d.ts files so tsc generates fresh declarations
+ * 2. tsc emits per-file .d.ts into a temp directory
+ * 3. rollup-plugin-dts bundles them into a single declaration file
+ * 4. A transform strips any underscore-prefixed members from the output
+ */
+
+import { execSync } from 'child_process';
+import { existsSync, mkdtempSync, readdirSync, rmSync, unlinkSync } from 'fs';
+import { tmpdir } from 'os';
+import { dirname, join, resolve } from 'path';
+import { rollup } from 'rollup';
+import dts from 'rollup-plugin-dts';
+
+const ROOT = resolve( import.meta.dirname, '..' );
+const PLUGINS_DIR = join( ROOT, 'src/core/plugins' );
+const OUT_FILE = join( PLUGINS_DIR, 'index.d.ts' );
+
+// Step 1: delete stale .d.ts files (recursively) so tsc generates fresh ones
+function deleteDtsFiles( dir ) {
+
+ for ( const entry of readdirSync( dir, { withFileTypes: true } ) ) {
+
+ const full = join( dir, entry.name );
+ if ( entry.isDirectory() ) {
+
+ deleteDtsFiles( full );
+
+ } else if ( entry.name.endsWith( '.d.ts' ) ) {
+
+ unlinkSync( full );
+
+ }
+
+ }
+
+}
+
+deleteDtsFiles( PLUGINS_DIR );
+
+// Step 2: emit .d.ts to a temp directory
+const tmpDir = mkdtempSync( join( tmpdir(), 'dts-' ) );
+try {
+
+ execSync(
+ `npx tsc -p tsconfig.core-plugins.json --declarationDir ${ tmpDir }`,
+ { cwd: ROOT, stdio: 'inherit' },
+ );
+
+ // Step 3+4: bundle with rollup-dts and strip _ members
+ const entry = join( tmpDir, 'core/plugins/index.d.ts' );
+
+ const bundle = await rollup( {
+ input: entry,
+ plugins: [
+ resolveDtsExtensions( tmpDir ),
+ dts(),
+ stripUnderscoreMembers(),
+ ],
+ external: [ /^3d-tiles-renderer/ ],
+ } );
+
+ await bundle.write( {
+ file: OUT_FILE,
+ format: 'es',
+ } );
+
+ await bundle.close();
+ console.log( `Written: ${ OUT_FILE }` );
+
+} finally {
+
+ rmSync( tmpDir, { recursive: true, force: true } );
+
+}
+
+/**
+ * Resolves .js imports inside the temp directory to their .d.ts counterparts.
+ */
+function resolveDtsExtensions( tmpDir ) {
+
+ return {
+ name: 'resolve-dts-extensions',
+ resolveId( id, importer ) {
+
+ if ( importer && importer.startsWith( tmpDir ) && id.endsWith( '.js' ) ) {
+
+ const candidate = join( dirname( importer ), id.replace( /\.js$/, '.d.ts' ) );
+ if ( existsSync( candidate ) ) return candidate;
+
+ }
+
+ return null;
+
+ },
+ };
+
+}
+
+/**
+ * Rollup transform that removes underscore-prefixed class members from .d.ts output.
+ * Handles single-line and multiline (inline object type) member declarations.
+ */
+function stripUnderscoreMembers() {
+
+ return {
+ name: 'strip-underscore-members',
+ renderChunk( code ) {
+
+ // Match underscore-prefixed member declarations, including multiline ones
+ // where the type spans multiple lines (e.g. _foo: {\n bar: any;\n};)
+ // Strategy: track brace depth after matching a _ member opener.
+ const lines = code.split( '\n' );
+ const out = [];
+ let skip = 0; // brace depth while skipping a multiline member
+
+ for ( const line of lines ) {
+
+ if ( skip > 0 ) {
+
+ // count braces to know when the member body ends
+ for ( const ch of line ) {
+
+ if ( ch === '{' ) skip ++;
+ else if ( ch === '}' ) skip --;
+
+ }
+
+ continue;
+
+ }
+
+ if ( /^\s+(private\s+)?_\w+[\s:(]/.test( line ) ) {
+
+ // count any opening braces on this line to detect multiline type
+ for ( const ch of line ) {
+
+ if ( ch === '{' ) skip ++;
+ else if ( ch === '}' ) skip --;
+
+ }
+
+ // if skip > 0 the body continues on subsequent lines; either way skip this line
+ continue;
+
+ }
+
+ out.push( line );
+
+ }
+
+ return { code: out.join( '\n' ), map: null };
+
+ },
+ };
+
+}
From 9ca5979d1493d4068e5f5effb11d6d891a6fb174 Mon Sep 17 00:00:00 2001
From: Garrett Johnson
Date: Sun, 15 Mar 2026 15:37:00 +0900
Subject: [PATCH 2/8] Generate d.ts files
---
src/core/plugins/CesiumIonAuthPlugin.js | 4 +++
src/core/plugins/auth/GoogleCloudAuth.js | 4 +--
src/core/plugins/index.d.ts | 24 +++++++++++---
utils/gen-dts.js | 41 ++++++++++++++++++++++--
4 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/src/core/plugins/CesiumIonAuthPlugin.js b/src/core/plugins/CesiumIonAuthPlugin.js
index 65b07b7b3..f5d0e11f8 100644
--- a/src/core/plugins/CesiumIonAuthPlugin.js
+++ b/src/core/plugins/CesiumIonAuthPlugin.js
@@ -1,6 +1,10 @@
import { CesiumIonAuth } from './auth/CesiumIonAuth.js';
import { GoogleCloudAuthPlugin } from './GoogleCloudAuthPlugin.js';
+/**
+ * @typedef {import('3d-tiles-renderer/core').TilesRendererBase} TilesRendererBase
+ */
+
/**
* @callback AssetTypeHandlerCallback
* @param {string} type - The Cesium Ion asset type (e.g. `'TERRAIN'`, `'GLTF'`, `'CZML'`).
diff --git a/src/core/plugins/auth/GoogleCloudAuth.js b/src/core/plugins/auth/GoogleCloudAuth.js
index cae79c921..01026a7a9 100644
--- a/src/core/plugins/auth/GoogleCloudAuth.js
+++ b/src/core/plugins/auth/GoogleCloudAuth.js
@@ -19,7 +19,7 @@ export class GoogleCloudAuth {
/**
* @param {Object} [options={}]
* @param {string} options.apiToken
- * @param {Object|null} [options.sessionOptions=null]
+ * @param {{ mapType?: string, language?: string, region?: string, [key: string]: any }|null} [options.sessionOptions=null]
* @param {boolean} [options.autoRefreshToken=false]
*/
constructor( options = {} ) {
@@ -47,7 +47,7 @@ export class GoogleCloudAuth {
this.sessionToken = null;
/**
* Session options passed as the POST body when creating a Map Tiles session.
- * @type {Object|null}
+ * @type {{ mapType?: string, language?: string, region?: string, [key: string]: any }|null}
*/
this.sessionOptions = sessionOptions;
this._tokenRefreshPromise = null;
diff --git a/src/core/plugins/index.d.ts b/src/core/plugins/index.d.ts
index 007996745..298c9b32f 100644
--- a/src/core/plugins/index.d.ts
+++ b/src/core/plugins/index.d.ts
@@ -1,4 +1,4 @@
-import { LoaderBase } from '3d-tiles-renderer/core';
+import { TilesRendererBase, LoaderBase } from '3d-tiles-renderer/core';
/**
* @classdesc
@@ -35,6 +35,9 @@ declare class CesiumIonAuth {
refreshToken(options: any): any;
}
+/**
+ * @typedef {import('3d-tiles-renderer/core').TilesRendererBase} TilesRendererBase
+ */
/**
* @callback AssetTypeHandlerCallback
* @param {string} type - The Cesium Ion asset type (e.g. `'TERRAIN'`, `'GLTF'`, `'CZML'`).
@@ -95,6 +98,7 @@ declare class CesiumIonAuthPlugin {
fetchData(uri: any, options: any): Promise;
getAttributions(target: any): void;
}
+
type AssetTypeHandlerCallback = (type: string, tiles: TilesRendererBase, asset: any) => any;
/**
@@ -107,12 +111,17 @@ declare class GoogleCloudAuth {
/**
* @param {Object} [options={}]
* @param {string} options.apiToken
- * @param {Object|null} [options.sessionOptions=null]
+ * @param {{ mapType?: string, language?: string, region?: string, [key: string]: any }|null} [options.sessionOptions=null]
* @param {boolean} [options.autoRefreshToken=false]
*/
constructor(options?: {
apiToken: string;
- sessionOptions?: any | null;
+ sessionOptions?: {
+ mapType?: string;
+ language?: string;
+ region?: string;
+ [key: string]: any;
+ } | null;
autoRefreshToken?: boolean;
});
get isMapTilesSession(): boolean;
@@ -138,9 +147,14 @@ declare class GoogleCloudAuth {
sessionToken: string | null;
/**
* Session options passed as the POST body when creating a Map Tiles session.
- * @type {Object|null}
+ * @type {{ mapType?: string, language?: string, region?: string, [key: string]: any }|null}
*/
- sessionOptions: any | null;
+ sessionOptions: {
+ mapType?: string;
+ language?: string;
+ region?: string;
+ [key: string]: any;
+ } | null;
fetch(url: any, options: any): Promise;
refreshToken(options: any): any;
}
diff --git a/utils/gen-dts.js b/utils/gen-dts.js
index fc5c9fb26..51ce87912 100644
--- a/utils/gen-dts.js
+++ b/utils/gen-dts.js
@@ -4,12 +4,13 @@
* Steps:
* 1. Delete stale .d.ts files so tsc generates fresh declarations
* 2. tsc emits per-file .d.ts into a temp directory
- * 3. rollup-plugin-dts bundles them into a single declaration file
- * 4. A transform strips any underscore-prefixed members from the output
+ * 3. Type alias imports are rewritten to avoid a rollup-plugin-dts bug with invalid identifiers
+ * 4. rollup-plugin-dts bundles them into a single declaration file
+ * 5. A transform strips any underscore-prefixed members from the output
*/
import { execSync } from 'child_process';
-import { existsSync, mkdtempSync, readdirSync, rmSync, unlinkSync } from 'fs';
+import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, unlinkSync, writeFileSync } from 'fs';
import { tmpdir } from 'os';
import { dirname, join, resolve } from 'path';
import { rollup } from 'rollup';
@@ -50,6 +51,9 @@ try {
{ cwd: ROOT, stdio: 'inherit' },
);
+ // Fix any invalid namespace imports tsc emitted (e.g. `import * as 3d_...`)
+ fixTypeAliasImportsInDir( tmpDir );
+
// Step 3+4: bundle with rollup-dts and strip _ members
const entry = join( tmpDir, 'core/plugins/index.d.ts' );
@@ -100,6 +104,37 @@ function resolveDtsExtensions( tmpDir ) {
}
+/**
+ * Walks a directory and rewrites .d.ts files, converting tsc's `export type X = import("pkg").X`
+ * aliases to `import type { X } from "pkg"`. This avoids rollup-plugin-dts generating namespace
+ * imports for packages whose names are invalid JS identifiers (e.g. '3d-tiles-renderer/core').
+ */
+function fixTypeAliasImportsInDir( dir ) {
+
+ for ( const entry of readdirSync( dir, { withFileTypes: true } ) ) {
+
+ const full = join( dir, entry.name );
+ if ( entry.isDirectory() ) {
+
+ fixTypeAliasImportsInDir( full );
+
+ } else if ( entry.name.endsWith( '.d.ts' ) ) {
+
+ const code = readFileSync( full, 'utf8' );
+ const result = code.replace(
+ /^export type (\w+) = import\(["']([^"']+)["']\)\.(\w+);$/gm,
+ ( _, local, pkg, exported ) => local === exported
+ ? `import type { ${ local } } from "${ pkg }";`
+ : `import type { ${ exported } as ${ local } } from "${ pkg }";`,
+ );
+ if ( result !== code ) writeFileSync( full, result, 'utf8' );
+
+ }
+
+ }
+
+}
+
/**
* Rollup transform that removes underscore-prefixed class members from .d.ts output.
* Handles single-line and multiline (inline object type) member declarations.
From 0896cd698c67da23a4d297e256a32d72c8709b33 Mon Sep 17 00:00:00 2001
From: Garrett Johnson
Date: Sun, 15 Mar 2026 15:45:03 +0900
Subject: [PATCH 3/8] Add jsdoc linting
---
eslint.config.js | 33 ++++
package-lock.json | 246 +++++++++++++++++++++++++++++-
package.json | 1 +
src/core/plugins/SUBTREELoader.js | 16 +-
4 files changed, 285 insertions(+), 11 deletions(-)
diff --git a/eslint.config.js b/eslint.config.js
index 101886499..c7aeb10ad 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -5,6 +5,7 @@ import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import globals from 'globals';
import mdcs from 'eslint-config-mdcs';
+import jsdoc from 'eslint-plugin-jsdoc';
export default [
// files to ignore
@@ -99,6 +100,38 @@ export default [
},
},
+ // jsdoc
+ {
+ name: 'jsdoc rules',
+ files: [ '**/*.js', '**/*.jsx' ],
+ plugins: {
+ jsdoc,
+ },
+ settings: {
+ jsdoc: {
+ preferredTypes: {
+ Any: 'any',
+ Boolean: 'boolean',
+ Number: 'number',
+ object: 'Object',
+ String: 'string',
+ },
+ tagNamePreference: {
+ returns: 'return',
+ extends: 'augments',
+ },
+ },
+ },
+ rules: {
+ 'jsdoc/check-types': 'error',
+ 'jsdoc/require-param-type': 'error',
+ 'jsdoc/require-returns-type': 'error',
+ 'jsdoc/require-returns': 'off',
+ 'jsdoc/require-param-description': 'off',
+ 'jsdoc/require-returns-description': 'off',
+ },
+ },
+
// vitest
{
name: 'vitest rules',
diff --git a/package-lock.json b/package-lock.json
index fffc871ac..436ba0d23 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"concurrently": "^6.2.1",
"eslint": "^9.0.0",
"eslint-config-mdcs": "^5.0.0",
+ "eslint-plugin-jsdoc": "^62.8.0",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-react-hooks": "^5.0.0",
"globals": "^16.5.0",
@@ -790,6 +791,33 @@
"node": ">=20.19.0"
}
},
+ "node_modules/@es-joy/jsdoccomment": {
+ "version": "0.84.0",
+ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.84.0.tgz",
+ "integrity": "sha512-0xew1CxOam0gV5OMjh2KjFQZsKL2bByX1+q4j3E73MpYIdyUxcZb/xQct9ccUb+ve5KGUYbCUxyPnYB7RbuP+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.8",
+ "@typescript-eslint/types": "^8.54.0",
+ "comment-parser": "1.4.5",
+ "esquery": "^1.7.0",
+ "jsdoc-type-pratt-parser": "~7.1.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ }
+ },
+ "node_modules/@es-joy/resolve.exports": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@es-joy/resolve.exports/-/resolve.exports-1.2.0.tgz",
+ "integrity": "sha512-Q9hjxWI5xBM+qW2enxfe8wDKdFWMfd0Z29k5ZJnuBqD/CasY5Zryj09aCA6owbGATWz+39p5uIdaHXpopOcG8g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
@@ -2775,6 +2803,19 @@
"win32"
]
},
+ "node_modules/@sindresorhus/base62": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/base62/-/base62-1.0.0.tgz",
+ "integrity": "sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@spz-loader/core": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@spz-loader/core/-/core-0.3.0.tgz",
@@ -3458,9 +3499,9 @@
}
},
"node_modules/acorn": {
- "version": "8.15.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
- "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
"bin": {
@@ -3523,6 +3564,16 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/are-docs-informative": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+ "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -4089,6 +4140,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/comment-parser": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.5.tgz",
+ "integrity": "sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12.0.0"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -4734,6 +4795,79 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/eslint-plugin-jsdoc": {
+ "version": "62.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-62.8.0.tgz",
+ "integrity": "sha512-hu3r9/6JBmPG6wTcqtYzgZAnjEG2eqRUATfkFscokESg1VDxZM21ZaMire0KjeMwfj+SXvgB4Rvh5LBuesj92w==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@es-joy/jsdoccomment": "~0.84.0",
+ "@es-joy/resolve.exports": "1.2.0",
+ "are-docs-informative": "^0.0.2",
+ "comment-parser": "1.4.5",
+ "debug": "^4.4.3",
+ "escape-string-regexp": "^4.0.0",
+ "espree": "^11.1.0",
+ "esquery": "^1.7.0",
+ "html-entities": "^2.6.0",
+ "object-deep-merge": "^2.0.0",
+ "parse-imports-exports": "^0.2.4",
+ "semver": "^7.7.4",
+ "spdx-expression-parse": "^4.0.0",
+ "to-valid-identifier": "^1.0.0"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
+ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc/node_modules/espree": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz",
+ "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.16.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^5.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-jsdoc/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/eslint-plugin-react": {
"version": "7.37.5",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
@@ -5458,6 +5592,23 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/html-entities": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz",
+ "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/mdevils"
+ },
+ {
+ "type": "patreon",
+ "url": "https://patreon.com/mdevils"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -6078,6 +6229,16 @@
"node": ">=12.0.0"
}
},
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-7.1.1.tgz",
+ "integrity": "sha512-/2uqY7x6bsrpi3i9LVU6J89352C0rpMk0as8trXxCtvd4kPk1ke/Eyif6wqfSLvoNJqcDG9Vk4UsXgygzCt2xA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
"node_modules/jsdoc/node_modules/escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
@@ -6565,6 +6726,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/object-deep-merge": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/object-deep-merge/-/object-deep-merge-2.0.0.tgz",
+ "integrity": "sha512-3DC3UMpeffLTHiuXSy/UG4NOIYTLlY9u3V82+djSCLYClWobZiS4ivYzpIUWrRY/nfsJ8cWsKyG3QfyLePmhvg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
@@ -6762,6 +6930,23 @@
"node": ">=6"
}
},
+ "node_modules/parse-imports-exports": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz",
+ "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse-statements": "1.0.11"
+ }
+ },
+ "node_modules/parse-statements": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz",
+ "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -7186,6 +7371,19 @@
"lodash": "^4.17.21"
}
},
+ "node_modules/reserved-identifiers": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz",
+ "integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/resolve": {
"version": "2.0.0-next.5",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
@@ -7548,6 +7746,31 @@
"integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==",
"dev": true
},
+ "node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+ "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.23",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz",
+ "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
"node_modules/split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -7889,6 +8112,23 @@
"node": ">=14.0.0"
}
},
+ "node_modules/to-valid-identifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-valid-identifier/-/to-valid-identifier-1.0.0.tgz",
+ "integrity": "sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/base62": "^1.0.0",
+ "reserved-identifiers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/topojson-client": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz",
diff --git a/package.json b/package.json
index 95b22bff4..7049a4207 100644
--- a/package.json
+++ b/package.json
@@ -100,6 +100,7 @@
"concurrently": "^6.2.1",
"eslint": "^9.0.0",
"eslint-config-mdcs": "^5.0.0",
+ "eslint-plugin-jsdoc": "^62.8.0",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-react-hooks": "^5.0.0",
"globals": "^16.5.0",
diff --git a/src/core/plugins/SUBTREELoader.js b/src/core/plugins/SUBTREELoader.js
index a7213ccfe..067fa93e5 100644
--- a/src/core/plugins/SUBTREELoader.js
+++ b/src/core/plugins/SUBTREELoader.js
@@ -84,7 +84,7 @@ export class SUBTREELoader extends LoaderBase {
/**
* A helper object for storing the two parts of the subtree binary
*
- * @typedef {object} Subtree
+ * @typedef {Object} Subtree
* @property {number} version
* @property {JSON} subtreeJson
* @property {ArrayBuffer} subtreeByte
@@ -93,7 +93,7 @@ export class SUBTREELoader extends LoaderBase {
/**
*
- * @param buffer
+ * @param {ArrayBuffer} buffer
* @return {Subtree}
*/
parseBuffer( buffer ) {
@@ -272,7 +272,7 @@ export class SUBTREELoader extends LoaderBase {
*
* @param {BufferHeader[]} bufferHeaders The preprocessed buffer headers
* @param {ArrayBuffer} internalBuffer The binary chunk of the subtree file
- * @returns {object} buffersU8 A dictionary of buffer index to a Uint8Array of its contents.
+ * @returns {Object} buffersU8 A dictionary of buffer index to a Uint8Array of its contents.
* @private
*/
async requestActiveBuffers( bufferHeaders, internalBuffer ) {
@@ -341,8 +341,8 @@ export class SUBTREELoader extends LoaderBase {
* extract a subarray from one of the active buffers.
*
* @param {BufferViewHeader[]} bufferViewHeaders
- * @param {object} buffersU8 A dictionary of buffer index to a Uint8Array of its contents.
- * @returns {object} A dictionary of buffer view index to a Uint8Array of its contents.
+ * @param {Object} buffersU8 A dictionary of buffer index to a Uint8Array of its contents.
+ * @returns {Object} A dictionary of buffer view index to a Uint8Array of its contents.
* @private
*/
parseActiveBufferViews( bufferViewHeaders, buffersU8 ) {
@@ -375,7 +375,7 @@ export class SUBTREELoader extends LoaderBase {
* Buffers are assumed inactive until explicitly marked active. This is used
* to avoid fetching unneeded buffers.
*
- * @typedef {object} BufferHeader
+ * @typedef {Object} BufferHeader
* @property {boolean} isActive Whether this buffer is currently used.
* @property {string} [uri] The URI of the buffer (external buffers only)
* @property {number} byteLength The byte length of the buffer, including any padding contained within.
@@ -407,7 +407,7 @@ export class SUBTREELoader extends LoaderBase {
* A buffer view header is the JSON header from the subtree JSON chunk plus
* the isActive flag and a reference to the header for the underlying buffer.
*
- * @typedef {object} BufferViewHeader
+ * @typedef {Object} BufferViewHeader
* @property {BufferHeader} bufferHeader A reference to the header for the underlying buffer
* @property {boolean} isActive Whether this bufferView is currently used.
* @property {number} buffer The index of the underlying buffer.
@@ -489,7 +489,7 @@ export class SUBTREELoader extends LoaderBase {
* @param {Object} availabilityJson A JSON object representing the availability.
* @param {Object} bufferViewsU8 A dictionary of buffer view index to its Uint8Array contents.
* @param {number} lengthBits The length of the availability bitstream in bits.
- * @returns {object}
+ * @returns {Object}
* @private
*/
parseAvailabilityBitstream(
From 8a9d216dcd30747ad917649b6152aaaf27ea9a2e Mon Sep 17 00:00:00 2001
From: Garrett Johnson
Date: Sun, 15 Mar 2026 16:36:38 +0900
Subject: [PATCH 4/8] Remove old d.ts
---
src/core/renderer/constants.d.ts | 3 -
src/core/renderer/loaders/B3DMLoaderBase.d.ts | 17 ---
src/core/renderer/loaders/CMPTLoaderBase.d.ts | 21 ---
src/core/renderer/loaders/I3DMLoaderBase.d.ts | 17 ---
src/core/renderer/loaders/LoaderBase.d.ts | 11 --
src/core/renderer/loaders/PNTSLoaderBase.d.ts | 16 --
src/core/renderer/tiles/Tile.d.ts | 140 ------------------
.../renderer/tiles/TilesRendererBase.d.ts | 86 -----------
src/core/renderer/tiles/Tileset.d.ts | 66 ---------
src/core/renderer/utilities/BatchTable.d.ts | 26 ----
src/core/renderer/utilities/FeatureTable.d.ts | 33 -----
src/core/renderer/utilities/LRUCache.d.ts | 14 --
.../renderer/utilities/PriorityQueue.d.ts | 17 ---
13 files changed, 467 deletions(-)
delete mode 100644 src/core/renderer/constants.d.ts
delete mode 100644 src/core/renderer/loaders/B3DMLoaderBase.d.ts
delete mode 100644 src/core/renderer/loaders/CMPTLoaderBase.d.ts
delete mode 100644 src/core/renderer/loaders/I3DMLoaderBase.d.ts
delete mode 100644 src/core/renderer/loaders/LoaderBase.d.ts
delete mode 100644 src/core/renderer/loaders/PNTSLoaderBase.d.ts
delete mode 100644 src/core/renderer/tiles/Tile.d.ts
delete mode 100644 src/core/renderer/tiles/TilesRendererBase.d.ts
delete mode 100644 src/core/renderer/tiles/Tileset.d.ts
delete mode 100644 src/core/renderer/utilities/BatchTable.d.ts
delete mode 100644 src/core/renderer/utilities/FeatureTable.d.ts
delete mode 100644 src/core/renderer/utilities/LRUCache.d.ts
delete mode 100644 src/core/renderer/utilities/PriorityQueue.d.ts
diff --git a/src/core/renderer/constants.d.ts b/src/core/renderer/constants.d.ts
deleted file mode 100644
index f9b5c144b..000000000
--- a/src/core/renderer/constants.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export const WGS84_RADIUS: number;
-export const WGS84_FLATTENING: number;
-export const WGS84_HEIGHT: number;
diff --git a/src/core/renderer/loaders/B3DMLoaderBase.d.ts b/src/core/renderer/loaders/B3DMLoaderBase.d.ts
deleted file mode 100644
index 62880bacb..000000000
--- a/src/core/renderer/loaders/B3DMLoaderBase.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { BatchTable } from '../utilities/BatchTable.js';
-import { FeatureTable } from '../utilities/FeatureTable.js';
-import { LoaderBase } from './LoaderBase.js';
-
-export interface B3DMBaseResult {
-
- version : string;
- featureTable: FeatureTable;
- batchTable : BatchTable;
- glbBytes : Uint8Array;
-
-}
-
-export class B3DMLoaderBase
- extends LoaderBase {
-
-}
diff --git a/src/core/renderer/loaders/CMPTLoaderBase.d.ts b/src/core/renderer/loaders/CMPTLoaderBase.d.ts
deleted file mode 100644
index 525a1c4cd..000000000
--- a/src/core/renderer/loaders/CMPTLoaderBase.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { LoaderBase } from './LoaderBase.js';
-
-interface TileInfo {
-
- type : string;
- buffer : Uint8Array;
- version : string;
-
-}
-
-export interface CMPTBaseResult {
-
- version : string;
- tiles : Array< TileInfo >;
-
-}
-
-export class CMPTLoaderBase
- extends LoaderBase {
-
-}
diff --git a/src/core/renderer/loaders/I3DMLoaderBase.d.ts b/src/core/renderer/loaders/I3DMLoaderBase.d.ts
deleted file mode 100644
index 7ed313ec6..000000000
--- a/src/core/renderer/loaders/I3DMLoaderBase.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { BatchTable } from '../utilities/BatchTable.js';
-import { FeatureTable } from '../utilities/FeatureTable.js';
-import { LoaderBase } from './LoaderBase.js';
-
-export interface I3DMBaseResult {
-
- version : string;
- featureTable: FeatureTable;
- batchTable : BatchTable;
- glbBytes : Uint8Array;
-
-}
-
-export class I3DMLoaderBase
- extends LoaderBase {
-
-}
diff --git a/src/core/renderer/loaders/LoaderBase.d.ts b/src/core/renderer/loaders/LoaderBase.d.ts
deleted file mode 100644
index 5e73d3540..000000000
--- a/src/core/renderer/loaders/LoaderBase.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export class LoaderBase> {
-
- fetchOptions: any;
- workingPath: string;
- /** @deprecated in favor of `loadAsync` */
- load( url: string ): Promise< Result >;
- loadAsync( url: string ): Promise< Result >;
- resolveExternalURL( url: string ): string;
- parse( buffer: ArrayBuffer ): ParseResult;
-
-}
diff --git a/src/core/renderer/loaders/PNTSLoaderBase.d.ts b/src/core/renderer/loaders/PNTSLoaderBase.d.ts
deleted file mode 100644
index 25b5a002e..000000000
--- a/src/core/renderer/loaders/PNTSLoaderBase.d.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { BatchTable } from '../utilities/BatchTable.js';
-import { FeatureTable } from '../utilities/FeatureTable.js';
-import { LoaderBase } from './LoaderBase.js';
-
-export interface PNTSBaseResult {
-
- version : string;
- featureTable: FeatureTable;
- batchTable : BatchTable;
-
-}
-
-export class PNTSLoaderBase
- extends LoaderBase {
-
-}
diff --git a/src/core/renderer/tiles/Tile.d.ts b/src/core/renderer/tiles/Tile.d.ts
deleted file mode 100644
index 21e338596..000000000
--- a/src/core/renderer/tiles/Tile.d.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * Internal implementation details for tile management
- */
-export interface TileInternalData {
- hasContent: boolean;
- hasRenderableContent: boolean;
- hasUnrenderableContent: boolean;
- loadingState: number;
- basePath: string;
- depth: number;
- depthFromRenderedParent: number;
- /**
- * Whether this tile was synthetically based on loaded parent tile state.
- */
- isVirtual: boolean;
- /**
- * The number of virtual children appended to this tile's children array by plugins.
- */
- virtualChildCount: number;
-}
-
-/**
- * Traversal state data updated during each frame's tile traversal
- */
-export interface TileTraversalData {
- /**
- * How far this tile's bounds are from the nearest active camera.
- * Expected to be filled in during calculateError implementations.
- */
- distanceFromCamera: number;
- /**
- * The screen space error for this tile
- */
- error: number;
- /**
- * Whether or not the tile was within the frustum on the last update run
- */
- inFrustum: boolean;
- /**
- * Whether this tile is a leaf node in the used tree
- */
- isLeaf: boolean;
- /**
- * Whether or not the tile was visited during the last update run
- */
- used: boolean;
- /**
- * Whether or not the tile was used in the previous frame
- */
- usedLastFrame: boolean;
- /**
- * This tile is currently visible if:
- * 1: Tile content is loaded
- * 2: Tile is within a camera frustum
- * 3: Tile meets the SSE requirements
- */
- visible: boolean;
-}
-
-/**
- * A 3D Tiles tile with both spec fields (from tileset JSON) and renderer-managed state.
- *
- * See spec for full schema: https://github.com/CesiumGS/3d-tiles/blob/master/specification/schema/tile.schema.json
- */
-export interface Tile {
-
- boundingVolume: {
-
- /**
- * An array of 12 numbers that define an oriented bounding box. The first three elements define the x, y, and z
- * values for the center of the box. The next three elements (with indices 3, 4, and 5) define the x axis
- * direction and half-length. The next three elements (indices 6, 7, and 8) define the y axis direction and
- * half-length. The last three elements (indices 9, 10, and 11) define the z axis direction and half-length.
- */
- box?: number[];
-
- /**
- * An array of four numbers that define a bounding sphere. The first three elements define the x, y, and z
- * values for the center of the sphere. The last element (with index 3) defines the radius in meters.
- */
- sphere?: number[];
-
- };
-
- /**
- * The error, in meters, introduced if this tileset is not rendered. At runtime, the geometric error is used to compute screen space error (SSE), i.e., the error measured in pixels.
- */
- geometricError: number;
-
- parent: Tile | null;
-
- children?: Tile[];
-
- content?: {
-
- uri: string;
-
- /**
- * Dictionary object with content specific extension objects.
- */
- extensions?: Record;
-
- extras?: Record;
-
- // Non standard, noted here as it exists in the code in this package to support old pre-1.0 tilesets
- url?: string;
-
- };
-
- // An object that describes the implicit subdivision of this tile.
- implicitTiling?: {
- // A string describing the subdivision scheme used within the tileset.
- subdivisionScheme: 'QUADTREE' | 'OCTREE';
- subtreeLevels: number;
- availableLevels: number;
- // An object describing the location of subtree files.
- subtrees: {
- // A template URI pointing to subtree files
- uri: string;
- }
- };
-
- /**
- * Dictionary object with tile specific extension objects.
- */
- extensions?: Record;
-
- extras?: Record;
-
- refine?: 'REPLACE' | 'ADD';
-
- transform?: number[];
-
- // Internal implementation details for tile management
- internal: TileInternalData;
-
- // Traversal state data updated during each frame's tile traversal
- traversal: TileTraversalData;
-
-}
diff --git a/src/core/renderer/tiles/TilesRendererBase.d.ts b/src/core/renderer/tiles/TilesRendererBase.d.ts
deleted file mode 100644
index 2cc6be490..000000000
--- a/src/core/renderer/tiles/TilesRendererBase.d.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { LRUCache } from '../utilities/LRUCache.js';
-import { PriorityQueue } from '../utilities/PriorityQueue.js';
-import { Tile } from './Tile.js';
-import { Tileset } from './Tileset.js';
-
-// Events dispatched by TilesRendererBase, available across all renderer implementations.
-export interface TilesRendererBaseEventMap {
- 'needs-update': {};
- 'load-content': {};
- 'load-tileset': { tileset : Tileset, /* @deprecated Use tileset instead */ tileSet? : Tileset, url : string };
- /* @deprecated Use 'load-tileset' instead */
- 'load-tile-set': { tileset : Tileset, /* @deprecated Use tileset instead */ tileSet? : Tileset, url : string };
- 'load-root-tileset': { tileset : Tileset, url : string };
- 'tiles-load-start': {};
- 'tiles-load-end': {};
- 'tile-download-start': { tile : Tile, uri : string };
- 'load-model': { scene : TScene, tile : Tile, url : string };
- 'dispose-model': { scene : TScene, tile : Tile };
- 'tile-visibility-change': { scene : TScene, tile : Tile, visible : boolean };
- 'update-before': {};
- 'update-after': {};
- 'load-error': { tile : Tile | null, error : Error, url : string | URL };
-}
-
-export class TilesRendererBase {
-
- readonly rootTileset : Tileset | null;
- /** @deprecated Use rootTileset instead */
- readonly rootTileSet : Tileset | null;
- readonly root : Tile | null;
- readonly visibleTiles : Set;
- readonly activeTiles : Set;
-
- errorTarget : number;
- errorThreshold : number;
- displayActiveTiles : boolean;
- maxDepth : number;
- loadSiblings : boolean;
- optimizedLoadStrategy : boolean;
- maxTilesProcessed : number;
-
- readonly loadProgress : number;
-
- fetchOptions : RequestInit;
-
- lruCache : LRUCache;
- parseQueue : PriorityQueue;
- downloadQueue : PriorityQueue;
- processNodeQueue: PriorityQueue;
-
- constructor( url?: string );
- update() : void;
- registerPlugin( plugin: object ) : void;
- unregisterPlugin( plugin: object | string ) : boolean;
- getPluginByName( plugin: object | string ) : object;
- traverse(
- beforeCb : ( ( tile : object, parent : object, depth : number ) => boolean ) | null,
- afterCb : ( ( tile : object, parent : object, depth : number ) => boolean ) | null
- ) : void;
- getAttributions( target? : Array<{ type: string, value: any }> ) : Array<{ type: string, value: any }>;
-
- addEventListener(
- name : T,
- callback : ( event : TEventMap[ T ] & { type : T } ) => void
- ) : void;
- addEventListener( name : string, callback : ( event : any ) => void ) : void;
-
- removeEventListener(
- name : T,
- callback : ( event : TEventMap[ T ] & { type : T } ) => void
- ) : void;
- removeEventListener( name : string, callback : ( event : any ) => void ) : void;
-
- hasEventListener(
- name : T,
- callback : ( event : TEventMap[ T ] & { type : T } ) => void
- ) : boolean;
- hasEventListener( name : string, callback : ( event : any ) => void ) : boolean;
-
- dispatchEvent( event : TEventMap[ T ] & { type : T } ) : void;
- dispatchEvent( event : { type : string } ) : void;
-
- dispose() : void;
- resetFailedTiles() : void;
-
-}
diff --git a/src/core/renderer/tiles/Tileset.d.ts b/src/core/renderer/tiles/Tileset.d.ts
deleted file mode 100644
index 46049c287..000000000
--- a/src/core/renderer/tiles/Tileset.d.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { Tile } from './Tile.js';
-
-/**
- * A 3d-tiles tileset.
- *
- * Schema, see: https://github.com/CesiumGS/3d-tiles/blob/main/specification/schema/tileset.schema.json
- */
-export interface Tileset {
-
- /**
- * Metadata about the entire tileset.
- */
- asset: {
-
- /**
- * 3d-tiles version
- */
- version: string,
-
- /**
- * Application specific version
- */
- tilesetVersion?: string,
-
- /**
- * Dictionary object with extension-specific objects.
- */
- extensions? : Record,
-
- };
-
- /**
- * The error, in meters, introduced if this tileset is not rendered. At runtime, the geometric error is used to compute screen space error (SSE), i.e., the error measured in pixels.
- */
- geometricError: number;
-
- /**
- * The root tile.
- */
- root: Tile;
-
- // optional properties
-
- /**
- * Names of 3D Tiles extensions used somewhere in this tileset.
- */
- extensionsUsed?: string[];
-
- /**
- * Names of 3D Tiles extensions required to properly load this tileset.
- */
- extensionsRequired?: string[];
-
- /**
- * A dictionary object of metadata about per-feature properties.
- */
- properties?: Record;
-
- /**
- * Dictionary object with extension-specific objects.
- */
- extensions? : Record;
-
- extras? : Record;
-
-}
diff --git a/src/core/renderer/utilities/BatchTable.d.ts b/src/core/renderer/utilities/BatchTable.d.ts
deleted file mode 100644
index 0798e9881..000000000
--- a/src/core/renderer/utilities/BatchTable.d.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { FeatureTable } from './FeatureTable.js';
-
-export class BatchTable extends FeatureTable {
-
- count : number;
-
- constructor(
- buffer : ArrayBuffer,
- count : number,
- start : number,
- headerLength : number,
- binLength : number
- );
-
- getKeys() : Array< string >;
-
- getDataFromId(
- id: number,
- target?: object
- ) : object;
-
- getPropertyArray(
- key: string,
- ) : number | string | ArrayBufferView;
-
-}
diff --git a/src/core/renderer/utilities/FeatureTable.d.ts b/src/core/renderer/utilities/FeatureTable.d.ts
deleted file mode 100644
index d9c8eb2e2..000000000
--- a/src/core/renderer/utilities/FeatureTable.d.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-interface FeatureTableHeader {
-
- extensions?: object;
- extras?: any;
-
-}
-
-export class FeatureTable {
-
- buffer : ArrayBuffer;
- binOffset : number;
- binLength : number;
- header : FeatureTableHeader;
-
- constructor(
- buffer : ArrayBuffer,
- start : number,
- headerLength : number,
- binLength : number
- );
-
- getKeys() : Array< string >;
-
- getData(
- key : string,
- count : number,
- defaultComponentType? : string | null,
- defaultType? : string | null
- ) : number | string | ArrayBufferView;
-
- getBuffer( byteOffset : number, byteLength : number ) : ArrayBuffer;
-
-}
diff --git a/src/core/renderer/utilities/LRUCache.d.ts b/src/core/renderer/utilities/LRUCache.d.ts
deleted file mode 100644
index a54968185..000000000
--- a/src/core/renderer/utilities/LRUCache.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-export class LRUCache {
-
- minSize: number;
- maxSize: number;
- minBytesSize: number;
- maxBytesSize: number;
- unloadPercent: number;
- autoMarkUnused: boolean;
-
- unloadPriorityCallback: ( item: any ) => number;
-
- isUsed( item: any ): boolean;
-
-}
diff --git a/src/core/renderer/utilities/PriorityQueue.d.ts b/src/core/renderer/utilities/PriorityQueue.d.ts
deleted file mode 100644
index 5ebab4f4f..000000000
--- a/src/core/renderer/utilities/PriorityQueue.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-export class PriorityQueue {
-
- maxJobs : number;
- autoUpdate : boolean;
- priorityCallback : ( itemA : any, itemB : any ) => number;
-
- schedulingCallback : ( func : () => void ) => void;
-
- sort() : void;
- add( item : any, callback : ( item : any ) => any ) : Promise< any >;
- remove( item : any ) : void;
- removeByFilter( filter : ( item : any ) => boolean ) : void;
-
- tryRunJobs() : void;
- scheduleJobRun() : void;
-
-}
From 1ffe0360b6cb6de04d1c4587b210d1e99eff9065 Mon Sep 17 00:00:00 2001
From: Garrett Johnson
Date: Sun, 15 Mar 2026 18:23:29 +0900
Subject: [PATCH 5/8] Updates
---
eslint.config.js | 1 +
src/core/plugins/index.d.ts | 4 +-
src/core/renderer/index.d.ts | 1096 +++++++++++++++++++++++++++++++++-
tsconfig.core-plugins.json | 23 -
tsconfig.dts.json | 15 +
utils/gen-dts.js | 437 ++++++++++++--
6 files changed, 1489 insertions(+), 87 deletions(-)
delete mode 100644 tsconfig.core-plugins.json
create mode 100644 tsconfig.dts.json
diff --git a/eslint.config.js b/eslint.config.js
index c7aeb10ad..40e01b666 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -14,6 +14,7 @@ export default [
ignores: [
'**/node_modules/**',
'**/build/**',
+ '**/*.d.ts',
],
},
diff --git a/src/core/plugins/index.d.ts b/src/core/plugins/index.d.ts
index 298c9b32f..6820d0ee1 100644
--- a/src/core/plugins/index.d.ts
+++ b/src/core/plugins/index.d.ts
@@ -253,9 +253,9 @@ declare class EnforceNonZeroErrorPlugin {
* parsed result.
* @augments LoaderBase
*/
-declare class QuantizedMeshLoaderBase extends LoaderBase> {
+declare class QuantizedMeshLoaderBase extends LoaderBase {
constructor(...args: any[]);
- loadAsync(...args: any[]): Promise;
+ loadAsync(...args: any[]): Promise;
parse(buffer: any): {
header: {
center: number[];
diff --git a/src/core/renderer/index.d.ts b/src/core/renderer/index.d.ts
index 716ae3b8e..1144fcbb3 100644
--- a/src/core/renderer/index.d.ts
+++ b/src/core/renderer/index.d.ts
@@ -1,15 +1,1081 @@
-// common
-export * from './tiles/TilesRendererBase.js';
-export { Tile, TileInternalData, TileTraversalData } from './tiles/Tile.js';
-export { Tileset } from './tiles/Tileset.js';
-export * from './loaders/B3DMLoaderBase.js';
-export * from './loaders/I3DMLoaderBase.js';
-export * from './loaders/PNTSLoaderBase.js';
-export * from './loaders/CMPTLoaderBase.js';
-export * from './loaders/LoaderBase.js';
-export * from './constants.js';
-
-export { LRUCache } from './utilities/LRUCache.js';
-export { PriorityQueue } from './utilities/PriorityQueue.js';
-export { BatchTable } from './utilities/BatchTable.js';
-export { FeatureTable } from './utilities/FeatureTable.js';
+type UnloadPriorityCallback = (a: any, b: any) => number;
+type RemoveCallback = (item: any) => any;
+/**
+ * @callback UnloadPriorityCallback
+ * @param {any} a
+ * @param {any} b
+ * @returns {number}
+ */
+/**
+ * @callback RemoveCallback
+ * @param {any} item
+ */
+/**
+ * Least-recently-used cache for managing tile content lifecycle. Tracks which items
+ * are in use each frame and evicts unused items when the cache exceeds its size limits.
+ */
+declare class LRUCache {
+ set unloadPriorityCallback(cb: UnloadPriorityCallback | null);
+ /**
+ * Comparator used to determine eviction order. Items that sort last are evicted first.
+ * Defaults to `null` (eviction order is by last-used time).
+ * @type {UnloadPriorityCallback|null}
+ */
+ get unloadPriorityCallback(): UnloadPriorityCallback | null;
+ /**
+ * Minimum number of items to keep in the cache after eviction.
+ * @type {number}
+ */
+ minSize: number;
+ /**
+ * Maximum number of items before eviction is triggered.
+ * @type {number}
+ */
+ maxSize: number;
+ /**
+ * Minimum total bytes to retain after eviction.
+ * @type {number}
+ */
+ minBytesSize: number;
+ /**
+ * Maximum total bytes before eviction is triggered.
+ * @type {number}
+ */
+ maxBytesSize: number;
+ /**
+ * Fraction of excess items/bytes to unload per eviction pass.
+ * @type {number}
+ */
+ unloadPercent: number;
+ /**
+ * If true, items are automatically marked as unused at the start of each eviction pass.
+ * @type {boolean}
+ */
+ autoMarkUnused: boolean;
+ itemSet: Map;
+ itemList: any[];
+ usedSet: Set;
+ callbacks: Map;
+ unloadingHandle: number;
+ cachedBytes: number;
+ bytesMap: Map;
+ loadedSet: Set;
+ defaultPriorityCallback: (item: any) => any;
+ /**
+ * Returns whether the cache has reached its maximum item count or byte size.
+ * @returns {boolean}
+ */
+ isFull(): boolean;
+ /**
+ * Returns the byte size registered for the given item, or 0 if not tracked.
+ * @param {any} item
+ * @returns {number}
+ */
+ getMemoryUsage(item: any): number;
+ /**
+ * Sets the byte size for the given item, updating the total `cachedBytes` count.
+ * @param {any} item
+ * @param {number} bytes
+ */
+ setMemoryUsage(item: any, bytes: number): void;
+ /**
+ * Adds an item to the cache. Returns false if the item already exists or the cache is full.
+ * @param {any} item
+ * @param {RemoveCallback} removeCb - Called with the item when it is evicted
+ * @returns {boolean}
+ */
+ add(item: any, removeCb: RemoveCallback): boolean;
+ /**
+ * Returns whether the given item is in the cache.
+ * @param {any} item
+ * @returns {boolean}
+ */
+ has(item: any): boolean;
+ /**
+ * Removes an item from the cache immediately, invoking its removal callback.
+ * Returns false if the item was not in the cache.
+ * @param {any} item
+ * @returns {boolean}
+ */
+ remove(item: any): boolean;
+ /**
+ * Marks whether an item has finished loading. Unloaded items may be evicted early
+ * when the cache is over its max size limits, even if they are marked as used.
+ * @param {any} item
+ * @param {boolean} value
+ */
+ setLoaded(item: any, value: boolean): void;
+ /**
+ * Marks an item as used in the current frame, preventing it from being evicted.
+ * @param {any} item
+ */
+ markUsed(item: any): void;
+ /**
+ * Marks an item as unused, making it eligible for eviction.
+ * @param {any} item
+ */
+ markUnused(item: any): void;
+ /**
+ * Marks all items in the cache as unused.
+ */
+ markAllUnused(): void;
+ /**
+ * Returns whether the given item is currently marked as used.
+ * @param {any} item
+ * @returns {boolean}
+ */
+ isUsed(item: any): boolean;
+ /**
+ * Evicts unused items until the cache is within its min size and byte limits.
+ * Items are sorted by `unloadPriorityCallback` before eviction.
+ */
+ unloadUnusedContent(): void;
+ /**
+ * Schedules `unloadUnusedContent` to run asynchronously via microtask.
+ */
+ scheduleUnload(): void;
+ scheduled: boolean;
+}
+
+/**
+ * Error thrown when a queued item's promise is rejected because the item was removed
+ * before its callback could run.
+ *
+ * @extends Error
+ */
+declare class PriorityQueueItemRemovedError extends Error {
+ constructor();
+}
+/**
+ * @callback PriorityCallback
+ * @param {any} a
+ * @param {any} b
+ * @returns {number}
+ */
+/**
+ * @callback SchedulingCallback
+ * @param {Function} func
+ */
+/**
+ * @callback ItemCallback
+ * @param {any} item
+ * @returns {Promise|any}
+ */
+/**
+ * @callback FilterCallback
+ * @param {any} item
+ * @returns {boolean}
+ */
+/**
+ * Priority queue for scheduling async work with a concurrency limit. Items are
+ * sorted by `priorityCallback` and dispatched up to `maxJobs` at a time.
+ */
+declare class PriorityQueue {
+ get running(): boolean;
+ /**
+ * Maximum number of jobs that can run concurrently.
+ * @type {number}
+ */
+ maxJobs: number;
+ items: any[];
+ callbacks: Map;
+ currJobs: number;
+ scheduled: boolean;
+ /**
+ * If true, job runs are automatically scheduled after `add` and after each job completes.
+ * @type {boolean}
+ */
+ autoUpdate: boolean;
+ /**
+ * Comparator used to sort queued items. Higher-priority items should sort last
+ * (i.e. return positive when `itemA` should run before `itemB`). Defaults to `null`.
+ * @type {PriorityCallback|null}
+ */
+ priorityCallback: PriorityCallback | null;
+ /**
+ * Callback used to schedule a deferred job run. Defaults to `requestAnimationFrame`.
+ * @type {SchedulingCallback}
+ */
+ schedulingCallback: SchedulingCallback;
+ /**
+ * Sorts the pending item list using `priorityCallback`, if set.
+ */
+ sort(): void;
+ /**
+ * Returns whether the given item is currently queued.
+ * @param {any} item
+ * @returns {boolean}
+ */
+ has(item: any): boolean;
+ /**
+ * Adds an item to the queue and returns a Promise that resolves when the item's
+ * callback completes, or rejects if the item is removed before running.
+ * @param {any} item
+ * @param {ItemCallback} callback - Invoked with `item` when it is dequeued; may return a Promise
+ * @returns {Promise}
+ */
+ add(item: any, callback: ItemCallback): Promise;
+ /**
+ * Removes an item from the queue, rejecting its promise with `PriorityQueueItemRemovedError`.
+ * @param {any} item
+ */
+ remove(item: any): void;
+ /**
+ * Removes all queued items for which `filter` returns true.
+ * @param {FilterCallback} filter - Called with each item; return true to remove
+ */
+ removeByFilter(filter: FilterCallback): void;
+ /**
+ * Immediately attempts to dequeue and run pending jobs up to `maxJobs` concurrency.
+ */
+ tryRunJobs(): void;
+ /**
+ * Schedules a deferred call to `tryRunJobs` via `schedulingCallback`.
+ */
+ scheduleJobRun(): void;
+}
+type PriorityCallback = (a: any, b: any) => number;
+type SchedulingCallback = (func: Function) => any;
+type ItemCallback = (item: any) => Promise | any;
+type FilterCallback = (item: any) => boolean;
+
+/**
+ * Internal renderer state added to each tile during preprocessing.
+ * @typedef {Object} TileInternalData
+ * @property {boolean} hasContent - Whether the tile has a content URI.
+ * @property {boolean} hasRenderableContent - Whether the tile content is a renderable model (not an external tileset).
+ * @property {boolean} hasUnrenderableContent - Whether the tile content is an external tileset JSON.
+ * @property {number} loadingState - Current loading state constant (UNLOADED, QUEUED, LOADING, PARSING, LOADED, or FAILED).
+ * @property {string} basePath - Base URL used to resolve relative content URIs.
+ * @property {number} depth - Depth of this tile in the full tile hierarchy.
+ * @property {number} depthFromRenderedParent - Depth from the nearest ancestor with renderable content.
+ * @property {boolean} isVirtual - Whether this tile was synthetically generated by a plugin.
+ * @property {number} virtualChildCount - Number of virtual children appended to this tile by plugins.
+ */
+/**
+ * Per-frame traversal state updated on each tile during `TilesRendererBase.update`.
+ * @typedef {Object} TileTraversalData
+ * @property {number} distanceFromCamera - Distance from the tile bounds to the nearest active camera.
+ * @property {number} error - Screen space error computed for this tile.
+ * @property {boolean} inFrustum - Whether the tile was within the camera frustum on the last update.
+ * @property {boolean} isLeaf - Whether this tile is a leaf node in the used tile tree.
+ * @property {boolean} used - Whether this tile was visited during the last update traversal.
+ * @property {boolean} usedLastFrame - Whether this tile was visited in the previous frame.
+ * @property {boolean} visible - Whether this tile is currently visible (loaded, in frustum, meets SSE).
+ */
+/**
+ * A 3D Tiles tile with both spec fields (from tileset JSON) and renderer-managed state.
+ * @typedef {Object} Tile
+ * @property {Object} boundingVolume - Bounding volume. Has either a `box` (12-element array) or `sphere` (4-element array) field.
+ * @property {number} geometricError - Error in meters introduced if this tile is not rendered.
+ * @property {Tile|null} parent - Parent tile, or null for the root.
+ * @property {Tile[]} [children] - Child tiles.
+ * @property {Object} [content] - Loadable content URI reference.
+ * @property {'REPLACE'|'ADD'} [refine] - Refinement strategy; inherited from the parent if omitted.
+ * @property {number[]} [transform] - Optional 4x4 column-major transform matrix.
+ * @property {Object} [extensions] - Extension-specific objects.
+ * @property {Object} [extras] - Extra application-specific data.
+ * @property {TileInternalData} internal - Internal renderer state.
+ * @property {TileTraversalData} traversal - Per-frame traversal state.
+ */
+/**
+ * A loaded 3D Tiles tileset JSON object.
+ * @typedef {Object} Tileset
+ * @property {Object} asset - Metadata about the tileset. Contains `version` (string) and optional `tilesetVersion` (string).
+ * @property {number} geometricError - Error in meters for the entire tileset.
+ * @property {Tile} root - The root tile.
+ * @property {string[]} [extensionsUsed] - Names of extensions used somewhere in the tileset.
+ * @property {string[]} [extensionsRequired] - Names of extensions required to load the tileset.
+ * @property {Object} [properties] - Metadata about per-feature properties.
+ * @property {Object} [extensions] - Extension-specific objects.
+ * @property {Object} [extras] - Extra application-specific data.
+ */
+/**
+ * Fired when the renderer determines a new render is required — e.g. after a tile loads.
+ * @event TilesRendererBase#needs-update
+ */
+/**
+ * Fired when any tile content (model or external tileset) finishes loading.
+ * @event TilesRendererBase#load-content
+ */
+/**
+ * Fired when any tileset JSON finishes loading.
+ * @event TilesRendererBase#load-tileset
+ * @property {Tileset} tileset - The loaded tileset object.
+ * @property {string} url - The URL from which the tileset was loaded.
+ */
+/**
+ * Fired when the root tileset JSON finishes loading.
+ * @event TilesRendererBase#load-root-tileset
+ * @property {Tileset} tileset - The loaded root tileset object.
+ * @property {string} url - The URL from which the tileset was loaded.
+ */
+/**
+ * Fired when tile downloads begin after a period of inactivity.
+ * @event TilesRendererBase#tiles-load-start
+ */
+/**
+ * Fired when all pending tile downloads and parses have completed.
+ * @event TilesRendererBase#tiles-load-end
+ */
+/**
+ * Fired when a tile content download begins.
+ * @event TilesRendererBase#tile-download-start
+ * @property {Tile} tile - The tile being downloaded.
+ * @property {string} uri - The URI being fetched.
+ */
+/**
+ * Fired when a tile's renderable content (model/scene) is created.
+ * The `scene` type is engine-specific (e.g. `THREE.Group` in three.js).
+ * @event TilesRendererBase#load-model
+ * @property {Object} scene - The engine-specific scene object created for this tile.
+ * @property {Tile} tile - The tile the scene belongs to.
+ * @property {string} url - The URL the content was loaded from.
+ */
+/**
+ * Fired when a tile's renderable content is about to be removed and destroyed.
+ * The `scene` type is engine-specific (e.g. `THREE.Group` in three.js).
+ * @event TilesRendererBase#dispose-model
+ * @property {Object} scene - The engine-specific scene object being disposed.
+ * @property {Tile} tile - The tile the scene belonged to.
+ */
+/**
+ * Fired when a tile transitions between visible and hidden.
+ * The `scene` type is engine-specific (e.g. `THREE.Group` in three.js).
+ * @event TilesRendererBase#tile-visibility-change
+ * @property {Object} scene - The engine-specific scene object.
+ * @property {Tile} tile - The tile whose visibility changed.
+ * @property {boolean} visible - Whether the tile is now visible.
+ */
+/**
+ * Fired at the start of each `update()` call, before traversal begins.
+ * @event TilesRendererBase#update-before
+ */
+/**
+ * Fired at the end of each `update()` call, after traversal completes.
+ * @event TilesRendererBase#update-after
+ */
+/**
+ * Fired when a tile or tileset fails to load.
+ * @event TilesRendererBase#load-error
+ * @property {Tile|null} tile - The tile that failed, or null if a root tileset failed.
+ * @property {Error} error - The error that occurred.
+ * @property {string|URL} url - The URL that failed to load.
+ */
+/**
+ * Base class for 3D Tiles renderers. Manages tile loading, caching, traversal,
+ * and a plugin system for extending rendering behavior. Engine-specific renderers
+ * extend this class to add camera projection, scene management, and tile display.
+ */
+interface TilesRendererBaseEventMap {
+ 'needs-update': {};
+ 'load-content': {};
+ 'load-tileset': { tileset: Tileset; url: string };
+ 'load-root-tileset': { tileset: Tileset; url: string };
+ 'tiles-load-start': {};
+ 'tiles-load-end': {};
+ 'tile-download-start': { tile: Tile; uri: string };
+ 'load-model': { scene: TScene; tile: Tile; url: string };
+ 'dispose-model': { scene: TScene; tile: Tile };
+ 'tile-visibility-change': { scene: TScene; tile: Tile; visible: boolean };
+ 'update-before': {};
+ 'update-after': {};
+ 'load-error': { tile: Tile | null; error: Error; url: string | URL };
+}
+
+declare class TilesRendererBase {
+ /**
+ * @param {string} [url] - URL of the root tileset JSON to load.
+ */
+ constructor(url?: string);
+ /**
+ * Root tile of the loaded root tileset, or null if not yet loaded.
+ * @type {Tile|null}
+ */
+ get root(): Tile | null;
+ get rootTileSet(): Tileset;
+ /**
+ * Fraction of tiles loaded since the last idle state, from 0 (nothing loaded) to 1 (all loaded).
+ * @type {number}
+ */
+ get loadProgress(): number;
+ set errorThreshold(v: number);
+ get errorThreshold(): number;
+ rootLoadingState: number;
+ /**
+ * The loaded root tileset object, or null if not yet loaded.
+ * @type {Tileset|null}
+ * @readonly
+ */
+ readonly rootTileset: Tileset | null;
+ rootURL: string;
+ /**
+ * Options passed to `fetch` when loading tile and tileset resources.
+ * @type {RequestInit}
+ */
+ fetchOptions: RequestInit;
+ plugins: any[];
+ queuedTiles: any[];
+ cachedSinceLoadComplete: Set;
+ isLoading: boolean;
+ processedTiles: WeakSet