@nodaro/shared 3.1.0 → 3.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodaro/shared",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Shared types, model catalog, wire contracts, and structural vocabularies for the Nodaro platform and SDK.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -0,0 +1,36 @@
1
+ import { describe, expect, it } from "vitest"
2
+ import { scene3DPlanV2Schema } from "../scene3d-v2-plan.js"
3
+ import { applyScene3DV2EditOperations } from "../scene3d-v2-edit.js"
4
+ import { computeScene3DPlanV2ContentHash, verifyScene3DPlanV2ContentHash } from "../scene3d-v2-resources.js"
5
+ import { planV2 } from "./scene3d-v2-fixtures.js"
6
+
7
+ describe("baked entity visibility", () => {
8
+ it("round-trips false without adding a default to existing revisions", async () => {
9
+ const original = planV2()
10
+ const hidden = { ...original, objects: original.objects.map(e => ({ ...e, visible: false })) }
11
+ expect(scene3DPlanV2Schema.parse(hidden).objects.every(e => e.visible === false)).toBe(true)
12
+ expect(scene3DPlanV2Schema.parse(original).objects.every(e => !("visible" in e))).toBe(true)
13
+ expect(await computeScene3DPlanV2ContentHash(hidden)).not.toBe(await computeScene3DPlanV2ContentHash(original))
14
+ expect(scene3DPlanV2Schema.safeParse({ ...hidden, objects: hidden.objects.map(e => ({ ...e, visible: "false" })) }).success).toBe(false)
15
+ })
16
+
17
+ it("keeps baked visibility when a temporary show override is added and removed", async () => {
18
+ const original = planV2()
19
+ const hidden = { ...original, overrides: [], objects: original.objects.map(e => ({ ...e, visible: e.id !== "e2" })) }
20
+ hidden.provenance = { ...hidden.provenance, contentHash: await computeScene3DPlanV2ContentHash(hidden) }
21
+ const shown = await applyScene3DV2EditOperations(hidden, [{ op: "set-override", override: {
22
+ kind: "entity-visibility", entityId: "e2", visible: true,
23
+ } }], { expectedRevisionId: hidden.revisionId })
24
+ expect(shown.ok).toBe(true)
25
+ if (!shown.ok) return
26
+ const override = shown.plan.overrides!.find(o => o.kind === "entity-visibility")!
27
+ const reset = await applyScene3DV2EditOperations(shown.plan, [{ op: "remove-override", overrideId: override.id }], {
28
+ expectedRevisionId: shown.plan.revisionId,
29
+ })
30
+ expect(reset.ok).toBe(true)
31
+ if (!reset.ok) return
32
+ expect(reset.plan.objects.find(e => e.id === "e2")?.visible).toBe(false)
33
+ expect(reset.plan.overrides).toEqual([])
34
+ expect(await verifyScene3DPlanV2ContentHash(reset.plan)).toBe(true)
35
+ })
36
+ })
package/src/scene3d-v2.ts CHANGED
@@ -314,6 +314,8 @@ export interface Scene3DEntityV2 {
314
314
  position?: Vec3
315
315
  rotation?: Vec3
316
316
  scale?: Vec3
317
+ /** Baked visibility before manual overlays. Absent means visible. */
318
+ visible?: boolean
317
319
  /** The selection/identity chip colour. Opaque hex, sRGB. */
318
320
  identityColor?: string
319
321
  anchors?: Scene3DAnchor[]
@@ -541,6 +543,7 @@ export const scene3DEntityV2Schema = z
541
543
  position: vec3Schema.optional(),
542
544
  rotation: rotationVec3Schema.optional(),
543
545
  scale: scaleVec3Schema.optional(),
546
+ visible: z.boolean().optional(),
544
547
  identityColor: scene3DColorSchema.optional(),
545
548
  anchors: z.array(scene3DAnchorSchema).max(SCENE3D_V2_LIMITS.maxAnchorsPerEntity).optional(),
546
549
  capabilities: z.array(scene3DEntityCapabilitySchema).max(SCENE3D_ENTITY_CAPABILITIES.length).optional(),