@triscope/core 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/dist/compose.d.ts +11 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +152 -0
- package/dist/compose.js.map +1 -0
- package/dist/editor.d.ts +14 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +131 -0
- package/dist/editor.js.map +1 -0
- package/dist/harness.d.ts +199 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +1027 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +94 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +434 -0
- package/dist/inspect.js.map +1 -0
- package/dist/knob-utils.d.ts +22 -0
- package/dist/knob-utils.d.ts.map +1 -0
- package/dist/knob-utils.js +51 -0
- package/dist/knob-utils.js.map +1 -0
- package/dist/lab/css.d.ts +11 -0
- package/dist/lab/css.d.ts.map +1 -0
- package/dist/lab/css.js +57 -0
- package/dist/lab/css.js.map +1 -0
- package/dist/lab/dom.d.ts +13 -0
- package/dist/lab/dom.d.ts.map +1 -0
- package/dist/lab/dom.js +76 -0
- package/dist/lab/dom.js.map +1 -0
- package/dist/motion-probe.d.ts +47 -0
- package/dist/motion-probe.d.ts.map +1 -0
- package/dist/motion-probe.js +122 -0
- package/dist/motion-probe.js.map +1 -0
- package/dist/probe-utils.d.ts +14 -0
- package/dist/probe-utils.d.ts.map +1 -0
- package/dist/probe-utils.js +18 -0
- package/dist/probe-utils.js.map +1 -0
- package/dist/scene-cameras.d.ts +6 -0
- package/dist/scene-cameras.d.ts.map +1 -0
- package/dist/scene-cameras.js +20 -0
- package/dist/scene-cameras.js.map +1 -0
- package/dist/scene-delta.d.ts +21 -0
- package/dist/scene-delta.d.ts.map +1 -0
- package/dist/scene-delta.js +57 -0
- package/dist/scene-delta.js.map +1 -0
- package/dist/scene-introspect.d.ts +78 -0
- package/dist/scene-introspect.d.ts.map +1 -0
- package/dist/scene-introspect.js +164 -0
- package/dist/scene-introspect.js.map +1 -0
- package/dist/scene-registry.d.ts +36 -0
- package/dist/scene-registry.d.ts.map +1 -0
- package/dist/scene-registry.js +64 -0
- package/dist/scene-registry.js.map +1 -0
- package/dist/scene-view.d.ts +52 -0
- package/dist/scene-view.d.ts.map +1 -0
- package/dist/scene-view.js +171 -0
- package/dist/scene-view.js.map +1 -0
- package/dist/source-tag.d.ts +34 -0
- package/dist/source-tag.d.ts.map +1 -0
- package/dist/source-tag.js +120 -0
- package/dist/source-tag.js.map +1 -0
- package/dist/telemetry.d.ts +53 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +302 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +142 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/uniform-access.d.ts +32 -0
- package/dist/uniform-access.d.ts.map +1 -0
- package/dist/uniform-access.js +144 -0
- package/dist/uniform-access.js.map +1 -0
- package/dist/validate.d.ts +2 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +81 -0
- package/dist/validate.js.map +1 -0
- package/dist/vite.d.ts +3 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +4 -0
- package/dist/vite.js.map +1 -0
- package/dist/warnings.d.ts +24 -0
- package/dist/warnings.d.ts.map +1 -0
- package/dist/warnings.js +26 -0
- package/dist/warnings.js.map +1 -0
- package/package.json +60 -0
- package/src/compose.ts +164 -0
- package/src/editor.ts +138 -0
- package/src/harness.ts +1263 -0
- package/src/index.ts +58 -0
- package/src/inspect.ts +498 -0
- package/src/knob-utils.ts +60 -0
- package/src/lab/css.ts +56 -0
- package/src/lab/dom.ts +88 -0
- package/src/motion-probe.ts +135 -0
- package/src/probe-utils.ts +17 -0
- package/src/scene-cameras.ts +33 -0
- package/src/scene-delta.ts +69 -0
- package/src/scene-introspect.ts +230 -0
- package/src/scene-registry.ts +103 -0
- package/src/scene-view.ts +204 -0
- package/src/source-tag.ts +139 -0
- package/src/telemetry.ts +337 -0
- package/src/three-webgpu-shim.d.ts +130 -0
- package/src/types.ts +121 -0
- package/src/uniform-access.ts +152 -0
- package/src/validate.ts +82 -0
- package/src/vite.ts +5 -0
- package/src/warnings.ts +41 -0
package/src/editor.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { Knob } from './types.js';
|
|
2
|
+
|
|
3
|
+
type KnobChange = (key: string, value: number | string | boolean) => void;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Render a minimal slider/color/checkbox editor for the element's knobs into the given DOM container.
|
|
7
|
+
* Returns a `setValue(key, value)` function so external sources (MCP) can keep the UI in sync.
|
|
8
|
+
*
|
|
9
|
+
* Stays deliberately bare-bones — the styling is the host page's job.
|
|
10
|
+
*/
|
|
11
|
+
export function mountEditor(
|
|
12
|
+
container: HTMLElement,
|
|
13
|
+
knobs: Record<string, Knob>,
|
|
14
|
+
initial: Record<string, number | string | boolean>,
|
|
15
|
+
onChange: KnobChange,
|
|
16
|
+
): { setValue: (key: string, value: number | string | boolean) => void; destroy: () => void } {
|
|
17
|
+
container.replaceChildren();
|
|
18
|
+
container.classList.add('triscope-editor');
|
|
19
|
+
|
|
20
|
+
const inputs = new Map<string, HTMLInputElement>();
|
|
21
|
+
const values = new Map<string, HTMLOutputElement>();
|
|
22
|
+
|
|
23
|
+
for (const [key, spec] of Object.entries(knobs)) {
|
|
24
|
+
const row = document.createElement('div');
|
|
25
|
+
row.className = 'triscope-editor__row';
|
|
26
|
+
row.dataset.knobKey = key;
|
|
27
|
+
|
|
28
|
+
const label = document.createElement('label');
|
|
29
|
+
label.textContent = spec.label ?? key;
|
|
30
|
+
label.title = key;
|
|
31
|
+
row.appendChild(label);
|
|
32
|
+
|
|
33
|
+
const input = document.createElement('input');
|
|
34
|
+
input.dataset.knobKey = key;
|
|
35
|
+
|
|
36
|
+
const out = document.createElement('output');
|
|
37
|
+
|
|
38
|
+
if (spec.type === 'number' || spec.type === 'int') {
|
|
39
|
+
input.type = 'range';
|
|
40
|
+
input.min = String(spec.min);
|
|
41
|
+
input.max = String(spec.max);
|
|
42
|
+
input.step = String(spec.type === 'int' ? 1 : (spec.step ?? (spec.max - spec.min) / 200));
|
|
43
|
+
const v = typeof initial[key] === 'number' ? Number(initial[key]) : spec.default;
|
|
44
|
+
input.value = String(v);
|
|
45
|
+
out.textContent = formatNumber(v, spec.type);
|
|
46
|
+
input.oninput = () => {
|
|
47
|
+
const num = spec.type === 'int' ? parseInt(input.value, 10) : parseFloat(input.value);
|
|
48
|
+
out.textContent = formatNumber(num, spec.type);
|
|
49
|
+
onChange(key, num);
|
|
50
|
+
};
|
|
51
|
+
} else if (spec.type === 'color') {
|
|
52
|
+
input.type = 'color';
|
|
53
|
+
const v = typeof initial[key] === 'string' ? String(initial[key]) : spec.default;
|
|
54
|
+
input.value = v;
|
|
55
|
+
out.textContent = v;
|
|
56
|
+
input.oninput = () => {
|
|
57
|
+
out.textContent = input.value;
|
|
58
|
+
onChange(key, input.value);
|
|
59
|
+
};
|
|
60
|
+
} else if (spec.type === 'boolean') {
|
|
61
|
+
input.type = 'checkbox';
|
|
62
|
+
const v = typeof initial[key] === 'boolean' ? Boolean(initial[key]) : spec.default;
|
|
63
|
+
input.checked = v;
|
|
64
|
+
out.textContent = v ? 'on' : 'off';
|
|
65
|
+
input.onchange = () => {
|
|
66
|
+
out.textContent = input.checked ? 'on' : 'off';
|
|
67
|
+
onChange(key, input.checked);
|
|
68
|
+
};
|
|
69
|
+
} else if (spec.type === 'trigger') {
|
|
70
|
+
// Trigger renders as a button. Each click fires onChange(true) — the
|
|
71
|
+
// value carries no state, the act itself is the signal.
|
|
72
|
+
const btn = document.createElement('button');
|
|
73
|
+
btn.type = 'button';
|
|
74
|
+
btn.textContent = spec.label ?? key;
|
|
75
|
+
btn.dataset.knobKey = key;
|
|
76
|
+
btn.onclick = () => {
|
|
77
|
+
out.textContent = 'fired';
|
|
78
|
+
onChange(key, true);
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
out.textContent = '–';
|
|
81
|
+
}, 400);
|
|
82
|
+
};
|
|
83
|
+
out.textContent = '–';
|
|
84
|
+
row.appendChild(btn);
|
|
85
|
+
row.appendChild(out);
|
|
86
|
+
container.appendChild(row);
|
|
87
|
+
values.set(key, out);
|
|
88
|
+
// No persistent input element — leave inputs.set unset; setValue from
|
|
89
|
+
// external pulse will still flash the output.
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
row.appendChild(input);
|
|
94
|
+
row.appendChild(out);
|
|
95
|
+
container.appendChild(row);
|
|
96
|
+
inputs.set(key, input);
|
|
97
|
+
values.set(key, out);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
setValue(key, value) {
|
|
102
|
+
const out = values.get(key);
|
|
103
|
+
const spec = knobs[key];
|
|
104
|
+
if (!out || !spec) return;
|
|
105
|
+
if (spec.type === 'trigger') {
|
|
106
|
+
// External pulse — flash the output to confirm receipt; no input
|
|
107
|
+
// element to sync because trigger has no persistent state.
|
|
108
|
+
out.textContent = 'fired';
|
|
109
|
+
setTimeout(() => {
|
|
110
|
+
out.textContent = '–';
|
|
111
|
+
}, 400);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const inp = inputs.get(key);
|
|
115
|
+
if (!inp) return;
|
|
116
|
+
if (spec.type === 'number' || spec.type === 'int') {
|
|
117
|
+
inp.value = String(value);
|
|
118
|
+
out.textContent = formatNumber(Number(value), spec.type);
|
|
119
|
+
} else if (spec.type === 'color') {
|
|
120
|
+
inp.value = String(value);
|
|
121
|
+
out.textContent = String(value);
|
|
122
|
+
} else if (spec.type === 'boolean') {
|
|
123
|
+
inp.checked = Boolean(value);
|
|
124
|
+
out.textContent = inp.checked ? 'on' : 'off';
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
destroy() {
|
|
128
|
+
container.replaceChildren();
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function formatNumber(v: number, type: 'number' | 'int'): string {
|
|
134
|
+
if (type === 'int') return String(Math.round(v));
|
|
135
|
+
if (Math.abs(v) >= 100) return v.toFixed(1);
|
|
136
|
+
if (Math.abs(v) >= 1) return v.toFixed(2);
|
|
137
|
+
return v.toFixed(3);
|
|
138
|
+
}
|