@plasius/gpu-shared 0.1.4 → 0.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasius/gpu-shared",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Shared browser-safe demo runtime and asset helpers for the Plasius gpu-* package family.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -66,7 +66,7 @@
66
66
  "eslint": "^10.1.0",
67
67
  "globals": "^17.3.0",
68
68
  "tsup": "^8.5.0",
69
- "typescript": "^5.9.3"
69
+ "typescript": "^6.0.2"
70
70
  },
71
71
  "repository": {
72
72
  "type": "git",
package/src/asset-url.js CHANGED
@@ -1,10 +1,37 @@
1
1
  const INLINE_BRIGANTINE_GLTF_URL =
2
2
  "data:application/json;base64,ewogICJhc3NldCI6IHsKICAgICJ2ZXJzaW9uIjogIjIuMCIsCiAgICAiZ2VuZXJhdG9yIjogIlBsYXNpdXMgZGVtbyBhc3NldCBnZW5lcmF0b3IiCiAgfSwKICAic2NlbmUiOiAwLAogICJzY2VuZXMiOiBbCiAgICB7CiAgICAgICJub2RlcyI6IFswXQogICAgfQogIF0sCiAgIm5vZGVzIjogWwogICAgewogICAgICAibWVzaCI6IDAsCiAgICAgICJuYW1lIjogImJyaWdhbnRpbmUiLAogICAgICAiZXh0cmFzIjogewogICAgICAgICJwaHlzaWNzIjogewogICAgICAgICAgInNoYXBlIjogImJveCIsCiAgICAgICAgICAiaGFsZkV4dGVudHMiOiBbMS4zNSwgMC45NSwgMy45XSwKICAgICAgICAgICJtYXNzIjogMzIwMCwKICAgICAgICAgICJyZXN0aXR1dGlvbiI6IDAuMjIsCiAgICAgICAgICAibGluZWFyRGFtcGluZyI6IDAuMDQsCiAgICAgICAgICAiYW5ndWxhckRhbXBpbmciOiAwLjA4LAogICAgICAgICAgIndhdGVybGluZSI6IDAuNDIKICAgICAgICB9CiAgICAgIH0KICAgIH0KICBdLAogICJtZXNoZXMiOiBbCiAgICB7CiAgICAgICJuYW1lIjogImJyaWdhbnRpbmUtaHVsbCIsCiAgICAgICJwcmltaXRpdmVzIjogWwogICAgICAgIHsKICAgICAgICAgICJhdHRyaWJ1dGVzIjogewogICAgICAgICAgICAiUE9TSVRJT04iOiAwCiAgICAgICAgICB9LAogICAgICAgICAgImluZGljZXMiOiAxLAogICAgICAgICAgIm1hdGVyaWFsIjogMAogICAgICAgIH0KICAgICAgXQogICAgfQogIF0sCiAgIm1hdGVyaWFscyI6IFsKICAgIHsKICAgICAgIm5hbWUiOiAicGFpbnRlZC1odWxsIiwKICAgICAgInBick1ldGFsbGljUm91Z2huZXNzIjogewogICAgICAgICJiYXNlQ29sb3JGYWN0b3IiOiBbMC41NiwgMC4zMywgMC4yMiwgMV0sCiAgICAgICAgIm1ldGFsbGljRmFjdG9yIjogMC4wOCwKICAgICAgICAicm91Z2huZXNzRmFjdG9yIjogMC45MgogICAgICB9CiAgICB9CiAgXSwKICAiYnVmZmVycyI6IFsKICAgIHsKICAgICAgInVyaSI6ICJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsbXBtWnZ3QUFBTC9OekV6QW1wbVpQd0FBQUwvTnpFekF6Y3lzdnpNenM3NHpNN08vemN5c1B6TXpzNzR6TTdPL0FBQ2d2ODNNVEwzTnpNdy9BQUNnUDgzTVRMM056TXcvQUFBQUFPeFJPTDR6TTROQUFBQUFBR1ptNWo0QUFIQkFNek56dnpNenN6NmFtUm5BTXpOelB6TXpzejZhbVJuQXpjeE12ejBLMXo3TnpFdy96Y3hNUHowSzF6N056RXcvQUFBQUFETXpjejltWm1hL0FBQUNBQU1BQUFBREFBRUFBZ0FFQUFVQUFnQUZBQU1BQkFBSEFBVUFCQUFHQUFjQUJRQUhBQVlBQUFBQkFBa0FBQUFKQUFnQUNBQUpBQXdBQWdBSUFBd0FBd0FNQUFrQUFnQU1BQW9BQXdBTEFBd0FBZ0FLQUFRQUF3QUZBQXNBQ2dBTUFBc0FBQUFJQUFJQUFRQURBQWtBQkFBS0FBWUFCUUFHQUFzQUFnQUtBQXNBQWdBTEFBTUEiLAogICAgICAiYnl0ZUxlbmd0aCI6IDI5NAogICAgfQogIF0sCiAgImJ1ZmZlclZpZXdzIjogWwogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiYnl0ZUxlbmd0aCI6IDE1NiwKICAgICAgInRhcmdldCI6IDM0OTYyCiAgICB9LAogICAgewogICAgICAiYnVmZmVyIjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAxNTYsCiAgICAgICJieXRlTGVuZ3RoIjogMTM4LAogICAgICAidGFyZ2V0IjogMzQ5NjMKICAgIH0KICBdLAogICJhY2Nlc3NvcnMiOiBbCiAgICB7CiAgICAgICJidWZmZXJWaWV3IjogMCwKICAgICAgImJ5dGVPZmZzZXQiOiAwLAogICAgICAiY29tcG9uZW50VHlwZSI6IDUxMjYsCiAgICAgICJjb3VudCI6IDEzLAogICAgICAidHlwZSI6ICJWRUMzIiwKICAgICAgIm1pbiI6IFstMS4zNSwgLTAuNSwgLTMuMl0sCiAgICAgICJtYXgiOiBbMS4zNSwgMC45NSwgNC4xXQogICAgfSwKICAgIHsKICAgICAgImJ1ZmZlclZpZXciOiAxLAogICAgICAiYnl0ZU9mZnNldCI6IDAsCiAgICAgICJjb21wb25lbnRUeXBlIjogNTEyMywKICAgICAgImNvdW50IjogNjksCiAgICAgICJ0eXBlIjogIlNDQUxBUiIsCiAgICAgICJtYXgiOiBbMTJdLAogICAgICAibWluIjogWzBdCiAgICB9CiAgXQp9Cg==";
3
3
 
4
+ function createInlineShowcaseAssetUrl() {
5
+ return new URL(INLINE_BRIGANTINE_GLTF_URL);
6
+ }
7
+
8
+ function getBrowserBaseUrl() {
9
+ if (typeof document !== "undefined" && typeof document.baseURI === "string" && document.baseURI.length > 0) {
10
+ return document.baseURI;
11
+ }
12
+ if (
13
+ typeof window !== "undefined" &&
14
+ typeof window.location?.href === "string" &&
15
+ window.location.href.length > 0
16
+ ) {
17
+ return window.location.href;
18
+ }
19
+ return null;
20
+ }
21
+
4
22
  export function resolveShowcaseAssetUrl(baseUrl = import.meta.url) {
5
23
  try {
6
24
  return new URL("../assets/brigantine.gltf", baseUrl);
7
25
  } catch {
8
- return new URL(INLINE_BRIGANTINE_GLTF_URL);
26
+ const browserBaseUrl = getBrowserBaseUrl();
27
+ if (browserBaseUrl) {
28
+ try {
29
+ const normalizedBaseUrl = new URL(baseUrl, browserBaseUrl);
30
+ return new URL("../assets/brigantine.gltf", normalizedBaseUrl);
31
+ } catch {
32
+ return createInlineShowcaseAssetUrl();
33
+ }
34
+ }
35
+ return createInlineShowcaseAssetUrl();
9
36
  }
10
37
  }
@@ -76,6 +76,40 @@ function computeBounds(positions) {
76
76
  return { min, max };
77
77
  }
78
78
 
79
+ function resolveBrowserRequestBaseUrl() {
80
+ if (typeof document !== "undefined" && typeof document.baseURI === "string" && document.baseURI.length > 0) {
81
+ return document.baseURI;
82
+ }
83
+ if (
84
+ typeof window !== "undefined" &&
85
+ typeof window.location?.href === "string" &&
86
+ window.location.href.length > 0
87
+ ) {
88
+ return window.location.href;
89
+ }
90
+ return null;
91
+ }
92
+
93
+ function resolveFetchBaseUrl(requestUrl, responseUrl) {
94
+ if (typeof responseUrl === "string" && responseUrl.length > 0) {
95
+ try {
96
+ return new URL(responseUrl);
97
+ } catch {
98
+ // Keep trying the other candidates when an environment reports a malformed response URL.
99
+ }
100
+ }
101
+
102
+ try {
103
+ return new URL(requestUrl);
104
+ } catch {
105
+ const browserBaseUrl = resolveBrowserRequestBaseUrl();
106
+ if (browserBaseUrl) {
107
+ return new URL(requestUrl, browserBaseUrl);
108
+ }
109
+ throw new Error(`Unable to resolve a stable base URL for glTF asset loading: ${String(requestUrl)}`);
110
+ }
111
+ }
112
+
79
113
  export async function loadGltfModel(url) {
80
114
  const response = await fetch(url);
81
115
  if (!response.ok) {
@@ -83,6 +117,7 @@ export async function loadGltfModel(url) {
83
117
  }
84
118
 
85
119
  const document = await response.json();
120
+ const baseUrl = resolveFetchBaseUrl(url, response.url);
86
121
  const buffers = await Promise.all(
87
122
  (document.buffers ?? []).map(async (buffer) => {
88
123
  if (typeof buffer.uri !== "string") {
@@ -91,7 +126,7 @@ export async function loadGltfModel(url) {
91
126
  if (buffer.uri.startsWith("data:")) {
92
127
  return decodeDataUri(buffer.uri);
93
128
  }
94
- const nested = await fetch(new URL(buffer.uri, url));
129
+ const nested = await fetch(new URL(buffer.uri, baseUrl));
95
130
  if (!nested.ok) {
96
131
  throw new Error(`Failed to load glTF buffer: ${nested.status} ${nested.statusText}`);
97
132
  }
package/src/index.d.ts CHANGED
@@ -34,6 +34,10 @@ export interface MountGpuShowcaseOptions {
34
34
  packageName?: string;
35
35
  title?: string;
36
36
  subtitle?: string;
37
+ createState?: () => unknown;
38
+ updateState?: (state: unknown, scene: Record<string, unknown>, dt: number) => unknown;
39
+ describeState?: (state: unknown, scene: Record<string, unknown>) => Record<string, unknown> | null;
40
+ destroyState?: (state: unknown) => void;
37
41
  }
38
42
 
39
43
  export interface MountGpuShowcaseResult {