@flighthq/scene3d-resources 0.3.0 → 0.3.1-next.320.fe56fc2
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/resolveScene3DResources.d.ts +2 -2
- package/dist/resolveScene3DResources.d.ts.map +1 -1
- package/dist/resolveScene3DResources.js +22 -25
- package/dist/resolveScene3DResources.js.map +1 -1
- package/package.json +13 -13
- package/src/getScene3DResourceTextures.test.ts +1 -0
- package/src/resolveScene3DResources.test.ts +53 -35
- package/src/revealScene3DResourcesOnResolve.test.ts +1 -0
- package/src/sceneResourceResolver.test.ts +1 -0
- package/src/sceneResourceSignals.test.ts +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function resolveOneScene3DResourceTexture(resolver: Readonly<Scene3DResourceResolver>, ref:
|
|
1
|
+
import type { ImageResourceReference, ResolveScene3DResourcesOptions, Scene3D, Scene3DResources, Scene3DResourceResolver, TextureSource, UpdateScene3DResourceStreamingOptions } from '@flighthq/types/contract';
|
|
2
|
+
export declare function resolveOneScene3DResourceTexture(resolver: Readonly<Scene3DResourceResolver>, ref: ImageResourceReference, signal: AbortSignal): Promise<TextureSource | null>;
|
|
3
3
|
export declare function resolveScene3DResources(scene: Readonly<Scene3D>, resolver: Scene3DResourceResolver, options?: Readonly<ResolveScene3DResourcesOptions>): Scene3DResources;
|
|
4
4
|
export declare function updateScene3DResourceStreaming(scene: Readonly<Scene3D>, resolver: Scene3DResourceResolver, options?: Readonly<UpdateScene3DResourceStreamingOptions>): Scene3DResources;
|
|
5
5
|
//# sourceMappingURL=resolveScene3DResources.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveScene3DResources.d.ts","sourceRoot":"","sources":["../src/resolveScene3DResources.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"resolveScene3DResources.d.ts","sourceRoot":"","sources":["../src/resolveScene3DResources.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,gBAAgB,EAChB,uBAAuB,EAGvB,aAAa,EACb,qCAAqC,EACtC,MAAM,0BAA0B,CAAC;AAUlC,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,QAAQ,CAAC,uBAAuB,CAAC,EAC3C,GAAG,EAAE,sBAAsB,EAC3B,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAE/B;AAMD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EACxB,QAAQ,EAAE,uBAAuB,EACjC,OAAO,CAAC,EAAE,QAAQ,CAAC,8BAA8B,CAAC,GACjD,gBAAgB,CA0ClB;AAID,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EACxB,QAAQ,EAAE,uBAAuB,EACjC,OAAO,CAAC,EAAE,QAAQ,CAAC,qCAAqC,CAAC,GACxD,gBAAgB,CAQlB"}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import { createImageResourceFailure,
|
|
1
|
+
import { createImageResourceFailure, resolveImageResourceReference } from '@flighthq/image/contract';
|
|
2
2
|
import { queueResourceLoad } from '@flighthq/loader/contract';
|
|
3
3
|
import { emitSignal } from '@flighthq/signals/contract';
|
|
4
|
-
import { ImageResourceFailureKind,
|
|
4
|
+
import { ImageResourceFailureKind, ResourceResolutionState } from '@flighthq/types/contract';
|
|
5
5
|
import { Scene3DResourceResolverRuntimeKey } from '@flighthq/types/contract';
|
|
6
6
|
import { getScene3DResourceTextures, getScene3DTextureResourceReference } from './getScene3DResourceTextures';
|
|
7
|
-
// Resolves one texture's ref to
|
|
7
|
+
// Resolves one texture's ref to a TextureSource (or null for an expected failure): Embedded bytes
|
|
8
8
|
// decode through @flighthq/image; External URIs go through the resolver's fetch seam. Cancellation is
|
|
9
9
|
// carried by `signal` (both paths reject on abort). Exported for direct testing of the two ref kinds.
|
|
10
10
|
export function resolveOneScene3DResourceTexture(resolver, ref, signal) {
|
|
11
|
-
|
|
12
|
-
return loadImageResourceFromBytes(ref.bytes, ref.mimeType ?? undefined, signal);
|
|
13
|
-
}
|
|
14
|
-
return resolver.fetch(ref, signal);
|
|
11
|
+
return resolveImageResourceReference(ref, resolver.fetch, signal);
|
|
15
12
|
}
|
|
16
13
|
// Reconciles the selected working set entirely synchronously. It groups shared references, recognizes
|
|
17
|
-
// content already present on a texture, and binds resolver-cached
|
|
14
|
+
// content already present on a texture, and binds resolver-cached sources to every selected subscriber.
|
|
18
15
|
// Acquisition, cancellation, Promise scheduling, and priority policy belong to the explicit update/load
|
|
19
16
|
// operations.
|
|
20
17
|
export function resolveScene3DResources(scene, resolver, options) {
|
|
@@ -27,9 +24,9 @@ export function resolveScene3DResources(scene, resolver, options) {
|
|
|
27
24
|
const ref = getScene3DTextureResourceReference(scene, texture);
|
|
28
25
|
if (ref == null)
|
|
29
26
|
continue;
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
32
|
-
runtime.resolved.set(ref,
|
|
27
|
+
const source = texture.dimension === '2d' ? texture.source : null;
|
|
28
|
+
if (source !== null) {
|
|
29
|
+
runtime.resolved.set(ref, source);
|
|
33
30
|
ref.failure = null;
|
|
34
31
|
ref.state = ResourceResolutionState.Resolved;
|
|
35
32
|
}
|
|
@@ -45,8 +42,8 @@ export function resolveScene3DResources(scene, resolver, options) {
|
|
|
45
42
|
const resolved = [];
|
|
46
43
|
const unresolved = [];
|
|
47
44
|
for (const [ref, subscribers] of working) {
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
45
|
+
const source = runtime.resolved.get(ref);
|
|
46
|
+
if (source === undefined) {
|
|
50
47
|
if (ref.state === ResourceResolutionState.Resolved)
|
|
51
48
|
ref.state = ResourceResolutionState.Unresolved;
|
|
52
49
|
unresolved.push({ ref, textures: subscribers });
|
|
@@ -55,9 +52,9 @@ export function resolveScene3DResources(scene, resolver, options) {
|
|
|
55
52
|
ref.failure = null;
|
|
56
53
|
ref.state = ResourceResolutionState.Resolved;
|
|
57
54
|
for (let i = 0; i < subscribers.length; i++) {
|
|
58
|
-
bindResolvedScene3DResource(resolver, subscribers[i], ref,
|
|
55
|
+
bindResolvedScene3DResource(resolver, subscribers[i], ref, source);
|
|
59
56
|
}
|
|
60
|
-
resolved.push({
|
|
57
|
+
resolved.push({ ref, source, textures: subscribers });
|
|
61
58
|
}
|
|
62
59
|
return { resolved, scene, unresolved };
|
|
63
60
|
}
|
|
@@ -95,16 +92,16 @@ function cancelDroppedResolutions(resolver, working) {
|
|
|
95
92
|
}
|
|
96
93
|
}
|
|
97
94
|
}
|
|
98
|
-
function finishScene3DResourceResolution(resolver, ref, entry,
|
|
95
|
+
function finishScene3DResourceResolution(resolver, ref, entry, source) {
|
|
99
96
|
const runtime = resolver[Scene3DResourceResolverRuntimeKey];
|
|
100
97
|
// Ignore a late settle whose entry was already cancelled or replaced by a newer request.
|
|
101
98
|
if (runtime.inFlight.get(ref) !== entry)
|
|
102
99
|
return;
|
|
103
100
|
runtime.inFlight.delete(ref);
|
|
104
|
-
if (
|
|
105
|
-
ref.failure
|
|
101
|
+
if (source === null) {
|
|
102
|
+
ref.failure ??= {
|
|
106
103
|
kind: ImageResourceFailureKind.Unavailable,
|
|
107
|
-
message: 'Image resource resolution returned no
|
|
104
|
+
message: 'Image resource resolution returned no source',
|
|
108
105
|
name: null,
|
|
109
106
|
};
|
|
110
107
|
ref.state = ResourceResolutionState.Failed;
|
|
@@ -112,11 +109,11 @@ function finishScene3DResourceResolution(resolver, ref, entry, image) {
|
|
|
112
109
|
emitScene3DResourceEvent(resolver, texture, ref, false);
|
|
113
110
|
return;
|
|
114
111
|
}
|
|
115
|
-
runtime.resolved.set(ref,
|
|
112
|
+
runtime.resolved.set(ref, source);
|
|
116
113
|
ref.failure = null;
|
|
117
114
|
ref.state = ResourceResolutionState.Resolved;
|
|
118
115
|
for (const texture of entry.subscribers)
|
|
119
|
-
bindResolvedScene3DResource(resolver, texture, ref,
|
|
116
|
+
bindResolvedScene3DResource(resolver, texture, ref, source);
|
|
120
117
|
}
|
|
121
118
|
function failScene3DResourceResolution(resolver, ref, entry, cause) {
|
|
122
119
|
const runtime = resolver[Scene3DResourceResolverRuntimeKey];
|
|
@@ -131,12 +128,12 @@ function failScene3DResourceResolution(resolver, ref, entry, cause) {
|
|
|
131
128
|
for (const texture of entry.subscribers)
|
|
132
129
|
emitScene3DResourceEvent(resolver, texture, ref, false);
|
|
133
130
|
}
|
|
134
|
-
function bindResolvedScene3DResource(resolver, texture, ref,
|
|
131
|
+
function bindResolvedScene3DResource(resolver, texture, ref, source) {
|
|
135
132
|
if (texture.dimension !== '2d')
|
|
136
133
|
return;
|
|
137
|
-
if (texture.source ===
|
|
134
|
+
if (texture.source === source)
|
|
138
135
|
return;
|
|
139
|
-
texture.source =
|
|
136
|
+
texture.source = source;
|
|
140
137
|
texture.version = (texture.version + 1) >>> 0;
|
|
141
138
|
emitScene3DResourceEvent(resolver, texture, ref, true);
|
|
142
139
|
}
|
|
@@ -191,7 +188,7 @@ function requestWorkingResolutions(resolver, working, options) {
|
|
|
191
188
|
promise: _resolvedVoid,
|
|
192
189
|
subscribers: new Set(subscribers),
|
|
193
190
|
};
|
|
194
|
-
entry.promise = handle.promise.then((
|
|
191
|
+
entry.promise = handle.promise.then((source) => finishScene3DResourceResolution(resolver, ref, entry, source), (cause) => failScene3DResourceResolution(resolver, ref, entry, cause));
|
|
195
192
|
runtime.inFlight.set(ref, entry);
|
|
196
193
|
}
|
|
197
194
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveScene3DResources.js","sourceRoot":"","sources":["../src/resolveScene3DResources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,
|
|
1
|
+
{"version":3,"file":"resolveScene3DResources.js","sourceRoot":"","sources":["../src/resolveScene3DResources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACrG,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAYxD,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAC7F,OAAO,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAG7E,OAAO,EAAE,0BAA0B,EAAE,kCAAkC,EAAE,MAAM,8BAA8B,CAAC;AAE9G,kGAAkG;AAClG,sGAAsG;AACtG,sGAAsG;AACtG,MAAM,UAAU,gCAAgC,CAC9C,QAA2C,EAC3C,GAA2B,EAC3B,MAAmB;IAEnB,OAAO,6BAA6B,CAAC,GAAG,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACpE,CAAC;AAED,sGAAsG;AACtG,wGAAwG;AACxG,wGAAwG;AACxG,cAAc;AACd,MAAM,UAAU,uBAAuB,CACrC,KAAwB,EACxB,QAAiC,EACjC,OAAkD;IAElD,MAAM,OAAO,GAAI,QAA+C,CAAC,iCAAiC,CAAC,CAAC;IACpG,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,0BAA0B,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqC,CAAC;IAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,kCAAkC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,GAAG,IAAI,IAAI;YAAE,SAAS;QAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAClE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAClC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;YACnB,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,QAAQ,CAAC;QAC/C,CAAC;QACD,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC;YAAE,SAAS;QAC7E,IAAI,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,WAAW,GAAG,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAChC,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,QAAQ,GAAiC,EAAE,CAAC;IAClD,MAAM,UAAU,GAAgC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,OAAO,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,GAAG,CAAC,KAAK,KAAK,uBAAuB,CAAC,QAAQ;gBAAE,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,UAAU,CAAC;YACnG,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;YAChD,SAAS;QACX,CAAC;QACD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;QACnB,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,QAAQ,CAAC;QAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,2BAA2B,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QACrE,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACzC,CAAC;AAED,uGAAuG;AACvG,yGAAyG;AACzG,MAAM,UAAU,8BAA8B,CAC5C,KAAwB,EACxB,QAAiC,EACjC,OAAyD;IAEzD,MAAM,SAAS,GAAG,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqC,CAAC;IAC7D,oCAAoC,CAAC,OAAO,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClE,oCAAoC,CAAC,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACpE,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,oCAAoC,CAC3C,GAA2C,EAC3C,MAA4C;IAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAC/B,QAAiC,EACjC,OAAgE;IAEhE,MAAM,OAAO,GAAI,QAA+C,CAAC,iCAAiC,CAAC,CAAC;IACpG,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,SAAS;QACX,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,iGAAiG;QACjG,IAAI,GAAG,CAAC,KAAK,KAAK,uBAAuB,CAAC,OAAO,EAAE,CAAC;YAClD,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,UAAU,CAAC;QACjD,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,+BAA+B,CACtC,QAAiC,EACjC,GAA2B,EAC3B,KAA8B,EAC9B,MAA4B;IAE5B,MAAM,OAAO,GAAI,QAA+C,CAAC,iCAAiC,CAAC,CAAC;IACpG,yFAAyF;IACzF,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;QAAE,OAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,GAAG,CAAC,OAAO,KAAK;YACd,IAAI,EAAE,wBAAwB,CAAC,WAAW;YAC1C,OAAO,EAAE,8CAA8C;YACvD,IAAI,EAAE,IAAI;SACX,CAAC;QACF,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,MAAM,CAAC;QAC3C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,WAAW;YAAE,wBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACjG,OAAO;IACT,CAAC;IACD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAClC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;IACnB,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,QAAQ,CAAC;IAC7C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,WAAW;QAAE,2BAA2B,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AACvG,CAAC;AAED,SAAS,6BAA6B,CACpC,QAAiC,EACjC,GAA2B,EAC3B,KAA8B,EAC9B,KAAc;IAEd,MAAM,OAAO,GAAI,QAA+C,CAAC,iCAAiC,CAAC,CAAC;IACpG,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;QAAE,OAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,gGAAgG;IAChG,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO;IAC5C,GAAG,CAAC,OAAO,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;IAChD,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,MAAM,CAAC;IAC3C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,WAAW;QAAE,wBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AACnG,CAAC;AAED,SAAS,2BAA2B,CAClC,QAA2C,EAC3C,OAAgB,EAChB,GAA2B,EAC3B,MAAqB;IAErB,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;QAAE,OAAO;IACvC,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO;IACtC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC9C,wBAAwB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,wBAAwB,CAC/B,QAA2C,EAC3C,OAAgB,EAChB,GAA2B,EAC3B,QAAiB;IAEjB,MAAM,OAAO,GAAI,QAA+C,CAAC,iCAAiC,CAAC,CAAC,OAAO,CAAC;IAC5G,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO;IAC7B,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAC/B,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,yBAAyB,CAChC,QAAiC,EACjC,OAAgE,EAChE,OAAyD;IAEzD,MAAM,OAAO,GAAI,QAA+C,CAAC,iCAAiC,CAAC,CAAC;IACpG,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,OAAO,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;YACnB,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,QAAQ,CAAC;YAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,2BAA2B,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YACvE,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACxC,IAAI,GAAG,CAAC,KAAK,KAAK,uBAAuB,CAAC,QAAQ;YAAE,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,UAAU,CAAC;QACnG,IAAI,GAAG,CAAC,KAAK,KAAK,uBAAuB,CAAC,UAAU;YAAE,SAAS;QAC/D,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;QACnB,GAAG,CAAC,KAAK,GAAG,uBAAuB,CAAC,OAAO,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;YACpC,QAAQ,GAAG,MAAM,CAAC,iBAAiB,CAAC;YACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,iBAAiB,CAAuB,OAAO,CAAC,MAAM,EAAE;YACrE,IAAI,EAAE,CAAC,YAAY,EAAE,EAAE;gBACrB,uFAAuF;gBACvF,IAAI,YAAY,CAAC,OAAO;oBAAE,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;;oBAC3D,YAAY,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBACzG,OAAO,gCAAgC,CAAC,QAAQ,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5E,CAAC;YACD,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,KAAK,GAA4B;YACrC,UAAU;YACV,OAAO,EAAE,aAAa;YACtB,WAAW,EAAE,IAAI,GAAG,CAAC,WAAW,CAAC;SAClC,CAAC;QACF,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CACjC,CAAC,MAAM,EAAE,EAAE,CAAC,+BAA+B,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,EACzE,CAAC,KAAK,EAAE,EAAE,CAAC,6BAA6B,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CACtE,CAAC;QACF,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/scene3d-resources",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-next.320.fe56fc2",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,18 +38,18 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/entity": "0.3.
|
|
42
|
-
"@flighthq/image": "0.3.
|
|
43
|
-
"@flighthq/loader": "0.3.
|
|
44
|
-
"@flighthq/log": "0.3.
|
|
45
|
-
"@flighthq/net": "0.3.
|
|
46
|
-
"@flighthq/node": "0.3.
|
|
47
|
-
"@flighthq/scene3d": "0.3.
|
|
48
|
-
"@flighthq/scene3d-formats": "0.3.
|
|
49
|
-
"@flighthq/signals": "0.3.
|
|
50
|
-
"@flighthq/texture": "0.3.
|
|
51
|
-
"@flighthq/tween": "0.3.
|
|
52
|
-
"@flighthq/types": "0.3.
|
|
41
|
+
"@flighthq/entity": "0.3.1-next.320.fe56fc2",
|
|
42
|
+
"@flighthq/image": "0.3.1-next.320.fe56fc2",
|
|
43
|
+
"@flighthq/loader": "0.3.1-next.320.fe56fc2",
|
|
44
|
+
"@flighthq/log": "0.3.1-next.320.fe56fc2",
|
|
45
|
+
"@flighthq/net": "0.3.1-next.320.fe56fc2",
|
|
46
|
+
"@flighthq/node": "0.3.1-next.320.fe56fc2",
|
|
47
|
+
"@flighthq/scene3d": "0.3.1-next.320.fe56fc2",
|
|
48
|
+
"@flighthq/scene3d-formats": "0.3.1-next.320.fe56fc2",
|
|
49
|
+
"@flighthq/signals": "0.3.1-next.320.fe56fc2",
|
|
50
|
+
"@flighthq/texture": "0.3.1-next.320.fe56fc2",
|
|
51
|
+
"@flighthq/tween": "0.3.1-next.320.fe56fc2",
|
|
52
|
+
"@flighthq/types": "0.3.1-next.320.fe56fc2"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@flighthq/materials": "*",
|
|
@@ -11,6 +11,7 @@ import { getScene3DResourceTextures, getScene3DTextureResourceReference } from '
|
|
|
11
11
|
|
|
12
12
|
function embeddedRef(state: ResourceResolutionState = ResourceResolutionState.Unresolved): ImageResourceReference {
|
|
13
13
|
return {
|
|
14
|
+
alphaType: 'straight',
|
|
14
15
|
bytes: new Uint8Array([1, 2, 3]),
|
|
15
16
|
failure: null,
|
|
16
17
|
kind: ImageResourceReferenceKind.Embedded,
|
|
@@ -21,12 +21,12 @@ import type * as Scene3DResourceResolverModule from './sceneResourceResolver';
|
|
|
21
21
|
import type * as Scene3DResourceSignalsModule from './sceneResourceSignals';
|
|
22
22
|
|
|
23
23
|
const fakeImage = { height: 2, kind: ImageTextureSourceKind, width: 2 } as unknown as Image;
|
|
24
|
-
type
|
|
24
|
+
type ResolveImageResourceReference = typeof ImageModule.resolveImageResourceReference;
|
|
25
25
|
|
|
26
26
|
let createBuiltInScene3DResourceResolver: typeof Scene3DResourceResolverModule.createBuiltInScene3DResourceResolver;
|
|
27
27
|
let disposeScene3DResourceResolver: typeof Scene3DResourceResolverModule.disposeScene3DResourceResolver;
|
|
28
28
|
let enableScene3DResourceSignals: typeof Scene3DResourceSignalsModule.enableScene3DResourceSignals;
|
|
29
|
-
let
|
|
29
|
+
let resolveReference: Mock<ResolveImageResourceReference>;
|
|
30
30
|
let resolveOneScene3DResourceTexture: typeof ResolveScene3DResourcesModule.resolveOneScene3DResourceTexture;
|
|
31
31
|
let resolveScene3DResources: typeof ResolveScene3DResourcesModule.resolveScene3DResources;
|
|
32
32
|
let updateScene3DResourceStreaming: typeof ResolveScene3DResourcesModule.updateScene3DResourceStreaming;
|
|
@@ -37,6 +37,7 @@ let sceneResources: ImageResourceReference[] = [];
|
|
|
37
37
|
function embeddedRef(mimeType: string | null = 'image/png'): ImageResourceReference {
|
|
38
38
|
const ref: ImageResourceReference = {
|
|
39
39
|
bytes: new Uint8Array([9, 9]),
|
|
40
|
+
alphaType: 'straight',
|
|
40
41
|
failure: null,
|
|
41
42
|
kind: ImageResourceReferenceKind.Embedded,
|
|
42
43
|
mimeType,
|
|
@@ -86,13 +87,12 @@ async function settle(resolver: Scene3DResourceResolver): Promise<void> {
|
|
|
86
87
|
|
|
87
88
|
beforeAll(async () => {
|
|
88
89
|
vi.resetModules();
|
|
89
|
-
|
|
90
|
-
// Override only the
|
|
90
|
+
resolveReference = vi.fn<ResolveImageResourceReference>();
|
|
91
|
+
// Override only the resource atom; the rest of the module stays real, so growing @flighthq/image cannot
|
|
91
92
|
// silently blank out a code path under test.
|
|
92
93
|
vi.doMock('@flighthq/image/contract', async (importOriginal) => ({
|
|
93
94
|
...(await importOriginal<typeof ImageModule>()),
|
|
94
|
-
|
|
95
|
-
loadImageResourceFromUrl: vi.fn(),
|
|
95
|
+
resolveImageResourceReference: resolveReference,
|
|
96
96
|
}));
|
|
97
97
|
({ resolveOneScene3DResourceTexture, resolveScene3DResources, updateScene3DResourceStreaming } =
|
|
98
98
|
await import('./resolveScene3DResources'));
|
|
@@ -107,31 +107,36 @@ afterAll(() => {
|
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
afterEach(() => {
|
|
110
|
-
|
|
110
|
+
resolveReference.mockReset();
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
describe('resolveOneScene3DResourceTexture', () => {
|
|
114
114
|
it('decodes embedded bytes through @flighthq/image', async () => {
|
|
115
|
-
|
|
115
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
116
116
|
const resolver = createBuiltInScene3DResourceResolver();
|
|
117
117
|
const ref = embeddedRef('image/jpeg');
|
|
118
118
|
const signal = new AbortController().signal;
|
|
119
119
|
const result = await resolveOneScene3DResourceTexture(resolver, ref, signal);
|
|
120
|
-
expect(
|
|
120
|
+
expect(resolveReference).toHaveBeenCalledWith(ref, resolver.fetch, signal);
|
|
121
121
|
expect(result).toBe(fakeImage);
|
|
122
122
|
disposeScene3DResourceResolver(resolver);
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
it('passes
|
|
126
|
-
|
|
125
|
+
it('passes the complete plain embedded reference to the shared resource atom', async () => {
|
|
126
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
127
127
|
const resolver = createBuiltInScene3DResourceResolver();
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
const ref = embeddedRef(null);
|
|
129
|
+
const signal = new AbortController().signal;
|
|
130
|
+
await resolveOneScene3DResourceTexture(resolver, ref, signal);
|
|
131
|
+
expect(resolveReference).toHaveBeenCalledWith(ref, resolver.fetch, signal);
|
|
130
132
|
disposeScene3DResourceResolver(resolver);
|
|
131
133
|
});
|
|
132
134
|
|
|
133
135
|
it('routes external refs through the resolver fetch seam', async () => {
|
|
134
136
|
const fetch = vi.fn(async () => fakeImage);
|
|
137
|
+
resolveReference.mockImplementation((ref, resolveFetch, signal) =>
|
|
138
|
+
ref.kind === ImageResourceReferenceKind.External ? resolveFetch(ref, signal) : Promise.resolve(null),
|
|
139
|
+
);
|
|
135
140
|
const resolver = createBuiltInScene3DResourceResolver({ fetch });
|
|
136
141
|
const ref = externalRef();
|
|
137
142
|
const signal = new AbortController().signal;
|
|
@@ -145,8 +150,8 @@ describe('resolveOneScene3DResourceTexture', () => {
|
|
|
145
150
|
describe('resolveScene3DResources', () => {
|
|
146
151
|
it('does not cancel acquisition owned by a streaming update', async () => {
|
|
147
152
|
let loadSignal: AbortSignal | undefined;
|
|
148
|
-
|
|
149
|
-
(
|
|
153
|
+
resolveReference.mockImplementation(
|
|
154
|
+
(_ref, _fetch, signal) =>
|
|
150
155
|
new Promise<Image>((_resolve, reject) => {
|
|
151
156
|
loadSignal = signal;
|
|
152
157
|
signal?.addEventListener('abort', () => reject(signal.reason));
|
|
@@ -168,7 +173,7 @@ describe('resolveScene3DResources', () => {
|
|
|
168
173
|
});
|
|
169
174
|
|
|
170
175
|
it('returns the selected unresolved working set without starting acquisition', () => {
|
|
171
|
-
|
|
176
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
172
177
|
const ref = embeddedRef();
|
|
173
178
|
const a = createTexture({ resource: ref });
|
|
174
179
|
const b = createTexture({ resource: ref });
|
|
@@ -181,7 +186,7 @@ describe('resolveScene3DResources', () => {
|
|
|
181
186
|
expect(resources.resolved).toEqual([]);
|
|
182
187
|
expect(resources.unresolved).toEqual([{ ref, textures: [a, b] }]);
|
|
183
188
|
expect(ref.state).toBe(ResourceResolutionState.Unresolved);
|
|
184
|
-
expect(
|
|
189
|
+
expect(resolveReference).not.toHaveBeenCalled();
|
|
185
190
|
disposeScene3DResourceResolver(resolver);
|
|
186
191
|
});
|
|
187
192
|
|
|
@@ -197,7 +202,7 @@ describe('resolveScene3DResources', () => {
|
|
|
197
202
|
const resources = resolveScene3DResources(scene, resolver);
|
|
198
203
|
|
|
199
204
|
expect(resources.unresolved).toEqual([]);
|
|
200
|
-
expect(resources.resolved).toEqual([{
|
|
205
|
+
expect(resources.resolved).toEqual([{ ref, source: fakeImage, textures: [a, b] }]);
|
|
201
206
|
expect(getTextureSource(b)).toBe(fakeImage);
|
|
202
207
|
expect(ref.state).toBe(ResourceResolutionState.Resolved);
|
|
203
208
|
disposeScene3DResourceResolver(resolver);
|
|
@@ -206,7 +211,7 @@ describe('resolveScene3DResources', () => {
|
|
|
206
211
|
|
|
207
212
|
describe('updateScene3DResourceStreaming', () => {
|
|
208
213
|
it('resolves every pending texture, binding the image and advancing state', async () => {
|
|
209
|
-
|
|
214
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
210
215
|
const a = pendingTexture();
|
|
211
216
|
const b = pendingTexture();
|
|
212
217
|
const scene = meshScene3D(a, b);
|
|
@@ -224,7 +229,7 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
224
229
|
});
|
|
225
230
|
|
|
226
231
|
it('fetches and decodes one shared resource once, then binds every subscribed texture', async () => {
|
|
227
|
-
|
|
232
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
228
233
|
const ref = embeddedRef();
|
|
229
234
|
const a = createTexture({ resource: ref });
|
|
230
235
|
const b = createTexture({ resource: ref });
|
|
@@ -234,7 +239,7 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
234
239
|
updateScene3DResourceStreaming(scene, resolver);
|
|
235
240
|
await settle(resolver);
|
|
236
241
|
|
|
237
|
-
expect(
|
|
242
|
+
expect(resolveReference).toHaveBeenCalledTimes(1);
|
|
238
243
|
expect(getTextureSource(a)).toBe(fakeImage);
|
|
239
244
|
expect(getTextureSource(b)).toBe(fakeImage);
|
|
240
245
|
expect(ref.state).toBe(ResourceResolutionState.Resolved);
|
|
@@ -243,8 +248,8 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
243
248
|
|
|
244
249
|
it('keeps a shared load alive until its final subscriber leaves the working set', async () => {
|
|
245
250
|
let loadSignal: AbortSignal | undefined;
|
|
246
|
-
|
|
247
|
-
(
|
|
251
|
+
resolveReference.mockImplementation(
|
|
252
|
+
(_ref, _fetch, signal) =>
|
|
248
253
|
new Promise<Image>((_resolve, reject) => {
|
|
249
254
|
loadSignal = signal;
|
|
250
255
|
signal?.addEventListener('abort', () => reject(signal.reason));
|
|
@@ -269,7 +274,7 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
269
274
|
});
|
|
270
275
|
|
|
271
276
|
it('binds a later subscriber from the resolved resource cache without decoding again', async () => {
|
|
272
|
-
|
|
277
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
273
278
|
const ref = embeddedRef();
|
|
274
279
|
const a = createTexture({ resource: ref });
|
|
275
280
|
const b = createTexture({ resource: ref });
|
|
@@ -283,12 +288,12 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
283
288
|
|
|
284
289
|
updateScene3DResourceStreaming(scene, resolver, { select: (texture) => texture === b });
|
|
285
290
|
expect(getTextureSource(b)).toBe(fakeImage);
|
|
286
|
-
expect(
|
|
291
|
+
expect(resolveReference).toHaveBeenCalledTimes(1);
|
|
287
292
|
disposeScene3DResourceResolver(resolver);
|
|
288
293
|
});
|
|
289
294
|
|
|
290
295
|
it('limits the working set to textures the select predicate accepts', async () => {
|
|
291
|
-
|
|
296
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
292
297
|
const wanted = pendingTexture();
|
|
293
298
|
const skipped = pendingTexture();
|
|
294
299
|
const scene = meshScene3D(wanted, skipped);
|
|
@@ -304,6 +309,19 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
304
309
|
});
|
|
305
310
|
|
|
306
311
|
it('fails a texture whose external fetch returns null', async () => {
|
|
312
|
+
resolveReference.mockImplementation(async (ref, fetch, signal) => {
|
|
313
|
+
if (ref.kind !== ImageResourceReferenceKind.External) return null;
|
|
314
|
+
const source = await fetch(ref, signal);
|
|
315
|
+
if (source === null) {
|
|
316
|
+
ref.failure = {
|
|
317
|
+
kind: ImageResourceFailureKind.Unavailable,
|
|
318
|
+
message: 'Image resource unavailable',
|
|
319
|
+
name: null,
|
|
320
|
+
};
|
|
321
|
+
ref.state = ResourceResolutionState.Failed;
|
|
322
|
+
}
|
|
323
|
+
return source;
|
|
324
|
+
});
|
|
307
325
|
const texture = createTexture({ resource: externalRef() });
|
|
308
326
|
const scene = meshScene3D(texture);
|
|
309
327
|
const resolver = createBuiltInScene3DResourceResolver({ fetch: async () => null });
|
|
@@ -315,14 +333,14 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
315
333
|
expect(resourceOf(texture)?.state).toBe(ResourceResolutionState.Failed);
|
|
316
334
|
expect(resourceOf(texture)?.failure).toEqual({
|
|
317
335
|
kind: ImageResourceFailureKind.Unavailable,
|
|
318
|
-
message: 'Image resource
|
|
336
|
+
message: 'Image resource unavailable',
|
|
319
337
|
name: null,
|
|
320
338
|
});
|
|
321
339
|
disposeScene3DResourceResolver(resolver);
|
|
322
340
|
});
|
|
323
341
|
|
|
324
342
|
it('fails a texture whose decode throws', async () => {
|
|
325
|
-
|
|
343
|
+
resolveReference.mockRejectedValue(new Error('bad image'));
|
|
326
344
|
const texture = pendingTexture();
|
|
327
345
|
const scene = meshScene3D(texture);
|
|
328
346
|
const resolver = createBuiltInScene3DResourceResolver();
|
|
@@ -342,8 +360,8 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
342
360
|
it('cancels and reverts a load dropped from the working set, then re-requests on re-entry', async () => {
|
|
343
361
|
const loadSignals: AbortSignal[] = [];
|
|
344
362
|
// A load that hangs until its signal aborts, so we can drop it mid-flight.
|
|
345
|
-
|
|
346
|
-
(
|
|
363
|
+
resolveReference.mockImplementation(
|
|
364
|
+
(_ref, _fetch, signal) =>
|
|
347
365
|
new Promise<Image>((_resolve, reject) => {
|
|
348
366
|
if (signal !== undefined) loadSignals.push(signal);
|
|
349
367
|
signal?.addEventListener('abort', () => reject(signal.reason));
|
|
@@ -372,21 +390,21 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
372
390
|
});
|
|
373
391
|
|
|
374
392
|
it('does not re-request a texture already in flight', async () => {
|
|
375
|
-
|
|
393
|
+
resolveReference.mockImplementation(() => new Promise<Image>(() => {}));
|
|
376
394
|
const texture = pendingTexture();
|
|
377
395
|
const scene = meshScene3D(texture);
|
|
378
396
|
const resolver = createBuiltInScene3DResourceResolver();
|
|
379
397
|
|
|
380
398
|
updateScene3DResourceStreaming(scene, resolver);
|
|
381
|
-
await vi.waitFor(() => expect(
|
|
399
|
+
await vi.waitFor(() => expect(resolveReference).toHaveBeenCalledTimes(1));
|
|
382
400
|
updateScene3DResourceStreaming(scene, resolver);
|
|
383
|
-
expect(
|
|
401
|
+
expect(resolveReference).toHaveBeenCalledTimes(1);
|
|
384
402
|
|
|
385
403
|
disposeScene3DResourceResolver(resolver);
|
|
386
404
|
});
|
|
387
405
|
|
|
388
406
|
it('emits onResourceResolved when signals are enabled', async () => {
|
|
389
|
-
|
|
407
|
+
resolveReference.mockResolvedValue(fakeImage);
|
|
390
408
|
const texture = pendingTexture();
|
|
391
409
|
const scene = meshScene3D(texture);
|
|
392
410
|
const resolver = createBuiltInScene3DResourceResolver();
|
|
@@ -405,7 +423,7 @@ describe('updateScene3DResourceStreaming', () => {
|
|
|
405
423
|
});
|
|
406
424
|
|
|
407
425
|
it('emits onResourceFailed when a decode throws', async () => {
|
|
408
|
-
|
|
426
|
+
resolveReference.mockRejectedValue(new Error('bad image'));
|
|
409
427
|
const texture = pendingTexture();
|
|
410
428
|
const scene = meshScene3D(texture);
|
|
411
429
|
const resolver = createBuiltInScene3DResourceResolver();
|
|
@@ -23,6 +23,7 @@ const testResources: EmbeddedImageResourceReference[] = [];
|
|
|
23
23
|
|
|
24
24
|
function pendingRef(): EmbeddedImageResourceReference {
|
|
25
25
|
const ref: EmbeddedImageResourceReference = {
|
|
26
|
+
alphaType: 'straight',
|
|
26
27
|
bytes: new Uint8Array([0x89, 0x50, 0x4e, 0x47]),
|
|
27
28
|
failure: null,
|
|
28
29
|
kind: 'Embedded',
|
|
@@ -61,6 +61,7 @@ describe('disposeScene3DResourceResolver', () => {
|
|
|
61
61
|
const resolver = createScene3DResourceResolver();
|
|
62
62
|
const controller = new AbortController();
|
|
63
63
|
const ref = {
|
|
64
|
+
alphaType: 'straight',
|
|
64
65
|
bytes: new Uint8Array(0),
|
|
65
66
|
failure: null,
|
|
66
67
|
kind: ImageResourceReferenceKind.Embedded,
|