worldorbit 2.6.0 → 3.0.1
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/README.md +20 -9
- package/dist/browser/core/dist/atlas-edit.d.ts +11 -0
- package/dist/browser/core/dist/atlas-edit.js +347 -0
- package/dist/browser/core/dist/atlas-utils.d.ts +22 -0
- package/dist/browser/core/dist/atlas-utils.js +189 -0
- package/dist/browser/core/dist/atlas-validate.d.ts +2 -0
- package/dist/browser/core/dist/atlas-validate.js +488 -0
- package/dist/browser/core/dist/diagnostics.d.ts +10 -0
- package/dist/browser/core/dist/diagnostics.js +109 -0
- package/dist/browser/core/dist/draft-parse.d.ts +3 -0
- package/dist/browser/core/dist/draft-parse.js +1654 -0
- package/dist/browser/core/dist/draft.d.ts +21 -0
- package/dist/browser/core/dist/draft.js +482 -0
- package/dist/browser/core/dist/errors.d.ts +7 -0
- package/dist/browser/core/dist/errors.js +16 -0
- package/dist/browser/core/dist/format.d.ts +4 -0
- package/dist/browser/core/dist/format.js +613 -0
- package/dist/browser/core/dist/index.d.ts +29 -0
- package/dist/browser/core/dist/index.js +35 -6542
- package/dist/browser/core/dist/load.d.ts +4 -0
- package/dist/browser/core/dist/load.js +182 -0
- package/dist/browser/core/dist/markdown.d.ts +2 -0
- package/dist/browser/core/dist/markdown.js +37 -0
- package/dist/browser/core/dist/normalize.d.ts +2 -0
- package/dist/browser/core/dist/normalize.js +312 -0
- package/dist/browser/core/dist/parse.d.ts +2 -0
- package/dist/browser/core/dist/parse.js +133 -0
- package/dist/browser/core/dist/scene.d.ts +3 -0
- package/dist/browser/core/dist/scene.js +1901 -0
- package/dist/browser/core/dist/schema.d.ts +8 -0
- package/dist/browser/core/dist/schema.js +298 -0
- package/dist/browser/core/dist/spatial-scene.d.ts +3 -0
- package/dist/browser/core/dist/spatial-scene.js +420 -0
- package/dist/browser/core/dist/tokenize.d.ts +4 -0
- package/dist/browser/core/dist/tokenize.js +68 -0
- package/dist/browser/core/dist/types.d.ts +637 -0
- package/dist/browser/core/dist/types.js +1 -0
- package/dist/browser/core/dist/validate.d.ts +2 -0
- package/dist/browser/core/dist/validate.js +56 -0
- package/dist/browser/editor/dist/editor.d.ts +2 -0
- package/dist/browser/editor/dist/editor.js +3700 -0
- package/dist/browser/editor/dist/index.d.ts +2 -0
- package/dist/browser/editor/dist/index.js +1 -12250
- package/dist/browser/editor/dist/types.d.ts +59 -0
- package/dist/browser/editor/dist/types.js +1 -0
- package/dist/browser/markdown/dist/html.d.ts +3 -0
- package/dist/browser/markdown/dist/html.js +64 -0
- package/dist/browser/markdown/dist/index.d.ts +4 -0
- package/dist/browser/markdown/dist/index.js +3 -6179
- package/dist/browser/markdown/dist/rehype.d.ts +10 -0
- package/dist/browser/markdown/dist/rehype.js +49 -0
- package/dist/browser/markdown/dist/remark.d.ts +9 -0
- package/dist/browser/markdown/dist/remark.js +28 -0
- package/dist/browser/markdown/dist/types.d.ts +11 -0
- package/dist/browser/markdown/dist/types.js +1 -0
- package/dist/browser/viewer/dist/atlas-state.d.ts +12 -0
- package/dist/browser/viewer/dist/atlas-state.js +269 -0
- package/dist/browser/viewer/dist/atlas-viewer.d.ts +2 -0
- package/dist/browser/viewer/dist/atlas-viewer.js +495 -0
- package/dist/browser/viewer/dist/custom-element.d.ts +1 -0
- package/dist/browser/viewer/dist/custom-element.js +78 -0
- package/dist/browser/viewer/dist/embed.d.ts +24 -0
- package/dist/browser/viewer/dist/embed.js +172 -0
- package/dist/browser/viewer/dist/errors.d.ts +6 -0
- package/dist/browser/viewer/dist/errors.js +12 -0
- package/dist/browser/viewer/dist/index.d.ts +10 -0
- package/dist/browser/viewer/dist/index.js +9 -8334
- package/dist/browser/viewer/dist/minimap.d.ts +3 -0
- package/dist/browser/viewer/dist/minimap.js +63 -0
- package/dist/browser/viewer/dist/render.d.ts +6 -0
- package/dist/browser/viewer/dist/render.js +670 -0
- package/dist/browser/viewer/dist/runtime-3d.d.ts +19 -0
- package/dist/browser/viewer/dist/runtime-3d.js +494 -0
- package/dist/browser/viewer/dist/theme.d.ts +4 -0
- package/dist/browser/viewer/dist/theme.js +103 -0
- package/dist/browser/viewer/dist/tooltip.d.ts +3 -0
- package/dist/browser/viewer/dist/tooltip.js +198 -0
- package/dist/browser/viewer/dist/types.d.ts +292 -0
- package/dist/browser/viewer/dist/types.js +1 -0
- package/dist/browser/viewer/dist/vendor/three.module.js +53032 -0
- package/dist/browser/viewer/dist/viewer-state.d.ts +19 -0
- package/dist/browser/viewer/dist/viewer-state.js +162 -0
- package/dist/browser/viewer/dist/viewer.d.ts +2 -0
- package/dist/browser/viewer/dist/viewer.js +1662 -0
- package/dist/unpkg/core/dist/atlas-edit.d.ts +11 -0
- package/dist/unpkg/core/dist/atlas-edit.js +347 -0
- package/dist/unpkg/core/dist/atlas-utils.d.ts +22 -0
- package/dist/unpkg/core/dist/atlas-utils.js +189 -0
- package/dist/unpkg/core/dist/atlas-validate.d.ts +2 -0
- package/dist/unpkg/core/dist/atlas-validate.js +488 -0
- package/dist/unpkg/core/dist/diagnostics.d.ts +10 -0
- package/dist/unpkg/core/dist/diagnostics.js +109 -0
- package/dist/unpkg/core/dist/draft-parse.d.ts +3 -0
- package/dist/unpkg/core/dist/draft-parse.js +1654 -0
- package/dist/unpkg/core/dist/draft.d.ts +21 -0
- package/dist/unpkg/core/dist/draft.js +482 -0
- package/dist/unpkg/core/dist/errors.d.ts +7 -0
- package/dist/unpkg/core/dist/errors.js +16 -0
- package/dist/unpkg/core/dist/format.d.ts +4 -0
- package/dist/unpkg/core/dist/format.js +613 -0
- package/dist/unpkg/core/dist/index.d.ts +29 -0
- package/dist/unpkg/core/dist/index.js +35 -6614
- package/dist/unpkg/core/dist/load.d.ts +4 -0
- package/dist/unpkg/core/dist/load.js +182 -0
- package/dist/unpkg/core/dist/markdown.d.ts +2 -0
- package/dist/unpkg/core/dist/markdown.js +37 -0
- package/dist/unpkg/core/dist/normalize.d.ts +2 -0
- package/dist/unpkg/core/dist/normalize.js +312 -0
- package/dist/unpkg/core/dist/parse.d.ts +2 -0
- package/dist/unpkg/core/dist/parse.js +133 -0
- package/dist/unpkg/core/dist/scene.d.ts +3 -0
- package/dist/unpkg/core/dist/scene.js +1901 -0
- package/dist/unpkg/core/dist/schema.d.ts +8 -0
- package/dist/unpkg/core/dist/schema.js +298 -0
- package/dist/unpkg/core/dist/spatial-scene.d.ts +3 -0
- package/dist/unpkg/core/dist/spatial-scene.js +420 -0
- package/dist/unpkg/core/dist/tokenize.d.ts +4 -0
- package/dist/unpkg/core/dist/tokenize.js +68 -0
- package/dist/unpkg/core/dist/types.d.ts +637 -0
- package/dist/unpkg/core/dist/types.js +1 -0
- package/dist/unpkg/core/dist/validate.d.ts +2 -0
- package/dist/unpkg/core/dist/validate.js +56 -0
- package/dist/unpkg/editor/dist/editor.d.ts +2 -0
- package/dist/unpkg/editor/dist/editor.js +3700 -0
- package/dist/unpkg/editor/dist/index.d.ts +2 -0
- package/dist/unpkg/editor/dist/index.js +1 -12275
- package/dist/unpkg/editor/dist/types.d.ts +59 -0
- package/dist/unpkg/editor/dist/types.js +1 -0
- package/dist/unpkg/markdown/dist/html.d.ts +3 -0
- package/dist/unpkg/markdown/dist/html.js +64 -0
- package/dist/unpkg/markdown/dist/index.d.ts +4 -0
- package/dist/unpkg/markdown/dist/index.js +3 -6207
- package/dist/unpkg/markdown/dist/rehype.d.ts +10 -0
- package/dist/unpkg/markdown/dist/rehype.js +49 -0
- package/dist/unpkg/markdown/dist/remark.d.ts +9 -0
- package/dist/unpkg/markdown/dist/remark.js +28 -0
- package/dist/unpkg/markdown/dist/types.d.ts +11 -0
- package/dist/unpkg/markdown/dist/types.js +1 -0
- package/dist/unpkg/viewer/dist/atlas-state.d.ts +12 -0
- package/dist/unpkg/viewer/dist/atlas-state.js +269 -0
- package/dist/unpkg/viewer/dist/atlas-viewer.d.ts +2 -0
- package/dist/unpkg/viewer/dist/atlas-viewer.js +495 -0
- package/dist/unpkg/viewer/dist/custom-element.d.ts +1 -0
- package/dist/unpkg/viewer/dist/custom-element.js +78 -0
- package/dist/unpkg/viewer/dist/embed.d.ts +24 -0
- package/dist/unpkg/viewer/dist/embed.js +172 -0
- package/dist/unpkg/viewer/dist/errors.d.ts +6 -0
- package/dist/unpkg/viewer/dist/errors.js +12 -0
- package/dist/unpkg/viewer/dist/index.d.ts +10 -0
- package/dist/unpkg/viewer/dist/index.js +9 -8391
- package/dist/unpkg/viewer/dist/minimap.d.ts +3 -0
- package/dist/unpkg/viewer/dist/minimap.js +63 -0
- package/dist/unpkg/viewer/dist/render.d.ts +6 -0
- package/dist/unpkg/viewer/dist/render.js +670 -0
- package/dist/unpkg/viewer/dist/runtime-3d.d.ts +19 -0
- package/dist/unpkg/viewer/dist/runtime-3d.js +494 -0
- package/dist/unpkg/viewer/dist/theme.d.ts +4 -0
- package/dist/unpkg/viewer/dist/theme.js +103 -0
- package/dist/unpkg/viewer/dist/tooltip.d.ts +3 -0
- package/dist/unpkg/viewer/dist/tooltip.js +198 -0
- package/dist/unpkg/viewer/dist/types.d.ts +292 -0
- package/dist/unpkg/viewer/dist/types.js +1 -0
- package/dist/unpkg/viewer/dist/vendor/three.module.js +53032 -0
- package/dist/unpkg/viewer/dist/viewer-state.d.ts +19 -0
- package/dist/unpkg/viewer/dist/viewer-state.js +162 -0
- package/dist/unpkg/viewer/dist/viewer.d.ts +2 -0
- package/dist/unpkg/viewer/dist/viewer.js +1662 -0
- package/dist/unpkg/worldorbit-core.min.js +10 -10
- package/dist/unpkg/worldorbit-editor.min.js +4109 -256
- package/dist/unpkg/worldorbit-markdown.min.js +26 -26
- package/dist/unpkg/worldorbit-viewer.min.js +3945 -92
- package/dist/unpkg/worldorbit.js +32219 -199
- package/dist/unpkg/worldorbit.min.js +3949 -96
- package/package.json +1 -1
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/spatial-scene.d.ts +3 -0
- package/packages/core/dist/spatial-scene.js +420 -0
- package/packages/core/dist/types.d.ts +105 -0
- package/packages/editor/dist/editor.js +25 -4
- package/packages/editor/dist/types.d.ts +4 -0
- package/packages/markdown/dist/html.js +10 -3
- package/packages/viewer/dist/atlas-state.js +3 -0
- package/packages/viewer/dist/atlas-viewer.js +1 -0
- package/packages/viewer/dist/custom-element.js +18 -4
- package/packages/viewer/dist/embed.d.ts +5 -1
- package/packages/viewer/dist/embed.js +58 -24
- package/packages/viewer/dist/errors.d.ts +6 -0
- package/packages/viewer/dist/errors.js +12 -0
- package/packages/viewer/dist/index.d.ts +1 -0
- package/packages/viewer/dist/index.js +1 -0
- package/packages/viewer/dist/runtime-3d.d.ts +19 -0
- package/packages/viewer/dist/runtime-3d.js +494 -0
- package/packages/viewer/dist/types.d.ts +21 -2
- package/packages/viewer/dist/vendor/three.module.js +53032 -0
- package/packages/viewer/dist/viewer.js +501 -41
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AtlasDocumentPath, AtlasResolvedDiagnostic, WorldOrbitAtlasDocument, WorldOrbitAtlasDocumentVersion, WorldOrbitDiagnostic } from "./types.js";
|
|
2
|
+
export declare function createEmptyAtlasDocument(systemId?: string, version?: WorldOrbitAtlasDocumentVersion): WorldOrbitAtlasDocument;
|
|
3
|
+
export declare function cloneAtlasDocument(document: WorldOrbitAtlasDocument): WorldOrbitAtlasDocument;
|
|
4
|
+
export declare function listAtlasDocumentPaths(document: WorldOrbitAtlasDocument): AtlasDocumentPath[];
|
|
5
|
+
export declare function getAtlasDocumentNode(document: WorldOrbitAtlasDocument, path: AtlasDocumentPath): unknown;
|
|
6
|
+
export declare function upsertAtlasDocumentNode(document: WorldOrbitAtlasDocument, path: AtlasDocumentPath, value: unknown): WorldOrbitAtlasDocument;
|
|
7
|
+
export declare function updateAtlasDocumentNode(document: WorldOrbitAtlasDocument, path: AtlasDocumentPath, updater: (value: unknown) => unknown): WorldOrbitAtlasDocument;
|
|
8
|
+
export declare function removeAtlasDocumentNode(document: WorldOrbitAtlasDocument, path: AtlasDocumentPath): WorldOrbitAtlasDocument;
|
|
9
|
+
export declare function resolveAtlasDiagnostics(document: WorldOrbitAtlasDocument, diagnostics: WorldOrbitDiagnostic[]): AtlasResolvedDiagnostic[];
|
|
10
|
+
export declare function resolveAtlasDiagnosticPath(document: WorldOrbitAtlasDocument, diagnostic: WorldOrbitDiagnostic): AtlasDocumentPath | null;
|
|
11
|
+
export declare function validateAtlasDocumentWithDiagnostics(document: WorldOrbitAtlasDocument): AtlasResolvedDiagnostic[];
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { collectAtlasDiagnostics } from "./atlas-validate.js";
|
|
2
|
+
export function createEmptyAtlasDocument(systemId = "WorldOrbit", version = "2.5") {
|
|
3
|
+
return {
|
|
4
|
+
format: "worldorbit",
|
|
5
|
+
version,
|
|
6
|
+
schemaVersion: version,
|
|
7
|
+
sourceVersion: "1.0",
|
|
8
|
+
system: {
|
|
9
|
+
type: "system",
|
|
10
|
+
id: systemId,
|
|
11
|
+
title: systemId,
|
|
12
|
+
description: null,
|
|
13
|
+
epoch: null,
|
|
14
|
+
referencePlane: null,
|
|
15
|
+
defaults: {
|
|
16
|
+
view: "topdown",
|
|
17
|
+
scale: null,
|
|
18
|
+
units: null,
|
|
19
|
+
preset: null,
|
|
20
|
+
theme: null,
|
|
21
|
+
},
|
|
22
|
+
atlasMetadata: {},
|
|
23
|
+
viewpoints: [],
|
|
24
|
+
annotations: [],
|
|
25
|
+
},
|
|
26
|
+
groups: [],
|
|
27
|
+
relations: [],
|
|
28
|
+
events: [],
|
|
29
|
+
objects: [],
|
|
30
|
+
diagnostics: [],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function cloneAtlasDocument(document) {
|
|
34
|
+
return structuredClone(document);
|
|
35
|
+
}
|
|
36
|
+
export function listAtlasDocumentPaths(document) {
|
|
37
|
+
const paths = [{ kind: "system" }, { kind: "defaults" }];
|
|
38
|
+
if (document.system) {
|
|
39
|
+
for (const key of Object.keys(document.system.atlasMetadata).sort()) {
|
|
40
|
+
paths.push({ kind: "metadata", key });
|
|
41
|
+
}
|
|
42
|
+
for (const viewpoint of [...document.system.viewpoints].sort(compareIdLike)) {
|
|
43
|
+
paths.push({ kind: "viewpoint", id: viewpoint.id });
|
|
44
|
+
}
|
|
45
|
+
for (const annotation of [...document.system.annotations].sort(compareIdLike)) {
|
|
46
|
+
paths.push({ kind: "annotation", id: annotation.id });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const group of [...document.groups].sort(compareIdLike)) {
|
|
50
|
+
paths.push({ kind: "group", id: group.id });
|
|
51
|
+
}
|
|
52
|
+
for (const relation of [...document.relations].sort(compareIdLike)) {
|
|
53
|
+
paths.push({ kind: "relation", id: relation.id });
|
|
54
|
+
}
|
|
55
|
+
for (const event of [...document.events].sort(compareIdLike)) {
|
|
56
|
+
paths.push({ kind: "event", id: event.id });
|
|
57
|
+
for (const pose of [...event.positions].sort(comparePoseObjectId)) {
|
|
58
|
+
paths.push({ kind: "event-pose", id: event.id, key: pose.objectId });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for (const object of [...document.objects].sort(compareIdLike)) {
|
|
62
|
+
paths.push({ kind: "object", id: object.id });
|
|
63
|
+
}
|
|
64
|
+
return paths;
|
|
65
|
+
}
|
|
66
|
+
export function getAtlasDocumentNode(document, path) {
|
|
67
|
+
switch (path.kind) {
|
|
68
|
+
case "system":
|
|
69
|
+
return document.system;
|
|
70
|
+
case "defaults":
|
|
71
|
+
return document.system?.defaults ?? null;
|
|
72
|
+
case "metadata":
|
|
73
|
+
return path.key ? (document.system?.atlasMetadata[path.key] ?? null) : null;
|
|
74
|
+
case "group":
|
|
75
|
+
return path.id ? findGroup(document, path.id) : null;
|
|
76
|
+
case "event":
|
|
77
|
+
return path.id ? findEvent(document, path.id) : null;
|
|
78
|
+
case "event-pose":
|
|
79
|
+
return path.id && path.key ? findEventPose(document, path.id, path.key) : null;
|
|
80
|
+
case "object":
|
|
81
|
+
return path.id ? findObject(document, path.id) : null;
|
|
82
|
+
case "viewpoint":
|
|
83
|
+
return path.id ? findViewpoint(document.system, path.id) : null;
|
|
84
|
+
case "annotation":
|
|
85
|
+
return path.id ? findAnnotation(document.system, path.id) : null;
|
|
86
|
+
case "relation":
|
|
87
|
+
return path.id ? findRelation(document, path.id) : null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function upsertAtlasDocumentNode(document, path, value) {
|
|
91
|
+
const next = cloneAtlasDocument(document);
|
|
92
|
+
const system = ensureSystem(next);
|
|
93
|
+
switch (path.kind) {
|
|
94
|
+
case "system":
|
|
95
|
+
next.system = value;
|
|
96
|
+
return next;
|
|
97
|
+
case "defaults":
|
|
98
|
+
system.defaults = {
|
|
99
|
+
...system.defaults,
|
|
100
|
+
...value,
|
|
101
|
+
};
|
|
102
|
+
return next;
|
|
103
|
+
case "metadata":
|
|
104
|
+
if (!path.key) {
|
|
105
|
+
throw new Error('Metadata updates require a "key" value.');
|
|
106
|
+
}
|
|
107
|
+
if (value === null || value === undefined || value === "") {
|
|
108
|
+
delete system.atlasMetadata[path.key];
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
system.atlasMetadata[path.key] = String(value);
|
|
112
|
+
}
|
|
113
|
+
return next;
|
|
114
|
+
case "group":
|
|
115
|
+
if (!path.id) {
|
|
116
|
+
throw new Error('Group updates require an "id" value.');
|
|
117
|
+
}
|
|
118
|
+
upsertById(next.groups, value);
|
|
119
|
+
return next;
|
|
120
|
+
case "event":
|
|
121
|
+
if (!path.id) {
|
|
122
|
+
throw new Error('Event updates require an "id" value.');
|
|
123
|
+
}
|
|
124
|
+
upsertById(next.events, value);
|
|
125
|
+
return next;
|
|
126
|
+
case "event-pose":
|
|
127
|
+
if (!path.id || !path.key) {
|
|
128
|
+
throw new Error('Event pose updates require an event "id" and pose "key" value.');
|
|
129
|
+
}
|
|
130
|
+
upsertEventPose(next.events, path.id, value);
|
|
131
|
+
return next;
|
|
132
|
+
case "object":
|
|
133
|
+
if (!path.id) {
|
|
134
|
+
throw new Error('Object updates require an "id" value.');
|
|
135
|
+
}
|
|
136
|
+
upsertById(next.objects, value);
|
|
137
|
+
return next;
|
|
138
|
+
case "viewpoint":
|
|
139
|
+
if (!path.id) {
|
|
140
|
+
throw new Error('Viewpoint updates require an "id" value.');
|
|
141
|
+
}
|
|
142
|
+
upsertById(system.viewpoints, value);
|
|
143
|
+
return next;
|
|
144
|
+
case "annotation":
|
|
145
|
+
if (!path.id) {
|
|
146
|
+
throw new Error('Annotation updates require an "id" value.');
|
|
147
|
+
}
|
|
148
|
+
upsertById(system.annotations, value);
|
|
149
|
+
return next;
|
|
150
|
+
case "relation":
|
|
151
|
+
if (!path.id) {
|
|
152
|
+
throw new Error('Relation updates require an "id" value.');
|
|
153
|
+
}
|
|
154
|
+
upsertById(next.relations, value);
|
|
155
|
+
return next;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export function updateAtlasDocumentNode(document, path, updater) {
|
|
159
|
+
return upsertAtlasDocumentNode(document, path, updater(getAtlasDocumentNode(document, path)));
|
|
160
|
+
}
|
|
161
|
+
export function removeAtlasDocumentNode(document, path) {
|
|
162
|
+
const next = cloneAtlasDocument(document);
|
|
163
|
+
const system = ensureSystem(next);
|
|
164
|
+
switch (path.kind) {
|
|
165
|
+
case "metadata":
|
|
166
|
+
if (path.key) {
|
|
167
|
+
delete system.atlasMetadata[path.key];
|
|
168
|
+
}
|
|
169
|
+
return next;
|
|
170
|
+
case "object":
|
|
171
|
+
if (path.id) {
|
|
172
|
+
next.objects = next.objects.filter((object) => object.id !== path.id);
|
|
173
|
+
}
|
|
174
|
+
return next;
|
|
175
|
+
case "group":
|
|
176
|
+
if (path.id) {
|
|
177
|
+
next.groups = next.groups.filter((group) => group.id !== path.id);
|
|
178
|
+
}
|
|
179
|
+
return next;
|
|
180
|
+
case "event":
|
|
181
|
+
if (path.id) {
|
|
182
|
+
next.events = next.events.filter((event) => event.id !== path.id);
|
|
183
|
+
}
|
|
184
|
+
return next;
|
|
185
|
+
case "event-pose":
|
|
186
|
+
if (path.id && path.key) {
|
|
187
|
+
const event = findEvent(next, path.id);
|
|
188
|
+
if (event) {
|
|
189
|
+
event.positions = event.positions.filter((pose) => pose.objectId !== path.key);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return next;
|
|
193
|
+
case "viewpoint":
|
|
194
|
+
if (path.id) {
|
|
195
|
+
system.viewpoints = system.viewpoints.filter((viewpoint) => viewpoint.id !== path.id);
|
|
196
|
+
}
|
|
197
|
+
return next;
|
|
198
|
+
case "annotation":
|
|
199
|
+
if (path.id) {
|
|
200
|
+
system.annotations = system.annotations.filter((annotation) => annotation.id !== path.id);
|
|
201
|
+
}
|
|
202
|
+
return next;
|
|
203
|
+
case "relation":
|
|
204
|
+
if (path.id) {
|
|
205
|
+
next.relations = next.relations.filter((relation) => relation.id !== path.id);
|
|
206
|
+
}
|
|
207
|
+
return next;
|
|
208
|
+
default:
|
|
209
|
+
return next;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
export function resolveAtlasDiagnostics(document, diagnostics) {
|
|
213
|
+
return diagnostics.map((diagnostic) => ({
|
|
214
|
+
diagnostic,
|
|
215
|
+
path: resolveAtlasDiagnosticPath(document, diagnostic),
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
export function resolveAtlasDiagnosticPath(document, diagnostic) {
|
|
219
|
+
if (diagnostic.objectId && findObject(document, diagnostic.objectId)) {
|
|
220
|
+
return {
|
|
221
|
+
kind: "object",
|
|
222
|
+
id: diagnostic.objectId,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (diagnostic.field?.startsWith("group.")) {
|
|
226
|
+
const parts = diagnostic.field.split(".");
|
|
227
|
+
if (parts[1] && findGroup(document, parts[1])) {
|
|
228
|
+
return {
|
|
229
|
+
kind: "group",
|
|
230
|
+
id: parts[1],
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (diagnostic.field?.startsWith("viewpoint.")) {
|
|
235
|
+
const parts = diagnostic.field.split(".");
|
|
236
|
+
if (parts[1] && findViewpoint(document.system, parts[1])) {
|
|
237
|
+
return {
|
|
238
|
+
kind: "viewpoint",
|
|
239
|
+
id: parts[1],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (diagnostic.field?.startsWith("annotation.")) {
|
|
244
|
+
const parts = diagnostic.field.split(".");
|
|
245
|
+
if (parts[1] && findAnnotation(document.system, parts[1])) {
|
|
246
|
+
return {
|
|
247
|
+
kind: "annotation",
|
|
248
|
+
id: parts[1],
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (diagnostic.field?.startsWith("relation.")) {
|
|
253
|
+
const parts = diagnostic.field.split(".");
|
|
254
|
+
if (parts[1] && findRelation(document, parts[1])) {
|
|
255
|
+
return {
|
|
256
|
+
kind: "relation",
|
|
257
|
+
id: parts[1],
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (diagnostic.field?.startsWith("event.")) {
|
|
262
|
+
const parts = diagnostic.field.split(".");
|
|
263
|
+
if (parts[1] && findEvent(document, parts[1])) {
|
|
264
|
+
if (parts[2] === "pose" && parts[3] && findEventPose(document, parts[1], parts[3])) {
|
|
265
|
+
return {
|
|
266
|
+
kind: "event-pose",
|
|
267
|
+
id: parts[1],
|
|
268
|
+
key: parts[3],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
kind: "event",
|
|
273
|
+
id: parts[1],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (diagnostic.field && diagnostic.field in ensureSystem(document).atlasMetadata) {
|
|
278
|
+
return {
|
|
279
|
+
kind: "metadata",
|
|
280
|
+
key: diagnostic.field,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
export function validateAtlasDocumentWithDiagnostics(document) {
|
|
286
|
+
const diagnostics = [
|
|
287
|
+
...document.diagnostics,
|
|
288
|
+
...collectAtlasDiagnostics(document, document.version),
|
|
289
|
+
];
|
|
290
|
+
return resolveAtlasDiagnostics(document, diagnostics);
|
|
291
|
+
}
|
|
292
|
+
function ensureSystem(document) {
|
|
293
|
+
if (document.system) {
|
|
294
|
+
return document.system;
|
|
295
|
+
}
|
|
296
|
+
document.system = createEmptyAtlasDocument().system;
|
|
297
|
+
return document.system;
|
|
298
|
+
}
|
|
299
|
+
function findObject(document, objectId) {
|
|
300
|
+
return document.objects.find((object) => object.id === objectId) ?? null;
|
|
301
|
+
}
|
|
302
|
+
function findGroup(document, groupId) {
|
|
303
|
+
return document.groups.find((group) => group.id === groupId) ?? null;
|
|
304
|
+
}
|
|
305
|
+
function findRelation(document, relationId) {
|
|
306
|
+
return document.relations.find((relation) => relation.id === relationId) ?? null;
|
|
307
|
+
}
|
|
308
|
+
function findEvent(document, eventId) {
|
|
309
|
+
return document.events.find((event) => event.id === eventId) ?? null;
|
|
310
|
+
}
|
|
311
|
+
function findEventPose(document, eventId, objectId) {
|
|
312
|
+
return findEvent(document, eventId)?.positions.find((pose) => pose.objectId === objectId) ?? null;
|
|
313
|
+
}
|
|
314
|
+
function findViewpoint(system, viewpointId) {
|
|
315
|
+
return system?.viewpoints.find((viewpoint) => viewpoint.id === viewpointId) ?? null;
|
|
316
|
+
}
|
|
317
|
+
function findAnnotation(system, annotationId) {
|
|
318
|
+
return system?.annotations.find((annotation) => annotation.id === annotationId) ?? null;
|
|
319
|
+
}
|
|
320
|
+
function upsertById(items, value) {
|
|
321
|
+
const index = items.findIndex((item) => item.id === value.id);
|
|
322
|
+
if (index === -1) {
|
|
323
|
+
items.push(value);
|
|
324
|
+
items.sort(compareIdLike);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
items[index] = value;
|
|
328
|
+
}
|
|
329
|
+
function upsertEventPose(events, eventId, value) {
|
|
330
|
+
const event = events.find((entry) => entry.id === eventId);
|
|
331
|
+
if (!event) {
|
|
332
|
+
throw new Error(`Unknown event "${eventId}" for pose update.`);
|
|
333
|
+
}
|
|
334
|
+
const index = event.positions.findIndex((entry) => entry.objectId === value.objectId);
|
|
335
|
+
if (index === -1) {
|
|
336
|
+
event.positions.push(value);
|
|
337
|
+
event.positions.sort(comparePoseObjectId);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
event.positions[index] = value;
|
|
341
|
+
}
|
|
342
|
+
function compareIdLike(left, right) {
|
|
343
|
+
return left.id.localeCompare(right.id);
|
|
344
|
+
}
|
|
345
|
+
function comparePoseObjectId(left, right) {
|
|
346
|
+
return left.objectId.localeCompare(right.objectId);
|
|
347
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AstFieldNode, AstSourceLocation, AtReference, NormalizedValue, UnitValue, WorldOrbitObjectType } from "./types.js";
|
|
2
|
+
export interface AtlasFieldLike {
|
|
3
|
+
key: string;
|
|
4
|
+
values: string[];
|
|
5
|
+
location: AstSourceLocation;
|
|
6
|
+
}
|
|
7
|
+
export declare function normalizeIdentifier(value: string): string;
|
|
8
|
+
export declare function humanizeIdentifier(value: string): string;
|
|
9
|
+
export declare function parseAtlasUnitValue(input: string, location?: AstSourceLocation, fieldKey?: string): UnitValue;
|
|
10
|
+
export declare function tryParseAtlasUnitValue(input: string): UnitValue | null;
|
|
11
|
+
export declare function parseAtlasNumber(input: string, key: string, location?: AstSourceLocation): number;
|
|
12
|
+
export declare function parseAtlasBoolean(input: string, key: string, location?: AstSourceLocation): boolean;
|
|
13
|
+
export declare function parseAtlasFieldBoolean(field: AtlasFieldLike): boolean;
|
|
14
|
+
export declare function parseAtlasAtReference(target: string, location?: AstSourceLocation): AtReference;
|
|
15
|
+
export declare function validateAtlasImageSource(value: string, location?: AstSourceLocation): void;
|
|
16
|
+
export declare function normalizeLegacyScalarValue(key: string, values: string[], location: AstSourceLocation): NormalizedValue;
|
|
17
|
+
export declare function ensureAtlasFieldSupported(key: string, objectType: WorldOrbitObjectType, location: AstSourceLocation): void;
|
|
18
|
+
export declare function singleAtlasFieldValue(field: Pick<AtlasFieldLike, "key" | "values" | "location">): string;
|
|
19
|
+
export declare function singleAtlasValue(values: string[], key: string, location?: AstSourceLocation): string;
|
|
20
|
+
export declare function isStructureLikeObjectType(objectType: WorldOrbitObjectType): boolean;
|
|
21
|
+
export declare function cloneNormalizedValue(value: NormalizedValue): NormalizedValue;
|
|
22
|
+
export declare function cloneFieldNode(field: AstFieldNode): AstFieldNode;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { WorldOrbitError } from "./errors.js";
|
|
2
|
+
import { getFieldSchema, unitFamilyAllowsUnit } from "./schema.js";
|
|
3
|
+
const UNIT_PATTERN = /^(-?\d+(?:\.\d+)?)(kpc|min|mj|rj|ky|my|gy|au|km|me|re|pc|ly|deg|sol|K|m|s|h|d|y)?$/;
|
|
4
|
+
const BOOLEAN_VALUES = new Map([
|
|
5
|
+
["true", true],
|
|
6
|
+
["false", false],
|
|
7
|
+
["yes", true],
|
|
8
|
+
["no", false],
|
|
9
|
+
]);
|
|
10
|
+
const URL_SCHEME_PATTERN = /^[A-Za-z][A-Za-z0-9+.-]*:/;
|
|
11
|
+
export function normalizeIdentifier(value) {
|
|
12
|
+
return value
|
|
13
|
+
.trim()
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
16
|
+
.replace(/^-+|-+$/g, "");
|
|
17
|
+
}
|
|
18
|
+
export function humanizeIdentifier(value) {
|
|
19
|
+
return value
|
|
20
|
+
.split(/[-_]+/)
|
|
21
|
+
.filter(Boolean)
|
|
22
|
+
.map((segment) => segment[0].toUpperCase() + segment.slice(1))
|
|
23
|
+
.join(" ");
|
|
24
|
+
}
|
|
25
|
+
export function parseAtlasUnitValue(input, location, fieldKey) {
|
|
26
|
+
const match = input.match(UNIT_PATTERN);
|
|
27
|
+
if (!match) {
|
|
28
|
+
throw WorldOrbitError.fromLocation(`Invalid unit value "${input}"`, location);
|
|
29
|
+
}
|
|
30
|
+
const unitValue = {
|
|
31
|
+
value: Number(match[1]),
|
|
32
|
+
unit: match[2] ?? null,
|
|
33
|
+
};
|
|
34
|
+
if (fieldKey) {
|
|
35
|
+
const schema = getFieldSchema(fieldKey);
|
|
36
|
+
if (schema?.unitFamily && !unitFamilyAllowsUnit(schema.unitFamily, unitValue.unit)) {
|
|
37
|
+
throw WorldOrbitError.fromLocation(`Unit "${unitValue.unit ?? "none"}" is not valid for "${fieldKey}"`, location);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return unitValue;
|
|
41
|
+
}
|
|
42
|
+
export function tryParseAtlasUnitValue(input) {
|
|
43
|
+
const match = input.match(UNIT_PATTERN);
|
|
44
|
+
if (!match) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
value: Number(match[1]),
|
|
49
|
+
unit: match[2] ?? null,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function parseAtlasNumber(input, key, location) {
|
|
53
|
+
const value = Number(input);
|
|
54
|
+
if (!Number.isFinite(value)) {
|
|
55
|
+
throw WorldOrbitError.fromLocation(`Invalid numeric value "${input}" for "${key}"`, location);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
export function parseAtlasBoolean(input, key, location) {
|
|
60
|
+
const parsed = BOOLEAN_VALUES.get(input.toLowerCase());
|
|
61
|
+
if (parsed === undefined) {
|
|
62
|
+
throw WorldOrbitError.fromLocation(`Invalid boolean value "${input}" for "${key}"`, location);
|
|
63
|
+
}
|
|
64
|
+
return parsed;
|
|
65
|
+
}
|
|
66
|
+
export function parseAtlasFieldBoolean(field) {
|
|
67
|
+
return parseAtlasBoolean(singleAtlasFieldValue(field), field.key, field.location);
|
|
68
|
+
}
|
|
69
|
+
export function parseAtlasAtReference(target, location) {
|
|
70
|
+
if (/^[A-Za-z0-9._-]+-[A-Za-z0-9._-]+:L\d+$/i.test(target)) {
|
|
71
|
+
throw WorldOrbitError.fromLocation(`Invalid special position "${target}"`, location);
|
|
72
|
+
}
|
|
73
|
+
const pairedMatch = target.match(/^([A-Za-z0-9._-]+)-([A-Za-z0-9._-]+):(L[1-5])$/);
|
|
74
|
+
if (pairedMatch) {
|
|
75
|
+
return {
|
|
76
|
+
kind: "lagrange",
|
|
77
|
+
primary: pairedMatch[1],
|
|
78
|
+
secondary: pairedMatch[2],
|
|
79
|
+
point: pairedMatch[3],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const simpleMatch = target.match(/^([A-Za-z0-9._-]+):(L[1-5])$/);
|
|
83
|
+
if (simpleMatch) {
|
|
84
|
+
return {
|
|
85
|
+
kind: "lagrange",
|
|
86
|
+
primary: simpleMatch[1],
|
|
87
|
+
secondary: null,
|
|
88
|
+
point: simpleMatch[2],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (/^[A-Za-z0-9._-]+:L\d+$/i.test(target)) {
|
|
92
|
+
throw WorldOrbitError.fromLocation(`Invalid special position "${target}"`, location);
|
|
93
|
+
}
|
|
94
|
+
const anchorMatch = target.match(/^([A-Za-z0-9._-]+):([A-Za-z0-9._-]+)$/);
|
|
95
|
+
if (anchorMatch) {
|
|
96
|
+
return {
|
|
97
|
+
kind: "anchor",
|
|
98
|
+
objectId: anchorMatch[1],
|
|
99
|
+
anchor: anchorMatch[2],
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
kind: "named",
|
|
104
|
+
name: target,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function validateAtlasImageSource(value, location) {
|
|
108
|
+
if (!value) {
|
|
109
|
+
throw WorldOrbitError.fromLocation('Field "image" must not be empty', location);
|
|
110
|
+
}
|
|
111
|
+
if (value.startsWith("//")) {
|
|
112
|
+
throw WorldOrbitError.fromLocation('Field "image" must use a relative path, root-relative path, or an http/https URL', location);
|
|
113
|
+
}
|
|
114
|
+
const schemeMatch = value.match(URL_SCHEME_PATTERN);
|
|
115
|
+
if (!schemeMatch) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const scheme = schemeMatch[0].slice(0, -1).toLowerCase();
|
|
119
|
+
if (scheme !== "http" && scheme !== "https") {
|
|
120
|
+
throw WorldOrbitError.fromLocation(`Field "image" does not support the "${scheme}" scheme`, location);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export function normalizeLegacyScalarValue(key, values, location) {
|
|
124
|
+
const schema = getFieldSchema(key);
|
|
125
|
+
if (!schema) {
|
|
126
|
+
throw WorldOrbitError.fromLocation(`Unknown field "${key}"`, location);
|
|
127
|
+
}
|
|
128
|
+
if (schema.arity === "single" && values.length !== 1) {
|
|
129
|
+
throw WorldOrbitError.fromLocation(`Field "${key}" expects exactly one value`, location);
|
|
130
|
+
}
|
|
131
|
+
switch (schema.kind) {
|
|
132
|
+
case "list":
|
|
133
|
+
return values;
|
|
134
|
+
case "boolean":
|
|
135
|
+
return parseAtlasBoolean(singleAtlasValue(values, key, location), key, location);
|
|
136
|
+
case "number":
|
|
137
|
+
return parseAtlasNumber(singleAtlasValue(values, key, location), key, location);
|
|
138
|
+
case "unit":
|
|
139
|
+
return parseAtlasUnitValue(singleAtlasValue(values, key, location), location, key);
|
|
140
|
+
case "string": {
|
|
141
|
+
const value = values.join(" ").trim();
|
|
142
|
+
if (key === "image") {
|
|
143
|
+
validateAtlasImageSource(value, location);
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export function ensureAtlasFieldSupported(key, objectType, location) {
|
|
150
|
+
const schema = getFieldSchema(key);
|
|
151
|
+
if (!schema) {
|
|
152
|
+
throw WorldOrbitError.fromLocation(`Unknown field "${key}"`, location);
|
|
153
|
+
}
|
|
154
|
+
if (!schema.objectTypes.includes(objectType)) {
|
|
155
|
+
throw WorldOrbitError.fromLocation(`Field "${key}" is not valid on "${objectType}"`, location);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export function singleAtlasFieldValue(field) {
|
|
159
|
+
return singleAtlasValue(field.values, field.key, field.location);
|
|
160
|
+
}
|
|
161
|
+
export function singleAtlasValue(values, key, location) {
|
|
162
|
+
if (values.length !== 1) {
|
|
163
|
+
throw WorldOrbitError.fromLocation(`Field "${key}" expects exactly one value`, location);
|
|
164
|
+
}
|
|
165
|
+
return values[0];
|
|
166
|
+
}
|
|
167
|
+
export function isStructureLikeObjectType(objectType) {
|
|
168
|
+
return objectType === "structure" || objectType === "phenomenon";
|
|
169
|
+
}
|
|
170
|
+
export function cloneNormalizedValue(value) {
|
|
171
|
+
if (Array.isArray(value)) {
|
|
172
|
+
return [...value];
|
|
173
|
+
}
|
|
174
|
+
if (value && typeof value === "object" && "value" in value) {
|
|
175
|
+
return {
|
|
176
|
+
value: value.value,
|
|
177
|
+
unit: value.unit,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return value;
|
|
181
|
+
}
|
|
182
|
+
export function cloneFieldNode(field) {
|
|
183
|
+
return {
|
|
184
|
+
type: "field",
|
|
185
|
+
key: field.key,
|
|
186
|
+
values: [...field.values],
|
|
187
|
+
location: { ...field.location },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { WorldOrbitAnyDocumentVersion, WorldOrbitAtlasDocument, WorldOrbitDiagnostic, WorldOrbitDraftDocument } from "./types.js";
|
|
2
|
+
export declare function collectAtlasDiagnostics(document: WorldOrbitAtlasDocument | WorldOrbitDraftDocument, sourceSchemaVersion?: WorldOrbitAnyDocumentVersion): WorldOrbitDiagnostic[];
|