mujoco-react 9.6.0 → 10.0.0

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/src/types.ts CHANGED
@@ -17,7 +17,7 @@ import * as THREE from 'three';
17
17
  * ```ts
18
18
  * declare module 'mujoco-react' {
19
19
  * interface Register {
20
- * robots: {
20
+ * models: {
21
21
  * panda: {
22
22
  * actuators: 'joint1' | 'joint2' | 'gripper';
23
23
  * sensors: 'force_sensor' | 'torque_sensor';
@@ -35,45 +35,45 @@ import * as THREE from 'three';
35
35
  */
36
36
  export interface Register {}
37
37
 
38
- export type RegisteredRobotMap = Register extends { robots: infer T extends Record<string, Record<string, string>> }
38
+ export type RegisteredModelMap = Register extends { models: infer T extends Record<string, Record<string, string>> }
39
39
  ? T
40
40
  : never;
41
- export type Robots = [RegisteredRobotMap] extends [never] ? string : Extract<keyof RegisteredRobotMap, string>;
42
- export type RobotResource<TRobot extends string, TKey extends string> =
43
- [RegisteredRobotMap] extends [never]
41
+ export type Models = [RegisteredModelMap] extends [never] ? string : Extract<keyof RegisteredModelMap, string>;
42
+ export type ModelResource<TModel extends string, TKey extends string> =
43
+ [RegisteredModelMap] extends [never]
44
44
  ? string
45
- : TRobot extends keyof RegisteredRobotMap
46
- ? TKey extends keyof RegisteredRobotMap[TRobot]
47
- ? RegisteredRobotMap[TRobot][TKey]
45
+ : TModel extends keyof RegisteredModelMap
46
+ ? TKey extends keyof RegisteredModelMap[TModel]
47
+ ? RegisteredModelMap[TModel][TKey]
48
48
  : string
49
49
  : never;
50
- export type RobotActuators<TRobot extends string> = RobotResource<TRobot, 'actuators'>;
51
- export type RobotSensors<TRobot extends string> = RobotResource<TRobot, 'sensors'>;
52
- export type RobotBodies<TRobot extends string> = RobotResource<TRobot, 'bodies'>;
53
- export type RobotJoints<TRobot extends string> = RobotResource<TRobot, 'joints'>;
54
- export type RobotSites<TRobot extends string> = RobotResource<TRobot, 'sites'>;
55
- export type RobotGeoms<TRobot extends string> = RobotResource<TRobot, 'geoms'>;
56
- export type RobotKeyframes<TRobot extends string> = RobotResource<TRobot, 'keyframes'>;
57
- export type RobotCameras<TRobot extends string> = RobotResource<TRobot, 'cameras'>;
50
+ export type ModelActuators<TModel extends string> = ModelResource<TModel, 'actuators'>;
51
+ export type ModelSensors<TModel extends string> = ModelResource<TModel, 'sensors'>;
52
+ export type ModelBodies<TModel extends string> = ModelResource<TModel, 'bodies'>;
53
+ export type ModelJoints<TModel extends string> = ModelResource<TModel, 'joints'>;
54
+ export type ModelSites<TModel extends string> = ModelResource<TModel, 'sites'>;
55
+ export type ModelGeoms<TModel extends string> = ModelResource<TModel, 'geoms'>;
56
+ export type ModelKeyframes<TModel extends string> = ModelResource<TModel, 'keyframes'>;
57
+ export type ModelCameras<TModel extends string> = ModelResource<TModel, 'cameras'>;
58
58
 
59
59
  export type RegisterResourceKey = 'actuators' | 'sensors' | 'bodies' | 'joints' | 'sites' | 'geoms' | 'keyframes' | 'cameras';
60
- export type RobotResourceObject<TRobot extends string, TKey extends RegisterResourceKey> =
61
- string extends RobotResource<TRobot, TKey>
60
+ export type ModelResourceObject<TModel extends string, TKey extends RegisterResourceKey> =
61
+ string extends ModelResource<TModel, TKey>
62
62
  ? Record<string, string>
63
- : { readonly [K in RobotResource<TRobot, TKey>]: K };
64
- export type RobotResourceCategory<TKey extends RegisterResourceKey> =
65
- string extends Robots
63
+ : { readonly [K in ModelResource<TModel, TKey>]: K };
64
+ export type ModelResourceCategory<TKey extends RegisterResourceKey> =
65
+ string extends Models
66
66
  ? Record<string, Record<string, string>>
67
- : { readonly [TRobot in Robots]: RobotResourceObject<TRobot, TKey> };
68
- export type RobotResourceRegistry =
69
- string extends Robots
67
+ : { readonly [TModel in Models]: ModelResourceObject<TModel, TKey> };
68
+ export type ModelResourceRegistry =
69
+ string extends Models
70
70
  ? Record<string, Record<RegisterResourceKey, Record<string, string>>>
71
- : { readonly [TRobot in Robots]: { readonly [TKey in RegisterResourceKey]: RobotResourceObject<TRobot, TKey> } };
71
+ : { readonly [TModel in Models]: { readonly [TKey in RegisterResourceKey]: ModelResourceObject<TModel, TKey> } };
72
72
 
73
- type RuntimeRobotResources = Record<string, Record<RegisterResourceKey, Record<string, string>>>;
74
- type RuntimeRobotResourceRegistration = Readonly<Record<string, Readonly<Record<RegisterResourceKey, Readonly<Record<string, string>>>>>>;
73
+ type RuntimeModelResources = Record<string, Record<RegisterResourceKey, Record<string, string>>>;
74
+ type RuntimeModelResourceRegistration = Readonly<Record<string, Readonly<Record<RegisterResourceKey, Readonly<Record<string, string>>>>>>;
75
75
 
76
- const runtimeRobotResources: RuntimeRobotResources = {};
76
+ const runtimeModelResources: RuntimeModelResources = {};
77
77
  const REGISTER_RESOURCE_KEYS: RegisterResourceKey[] = ['actuators', 'sensors', 'bodies', 'joints', 'sites', 'geoms', 'keyframes', 'cameras'];
78
78
 
79
79
  function createEmptyRuntimeResources(): Record<RegisterResourceKey, Record<string, string>> {
@@ -89,54 +89,54 @@ function createEmptyRuntimeResources(): Record<RegisterResourceKey, Record<strin
89
89
  };
90
90
  }
91
91
 
92
- export function registerRobotResources(resources: RuntimeRobotResourceRegistration): void {
93
- for (const [robot, robotResources] of Object.entries(resources)) {
94
- const existing = runtimeRobotResources[robot] ?? createEmptyRuntimeResources();
92
+ export function registerModelResources(resources: RuntimeModelResourceRegistration): void {
93
+ for (const [model, modelResources] of Object.entries(resources)) {
94
+ const existing = runtimeModelResources[model] ?? createEmptyRuntimeResources();
95
95
  for (const key of REGISTER_RESOURCE_KEYS) {
96
- existing[key] = { ...existing[key], ...(robotResources[key] ?? {}) };
96
+ existing[key] = { ...existing[key], ...(modelResources[key] ?? {}) };
97
97
  }
98
- runtimeRobotResources[robot] = existing;
98
+ runtimeModelResources[model] = existing;
99
99
  }
100
100
  }
101
101
 
102
- function createResourceCategory<TKey extends RegisterResourceKey>(key: TKey): RobotResourceCategory<TKey> {
102
+ function createResourceCategory<TKey extends RegisterResourceKey>(key: TKey): ModelResourceCategory<TKey> {
103
103
  return new Proxy({}, {
104
- get(_target, robot) {
105
- if (typeof robot !== 'string') return undefined;
106
- return runtimeRobotResources[robot]?.[key] ?? {};
104
+ get(_target, model) {
105
+ if (typeof model !== 'string') return undefined;
106
+ return runtimeModelResources[model]?.[key] ?? {};
107
107
  },
108
108
  ownKeys() {
109
- return Reflect.ownKeys(runtimeRobotResources);
109
+ return Reflect.ownKeys(runtimeModelResources);
110
110
  },
111
- getOwnPropertyDescriptor(_target, robot) {
112
- if (typeof robot !== 'string' || !(robot in runtimeRobotResources)) return undefined;
111
+ getOwnPropertyDescriptor(_target, model) {
112
+ if (typeof model !== 'string' || !(model in runtimeModelResources)) return undefined;
113
113
  return { enumerable: true, configurable: true };
114
114
  },
115
- }) as RobotResourceCategory<TKey>;
115
+ }) as ModelResourceCategory<TKey>;
116
116
  }
117
117
 
118
- export const RobotResources: RobotResourceRegistry = new Proxy(runtimeRobotResources, {
119
- get(target, robot) {
120
- if (typeof robot !== 'string') return undefined;
121
- return target[robot] ?? createEmptyRuntimeResources();
118
+ export const ModelResources: ModelResourceRegistry = new Proxy(runtimeModelResources, {
119
+ get(target, model) {
120
+ if (typeof model !== 'string') return undefined;
121
+ return target[model] ?? createEmptyRuntimeResources();
122
122
  },
123
123
  ownKeys(target) {
124
124
  return Reflect.ownKeys(target);
125
125
  },
126
- getOwnPropertyDescriptor(target, robot) {
127
- if (typeof robot !== 'string' || !(robot in target)) return undefined;
126
+ getOwnPropertyDescriptor(target, model) {
127
+ if (typeof model !== 'string' || !(model in target)) return undefined;
128
128
  return { enumerable: true, configurable: true };
129
129
  },
130
- }) as RobotResourceRegistry;
130
+ }) as ModelResourceRegistry;
131
131
 
132
- export const RobotActuators: RobotResourceCategory<'actuators'> = createResourceCategory('actuators');
133
- export const RobotSensors: RobotResourceCategory<'sensors'> = createResourceCategory('sensors');
134
- export const RobotBodies: RobotResourceCategory<'bodies'> = createResourceCategory('bodies');
135
- export const RobotJoints: RobotResourceCategory<'joints'> = createResourceCategory('joints');
136
- export const RobotSites: RobotResourceCategory<'sites'> = createResourceCategory('sites');
137
- export const RobotGeoms: RobotResourceCategory<'geoms'> = createResourceCategory('geoms');
138
- export const RobotKeyframes: RobotResourceCategory<'keyframes'> = createResourceCategory('keyframes');
139
- export const RobotCameras: RobotResourceCategory<'cameras'> = createResourceCategory('cameras');
132
+ export const ModelActuators: ModelResourceCategory<'actuators'> = createResourceCategory('actuators');
133
+ export const ModelSensors: ModelResourceCategory<'sensors'> = createResourceCategory('sensors');
134
+ export const ModelBodies: ModelResourceCategory<'bodies'> = createResourceCategory('bodies');
135
+ export const ModelJoints: ModelResourceCategory<'joints'> = createResourceCategory('joints');
136
+ export const ModelSites: ModelResourceCategory<'sites'> = createResourceCategory('sites');
137
+ export const ModelGeoms: ModelResourceCategory<'geoms'> = createResourceCategory('geoms');
138
+ export const ModelKeyframes: ModelResourceCategory<'keyframes'> = createResourceCategory('keyframes');
139
+ export const ModelCameras: ModelResourceCategory<'cameras'> = createResourceCategory('cameras');
140
140
 
141
141
  export type Actuators = Register extends { actuators: infer T extends string } ? T : string;
142
142
  export type Sensors = Register extends { sensors: infer T extends string } ? T : string;
@@ -1532,7 +1532,30 @@ export interface BodyStateResult {
1532
1532
  angularVelocity: React.RefObject<THREE.Vector3>;
1533
1533
  }
1534
1534
 
1535
+ export type JointStateKind = 'auto' | 'scalar' | 'array';
1536
+
1537
+ export interface JointStateOptions {
1538
+ /**
1539
+ * Expected joint value shape.
1540
+ *
1541
+ * - `auto`: scalar joints return numbers, ball/free joints return Float64Array.
1542
+ * - `scalar`: return numeric refs for hinge/slide joints.
1543
+ * - `array`: return Float64Array refs for ball/free joints.
1544
+ */
1545
+ kind?: JointStateKind;
1546
+ }
1547
+
1535
1548
  export interface JointStateResult {
1536
1549
  position: React.RefObject<number | Float64Array>;
1537
1550
  velocity: React.RefObject<number | Float64Array>;
1538
1551
  }
1552
+
1553
+ export interface ScalarJointStateResult {
1554
+ position: React.RefObject<number>;
1555
+ velocity: React.RefObject<number>;
1556
+ }
1557
+
1558
+ export interface ArrayJointStateResult {
1559
+ position: React.RefObject<Float64Array>;
1560
+ velocity: React.RefObject<Float64Array>;
1561
+ }
package/src/vite.ts CHANGED
@@ -221,21 +221,21 @@ function renderRegister(
221
221
  const fields = REGISTER_KEYS
222
222
  .filter((key) => names[key].size > 0)
223
223
  .map((key) => ` ${key}: ${renderUnion(names[key])};`);
224
- const robots = models
225
- .map((model) => ` ${quoteProperty(model.id)}: {\n${renderRobotFields(model.names)}\n };`);
224
+ const modelFields = models
225
+ .map((model) => ` ${quoteProperty(model.id)}: {\n${renderModelFields(model.names)}\n };`);
226
226
  const namespaceAliases = renderNamespaceAliases(models);
227
- const registerImport = declarationsOnly ? '' : `import { registerRobotResources } from '${moduleName}';\n`;
228
- const resources = declarationsOnly ? '' : `${renderResourceTypes(models)}\n\n${renderResourceConstants(models)}\n\nregisterRobotResources(generatedRobotResources);\n\n`;
227
+ const registerImport = declarationsOnly ? '' : `import { registerModelResources } from '${moduleName}';\n`;
228
+ const resources = declarationsOnly ? '' : `${renderResourceTypes(models)}\n\n${renderResourceConstants(models)}\n\nregisterModelResources(generatedModelResources);\n\n`;
229
229
 
230
230
  return `// Auto-generated by mujoco-react. Do not edit.
231
231
  // Regenerate by running Vite with the mujocoReact() plugin or \`mujoco-react codegen\`.
232
232
 
233
- ${registerImport}import type { RobotResource } from '${moduleName}';
233
+ ${registerImport}import type { ModelResource } from '${moduleName}';
234
234
 
235
235
  ${resources}declare module '${moduleName}' {
236
236
  interface Register {
237
- robots: {
238
- ${robots.join('\n')}
237
+ models: {
238
+ ${modelFields.join('\n')}
239
239
  };
240
240
  ${fields.join('\n')}
241
241
  }
@@ -249,7 +249,7 @@ function renderResourceTypes(models: readonly ModelEntry[]): string {
249
249
  const modelTypes = models
250
250
  .map((model) => ` readonly ${quoteProperty(model.id)}: {\n${renderResourceTypeFields(model.names)}\n };`)
251
251
  .join('\n');
252
- return `type GeneratedRobotResources = {\n${modelTypes}\n};`;
252
+ return `type GeneratedModelResources = {\n${modelTypes}\n};`;
253
253
  }
254
254
 
255
255
  function renderResourceTypeFields(names: Record<RegisterKey, Set<string>>): string {
@@ -268,7 +268,7 @@ function renderResourceConstants(models: readonly ModelEntry[]): string {
268
268
  const entries = models
269
269
  .map((model) => ` ${quoteProperty(model.id)}: {\n${renderResourceConstantFields(model.names)}\n },`)
270
270
  .join('\n');
271
- return `const generatedRobotResources: GeneratedRobotResources = {\n${entries}\n};`;
271
+ return `const generatedModelResources: GeneratedModelResources = {\n${entries}\n};`;
272
272
  }
273
273
 
274
274
  function renderResourceConstantFields(names: Record<RegisterKey, Set<string>>): string {
@@ -283,7 +283,7 @@ function renderResourceObject(values: Set<string>): string {
283
283
  return entries.length > 0 ? `{\n${entries.join('\n')}\n }` : '{}';
284
284
  }
285
285
 
286
- function renderRobotFields(names: Record<RegisterKey, Set<string>>): string {
286
+ function renderModelFields(names: Record<RegisterKey, Set<string>>): string {
287
287
  return REGISTER_KEYS
288
288
  .map((key) => ` ${key}: ${names[key].size > 0 ? renderUnion(names[key]) : 'never'};`)
289
289
  .join('\n');
@@ -295,23 +295,23 @@ function renderUnion(values: Set<string>): string {
295
295
 
296
296
  function renderNamespaceAliases(models: readonly ModelEntry[]): string {
297
297
  const namespaces: Record<RegisterKey, string> = {
298
- actuators: 'RobotActuators',
299
- sensors: 'RobotSensors',
300
- bodies: 'RobotBodies',
301
- joints: 'RobotJoints',
302
- sites: 'RobotSites',
303
- geoms: 'RobotGeoms',
304
- keyframes: 'RobotKeyframes',
305
- cameras: 'RobotCameras',
298
+ actuators: 'ModelActuators',
299
+ sensors: 'ModelSensors',
300
+ bodies: 'ModelBodies',
301
+ joints: 'ModelJoints',
302
+ sites: 'ModelSites',
303
+ geoms: 'ModelGeoms',
304
+ keyframes: 'ModelKeyframes',
305
+ cameras: 'ModelCameras',
306
306
  };
307
307
 
308
308
  const blocks = REGISTER_KEYS
309
309
  .map((key) => {
310
- const aliases = models
310
+ const modelAliases = models
311
311
  .filter((model) => isIdentifier(model.id))
312
- .map((model) => ` export type ${model.id} = RobotResource<'${escapeTs(model.id)}', '${key}'>;`);
313
- if (aliases.length === 0) return '';
314
- return ` export namespace ${namespaces[key]} {\n${aliases.join('\n')}\n }`;
312
+ .map((model) => ` export type ${model.id} = ModelResource<'${escapeTs(model.id)}', '${key}'>;`);
313
+ if (modelAliases.length === 0) return '';
314
+ return ` export namespace ${namespaces[key]} {\n${modelAliases.join('\n')}\n }`;
315
315
  })
316
316
  .filter(Boolean)
317
317
  .join('\n\n');