@descix/frqtl-node 0.0.0-stage → 0.6.0-p0.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/CLAUDE.md +87 -0
- package/LICENSE.md +664 -0
- package/README.md +84 -2
- package/dist/dist-manifest.json +218 -0
- package/dist/eyes/index.js +109 -0
- package/dist/fat/pkg-node/egpt_wasm.js +1277 -0
- package/dist/fat/pkg-node/egpt_wasm_bg.wasm +0 -0
- package/dist/fat/pkg-node/package.json +12 -0
- package/dist/frqtl/assets/vendor/chroma.mjs +64 -0
- package/dist/frqtl/compat/boot-node.js +34 -0
- package/dist/frqtl/compat/engine.js +127 -0
- package/dist/frqtl/compat/package-root.js +24 -0
- package/dist/frqtl/compat/providers/wasm-engine.js +2499 -0
- package/dist/frqtl/compat/providers/wasm-load-browser.js +134 -0
- package/dist/frqtl/compat/providers/wasm-load-node.js +59 -0
- package/dist/frqtl/compat/renderer/FieldBuilder.js +145 -0
- package/dist/frqtl/compat/renderer/Filters.js +163 -0
- package/dist/frqtl/compat/renderer/RenderFamily.js +84 -0
- package/dist/frqtl/compat/renderer/RenderMesh.js +99 -0
- package/dist/frqtl/compat/renderer/RenderShape.js +154 -0
- package/dist/frqtl/compat/renderer/camera2d-geometry.js +183 -0
- package/dist/frqtl/compat/renderer/captureStill-common.js +258 -0
- package/dist/frqtl/compat/renderer/display-slot.js +96 -0
- package/dist/frqtl/compat/renderer/lo-drawn-center.js +231 -0
- package/dist/frqtl/compat/renderer/orbit-bag.js +216 -0
- package/dist/frqtl/compat/renderer/providers/godrays-layer.js +213 -0
- package/dist/frqtl/compat/renderer/providers/index.js +22 -0
- package/dist/frqtl/compat/renderer/providers/p5-provider.js +861 -0
- package/dist/frqtl/compat/renderer/providers/three-camera-contract.js +160 -0
- package/dist/frqtl/compat/renderer/providers/three-camera-geometry.js +571 -0
- package/dist/frqtl/compat/renderer/providers/three-provider.js +2470 -0
- package/dist/frqtl/compat/renderer/renderCapabilities-common.js +186 -0
- package/dist/frqtl/compat/renderer/renderer-provider-contract.js +238 -0
- package/dist/frqtl/compat/renderer/unprojectStill.js +172 -0
- package/dist/frqtl/compat/vendor.js +196 -0
- package/dist/frqtl/node-entry.js +17 -0
- package/dist/frqtl/objects/FrqtlApp.js +2920 -0
- package/dist/frqtl/objects/ObjectFactory.js +296 -0
- package/dist/frqtl/objects/RecipeContext.js +322 -0
- package/dist/frqtl/objects/collectors/DataCollector.js +116 -0
- package/dist/frqtl/objects/constants/WallBehaviors.js +178 -0
- package/dist/frqtl/objects/geometry/SlabFace.js +258 -0
- package/dist/frqtl/objects/instruments/capture-host.js +453 -0
- package/dist/frqtl/objects/instruments/capture.js +710 -0
- package/dist/frqtl/objects/instruments/hosted-eyes.js +984 -0
- package/dist/frqtl/objects/kinds-entry.js +14 -0
- package/dist/frqtl/objects/kinds.js +190 -0
- package/dist/frqtl/objects/objects/Box.js +273 -0
- package/dist/frqtl/objects/objects/Bullet.js +155 -0
- package/dist/frqtl/objects/objects/CircuitGate.js +380 -0
- package/dist/frqtl/objects/objects/CircuitProbe.js +214 -0
- package/dist/frqtl/objects/objects/DirectedTunnel.js +411 -0
- package/dist/frqtl/objects/objects/EgptFractal.js +164 -0
- package/dist/frqtl/objects/objects/LightSource.js +351 -0
- package/dist/frqtl/objects/objects/QuantumEmitter.js +760 -0
- package/dist/frqtl/objects/objects/Tube.js +471 -0
- package/dist/frqtl/objects/objects/absorbRadiation.js +309 -0
- package/dist/frqtl/objects/objects/actionCompiler.js +1747 -0
- package/dist/frqtl/objects/objects/controlAction.js +89 -0
- package/dist/frqtl/objects/objects/controlBind.js +278 -0
- package/dist/frqtl/objects/objects/directedRedirectProgram.js +120 -0
- package/dist/frqtl/objects/objects/emitterProgram.js +209 -0
- package/dist/frqtl/objects/objects/frqtl-control-slider.js +197 -0
- package/dist/frqtl/objects/objects/frqtl-control-sync.js +272 -0
- package/dist/frqtl/objects/objects/frqtl-control-widgets.js +219 -0
- package/dist/frqtl/objects/objects/frqtl-control-write-queue.js +174 -0
- package/dist/frqtl/objects/objects/makeControlsForObject.js +820 -0
- package/dist/frqtl/objects/objects/makeControlsForRenderSurface.js +161 -0
- package/dist/frqtl/objects/objects/slitLinerScatter.js +261 -0
- package/dist/frqtl/objects/objects/sustainedSource.js +298 -0
- package/dist/frqtl/objects/objects/tagger.js +228 -0
- package/dist/frqtl/objects/schema/engine-scopes.js +468 -0
- package/dist/frqtl/objects/schema/index.js +256 -0
- package/dist/frqtl/objects/schema/scopes.js +457 -0
- package/dist/frqtl/objects/schema/validate-descriptor.js +49 -0
- package/dist/frqtl/objects/schema/valueNormalizer.js +366 -0
- package/dist/frqtl/objects/setup/_collisionMatrixLanes.js +66 -0
- package/dist/frqtl/objects/setup/_setupOptions.js +118 -0
- package/dist/frqtl/objects/setup/_worldInit.js +162 -0
- package/dist/frqtl/objects/setup/setupBlackbodySubstrate.js +242 -0
- package/dist/frqtl/objects/setup/setupCircuitBasic.js +447 -0
- package/dist/frqtl/objects/setup/setupCollisionMatrix.js +188 -0
- package/dist/frqtl/objects/setup/setupConeEmitter3D.js +250 -0
- package/dist/frqtl/objects/setup/setupDoubleSlit.js +326 -0
- package/dist/frqtl/objects/setup/setupDoubleSlit_Laser.js +229 -0
- package/dist/frqtl/objects/setup/setupEmpty.js +59 -0
- package/dist/frqtl/objects/setup/setupFxSmoke.js +209 -0
- package/dist/frqtl/objects/setup/setupG1Race.js +80 -0
- package/dist/frqtl/objects/setup/setupG2Sweep.js +89 -0
- package/dist/frqtl/objects/setup/setupG3Collide.js +177 -0
- package/dist/frqtl/objects/setup/setupLightSourceLab.js +277 -0
- package/dist/frqtl/objects/setup/setupOscillator.js +68 -0
- package/dist/frqtl/objects/setup/setupParticleWalk.js +93 -0
- package/dist/frqtl/objects/setup/setupParticleWalk3D.js +133 -0
- package/dist/frqtl/objects/setup/setupSphereEmitter3D.js +1258 -0
- package/dist/frqtl/objects/setup/setupTraceCircuit.js +239 -0
- package/dist/frqtl/objects/setup/setupTunnelLab.js +240 -0
- package/dist/frqtl/objects/setup/setupTunnelPointExit.js +306 -0
- package/dist/frqtl/objects/setup/setupWaveInterference.js +177 -0
- package/dist/frqtl/objects/v1-replacements.js +29 -0
- package/dist/frqtl/package-core.js +23 -0
- package/dist/frqtl/parts/CameraControls.js +643 -0
- package/dist/frqtl/parts/CameraPath.js +575 -0
- package/dist/frqtl/parts/CollisionActions.js +34 -0
- package/dist/frqtl/parts/CollisionTypes.js +30 -0
- package/dist/frqtl/parts/DetectorWall.js +496 -0
- package/dist/frqtl/parts/FrqtlControlOverlay.js +227 -0
- package/dist/frqtl/parts/FrqtlControlsPanel.js +415 -0
- package/dist/frqtl/parts/FrqtlVision.js +818 -0
- package/dist/frqtl/parts/GraphingDetectorWall.js +489 -0
- package/dist/frqtl/parts/LargeObject.js +405 -0
- package/dist/frqtl/parts/LightColor.js +255 -0
- package/dist/frqtl/parts/LiveChart.js +285 -0
- package/dist/frqtl/parts/LogicGate.js +717 -0
- package/dist/frqtl/parts/OvenBox.js +611 -0
- package/dist/frqtl/parts/PointSource.js +762 -0
- package/dist/frqtl/parts/Rectangle.js +200 -0
- package/dist/frqtl/parts/SlitLightSource.js +234 -0
- package/dist/frqtl/parts/SlitScreen.js +628 -0
- package/dist/frqtl/parts/SphereEmitter.js +946 -0
- package/dist/frqtl/parts/Trace.js +508 -0
- package/dist/frqtl/parts/Tunnel.js +1057 -0
- package/dist/frqtl/parts/Wall.js +1211 -0
- package/dist/frqtl/parts/index.js +33 -0
- package/dist/frqtl/scenes/absorbing-wall-3d.js +33 -0
- package/dist/frqtl/scenes/absorbing-wall.js +32 -0
- package/dist/frqtl/scenes/atomic-model.js +88 -0
- package/dist/frqtl/scenes/big-bang.js +46 -0
- package/dist/frqtl/scenes/blackbody.js +81 -0
- package/dist/frqtl/scenes/circuit-sat.js +127 -0
- package/dist/frqtl/scenes/collision-matrix-3d.js +107 -0
- package/dist/frqtl/scenes/counting-wall-3d.js +36 -0
- package/dist/frqtl/scenes/counting-wall.js +38 -0
- package/dist/frqtl/scenes/double-slit.js +31 -0
- package/dist/frqtl/scenes/dse-one-emitter.js +196 -0
- package/dist/frqtl/scenes/dse-one-slit.js +114 -0
- package/dist/frqtl/scenes/dse-photoelectric.js +70 -0
- package/dist/frqtl/scenes/dse-tunnel-rebuild.js +243 -0
- package/dist/frqtl/scenes/dse-two-emitters.js +196 -0
- package/dist/frqtl/scenes/dse-two-slits.js +132 -0
- package/dist/frqtl/scenes/empty.js +14 -0
- package/dist/frqtl/scenes/laser-buildup.js +49 -0
- package/dist/frqtl/scenes/mirror-3d.js +56 -0
- package/dist/frqtl/scenes/mirror-route.js +140 -0
- package/dist/frqtl/scenes/mirror.js +38 -0
- package/dist/frqtl/scenes/omni-3d.js +27 -0
- package/dist/frqtl/scenes/omni-source.js +22 -0
- package/dist/frqtl/scenes/self-interference.js +39 -0
- package/dist/frqtl/scenes/smoking-gun.js +122 -0
- package/dist/frqtl/scenes/straight-walk.js +22 -0
- package/dist/frqtl/scenes/sun.js +39 -0
- package/dist/frqtl/scenes/two-source.js +37 -0
- package/dist/frqtl/scenes/wave.js +26 -0
- package/dist/shim/bundle/frqnb.js +112 -0
- package/dist/shim/bundle/index.js +121 -0
- package/dist/shim/bundle/indexHtml.js +107 -0
- package/dist/shim/bundle/manifest.js +95 -0
- package/dist/shim/bundle/zip.js +243 -0
- package/dist/shim/bus.js +67 -0
- package/dist/shim/controls/index.js +627 -0
- package/dist/shim/controls/registry.js +274 -0
- package/dist/shim/engine/artifact-shell.js +211 -0
- package/dist/shim/engine/boot-phases.js +44 -0
- package/dist/shim/engine/engine-stack-boot.js +59 -0
- package/dist/shim/engine/router.js +690 -0
- package/dist/shim/experiment-frame/index.js +296 -0
- package/dist/shim/expr/ast-schema.js +369 -0
- package/dist/shim/field-descriptor/index.js +325 -0
- package/dist/shim/frame-data/index.js +224 -0
- package/dist/shim/index.js +67 -0
- package/dist/shim/notebook/canvas-guard.js +82 -0
- package/dist/shim/notebook/catalog.js +35 -0
- package/dist/shim/notebook/format.js +736 -0
- package/dist/shim/notebook/frqtl-setups-importmap.js +81 -0
- package/dist/shim/notebook/kernel.js +671 -0
- package/dist/shim/notebook/knob.js +150 -0
- package/dist/shim/notebook/module-resolver.js +260 -0
- package/dist/shim/notebook/notebook-knobs.js +65 -0
- package/dist/shim/notebook/produced-bindings.js +67 -0
- package/dist/shim/notebook/realm-registry.js +121 -0
- package/dist/shim/notebook/realm-transport.js +73 -0
- package/dist/shim/notebook/setup-builder.js +507 -0
- package/dist/shim/notebook/store.js +159 -0
- package/dist/shim/notebook/vendor-importmap.js +134 -0
- package/dist/shim/notebook/view-builder.js +189 -0
- package/dist/shim/notebook/view-ctx.js +100 -0
- package/dist/shim/notebook/view-handle.js +202 -0
- package/dist/shim/notebook/warmup.js +102 -0
- package/dist/shim/package.json +4 -0
- package/dist/shim/page-params/index.js +213 -0
- package/dist/shim/project/identity.js +112 -0
- package/dist/shim/project/index.js +19 -0
- package/dist/shim/project/link.js +402 -0
- package/dist/shim/project/node-specifier-hook.mjs +35 -0
- package/dist/shim/project/register-node.mjs +17 -0
- package/dist/shim/project/specifiers.js +106 -0
- package/dist/shim/registry/copy-gate.js +110 -0
- package/dist/shim/registry/exhibits.js +455 -0
- package/dist/shim/registry/experiments.js +215 -0
- package/dist/shim/registry/index.js +19 -0
- package/dist/shim/registry/scene-source.js +157 -0
- package/dist/shim/registry/walkthrough.js +804 -0
- package/dist/shim/render/capture-envelope.js +279 -0
- package/dist/shim/render/heat-colormap.js +92 -0
- package/dist/shim/render/render-stages.js +855 -0
- package/dist/shim/render/sun-look.js +33 -0
- package/dist/shim/render-state/apply.js +262 -0
- package/dist/shim/render-state/index.js +74 -0
- package/dist/shim/rpc/index.js +207 -0
- package/dist/shim/runtime/index.js +1023 -0
- package/dist/shim/storage/boot.js +69 -0
- package/dist/shim/storage/index.js +169 -0
- package/dist/shim/storage/local-storage-provider.js +230 -0
- package/dist/shim/storage/make-namespace-store.js +132 -0
- package/dist/shim/storage/modules.js +249 -0
- package/dist/shim/storage/projects.js +150 -0
- package/llms.txt +12 -0
- package/package.json +63 -4
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
/* Copyright 2023-2026 by Essam Abadir */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* scopes.js — the schema's SCOPE descriptor rows: the engine and render scopes an inspector or an
|
|
5
|
+
* op-program addresses, NOT placeable kinds. They have no class, no builder and no defaults; they
|
|
6
|
+
* are never constructed, registered or forked.
|
|
7
|
+
*
|
|
8
|
+
* SCOPE_DESCRIPTORS { particle, backdrop, Frame, Universe, Dimension, LargeObject }
|
|
9
|
+
* shapeValuesMap() the render.shape constraint map (frame-data owns the list)
|
|
10
|
+
*
|
|
11
|
+
* ObjectSchema.get(name) reads the kinds registry first, then these rows; objects/kinds.js
|
|
12
|
+
* registerKind REFUSES a class whose name is a scope row's, so one name never has two owners — with
|
|
13
|
+
* ONE exception: a kind whose descriptor IS that row's object (LargeObject: the part registers the
|
|
14
|
+
* engine door's row by reference, so the name still has one owner, this file).
|
|
15
|
+
* Frame / Universe / Dimension are the engine-core accessor descriptors, owned by engine-scopes.js.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import * as EngineScopes from './engine-scopes.js';
|
|
19
|
+
import { validateDescriptor } from './validate-descriptor.js';
|
|
20
|
+
import * as ValueNormalizer from './valueNormalizer.js';
|
|
21
|
+
import * as FrameDataSchema from '../../../shim/frame-data/index.js';
|
|
22
|
+
import { CollisionTypes } from '../../parts/CollisionTypes.js';
|
|
23
|
+
import { CollisionActions } from '../../parts/CollisionActions.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The render-intent shape vocabulary as a constraint map (value → value), read from frame-data's
|
|
27
|
+
* RENDER_INTENT_VALUES['render.shape'] — the ONE owner of the shape list. Schema/index.js re-exports it.
|
|
28
|
+
* @returns {Object<string,string>}
|
|
29
|
+
*/
|
|
30
|
+
export function shapeValuesMap() {
|
|
31
|
+
var arr = FrameDataSchema.RENDER_INTENT_VALUES['render.shape'];
|
|
32
|
+
var m = {};
|
|
33
|
+
if (Array.isArray(arr)) { for (var i = 0; i < arr.length; i++) { m[arr[i]] = arr[i]; } }
|
|
34
|
+
return m;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* particle — A leaf frame (is_leaf=true) produced by engine emitters.
|
|
39
|
+
* Not directly constructable by the IDE; emitted by engine tick functions.
|
|
40
|
+
* Descriptor is for inspector display only (all fields are readonly).
|
|
41
|
+
*/
|
|
42
|
+
var ParticleDescriptor = {
|
|
43
|
+
kind: 'particle',
|
|
44
|
+
description: 'A leaf frame (is_leaf=true) — the fundamental quantum of the simulation. ' +
|
|
45
|
+
'Particles are not directly placeable; they are emitted by QuantumEmitter, PointSource, ' +
|
|
46
|
+
'and other emitter objects. Every "particle" IS a Frame: the Frame Axiom states there is ' +
|
|
47
|
+
'no separate particle class. Leaf frames have mass = capacity (engine invariant).',
|
|
48
|
+
fields: [
|
|
49
|
+
{
|
|
50
|
+
name: 'x',
|
|
51
|
+
type: 'readonly',
|
|
52
|
+
engineVisible: true,
|
|
53
|
+
description: 'Current X position (physics pixels)'
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'y',
|
|
57
|
+
type: 'readonly',
|
|
58
|
+
engineVisible: true,
|
|
59
|
+
description: 'Current Y position (physics pixels)'
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'vx',
|
|
63
|
+
type: 'readonly',
|
|
64
|
+
engineVisible: true,
|
|
65
|
+
description: 'Current X momentum (pixels/tick). Accumulates when the 1px/tick speed limit is exceeded.'
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'vy',
|
|
69
|
+
type: 'readonly',
|
|
70
|
+
engineVisible: true,
|
|
71
|
+
description: 'Current Y momentum (pixels/tick). Accumulates when the 1px/tick speed limit is exceeded.'
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'mass',
|
|
75
|
+
type: 'readonly',
|
|
76
|
+
engineVisible: true,
|
|
77
|
+
description: 'Pixel occupancy count (Frame Axiom: leaf mass = capacity). Mass drives wavelength: higher mass → shorter wavelength → higher frequency.'
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'wavelength',
|
|
81
|
+
type: 'readonly',
|
|
82
|
+
engineVisible: true,
|
|
83
|
+
description: 'floor(capacity/mass * WAVELENGTH_CONSTANT), minimum 4 (engine invariant 6). Controls the probabilistic coin-flip that creates wave behavior.'
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
};
|
|
87
|
+
var BackdropDescriptor = {
|
|
88
|
+
kind: 'backdrop',
|
|
89
|
+
description: 'A render-only background image or color fill. ' +
|
|
90
|
+
'Created as a LargeObject with NONE collision type and no actions, ' +
|
|
91
|
+
'so it is invisible to the physics engine. Use it for scene backgrounds, ' +
|
|
92
|
+
'lab diagrams, or any decoration that should never interact with particles.',
|
|
93
|
+
fields: [
|
|
94
|
+
{
|
|
95
|
+
name: 'rect',
|
|
96
|
+
type: 'rect',
|
|
97
|
+
engineVisible: false,
|
|
98
|
+
description: 'Bounding rectangle for the backdrop image or fill (render-only). Typically matches the full canvas rect.'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'visible',
|
|
102
|
+
type: 'boolean',
|
|
103
|
+
engineVisible: false,
|
|
104
|
+
description: 'Whether the backdrop is rendered (render-only). Toggling false hides the background.'
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'color',
|
|
108
|
+
type: 'rgb',
|
|
109
|
+
engineVisible: false,
|
|
110
|
+
description: 'Fallback fill color [r, g, b] used when no image is provided (render-only).'
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'alpha',
|
|
114
|
+
type: 'number',
|
|
115
|
+
constraint: { min: 0, max: 255, integer: true },
|
|
116
|
+
engineVisible: false,
|
|
117
|
+
widgetHint: 'slider',
|
|
118
|
+
description: 'Render opacity 0-255 (render-only)'
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* LargeObject — Engine-registered wall/boundary/detector: primitive 4 of THE_MINIMAL_SIM, so its
|
|
124
|
+
* descriptor is an ENGINE-DOOR scope row (the engine's updateObjectProperty(h, 'LargeObject', …)
|
|
125
|
+
* validates against it with no part imported). parts/LargeObject.js registers its kind with
|
|
126
|
+
* `descriptor:` set to THIS object, by reference.
|
|
127
|
+
* Constructor: LargeObject(universe, rect, collision_type, actions, name,
|
|
128
|
+
* reposition, observedDimensions, search_padding, color)
|
|
129
|
+
*/
|
|
130
|
+
var LargeObjectDescriptor = {
|
|
131
|
+
kind: 'LargeObject',
|
|
132
|
+
description: 'A rectangular engine-registered boundary object (wall, detector, barrier). ' +
|
|
133
|
+
'The engine evaluates particle collisions against every registered LargeObject each tick ' +
|
|
134
|
+
'and applies the configured collision_type + actions to matching particles.',
|
|
135
|
+
fields: [
|
|
136
|
+
{
|
|
137
|
+
name: 'rect',
|
|
138
|
+
type: 'rect',
|
|
139
|
+
engineVisible: true,
|
|
140
|
+
unit: 'px',
|
|
141
|
+
description: 'Bounding rectangle in physics pixels ' + ValueNormalizer.rectTupleText(4) + '. ' +
|
|
142
|
+
'FRQTL-MAINT (2026-07-01): may also carry explicit z/depth ' +
|
|
143
|
+
ValueNormalizer.rectTupleText(6) + ' — WASM-only, MIRRORS the engine\'s ' +
|
|
144
|
+
'Rectangle::from_top_left argument order. Omitting z/d ' +
|
|
145
|
+
'is back-compat: the engine defaults z=0, d=w (bit-identical to the ' +
|
|
146
|
+
'pre-fix hardcoded behavior — see #61).'
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
// ── SWEPT-OBB NARROW-PHASE region (circulation §2) ──────────────────────────
|
|
150
|
+
// The RESOLVED, convention-FREE collision region produced by the ONE
|
|
151
|
+
// SlabFace authority (lib/frqtl/objects/geometry/SlabFace.js) for a NON-
|
|
152
|
+
// cardinal (rotated) wall: { kind:'obb', theta, hw, hh, hz } — theta in
|
|
153
|
+
// RADIANS in the engine's own frame, NEVER the raw orientationDeg (storing
|
|
154
|
+
// orientationDeg here + re-deriving "90+" in Rust is the convention-drift
|
|
155
|
+
// bug the circulation rejects). null/absent = today's pure AABB path,
|
|
156
|
+
// BYTE-IDENTICAL (the sugar emits null at cardinals via SlabFace.isCardinal,
|
|
157
|
+
// so a present region is always non-cardinal). engineVisible:true — the
|
|
158
|
+
// engine's narrow-phase filter (universe.rs) consumes it directly (unlike
|
|
159
|
+
// collision_type/actions, which are sugar-compiled). internal:true — a
|
|
160
|
+
// compiled/derived engine field, never a designer Inspector control (same
|
|
161
|
+
// class as `program`). Throw-or-apply validation of the { kind, theta, hw,
|
|
162
|
+
// hh } shape lives at the ABI (egpt_wasm RegionJs::into_region); `poly` is
|
|
163
|
+
// reserved-but-rejected in v1. Written via updateObjectProperty(handle,
|
|
164
|
+
// 'LargeObject', 'region', regionOrNull) — the SAME live-push path `program`
|
|
165
|
+
// uses (register-time or on a live orientation edit). WASM-only surface
|
|
166
|
+
// (the frozen 2D JS fixture FAILS LOUD on a non-null region).
|
|
167
|
+
name: 'region',
|
|
168
|
+
type: 'object',
|
|
169
|
+
engineVisible: true,
|
|
170
|
+
internal: true,
|
|
171
|
+
description: 'SWEPT-OBB narrow-phase collision region (circulation §2): ' +
|
|
172
|
+
'{ kind:"obb", theta(radians), hw, hh, hz } produced by the SlabFace authority ' +
|
|
173
|
+
'for a rotated wall, or null (default) = the byte-identical AABB path. Convention-' +
|
|
174
|
+
'free geometry (theta in the engine frame, never raw orientationDeg). The engine ' +
|
|
175
|
+
'narrow-phase filters candidates by a SWEPT prev→now segment-vs-OBB test ahead of ' +
|
|
176
|
+
'BOTH the op-program trigger and the collided-frame collection, so a tilted mirror ' +
|
|
177
|
+
'collides AT its drawn face (not the AABB entry plane). WASM-only.'
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'collision_type',
|
|
181
|
+
type: 'enum',
|
|
182
|
+
constraint: { values: CollisionTypes },
|
|
183
|
+
// SUGAR-INPUT (G2/G4b): the engine has NO collision_type dispatch (G2 deleted it).
|
|
184
|
+
// collision_type is a declarative sugar field that actionCompiler.js lowers to an
|
|
185
|
+
// op-program at REGISTRATION. engineVisible:false — the engine never reads it directly.
|
|
186
|
+
// Studio Controls Realignment S4 (design §2.3.5):
|
|
187
|
+
// FrqtlApp.updateObjectProperty routes a runtime edit of THIS field through
|
|
188
|
+
// LargeObject.recompileActions() (re-runs actionCompiler.js + pushes the new
|
|
189
|
+
// op-program), so a live edit DOES retarget the running behavior (e.g. WALL → NONE
|
|
190
|
+
// mid-run) — no longer display-only.
|
|
191
|
+
engineVisible: false,
|
|
192
|
+
description: 'SUGAR-INPUT (compiled to an op-program at registration; engine has no ' +
|
|
193
|
+
'collision_type dispatch). NONE = pass-through; BOUNCE = reverse momentum; WALL = stop; ' +
|
|
194
|
+
'RANDOM_X/Y/XY = randomise that velocity component; ' +
|
|
195
|
+
'MOMENTUM_BASED = redirect proportional to incoming momentum.'
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'actions',
|
|
199
|
+
type: 'enum-set',
|
|
200
|
+
constraint: { values: CollisionActions },
|
|
201
|
+
// SUGAR-INPUT (G3/G4b): the CollisionAction engine enum + actions field were DELETED
|
|
202
|
+
// (G3). actions is a declarative sugar field that actionCompiler.js lowers to an
|
|
203
|
+
// op-program at REGISTRATION. engineVisible:false — the engine never reads it
|
|
204
|
+
// directly. Studio Controls Realignment S4: a runtime edit of THIS field is ALSO
|
|
205
|
+
// routed through LargeObject.recompileActions() (see the collision_type field's
|
|
206
|
+
// doc, above) — live, not mirror-only.
|
|
207
|
+
engineVisible: false,
|
|
208
|
+
description: 'SUGAR-INPUT (compiled to an op-program at registration; engine has no ' +
|
|
209
|
+
'action dispatch). ABSORB = remove the particle; COUNT = increment hit counter; ' +
|
|
210
|
+
'MARK = flag the particle (writes string_map.detector_name = loName); ' +
|
|
211
|
+
'DETECT = record the detection event (same as MARK); ' +
|
|
212
|
+
'LOG = emit a log entry; BOUNCE = apply bounce momentum; ' +
|
|
213
|
+
'BLOCK = stop the particle.'
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'name',
|
|
217
|
+
type: 'string',
|
|
218
|
+
engineVisible: false,
|
|
219
|
+
description: 'Human-readable identifier for this object (display/debug only; not engine-visible after construction)'
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
name: 'reposition',
|
|
223
|
+
type: 'enum',
|
|
224
|
+
constraint: { values: { top: 'top', bottom: 'bottom', left: 'left', right: 'right', closest: 'closest' } },
|
|
225
|
+
engineVisible: true,
|
|
226
|
+
description: 'Eject direction when a quantum is found overlapping this object\'s rect. ' +
|
|
227
|
+
'"closest" ejects toward the nearest edge; the cardinal values force a specific side.'
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
name: 'search_padding',
|
|
231
|
+
type: 'number',
|
|
232
|
+
constraint: { min: 0, integer: true },
|
|
233
|
+
engineVisible: false,
|
|
234
|
+
description: 'DEPRECATED / IGNORED. The engine no longer reads this; the collision ' +
|
|
235
|
+
'search rect now expands by the dimension\'s mb_w. Retained ' +
|
|
236
|
+
'only as a reserved positional constructor placeholder.'
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: 'color',
|
|
240
|
+
type: 'rgb',
|
|
241
|
+
engineVisible: false,
|
|
242
|
+
description: 'Render color [r, g, b] 0-255 each. Affects only the drawn appearance; engine collision is unaffected.'
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: 'alpha',
|
|
246
|
+
type: 'number',
|
|
247
|
+
constraint: { min: 0, max: 255, integer: true },
|
|
248
|
+
engineVisible: false,
|
|
249
|
+
widgetHint: 'slider',
|
|
250
|
+
description: 'Render opacity 0-255 (render-only). 0 = fully transparent, 255 = fully opaque.'
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: 'visible',
|
|
254
|
+
type: 'boolean',
|
|
255
|
+
engineVisible: false,
|
|
256
|
+
description: 'Whether the object is drawn (render-only). Setting false hides the visual; engine collision detection remains active.'
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: 'shellRender',
|
|
260
|
+
type: 'enum',
|
|
261
|
+
constraint: { values: { design: 'design', run: 'run', never: 'never' } },
|
|
262
|
+
engineVisible: false,
|
|
263
|
+
// WHEN this object's visual shell paints (render-only, generalizes
|
|
264
|
+
// the `_designMarker` boolean at the ONE _visibleLargeObjects authority):
|
|
265
|
+
// design — only while authoring (Design mode). The manipulable-marker
|
|
266
|
+
// default (a SphereEmitter marker is invisible during Run — you see the
|
|
267
|
+
// emission, not the source).
|
|
268
|
+
// run — ALWAYS visible (the "red light bulb" opt-in: a run-visible shell;
|
|
269
|
+
// pair with visible:true + color:[255,0,0] + a low alpha for the orb).
|
|
270
|
+
// never — never drawn.
|
|
271
|
+
// Absent → the effective default is derived at the filter (a _designMarker LO
|
|
272
|
+
// defaults 'design'; an ordinary LO defaults always-visible = 'run') so every
|
|
273
|
+
// existing scene is byte-identical. A live edit (updateObjectProperty) sets the
|
|
274
|
+
// per-instance override that _visibleLargeObjects reads.
|
|
275
|
+
description: 'When this object\'s visual shell renders (render-only): design = only ' +
|
|
276
|
+
'while authoring (Bite-4b marker default); run = always visible (the "red light ' +
|
|
277
|
+
'bulb" opt-in); never = hidden. Generalizes the design-only marker suppression ' +
|
|
278
|
+
'at the single _visibleLargeObjects authority; engine collision is unaffected.'
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: 'drawAsCircle',
|
|
282
|
+
type: 'boolean',
|
|
283
|
+
engineVisible: false,
|
|
284
|
+
description: 'Render as a circle inscribed in the bounding rect instead of a rectangle (render-only).'
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: 'shellShape',
|
|
288
|
+
type: 'enum',
|
|
289
|
+
// Vocab FERRIED from the ONE owner (lib/shim/frame-data render.shape set) —
|
|
290
|
+
// the same set "Default Shape" uses; never a hand-listed enum (R2-3).
|
|
291
|
+
constraint: { values: shapeValuesMap() },
|
|
292
|
+
engineVisible: false,
|
|
293
|
+
description: 'Render shape of this object\'s visual shell (render-only): ball|box|circle|' +
|
|
294
|
+
'cube|sphere. For a SphereEmitter this is the shape of the emitter\'s outer LO frame ' +
|
|
295
|
+
'(the "red light bulb" orb vs a box). Honored by the provider draw layer (capability-' +
|
|
296
|
+
'based, zero engine change); absent/omitted falls back to drawAsCircle. cube/sphere ' +
|
|
297
|
+
'degrade to box/ball in 2D.'
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: 'layer',
|
|
301
|
+
type: 'number',
|
|
302
|
+
constraint: { min: 0, integer: true },
|
|
303
|
+
engineVisible: true,
|
|
304
|
+
description: 'Dimension layer this object is scoped to (0 = fundamental/lowest; null = all layers). Selects which Dimension passes this object participates in (observed_dimensions=[layer]; null = all). Candidates come from that dimension\'s frame list.'
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: 'count',
|
|
308
|
+
type: 'number',
|
|
309
|
+
constraint: { min: 0, integer: true },
|
|
310
|
+
engineVisible: true,
|
|
311
|
+
description: 'Writable integer counter (SLICE 3, binding item 2). ' +
|
|
312
|
+
'Incremented via op-program: set self.count = self.count + 1. ' +
|
|
313
|
+
'Routed through setObjectProperty like any property — NOT an interpreter special-case. ' +
|
|
314
|
+
'Default 0; reset only by an explicit op or by user code. ' +
|
|
315
|
+
'Mirrors the count field in the Rust LargeObjectSpec (universe.rs).'
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: 'program',
|
|
319
|
+
type: 'object',
|
|
320
|
+
engineVisible: true,
|
|
321
|
+
// W1 tweak (T3): the compiled op-program AST is an ENGINE INTERNAL, not a
|
|
322
|
+
// designer control — the raw JSON must never render in the STUDIO Inspector.
|
|
323
|
+
// `internal:true` is the ONE authority for "hide from the designer surface"
|
|
324
|
+
// (consumed by makeControlsForObject + AuthorView's renderInspector); the
|
|
325
|
+
// program is still engineVisible + captured for codegen/round-trip.
|
|
326
|
+
internal: true,
|
|
327
|
+
description: 'Op-program attached to this LO (§10.3 SLICE 3). ' +
|
|
328
|
+
'Shape: { on: "collision"|"tick", ops: [{ set: "<handle>.<prop>", to: ExprAST }] }. ' +
|
|
329
|
+
'on:"collision" — runs once per overlapping frame per tick, BEFORE ABSORB. ' +
|
|
330
|
+
'on:"tick" — runs once per LO per tick (Phase A). ' +
|
|
331
|
+
'null clears the program. Written via updateObjectProperty(handle, "LargeObject", "program", prog) ' +
|
|
332
|
+
'— used by §10.3 L3 to attach eject op-programs to oven walls after registration.'
|
|
333
|
+
},
|
|
334
|
+
// ── Read-only: derived geometry (self.* in op-program scope) ────────
|
|
335
|
+
// These are derived from the rect field and exposed as flat scalars in the
|
|
336
|
+
// op-program scope bag (Rust lo_to_scope_bag; JS evalExpr Ref expansion).
|
|
337
|
+
// They are READ-ONLY — rect is the single writable authority.
|
|
338
|
+
// All are required by the §10.3 eject-expression proof (which side of the
|
|
339
|
+
// wall do we eject to? → Cond(Cmp(frame.x, self.cx), ...)).
|
|
340
|
+
{
|
|
341
|
+
name: 'left',
|
|
342
|
+
type: 'readonly',
|
|
343
|
+
internal: true,
|
|
344
|
+
engineVisible: true,
|
|
345
|
+
description: 'Derived: rect.left (left edge in physics pixels). Read-only in scope; rect is the writable authority.'
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
name: 'right',
|
|
349
|
+
type: 'readonly',
|
|
350
|
+
internal: true,
|
|
351
|
+
engineVisible: true,
|
|
352
|
+
description: 'Derived: rect.right (right edge = rect.left + rect.w). Read-only in scope.'
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'top',
|
|
356
|
+
type: 'readonly',
|
|
357
|
+
internal: true,
|
|
358
|
+
engineVisible: true,
|
|
359
|
+
description: 'Derived: rect.top (top edge in physics pixels). Read-only in scope.'
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: 'bottom',
|
|
363
|
+
type: 'readonly',
|
|
364
|
+
internal: true,
|
|
365
|
+
engineVisible: true,
|
|
366
|
+
description: 'Derived: rect.bottom (bottom edge = rect.top + rect.h). Read-only in scope.'
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
name: 'cx',
|
|
370
|
+
type: 'readonly',
|
|
371
|
+
internal: true,
|
|
372
|
+
engineVisible: true,
|
|
373
|
+
description: 'Derived: rect.x (center X = rect.left + rect.w/2). Read-only in scope.'
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: 'cy',
|
|
377
|
+
type: 'readonly',
|
|
378
|
+
internal: true,
|
|
379
|
+
engineVisible: true,
|
|
380
|
+
description: 'Derived: rect.y (center Y = rect.top + rect.h/2). Read-only in scope.'
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: 'w',
|
|
384
|
+
type: 'readonly',
|
|
385
|
+
internal: true,
|
|
386
|
+
engineVisible: true,
|
|
387
|
+
description: 'Derived: rect.w (width in physics pixels). Read-only in scope.'
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
name: 'h',
|
|
391
|
+
type: 'readonly',
|
|
392
|
+
internal: true,
|
|
393
|
+
engineVisible: true,
|
|
394
|
+
description: 'Derived: rect.h (height in physics pixels). Read-only in scope.'
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: 'x',
|
|
398
|
+
type: 'readonly',
|
|
399
|
+
internal: true,
|
|
400
|
+
engineVisible: true,
|
|
401
|
+
description: 'Derived: rect.x (center X, alias for cx). Read-only; rect is the writable authority.'
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: 'y',
|
|
405
|
+
type: 'readonly',
|
|
406
|
+
internal: true,
|
|
407
|
+
engineVisible: true,
|
|
408
|
+
description: 'Derived: rect.y (center Y, alias for cy). Read-only; rect is the writable authority.'
|
|
409
|
+
},
|
|
410
|
+
// ── FRQTL-MAINT (2026-07-01) — z/depth readonly geometry ────────────
|
|
411
|
+
// Already emitted by the Rust op-program scope bag (universe.rs
|
|
412
|
+
// lo_to_scope_bag) for every LO regardless of whether z/d were ever
|
|
413
|
+
// meaningfully non-default; listed here now that the rect field can
|
|
414
|
+
// actually carry a non-default z/d (see rect field above). WASM-only
|
|
415
|
+
// (the frozen JS reference engine's evalExpr scope bag is 2D-only).
|
|
416
|
+
{
|
|
417
|
+
name: 'near',
|
|
418
|
+
type: 'readonly',
|
|
419
|
+
internal: true,
|
|
420
|
+
engineVisible: true,
|
|
421
|
+
description: 'Derived: rect.near (near z-face = rect.z - rect.d/2 in centered terms, ' +
|
|
422
|
+
'or the literal z corner in corner-mode registration). Read-only in scope; rect is ' +
|
|
423
|
+
'the writable authority. WASM-only.'
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
name: 'far',
|
|
427
|
+
type: 'readonly',
|
|
428
|
+
internal: true,
|
|
429
|
+
engineVisible: true,
|
|
430
|
+
description: 'Derived: rect.far (far z-face = rect.near + rect.d). Read-only in scope. WASM-only.'
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
name: 'd',
|
|
434
|
+
type: 'readonly',
|
|
435
|
+
internal: true,
|
|
436
|
+
engineVisible: true,
|
|
437
|
+
description: 'Derived: rect.d (depth in physics pixels). Read-only in scope. WASM-only.'
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
name: 'cz',
|
|
441
|
+
type: 'readonly',
|
|
442
|
+
internal: true,
|
|
443
|
+
engineVisible: true,
|
|
444
|
+
description: 'Derived: rect.z (center Z). Read-only in scope. WASM-only.'
|
|
445
|
+
}
|
|
446
|
+
]
|
|
447
|
+
};
|
|
448
|
+
/** The scope rows, in the schema's published order. */
|
|
449
|
+
export const SCOPE_DESCRIPTORS = Object.freeze({
|
|
450
|
+
particle: ParticleDescriptor,
|
|
451
|
+
backdrop: BackdropDescriptor,
|
|
452
|
+
Frame: EngineScopes.FrameDescriptor, // writable engine-core accessor (distinct from particle)
|
|
453
|
+
Universe: EngineScopes.UniverseDescriptor, // C1 B4 — read-only universe state for op-program scope
|
|
454
|
+
Dimension: EngineScopes.DimensionDescriptor, // C1 B4 — read-only dimension properties
|
|
455
|
+
LargeObject: LargeObjectDescriptor // the engine door's object scope; the LargeObject part registers it BY REFERENCE
|
|
456
|
+
});
|
|
457
|
+
Object.keys(SCOPE_DESCRIPTORS).forEach(function (name) { validateDescriptor(name, SCOPE_DESCRIPTORS[name]); });
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* Copyright 2023-2026 by Essam Abadir */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* validate-descriptor.js — THE descriptor-shape validator (schema/'s own), applied to every row the
|
|
5
|
+
* schema serves: each scope row (schema/scopes.js) and each kind a part registers
|
|
6
|
+
* (objects/kinds.js registerKind).
|
|
7
|
+
*
|
|
8
|
+
* validateDescriptor(name, descriptor) → descriptor THROWS on a malformed descriptor
|
|
9
|
+
*
|
|
10
|
+
* Two load-time drift guards, each against its ONE owner in lib/shim/field-descriptor:
|
|
11
|
+
* - every field's `type` is a member of FIELD_TYPES (the shared field-SHAPE vocabulary);
|
|
12
|
+
* - a declared `ux:{}` block survives normalizeUx (the STUDIO presentation vocabulary).
|
|
13
|
+
* A descriptor with NO ux block is untouched (today's behavior).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import * as FieldDescriptorSchema from '../../../shim/field-descriptor/index.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} name — the row's name (a kind's class name, or a scope row's key)
|
|
20
|
+
* @param {object} descriptor — { description, fields: [...], ux? }
|
|
21
|
+
* @returns {object} the same descriptor
|
|
22
|
+
*/
|
|
23
|
+
export function validateDescriptor(name, descriptor) {
|
|
24
|
+
if (!descriptor || typeof descriptor !== 'object' || !Array.isArray(descriptor.fields)) {
|
|
25
|
+
throw new TypeError('[lib/frqtl/objects/schema] descriptor "' + name + '" must be an object with a ' +
|
|
26
|
+
'fields array (and a description). (FAIL-LOUD.)');
|
|
27
|
+
}
|
|
28
|
+
var fieldTypeSet = FieldDescriptorSchema.FIELD_TYPES;
|
|
29
|
+
var fields = descriptor.fields;
|
|
30
|
+
for (var fi = 0; fi < fields.length; fi++) {
|
|
31
|
+
var ft = fields[fi].type;
|
|
32
|
+
if (fieldTypeSet.indexOf(ft) === -1) {
|
|
33
|
+
throw new Error('[lib/frqtl/objects/schema] descriptor "' + name + '" field "' +
|
|
34
|
+
fields[fi].name + '" has type "' + ft + '" — not a member of ' +
|
|
35
|
+
'lib/shim/field-descriptor\'s FIELD_TYPES ([' + fieldTypeSet.join(', ') + ']). ' +
|
|
36
|
+
'(FAIL-LOUD — the field-type vocabulary is shared; add the type at the ONE ' +
|
|
37
|
+
'owner, lib/shim/field-descriptor/index.js, never here.)');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (descriptor.ux !== undefined) {
|
|
41
|
+
try {
|
|
42
|
+
FieldDescriptorSchema.normalizeUx(descriptor.ux);
|
|
43
|
+
} catch (uxErr) {
|
|
44
|
+
throw new Error('[lib/frqtl/objects/schema] descriptor "' + name +
|
|
45
|
+
'" has an invalid ux block: ' + uxErr.message);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return descriptor;
|
|
49
|
+
}
|