@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/types.ts","../src/validation.ts","../src/resolve.ts"],"sourcesContent":["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/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plasius/scene-object",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Reusable scene-object transforms, bounds, attachment points, and snapshot contracts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"audit:eslint": "eslint . --max-warnings=0",
|
|
27
|
+
"audit:deps": "npm ls --all --omit=optional --omit=peer > /dev/null 2>&1 || true",
|
|
28
|
+
"audit:npm": "npm audit --audit-level=high --omit=dev",
|
|
29
|
+
"audit:test": "vitest run --coverage",
|
|
30
|
+
"lint": "eslint . --max-warnings=0",
|
|
31
|
+
"prepare": "npm run build",
|
|
32
|
+
"clean": "rimraf dist",
|
|
33
|
+
"test:coverage": "vitest run --coverage",
|
|
34
|
+
"pack:check": "node scripts/verify-public-package.cjs"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"scene-object",
|
|
38
|
+
"scene",
|
|
39
|
+
"object",
|
|
40
|
+
"transform",
|
|
41
|
+
"bounds",
|
|
42
|
+
"attachments",
|
|
43
|
+
"runtime-contracts",
|
|
44
|
+
"typescript",
|
|
45
|
+
"plasius",
|
|
46
|
+
"validation",
|
|
47
|
+
"portable"
|
|
48
|
+
],
|
|
49
|
+
"author": "Plasius LTD <development@plasius.co.uk>",
|
|
50
|
+
"license": "Apache-2.0",
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/Plasius-LTD/scene-object.git"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/Plasius-LTD/scene-object/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/Plasius-LTD/scene-object#readme",
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/js": "^10.0.1",
|
|
61
|
+
"@types/node": "^25.7.0",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
63
|
+
"@typescript-eslint/parser": "^8.59.3",
|
|
64
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
65
|
+
"eslint": "^10.3.0",
|
|
66
|
+
"globals": "^17.6.0",
|
|
67
|
+
"tsup": "^8.5.1",
|
|
68
|
+
"tsx": "^4.21.0",
|
|
69
|
+
"typescript": "^6.0.3",
|
|
70
|
+
"vitest": "^4.1.6"
|
|
71
|
+
},
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public"
|
|
74
|
+
},
|
|
75
|
+
"funding": [
|
|
76
|
+
{
|
|
77
|
+
"type": "patreon",
|
|
78
|
+
"url": "https://www.patreon.com/c/plasiusltd/membership"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "github",
|
|
82
|
+
"url": "https://github.com/sponsors/Plasius-LTD"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"overrides": {
|
|
86
|
+
"minimatch": "^10.2.1"
|
|
87
|
+
},
|
|
88
|
+
"engines": {
|
|
89
|
+
"node": ">=24"
|
|
90
|
+
}
|
|
91
|
+
}
|