lecodes-web-host 2.0.0 → 2.0.2
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/api.d.ts +41 -0
- package/dist/assets/uberarchive-DLH-kBhM.bin +0 -0
- package/dist/index.js +102 -8
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/assets/uberarchive-uXjRYa9p.bin +0 -0
package/dist/api.d.ts
CHANGED
|
@@ -46,12 +46,45 @@ export type PreviewError = {
|
|
|
46
46
|
detail?: string;
|
|
47
47
|
nativeFrames?: string[];
|
|
48
48
|
};
|
|
49
|
+
/** A 3D engine in place of the runtime's: the `_creator` contract implemented in TypeScript
|
|
50
|
+
* (lecodes-gl-lite). The host opens and closes its scene, tells it the size, and disposes of it;
|
|
51
|
+
* the engine shows its own canvas. */
|
|
52
|
+
export type Engine3d = Record<string, any> & {
|
|
53
|
+
openScene(sceneId: number): void;
|
|
54
|
+
closeScene(): void;
|
|
55
|
+
_onResize?(width: number, height: number, factor: number): void;
|
|
56
|
+
_dispose?(): void;
|
|
57
|
+
};
|
|
58
|
+
/** The host's fetched buffers and media players: the ids a bundle hands an engine are these. */
|
|
59
|
+
export type HostStores = {
|
|
60
|
+
fetch(url: string, options: any, onComplete: (systemId: number, statusCode: number) => void, onReject: (err: Error) => void): unknown;
|
|
61
|
+
getBuffer(systemId: number): ArrayBuffer;
|
|
62
|
+
getBlob(systemId: number): Blob;
|
|
63
|
+
putBuffer(buffer: ArrayBuffer): number;
|
|
64
|
+
putLocalBuffer(name: string, buffer: ArrayBuffer): void;
|
|
65
|
+
hasLocalBuffer(name: string): boolean;
|
|
66
|
+
getLocalName(systemId: number): string | undefined;
|
|
67
|
+
getPlayer(id: number): HTMLVideoElement | HTMLAudioElement | null | undefined;
|
|
68
|
+
removePlayers(): void;
|
|
69
|
+
};
|
|
70
|
+
/** What the host lends an engine of the embedder's. */
|
|
71
|
+
export type EnginePage = {
|
|
72
|
+
/** A canvas over the whole container, its backing store in device px, hidden until shown. */
|
|
73
|
+
newCanvas(): HTMLCanvasElement;
|
|
74
|
+
preloads: Set<string>;
|
|
75
|
+
/** The painter behind `_creatorCanvas` (a texture made of a canvas of the app's is read here). */
|
|
76
|
+
canvasHost: any;
|
|
77
|
+
stores: HostStores;
|
|
78
|
+
};
|
|
49
79
|
export type HostOptions = {
|
|
50
80
|
/** The header of the bundle the host is for (`parseBundleHeader`): its engines decide the profile,
|
|
51
81
|
* its materials the archives, its fonts the boot faces. */
|
|
52
82
|
header?: BundleHeader;
|
|
53
83
|
/** The runtime profile, in place of the header's (a host with no bundle yet: an editor). */
|
|
54
84
|
profile?: HostProfile;
|
|
85
|
+
/** A 3D engine of the embedder's as `_creator`, on a profile that carries none (`2d`, `ui`):
|
|
86
|
+
* an editor's viewport on the lite engine. Ignored on the `full` profile. */
|
|
87
|
+
engine3d?: (page: EnginePage) => Promise<Engine3d>;
|
|
55
88
|
/** false = an engine-only host: no UI renderer, no fonts. Default true. */
|
|
56
89
|
ui?: boolean;
|
|
57
90
|
/** The project, as the key its storage is kept under. Default: the header's name. */
|
|
@@ -147,6 +180,10 @@ export type Layer = {
|
|
|
147
180
|
export type HostUI = {
|
|
148
181
|
/** The layers the host paints now. */
|
|
149
182
|
frame(): Layer[];
|
|
183
|
+
/** The node the runtime made last. An inspector that is told of an element as the SDK makes it
|
|
184
|
+
* (`__lecodesCaptureSites` as a function) ties the element to this node: the SDK calls straight
|
|
185
|
+
* after the create that made it. */
|
|
186
|
+
readonly lastCreated: number;
|
|
150
187
|
/** The elements named `name`. */
|
|
151
188
|
findAll(name: string): RenderNode[];
|
|
152
189
|
/** The render tree as JSON / as text (what `lecodes render` writes). */
|
|
@@ -167,6 +204,10 @@ export type Host = {
|
|
|
167
204
|
readonly world: Record<string, unknown>;
|
|
168
205
|
/** The UI as the host paints it; null on an engine-only host. */
|
|
169
206
|
readonly ui: HostUI | null;
|
|
207
|
+
/** The embedder's 3D engine (`engine3d`), as it made it; null where the runtime's own runs. */
|
|
208
|
+
engine3d(): Engine3d | null;
|
|
209
|
+
/** Bytes of the host's store, by their id: what a bundle fetched, what an engine captured. */
|
|
210
|
+
getBuffer(systemId: number): ArrayBuffer | undefined;
|
|
170
211
|
/** Evaluate a bundle. Throws when the bundle is of another SDK major than this host. */
|
|
171
212
|
run(code: string, options?: RunOptions): Run;
|
|
172
213
|
/** A plugin's web half, by the id an app lists it under; a bundle gets the ones its header names. */
|
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ const assetsURL = function(dep, importerUrl) {
|
|
|
6
6
|
return new URL(dep, importerUrl).href;
|
|
7
7
|
};
|
|
8
8
|
const seen = {};
|
|
9
|
-
const
|
|
9
|
+
const __lecodesHostPreload = function preload(baseModule, deps, importerUrl) {
|
|
10
10
|
let promise = Promise.resolve();
|
|
11
11
|
if (deps && deps.length > 0) {
|
|
12
12
|
let allSettled2 = function(promises) {
|
|
@@ -84,9 +84,9 @@ const __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
|
84
84
|
});
|
|
85
85
|
};
|
|
86
86
|
const factories = {
|
|
87
|
-
full: () =>
|
|
88
|
-
"2d": () =>
|
|
89
|
-
ui: () =>
|
|
87
|
+
full: () => __lecodesHostPreload(() => import("./chunks/creator-full-BYRA3WbP.js"), true ? [] : void 0, import.meta.url),
|
|
88
|
+
"2d": () => __lecodesHostPreload(() => import("./chunks/creator-2d-D13oxDsX.js"), true ? [] : void 0, import.meta.url),
|
|
89
|
+
ui: () => __lecodesHostPreload(() => import("./chunks/creator-ui-Cvoc0NZK.js"), true ? [] : void 0, import.meta.url)
|
|
90
90
|
};
|
|
91
91
|
const wasmUrl = {
|
|
92
92
|
full: () => new URL("" + new URL("assets/creator-full-D2dSDdDj.wasm", import.meta.url).href, import.meta.url).href,
|
|
@@ -767,6 +767,67 @@ const installWasmCrashSymbolizer = () => {
|
|
|
767
767
|
};
|
|
768
768
|
const arrayBuffers = [null];
|
|
769
769
|
new TextDecoder("utf-8");
|
|
770
|
+
const _fetch = async (url, fetchOptions, onComplete, onReject) => {
|
|
771
|
+
let body = void 0;
|
|
772
|
+
if (fetchOptions.body) {
|
|
773
|
+
if (typeof fetchOptions.body === "object" && Array.isArray(fetchOptions.body._entries)) {
|
|
774
|
+
const formData = new FormData();
|
|
775
|
+
for (let [key, value, filename] of fetchOptions.body._entries) {
|
|
776
|
+
if (typeof value === "object") {
|
|
777
|
+
formData.append(key, new Blob([getBuffer(value._id)]), filename);
|
|
778
|
+
} else {
|
|
779
|
+
formData.append(key, value);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
body = formData;
|
|
783
|
+
} else if (typeof fetchOptions.body === "string") {
|
|
784
|
+
body = fetchOptions.body;
|
|
785
|
+
} else {
|
|
786
|
+
onReject(new Error("Invalid body"));
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
const resp = await fetch(url, {
|
|
790
|
+
method: fetchOptions.method,
|
|
791
|
+
body,
|
|
792
|
+
headers: fetchOptions.headers,
|
|
793
|
+
mode: "cors",
|
|
794
|
+
credentials: "omit"
|
|
795
|
+
});
|
|
796
|
+
const onProgress = typeof fetchOptions.onProgress === "function" ? fetchOptions.onProgress : null;
|
|
797
|
+
if (!onProgress) {
|
|
798
|
+
const buffer = await resp.arrayBuffer();
|
|
799
|
+
arrayBuffers.push(buffer);
|
|
800
|
+
onComplete(arrayBuffers.length - 1, resp.status);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
const reader = resp.body?.getReader();
|
|
804
|
+
if (!reader) {
|
|
805
|
+
const buffer = await resp.arrayBuffer();
|
|
806
|
+
arrayBuffers.push(buffer);
|
|
807
|
+
onComplete(arrayBuffers.length - 1, resp.status);
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
const contentLength = Number(resp.headers.get("content-length")) || void 0;
|
|
811
|
+
let loaded = 0;
|
|
812
|
+
const chunks = [];
|
|
813
|
+
while (true) {
|
|
814
|
+
const { done, value } = await reader.read();
|
|
815
|
+
if (done) break;
|
|
816
|
+
if (value) {
|
|
817
|
+
chunks.push(value);
|
|
818
|
+
loaded += value.length;
|
|
819
|
+
onProgress({ loaded, total: contentLength });
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
const result = new Uint8Array(loaded);
|
|
823
|
+
let offset = 0;
|
|
824
|
+
for (const chunk of chunks) {
|
|
825
|
+
result.set(chunk, offset);
|
|
826
|
+
offset += chunk.length;
|
|
827
|
+
}
|
|
828
|
+
arrayBuffers.push(result.buffer);
|
|
829
|
+
onComplete(arrayBuffers.length - 1, resp.status);
|
|
830
|
+
};
|
|
770
831
|
const getUrl = (systemId) => {
|
|
771
832
|
const blob = new Blob([arrayBuffers[systemId]]);
|
|
772
833
|
return URL.createObjectURL(blob);
|
|
@@ -785,7 +846,17 @@ const putBuffer = (buffer) => {
|
|
|
785
846
|
return arrayBuffers.length - 1;
|
|
786
847
|
};
|
|
787
848
|
const map = /* @__PURE__ */ new Map();
|
|
849
|
+
const putLocalBuffer = (str, buf) => {
|
|
850
|
+
map.set(str, buf);
|
|
851
|
+
const systemId = localResources.get(str);
|
|
852
|
+
if (systemId !== void 0) arrayBuffers[systemId] = buf;
|
|
853
|
+
};
|
|
854
|
+
const hasLocalBuffer = (str) => map.has(str);
|
|
788
855
|
const localResources = /* @__PURE__ */ new Map();
|
|
856
|
+
const getLocalName = (systemId) => {
|
|
857
|
+
for (const [name, id] of localResources) if (id === systemId) return name;
|
|
858
|
+
return void 0;
|
|
859
|
+
};
|
|
789
860
|
const _fetchLocal = (path) => {
|
|
790
861
|
const existsSystemId = localResources.get(path);
|
|
791
862
|
if (existsSystemId !== void 0) {
|
|
@@ -3871,7 +3942,7 @@ const loadBootFonts = async (fonts, doc, budgetMs = 2e3) => {
|
|
|
3871
3942
|
}
|
|
3872
3943
|
await Promise.race([Promise.all(loads), new Promise((res) => setTimeout(res, budgetMs))]);
|
|
3873
3944
|
};
|
|
3874
|
-
const SDK_VERSION = "2.0.
|
|
3945
|
+
const SDK_VERSION = "2.0.2";
|
|
3875
3946
|
const sdkMajor = (version) => {
|
|
3876
3947
|
const m = version?.match(/^(\d+)\.\d+\.\d+/);
|
|
3877
3948
|
return m ? Number(m[1]) : null;
|
|
@@ -4392,7 +4463,7 @@ const materialGroupsOf = (preloads) => {
|
|
|
4392
4463
|
const materialsBase = "" + new URL("assets/materials-uri4FvPE.bin", import.meta.url).href;
|
|
4393
4464
|
const materialsWorld = "" + new URL("assets/materials-world-CQWt8TAm.bin", import.meta.url).href;
|
|
4394
4465
|
const iblTexture = "" + new URL("assets/neutral_ibl128-D-lzdkLN.ktx", import.meta.url).href;
|
|
4395
|
-
const uberarchive = "" + new URL("assets/uberarchive-
|
|
4466
|
+
const uberarchive = "" + new URL("assets/uberarchive-DLH-kBhM.bin", import.meta.url).href;
|
|
4396
4467
|
const ARCHIVES = { base: materialsBase, world: materialsWorld };
|
|
4397
4468
|
const join = (parts) => {
|
|
4398
4469
|
const out = new Uint8Array(parts.reduce((n, p) => n + p.byteLength, 0));
|
|
@@ -4963,6 +5034,7 @@ const makeWorld = () => {
|
|
|
4963
5034
|
};
|
|
4964
5035
|
return { global, evaluate };
|
|
4965
5036
|
};
|
|
5037
|
+
const stores = { fetch: _fetch, getBuffer, getBlob, putBuffer, putLocalBuffer, hasLocalBuffer, getLocalName, getPlayer, removePlayers };
|
|
4966
5038
|
const nullHostUI = (onDestination, onDropped) => ({
|
|
4967
5039
|
nodeFactory() {
|
|
4968
5040
|
},
|
|
@@ -5044,15 +5116,27 @@ const createHost$1 = async (root, options = {}) => {
|
|
|
5044
5116
|
M._free(p);
|
|
5045
5117
|
}
|
|
5046
5118
|
};
|
|
5119
|
+
let engine3d = null;
|
|
5120
|
+
let engine3dScene = -1;
|
|
5047
5121
|
let destination = -1;
|
|
5048
|
-
const onDestination = (kind) => {
|
|
5122
|
+
const onDestination = (kind, id) => {
|
|
5049
5123
|
destination = kind;
|
|
5050
5124
|
if (kind === TREE_DEST_SCENE3D) gl?.show();
|
|
5051
5125
|
if (kind === TREE_DEST_SCENE2D) scene2d?.show();
|
|
5126
|
+
if (engine3d && kind === TREE_DEST_SCENE3D && id !== engine3dScene) {
|
|
5127
|
+
engine3dScene = id;
|
|
5128
|
+
engine3d.openScene(id);
|
|
5129
|
+
}
|
|
5052
5130
|
};
|
|
5053
5131
|
const onDropped = (kind) => {
|
|
5054
5132
|
if (kind === destination) return;
|
|
5055
|
-
if (kind === TREE_DEST_SCENE3D)
|
|
5133
|
+
if (kind === TREE_DEST_SCENE3D) {
|
|
5134
|
+
gl?.hide();
|
|
5135
|
+
if (engine3d && engine3dScene >= 0) {
|
|
5136
|
+
engine3dScene = -1;
|
|
5137
|
+
engine3d.closeScene();
|
|
5138
|
+
}
|
|
5139
|
+
}
|
|
5056
5140
|
if (kind === TREE_DEST_SCENE2D) scene2d?.hide();
|
|
5057
5141
|
};
|
|
5058
5142
|
const canvasHost = createCanvasHost();
|
|
@@ -5110,12 +5194,17 @@ const createHost$1 = async (root, options = {}) => {
|
|
|
5110
5194
|
M._creatorWebInit();
|
|
5111
5195
|
if (options.launchUrl) withStr(options.launchUrl, (p) => M._creatorWebSetLaunchUrl(p));
|
|
5112
5196
|
renderer?.ui.install();
|
|
5197
|
+
if (!has3d && options.engine3d) {
|
|
5198
|
+
engine3d = await options.engine3d({ newCanvas: page.newCanvas, preloads, canvasHost, stores });
|
|
5199
|
+
Object.defineProperty(globals, "_creator", { value: engine3d, configurable: true, writable: true, enumerable: false });
|
|
5200
|
+
}
|
|
5113
5201
|
if (has3d && header?.gl !== "defer") globals._creator?.createEngine();
|
|
5114
5202
|
const safeArea = createSafeArea(root);
|
|
5115
5203
|
if (options.safeArea) safeArea.set(options.safeArea);
|
|
5116
5204
|
const resize = (size) => {
|
|
5117
5205
|
gl?.resize();
|
|
5118
5206
|
scene2d?.resize();
|
|
5207
|
+
engine3d?._onResize?.(size.width, size.height, size.factor);
|
|
5119
5208
|
if (renderer) {
|
|
5120
5209
|
renderer.resize(size.width, size.height, size.factor);
|
|
5121
5210
|
renderer.setSafeArea(safeArea.current());
|
|
@@ -5146,6 +5235,10 @@ const createHost$1 = async (root, options = {}) => {
|
|
|
5146
5235
|
world: globals,
|
|
5147
5236
|
/** The UI as the renderer holds it (the render tree, the pointer routing); null on an engine-only host. */
|
|
5148
5237
|
ui: renderer?.ui ?? null,
|
|
5238
|
+
/** The embedder's 3D engine (`engine3d`), as it made it; null where the runtime's own runs. */
|
|
5239
|
+
engine3d: () => engine3d,
|
|
5240
|
+
/** Bytes of the host's store, by their id: what a bundle fetched, what an engine captured. */
|
|
5241
|
+
getBuffer: (systemId) => getBuffer(systemId),
|
|
5149
5242
|
/** Evaluate a bundle. Throws when the bundle is of another SDK major than this host. */
|
|
5150
5243
|
run(code, runOptions = {}) {
|
|
5151
5244
|
const bundle = runOptions.header ?? parseBundleHeader$1(code);
|
|
@@ -5184,6 +5277,7 @@ const createHost$1 = async (root, options = {}) => {
|
|
|
5184
5277
|
app.dispose();
|
|
5185
5278
|
removePlayers();
|
|
5186
5279
|
safeArea.destroy();
|
|
5280
|
+
engine3d?._dispose?.();
|
|
5187
5281
|
gl?.destroy();
|
|
5188
5282
|
scene2d?.destroy();
|
|
5189
5283
|
page.destroy();
|