@relu-interactives/spatial-ecs 0.2.5 → 0.2.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.
Files changed (42) hide show
  1. package/dist/{Video-DCMCLInA.d.ts → Video-B-qMljTn.d.ts} +15 -7
  2. package/dist/{Video-ChVFs9Tl.d.cts → Video-Dj4KBqQ1.d.cts} +15 -7
  3. package/dist/{chunk-4A66FSFT.js → chunk-EIC5B3A7.js} +4 -4
  4. package/dist/{chunk-4A66FSFT.js.map → chunk-EIC5B3A7.js.map} +1 -1
  5. package/dist/{chunk-CRP3W2GK.js → chunk-FDWNCXU3.js} +3 -3
  6. package/dist/{chunk-CRP3W2GK.js.map → chunk-FDWNCXU3.js.map} +1 -1
  7. package/dist/{chunk-NB6I5JJN.js → chunk-G2DUXNTQ.js} +3 -2
  8. package/dist/chunk-G2DUXNTQ.js.map +1 -0
  9. package/dist/{chunk-RXCUHGRB.js → chunk-NRSUYDBA.js} +183 -32
  10. package/dist/chunk-NRSUYDBA.js.map +1 -0
  11. package/dist/{chunk-KRZLEPRI.js → chunk-R5D5PWXV.js} +6 -2
  12. package/dist/chunk-R5D5PWXV.js.map +1 -0
  13. package/dist/components/index.cjs +4 -0
  14. package/dist/components/index.cjs.map +1 -1
  15. package/dist/components/index.d.cts +1 -1
  16. package/dist/components/index.d.ts +1 -1
  17. package/dist/components/index.js +1 -1
  18. package/dist/factories/index.cjs +4 -0
  19. package/dist/factories/index.cjs.map +1 -1
  20. package/dist/factories/index.d.cts +1 -1
  21. package/dist/factories/index.d.ts +1 -1
  22. package/dist/factories/index.js +3 -3
  23. package/dist/{index-D1I5L7bA.d.cts → index-B12sx9yF.d.cts} +1 -1
  24. package/dist/{index-DGZDgt3p.d.ts → index-Cf-PaKyN.d.ts} +1 -1
  25. package/dist/index.cjs +187 -28
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +12 -9
  30. package/dist/index.js.map +1 -1
  31. package/dist/systems/index.cjs +183 -28
  32. package/dist/systems/index.cjs.map +1 -1
  33. package/dist/systems/index.d.cts +16 -4
  34. package/dist/systems/index.d.ts +16 -4
  35. package/dist/systems/index.js +3 -3
  36. package/dist/worldSnapshotUtils.cjs +1 -0
  37. package/dist/worldSnapshotUtils.cjs.map +1 -1
  38. package/dist/worldSnapshotUtils.js +1 -1
  39. package/package.json +1 -1
  40. package/dist/chunk-KRZLEPRI.js.map +0 -1
  41. package/dist/chunk-NB6I5JJN.js.map +0 -1
  42. package/dist/chunk-RXCUHGRB.js.map +0 -1
@@ -89,14 +89,26 @@ declare class MeshGeometrySystem implements EcsSystem {
89
89
  }
90
90
 
91
91
  /**
92
- * Maintains `THREE.InstancedMesh` objects for entities with an
93
- * {@link InstancedMeshComponent}. Rebuilds the mesh when geometry parameters
94
- * or instance count change (signature-based dirty check), then writes per-
95
- * instance matrices every frame from the `instances` array.
92
+ * Maintains the runtime geometry for entities with an {@link InstancedMeshComponent}.
93
+ *
94
+ * - **Primitive kinds** (`cube`, `sphere`, `plane`, `cylinder`, `capsule`): creates a single
95
+ * `THREE.InstancedMesh` on the anchor and writes per-instance matrices every frame.
96
+ * - **Model kind** (`model`): asynchronously loads the GLTF/GLB at `comp.modelPath`, traverses
97
+ * the scene to collect all `THREE.Mesh` nodes, and creates one `THREE.InstancedMesh` per mesh
98
+ * (preserving the mesh's local transform and original materials). All sub-meshes are grouped
99
+ * under a `THREE.Group` stored in `comp.instancedMesh`. Per-instance matrices are composed as
100
+ * `instanceTransform × meshLocalMatrix` every frame.
101
+ *
102
+ * Geometry is rebuilt whenever the signature (`meshKind:parameters:instanceCount` for primitives,
103
+ * `model:path:instanceCount` for model kind) changes.
96
104
  */
97
105
  declare class InstancedMeshSystem implements EcsSystem {
98
106
  /** Signature tracking for geometry + instance count changes. */
99
107
  private readonly geometrySignatures;
108
+ /** Entities whose GLTF model is currently loading. Prevents duplicate load triggers. */
109
+ private readonly loadingEntities;
110
+ /** Per-mesh data for model kind, populated after GLTF load. */
111
+ private readonly modelMeshEntries;
100
112
  update(world: World): void;
101
113
  }
102
114
 
@@ -89,14 +89,26 @@ declare class MeshGeometrySystem implements EcsSystem {
89
89
  }
90
90
 
91
91
  /**
92
- * Maintains `THREE.InstancedMesh` objects for entities with an
93
- * {@link InstancedMeshComponent}. Rebuilds the mesh when geometry parameters
94
- * or instance count change (signature-based dirty check), then writes per-
95
- * instance matrices every frame from the `instances` array.
92
+ * Maintains the runtime geometry for entities with an {@link InstancedMeshComponent}.
93
+ *
94
+ * - **Primitive kinds** (`cube`, `sphere`, `plane`, `cylinder`, `capsule`): creates a single
95
+ * `THREE.InstancedMesh` on the anchor and writes per-instance matrices every frame.
96
+ * - **Model kind** (`model`): asynchronously loads the GLTF/GLB at `comp.modelPath`, traverses
97
+ * the scene to collect all `THREE.Mesh` nodes, and creates one `THREE.InstancedMesh` per mesh
98
+ * (preserving the mesh's local transform and original materials). All sub-meshes are grouped
99
+ * under a `THREE.Group` stored in `comp.instancedMesh`. Per-instance matrices are composed as
100
+ * `instanceTransform × meshLocalMatrix` every frame.
101
+ *
102
+ * Geometry is rebuilt whenever the signature (`meshKind:parameters:instanceCount` for primitives,
103
+ * `model:path:instanceCount` for model kind) changes.
96
104
  */
97
105
  declare class InstancedMeshSystem implements EcsSystem {
98
106
  /** Signature tracking for geometry + instance count changes. */
99
107
  private readonly geometrySignatures;
108
+ /** Entities whose GLTF model is currently loading. Prevents duplicate load triggers. */
109
+ private readonly loadingEntities;
110
+ /** Per-mesh data for model kind, populated after GLTF load. */
111
+ private readonly modelMeshEntries;
100
112
  update(world: World): void;
101
113
  }
102
114
 
@@ -1,6 +1,6 @@
1
- export { AnimationSystem, AudioSystem, CameraSyncSystem, EnvironmentSyncSystem, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MaterialSyncSystem, MeshGeometrySystem, ObjectVisibilitySystem, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, ScriptBehaviourSystem, TransformSyncSystem, VideoSystem } from '../chunk-RXCUHGRB.js';
2
- export { ObjectManagementSystem } from '../chunk-CRP3W2GK.js';
3
- import '../chunk-KRZLEPRI.js';
1
+ export { AnimationSystem, AudioSystem, CameraSyncSystem, EnvironmentSyncSystem, InputSystem, InstancedMeshSystem, KeyboardKeys, LightSyncSystem, MaterialSyncSystem, MeshGeometrySystem, ObjectVisibilitySystem, PhysicsSyncSystem, PostprocessingSyncSystem, RenderSystem, ScriptBehaviourSystem, TransformSyncSystem, VideoSystem } from '../chunk-NRSUYDBA.js';
2
+ export { ObjectManagementSystem } from '../chunk-FDWNCXU3.js';
3
+ import '../chunk-R5D5PWXV.js';
4
4
  import '../chunk-OY7ZODZP.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -115,6 +115,7 @@ function normalizeDebugValue(value, ctx) {
115
115
  return {
116
116
  __type: "InstancedMeshComponent",
117
117
  meshKind: typeof objectValue.meshKind === "string" ? objectValue.meshKind : "cube",
118
+ modelPath: typeof objectValue.modelPath === "string" ? objectValue.modelPath : "",
118
119
  meshParameters: normalizeDebugValue(objectValue.meshParameters, imCtx),
119
120
  castShadow: Boolean(objectValue.castShadow),
120
121
  receiveShadow: Boolean(objectValue.receiveShadow),
@@ -1 +1 @@
1
- {"version":3,"sources":["../core/Component.ts","../core/worldSnapshotUtils.ts"],"names":[],"mappings":"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","file":"worldSnapshotUtils.cjs","sourcesContent":["/**\n * Marker base class for every ECS component. Subclass `Component` to declare\n * a typed data container that systems can query.\n *\n * @remarks\n * Components own state only — runtime behaviour belongs in {@link Behaviour}\n * subclasses for user scripts. Keep fields plain (numbers, strings, vectors,\n * asset URLs).\n *\n * @category Components\n */\nexport class Component {}\n\n","import { Component } from \"./Component\";\nimport type { EntityId } from \"./types\";\n\nexport type ComponentClass<T extends Component> = new (...args: never[]) => T;\nexport type AnyComponent = Component;\n\nexport type WorldHistorySnapshot = {\n selectedEntityId: EntityId | null;\n entities: EntityId[];\n nextEntityId: number;\n components: Array<{\n componentType: ComponentClass<AnyComponent>;\n entries: Array<{\n entityId: EntityId;\n component: AnyComponent;\n }>;\n }>;\n};\n\nexport const DEBUG_CHANGE_IGNORED_SYSTEMS = new Set<string>([\n \"OrbitCameraSystem\",\n \"PhysicsSyncSystem\",\n]);\n\ntype NormalizeContext = {\n seen: WeakSet<object>;\n depth: number;\n maxDepth: number;\n};\n\nexport function normalizeDebugValue(\n value: unknown,\n ctx: NormalizeContext,\n): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n const valueType = typeof value;\n if (\n valueType === \"string\" ||\n valueType === \"number\" ||\n valueType === \"boolean\"\n ) {\n return value;\n }\n\n if (valueType === \"function\") {\n const fn = value as (...args: unknown[]) => unknown;\n return `[Function:${fn.name || \"anonymous\"}]`;\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (valueType !== \"object\") {\n return String(value);\n }\n\n const objectValue = value as Record<string, unknown>;\n\n const constructorName =\n objectValue.constructor?.name && objectValue.constructor.name !== \"Object\"\n ? objectValue.constructor.name\n : null;\n\n if (constructorName === \"AnimationClip\") {\n return {\n __type: \"AnimationClip\",\n name: typeof objectValue.name === \"string\" ? objectValue.name : \"\",\n };\n }\n\n if (constructorName === \"AnimationStateMachine\") {\n const clipValue =\n objectValue.clip && typeof objectValue.clip === \"object\"\n ? (objectValue.clip as Record<string, unknown>)\n : null;\n\n return {\n __type: \"AnimationStateMachine\",\n name: typeof objectValue.name === \"string\" ? objectValue.name : \"\",\n loop: Boolean(objectValue.loop),\n isPlaying: Boolean(objectValue.isPlaying),\n isPaused: Boolean(objectValue.isPaused),\n clip: {\n __type: \"AnimationClip\",\n name: typeof clipValue?.name === \"string\" ? clipValue.name : \"\",\n },\n };\n }\n\n if (constructorName === \"AnimationComponent\") {\n const clips = Array.isArray(objectValue.clips)\n ? objectValue.clips\n .map((clip) => {\n if (!clip || typeof clip !== \"object\") {\n return null;\n }\n\n const clipValue = clip as Record<string, unknown>;\n return {\n __type: \"AnimationClip\",\n name: typeof clipValue.name === \"string\" ? clipValue.name : \"\",\n };\n })\n .filter((clip): clip is { __type: \"AnimationClip\"; name: string } => clip !== null)\n : [];\n\n const availableClips = Array.isArray(objectValue.availableClips)\n ? objectValue.availableClips.filter(\n (entry): entry is string => typeof entry === \"string\" && entry.length > 0,\n )\n : clips.map((clip) => clip.name).filter((name) => name.length > 0);\n\n const externalClipSources = Array.isArray(objectValue.externalClipSources)\n ? objectValue.externalClipSources.filter(\n (entry): entry is string => typeof entry === \"string\" && entry.length > 0,\n )\n : [];\n\n const states = Array.isArray(objectValue.states)\n ? objectValue.states\n .map((state) => {\n if (!state || typeof state !== \"object\") {\n return null;\n }\n\n const stateValue = state as Record<string, unknown>;\n const clipValue =\n stateValue.clip && typeof stateValue.clip === \"object\"\n ? (stateValue.clip as Record<string, unknown>)\n : null;\n\n const name = typeof stateValue.name === \"string\" ? stateValue.name : \"\";\n const clip = typeof clipValue?.name === \"string\" ? clipValue.name : \"\";\n if (!name || !clip) {\n return null;\n }\n\n return {\n name,\n clip,\n clipId:\n typeof stateValue.clipId === \"string\" && stateValue.clipId.length > 0\n ? stateValue.clipId\n : null,\n loop: Boolean(stateValue.loop),\n };\n })\n .filter(\n (\n state,\n ): state is {\n name: string;\n clip: string;\n clipId: string | null;\n loop: boolean;\n } => state !== null,\n )\n : [];\n\n const activeValue =\n objectValue.active && typeof objectValue.active === \"object\"\n ? (objectValue.active as Record<string, unknown>)\n : null;\n\n const activeStateName =\n typeof objectValue.activeStateName === \"string\"\n ? objectValue.activeStateName\n : typeof activeValue?.name === \"string\"\n ? activeValue.name\n : null;\n\n return {\n __type: \"AnimationComponent\",\n clips,\n availableClips,\n externalClipSources,\n states,\n activeStateName,\n paused: Boolean(objectValue.paused),\n reverse: Boolean(objectValue.reverse),\n timeScale:\n typeof objectValue.timeScale === \"number\" && Number.isFinite(objectValue.timeScale)\n ? objectValue.timeScale\n : 1,\n crossFadeDuration:\n typeof objectValue.crossFadeDuration === \"number\" &&\n Number.isFinite(objectValue.crossFadeDuration)\n ? Math.max(0, objectValue.crossFadeDuration)\n : 0,\n };\n }\n\n if (constructorName === \"InstancedMeshComponent\") {\n // Only serialize the authoring fields. The live `instancedMesh` Three.js\n // ref changes on every geometry rebuild and must not enter the debug\n // snapshot — doing so would cause WorldChangeDetectionSystem to flood\n // the undo history with spurious entries.\n const imCtx: NormalizeContext = {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n };\n return {\n __type: \"InstancedMeshComponent\",\n meshKind: typeof objectValue.meshKind === \"string\" ? objectValue.meshKind : \"cube\",\n meshParameters: normalizeDebugValue(objectValue.meshParameters, imCtx),\n castShadow: Boolean(objectValue.castShadow),\n receiveShadow: Boolean(objectValue.receiveShadow),\n instances: normalizeDebugValue(objectValue.instances, imCtx),\n };\n }\n\n if (constructorName === \"PhysicsComponent\") {\n // `collider` Rapier references change every physics frame and must not\n // be included in the debug snapshot, otherwise the WorldChangeDetection-\n // System would detect a change every frame and flood the undo history.\n return {\n __type: \"PhysicsComponent\",\n values: normalizeDebugValue(objectValue.values, {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n }),\n };\n }\n\n if (constructorName === \"MaterialComponent\") {\n // Only serialize the authoring `values` state. The live Three.js\n // `material` / `materials` objects mutate after transparency is toggled\n // (shader recompilation flags, `needsUpdate`, etc.) and must not be\n // included in the debug snapshot — doing so causes the\n // WorldChangeDetectionSystem to detect a spurious change every frame.\n return {\n __type: \"MaterialComponent\",\n values: normalizeDebugValue(objectValue.values, {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n }),\n };\n }\n\n if (constructorName === \"VideoComponent\") {\n // Only serialize `path` and `options`. The live runtime fields\n // (`object`, `videoElement`, `texture`, `material`, `audioNode`) change\n // during video load/playback and must not be included in the debug\n // snapshot — doing so causes WorldChangeDetectionSystem to detect a\n // spurious change on every frame while a video is loading or playing.\n return {\n __type: \"VideoComponent\",\n path: typeof objectValue.path === \"string\" ? objectValue.path : \"\",\n options: normalizeDebugValue(objectValue.options, {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n }),\n };\n }\n\n if (ctx.seen.has(objectValue)) {\n return \"[Circular]\";\n }\n\n if (ctx.depth >= ctx.maxDepth) {\n return constructorName\n ? `[MaxDepth:${constructorName}]`\n : \"[MaxDepth:Object]\";\n }\n\n if (objectValue.nodeType === 1 && typeof objectValue.tagName === \"string\") {\n return `[HTMLElement:${String(objectValue.tagName)}]`;\n }\n\n if (objectValue.isObject3D === true) {\n const position = objectValue.position as\n | { x?: number; y?: number; z?: number }\n | undefined;\n\n return {\n __type: \"Object3D\",\n objectType: objectValue.type,\n name: objectValue.name,\n uuid: objectValue.uuid,\n position:\n position &&\n typeof position.x === \"number\" &&\n typeof position.y === \"number\" &&\n typeof position.z === \"number\"\n ? {\n x: position.x,\n y: position.y,\n z: position.z,\n }\n : undefined,\n };\n }\n\n ctx.seen.add(objectValue);\n const nextContext: NormalizeContext = {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n };\n\n if (Array.isArray(objectValue)) {\n return objectValue.map((item) => normalizeDebugValue(item, nextContext));\n }\n\n if (objectValue instanceof Map) {\n return {\n __type: \"Map\",\n entries: [...objectValue.entries()].map(([key, mapValue]) => [\n normalizeDebugValue(key, nextContext),\n normalizeDebugValue(mapValue, nextContext),\n ]),\n };\n }\n\n if (objectValue instanceof Set) {\n return {\n __type: \"Set\",\n values: [...objectValue.values()].map((setValue) =>\n normalizeDebugValue(setValue, nextContext),\n ),\n };\n }\n\n const normalized: Record<string, unknown> = {};\n const keys = Object.keys(objectValue).sort((a, b) => a.localeCompare(b));\n for (const key of keys) {\n normalized[key] = normalizeDebugValue(objectValue[key], nextContext);\n }\n\n return constructorName\n ? {\n __type: constructorName,\n ...normalized,\n }\n : normalized;\n}\n\nfunction shouldPreserveReference(value: object): boolean {\n const objectValue = value as Record<string, unknown>;\n\n if (objectValue.isObject3D === true) {\n return true;\n }\n\n if (objectValue.nodeType === 1 && typeof objectValue.tagName === \"string\") {\n return true;\n }\n\n return false;\n}\n\nexport function cloneHistoryValue<T>(\n value: T,\n seen: WeakMap<object, unknown> = new WeakMap<object, unknown>(),\n): T {\n if (value === null || value === undefined) {\n return value;\n }\n\n const valueType = typeof value;\n if (\n valueType === \"string\" ||\n valueType === \"number\" ||\n valueType === \"boolean\" ||\n valueType === \"bigint\" ||\n valueType === \"symbol\" ||\n valueType === \"function\"\n ) {\n return value;\n }\n\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n\n if (valueType !== \"object\") {\n return value;\n }\n\n const objectValue = value as Record<string, unknown>;\n\n if (shouldPreserveReference(objectValue)) {\n return value;\n }\n\n const seenValue = seen.get(objectValue);\n if (seenValue !== undefined) {\n return seenValue as T;\n }\n\n if (Array.isArray(objectValue)) {\n const cloneArray: unknown[] = [];\n seen.set(objectValue, cloneArray);\n\n for (const item of objectValue) {\n cloneArray.push(cloneHistoryValue(item, seen));\n }\n\n return cloneArray as T;\n }\n\n const prototype = Object.getPrototypeOf(objectValue);\n const shouldCloneWithPrototype =\n objectValue instanceof Component ||\n prototype === Object.prototype ||\n prototype === null;\n\n if (!shouldCloneWithPrototype) {\n return value;\n }\n\n const cloneObject = Object.create(prototype) as Record<string, unknown>;\n seen.set(objectValue, cloneObject);\n\n for (const key of Object.keys(objectValue)) {\n cloneObject[key] = cloneHistoryValue(objectValue[key], seen);\n }\n\n return cloneObject as T;\n}\n"]}
1
+ {"version":3,"sources":["../core/Component.ts","../core/worldSnapshotUtils.ts"],"names":[],"mappings":"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","file":"worldSnapshotUtils.cjs","sourcesContent":["/**\n * Marker base class for every ECS component. Subclass `Component` to declare\n * a typed data container that systems can query.\n *\n * @remarks\n * Components own state only — runtime behaviour belongs in {@link Behaviour}\n * subclasses for user scripts. Keep fields plain (numbers, strings, vectors,\n * asset URLs).\n *\n * @category Components\n */\nexport class Component {}\n\n","import { Component } from \"./Component\";\nimport type { EntityId } from \"./types\";\n\nexport type ComponentClass<T extends Component> = new (...args: never[]) => T;\nexport type AnyComponent = Component;\n\nexport type WorldHistorySnapshot = {\n selectedEntityId: EntityId | null;\n entities: EntityId[];\n nextEntityId: number;\n components: Array<{\n componentType: ComponentClass<AnyComponent>;\n entries: Array<{\n entityId: EntityId;\n component: AnyComponent;\n }>;\n }>;\n};\n\nexport const DEBUG_CHANGE_IGNORED_SYSTEMS = new Set<string>([\n \"OrbitCameraSystem\",\n \"PhysicsSyncSystem\",\n]);\n\ntype NormalizeContext = {\n seen: WeakSet<object>;\n depth: number;\n maxDepth: number;\n};\n\nexport function normalizeDebugValue(\n value: unknown,\n ctx: NormalizeContext,\n): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n const valueType = typeof value;\n if (\n valueType === \"string\" ||\n valueType === \"number\" ||\n valueType === \"boolean\"\n ) {\n return value;\n }\n\n if (valueType === \"function\") {\n const fn = value as (...args: unknown[]) => unknown;\n return `[Function:${fn.name || \"anonymous\"}]`;\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (valueType !== \"object\") {\n return String(value);\n }\n\n const objectValue = value as Record<string, unknown>;\n\n const constructorName =\n objectValue.constructor?.name && objectValue.constructor.name !== \"Object\"\n ? objectValue.constructor.name\n : null;\n\n if (constructorName === \"AnimationClip\") {\n return {\n __type: \"AnimationClip\",\n name: typeof objectValue.name === \"string\" ? objectValue.name : \"\",\n };\n }\n\n if (constructorName === \"AnimationStateMachine\") {\n const clipValue =\n objectValue.clip && typeof objectValue.clip === \"object\"\n ? (objectValue.clip as Record<string, unknown>)\n : null;\n\n return {\n __type: \"AnimationStateMachine\",\n name: typeof objectValue.name === \"string\" ? objectValue.name : \"\",\n loop: Boolean(objectValue.loop),\n isPlaying: Boolean(objectValue.isPlaying),\n isPaused: Boolean(objectValue.isPaused),\n clip: {\n __type: \"AnimationClip\",\n name: typeof clipValue?.name === \"string\" ? clipValue.name : \"\",\n },\n };\n }\n\n if (constructorName === \"AnimationComponent\") {\n const clips = Array.isArray(objectValue.clips)\n ? objectValue.clips\n .map((clip) => {\n if (!clip || typeof clip !== \"object\") {\n return null;\n }\n\n const clipValue = clip as Record<string, unknown>;\n return {\n __type: \"AnimationClip\",\n name: typeof clipValue.name === \"string\" ? clipValue.name : \"\",\n };\n })\n .filter((clip): clip is { __type: \"AnimationClip\"; name: string } => clip !== null)\n : [];\n\n const availableClips = Array.isArray(objectValue.availableClips)\n ? objectValue.availableClips.filter(\n (entry): entry is string => typeof entry === \"string\" && entry.length > 0,\n )\n : clips.map((clip) => clip.name).filter((name) => name.length > 0);\n\n const externalClipSources = Array.isArray(objectValue.externalClipSources)\n ? objectValue.externalClipSources.filter(\n (entry): entry is string => typeof entry === \"string\" && entry.length > 0,\n )\n : [];\n\n const states = Array.isArray(objectValue.states)\n ? objectValue.states\n .map((state) => {\n if (!state || typeof state !== \"object\") {\n return null;\n }\n\n const stateValue = state as Record<string, unknown>;\n const clipValue =\n stateValue.clip && typeof stateValue.clip === \"object\"\n ? (stateValue.clip as Record<string, unknown>)\n : null;\n\n const name = typeof stateValue.name === \"string\" ? stateValue.name : \"\";\n const clip = typeof clipValue?.name === \"string\" ? clipValue.name : \"\";\n if (!name || !clip) {\n return null;\n }\n\n return {\n name,\n clip,\n clipId:\n typeof stateValue.clipId === \"string\" && stateValue.clipId.length > 0\n ? stateValue.clipId\n : null,\n loop: Boolean(stateValue.loop),\n };\n })\n .filter(\n (\n state,\n ): state is {\n name: string;\n clip: string;\n clipId: string | null;\n loop: boolean;\n } => state !== null,\n )\n : [];\n\n const activeValue =\n objectValue.active && typeof objectValue.active === \"object\"\n ? (objectValue.active as Record<string, unknown>)\n : null;\n\n const activeStateName =\n typeof objectValue.activeStateName === \"string\"\n ? objectValue.activeStateName\n : typeof activeValue?.name === \"string\"\n ? activeValue.name\n : null;\n\n return {\n __type: \"AnimationComponent\",\n clips,\n availableClips,\n externalClipSources,\n states,\n activeStateName,\n paused: Boolean(objectValue.paused),\n reverse: Boolean(objectValue.reverse),\n timeScale:\n typeof objectValue.timeScale === \"number\" && Number.isFinite(objectValue.timeScale)\n ? objectValue.timeScale\n : 1,\n crossFadeDuration:\n typeof objectValue.crossFadeDuration === \"number\" &&\n Number.isFinite(objectValue.crossFadeDuration)\n ? Math.max(0, objectValue.crossFadeDuration)\n : 0,\n };\n }\n\n if (constructorName === \"InstancedMeshComponent\") {\n // Only serialize the authoring fields. The live `instancedMesh` Three.js\n // ref changes on every geometry rebuild and must not enter the debug\n // snapshot — doing so would cause WorldChangeDetectionSystem to flood\n // the undo history with spurious entries.\n const imCtx: NormalizeContext = {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n };\n return {\n __type: \"InstancedMeshComponent\",\n meshKind: typeof objectValue.meshKind === \"string\" ? objectValue.meshKind : \"cube\",\n modelPath: typeof objectValue.modelPath === \"string\" ? objectValue.modelPath : \"\",\n meshParameters: normalizeDebugValue(objectValue.meshParameters, imCtx),\n castShadow: Boolean(objectValue.castShadow),\n receiveShadow: Boolean(objectValue.receiveShadow),\n instances: normalizeDebugValue(objectValue.instances, imCtx),\n };\n }\n\n if (constructorName === \"PhysicsComponent\") {\n // `collider` Rapier references change every physics frame and must not\n // be included in the debug snapshot, otherwise the WorldChangeDetection-\n // System would detect a change every frame and flood the undo history.\n return {\n __type: \"PhysicsComponent\",\n values: normalizeDebugValue(objectValue.values, {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n }),\n };\n }\n\n if (constructorName === \"MaterialComponent\") {\n // Only serialize the authoring `values` state. The live Three.js\n // `material` / `materials` objects mutate after transparency is toggled\n // (shader recompilation flags, `needsUpdate`, etc.) and must not be\n // included in the debug snapshot — doing so causes the\n // WorldChangeDetectionSystem to detect a spurious change every frame.\n return {\n __type: \"MaterialComponent\",\n values: normalizeDebugValue(objectValue.values, {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n }),\n };\n }\n\n if (constructorName === \"VideoComponent\") {\n // Only serialize `path` and `options`. The live runtime fields\n // (`object`, `videoElement`, `texture`, `material`, `audioNode`) change\n // during video load/playback and must not be included in the debug\n // snapshot — doing so causes WorldChangeDetectionSystem to detect a\n // spurious change on every frame while a video is loading or playing.\n return {\n __type: \"VideoComponent\",\n path: typeof objectValue.path === \"string\" ? objectValue.path : \"\",\n options: normalizeDebugValue(objectValue.options, {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n }),\n };\n }\n\n if (ctx.seen.has(objectValue)) {\n return \"[Circular]\";\n }\n\n if (ctx.depth >= ctx.maxDepth) {\n return constructorName\n ? `[MaxDepth:${constructorName}]`\n : \"[MaxDepth:Object]\";\n }\n\n if (objectValue.nodeType === 1 && typeof objectValue.tagName === \"string\") {\n return `[HTMLElement:${String(objectValue.tagName)}]`;\n }\n\n if (objectValue.isObject3D === true) {\n const position = objectValue.position as\n | { x?: number; y?: number; z?: number }\n | undefined;\n\n return {\n __type: \"Object3D\",\n objectType: objectValue.type,\n name: objectValue.name,\n uuid: objectValue.uuid,\n position:\n position &&\n typeof position.x === \"number\" &&\n typeof position.y === \"number\" &&\n typeof position.z === \"number\"\n ? {\n x: position.x,\n y: position.y,\n z: position.z,\n }\n : undefined,\n };\n }\n\n ctx.seen.add(objectValue);\n const nextContext: NormalizeContext = {\n seen: ctx.seen,\n depth: ctx.depth + 1,\n maxDepth: ctx.maxDepth,\n };\n\n if (Array.isArray(objectValue)) {\n return objectValue.map((item) => normalizeDebugValue(item, nextContext));\n }\n\n if (objectValue instanceof Map) {\n return {\n __type: \"Map\",\n entries: [...objectValue.entries()].map(([key, mapValue]) => [\n normalizeDebugValue(key, nextContext),\n normalizeDebugValue(mapValue, nextContext),\n ]),\n };\n }\n\n if (objectValue instanceof Set) {\n return {\n __type: \"Set\",\n values: [...objectValue.values()].map((setValue) =>\n normalizeDebugValue(setValue, nextContext),\n ),\n };\n }\n\n const normalized: Record<string, unknown> = {};\n const keys = Object.keys(objectValue).sort((a, b) => a.localeCompare(b));\n for (const key of keys) {\n normalized[key] = normalizeDebugValue(objectValue[key], nextContext);\n }\n\n return constructorName\n ? {\n __type: constructorName,\n ...normalized,\n }\n : normalized;\n}\n\nfunction shouldPreserveReference(value: object): boolean {\n const objectValue = value as Record<string, unknown>;\n\n if (objectValue.isObject3D === true) {\n return true;\n }\n\n if (objectValue.nodeType === 1 && typeof objectValue.tagName === \"string\") {\n return true;\n }\n\n return false;\n}\n\nexport function cloneHistoryValue<T>(\n value: T,\n seen: WeakMap<object, unknown> = new WeakMap<object, unknown>(),\n): T {\n if (value === null || value === undefined) {\n return value;\n }\n\n const valueType = typeof value;\n if (\n valueType === \"string\" ||\n valueType === \"number\" ||\n valueType === \"boolean\" ||\n valueType === \"bigint\" ||\n valueType === \"symbol\" ||\n valueType === \"function\"\n ) {\n return value;\n }\n\n if (value instanceof Date) {\n return new Date(value.getTime()) as T;\n }\n\n if (valueType !== \"object\") {\n return value;\n }\n\n const objectValue = value as Record<string, unknown>;\n\n if (shouldPreserveReference(objectValue)) {\n return value;\n }\n\n const seenValue = seen.get(objectValue);\n if (seenValue !== undefined) {\n return seenValue as T;\n }\n\n if (Array.isArray(objectValue)) {\n const cloneArray: unknown[] = [];\n seen.set(objectValue, cloneArray);\n\n for (const item of objectValue) {\n cloneArray.push(cloneHistoryValue(item, seen));\n }\n\n return cloneArray as T;\n }\n\n const prototype = Object.getPrototypeOf(objectValue);\n const shouldCloneWithPrototype =\n objectValue instanceof Component ||\n prototype === Object.prototype ||\n prototype === null;\n\n if (!shouldCloneWithPrototype) {\n return value;\n }\n\n const cloneObject = Object.create(prototype) as Record<string, unknown>;\n seen.set(objectValue, cloneObject);\n\n for (const key of Object.keys(objectValue)) {\n cloneObject[key] = cloneHistoryValue(objectValue[key], seen);\n }\n\n return cloneObject as T;\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { DEBUG_CHANGE_IGNORED_SYSTEMS, cloneHistoryValue, normalizeDebugValue } from './chunk-NB6I5JJN.js';
1
+ export { DEBUG_CHANGE_IGNORED_SYSTEMS, cloneHistoryValue, normalizeDebugValue } from './chunk-G2DUXNTQ.js';
2
2
  import './chunk-OY7ZODZP.js';
3
3
  //# sourceMappingURL=worldSnapshotUtils.js.map
4
4
  //# sourceMappingURL=worldSnapshotUtils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@relu-interactives/spatial-ecs",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Reusable ECS core engine for Relu Spatial editor and runtime experiences.",
5
5
  "license": "MIT",
6
6
  "private": false,