@volter/editor-react 0.5.211 → 0.5.212

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.
@@ -1,44 +1,8 @@
1
- /**
2
- * Declared-prop resolution for a custom R3F component — what the inspector
3
- * shows for a `<Enemy …>` node.
4
- *
5
- * WHY THIS EXISTS. The inspector used to describe a node purely by the
6
- * attributes physically written in its JSX tag: a prop nobody typed was
7
- * invisible, and its widget was guessed from the raw attribute text, so
8
- * `variant="sharpshooter"` read as free text even though the component
9
- * declares a two-value union. That is backwards from every mainstream engine —
10
- * Unity/Godot/Unreal show a component's whole declared surface at its defaults
11
- * and treat the authored values as the subset you have overridden.
12
- *
13
- * HOW IT PARSES, and why not the way the neighbours do. Two different
14
- * questions need two different tools:
15
- *
16
- * - WHICH props belong to this component is SYNTACTIC. It is the members the
17
- * author literally wrote in the props type. `ThreeElements['group'] & {…}`
18
- * contributes only the `{…}`; the forwarded native surface is hundreds of
19
- * three.js props the author did not author. So this walks the type node's
20
- * own AST and only descends into declarations that live in the project.
21
- *
22
- * - WHAT TYPE each prop has is SEMANTIC, and is exactly the job of the
23
- * TypeScript type checker. `variant: EnemyVariant` where
24
- * `EnemyVariant = keyof typeof ENEMY_MODEL_PATHS` resolves to
25
- * `'raider' | 'sharpshooter'` with no grammar written here at all.
26
- *
27
- * The sibling analysers in `oid-transform.ts` answer their (narrower) type
28
- * question by regexing `TypeNode.getText()`, which is why they only recognize
29
- * `ThreeElements['group']` spelled that one way. Do not copy that here: a
30
- * checker was always the right instrument for reading types, and this module
31
- * pays the one-time cost of a real program to get it.
32
- *
33
- * COST. A `ts.LanguageService` over the project's own tsconfig — ~1.7s and
34
- * ~2.4k files cold for a shipped example, then warm and incremental. It is
35
- * built lazily on the first inspector query and reused; only project files are
36
- * version-stamped, so an ordinary edit re-checks without a rebuild.
37
- *
38
- * SERVER-SIDE ONLY: this imports `typescript` and `node:fs` and is used from
39
- * `vite-plugin-ui-oid.ts`. The editor bundle receives the RESULT on the OID
40
- * index entry — it never parses TypeScript itself.
41
- */
1
+ /** Resolve authored component props with the project's TypeScript language service.
2
+ * The authored prop names come from project type declarations; the checker
3
+ * supplies their types, including aliases and inferred union values. Native
4
+ * forwarded props are excluded. The service is lazy and incremental, and runs
5
+ * in the declared-prop worker; clients receive the resulting OID-index specs. */
42
6
  import { statSync } from 'node:fs';
43
7
  import { dirname, resolve } from 'node:path';
44
8
  import ts from 'typescript';
@@ -467,27 +431,7 @@ export class ComponentPropResolver {
467
431
  for (const { symbol, declaration } of ownProps(propsType, homePackage)) {
468
432
  specs.set(symbol.getName(), declaredSpec(symbol, declaration, checker, defaults));
469
433
  }
470
- // A prop the component DESTRUCTURES is a prop it reads, whatever package
471
- // its type was declared in — so membership is settled and only the type is
472
- // left, which is the checker's job (this module's own split, see the
473
- // header). `ownProps`' package filter answers "which of the hundreds of
474
- // FORWARDED members did this author write?"; it must not also decide
475
- // whether a prop the author literally named has a knowable type.
476
- //
477
- // MEASURED on the racing ingest: `<Physics allowSleep broadphase
478
- // defaultContactMaterial>` and `<Vehicle angularVelocity>` are all read by
479
- // their component's own destructuring while being declared in
480
- // `@pmndrs/cannon-worker-api` — a different package from the component's
481
- // — so every one arrived typeless and the inspector fell through to
482
- // guessing the widget from the attribute TEXT (`allowSleep` → `boolean` by
483
- // luck; `broadphase` → free-text `string` where the declaration is a
484
- // two-value union; `angularVelocity` → `string` where it is a Triplet).
485
- //
486
- // `getTypeOfSymbol`, not `getTypeOfSymbolAtLocation`: a `Pick<>`-mapped
487
- // member has NO declaration to pass as the location (measured — `Vehicle`'s
488
- // `angularVelocity` reports `declarations.length === 0`), which is also why
489
- // `declaredSpec` cannot be reused here. A prop with no reachable type stays
490
- // `null`, and the inspector's loud text-guess fallback still covers it.
434
+ // Resolve aliased type members through their symbol at the JSX opening element.
491
435
  for (const name of order) {
492
436
  if (specs.has(name)) continue;
493
437
  const symbol = propsType.getProperty(name);
@@ -0,0 +1,24 @@
1
+ /** Local JSX names imported as Drei's Detailed component. */
2
+
3
+ import ts from 'typescript';
4
+
5
+ export function dreiDetailedLocalNames(sf: ts.SourceFile): Set<string> {
6
+ const names = new Set<string>();
7
+ for (const statement of sf.statements) {
8
+ if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) {
9
+ continue;
10
+ }
11
+ if (!statement.moduleSpecifier.text.startsWith('@react-three/drei')) continue;
12
+ const bindings = statement.importClause?.namedBindings;
13
+ if (bindings && ts.isNamedImports(bindings)) {
14
+ for (const element of bindings.elements) {
15
+ if ((element.propertyName?.text ?? element.name.text) === 'Detailed') {
16
+ names.add(element.name.text);
17
+ }
18
+ }
19
+ } else if (bindings && ts.isNamespaceImport(bindings)) {
20
+ names.add(`${bindings.name.text}.Detailed`);
21
+ }
22
+ }
23
+ return names;
24
+ }