@volter/editor-threejs 0.5.211 → 0.5.213
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/NOTICE +7 -2
- package/README.md +8 -13
- package/contributions/animation-mixers.service.ts +2 -4
- package/contributions/animation-timeline.utility.tsx +1 -2
- package/contributions/three.page.ts +50 -0
- package/dist-node/serving.mjs +84 -3
- package/dist-node/shared-three.mjs +145 -0
- package/package.json +296 -16
- package/serving/animation-stamp.ts +1 -1
- package/serving/index.ts +22 -5
- package/serving/model-import-conversion.ts +6 -3
- package/serving/shared-three.ts +176 -0
- package/src/adapter/constraint.ts +1 -18
- package/src/adapter/object3d-authoring-subject.ts +1 -12
- package/src/adapter/reflection-probe.ts +1 -9
- package/src/adapter/three-contract.ts +6 -60
- package/src/animation/live-mixers.ts +0 -4
- package/src/api.ts +7 -0
- package/src/asset-loaders.ts +2 -178
- package/src/capture/photograph-sampling.ts +333 -0
- package/src/capture/scene.ts +1 -1
- package/src/ecs/object-marks.ts +6 -14
- package/src/ecs/user-data.ts +3 -138
- package/src/kit/animation/three-clips-subject.ts +19 -42
- package/src/kit/asset-compare-core.ts +161 -0
- package/src/kit/asset-compare.ts +8 -27
- package/src/kit/asset-preview-command.ts +14 -19
- package/src/kit/asset-preview-framing.ts +8 -67
- package/src/kit/asset-preview.ts +109 -342
- package/src/kit/asset-workflow/model-inspection.ts +11 -154
- package/src/kit/asset-workflow/preview-resource-lifetime.ts +25 -0
- package/src/kit/authoring/component-instance-root.ts +3 -39
- package/src/kit/authoring/live-object-transform.ts +1 -30
- package/src/kit/authoring/object3d-document-session-registry.ts +7 -15
- package/src/kit/authoring/object3d-document-session.ts +471 -208
- package/src/kit/authoring/shell-viewport-policy.ts +18 -24
- package/src/kit/authoring/source-object3d-authoring-adapter.ts +6 -48
- package/src/kit/authoring/three-projection-core.ts +11 -40
- package/src/kit/authoring/viewport-pick-context.ts +5 -12
- package/src/kit/authoring/viewport-raycast.ts +15 -93
- package/src/kit/authoring/world-hidden-viewport.ts +8 -61
- package/src/kit/capture-camera-pose.ts +68 -0
- package/src/kit/collaboration-presence.ts +41 -0
- package/src/kit/components/CameraInfo.tsx +4 -6
- package/src/kit/components/InspectorObjectPreview.tsx +3 -30
- package/src/kit/components/Object3DDocumentToolbar.css +75 -0
- package/src/kit/components/Object3DDocumentToolbar.tsx +18 -84
- package/src/kit/components/Object3DDocumentViewport.tsx +6 -11
- package/src/kit/components/StageHost.css +40 -0
- package/src/kit/components/StageHost.tsx +192 -439
- package/src/kit/components/StageOverlays.tsx +1 -2
- package/src/kit/components/StatsOverlay.tsx +5 -17
- package/src/kit/components/ViewportFurniture.tsx +27 -154
- package/src/kit/components/ViewportOverlay.tsx +13 -17
- package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
- package/src/kit/components/ViewportShadingMenu.tsx +2 -42
- package/src/kit/components/ViewportViewMenu.tsx +7 -18
- package/src/kit/components/asset-viewers/EntityModelDocument.tsx +6 -17
- package/src/kit/components/asset-viewers/EnvironmentAssetDocument.tsx +9 -11
- package/src/kit/components/asset-viewers/LiveModuleDocument.tsx +31 -133
- package/src/kit/components/asset-viewers/LutAssetDocument.tsx +10 -12
- package/src/kit/components/asset-viewers/ModelAssetDocument.tsx +4 -8
- package/src/kit/components/asset-viewers/Object3DPreview.tsx +13 -64
- package/src/kit/components/asset-viewers/QuarksAssetDocument.tsx +6 -10
- package/src/kit/components/asset-viewers/ShaderAssetDocument.tsx +48 -65
- package/src/kit/components/asset-viewers/shader-source.ts +144 -0
- package/src/kit/components/asset-viewers/three-asset-viewers.tsx +2 -14
- package/src/kit/components/object3d-contribution-surfaces.tsx +5 -3
- package/src/kit/components/stage-keyboard.tsx +6 -12
- package/src/kit/components/stage-overlay-set.tsx +11 -20
- package/src/kit/components/stage-presence-markers.ts +9 -32
- package/src/kit/components/stage-transform-chrome.ts +4 -4
- package/src/kit/components/stage-transform-tools.tsx +7 -14
- package/src/kit/components/standard-viewport-dressing.ts +47 -167
- package/src/kit/components/world-root-binding.ts +2 -7
- package/src/kit/constraint-helper.ts +1 -1
- package/src/kit/document-renderer-session.ts +114 -0
- package/src/kit/editor-presentation-activity.ts +58 -0
- package/src/kit/editor-shell-store.ts +31 -403
- package/src/kit/editor-viewport.ts +486 -1762
- package/src/kit/entity-lod.ts +3 -16
- package/src/kit/entity-object.ts +1 -39
- package/src/kit/hierarchy-mark-reader.ts +13 -30
- package/src/kit/instanced-presentation.ts +1 -47
- package/src/kit/live-gesture-lock.ts +35 -0
- package/src/kit/live-module-source.ts +12 -52
- package/src/kit/model-thumbnail.ts +7 -35
- package/src/kit/play-camera-flight.ts +7 -16
- package/src/kit/projection/three.ts +13 -366
- package/src/kit/retained-document-states.ts +91 -0
- package/src/kit/scene-document-viewport.ts +3 -3
- package/src/kit/scene-framing.ts +11 -152
- package/src/kit/scene-view-fog.ts +2 -47
- package/src/kit/spatial-handle-visuals.ts +19 -28
- package/src/kit/stories/three-story-model.ts +5 -33
- package/src/kit/three-canvas-render.ts +3 -4
- package/src/kit/three-hierarchy-row-media.ts +3 -11
- package/src/kit/three-inspection-media.ts +6 -6
- package/src/kit/three-integration.ts +18 -18
- package/src/kit/three-state.ts +2 -19
- package/src/kit/three-viewport/camera-fit.ts +2 -6
- package/src/kit/three-viewport/selection-brackets.ts +5 -20
- package/src/kit/three-viewport/selection-outline.ts +4 -56
- package/src/kit/three-viewport/skeleton-helper.ts +1 -32
- package/src/kit/three-viewport/source-color.ts +1 -33
- package/src/kit/three-viewport/studio-environment.ts +4 -55
- package/src/kit/three-viewport-presentation.ts +23 -0
- package/src/kit/transport-strip.tsx +147 -0
- package/src/kit/viewport-actions.ts +8 -50
- package/src/kit/viewport-authoring-policy.ts +5 -52
- package/src/kit/viewport-commands.ts +28 -57
- package/src/kit/viewport-hotkeys.ts +29 -31
- package/src/kit/viewport-status-facet.ts +4 -5
- package/src/loader.ts +8 -71
- package/src/object3d-contributions.ts +18 -34
- package/src/viewport/clip-planes.ts +4 -32
- package/src/viewport/content-bounds.ts +13 -142
- package/src/viewport/editor-layers.ts +4 -26
- package/src/viewport/environment.ts +1 -1
- package/src/viewport/preview-renderer.ts +7 -45
- package/src/viewport/renderer-ownership.ts +14 -62
- package/src/viewport-api.ts +14 -33
- package/src/viewport-door.ts +16 -86
- package/contributions/three-integration.service.ts +0 -13
- package/src/adapter/hierarchy-marks.ts +0 -156
- package/src/adapter/ingest/scene-capture.ts +0 -843
- package/src/adapter/ingest/structural-ids.ts +0 -139
- package/src/adapter/ingest/visible-capture-window.ts +0 -302
- package/src/adapter/renderer-config.ts +0 -115
- package/src/asset-parse-error.ts +0 -29
- package/src/host-hierarchy-objects.ts +0 -31
- package/src/kit/authoring/design-time-settle.ts +0 -343
- package/src/kit/camera-authoring.ts +0 -175
package/NOTICE
CHANGED
|
@@ -10,5 +10,10 @@ with src/asset-loaders.ts, src/asset-parse-error.ts and src/loader.ts, were
|
|
|
10
10
|
imported from the Apache-2.0 @volter/threejs-runtime package. They retain that
|
|
11
11
|
license; LICENSE-APACHE contains its text.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
Original AGPL source revision: cf9cb8e22dd7ae5709ed0dd8a46dd6f16d1e4945.
|
|
14
|
+
The Apache-2.0 runtime modules were transferred at revision 09c2749ce.
|
|
15
|
+
|
|
16
|
+
Modules moved under src/kit/ from @volter/sdk's src/kit/ because only this package
|
|
17
|
+
imports them (docs/adr/sdk-plugin-api.md, decisions 1 and 4) are Volter AI, Inc.'s
|
|
18
|
+
own work and are AGPL-3.0-only here, as editor source. The @volter/sdk releases
|
|
19
|
+
that carried them remain Apache-2.0.
|
package/README.md
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Cyclotron three.js integration
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The assembled three.js viewport, scene presentation, object authoring, animation
|
|
4
|
+
inspection, asset loading and capture used by Cyclotron and its Blender integration.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
The integration reaches the editor host through `@volter/sdk`. Structural object
|
|
7
|
+
marks and asset utilities keep their own small module boundaries, so a consumer
|
|
8
|
+
can load them independently of the viewport.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
these small modules must not pull in a gameplay runtime.
|
|
13
|
-
|
|
14
|
-
Run `npm run typecheck -w @volter/editor-threejs` through the active World.
|
|
15
|
-
See NOTICE for the per-file license distinction. This package remains private
|
|
16
|
-
while the editor migration and complete distribution review are unfinished.
|
|
10
|
+
Run `npm run typecheck -w @volter/editor-threejs` from the repository root.
|
|
11
|
+
See NOTICE for the per-file license distinction.
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* clips it has played through each and the objects each animates, so "the timeline found
|
|
5
|
-
* nothing" is answerable from the session.
|
|
2
|
+
* Report live animation mixers, their played clips and animated objects through a workspace service
|
|
3
|
+
* status facet.
|
|
6
4
|
*/
|
|
7
5
|
import { editorHost } from '@volter/sdk/host';
|
|
8
6
|
import { liveMixers } from '../src/animation/live-mixers';
|
|
@@ -6,12 +6,11 @@
|
|
|
6
6
|
* its Scene view. While Play drives time the strip goes read-only and says why.
|
|
7
7
|
*/
|
|
8
8
|
import { editorHost } from '@volter/sdk/host';
|
|
9
|
-
import { TransportStrip } from '
|
|
9
|
+
import { TransportStrip } from '../src/kit/transport-strip';
|
|
10
10
|
import { Text } from '@volter/sdk/widgets';
|
|
11
11
|
import { useCallback, useSyncExternalStore } from 'react';
|
|
12
12
|
|
|
13
13
|
export const point = 'workspace.utility';
|
|
14
|
-
export const title = 'Animation';
|
|
15
14
|
|
|
16
15
|
export default function AnimationTimeline() {
|
|
17
16
|
const { documents, transport } = editorHost();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EDITOR-THREEJS'S PAGE HALF (`contributes.volter.page`, `docs/adr/plugin-apis.md`): it installs the
|
|
3
|
+
* Three integration (`../src/kit/three-integration.ts`) and registers the Three viewport's relay verbs as
|
|
4
|
+
* the Code-OSS commands `volter.<verb>` its package.json declares, with their budgets
|
|
5
|
+
* (`../src/kit/viewport-commands.ts`). Its API is the shared viewport for a document that draws its own content in it:
|
|
6
|
+
* the viewport, each mounted stage (its rig, renderer included, and its frame), a document's display transform, its
|
|
7
|
+
* framing and its World.
|
|
8
|
+
*
|
|
9
|
+
* It activates on its first event: a viewport verb, the Animation panel's first showing, an Asset Lab
|
|
10
|
+
* route with no viewer (`onAssetViewer:`), or a JSON document opening (`onAssetViewer:json`), whose three.quarks
|
|
11
|
+
* particle systems its recognizer claims; and before editor-blender, which names it in `extensionDependencies`
|
|
12
|
+
* because a model document draws through the surfaces and stages this integration installs. A viewport that editor-blender or editor-ui mounts as a library
|
|
13
|
+
* ensures the integration itself before it mounts, whether or not this page half has activated.
|
|
14
|
+
*/
|
|
15
|
+
import { registerVerbCommands } from '@volter/sdk/commands';
|
|
16
|
+
import type { PluginContext } from '@volter/sdk/plugins';
|
|
17
|
+
import type * as THREE from 'three';
|
|
18
|
+
import { object3DDocumentSession } from '../src/kit/authoring/object3d-document-session-registry';
|
|
19
|
+
import { Object3DDocumentViewport } from '../src/kit/components/Object3DDocumentViewport';
|
|
20
|
+
import { ensureThreeIntegration } from '../src/kit/three-integration';
|
|
21
|
+
import { viewportVerbs } from '../src/kit/viewport-commands';
|
|
22
|
+
import type { DocumentDisplayTransform } from '../src/render/document-display-transform';
|
|
23
|
+
import { DocumentScene } from '../src/render/document-scene';
|
|
24
|
+
import { onViewportStages, viewportStages } from '../src/viewport-door';
|
|
25
|
+
|
|
26
|
+
export function activate(context: PluginContext) {
|
|
27
|
+
context.subscriptions.push({ dispose: ensureThreeIntegration() });
|
|
28
|
+
registerVerbCommands(context, viewportVerbs);
|
|
29
|
+
return {
|
|
30
|
+
/** The shared viewport (orbit, pick, framing, overlays), drawing the root a document's `build` answers. */
|
|
31
|
+
Object3DDocumentViewport,
|
|
32
|
+
/** The stage a document has mounted, while it has one. */
|
|
33
|
+
stage: (documentId: string) => viewportStages().find((one) => one.documentId === documentId) ?? null,
|
|
34
|
+
/** Fires whenever a stage mounts or unmounts; the return unsubscribes. */
|
|
35
|
+
onStages: onViewportStages,
|
|
36
|
+
/** The scene-linear-to-display transform a document's stage applies to every frame it draws (null: the stage's
|
|
37
|
+
* own); false where the document has no stage session. */
|
|
38
|
+
setDisplayTransform(documentId: string, transform: DocumentDisplayTransform | null): boolean {
|
|
39
|
+
const session = object3DDocumentSession(documentId);
|
|
40
|
+
session?.setDisplayTransform(transform);
|
|
41
|
+
return session !== null;
|
|
42
|
+
},
|
|
43
|
+
/** Frame everything the document's stage draws, as the viewport's Frame All does; false where the document has
|
|
44
|
+
* no stage session or nothing to frame. */
|
|
45
|
+
frameAll: (documentId: string): boolean => object3DDocumentSession(documentId)?.frame(1, 'all') ?? false,
|
|
46
|
+
/** A document's World: the scene its `build` root stands in, whose background, environment and fog the stage draws
|
|
47
|
+
* by (it mirrors them into the scene it renders); null while the root stands in no stage. */
|
|
48
|
+
documentWorld: (root: THREE.Object3D): THREE.Scene | null => (root.parent instanceof DocumentScene ? root.parent : null),
|
|
49
|
+
};
|
|
50
|
+
}
|
package/dist-node/serving.mjs
CHANGED
|
@@ -285,7 +285,9 @@ async function parseSourceModel(primaryPath, format, bytes) {
|
|
|
285
285
|
return loader.parse(new TextDecoder().decode(bytes));
|
|
286
286
|
}
|
|
287
287
|
case "dae": {
|
|
288
|
-
|
|
288
|
+
const collada = new ColladaLoader().parse(new TextDecoder().decode(bytes), resourcePath);
|
|
289
|
+
if (!collada) throw new Error(`${primaryPath} is not a COLLADA document`);
|
|
290
|
+
return collada.scene;
|
|
289
291
|
}
|
|
290
292
|
case "stl": {
|
|
291
293
|
const geometry = new STLLoader().parse(bytes.buffer);
|
|
@@ -395,11 +397,90 @@ function disposeObject(root) {
|
|
|
395
397
|
});
|
|
396
398
|
}
|
|
397
399
|
|
|
400
|
+
// serving/shared-three.ts
|
|
401
|
+
import { readFileSync } from "node:fs";
|
|
402
|
+
import path from "node:path";
|
|
403
|
+
|
|
404
|
+
// ../sdk/src/shared-doorway.ts
|
|
405
|
+
var SHARED_DOORWAY_PREFIX = "\0volter-shared:";
|
|
406
|
+
function sharedDoorwayId(specifier) {
|
|
407
|
+
return `${SHARED_DOORWAY_PREFIX}${specifier}`;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// serving/shared-three.ts
|
|
411
|
+
var SHARED_THREE_SPECIFIER = "three";
|
|
412
|
+
var SHARED_THREE_MANIFEST_FILE = "volter-shared-three.json";
|
|
413
|
+
function readSharedThreeManifest(distPath) {
|
|
414
|
+
const manifestPath = path.join(distPath, SHARED_THREE_MANIFEST_FILE);
|
|
415
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
416
|
+
if (typeof manifest.file !== "string" || !manifest.file || typeof manifest.coreFile !== "string" || !manifest.coreFile)
|
|
417
|
+
throw new Error(`${manifestPath} must name the shared three.js and core chunks. Rebuild the editor.`);
|
|
418
|
+
return { file: manifest.file, coreFile: manifest.coreFile };
|
|
419
|
+
}
|
|
420
|
+
function sharedThreeUrl(file) {
|
|
421
|
+
return `/${file}`;
|
|
422
|
+
}
|
|
423
|
+
var SHARED_THREE_DOORWAY = sharedDoorwayId(SHARED_THREE_SPECIFIER);
|
|
424
|
+
var SHARED_THREE_CORE_DOORWAY = sharedDoorwayId("three/build/three.core.js");
|
|
425
|
+
function sharedThreePlugin(url, coreUrl) {
|
|
426
|
+
return {
|
|
427
|
+
// Vite includes this plugin name in the dependency cache version.
|
|
428
|
+
name: "volter-shared:three",
|
|
429
|
+
enforce: "pre",
|
|
430
|
+
// `three` is the shell's here, never prebundled: excluding it externalizes it out of every
|
|
431
|
+
// prebundled chunk (Fiber's own `import 'three'` included), so those imports resolve at serve
|
|
432
|
+
// time through this plugin. A specifier cannot be both included and excluded.
|
|
433
|
+
config(config) {
|
|
434
|
+
const optimizeDeps = config.optimizeDeps ??= {};
|
|
435
|
+
optimizeDeps.include = (optimizeDeps.include ?? []).filter((specifier) => specifier !== SHARED_THREE_SPECIFIER);
|
|
436
|
+
optimizeDeps.exclude = [...optimizeDeps.exclude ?? [], SHARED_THREE_SPECIFIER];
|
|
437
|
+
},
|
|
438
|
+
load(id) {
|
|
439
|
+
if (id === SHARED_THREE_CORE_DOORWAY) return `export * from ${JSON.stringify(coreUrl)};
|
|
440
|
+
`;
|
|
441
|
+
return id === SHARED_THREE_DOORWAY ? `export * from ${JSON.stringify(SHARED_THREE_SPECIFIER)};
|
|
442
|
+
export { default } from ${JSON.stringify(SHARED_THREE_SPECIFIER)};
|
|
443
|
+
` : void 0;
|
|
444
|
+
},
|
|
445
|
+
resolveId(source, importer, options) {
|
|
446
|
+
if (importer === SHARED_THREE_CORE_DOORWAY && source === coreUrl) return coreUrl;
|
|
447
|
+
const cleanSource = source.split("?")[0].replaceAll("\\", "/");
|
|
448
|
+
const cleanImporter = (importer ?? "").split("?")[0].replaceAll("\\", "/");
|
|
449
|
+
const core = /(?:^|\/)three\/build\/three\.core\.js$/.test(cleanSource) || cleanSource === "./three.core.js" && /\/three\/build\/three\.[^/]+\.js$/.test(cleanImporter);
|
|
450
|
+
if (source !== SHARED_THREE_SPECIFIER && !core) return void 0;
|
|
451
|
+
if (options?.scan) return void 0;
|
|
452
|
+
if (core) return SHARED_THREE_CORE_DOORWAY;
|
|
453
|
+
return importer === SHARED_THREE_DOORWAY ? url : SHARED_THREE_DOORWAY;
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function projectThreeDedupePlugin() {
|
|
458
|
+
return {
|
|
459
|
+
name: "volter-three-dedupe",
|
|
460
|
+
config: () => ({ resolve: { dedupe: [SHARED_THREE_SPECIFIER, "@react-three/fiber", "its-fine"] } })
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
function sharedThreeServingPlugins(shellOutputDir) {
|
|
464
|
+
const dedupe = projectThreeDedupePlugin();
|
|
465
|
+
if (shellOutputDir === null) return [dedupe];
|
|
466
|
+
const manifest = readSharedThreeManifest(shellOutputDir);
|
|
467
|
+
return [dedupe, sharedThreePlugin(sharedThreeUrl(manifest.file), sharedThreeUrl(manifest.coreFile))];
|
|
468
|
+
}
|
|
469
|
+
|
|
398
470
|
// serving/index.ts
|
|
399
471
|
var servingPlugins = (services) => {
|
|
400
472
|
services.registerModelConverter(threeModelConverter);
|
|
401
|
-
return [animationStampPlugin(services)];
|
|
473
|
+
return [...sharedThreeServingPlugins(services.shellOutputDir), animationStampPlugin(services)];
|
|
402
474
|
};
|
|
475
|
+
var substrates = [
|
|
476
|
+
{
|
|
477
|
+
substrate: "three",
|
|
478
|
+
surface: "stage",
|
|
479
|
+
dialects: ["r3f"],
|
|
480
|
+
default: { dialect: "r3f", anchors: ["source-prop", "source-structure", "construction-literal"] }
|
|
481
|
+
}
|
|
482
|
+
];
|
|
403
483
|
export {
|
|
404
|
-
servingPlugins
|
|
484
|
+
servingPlugins,
|
|
485
|
+
substrates
|
|
405
486
|
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// serving/shared-three.ts
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
4
|
+
import path2 from "node:path";
|
|
5
|
+
|
|
6
|
+
// ../sdk/src/shared-doorway.ts
|
|
7
|
+
var SHARED_DOORWAY_PREFIX = "\0volter-shared:";
|
|
8
|
+
function sharedDoorwayId(specifier) {
|
|
9
|
+
return `${SHARED_DOORWAY_PREFIX}${specifier}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ../sdk/src/shared-entry-module.ts
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
var VALID_IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
16
|
+
function sharedEntryModule(specifier, exportNames) {
|
|
17
|
+
const named = exportNames.filter((name) => VALID_IDENTIFIER.test(name)).map((name) => `export const ${name} = __m.${name};`);
|
|
18
|
+
return [
|
|
19
|
+
`import * as __ns from ${JSON.stringify(specifier)};`,
|
|
20
|
+
// Bracketed on purpose: `__ns.default` makes rollup warn that the ES-module
|
|
21
|
+
// shape (the jsx-dev-runtime shim) has no `default` export, which is the
|
|
22
|
+
// case this line exists to handle.
|
|
23
|
+
"const __m = __ns['default'] ?? __ns;",
|
|
24
|
+
"export default __m;",
|
|
25
|
+
...named,
|
|
26
|
+
""
|
|
27
|
+
].join("\n");
|
|
28
|
+
}
|
|
29
|
+
function installedExportNames(fromDir, specifier) {
|
|
30
|
+
const require_ = createRequire(path.join(fromDir, "package.json"));
|
|
31
|
+
const loaded = require_(specifier);
|
|
32
|
+
return Object.keys(loaded).filter((name) => name !== "default");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// serving/shared-three.ts
|
|
36
|
+
var SHARED_THREE_SPECIFIER = "three";
|
|
37
|
+
var SHARED_THREE_ENTRY_NAME = "volter-shared-three";
|
|
38
|
+
var SHARED_THREE_MANIFEST_FILE = "volter-shared-three.json";
|
|
39
|
+
var VIRTUAL_PREFIX = "\0volter-shared-three:";
|
|
40
|
+
function sharedThreeBuildPlugin(fromDir) {
|
|
41
|
+
let referenceId;
|
|
42
|
+
let coreReferenceId;
|
|
43
|
+
return {
|
|
44
|
+
name: "volter-shared-three-build",
|
|
45
|
+
apply: "build",
|
|
46
|
+
buildStart() {
|
|
47
|
+
const require_ = createRequire2(path2.join(fromDir, "package.json"));
|
|
48
|
+
coreReferenceId = this.emitFile({
|
|
49
|
+
type: "chunk",
|
|
50
|
+
id: path2.join(path2.dirname(require_.resolve("three")), "three.core.js"),
|
|
51
|
+
name: "volter-shared-three-core",
|
|
52
|
+
preserveSignature: "strict"
|
|
53
|
+
});
|
|
54
|
+
referenceId = this.emitFile({
|
|
55
|
+
type: "chunk",
|
|
56
|
+
id: `${VIRTUAL_PREFIX}${SHARED_THREE_SPECIFIER}`,
|
|
57
|
+
name: SHARED_THREE_ENTRY_NAME,
|
|
58
|
+
// Same reason as the shared-React entries: Vite's app build sets
|
|
59
|
+
// `preserveEntrySignatures: false`, which would mangle the entry's
|
|
60
|
+
// export names away — `strict` keeps `Mesh` spelled `Mesh`.
|
|
61
|
+
preserveSignature: "strict"
|
|
62
|
+
});
|
|
63
|
+
},
|
|
64
|
+
resolveId(id) {
|
|
65
|
+
return id.startsWith(VIRTUAL_PREFIX) ? id : void 0;
|
|
66
|
+
},
|
|
67
|
+
load(id) {
|
|
68
|
+
if (!id.startsWith(VIRTUAL_PREFIX)) return void 0;
|
|
69
|
+
const specifier = id.slice(VIRTUAL_PREFIX.length);
|
|
70
|
+
return sharedEntryModule(specifier, installedExportNames(fromDir, specifier));
|
|
71
|
+
},
|
|
72
|
+
generateBundle() {
|
|
73
|
+
this.emitFile({
|
|
74
|
+
type: "asset",
|
|
75
|
+
fileName: SHARED_THREE_MANIFEST_FILE,
|
|
76
|
+
source: `${JSON.stringify(
|
|
77
|
+
{ file: this.getFileName(referenceId), coreFile: this.getFileName(coreReferenceId) },
|
|
78
|
+
null,
|
|
79
|
+
2
|
|
80
|
+
)}
|
|
81
|
+
`
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function readSharedThreeManifest(distPath) {
|
|
87
|
+
const manifestPath = path2.join(distPath, SHARED_THREE_MANIFEST_FILE);
|
|
88
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
89
|
+
if (typeof manifest.file !== "string" || !manifest.file || typeof manifest.coreFile !== "string" || !manifest.coreFile)
|
|
90
|
+
throw new Error(`${manifestPath} must name the shared three.js and core chunks. Rebuild the editor.`);
|
|
91
|
+
return { file: manifest.file, coreFile: manifest.coreFile };
|
|
92
|
+
}
|
|
93
|
+
function sharedThreeUrl(file) {
|
|
94
|
+
return `/${file}`;
|
|
95
|
+
}
|
|
96
|
+
var SHARED_THREE_DOORWAY = sharedDoorwayId(SHARED_THREE_SPECIFIER);
|
|
97
|
+
var SHARED_THREE_CORE_DOORWAY = sharedDoorwayId("three/build/three.core.js");
|
|
98
|
+
function sharedThreePlugin(url, coreUrl) {
|
|
99
|
+
return {
|
|
100
|
+
// Vite includes this plugin name in the dependency cache version.
|
|
101
|
+
name: "volter-shared:three",
|
|
102
|
+
enforce: "pre",
|
|
103
|
+
// `three` is the shell's here, never prebundled: excluding it externalizes it out of every
|
|
104
|
+
// prebundled chunk (Fiber's own `import 'three'` included), so those imports resolve at serve
|
|
105
|
+
// time through this plugin. A specifier cannot be both included and excluded.
|
|
106
|
+
config(config) {
|
|
107
|
+
const optimizeDeps = config.optimizeDeps ??= {};
|
|
108
|
+
optimizeDeps.include = (optimizeDeps.include ?? []).filter((specifier) => specifier !== SHARED_THREE_SPECIFIER);
|
|
109
|
+
optimizeDeps.exclude = [...optimizeDeps.exclude ?? [], SHARED_THREE_SPECIFIER];
|
|
110
|
+
},
|
|
111
|
+
load(id) {
|
|
112
|
+
if (id === SHARED_THREE_CORE_DOORWAY) return `export * from ${JSON.stringify(coreUrl)};
|
|
113
|
+
`;
|
|
114
|
+
return id === SHARED_THREE_DOORWAY ? `export * from ${JSON.stringify(SHARED_THREE_SPECIFIER)};
|
|
115
|
+
export { default } from ${JSON.stringify(SHARED_THREE_SPECIFIER)};
|
|
116
|
+
` : void 0;
|
|
117
|
+
},
|
|
118
|
+
resolveId(source, importer, options) {
|
|
119
|
+
if (importer === SHARED_THREE_CORE_DOORWAY && source === coreUrl) return coreUrl;
|
|
120
|
+
const cleanSource = source.split("?")[0].replaceAll("\\", "/");
|
|
121
|
+
const cleanImporter = (importer ?? "").split("?")[0].replaceAll("\\", "/");
|
|
122
|
+
const core = /(?:^|\/)three\/build\/three\.core\.js$/.test(cleanSource) || cleanSource === "./three.core.js" && /\/three\/build\/three\.[^/]+\.js$/.test(cleanImporter);
|
|
123
|
+
if (source !== SHARED_THREE_SPECIFIER && !core) return void 0;
|
|
124
|
+
if (options?.scan) return void 0;
|
|
125
|
+
if (core) return SHARED_THREE_CORE_DOORWAY;
|
|
126
|
+
return importer === SHARED_THREE_DOORWAY ? url : SHARED_THREE_DOORWAY;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function projectThreeDedupePlugin() {
|
|
131
|
+
return {
|
|
132
|
+
name: "volter-three-dedupe",
|
|
133
|
+
config: () => ({ resolve: { dedupe: [SHARED_THREE_SPECIFIER, "@react-three/fiber", "its-fine"] } })
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function sharedThreeServingPlugins(shellOutputDir) {
|
|
137
|
+
const dedupe = projectThreeDedupePlugin();
|
|
138
|
+
if (shellOutputDir === null) return [dedupe];
|
|
139
|
+
const manifest = readSharedThreeManifest(shellOutputDir);
|
|
140
|
+
return [dedupe, sharedThreePlugin(sharedThreeUrl(manifest.file), sharedThreeUrl(manifest.coreFile))];
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
sharedThreeBuildPlugin,
|
|
144
|
+
sharedThreeServingPlugins
|
|
145
|
+
};
|