u-space 0.0.30 → 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/getTransferables-C97JPUVf.cjs +1 -0
- package/dist/getTransferables-DrzSmiCR.js +43 -0
- package/dist/index.cjs +3 -3
- package/dist/index.js +1549 -1026
- package/dist/modelDecodeProtocol-D1Apm9iG.cjs +1 -0
- package/dist/modelDecodeProtocol-wDB7ksYw.js +56 -0
- package/dist/src/loaders/ModelDecodeWorkerClient.d.ts +31 -0
- package/dist/src/loaders/ModelLoaderManager.d.ts +15 -2
- package/dist/src/loaders/buildDecodedGltfModel.d.ts +4 -0
- package/dist/src/loaders/index.d.ts +1 -0
- package/dist/src/objects/Model.d.ts +1 -0
- package/dist/src/worker/decodeGltfModel.d.ts +10 -0
- package/dist/src/worker/getTransferables.d.ts +1 -0
- package/dist/src/worker/index.d.ts +1 -0
- package/dist/src/worker/installWorkerImageLoader.d.ts +3 -0
- package/dist/src/worker/model-decoder.d.ts +13 -0
- package/dist/src/worker/modelDecodeProtocol.d.ts +205 -0
- package/dist/src/worker/workerImageUtils.d.ts +8 -0
- package/dist/worker/index.cjs +1 -1
- package/dist/worker/index.js +8 -6
- package/dist/worker/model-decoder.cjs +1 -0
- package/dist/worker/model-decoder.js +339 -0
- package/dist/worker/runtime.cjs +1 -1
- package/dist/worker/runtime.js +202 -208
- package/dist/workerImageUtils-lmOMyTQN.cjs +1 -0
- package/dist/workerImageUtils-mQD3TQ1N.js +105 -0
- package/docs/api-viewer.md +45 -1
- package/docs/changelog.md +15 -0
- package/docs/examples-guide.md +9 -3
- package/docs/getting-started.md +1 -1
- package/docs/index.md +1 -1
- package/docs/mcp.md +5 -3
- package/docs/release.md +5 -3
- package/package.json +9 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function h(n){const r=n.nodes??[];if(r.length>1e5)throw new Error(`Decoded glTF contains ${r.length} nodes; the safe limit is 100000.`);const D=new Uint8Array(r.length);for(let e=0;e<r.length;e++){const d=r[e].children??[],c=new Set;for(const o of d){if(!Number.isInteger(o)||o<0||o>=r.length)throw new Error(`Decoded glTF node ${e} references invalid child ${o}.`);if(c.has(o))throw new Error(`Decoded glTF node ${e} repeats child ${o}.`);if(c.add(o),D[o]++,D[o]>1)throw new Error(`Decoded glTF node ${o} has multiple parents.`)}}const t=new Uint8Array(r.length),E=(e,d)=>{if(d>512)throw new Error("Decoded glTF node graph exceeds the safe depth of 512.");if(t[e]===1)throw new Error(`Decoded glTF node graph contains a cycle at ${e}.`);if(t[e]!==2){t[e]=1;for(const c of r[e].children??[])E(c,d+1);t[e]=2}};for(let e=0;e<r.length;e++)E(e,1);const s=n.scene??0,l=n.scenes?.[s];if(!l)throw new Error(`Decoded glTF references missing scene ${s}.`);const i=new Set;for(const e of l.nodes??[]){if(!Number.isInteger(e)||e<0||e>=r.length)throw new Error(`Decoded glTF scene ${s} references invalid node ${e}.`);if(i.has(e))throw new Error(`Decoded glTF scene ${s} repeats root node ${e}.`);if(i.add(e),D[e]>0)throw new Error(`Decoded glTF scene root ${e} is also referenced as a child.`)}}class a extends Error{name="UnsupportedModelDecodeError";constructor(r){super(r)}}exports.MODEL_DECODE_PROTOCOL_VERSION=3;exports.UnsupportedModelDecodeError=a;exports.validateDecodedGltfNodeGraph=h;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const h = 3;
|
|
2
|
+
function a(n) {
|
|
3
|
+
const r = n.nodes ?? [];
|
|
4
|
+
if (r.length > 1e5)
|
|
5
|
+
throw new Error(
|
|
6
|
+
`Decoded glTF contains ${r.length} nodes; the safe limit is 100000.`
|
|
7
|
+
);
|
|
8
|
+
const D = new Uint8Array(r.length);
|
|
9
|
+
for (let e = 0; e < r.length; e++) {
|
|
10
|
+
const c = r[e].children ?? [], d = /* @__PURE__ */ new Set();
|
|
11
|
+
for (const o of c) {
|
|
12
|
+
if (!Number.isInteger(o) || o < 0 || o >= r.length)
|
|
13
|
+
throw new Error(`Decoded glTF node ${e} references invalid child ${o}.`);
|
|
14
|
+
if (d.has(o))
|
|
15
|
+
throw new Error(`Decoded glTF node ${e} repeats child ${o}.`);
|
|
16
|
+
if (d.add(o), D[o]++, D[o] > 1)
|
|
17
|
+
throw new Error(`Decoded glTF node ${o} has multiple parents.`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const t = new Uint8Array(r.length), i = (e, c) => {
|
|
21
|
+
if (c > 512)
|
|
22
|
+
throw new Error(
|
|
23
|
+
"Decoded glTF node graph exceeds the safe depth of 512."
|
|
24
|
+
);
|
|
25
|
+
if (t[e] === 1)
|
|
26
|
+
throw new Error(`Decoded glTF node graph contains a cycle at ${e}.`);
|
|
27
|
+
if (t[e] !== 2) {
|
|
28
|
+
t[e] = 1;
|
|
29
|
+
for (const d of r[e].children ?? []) i(d, c + 1);
|
|
30
|
+
t[e] = 2;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
for (let e = 0; e < r.length; e++) i(e, 1);
|
|
34
|
+
const s = n.scene ?? 0, l = n.scenes?.[s];
|
|
35
|
+
if (!l) throw new Error(`Decoded glTF references missing scene ${s}.`);
|
|
36
|
+
const E = /* @__PURE__ */ new Set();
|
|
37
|
+
for (const e of l.nodes ?? []) {
|
|
38
|
+
if (!Number.isInteger(e) || e < 0 || e >= r.length)
|
|
39
|
+
throw new Error(`Decoded glTF scene ${s} references invalid node ${e}.`);
|
|
40
|
+
if (E.has(e))
|
|
41
|
+
throw new Error(`Decoded glTF scene ${s} repeats root node ${e}.`);
|
|
42
|
+
if (E.add(e), D[e] > 0)
|
|
43
|
+
throw new Error(`Decoded glTF scene root ${e} is also referenced as a child.`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
class f extends Error {
|
|
47
|
+
name = "UnsupportedModelDecodeError";
|
|
48
|
+
constructor(r) {
|
|
49
|
+
super(r);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
h as M,
|
|
54
|
+
f as U,
|
|
55
|
+
a as v
|
|
56
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LoadingManager, Object3D } from 'three/webgpu';
|
|
2
|
+
import { type DecodedGltfModelPacket, type ModelDecodeRequestOptions } from '../worker/modelDecodeProtocol';
|
|
3
|
+
type DecodeLoadingManager = Pick<LoadingManager, 'resolveURL' | 'itemStart' | 'itemEnd' | 'itemError'>;
|
|
4
|
+
export interface ModelDecodeWorkerClientOptions {
|
|
5
|
+
onFatal?(error: ModelDecodeWorkerUnavailableError): void;
|
|
6
|
+
}
|
|
7
|
+
export interface ModelDecodeWorkerLoadOptions extends ModelDecodeRequestOptions {
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
loadingManager?: DecodeLoadingManager;
|
|
10
|
+
}
|
|
11
|
+
export declare class ModelDecodeWorkerUnavailableError extends Error {
|
|
12
|
+
name: string;
|
|
13
|
+
constructor(message: string, options?: ErrorOptions);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Reuses transferred bitmap identities so equal textures keep one batch key.
|
|
17
|
+
* The lookup is an LRU: evicting an entry drops only this client's strong
|
|
18
|
+
* reference; existing Three.js textures continue to own and use the bitmap.
|
|
19
|
+
*/
|
|
20
|
+
export declare function reuseDecodedImageContent(packet: DecodedGltfModelPacket, imagesByContent: Map<string, ImageBitmap>, maxEntries?: number): string[];
|
|
21
|
+
/** Render-Worker side client for the acknowledged model decoder Worker. */
|
|
22
|
+
export declare class ModelDecodeWorkerClient {
|
|
23
|
+
#private;
|
|
24
|
+
readonly worker: Worker;
|
|
25
|
+
constructor(worker: Worker, options?: ModelDecodeWorkerClientOptions);
|
|
26
|
+
get disposed(): boolean;
|
|
27
|
+
supports(url: string): boolean;
|
|
28
|
+
loadAsync(url: string, options?: ModelDecodeWorkerLoadOptions): Promise<Object3D>;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FileLoader, type Object3D, type WebGPURenderer
|
|
1
|
+
import { FileLoader, LoadingManager, type Object3D, type WebGPURenderer } from 'three/webgpu';
|
|
2
2
|
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
|
3
3
|
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
|
|
4
4
|
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
|
|
@@ -10,6 +10,7 @@ import { SBMLoader } from './SBMLoader';
|
|
|
10
10
|
import type { InteractionEventMap } from '../interactions';
|
|
11
11
|
export interface LoadParameters {
|
|
12
12
|
persistent?: boolean;
|
|
13
|
+
signal?: AbortSignal;
|
|
13
14
|
}
|
|
14
15
|
export declare class ModelLoaderManager {
|
|
15
16
|
private static CACHE_NAME;
|
|
@@ -22,6 +23,15 @@ export declare class ModelLoaderManager {
|
|
|
22
23
|
static fbxLoader: FBXLoader;
|
|
23
24
|
static objLoader: OBJLoader;
|
|
24
25
|
static stlLoader: STLLoader;
|
|
26
|
+
private static decodeWorkerClient;
|
|
27
|
+
/**
|
|
28
|
+
* Routes supported static glTF/GLB/SBMX models through a dedicated decoder
|
|
29
|
+
* Worker. ModelLoaderManager owns the supplied Worker and terminates it when
|
|
30
|
+
* replaced or cleared. The returned disposer only clears this specific
|
|
31
|
+
* Worker, so a late owner cleanup cannot terminate a newer replacement.
|
|
32
|
+
*/
|
|
33
|
+
static setDecodeWorker(worker: Worker | null): () => void;
|
|
34
|
+
static get decodeWorkerEnabled(): boolean;
|
|
25
35
|
static setLoadingManager(loadingManager: LoadingManager): void;
|
|
26
36
|
/**
|
|
27
37
|
* Set the renderer to enable KTX2 support and other renderer-dependent features.
|
|
@@ -36,5 +46,8 @@ export declare class ModelLoaderManager {
|
|
|
36
46
|
*/
|
|
37
47
|
static setKTX2Path(path: string): void;
|
|
38
48
|
static loadAsync(url: string, parameters?: LoadParameters): Promise<Object3D<InteractionEventMap>>;
|
|
39
|
-
private static
|
|
49
|
+
private static configureGltfLoader;
|
|
50
|
+
private static createParseLoadingManager;
|
|
51
|
+
private static loadSourceBuffer;
|
|
52
|
+
private static throwIfAborted;
|
|
40
53
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Object3D } from 'three/webgpu';
|
|
2
|
+
import { type DecodedGltfModelPacket } from '../worker/modelDecodeProtocol';
|
|
3
|
+
/** Rebuilds a supported static glTF packet in the Worker that owns Three.js. */
|
|
4
|
+
export declare function buildDecodedGltfModel(packet: DecodedGltfModelPacket): Object3D;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DecodedGltfModelPacket, type ModelDecodeRequestOptions } from './modelDecodeProtocol';
|
|
2
|
+
export interface ModelDecodeResourceHandle {
|
|
3
|
+
url: string;
|
|
4
|
+
complete(error?: unknown): void;
|
|
5
|
+
}
|
|
6
|
+
export interface ModelDecodeResourceResolver {
|
|
7
|
+
resolve(url: string, signal: AbortSignal): Promise<ModelDecodeResourceHandle>;
|
|
8
|
+
}
|
|
9
|
+
export declare function decodeGltfModelPacket(url: string, source: ArrayBuffer, options?: ModelDecodeRequestOptions, signal?: AbortSignal, resourceResolver?: ModelDecodeResourceResolver): Promise<DecodedGltfModelPacket>;
|
|
10
|
+
export declare function loadGltfModelPacket(url: string, options?: ModelDecodeRequestOptions, signal?: AbortSignal, resourceResolver?: ModelDecodeResourceResolver): Promise<DecodedGltfModelPacket>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getTransferables(value: unknown): Transferable[];
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export { clampWorkerImageDimensions, createWorkerImageBitmap } from './workerImageUtils';
|
|
1
2
|
/**
|
|
2
3
|
* Makes Three.js TextureLoader/CubeTextureLoader usable in a Worker by loading
|
|
3
4
|
* images with fetch() and createImageBitmap() instead of document.createElement('img').
|
|
5
|
+
* Images larger than WebGPU's portable 8192px limit are downscaled before
|
|
6
|
+
* decoding so they cannot invalidate the device's texture bindings.
|
|
4
7
|
*/
|
|
5
8
|
export declare function installWorkerImageLoader(): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ModelDecodeWorkerRequest, type ModelDecodeWorkerResponse } from './modelDecodeProtocol';
|
|
2
|
+
export * from './modelDecodeProtocol';
|
|
3
|
+
interface DecodeWorkerScope {
|
|
4
|
+
addEventListener(type: 'message', listener: (event: MessageEvent<ModelDecodeWorkerRequest>) => void): void;
|
|
5
|
+
postMessage(message: ModelDecodeWorkerResponse, transfer?: Transferable[]): void;
|
|
6
|
+
close(): void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Installs a serial, acknowledged static glTF/SBMX decoder in the current
|
|
10
|
+
* dedicated Worker. Only one decoded packet may be in flight at a time so a
|
|
11
|
+
* large scene cannot fill the render Worker's message queue with model data.
|
|
12
|
+
*/
|
|
13
|
+
export declare function installModelDecodeWorker(scope?: DecodeWorkerScope): void;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export declare const MODEL_DECODE_PROTOCOL_VERSION: 3;
|
|
2
|
+
export interface SerializedModelDecodeError {
|
|
3
|
+
message: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
stack?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ModelDecodeRequestOptions {
|
|
8
|
+
persistent?: boolean;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
credentials?: RequestCredentials;
|
|
11
|
+
/** Original absolute model URL used to resolve relative glTF dependencies. */
|
|
12
|
+
resourceBaseUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface GltfBufferDefinition {
|
|
15
|
+
byteLength: number;
|
|
16
|
+
uri?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface GltfBufferViewDefinition {
|
|
20
|
+
buffer: number;
|
|
21
|
+
byteOffset?: number;
|
|
22
|
+
byteLength: number;
|
|
23
|
+
byteStride?: number;
|
|
24
|
+
target?: number;
|
|
25
|
+
name?: string;
|
|
26
|
+
extensions?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
export interface GltfAccessorDefinition {
|
|
29
|
+
bufferView?: number;
|
|
30
|
+
byteOffset?: number;
|
|
31
|
+
componentType: number;
|
|
32
|
+
normalized?: boolean;
|
|
33
|
+
count: number;
|
|
34
|
+
type: string;
|
|
35
|
+
min?: number[];
|
|
36
|
+
max?: number[];
|
|
37
|
+
sparse?: unknown;
|
|
38
|
+
name?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface GltfTextureInfo {
|
|
41
|
+
index: number;
|
|
42
|
+
texCoord?: number;
|
|
43
|
+
scale?: number;
|
|
44
|
+
strength?: number;
|
|
45
|
+
extensions?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
export interface GltfMaterialDefinition {
|
|
48
|
+
name?: string;
|
|
49
|
+
pbrMetallicRoughness?: {
|
|
50
|
+
baseColorFactor?: number[];
|
|
51
|
+
baseColorTexture?: GltfTextureInfo;
|
|
52
|
+
metallicFactor?: number;
|
|
53
|
+
roughnessFactor?: number;
|
|
54
|
+
metallicRoughnessTexture?: GltfTextureInfo;
|
|
55
|
+
};
|
|
56
|
+
normalTexture?: GltfTextureInfo;
|
|
57
|
+
occlusionTexture?: GltfTextureInfo;
|
|
58
|
+
emissiveTexture?: GltfTextureInfo;
|
|
59
|
+
emissiveFactor?: number[];
|
|
60
|
+
alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';
|
|
61
|
+
alphaCutoff?: number;
|
|
62
|
+
doubleSided?: boolean;
|
|
63
|
+
extras?: unknown;
|
|
64
|
+
extensions?: Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
export interface GltfPrimitiveDefinition {
|
|
67
|
+
attributes: Record<string, number>;
|
|
68
|
+
indices?: number;
|
|
69
|
+
material?: number;
|
|
70
|
+
mode?: number;
|
|
71
|
+
targets?: unknown[];
|
|
72
|
+
extensions?: Record<string, unknown>;
|
|
73
|
+
}
|
|
74
|
+
export interface GltfMeshDefinition {
|
|
75
|
+
name?: string;
|
|
76
|
+
primitives: GltfPrimitiveDefinition[];
|
|
77
|
+
extras?: unknown;
|
|
78
|
+
}
|
|
79
|
+
export interface GltfNodeDefinition {
|
|
80
|
+
name?: string;
|
|
81
|
+
mesh?: number;
|
|
82
|
+
camera?: number;
|
|
83
|
+
children?: number[];
|
|
84
|
+
matrix?: number[];
|
|
85
|
+
translation?: number[];
|
|
86
|
+
rotation?: number[];
|
|
87
|
+
scale?: number[];
|
|
88
|
+
weights?: number[];
|
|
89
|
+
skin?: number;
|
|
90
|
+
extras?: unknown;
|
|
91
|
+
extensions?: Record<string, unknown>;
|
|
92
|
+
}
|
|
93
|
+
export interface GltfSceneDefinition {
|
|
94
|
+
name?: string;
|
|
95
|
+
nodes?: number[];
|
|
96
|
+
extras?: unknown;
|
|
97
|
+
}
|
|
98
|
+
export interface GltfImageDefinition {
|
|
99
|
+
name?: string;
|
|
100
|
+
uri?: string;
|
|
101
|
+
mimeType?: string;
|
|
102
|
+
bufferView?: number;
|
|
103
|
+
}
|
|
104
|
+
export interface GltfSamplerDefinition {
|
|
105
|
+
name?: string;
|
|
106
|
+
magFilter?: number;
|
|
107
|
+
minFilter?: number;
|
|
108
|
+
wrapS?: number;
|
|
109
|
+
wrapT?: number;
|
|
110
|
+
}
|
|
111
|
+
export interface GltfTextureDefinition {
|
|
112
|
+
name?: string;
|
|
113
|
+
sampler?: number;
|
|
114
|
+
source?: number;
|
|
115
|
+
extensions?: Record<string, unknown>;
|
|
116
|
+
}
|
|
117
|
+
export interface GltfDocument {
|
|
118
|
+
asset: {
|
|
119
|
+
version: string;
|
|
120
|
+
generator?: string;
|
|
121
|
+
};
|
|
122
|
+
scene?: number;
|
|
123
|
+
scenes?: GltfSceneDefinition[];
|
|
124
|
+
nodes?: GltfNodeDefinition[];
|
|
125
|
+
meshes?: GltfMeshDefinition[];
|
|
126
|
+
accessors?: GltfAccessorDefinition[];
|
|
127
|
+
bufferViews?: GltfBufferViewDefinition[];
|
|
128
|
+
buffers?: GltfBufferDefinition[];
|
|
129
|
+
materials?: GltfMaterialDefinition[];
|
|
130
|
+
textures?: GltfTextureDefinition[];
|
|
131
|
+
samplers?: GltfSamplerDefinition[];
|
|
132
|
+
images?: GltfImageDefinition[];
|
|
133
|
+
animations?: unknown[];
|
|
134
|
+
skins?: unknown[];
|
|
135
|
+
cameras?: unknown[];
|
|
136
|
+
extensionsUsed?: string[];
|
|
137
|
+
extensionsRequired?: string[];
|
|
138
|
+
extensions?: Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
export interface DecodedGltfModelPacket {
|
|
141
|
+
protocolVersion: typeof MODEL_DECODE_PROTOCOL_VERSION;
|
|
142
|
+
kind: 'gltf-static';
|
|
143
|
+
url: string;
|
|
144
|
+
document: GltfDocument;
|
|
145
|
+
buffers: ArrayBuffer[];
|
|
146
|
+
images: ImageBitmap[];
|
|
147
|
+
/** Stable content identities used to preserve material batching across models. */
|
|
148
|
+
imageKeys: string[];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Validates the parts of the glTF node graph that would otherwise make
|
|
152
|
+
* recursive Object3D reconstruction unsafe. glTF nodes form a forest: a node
|
|
153
|
+
* cannot be repeated under one parent, have multiple parents, or form cycles.
|
|
154
|
+
*/
|
|
155
|
+
export declare function validateDecodedGltfNodeGraph(document: GltfDocument): void;
|
|
156
|
+
export type ModelDecodeWorkerRequest = {
|
|
157
|
+
type: 'decode';
|
|
158
|
+
id: number;
|
|
159
|
+
url: string;
|
|
160
|
+
options: ModelDecodeRequestOptions;
|
|
161
|
+
} | {
|
|
162
|
+
type: 'cancel';
|
|
163
|
+
id: number;
|
|
164
|
+
} | {
|
|
165
|
+
type: 'ack';
|
|
166
|
+
id: number;
|
|
167
|
+
} | {
|
|
168
|
+
type: 'resource-resolved';
|
|
169
|
+
id: number;
|
|
170
|
+
resourceId: number;
|
|
171
|
+
url?: string;
|
|
172
|
+
error?: SerializedModelDecodeError;
|
|
173
|
+
} | {
|
|
174
|
+
type: 'dispose';
|
|
175
|
+
};
|
|
176
|
+
export type ModelDecodeWorkerResponse = {
|
|
177
|
+
type: 'decoded';
|
|
178
|
+
id: number;
|
|
179
|
+
packet: DecodedGltfModelPacket;
|
|
180
|
+
} | {
|
|
181
|
+
type: 'unsupported';
|
|
182
|
+
id: number;
|
|
183
|
+
reason: string;
|
|
184
|
+
} | {
|
|
185
|
+
type: 'error';
|
|
186
|
+
id: number;
|
|
187
|
+
error: SerializedModelDecodeError;
|
|
188
|
+
} | {
|
|
189
|
+
type: 'resolve-resource';
|
|
190
|
+
id: number;
|
|
191
|
+
resourceId: number;
|
|
192
|
+
url: string;
|
|
193
|
+
} | {
|
|
194
|
+
type: 'resource-complete';
|
|
195
|
+
id: number;
|
|
196
|
+
resourceId: number;
|
|
197
|
+
ok: boolean;
|
|
198
|
+
error?: SerializedModelDecodeError;
|
|
199
|
+
} | {
|
|
200
|
+
type: 'disposed';
|
|
201
|
+
};
|
|
202
|
+
export declare class UnsupportedModelDecodeError extends Error {
|
|
203
|
+
name: string;
|
|
204
|
+
constructor(message: string);
|
|
205
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ImageDimensions {
|
|
2
|
+
width: number;
|
|
3
|
+
height: number;
|
|
4
|
+
}
|
|
5
|
+
export declare const MAX_WORKER_TEXTURE_DIMENSION_2D = 8192;
|
|
6
|
+
export declare function clampWorkerImageDimensions(width: number, height: number, maxDimension?: number): ImageDimensions | null;
|
|
7
|
+
export declare function createWorkerImageBitmap(blob: Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
|
8
|
+
export {};
|
package/dist/worker/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("../protocol-IUAzx0lk.cjs"),n=["click","dblclick","contextmenu","pointerdown","pointerup","pointermove","pointercancel","wheel"];function a(i){const e=i,t=i,s=i;return{type:i.type,pointerId:t.pointerId,pointerType:t.pointerType,button:e.button,buttons:e.buttons,altKey:e.altKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,movementX:e.movementX,movementY:e.movementY,clientX:e.clientX,clientY:e.clientY,offsetX:e.offsetX,offsetY:e.offsetY,pageX:e.pageX,pageY:e.pageY,screenX:e.screenX,screenY:e.screenY,deltaX:s.deltaX,deltaY:s.deltaY,deltaZ:s.deltaZ,deltaMode:s.deltaMode}}function o(i){const e=new Error(i.message);return e.name=i.name??"WorkerError",i.stack&&(e.stack=i.stack),e}class r extends EventTarget{el;worker;canvas;#u;#f;#r=null;#i=new Map;#b=0;#t=!1;#e=!1;#n=null;#o=null;#a=null;#h=new Map;#s=0;#p=0;constructor(e){super(),this.el=e.el,this.worker=e.worker,this.canvas=e.canvas??document.createElement("canvas"),this.#u=e.pixelRatio,this.#f=e.terminateWorkerOnDispose??!0,this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.display="block",this.canvas.style.touchAction="none",this.canvas.parentElement||this.el.appendChild(this.canvas)}static isSupported(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"&&typeof HTMLCanvasElement<"u"&&"transferControlToOffscreen"in HTMLCanvasElement.prototype}init(){if(this.#n)return this.#n;if(this.#e)return Promise.reject(new Error("OffscreenViewerHost has been disposed."));if(!r.isSupported())return Promise.reject(new Error("This browser does not support transferring a canvas to a Worker."));this.#n=new Promise((e,t)=>{this.#o=e,this.#a=t}),this.worker.addEventListener("message",this.#y),this.worker.addEventListener("error",this.#
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("../protocol-IUAzx0lk.cjs"),u=require("../getTransferables-C97JPUVf.cjs"),n=["click","dblclick","contextmenu","pointerdown","pointerup","pointermove","pointercancel","wheel"];function a(i){const e=i,t=i,s=i;return{type:i.type,pointerId:t.pointerId,pointerType:t.pointerType,button:e.button,buttons:e.buttons,altKey:e.altKey,ctrlKey:e.ctrlKey,metaKey:e.metaKey,shiftKey:e.shiftKey,movementX:e.movementX,movementY:e.movementY,clientX:e.clientX,clientY:e.clientY,offsetX:e.offsetX,offsetY:e.offsetY,pageX:e.pageX,pageY:e.pageY,screenX:e.screenX,screenY:e.screenY,deltaX:s.deltaX,deltaY:s.deltaY,deltaZ:s.deltaZ,deltaMode:s.deltaMode}}function o(i){const e=new Error(i.message);return e.name=i.name??"WorkerError",i.stack&&(e.stack=i.stack),e}class r extends EventTarget{el;worker;canvas;#u;#f;#r=null;#i=new Map;#b=0;#t=!1;#e=!1;#n=null;#o=null;#a=null;#h=new Map;#s=0;#p=0;constructor(e){super(),this.el=e.el,this.worker=e.worker,this.canvas=e.canvas??document.createElement("canvas"),this.#u=e.pixelRatio,this.#f=e.terminateWorkerOnDispose??!0,this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.display="block",this.canvas.style.touchAction="none",this.canvas.parentElement||this.el.appendChild(this.canvas)}static isSupported(){return typeof Worker<"u"&&typeof OffscreenCanvas<"u"&&typeof HTMLCanvasElement<"u"&&"transferControlToOffscreen"in HTMLCanvasElement.prototype}init(){if(this.#n)return this.#n;if(this.#e)return Promise.reject(new Error("OffscreenViewerHost has been disposed."));if(!r.isSupported())return Promise.reject(new Error("This browser does not support transferring a canvas to a Worker."));this.#n=new Promise((e,t)=>{this.#o=e,this.#a=t}),this.worker.addEventListener("message",this.#y),this.worker.addEventListener("error",this.#g),this.#z(),this.#T();try{const e=this.canvas.transferControlToOffscreen(),t={type:"init",canvas:e,size:this.#v()};this.worker.postMessage(t,[e])}catch(e){const t=e instanceof Error?e:new Error(String(e));this.#d(t),this.#l()}return this.#n}request(e,t){if(this.#e)return Promise.reject(new Error("OffscreenViewerHost has been disposed."));if(!this.#t)return Promise.reject(new Error("The Worker viewer has not initialized yet."));const s=++this.#b,h={type:"request",id:s,command:e,payload:t};return this.worker.postMessage(h),new Promise((c,l)=>{this.#i.set(s,{resolve:d=>c(d),reject:l})})}dispose(){const e=new Error("OffscreenViewerHost has been disposed.");if(!this.#d(e))return;const t={type:"dispose"};this.worker.postMessage(t),this.#p=window.setTimeout(this.#l,1e3)}#z(){for(const e of n)this.canvas.addEventListener(e,this.#m,{passive:e!=="wheel"&&e!=="contextmenu"})}#M(){for(const e of n)this.canvas.removeEventListener(e,this.#m)}#T(){this.#r=new ResizeObserver(this.#c),this.#r.observe(this.el),window.addEventListener("resize",this.#c)}#v(){const e=this.canvas.getBoundingClientRect();return{width:Math.max(1,e.width||this.el.clientWidth),height:Math.max(1,e.height||this.el.clientHeight),top:e.top,left:e.left,pixelRatio:this.#u??Math.min(window.devicePixelRatio,1.5)}}#c=()=>{if(!this.#t||this.#e)return;const e={type:"resize",size:this.#v()};this.worker.postMessage(e)};#m=e=>{(e.type==="wheel"||e.type==="contextmenu")&&e.preventDefault();const t=e;if(e.type==="pointerdown")try{this.canvas.setPointerCapture(t.pointerId)}catch{}if(e.type==="pointerup"||e.type==="pointercancel"){this.#w();try{this.canvas.hasPointerCapture(t.pointerId)&&this.canvas.releasePointerCapture(t.pointerId)}catch{}}const s=a(e);if(e.type==="pointermove"){this.#h.set(s.pointerId??-1,s),this.#s||(this.#s=requestAnimationFrame(this.#w));return}this.#E(s)};#w=()=>{this.#s=0;for(const e of this.#h.values())this.#E(e);this.#h.clear()};#E(e){if(!this.#t||this.#e)return;const t={type:"dom-event",event:e};this.worker.postMessage(t)}#y=e=>{const t=e.data;if(!(this.#e&&t.type!=="error"&&t.type!=="disposed"))switch(t.type){case"initialized":if(this.#e)break;this.#t=!0,this.#o?.(),this.#o=null,this.#a=null,this.#c(),this.dispatchEvent(new Event("initialized"));break;case"ready":this.dispatchEvent(new CustomEvent("ready",{detail:t.detail}));break;case"status":this.dispatchEvent(new CustomEvent("status",{detail:t.message}));break;case"stats":this.dispatchEvent(new CustomEvent("stats",{detail:t.stats}));break;case"event":this.dispatchEvent(new CustomEvent(t.eventType,{detail:t.detail}));break;case"response":{const s=this.#i.get(t.id);if(!s)break;this.#i.delete(t.id),t.error?s.reject(o(t.error)):s.resolve(t.result);break}case"error":{const s=o(t.error);this.#t||this.#k(s),this.dispatchEvent(new CustomEvent("error",{detail:s}));break}case"disposed":this.#d(new Error("The Worker viewer has been disposed.")),this.dispatchEvent(new Event("disposed")),this.#l();break}};#g=e=>{const t=e.error instanceof Error?e.error:new Error(e.message);this.#d(t),this.dispatchEvent(new CustomEvent("error",{detail:t})),this.#l()};#l=()=>{window.clearTimeout(this.#p),this.#p=0,this.worker.removeEventListener("message",this.#y),this.worker.removeEventListener("error",this.#g),this.#f&&this.worker.terminate()};#d(e){if(this.#e)return!1;this.#e=!0,this.#s&&cancelAnimationFrame(this.#s),this.#s=0,this.#h.clear(),this.#r?.disconnect(),this.#r=null,window.removeEventListener("resize",this.#c),this.#M(),this.#t||this.#k(e);for(const t of this.#i.values())t.reject(e);return this.#i.clear(),this.canvas.remove(),!0}#k(e){this.#a?.(e),this.#o=null,this.#a=null}}exports.serializeError=p.serializeError;exports.getTransferables=u.getTransferables;exports.OffscreenViewerHost=r;exports.serializeDomEvent=a;
|
package/dist/worker/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { s as
|
|
1
|
+
import { s as u } from "../protocol-C-OMPz15.js";
|
|
2
|
+
import { g as m } from "../getTransferables-DrzSmiCR.js";
|
|
2
3
|
const r = [
|
|
3
4
|
"click",
|
|
4
5
|
"dblclick",
|
|
@@ -45,8 +46,8 @@ class o extends EventTarget {
|
|
|
45
46
|
el;
|
|
46
47
|
worker;
|
|
47
48
|
canvas;
|
|
48
|
-
#u;
|
|
49
49
|
#f;
|
|
50
|
+
#u;
|
|
50
51
|
#r = null;
|
|
51
52
|
#i = /* @__PURE__ */ new Map();
|
|
52
53
|
#b = 0;
|
|
@@ -59,7 +60,7 @@ class o extends EventTarget {
|
|
|
59
60
|
#s = 0;
|
|
60
61
|
#p = 0;
|
|
61
62
|
constructor(e) {
|
|
62
|
-
super(), this.el = e.el, this.worker = e.worker, this.canvas = e.canvas ?? document.createElement("canvas"), this.#
|
|
63
|
+
super(), this.el = e.el, this.worker = e.worker, this.canvas = e.canvas ?? document.createElement("canvas"), this.#f = e.pixelRatio, this.#u = e.terminateWorkerOnDispose ?? !0, this.canvas.style.width = "100%", this.canvas.style.height = "100%", this.canvas.style.display = "block", this.canvas.style.touchAction = "none", this.canvas.parentElement || this.el.appendChild(this.canvas);
|
|
63
64
|
}
|
|
64
65
|
static isSupported() {
|
|
65
66
|
return typeof Worker < "u" && typeof OffscreenCanvas < "u" && typeof HTMLCanvasElement < "u" && "transferControlToOffscreen" in HTMLCanvasElement.prototype;
|
|
@@ -124,7 +125,7 @@ class o extends EventTarget {
|
|
|
124
125
|
height: Math.max(1, e.height || this.el.clientHeight),
|
|
125
126
|
top: e.top,
|
|
126
127
|
left: e.left,
|
|
127
|
-
pixelRatio: this.#
|
|
128
|
+
pixelRatio: this.#f ?? Math.min(window.devicePixelRatio, 1.5)
|
|
128
129
|
};
|
|
129
130
|
}
|
|
130
131
|
#c = () => {
|
|
@@ -205,7 +206,7 @@ class o extends EventTarget {
|
|
|
205
206
|
this.#d(t), this.dispatchEvent(new CustomEvent("error", { detail: t })), this.#l();
|
|
206
207
|
};
|
|
207
208
|
#l = () => {
|
|
208
|
-
window.clearTimeout(this.#p), this.#p = 0, this.worker.removeEventListener("message", this.#y), this.worker.removeEventListener("error", this.#k), this.#
|
|
209
|
+
window.clearTimeout(this.#p), this.#p = 0, this.worker.removeEventListener("message", this.#y), this.worker.removeEventListener("error", this.#k), this.#u && this.worker.terminate();
|
|
209
210
|
};
|
|
210
211
|
#d(e) {
|
|
211
212
|
if (this.#e) return !1;
|
|
@@ -219,6 +220,7 @@ class o extends EventTarget {
|
|
|
219
220
|
}
|
|
220
221
|
export {
|
|
221
222
|
o as OffscreenViewerHost,
|
|
223
|
+
m as getTransferables,
|
|
222
224
|
d as serializeDomEvent,
|
|
223
|
-
|
|
225
|
+
u as serializeError
|
|
224
226
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("../getTransferables-C97JPUVf.cjs"),A=require("../workerImageUtils-lmOMyTQN.cjs"),w=require("../modelDecodeProtocol-D1Apm9iG.cjs"),D="u-space-model-loader-cache",S="SBMG----",F=1179937895,C=1313821514,U=5130562,k=new TextDecoder;function g(e){throw new w.UnsupportedModelDecodeError(e)}async function v(e,r,s,o=e,i=!1){const n=e.startsWith("data:")||e.startsWith("blob:");let l=!i;if(i&&!n)try{const u=new URL(e),c=new URL(o);l=(u.protocol==="http:"||u.protocol==="https:")&&u.origin===c.origin}catch{l=!1}const h=await fetch(e,n?{signal:s}:{signal:s,headers:l?r.headers:void 0,credentials:l?r.credentials:"omit"});if(!h.ok)throw new Error(`Failed to load model resource ${e}: ${h.status} ${h.statusText}`);return h}async function M(e,r,s,o,i,n,l){const h=$(e,r),u=n?await n.resolve(h,i):{url:h,complete(){}};try{const c=await v(u.url,o,i,s,!0),t=await l(c);return u.complete(),t}catch(c){throw u.complete(c),c}}async function B(e,r,s){if(r.persistent!==!1&&typeof caches<"u"){let o;try{o=await caches.open(D);const n=await o.match(e);if(n)return n.arrayBuffer()}catch(n){if(s.aborted)throw n;console.warn(`[ModelDecodeWorker] Failed to read Cache Storage for ${e}:`,n)}const i=await v(e,r,s);if(o)try{await o.put(e,i.clone())}catch(n){if(s.aborted)throw n;console.warn(`[ModelDecodeWorker] Failed to write Cache Storage for ${e}:`,n)}return i.arrayBuffer()}return(await v(e,r,s)).arrayBuffer()}function R(e){if(e.byteLength<8||k.decode(new Uint8Array(e,0,8))!==S)return e;const s=new Uint8Array(e.byteLength-8),o=new Uint8Array(e,8);for(let i=0;i<o.length;i++){const n=o[i];s[i]=n>>4&15|n<<4&240}return s.buffer}function G(e){const r=new DataView(e);if(e.byteLength>=12&&r.getUint32(0,!0)===F){const s=r.getUint32(8,!0);if(s>e.byteLength)throw new Error(`Invalid GLB length: expected ${s}, received ${e.byteLength}.`);let o=12,i;const n=[];for(;o+8<=s;){const l=r.getUint32(o,!0),h=r.getUint32(o+4,!0);if(o+=8,o+l>s)throw new Error("Invalid GLB chunk length.");const u=e.slice(o,o+l);h===C?i=JSON.parse(k.decode(u).replace(/\u0000+$/u,"")):h===U&&n.push(u),o+=l}if(!i)throw new Error("GLB does not contain a JSON chunk.");return{document:i,binaryChunks:n}}return{document:JSON.parse(k.decode(e).replace(/^\uFEFF/u,"")),binaryChunks:[]}}function V(e){e.asset?.version?.startsWith("2")||g("Only glTF 2.x static models are supported by the decode worker."),(e.extensionsRequired?.length||e.extensionsUsed?.length)&&g("glTF extensions are not supported by the decode worker."),e.animations?.length&&g("Animated glTF models must use the regular loader."),e.skins?.length&&g("Skinned glTF models must use the regular loader."),e.cameras?.length&&g("glTF cameras must use the regular loader."),w.validateDecodedGltfNodeGraph(e);for(const r of e.accessors??[])r.sparse&&g("Sparse glTF accessors must use the regular loader."),r.bufferView===void 0&&g("Accessors without a bufferView must use the regular loader."),["SCALAR","VEC2","VEC3","VEC4"].includes(r.type)||g(`Accessor type ${r.type} must use the regular loader.`),[5120,5121,5122,5123,5125,5126].includes(r.componentType)||g(`Accessor component type ${r.componentType} must use the regular loader.`);for(const r of e.bufferViews??[])r.extensions&&Object.keys(r.extensions).length>0&&g("Compressed glTF buffer views must use the regular loader.");for(const r of e.nodes??[])(r.skin!==void 0||r.weights?.length||r.camera!==void 0)&&g("Skinned, morphed, or camera glTF nodes must use the regular loader."),r.extensions&&Object.keys(r.extensions).length>0&&g("Extended glTF nodes must use the regular loader.");for(const r of e.meshes??[])for(const s of r.primitives)(s.mode??4)!==4&&g("Only triangle glTF primitives are supported."),s.targets?.length&&g("Morph targets must use the regular loader."),s.extensions&&Object.keys(s.extensions).length>0&&g("Extended glTF primitives must use the regular loader.");for(const r of e.materials??[])r.extensions&&Object.keys(r.extensions).length>0&&g("Extended glTF materials must use the regular loader.");for(const r of e.textures??[])r.extensions&&Object.keys(r.extensions).length>0&&g("Extended glTF textures must use the regular loader.")}function $(e,r){return e.startsWith("data:")||e.startsWith("blob:")?e:new URL(e,r).href}async function _(e,r,s,o,i,n,l){const h=[...r],u=[];for(const c of e.buffers??[]){let t;if(c.uri)t=await M(c.uri,s,o,i,n,l,a=>a.arrayBuffer());else{const a=h.shift();if(!a)throw new Error("glTF buffer is missing its GLB binary chunk.");t=a}if(t.byteLength<c.byteLength)throw new Error(`glTF buffer is truncated: expected ${c.byteLength}, received ${t.byteLength}.`);u.push(t),Reflect.deleteProperty(c,"uri")}return u}function I(e,r,s,o){const i=e.bufferViews?.[s];if(!i)throw new Error(`glTF image references missing bufferView ${s}.`);const n=r[i.buffer];if(!n)throw new Error(`glTF image references missing buffer ${i.buffer}.`);const l=i.byteOffset??0;return new Blob([new Uint8Array(n,l,i.byteLength)],{type:o??"application/octet-stream"})}async function N(e,r,s,o,i,n,l){const h=[],u=[];try{for(const c of e.images??[]){let t;if(c.uri)t=await M(c.uri,s,o,i,n,l,f=>f.blob());else if(c.bufferView!==void 0)t=I(e,r,c.bufferView,c.mimeType);else throw new Error("glTF image is missing both uri and bufferView.");if(n.aborted)throw n.reason??new DOMException("Aborted","AbortError");const a=await globalThis.crypto.subtle.digest("SHA-256",await t.arrayBuffer());if(n.aborted)throw n.reason??new DOMException("Aborted","AbortError");const d=Array.from(new Uint8Array(a),f=>f.toString(16).padStart(2,"0")).join("");u.push(`${t.type}:${t.size}:${d}`),h.push(await A.createWorkerImageBitmap(t,{imageOrientation:"flipY"})),Reflect.deleteProperty(c,"uri")}return{images:h,imageKeys:u}}catch(c){throw h.forEach(t=>t.close()),c}}async function P(e,r,s={},o=new AbortController().signal,i){const n=R(r),{document:l,binaryChunks:h}=G(n);V(l);const u=s.resourceBaseUrl??e,c=await _(l,h,u,e,s,o,i),{images:t,imageKeys:a}=await N(l,c,u,e,s,o,i);return{protocolVersion:w.MODEL_DECODE_PROTOCOL_VERSION,kind:"gltf-static",url:e,document:l,buffers:c,images:t,imageKeys:a}}async function W(e,r={},s=new AbortController().signal,o){const i=await B(e,r,s);return P(e,i,r,s,o)}function L(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:{message:String(e)}}function j(e=globalThis){const r=[],s=new Set;let o=null,i=!1,n=!1;const l=t=>new Promise(a=>{t.acknowledge=a}),h=(t,a)=>{for(const d of t.resources.values())d.cleanup(),d.reject(a);t.resources.clear()},u=t=>({async resolve(a,d){if(d.aborted)throw d.reason??new DOMException("Aborted","AbortError");const f=t.nextResourceId++,m=await new Promise((y,E)=>{const x=()=>{t.resources.delete(f),E(d.reason??new DOMException("Aborted","AbortError"))},b=()=>d.removeEventListener("abort",x);t.resources.set(f,{resolve(p){b(),t.resources.delete(f),y(p)},reject(p){b(),t.resources.delete(f),E(p)},cleanup:b}),d.addEventListener("abort",x,{once:!0});try{e.postMessage({type:"resolve-resource",id:t.id,resourceId:f,url:a})}catch(p){b(),t.resources.delete(f),E(p instanceof Error?p:new Error(String(p)))}});let O=!1;return{url:m,complete(y){O||(O=!0,e.postMessage({type:"resource-complete",id:t.id,resourceId:f,ok:y===void 0,error:y===void 0?void 0:L(y)}))}}}}),c=async()=>{if(!(i||n)){i=!0;try{for(;!n&&r.length>0;){const t=r.shift();if(s.delete(t.id))continue;const a={id:t.id,controller:new AbortController,nextResourceId:1,resources:new Map};o=a;try{const d=await W(t.url,t.options,a.controller.signal,u(a));if(s.delete(t.id)||n){d.images.forEach(f=>f.close());continue}try{e.postMessage({type:"decoded",id:t.id,packet:d},T.getTransferables(d))}catch(f){throw d.images.forEach(m=>m.close()),f}await l(a)}catch(d){const f=s.delete(t.id);if(a.controller.signal.aborted||f||n)continue;d instanceof w.UnsupportedModelDecodeError?e.postMessage({type:"unsupported",id:t.id,reason:d.message}):e.postMessage({type:"error",id:t.id,error:L(d)})}finally{h(a,new DOMException("Model decode request ended.","AbortError")),s.delete(t.id),o===a&&(o=null)}}}finally{i=!1,!n&&r.length>0&&c()}}};e.addEventListener("message",t=>{const a=t.data;if(a.type==="decode"){if(n)return;r.push(a),c();return}if(a.type==="cancel"){s.add(a.id),o?.id===a.id&&(o.controller.abort(),o.acknowledge?.());return}if(a.type==="ack"){o?.id===a.id&&o.acknowledge?.();return}if(a.type==="resource-resolved"){if(o?.id!==a.id)return;const d=o.resources.get(a.resourceId);if(!d)return;if(a.url!==void 0)d.resolve(a.url);else{const f=new Error(a.error?.message??"Failed to resolve model resource URL.");f.name=a.error?.name??"Error",f.stack=a.error?.stack,d.reject(f)}return}a.type==="dispose"&&(n=!0,r.length=0,o?.controller.abort(),o?.acknowledge?.(),e.postMessage({type:"disposed"}),e.close())})}exports.MODEL_DECODE_PROTOCOL_VERSION=w.MODEL_DECODE_PROTOCOL_VERSION;exports.UnsupportedModelDecodeError=w.UnsupportedModelDecodeError;exports.validateDecodedGltfNodeGraph=w.validateDecodedGltfNodeGraph;exports.installModelDecodeWorker=j;
|