@plasius/scene-object 0.1.2
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/LICENSE +203 -0
- package/README.md +40 -0
- package/dist/index.cjs +459 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +93 -0
- package/dist/index.d.ts +93 -0
- package/dist/index.js +425 -0
- package/dist/index.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/validation.ts","../src/resolve.ts"],"sourcesContent":["export {\n SCENE_OBJECT_RUNTIME_FLAG_ID,\n SCENE_OBJECT_SCHEMA_VERSION,\n type SceneObjectAttachment,\n type SceneObjectAttachmentPoint,\n type SceneObjectBounds,\n type SceneObjectManifest,\n type SceneObjectObjectState,\n type SceneObjectPoint,\n type SceneObjectReference,\n type SceneObjectResolutionRequest,\n type SceneObjectResolutionResult,\n type SceneObjectStateKind,\n type SceneObjectTransform,\n type SceneObjectValidationIssue,\n type SceneObjectValidationResult,\n type SceneObjectVector3,\n} from \"./types.js\";\nexport {\n createSceneObjectManifest,\n resolveSceneObjectById,\n resolveSceneObjectReferences,\n validateSceneObjectManifest,\n validateSceneObjectObjectState,\n} from \"./validation.js\";\nexport { resolveSceneObjectState } from \"./resolve.js\";\n","export const SCENE_OBJECT_SCHEMA_VERSION = \"1.0.0\";\nexport const SCENE_OBJECT_RUNTIME_FLAG_ID = \"scene.object.runtime.enabled\";\n\nexport type SceneObjectStateKind = \"idle\" | \"visible\" | \"hidden\" | \"disabled\";\n\nexport type SceneObjectCoordinateSpace =\n | \"normalized-viewport\"\n | \"pixel-viewport\"\n | \"world\"\n | \"local\";\n\nexport type SceneObjectUnits = \"ratio\" | \"pixels\";\n\nexport interface SceneObjectVector3 {\n x: number;\n y: number;\n z: number;\n}\n\nexport interface SceneObjectTransform {\n translate: SceneObjectVector3;\n rotate: SceneObjectVector3;\n scale: SceneObjectVector3;\n}\n\nexport interface SceneObjectBounds {\n rect: {\n x: number;\n y: number;\n width: number;\n height: number;\n unit: SceneObjectUnits;\n };\n depth?: number;\n coordinateSpace: SceneObjectCoordinateSpace;\n}\n\nexport interface SceneObjectPoint {\n id: string;\n x: number;\n y: number;\n z?: number;\n}\n\nexport interface SceneObjectAttachment {\n id: string;\n sourceObjectId: string;\n sourcePointId: string;\n targetObjectId: string;\n targetPointId: string;\n offset?: SceneObjectVector3;\n}\n\nexport type SceneObjectAttachmentPoint = SceneObjectPoint;\n\nexport interface SceneObjectObjectState {\n objectId: string;\n visible: boolean;\n tags?: string[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface SceneObjectReference {\n objectId: string;\n pointId: string;\n}\n\nexport interface SceneObjectManifest {\n schemaVersion: string;\n objects: SceneObjectDefinition[];\n stateSnapshots?: SceneObjectObjectState[];\n}\n\nexport interface SceneObjectDefinition {\n id: string;\n name?: string;\n transform: SceneObjectTransform;\n bounds: SceneObjectBounds;\n attachmentPoints?: SceneObjectPoint[];\n attachments?: SceneObjectAttachment[];\n}\n\nexport type SceneObjectValidationCode =\n | \"required\"\n | \"invalid-type\"\n | \"invalid-value\"\n | \"invalid-id\"\n | \"duplicate-id\"\n | \"invalid-reference\"\n | \"missing-reference\";\n\nexport interface SceneObjectValidationIssue {\n code: SceneObjectValidationCode;\n path: string;\n message: string;\n}\n\nexport interface SceneObjectValidationResult<T> {\n valid: boolean;\n issues: SceneObjectValidationIssue[];\n value?: T;\n}\n\nexport interface SceneObjectResolutionRequest {\n manifest: SceneObjectManifest;\n objectId: string;\n}\n\nexport interface SceneObjectResolutionResult {\n manifest: SceneObjectManifest;\n object: SceneObjectDefinition;\n}\n","import {\n SCENE_OBJECT_SCHEMA_VERSION,\n type SceneObjectBounds,\n type SceneObjectCoordinateSpace,\n type SceneObjectManifest,\n type SceneObjectObjectState,\n type SceneObjectPoint,\n type SceneObjectValidationIssue,\n type SceneObjectValidationResult,\n type SceneObjectDefinition,\n type SceneObjectAttachment,\n type SceneObjectResolutionRequest,\n type SceneObjectTransform,\n} from \"./types.js\";\n\nconst ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst COORDINATE_SPACES = new Set<SceneObjectCoordinateSpace>([\n \"normalized-viewport\",\n \"pixel-viewport\",\n \"world\",\n \"local\",\n]);\nconst UNITS = new Set([\"ratio\", \"pixels\"]);\n\nfunction pushIssue(\n issues: SceneObjectValidationIssue[],\n issue: SceneObjectValidationIssue,\n): void {\n issues.push(issue);\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value);\n}\n\nfunction validateKebabId(\n value: unknown,\n path: string,\n issues: SceneObjectValidationIssue[],\n): value is string {\n if (typeof value !== \"string\") {\n pushIssue(issues, {\n code: \"invalid-type\",\n path,\n message: \"Expected a string identifier.\",\n });\n return false;\n }\n\n if (!ID_PATTERN.test(value)) {\n pushIssue(issues, {\n code: \"invalid-id\",\n path,\n message: \"Identifiers must be kebab-case tokens.\",\n });\n return false;\n }\n\n return true;\n}\n\nfunction validateTransform(\n value: SceneObjectTransform,\n path: string,\n issues: SceneObjectValidationIssue[],\n): boolean {\n const vectorChecks = [\"translate\", \"rotate\", \"scale\"] as const;\n let valid = true;\n\n for (const field of vectorChecks) {\n const vector = value[field];\n if (!vector || typeof vector !== \"object\") {\n pushIssue(issues, {\n code: \"required\",\n path: `${path}.${field}`,\n message: `Expected a ${field} vector.`,\n });\n valid = false;\n continue;\n }\n\n for (const axis of [\"x\", \"y\", \"z\"] as const) {\n const raw = vector[axis];\n if (!isFiniteNumber(raw)) {\n pushIssue(issues, {\n code: \"invalid-type\",\n path: `${path}.${field}.${axis}`,\n message: `Vector ${axis} must be finite.`,\n });\n valid = false;\n }\n }\n }\n\n return valid;\n}\n\nfunction validatePoint(point: SceneObjectPoint, path: string, issues: SceneObjectValidationIssue[]): boolean {\n let valid = true;\n\n if (!validateKebabId(point.id, `${path}.id`, issues)) {\n valid = false;\n }\n\n for (const field of [\"x\", \"y\", \"z\"] as const) {\n const value = point[field];\n if (field === \"z\" && value === undefined) {\n continue;\n }\n if (!isFiniteNumber(value)) {\n pushIssue(issues, {\n code: \"invalid-type\",\n path: `${path}.${field}`,\n message: \"Attachment point axis must be finite.\",\n });\n valid = false;\n }\n }\n\n return valid;\n}\n\nfunction validateBounds(bounds: SceneObjectBounds, path: string, issues: SceneObjectValidationIssue[]): boolean {\n if (!bounds || typeof bounds !== \"object\") {\n pushIssue(issues, { code: \"required\", path, message: \"Expected bounds block.\" });\n return false;\n }\n\n if (!COORDINATE_SPACES.has(bounds.coordinateSpace as SceneObjectCoordinateSpace)) {\n pushIssue(issues, {\n code: \"invalid-value\",\n path: `${path}.coordinateSpace`,\n message: \"coordinateSpace must be normalized-viewport, pixel-viewport, world, or local.\",\n });\n return false;\n }\n\n const rect = bounds.rect;\n if (!rect || typeof rect !== \"object\") {\n pushIssue(issues, { code: \"required\", path: `${path}.rect`, message: \"Expected rect bounds.\" });\n return false;\n }\n\n if (!UNITS.has(rect.unit as string)) {\n pushIssue(issues, {\n code: \"invalid-value\",\n path: `${path}.rect.unit`,\n message: \"unit must be 'ratio' or 'pixels'.\",\n });\n return false;\n }\n\n let valid = true;\n for (const field of [\"x\", \"y\", \"width\", \"height\"] as const) {\n const value = rect[field];\n if (!isFiniteNumber(value) || value < 0) {\n pushIssue(issues, {\n code: \"invalid-type\",\n path: `${path}.rect.${field}`,\n message: \"Rect fields must be finite non-negative numbers.\",\n });\n valid = false;\n }\n }\n\n if (rect.width === 0 || rect.height === 0) {\n pushIssue(issues, {\n code: \"invalid-value\",\n path: `${path}.rect`,\n message: \"Rect width and height must be positive.\",\n });\n valid = false;\n }\n\n if (bounds.depth !== undefined && (!isFiniteNumber(bounds.depth) || bounds.depth < 0)) {\n pushIssue(issues, {\n code: \"invalid-type\",\n path: `${path}.depth`,\n message: \"depth must be a non-negative number.\",\n });\n valid = false;\n }\n\n return valid && isFiniteNumber(bounds.rect.width) && isFiniteNumber(bounds.rect.height);\n}\n\nfunction validateAttachmentTarget(\n attachment: {\n id: string;\n sourceObjectId: string;\n sourcePointId: string;\n targetObjectId: string;\n targetPointId: string;\n },\n path: string,\n issues: SceneObjectValidationIssue[],\n seenPoints: Map<string, Set<string>>,\n): boolean {\n let valid = true;\n if (!validateKebabId(attachment.id, `${path}.id`, issues)) {\n valid = false;\n }\n\n if (!validateKebabId(attachment.sourceObjectId, `${path}.sourceObjectId`, issues)) {\n valid = false;\n }\n\n if (!validateKebabId(attachment.targetObjectId, `${path}.targetObjectId`, issues)) {\n valid = false;\n }\n\n if (!validateKebabId(attachment.sourcePointId, `${path}.sourcePointId`, issues)) {\n valid = false;\n }\n\n if (!validateKebabId(attachment.targetPointId, `${path}.targetPointId`, issues)) {\n valid = false;\n }\n\n const sourcePoints = seenPoints.get(attachment.sourceObjectId);\n const targetPoints = seenPoints.get(attachment.targetObjectId);\n\n if (sourcePoints && !sourcePoints.has(attachment.sourcePointId)) {\n pushIssue(issues, {\n code: \"invalid-reference\",\n path: `${path}.sourcePointId`,\n message: \"sourcePointId does not exist on source object.\",\n });\n valid = false;\n }\n\n if (targetPoints && !targetPoints.has(attachment.targetPointId)) {\n pushIssue(issues, {\n code: \"invalid-reference\",\n path: `${path}.targetPointId`,\n message: \"targetPointId does not exist on target object.\",\n });\n valid = false;\n }\n\n return valid;\n}\n\nexport function validateSceneObjectManifest(\n manifest: unknown,\n): SceneObjectValidationResult<SceneObjectManifest> {\n const issues: SceneObjectValidationIssue[] = [];\n\n if (!manifest || typeof manifest !== \"object\") {\n return {\n valid: false,\n issues: [{ code: \"required\", path: \"$\", message: \"Expected a scene object manifest object.\" }],\n };\n }\n\n const value = manifest as Record<string, unknown>;\n let valid = true;\n\n if (value.schemaVersion !== SCENE_OBJECT_SCHEMA_VERSION) {\n pushIssue(issues, {\n code: \"invalid-value\",\n path: \"$.schemaVersion\",\n message: `schemaVersion must equal ${SCENE_OBJECT_SCHEMA_VERSION}.`,\n });\n valid = false;\n }\n\n if (!Array.isArray(value.objects) || value.objects.length === 0) {\n pushIssue(issues, {\n code: \"required\",\n path: \"$.objects\",\n message: \"Manifest must contain at least one object.\",\n });\n return { valid: false, issues };\n }\n\n const objects = value.objects as SceneObjectDefinition[];\n const seenObjects = new Set<string>();\n const pointsByObject = new Map<string, Set<string>>();\n\n for (const [index, object] of objects.entries()) {\n const path = `$.objects[${index}]`;\n\n if (!object || typeof object !== \"object\") {\n pushIssue(issues, { code: \"required\", path, message: \"Expected object definition.\" });\n valid = false;\n continue;\n }\n\n if (!validateKebabId(object.id, `${path}.id`, issues)) {\n valid = false;\n }\n\n if (seenObjects.has(object.id)) {\n pushIssue(issues, {\n code: \"duplicate-id\",\n path: `${path}.id`,\n message: `Duplicate object id '${object.id}' is not allowed.`,\n });\n valid = false;\n }\n seenObjects.add(object.id);\n\n if (!object.transform || typeof object.transform !== \"object\" || !validateTransform(object.transform as SceneObjectTransform, `${path}.transform`, issues)) {\n pushIssue(issues, {\n code: \"required\",\n path: `${path}.transform`,\n message: \"Object must define a transform.\",\n });\n valid = false;\n }\n\n if (!object.bounds) {\n pushIssue(issues, {\n code: \"required\",\n path: `${path}.bounds`,\n message: \"Object must define bounds.\",\n });\n valid = false;\n } else if (!validateBounds(object.bounds, `${path}.bounds`, issues)) {\n valid = false;\n }\n\n const attachmentPointIds = new Set<string>();\n const rawPoints = Array.isArray(object.attachmentPoints)\n ? object.attachmentPoints\n : [];\n for (const [pointIndex, point] of rawPoints.entries()) {\n if (!point || typeof point !== \"object\") {\n pushIssue(issues, {\n code: \"required\",\n path: `${path}.attachmentPoints[${pointIndex}]`,\n message: \"Expected attachment point definition.\",\n });\n valid = false;\n continue;\n }\n\n if (!validatePoint(point as SceneObjectPoint, `${path}.attachmentPoints[${pointIndex}]`, issues)) {\n valid = false;\n continue;\n }\n\n const pointId = (point as SceneObjectPoint).id;\n if (attachmentPointIds.has(pointId)) {\n pushIssue(issues, {\n code: \"duplicate-id\",\n path: `${path}.attachmentPoints[${pointIndex}].id`,\n message: `Duplicate attachment point '${pointId}' within object.`,\n });\n valid = false;\n }\n attachmentPointIds.add(pointId);\n }\n\n if (rawPoints.length > 0) {\n pointsByObject.set(object.id, attachmentPointIds);\n }\n\n if (Array.isArray(object.attachments)) {\n const attachmentIds = new Set<string>();\n for (const [attachmentIndex, attachment] of object.attachments.entries()) {\n if (!attachment || typeof attachment !== \"object\") {\n pushIssue(issues, {\n code: \"required\",\n path: `${path}.attachments[${attachmentIndex}]`,\n message: \"Expected attachment definition.\",\n });\n valid = false;\n continue;\n }\n\n if (!validateKebabId((attachment as SceneObjectAttachment).sourceObjectId, `${path}.attachments[${attachmentIndex}].sourceObjectId`, issues)) {\n valid = false;\n }\n\n if (!attachmentIds.has((attachment as { id?: string }).id ?? \"\")) {\n attachmentIds.add((attachment as { id?: string }).id ?? \"\");\n } else {\n pushIssue(issues, {\n code: \"duplicate-id\",\n path: `${path}.attachments[${attachmentIndex}].id`,\n message: \"Duplicate attachment id.\",\n });\n valid = false;\n }\n\n if (\n !validateAttachmentTarget(\n attachment as {\n id: string;\n sourceObjectId: string;\n sourcePointId: string;\n targetObjectId: string;\n targetPointId: string;\n },\n `${path}.attachments[${attachmentIndex}]`,\n issues,\n pointsByObject,\n )\n ) {\n valid = false;\n }\n }\n }\n }\n\n const objectIds = new Set(\n objects\n .filter((candidate): candidate is SceneObjectDefinition => Boolean(candidate && typeof candidate === \"object\"))\n .map((candidate) => candidate.id),\n );\n if (Array.isArray(value.stateSnapshots)) {\n for (const [stateIndex, state] of value.stateSnapshots.entries()) {\n const stateValue = state as SceneObjectObjectState;\n const path = `$.stateSnapshots[${stateIndex}]`;\n\n if (!stateValue || typeof stateValue !== \"object\") {\n pushIssue(issues, {\n code: \"required\",\n path,\n message: \"Expected object state definition.\",\n });\n valid = false;\n continue;\n }\n\n if (!validateKebabId(stateValue.objectId, `${path}.objectId`, issues)) {\n valid = false;\n }\n\n if (!objectIds.has(stateValue.objectId)) {\n pushIssue(issues, {\n code: \"missing-reference\",\n path: `${path}.objectId`,\n message: \"objectId does not reference an object in objects.\",\n });\n valid = false;\n }\n\n if (typeof stateValue.visible !== \"boolean\") {\n pushIssue(issues, {\n code: \"invalid-type\",\n path: `${path}.visible`,\n message: \"visible must be a boolean.\",\n });\n valid = false;\n }\n }\n }\n\n return valid\n ? { valid: true, issues, value: manifest as SceneObjectManifest }\n : { valid: false, issues };\n}\n\nexport function createSceneObjectManifest(manifest: SceneObjectManifest): SceneObjectManifest {\n const result = validateSceneObjectManifest(manifest);\n if (!result.valid || !result.value) {\n const summary = result.issues.map((issue) => `${issue.path}: ${issue.message}`).join(\"; \");\n throw new Error(`Invalid scene object manifest. ${summary}`);\n }\n\n return result.value;\n}\n\nexport function validateSceneObjectObjectState(state: unknown): SceneObjectValidationResult<SceneObjectObjectState> {\n if (!state || typeof state !== \"object\") {\n return {\n valid: false,\n issues: [{\n code: \"required\",\n path: \"$\",\n message: \"Expected an object state.\",\n }],\n };\n }\n\n const value = state as Record<string, unknown>;\n const issues: SceneObjectValidationIssue[] = [];\n let valid = true;\n\n if (!validateKebabId(value.objectId, \"$.objectId\", issues)) {\n valid = false;\n }\n\n if (typeof value.visible !== \"boolean\") {\n pushIssue(issues, {\n code: \"invalid-type\",\n path: \"$.visible\",\n message: \"visible must be a boolean.\",\n });\n valid = false;\n }\n\n return valid\n ? { valid: true, issues, value: state as SceneObjectObjectState }\n : { valid: false, issues };\n}\n\nexport function resolveSceneObjectReferences(\n manifest: SceneObjectManifest,\n): SceneObjectValidationResult<SceneObjectManifest> {\n const result = validateSceneObjectManifest(manifest);\n if (!result.valid || !result.value) {\n return { valid: false, issues: result.issues };\n }\n\n return { valid: true, issues: [], value: result.value };\n}\n\nexport function resolveSceneObjectById(\n requestOrManifest:\n | SceneObjectResolutionRequest\n | SceneObjectManifest,\n objectId?: string,\n): SceneObjectDefinition | undefined {\n const request: SceneObjectResolutionRequest = typeof objectId === \"string\"\n ? {\n manifest: requestOrManifest as SceneObjectManifest,\n objectId,\n }\n : requestOrManifest as SceneObjectResolutionRequest;\n\n const result = validateSceneObjectManifest(request.manifest);\n if (!result.valid || !result.value) {\n return undefined;\n }\n\n return result.value.objects.find((object) => object.id === request.objectId);\n}\n","import {\n SceneObjectManifest,\n SceneObjectObjectState,\n SceneObjectDefinition,\n} from \"./types.js\";\n\nexport function resolveSceneObjectState(\n manifest: SceneObjectManifest,\n objectId: string,\n): SceneObjectObjectState | undefined {\n if (!manifest.stateSnapshots || !Array.isArray(manifest.stateSnapshots)) {\n return undefined;\n }\n\n return manifest.stateSnapshots.find(\n (snapshot) => snapshot.objectId === objectId,\n );\n}\n\nexport function resolveSceneObjectById(\n manifest: SceneObjectManifest,\n objectId: string,\n): SceneObjectDefinition | undefined {\n return manifest.objects.find((object) => object.id === objectId);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
declare const SCENE_OBJECT_SCHEMA_VERSION = "1.0.0";
|
|
2
|
+
declare const SCENE_OBJECT_RUNTIME_FLAG_ID = "scene.object.runtime.enabled";
|
|
3
|
+
type SceneObjectStateKind = "idle" | "visible" | "hidden" | "disabled";
|
|
4
|
+
type SceneObjectCoordinateSpace = "normalized-viewport" | "pixel-viewport" | "world" | "local";
|
|
5
|
+
type SceneObjectUnits = "ratio" | "pixels";
|
|
6
|
+
interface SceneObjectVector3 {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
z: number;
|
|
10
|
+
}
|
|
11
|
+
interface SceneObjectTransform {
|
|
12
|
+
translate: SceneObjectVector3;
|
|
13
|
+
rotate: SceneObjectVector3;
|
|
14
|
+
scale: SceneObjectVector3;
|
|
15
|
+
}
|
|
16
|
+
interface SceneObjectBounds {
|
|
17
|
+
rect: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
unit: SceneObjectUnits;
|
|
23
|
+
};
|
|
24
|
+
depth?: number;
|
|
25
|
+
coordinateSpace: SceneObjectCoordinateSpace;
|
|
26
|
+
}
|
|
27
|
+
interface SceneObjectPoint {
|
|
28
|
+
id: string;
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
z?: number;
|
|
32
|
+
}
|
|
33
|
+
interface SceneObjectAttachment {
|
|
34
|
+
id: string;
|
|
35
|
+
sourceObjectId: string;
|
|
36
|
+
sourcePointId: string;
|
|
37
|
+
targetObjectId: string;
|
|
38
|
+
targetPointId: string;
|
|
39
|
+
offset?: SceneObjectVector3;
|
|
40
|
+
}
|
|
41
|
+
type SceneObjectAttachmentPoint = SceneObjectPoint;
|
|
42
|
+
interface SceneObjectObjectState {
|
|
43
|
+
objectId: string;
|
|
44
|
+
visible: boolean;
|
|
45
|
+
tags?: string[];
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
interface SceneObjectReference {
|
|
49
|
+
objectId: string;
|
|
50
|
+
pointId: string;
|
|
51
|
+
}
|
|
52
|
+
interface SceneObjectManifest {
|
|
53
|
+
schemaVersion: string;
|
|
54
|
+
objects: SceneObjectDefinition[];
|
|
55
|
+
stateSnapshots?: SceneObjectObjectState[];
|
|
56
|
+
}
|
|
57
|
+
interface SceneObjectDefinition {
|
|
58
|
+
id: string;
|
|
59
|
+
name?: string;
|
|
60
|
+
transform: SceneObjectTransform;
|
|
61
|
+
bounds: SceneObjectBounds;
|
|
62
|
+
attachmentPoints?: SceneObjectPoint[];
|
|
63
|
+
attachments?: SceneObjectAttachment[];
|
|
64
|
+
}
|
|
65
|
+
type SceneObjectValidationCode = "required" | "invalid-type" | "invalid-value" | "invalid-id" | "duplicate-id" | "invalid-reference" | "missing-reference";
|
|
66
|
+
interface SceneObjectValidationIssue {
|
|
67
|
+
code: SceneObjectValidationCode;
|
|
68
|
+
path: string;
|
|
69
|
+
message: string;
|
|
70
|
+
}
|
|
71
|
+
interface SceneObjectValidationResult<T> {
|
|
72
|
+
valid: boolean;
|
|
73
|
+
issues: SceneObjectValidationIssue[];
|
|
74
|
+
value?: T;
|
|
75
|
+
}
|
|
76
|
+
interface SceneObjectResolutionRequest {
|
|
77
|
+
manifest: SceneObjectManifest;
|
|
78
|
+
objectId: string;
|
|
79
|
+
}
|
|
80
|
+
interface SceneObjectResolutionResult {
|
|
81
|
+
manifest: SceneObjectManifest;
|
|
82
|
+
object: SceneObjectDefinition;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare function validateSceneObjectManifest(manifest: unknown): SceneObjectValidationResult<SceneObjectManifest>;
|
|
86
|
+
declare function createSceneObjectManifest(manifest: SceneObjectManifest): SceneObjectManifest;
|
|
87
|
+
declare function validateSceneObjectObjectState(state: unknown): SceneObjectValidationResult<SceneObjectObjectState>;
|
|
88
|
+
declare function resolveSceneObjectReferences(manifest: SceneObjectManifest): SceneObjectValidationResult<SceneObjectManifest>;
|
|
89
|
+
declare function resolveSceneObjectById(requestOrManifest: SceneObjectResolutionRequest | SceneObjectManifest, objectId?: string): SceneObjectDefinition | undefined;
|
|
90
|
+
|
|
91
|
+
declare function resolveSceneObjectState(manifest: SceneObjectManifest, objectId: string): SceneObjectObjectState | undefined;
|
|
92
|
+
|
|
93
|
+
export { SCENE_OBJECT_RUNTIME_FLAG_ID, SCENE_OBJECT_SCHEMA_VERSION, type SceneObjectAttachment, type SceneObjectAttachmentPoint, type SceneObjectBounds, type SceneObjectManifest, type SceneObjectObjectState, type SceneObjectPoint, type SceneObjectReference, type SceneObjectResolutionRequest, type SceneObjectResolutionResult, type SceneObjectStateKind, type SceneObjectTransform, type SceneObjectValidationIssue, type SceneObjectValidationResult, type SceneObjectVector3, createSceneObjectManifest, resolveSceneObjectById, resolveSceneObjectReferences, resolveSceneObjectState, validateSceneObjectManifest, validateSceneObjectObjectState };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
declare const SCENE_OBJECT_SCHEMA_VERSION = "1.0.0";
|
|
2
|
+
declare const SCENE_OBJECT_RUNTIME_FLAG_ID = "scene.object.runtime.enabled";
|
|
3
|
+
type SceneObjectStateKind = "idle" | "visible" | "hidden" | "disabled";
|
|
4
|
+
type SceneObjectCoordinateSpace = "normalized-viewport" | "pixel-viewport" | "world" | "local";
|
|
5
|
+
type SceneObjectUnits = "ratio" | "pixels";
|
|
6
|
+
interface SceneObjectVector3 {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
z: number;
|
|
10
|
+
}
|
|
11
|
+
interface SceneObjectTransform {
|
|
12
|
+
translate: SceneObjectVector3;
|
|
13
|
+
rotate: SceneObjectVector3;
|
|
14
|
+
scale: SceneObjectVector3;
|
|
15
|
+
}
|
|
16
|
+
interface SceneObjectBounds {
|
|
17
|
+
rect: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
unit: SceneObjectUnits;
|
|
23
|
+
};
|
|
24
|
+
depth?: number;
|
|
25
|
+
coordinateSpace: SceneObjectCoordinateSpace;
|
|
26
|
+
}
|
|
27
|
+
interface SceneObjectPoint {
|
|
28
|
+
id: string;
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
z?: number;
|
|
32
|
+
}
|
|
33
|
+
interface SceneObjectAttachment {
|
|
34
|
+
id: string;
|
|
35
|
+
sourceObjectId: string;
|
|
36
|
+
sourcePointId: string;
|
|
37
|
+
targetObjectId: string;
|
|
38
|
+
targetPointId: string;
|
|
39
|
+
offset?: SceneObjectVector3;
|
|
40
|
+
}
|
|
41
|
+
type SceneObjectAttachmentPoint = SceneObjectPoint;
|
|
42
|
+
interface SceneObjectObjectState {
|
|
43
|
+
objectId: string;
|
|
44
|
+
visible: boolean;
|
|
45
|
+
tags?: string[];
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
interface SceneObjectReference {
|
|
49
|
+
objectId: string;
|
|
50
|
+
pointId: string;
|
|
51
|
+
}
|
|
52
|
+
interface SceneObjectManifest {
|
|
53
|
+
schemaVersion: string;
|
|
54
|
+
objects: SceneObjectDefinition[];
|
|
55
|
+
stateSnapshots?: SceneObjectObjectState[];
|
|
56
|
+
}
|
|
57
|
+
interface SceneObjectDefinition {
|
|
58
|
+
id: string;
|
|
59
|
+
name?: string;
|
|
60
|
+
transform: SceneObjectTransform;
|
|
61
|
+
bounds: SceneObjectBounds;
|
|
62
|
+
attachmentPoints?: SceneObjectPoint[];
|
|
63
|
+
attachments?: SceneObjectAttachment[];
|
|
64
|
+
}
|
|
65
|
+
type SceneObjectValidationCode = "required" | "invalid-type" | "invalid-value" | "invalid-id" | "duplicate-id" | "invalid-reference" | "missing-reference";
|
|
66
|
+
interface SceneObjectValidationIssue {
|
|
67
|
+
code: SceneObjectValidationCode;
|
|
68
|
+
path: string;
|
|
69
|
+
message: string;
|
|
70
|
+
}
|
|
71
|
+
interface SceneObjectValidationResult<T> {
|
|
72
|
+
valid: boolean;
|
|
73
|
+
issues: SceneObjectValidationIssue[];
|
|
74
|
+
value?: T;
|
|
75
|
+
}
|
|
76
|
+
interface SceneObjectResolutionRequest {
|
|
77
|
+
manifest: SceneObjectManifest;
|
|
78
|
+
objectId: string;
|
|
79
|
+
}
|
|
80
|
+
interface SceneObjectResolutionResult {
|
|
81
|
+
manifest: SceneObjectManifest;
|
|
82
|
+
object: SceneObjectDefinition;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare function validateSceneObjectManifest(manifest: unknown): SceneObjectValidationResult<SceneObjectManifest>;
|
|
86
|
+
declare function createSceneObjectManifest(manifest: SceneObjectManifest): SceneObjectManifest;
|
|
87
|
+
declare function validateSceneObjectObjectState(state: unknown): SceneObjectValidationResult<SceneObjectObjectState>;
|
|
88
|
+
declare function resolveSceneObjectReferences(manifest: SceneObjectManifest): SceneObjectValidationResult<SceneObjectManifest>;
|
|
89
|
+
declare function resolveSceneObjectById(requestOrManifest: SceneObjectResolutionRequest | SceneObjectManifest, objectId?: string): SceneObjectDefinition | undefined;
|
|
90
|
+
|
|
91
|
+
declare function resolveSceneObjectState(manifest: SceneObjectManifest, objectId: string): SceneObjectObjectState | undefined;
|
|
92
|
+
|
|
93
|
+
export { SCENE_OBJECT_RUNTIME_FLAG_ID, SCENE_OBJECT_SCHEMA_VERSION, type SceneObjectAttachment, type SceneObjectAttachmentPoint, type SceneObjectBounds, type SceneObjectManifest, type SceneObjectObjectState, type SceneObjectPoint, type SceneObjectReference, type SceneObjectResolutionRequest, type SceneObjectResolutionResult, type SceneObjectStateKind, type SceneObjectTransform, type SceneObjectValidationIssue, type SceneObjectValidationResult, type SceneObjectVector3, createSceneObjectManifest, resolveSceneObjectById, resolveSceneObjectReferences, resolveSceneObjectState, validateSceneObjectManifest, validateSceneObjectObjectState };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var SCENE_OBJECT_SCHEMA_VERSION = "1.0.0";
|
|
3
|
+
var SCENE_OBJECT_RUNTIME_FLAG_ID = "scene.object.runtime.enabled";
|
|
4
|
+
|
|
5
|
+
// src/validation.ts
|
|
6
|
+
var ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
7
|
+
var COORDINATE_SPACES = /* @__PURE__ */ new Set([
|
|
8
|
+
"normalized-viewport",
|
|
9
|
+
"pixel-viewport",
|
|
10
|
+
"world",
|
|
11
|
+
"local"
|
|
12
|
+
]);
|
|
13
|
+
var UNITS = /* @__PURE__ */ new Set(["ratio", "pixels"]);
|
|
14
|
+
function pushIssue(issues, issue) {
|
|
15
|
+
issues.push(issue);
|
|
16
|
+
}
|
|
17
|
+
function isFiniteNumber(value) {
|
|
18
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
19
|
+
}
|
|
20
|
+
function validateKebabId(value, path, issues) {
|
|
21
|
+
if (typeof value !== "string") {
|
|
22
|
+
pushIssue(issues, {
|
|
23
|
+
code: "invalid-type",
|
|
24
|
+
path,
|
|
25
|
+
message: "Expected a string identifier."
|
|
26
|
+
});
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
if (!ID_PATTERN.test(value)) {
|
|
30
|
+
pushIssue(issues, {
|
|
31
|
+
code: "invalid-id",
|
|
32
|
+
path,
|
|
33
|
+
message: "Identifiers must be kebab-case tokens."
|
|
34
|
+
});
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
function validateTransform(value, path, issues) {
|
|
40
|
+
const vectorChecks = ["translate", "rotate", "scale"];
|
|
41
|
+
let valid = true;
|
|
42
|
+
for (const field of vectorChecks) {
|
|
43
|
+
const vector = value[field];
|
|
44
|
+
if (!vector || typeof vector !== "object") {
|
|
45
|
+
pushIssue(issues, {
|
|
46
|
+
code: "required",
|
|
47
|
+
path: `${path}.${field}`,
|
|
48
|
+
message: `Expected a ${field} vector.`
|
|
49
|
+
});
|
|
50
|
+
valid = false;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
for (const axis of ["x", "y", "z"]) {
|
|
54
|
+
const raw = vector[axis];
|
|
55
|
+
if (!isFiniteNumber(raw)) {
|
|
56
|
+
pushIssue(issues, {
|
|
57
|
+
code: "invalid-type",
|
|
58
|
+
path: `${path}.${field}.${axis}`,
|
|
59
|
+
message: `Vector ${axis} must be finite.`
|
|
60
|
+
});
|
|
61
|
+
valid = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return valid;
|
|
66
|
+
}
|
|
67
|
+
function validatePoint(point, path, issues) {
|
|
68
|
+
let valid = true;
|
|
69
|
+
if (!validateKebabId(point.id, `${path}.id`, issues)) {
|
|
70
|
+
valid = false;
|
|
71
|
+
}
|
|
72
|
+
for (const field of ["x", "y", "z"]) {
|
|
73
|
+
const value = point[field];
|
|
74
|
+
if (field === "z" && value === void 0) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (!isFiniteNumber(value)) {
|
|
78
|
+
pushIssue(issues, {
|
|
79
|
+
code: "invalid-type",
|
|
80
|
+
path: `${path}.${field}`,
|
|
81
|
+
message: "Attachment point axis must be finite."
|
|
82
|
+
});
|
|
83
|
+
valid = false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return valid;
|
|
87
|
+
}
|
|
88
|
+
function validateBounds(bounds, path, issues) {
|
|
89
|
+
if (!bounds || typeof bounds !== "object") {
|
|
90
|
+
pushIssue(issues, { code: "required", path, message: "Expected bounds block." });
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
if (!COORDINATE_SPACES.has(bounds.coordinateSpace)) {
|
|
94
|
+
pushIssue(issues, {
|
|
95
|
+
code: "invalid-value",
|
|
96
|
+
path: `${path}.coordinateSpace`,
|
|
97
|
+
message: "coordinateSpace must be normalized-viewport, pixel-viewport, world, or local."
|
|
98
|
+
});
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
const rect = bounds.rect;
|
|
102
|
+
if (!rect || typeof rect !== "object") {
|
|
103
|
+
pushIssue(issues, { code: "required", path: `${path}.rect`, message: "Expected rect bounds." });
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if (!UNITS.has(rect.unit)) {
|
|
107
|
+
pushIssue(issues, {
|
|
108
|
+
code: "invalid-value",
|
|
109
|
+
path: `${path}.rect.unit`,
|
|
110
|
+
message: "unit must be 'ratio' or 'pixels'."
|
|
111
|
+
});
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
let valid = true;
|
|
115
|
+
for (const field of ["x", "y", "width", "height"]) {
|
|
116
|
+
const value = rect[field];
|
|
117
|
+
if (!isFiniteNumber(value) || value < 0) {
|
|
118
|
+
pushIssue(issues, {
|
|
119
|
+
code: "invalid-type",
|
|
120
|
+
path: `${path}.rect.${field}`,
|
|
121
|
+
message: "Rect fields must be finite non-negative numbers."
|
|
122
|
+
});
|
|
123
|
+
valid = false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (rect.width === 0 || rect.height === 0) {
|
|
127
|
+
pushIssue(issues, {
|
|
128
|
+
code: "invalid-value",
|
|
129
|
+
path: `${path}.rect`,
|
|
130
|
+
message: "Rect width and height must be positive."
|
|
131
|
+
});
|
|
132
|
+
valid = false;
|
|
133
|
+
}
|
|
134
|
+
if (bounds.depth !== void 0 && (!isFiniteNumber(bounds.depth) || bounds.depth < 0)) {
|
|
135
|
+
pushIssue(issues, {
|
|
136
|
+
code: "invalid-type",
|
|
137
|
+
path: `${path}.depth`,
|
|
138
|
+
message: "depth must be a non-negative number."
|
|
139
|
+
});
|
|
140
|
+
valid = false;
|
|
141
|
+
}
|
|
142
|
+
return valid && isFiniteNumber(bounds.rect.width) && isFiniteNumber(bounds.rect.height);
|
|
143
|
+
}
|
|
144
|
+
function validateAttachmentTarget(attachment, path, issues, seenPoints) {
|
|
145
|
+
let valid = true;
|
|
146
|
+
if (!validateKebabId(attachment.id, `${path}.id`, issues)) {
|
|
147
|
+
valid = false;
|
|
148
|
+
}
|
|
149
|
+
if (!validateKebabId(attachment.sourceObjectId, `${path}.sourceObjectId`, issues)) {
|
|
150
|
+
valid = false;
|
|
151
|
+
}
|
|
152
|
+
if (!validateKebabId(attachment.targetObjectId, `${path}.targetObjectId`, issues)) {
|
|
153
|
+
valid = false;
|
|
154
|
+
}
|
|
155
|
+
if (!validateKebabId(attachment.sourcePointId, `${path}.sourcePointId`, issues)) {
|
|
156
|
+
valid = false;
|
|
157
|
+
}
|
|
158
|
+
if (!validateKebabId(attachment.targetPointId, `${path}.targetPointId`, issues)) {
|
|
159
|
+
valid = false;
|
|
160
|
+
}
|
|
161
|
+
const sourcePoints = seenPoints.get(attachment.sourceObjectId);
|
|
162
|
+
const targetPoints = seenPoints.get(attachment.targetObjectId);
|
|
163
|
+
if (sourcePoints && !sourcePoints.has(attachment.sourcePointId)) {
|
|
164
|
+
pushIssue(issues, {
|
|
165
|
+
code: "invalid-reference",
|
|
166
|
+
path: `${path}.sourcePointId`,
|
|
167
|
+
message: "sourcePointId does not exist on source object."
|
|
168
|
+
});
|
|
169
|
+
valid = false;
|
|
170
|
+
}
|
|
171
|
+
if (targetPoints && !targetPoints.has(attachment.targetPointId)) {
|
|
172
|
+
pushIssue(issues, {
|
|
173
|
+
code: "invalid-reference",
|
|
174
|
+
path: `${path}.targetPointId`,
|
|
175
|
+
message: "targetPointId does not exist on target object."
|
|
176
|
+
});
|
|
177
|
+
valid = false;
|
|
178
|
+
}
|
|
179
|
+
return valid;
|
|
180
|
+
}
|
|
181
|
+
function validateSceneObjectManifest(manifest) {
|
|
182
|
+
const issues = [];
|
|
183
|
+
if (!manifest || typeof manifest !== "object") {
|
|
184
|
+
return {
|
|
185
|
+
valid: false,
|
|
186
|
+
issues: [{ code: "required", path: "$", message: "Expected a scene object manifest object." }]
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const value = manifest;
|
|
190
|
+
let valid = true;
|
|
191
|
+
if (value.schemaVersion !== SCENE_OBJECT_SCHEMA_VERSION) {
|
|
192
|
+
pushIssue(issues, {
|
|
193
|
+
code: "invalid-value",
|
|
194
|
+
path: "$.schemaVersion",
|
|
195
|
+
message: `schemaVersion must equal ${SCENE_OBJECT_SCHEMA_VERSION}.`
|
|
196
|
+
});
|
|
197
|
+
valid = false;
|
|
198
|
+
}
|
|
199
|
+
if (!Array.isArray(value.objects) || value.objects.length === 0) {
|
|
200
|
+
pushIssue(issues, {
|
|
201
|
+
code: "required",
|
|
202
|
+
path: "$.objects",
|
|
203
|
+
message: "Manifest must contain at least one object."
|
|
204
|
+
});
|
|
205
|
+
return { valid: false, issues };
|
|
206
|
+
}
|
|
207
|
+
const objects = value.objects;
|
|
208
|
+
const seenObjects = /* @__PURE__ */ new Set();
|
|
209
|
+
const pointsByObject = /* @__PURE__ */ new Map();
|
|
210
|
+
for (const [index, object] of objects.entries()) {
|
|
211
|
+
const path = `$.objects[${index}]`;
|
|
212
|
+
if (!object || typeof object !== "object") {
|
|
213
|
+
pushIssue(issues, { code: "required", path, message: "Expected object definition." });
|
|
214
|
+
valid = false;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (!validateKebabId(object.id, `${path}.id`, issues)) {
|
|
218
|
+
valid = false;
|
|
219
|
+
}
|
|
220
|
+
if (seenObjects.has(object.id)) {
|
|
221
|
+
pushIssue(issues, {
|
|
222
|
+
code: "duplicate-id",
|
|
223
|
+
path: `${path}.id`,
|
|
224
|
+
message: `Duplicate object id '${object.id}' is not allowed.`
|
|
225
|
+
});
|
|
226
|
+
valid = false;
|
|
227
|
+
}
|
|
228
|
+
seenObjects.add(object.id);
|
|
229
|
+
if (!object.transform || typeof object.transform !== "object" || !validateTransform(object.transform, `${path}.transform`, issues)) {
|
|
230
|
+
pushIssue(issues, {
|
|
231
|
+
code: "required",
|
|
232
|
+
path: `${path}.transform`,
|
|
233
|
+
message: "Object must define a transform."
|
|
234
|
+
});
|
|
235
|
+
valid = false;
|
|
236
|
+
}
|
|
237
|
+
if (!object.bounds) {
|
|
238
|
+
pushIssue(issues, {
|
|
239
|
+
code: "required",
|
|
240
|
+
path: `${path}.bounds`,
|
|
241
|
+
message: "Object must define bounds."
|
|
242
|
+
});
|
|
243
|
+
valid = false;
|
|
244
|
+
} else if (!validateBounds(object.bounds, `${path}.bounds`, issues)) {
|
|
245
|
+
valid = false;
|
|
246
|
+
}
|
|
247
|
+
const attachmentPointIds = /* @__PURE__ */ new Set();
|
|
248
|
+
const rawPoints = Array.isArray(object.attachmentPoints) ? object.attachmentPoints : [];
|
|
249
|
+
for (const [pointIndex, point] of rawPoints.entries()) {
|
|
250
|
+
if (!point || typeof point !== "object") {
|
|
251
|
+
pushIssue(issues, {
|
|
252
|
+
code: "required",
|
|
253
|
+
path: `${path}.attachmentPoints[${pointIndex}]`,
|
|
254
|
+
message: "Expected attachment point definition."
|
|
255
|
+
});
|
|
256
|
+
valid = false;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (!validatePoint(point, `${path}.attachmentPoints[${pointIndex}]`, issues)) {
|
|
260
|
+
valid = false;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
const pointId = point.id;
|
|
264
|
+
if (attachmentPointIds.has(pointId)) {
|
|
265
|
+
pushIssue(issues, {
|
|
266
|
+
code: "duplicate-id",
|
|
267
|
+
path: `${path}.attachmentPoints[${pointIndex}].id`,
|
|
268
|
+
message: `Duplicate attachment point '${pointId}' within object.`
|
|
269
|
+
});
|
|
270
|
+
valid = false;
|
|
271
|
+
}
|
|
272
|
+
attachmentPointIds.add(pointId);
|
|
273
|
+
}
|
|
274
|
+
if (rawPoints.length > 0) {
|
|
275
|
+
pointsByObject.set(object.id, attachmentPointIds);
|
|
276
|
+
}
|
|
277
|
+
if (Array.isArray(object.attachments)) {
|
|
278
|
+
const attachmentIds = /* @__PURE__ */ new Set();
|
|
279
|
+
for (const [attachmentIndex, attachment] of object.attachments.entries()) {
|
|
280
|
+
if (!attachment || typeof attachment !== "object") {
|
|
281
|
+
pushIssue(issues, {
|
|
282
|
+
code: "required",
|
|
283
|
+
path: `${path}.attachments[${attachmentIndex}]`,
|
|
284
|
+
message: "Expected attachment definition."
|
|
285
|
+
});
|
|
286
|
+
valid = false;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (!validateKebabId(attachment.sourceObjectId, `${path}.attachments[${attachmentIndex}].sourceObjectId`, issues)) {
|
|
290
|
+
valid = false;
|
|
291
|
+
}
|
|
292
|
+
if (!attachmentIds.has(attachment.id ?? "")) {
|
|
293
|
+
attachmentIds.add(attachment.id ?? "");
|
|
294
|
+
} else {
|
|
295
|
+
pushIssue(issues, {
|
|
296
|
+
code: "duplicate-id",
|
|
297
|
+
path: `${path}.attachments[${attachmentIndex}].id`,
|
|
298
|
+
message: "Duplicate attachment id."
|
|
299
|
+
});
|
|
300
|
+
valid = false;
|
|
301
|
+
}
|
|
302
|
+
if (!validateAttachmentTarget(
|
|
303
|
+
attachment,
|
|
304
|
+
`${path}.attachments[${attachmentIndex}]`,
|
|
305
|
+
issues,
|
|
306
|
+
pointsByObject
|
|
307
|
+
)) {
|
|
308
|
+
valid = false;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const objectIds = new Set(
|
|
314
|
+
objects.filter((candidate) => Boolean(candidate && typeof candidate === "object")).map((candidate) => candidate.id)
|
|
315
|
+
);
|
|
316
|
+
if (Array.isArray(value.stateSnapshots)) {
|
|
317
|
+
for (const [stateIndex, state] of value.stateSnapshots.entries()) {
|
|
318
|
+
const stateValue = state;
|
|
319
|
+
const path = `$.stateSnapshots[${stateIndex}]`;
|
|
320
|
+
if (!stateValue || typeof stateValue !== "object") {
|
|
321
|
+
pushIssue(issues, {
|
|
322
|
+
code: "required",
|
|
323
|
+
path,
|
|
324
|
+
message: "Expected object state definition."
|
|
325
|
+
});
|
|
326
|
+
valid = false;
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (!validateKebabId(stateValue.objectId, `${path}.objectId`, issues)) {
|
|
330
|
+
valid = false;
|
|
331
|
+
}
|
|
332
|
+
if (!objectIds.has(stateValue.objectId)) {
|
|
333
|
+
pushIssue(issues, {
|
|
334
|
+
code: "missing-reference",
|
|
335
|
+
path: `${path}.objectId`,
|
|
336
|
+
message: "objectId does not reference an object in objects."
|
|
337
|
+
});
|
|
338
|
+
valid = false;
|
|
339
|
+
}
|
|
340
|
+
if (typeof stateValue.visible !== "boolean") {
|
|
341
|
+
pushIssue(issues, {
|
|
342
|
+
code: "invalid-type",
|
|
343
|
+
path: `${path}.visible`,
|
|
344
|
+
message: "visible must be a boolean."
|
|
345
|
+
});
|
|
346
|
+
valid = false;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return valid ? { valid: true, issues, value: manifest } : { valid: false, issues };
|
|
351
|
+
}
|
|
352
|
+
function createSceneObjectManifest(manifest) {
|
|
353
|
+
const result = validateSceneObjectManifest(manifest);
|
|
354
|
+
if (!result.valid || !result.value) {
|
|
355
|
+
const summary = result.issues.map((issue) => `${issue.path}: ${issue.message}`).join("; ");
|
|
356
|
+
throw new Error(`Invalid scene object manifest. ${summary}`);
|
|
357
|
+
}
|
|
358
|
+
return result.value;
|
|
359
|
+
}
|
|
360
|
+
function validateSceneObjectObjectState(state) {
|
|
361
|
+
if (!state || typeof state !== "object") {
|
|
362
|
+
return {
|
|
363
|
+
valid: false,
|
|
364
|
+
issues: [{
|
|
365
|
+
code: "required",
|
|
366
|
+
path: "$",
|
|
367
|
+
message: "Expected an object state."
|
|
368
|
+
}]
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
const value = state;
|
|
372
|
+
const issues = [];
|
|
373
|
+
let valid = true;
|
|
374
|
+
if (!validateKebabId(value.objectId, "$.objectId", issues)) {
|
|
375
|
+
valid = false;
|
|
376
|
+
}
|
|
377
|
+
if (typeof value.visible !== "boolean") {
|
|
378
|
+
pushIssue(issues, {
|
|
379
|
+
code: "invalid-type",
|
|
380
|
+
path: "$.visible",
|
|
381
|
+
message: "visible must be a boolean."
|
|
382
|
+
});
|
|
383
|
+
valid = false;
|
|
384
|
+
}
|
|
385
|
+
return valid ? { valid: true, issues, value: state } : { valid: false, issues };
|
|
386
|
+
}
|
|
387
|
+
function resolveSceneObjectReferences(manifest) {
|
|
388
|
+
const result = validateSceneObjectManifest(manifest);
|
|
389
|
+
if (!result.valid || !result.value) {
|
|
390
|
+
return { valid: false, issues: result.issues };
|
|
391
|
+
}
|
|
392
|
+
return { valid: true, issues: [], value: result.value };
|
|
393
|
+
}
|
|
394
|
+
function resolveSceneObjectById(requestOrManifest, objectId) {
|
|
395
|
+
const request = typeof objectId === "string" ? {
|
|
396
|
+
manifest: requestOrManifest,
|
|
397
|
+
objectId
|
|
398
|
+
} : requestOrManifest;
|
|
399
|
+
const result = validateSceneObjectManifest(request.manifest);
|
|
400
|
+
if (!result.valid || !result.value) {
|
|
401
|
+
return void 0;
|
|
402
|
+
}
|
|
403
|
+
return result.value.objects.find((object) => object.id === request.objectId);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// src/resolve.ts
|
|
407
|
+
function resolveSceneObjectState(manifest, objectId) {
|
|
408
|
+
if (!manifest.stateSnapshots || !Array.isArray(manifest.stateSnapshots)) {
|
|
409
|
+
return void 0;
|
|
410
|
+
}
|
|
411
|
+
return manifest.stateSnapshots.find(
|
|
412
|
+
(snapshot) => snapshot.objectId === objectId
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
export {
|
|
416
|
+
SCENE_OBJECT_RUNTIME_FLAG_ID,
|
|
417
|
+
SCENE_OBJECT_SCHEMA_VERSION,
|
|
418
|
+
createSceneObjectManifest,
|
|
419
|
+
resolveSceneObjectById,
|
|
420
|
+
resolveSceneObjectReferences,
|
|
421
|
+
resolveSceneObjectState,
|
|
422
|
+
validateSceneObjectManifest,
|
|
423
|
+
validateSceneObjectObjectState
|
|
424
|
+
};
|
|
425
|
+
//# sourceMappingURL=index.js.map
|