@volter/project 0.5.210 → 0.5.212
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/NOTICE +2 -2
- package/README.md +8 -15
- package/package.json +5 -26
- package/schemas/volter-project.schema.json +33 -145
- package/schemas/volter-settings.schema.json +11 -49
- package/src/adapter/adapter-module.ts +204 -465
- package/src/adapter/adapter-surface.ts +4 -32
- package/src/adapter/authoring-seam-contract.ts +7 -24
- package/src/adapter/authoring.ts +126 -265
- package/src/adapter/editor-looks.ts +96 -127
- package/src/adapter/finders/registry.ts +6 -21
- package/src/adapter/host-context.ts +17 -72
- package/src/adapter/index.ts +4 -77
- package/src/adapter/manifest-interpreter.ts +7 -50
- package/src/adapter/physics-adapter-2d.ts +4 -21
- package/src/adapter/root-adapter.ts +37 -111
- package/src/adapter/root-seam-contract.ts +3 -6
- package/src/adapter/root-stacking.ts +4 -46
- package/src/adapter/seam-evidence.ts +0 -16
- package/src/adapter/system-adapter.ts +24 -656
- package/src/adapter/system-seam-contract.ts +1 -91
- package/src/adapter/transform.ts +4 -3
- package/src/adapter/workspace-arrangement.ts +29 -49
- package/src/manifest/editor-port.ts +10 -36
- package/src/manifest/filename.ts +3 -42
- package/src/manifest/load-file.ts +9 -15
- package/src/manifest/load.ts +44 -179
- package/src/manifest/locate.ts +6 -29
- package/src/manifest/schema.ts +155 -427
- package/src/semver.ts +16 -0
- package/src/settings/keys.ts +9 -11
- package/src/settings/schema.ts +55 -44
- package/schemas/engine-api.json +0 -57
- package/schemas/engine-api.md +0 -22
- package/src/adapter/binding.ts +0 -445
- package/src/adapter/debug-registry-ref.ts +0 -19
- package/src/adapter/frame-capture.ts +0 -80
- package/src/adapter/ingest/contract-system-slots.ts +0 -28
- package/src/adapter/ingest/game-contract-seams.ts +0 -86
- package/src/adapter/ingest/game-contract.ts +0 -506
- package/src/adapter/ingest/mount-readiness.ts +0 -140
- package/src/adapter/loop-gate-report.ts +0 -53
- package/src/adapter/native-entry-surface.ts +0 -100
- package/src/adapter/render-audio.ts +0 -20
- package/src/adapter/render-memory.ts +0 -34
- package/src/adapter/renderer-config.ts +0 -84
- package/src/adapter/system-slot.ts +0 -301
- package/src/core/system-phase.ts +0 -52
- package/src/inspection.ts +0 -281
- package/src/manifest/configuration-kinds.ts +0 -241
- package/src/manifest/kind-modules.ts +0 -58
- package/src/manifest/runtime-environment.ts +0 -48
package/src/semver.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Compares two exact versions (`1.2.3`, with an optional prerelease or build suffix, which is not ordered),
|
|
2
|
+
// such as a project's pinned engine and the engine an editor runs. Anything else compares as `null`.
|
|
3
|
+
const EXACT_SEMVER = /^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
4
|
+
|
|
5
|
+
export function compareSemver(a: string, b: string): -1 | 0 | 1 | null {
|
|
6
|
+
const aMatch = EXACT_SEMVER.exec(a);
|
|
7
|
+
const bMatch = EXACT_SEMVER.exec(b);
|
|
8
|
+
if (!aMatch || !bMatch) return null;
|
|
9
|
+
for (let index = 1; index <= 3; index++) {
|
|
10
|
+
const aPart = Number(aMatch[index]);
|
|
11
|
+
const bPart = Number(bMatch[index]);
|
|
12
|
+
if (aPart < bPart) return -1;
|
|
13
|
+
if (aPart > bPart) return 1;
|
|
14
|
+
}
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
package/src/settings/keys.ts
CHANGED
|
@@ -4,22 +4,21 @@
|
|
|
4
4
|
*
|
|
5
5
|
* ## Why it exists, and why it is DERIVED
|
|
6
6
|
*
|
|
7
|
-
* Under the Code-OSS frame
|
|
7
|
+
* Under the Code-OSS frame the
|
|
8
8
|
* settings layers are the configuration service's, and a configuration service
|
|
9
|
-
* speaks FLAT DOTTED KEYS — `volter.appearance.
|
|
9
|
+
* speaks FLAT DOTTED KEYS — `volter.appearance.regions.header` — while
|
|
10
10
|
* `schema.ts`'s document is a nested object. Something has to be the one place
|
|
11
11
|
* those two spellings meet, and the same table is what the fork's
|
|
12
12
|
* `contributes.configuration` is generated from, so VS Code's Settings editor
|
|
13
13
|
* shows every volter setting with the description its `.describe()` call already
|
|
14
14
|
* carries.
|
|
15
15
|
*
|
|
16
|
-
* It is DERIVED from {@link EditorSettingsSchema} rather than written
|
|
17
|
-
*
|
|
18
|
-
* union: a hand-kept second list of the same seventeen keys drifts the first
|
|
16
|
+
* It is DERIVED from {@link EditorSettingsSchema} rather than written: a
|
|
17
|
+
* hand-kept second list of the same keys drifts the first
|
|
19
18
|
* time somebody adds a field, and a settings key with no declaration is
|
|
20
19
|
* invisible in the one settings UI rather than loud. The walk is over the JSON
|
|
21
20
|
* Schema Zod itself produces (`z.toJSONSchema`) — the SAME derivation
|
|
22
|
-
* `scripts/generate-schema.
|
|
21
|
+
* `packages/project/scripts/generate-schema.mjs` commits as
|
|
23
22
|
* `packages/project/schemas/volter-settings.schema.json`, which is what the
|
|
24
23
|
* fork's generator reads. One derivation, three consumers: this table, the
|
|
25
24
|
* committed schema a person's editor autocompletes against, and the frame's
|
|
@@ -40,13 +39,12 @@ export const SETTINGS_KEY_PREFIX = 'volter';
|
|
|
40
39
|
|
|
41
40
|
/** What a key is, and what the Settings editor shows for it. */
|
|
42
41
|
export interface SettingsKeyDescriptor {
|
|
43
|
-
/** The dotted name, prefix included: `volter.appearance.
|
|
42
|
+
/** The dotted name, prefix included: `volter.appearance.regions.header`. */
|
|
44
43
|
readonly key: string;
|
|
45
|
-
/** The path into the settings document: `['appearance', '
|
|
44
|
+
/** The path into the settings document: `['appearance', 'regions', 'header']`. */
|
|
46
45
|
readonly path: readonly string[];
|
|
47
|
-
/** JSON Schema `type`, when the field has exactly one. A nullable field
|
|
48
|
-
*
|
|
49
|
-
* rather than picking one of the two. */
|
|
46
|
+
/** JSON Schema `type`, when the field has exactly one. A nullable field has
|
|
47
|
+
* none, and the frame declares no type for it rather than picking one. */
|
|
50
48
|
readonly type?: string | undefined;
|
|
51
49
|
/** The closed set of values, when the field is an enum. */
|
|
52
50
|
readonly values?: readonly string[] | undefined;
|
package/src/settings/schema.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* THE SETTINGS DOCUMENT — the Zod truth for the two shared settings layers
|
|
3
|
-
* (ARCHITECTURE-CORE §Editor chrome, "Settings have four layers with named
|
|
4
|
-
* homes"):
|
|
2
|
+
* THE SETTINGS DOCUMENT — the Zod truth for the two shared settings layers:
|
|
5
3
|
*
|
|
6
|
-
* ~/.volter/settings.json
|
|
7
|
-
* <project>/.
|
|
8
|
-
*
|
|
4
|
+
* ~/.volter/settings.json the USER layer — one person, every project
|
|
5
|
+
* <project>/.vscode/settings.json the PROJECT layer — one project, committed,
|
|
6
|
+
* every person who opens it: its `volter.*`
|
|
7
|
+
* keys, in Code-OSS's own workspace settings
|
|
8
|
+
* (`editor-core/server/project-settings-file.ts`)
|
|
9
9
|
*
|
|
10
|
-
* Both
|
|
10
|
+
* Both layers carry the same shape; the project layer overrides the user layer
|
|
11
11
|
* key by key (`mergeEditorSettings`). Neither layer holds authored content —
|
|
12
12
|
* an unreadable file is reported by name and falls back to defaults, never
|
|
13
13
|
* migrated. The generated JSON Schema (`npm run generate-schema` →
|
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Every field here has a runtime reader in the editor's settings store
|
|
18
18
|
* consumers (`theme-preference.ts`, `workspace-regions.ts`,
|
|
19
|
-
* `keymap-presets.ts`, `workspace-presets.ts
|
|
20
|
-
* with no reader
|
|
21
|
-
* fields that have no runtime reader").
|
|
19
|
+
* `keymap-presets.ts`, `workspace-presets.ts`); a field
|
|
20
|
+
* with no runtime reader has no setting to govern.
|
|
22
21
|
*/
|
|
23
22
|
import { z } from 'zod';
|
|
24
23
|
|
|
@@ -27,29 +26,26 @@ const RegionVisibility = z.enum(['shown', 'hidden']);
|
|
|
27
26
|
export const ChromeRegionsSettingsSchema = z
|
|
28
27
|
.object({
|
|
29
28
|
workspaceTabs: RegionVisibility.optional().describe(
|
|
30
|
-
|
|
29
|
+
'The workspace tab strip in the top bar; hidden unless a style shows it.',
|
|
31
30
|
),
|
|
32
31
|
header: RegionVisibility.optional().describe('The top header bar.'),
|
|
33
32
|
shelf: RegionVisibility.optional().describe('The utility shelf.'),
|
|
34
33
|
inspector: z
|
|
35
34
|
.enum(['column', 'properties', 'card'])
|
|
36
35
|
.optional()
|
|
37
|
-
.describe('Inspector presentation:
|
|
36
|
+
.describe('Inspector presentation: a narrow docked column, properties panel or card.'),
|
|
38
37
|
drawer: RegionVisibility.optional().describe('The bottom drawer.'),
|
|
39
|
-
telemetry: RegionVisibility.optional().describe(
|
|
40
|
-
"The top bar's runtime telemetry cluster: the frame-rate readout, its sparkline and the audio meter. The Profiler utility is the same information's other door.",
|
|
41
|
-
),
|
|
42
38
|
hierarchyTypeSuffix: RegionVisibility.optional().describe(
|
|
43
|
-
"The `·TypeName` a component-instance row prints after its name in the hierarchy. Hidden leaves the row its name alone
|
|
39
|
+
"The `·TypeName` a component-instance row prints after its name in the hierarchy. Hidden leaves the row its name alone; the type stays reachable through the row's own tooltip and the inspector.",
|
|
44
40
|
),
|
|
45
41
|
hierarchyInstanceRule: RegionVisibility.optional().describe(
|
|
46
|
-
"The dotted rule a component-instance row draws under its name in the hierarchy. Hidden leaves the name unmarked
|
|
42
|
+
"The dotted rule a component-instance row draws under its name in the hierarchy. Hidden leaves the name unmarked; the fact stays reachable through the row's own tooltip, its source actions and the inspector.",
|
|
47
43
|
),
|
|
48
44
|
hierarchyRestrictions: z
|
|
49
45
|
.enum(['select+viewport', 'viewport+render'])
|
|
50
46
|
.optional()
|
|
51
47
|
.describe(
|
|
52
|
-
"Which restriction columns a hierarchy row carries at its right edge:
|
|
48
|
+
"Which restriction columns a hierarchy row carries at its right edge: the selection lock beside the eye, or the eye in its own column with the render column reserved and blank, the viewport having one visibility flag for viewport and render alike.",
|
|
53
49
|
),
|
|
54
50
|
})
|
|
55
51
|
.strict()
|
|
@@ -61,26 +57,20 @@ export const EditorSettingsSchema = z
|
|
|
61
57
|
.string()
|
|
62
58
|
.optional()
|
|
63
59
|
.describe('JSON Schema pointer for editor autocomplete; ignored by the editor.'),
|
|
60
|
+
style: z
|
|
61
|
+
.string()
|
|
62
|
+
.optional()
|
|
63
|
+
.describe(
|
|
64
|
+
'Editor style id (`classic`, `glass`, or one a package carries): its material, icon set and type. Choosing one also applies the colour theme it was drawn with.',
|
|
65
|
+
),
|
|
64
66
|
appearance: z
|
|
65
67
|
.object({
|
|
66
|
-
palette: z
|
|
67
|
-
.string()
|
|
68
|
-
.optional()
|
|
69
|
-
.describe('Editor palette id — a built-in or a custom theme document.'),
|
|
70
|
-
material: z
|
|
71
|
-
.string()
|
|
72
|
-
.optional()
|
|
73
|
-
.describe('Editor material id (`classic`, `glass`, or one a style bundle carries).'),
|
|
74
|
-
icons: z
|
|
75
|
-
.string()
|
|
76
|
-
.optional()
|
|
77
|
-
.describe('Editor icon set id (`default`, or one a style bundle carries).'),
|
|
78
68
|
regions: ChromeRegionsSettingsSchema.optional(),
|
|
79
69
|
})
|
|
80
70
|
.strict()
|
|
81
71
|
.optional()
|
|
82
72
|
.describe('How the editor chrome looks.'),
|
|
83
|
-
keymap: z.string().optional().describe('Active keymap preset id (`volter`,
|
|
73
|
+
keymap: z.string().optional().describe('Active keymap preset id (`volter`, or a contributed preset).'),
|
|
84
74
|
play: z
|
|
85
75
|
.object({
|
|
86
76
|
keepPanelsVisible: z
|
|
@@ -93,24 +83,11 @@ export const EditorSettingsSchema = z
|
|
|
93
83
|
.strict()
|
|
94
84
|
.optional()
|
|
95
85
|
.describe('How the editor presents Play mode.'),
|
|
96
|
-
devicePreview: z
|
|
97
|
-
.object({
|
|
98
|
-
preset: z.string().optional().describe('Device preview frame preset id.'),
|
|
99
|
-
touch: z
|
|
100
|
-
.boolean()
|
|
101
|
-
.nullable()
|
|
102
|
-
.optional()
|
|
103
|
-
.describe('Touch emulation override; null follows the preset.'),
|
|
104
|
-
})
|
|
105
|
-
.strict()
|
|
106
|
-
.optional()
|
|
107
|
-
.describe('The device frame the Game document previews in.'),
|
|
108
86
|
})
|
|
109
87
|
.strict()
|
|
110
88
|
.describe('Editor settings — the user layer and the project layer share this shape.');
|
|
111
89
|
|
|
112
90
|
export type EditorSettings = z.infer<typeof EditorSettingsSchema>;
|
|
113
|
-
export type ChromeRegionsSettings = z.infer<typeof ChromeRegionsSettingsSchema>;
|
|
114
91
|
|
|
115
92
|
/** Which layer a file is; the file paths are the server's. */
|
|
116
93
|
export type SettingsLayer = 'user' | 'project';
|
|
@@ -149,3 +126,37 @@ export function parseEditorSettings(
|
|
|
149
126
|
),
|
|
150
127
|
};
|
|
151
128
|
}
|
|
129
|
+
|
|
130
|
+
/** A settings FILE's text, read: `null` (no file) is the empty document; text that is not JSON or
|
|
131
|
+
* not a valid document carries its issues and no settings. */
|
|
132
|
+
export function parseEditorSettingsText(
|
|
133
|
+
text: string | null,
|
|
134
|
+
): { settings: EditorSettings; issues: [] } | { settings: null; issues: string[] } {
|
|
135
|
+
if (text === null) return { settings: {}, issues: [] };
|
|
136
|
+
let raw: unknown;
|
|
137
|
+
try {
|
|
138
|
+
raw = JSON.parse(text);
|
|
139
|
+
} catch (cause) {
|
|
140
|
+
return { settings: null, issues: [`not JSON: ${(cause as Error).message}`] };
|
|
141
|
+
}
|
|
142
|
+
return parseEditorSettings(raw);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The refusal of a write over a settings file that is invalid on disk, or `null` when the write
|
|
147
|
+
* may go ahead. Every door that writes a settings layer answers with this one (HTTP 409): an
|
|
148
|
+
* invalid file is the person's to fix, never the editor's to replace, because writing the
|
|
149
|
+
* session's document over it would discard everything else the file holds.
|
|
150
|
+
*/
|
|
151
|
+
export function settingsWriteRefusal(
|
|
152
|
+
layer: 'user' | 'project',
|
|
153
|
+
path: string,
|
|
154
|
+
onDiskIssues: readonly string[],
|
|
155
|
+
): { error: string; issues: readonly string[]; path: string } | null {
|
|
156
|
+
if (onDiskIssues.length === 0) return null;
|
|
157
|
+
return {
|
|
158
|
+
error: `${path} is invalid (${onDiskIssues.join('; ')}); fix it before the editor writes ${layer} settings again.`,
|
|
159
|
+
issues: onDiskIssues,
|
|
160
|
+
path,
|
|
161
|
+
};
|
|
162
|
+
}
|
package/schemas/engine-api.json
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$comment": "AUTO-GENERATED by scripts/generate-engine-manifest.ts — do not edit manually. Run 'npm run generate-engine-manifest'.",
|
|
3
|
-
"phases": [
|
|
4
|
-
{
|
|
5
|
-
"name": "input",
|
|
6
|
-
"description": "Sample input devices (keyboard, mouse, gamepad) at the top of the frame."
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
"name": "prePhysics",
|
|
10
|
-
"description": "Apply forces/intents to rigid bodies before the physics step."
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"name": "physics",
|
|
14
|
-
"description": "Step the Rapier physics world (fixed timestep)."
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"name": "postPhysics",
|
|
18
|
-
"description": "Read physics results back; sync transforms from bodies to Object3D."
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"name": "gameLogic",
|
|
22
|
-
"description": "General gameplay behavior."
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"name": "animation",
|
|
26
|
-
"description": "Advance animation graphs / mixers."
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"name": "preRender",
|
|
30
|
-
"description": "Final per-frame fixups (cameras, HUD state) before drawing."
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"name": "render",
|
|
34
|
-
"description": "Draw the frame."
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"phaseOrder": [
|
|
38
|
-
"input",
|
|
39
|
-
"prePhysics",
|
|
40
|
-
"physics",
|
|
41
|
-
"postPhysics",
|
|
42
|
-
"gameLogic",
|
|
43
|
-
"animation",
|
|
44
|
-
"preRender",
|
|
45
|
-
"render"
|
|
46
|
-
],
|
|
47
|
-
"phaseConstants": {
|
|
48
|
-
"INPUT": "input",
|
|
49
|
-
"PRE_PHYSICS": "prePhysics",
|
|
50
|
-
"PHYSICS": "physics",
|
|
51
|
-
"POST_PHYSICS": "postPhysics",
|
|
52
|
-
"GAME_LOGIC": "gameLogic",
|
|
53
|
-
"ANIMATION": "animation",
|
|
54
|
-
"PRE_RENDER": "preRender",
|
|
55
|
-
"RENDER": "render"
|
|
56
|
-
}
|
|
57
|
-
}
|
package/schemas/engine-api.md
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<!-- AUTO-GENERATED by scripts/generate-engine-manifest.ts — do not edit manually. -->
|
|
2
|
-
<!-- Run 'npm run generate-engine-manifest' to regenerate. -->
|
|
3
|
-
|
|
4
|
-
# Engine API Manifest
|
|
5
|
-
|
|
6
|
-
The schema-as-source-of-truth artifact for the engine's imperative surface — generated from the actual code so docs can never drift (see ROADMAP P0.3 / P2.9).
|
|
7
|
-
|
|
8
|
-
## System Phases
|
|
9
|
-
|
|
10
|
-
Each frame, systems run in this exact order (from `PHASE_ORDER` in `packages/project/src/core/system-phase.ts`):
|
|
11
|
-
|
|
12
|
-
| # | Phase | Constant | Description |
|
|
13
|
-
| - | ----- | -------- | ----------- |
|
|
14
|
-
| 1 | `input` | `SystemPhase.INPUT` | Sample input devices (keyboard, mouse, gamepad) at the top of the frame. |
|
|
15
|
-
| 2 | `prePhysics` | `SystemPhase.PRE_PHYSICS` | Apply forces/intents to rigid bodies before the physics step. |
|
|
16
|
-
| 3 | `physics` | `SystemPhase.PHYSICS` | Step the Rapier physics world (fixed timestep). |
|
|
17
|
-
| 4 | `postPhysics` | `SystemPhase.POST_PHYSICS` | Read physics results back; sync transforms from bodies to Object3D. |
|
|
18
|
-
| 5 | `gameLogic` | `SystemPhase.GAME_LOGIC` | General gameplay behavior. |
|
|
19
|
-
| 6 | `animation` | `SystemPhase.ANIMATION` | Advance animation graphs / mixers. |
|
|
20
|
-
| 7 | `preRender` | `SystemPhase.PRE_RENDER` | Final per-frame fixups (cameras, HUD state) before drawing. |
|
|
21
|
-
| 8 | `render` | `SystemPhase.RENDER` | Draw the frame. |
|
|
22
|
-
|