@almadar/core 1.0.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 +72 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1595 -0
- package/dist/index.js.map +1 -0
- package/dist/src/types/index.d.ts +14302 -0
- package/dist/src/types/index.js +1595 -0
- package/dist/src/types/index.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,1595 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/types/orbital.ts
|
|
4
|
+
var FieldTypeSchema = z.enum([
|
|
5
|
+
"string",
|
|
6
|
+
"number",
|
|
7
|
+
"boolean",
|
|
8
|
+
"date",
|
|
9
|
+
"timestamp",
|
|
10
|
+
"datetime",
|
|
11
|
+
"array",
|
|
12
|
+
"object",
|
|
13
|
+
"enum",
|
|
14
|
+
"relation"
|
|
15
|
+
]);
|
|
16
|
+
var RelationConfigSchema = z.object({
|
|
17
|
+
entity: z.string().min(1, "Target entity is required"),
|
|
18
|
+
field: z.string().optional(),
|
|
19
|
+
cardinality: z.enum(["one", "many"]).optional(),
|
|
20
|
+
onDelete: z.enum(["cascade", "nullify", "restrict"]).optional()
|
|
21
|
+
});
|
|
22
|
+
var FieldFormatSchema = z.enum([
|
|
23
|
+
"email",
|
|
24
|
+
"url",
|
|
25
|
+
"phone",
|
|
26
|
+
"date",
|
|
27
|
+
"datetime",
|
|
28
|
+
"uuid"
|
|
29
|
+
]);
|
|
30
|
+
var EntityFieldSchema = z.lazy(
|
|
31
|
+
() => z.object({
|
|
32
|
+
name: z.string().min(1, "Field name is required"),
|
|
33
|
+
type: FieldTypeSchema,
|
|
34
|
+
required: z.boolean().optional(),
|
|
35
|
+
default: z.unknown().optional(),
|
|
36
|
+
values: z.array(z.string()).optional(),
|
|
37
|
+
enum: z.array(z.string()).optional(),
|
|
38
|
+
format: FieldFormatSchema.optional(),
|
|
39
|
+
min: z.number().optional(),
|
|
40
|
+
max: z.number().optional(),
|
|
41
|
+
items: EntityFieldSchema.optional(),
|
|
42
|
+
relation: RelationConfigSchema.optional()
|
|
43
|
+
}).refine(
|
|
44
|
+
(field) => field.type !== "relation" || field.relation !== void 0,
|
|
45
|
+
{ message: 'Relation config is required when type is "relation"', path: ["relation"] }
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
var FieldSchema = EntityFieldSchema;
|
|
49
|
+
var ENTITY_ROLES = [
|
|
50
|
+
"player",
|
|
51
|
+
"enemy",
|
|
52
|
+
"npc",
|
|
53
|
+
"item",
|
|
54
|
+
"tile",
|
|
55
|
+
"projectile",
|
|
56
|
+
"effect",
|
|
57
|
+
"ui",
|
|
58
|
+
"decoration",
|
|
59
|
+
"vehicle"
|
|
60
|
+
];
|
|
61
|
+
var EntityRoleSchema = z.enum(ENTITY_ROLES);
|
|
62
|
+
var VISUAL_STYLES = ["pixel", "vector", "hd", "1-bit", "isometric"];
|
|
63
|
+
var VisualStyleSchema = z.enum(VISUAL_STYLES);
|
|
64
|
+
var GAME_TYPES = [
|
|
65
|
+
"platformer",
|
|
66
|
+
"roguelike",
|
|
67
|
+
"top-down",
|
|
68
|
+
"puzzle",
|
|
69
|
+
"racing",
|
|
70
|
+
"card",
|
|
71
|
+
"board",
|
|
72
|
+
"shooter",
|
|
73
|
+
"rpg"
|
|
74
|
+
];
|
|
75
|
+
var GameTypeSchema = z.enum(GAME_TYPES);
|
|
76
|
+
var AnimationDefSchema = z.object({
|
|
77
|
+
frames: z.union([z.array(z.number()), z.array(z.string())]),
|
|
78
|
+
fps: z.number().positive(),
|
|
79
|
+
loop: z.boolean()
|
|
80
|
+
});
|
|
81
|
+
var SemanticAssetRefSchema = z.object({
|
|
82
|
+
role: EntityRoleSchema,
|
|
83
|
+
category: z.string().min(1),
|
|
84
|
+
animations: z.array(z.string()).optional(),
|
|
85
|
+
style: VisualStyleSchema.optional(),
|
|
86
|
+
variant: z.string().optional()
|
|
87
|
+
});
|
|
88
|
+
var ResolvedAssetSchema = z.object({
|
|
89
|
+
basePath: z.string(),
|
|
90
|
+
path: z.string(),
|
|
91
|
+
tiles: z.array(z.number()).optional(),
|
|
92
|
+
tileSize: z.number().positive().optional(),
|
|
93
|
+
files: z.array(z.string()).optional(),
|
|
94
|
+
animations: z.record(AnimationDefSchema).optional()
|
|
95
|
+
});
|
|
96
|
+
var AssetMappingSchema = z.object({
|
|
97
|
+
path: z.string(),
|
|
98
|
+
tiles: z.array(z.number()).optional(),
|
|
99
|
+
tileSize: z.number().positive().optional(),
|
|
100
|
+
files: z.array(z.string()).optional(),
|
|
101
|
+
animations: z.record(AnimationDefSchema).optional()
|
|
102
|
+
});
|
|
103
|
+
var AssetMapSchema = z.object({
|
|
104
|
+
gameType: GameTypeSchema,
|
|
105
|
+
style: VisualStyleSchema,
|
|
106
|
+
basePath: z.string(),
|
|
107
|
+
mappings: z.record(AssetMappingSchema)
|
|
108
|
+
});
|
|
109
|
+
function createAssetKey(role, category) {
|
|
110
|
+
return `${role}:${category}`;
|
|
111
|
+
}
|
|
112
|
+
function parseAssetKey(key) {
|
|
113
|
+
const parts = key.split(":");
|
|
114
|
+
if (parts.length !== 2) return null;
|
|
115
|
+
return { role: parts[0], category: parts[1] };
|
|
116
|
+
}
|
|
117
|
+
function getDefaultAnimationsForRole(role) {
|
|
118
|
+
switch (role) {
|
|
119
|
+
case "player":
|
|
120
|
+
return ["idle", "run", "jump", "fall", "attack", "hurt", "die"];
|
|
121
|
+
case "enemy":
|
|
122
|
+
return ["idle", "walk", "attack", "hurt", "die"];
|
|
123
|
+
case "npc":
|
|
124
|
+
return ["idle", "walk", "talk"];
|
|
125
|
+
case "item":
|
|
126
|
+
return ["idle", "collected"];
|
|
127
|
+
case "tile":
|
|
128
|
+
return ["static"];
|
|
129
|
+
case "projectile":
|
|
130
|
+
return ["fly", "hit", "expire"];
|
|
131
|
+
case "effect":
|
|
132
|
+
return ["play"];
|
|
133
|
+
case "ui":
|
|
134
|
+
return ["normal", "hover", "pressed", "disabled"];
|
|
135
|
+
case "decoration":
|
|
136
|
+
return ["idle"];
|
|
137
|
+
case "vehicle":
|
|
138
|
+
return ["idle", "move", "brake"];
|
|
139
|
+
default:
|
|
140
|
+
return ["idle"];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function validateAssetAnimations(assetRef, requiredAnimations) {
|
|
144
|
+
const provided = assetRef.animations || [];
|
|
145
|
+
const missing = requiredAnimations.filter((anim) => !provided.includes(anim));
|
|
146
|
+
return { valid: missing.length === 0, missing };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/types/entity.ts
|
|
150
|
+
var EntityPersistenceSchema = z.enum([
|
|
151
|
+
"persistent",
|
|
152
|
+
"runtime",
|
|
153
|
+
"singleton",
|
|
154
|
+
"instance"
|
|
155
|
+
]);
|
|
156
|
+
var OrbitalEntitySchema = z.object({
|
|
157
|
+
name: z.string().min(1, "Entity name is required"),
|
|
158
|
+
persistence: EntityPersistenceSchema.default("persistent"),
|
|
159
|
+
collection: z.string().optional(),
|
|
160
|
+
fields: z.array(EntityFieldSchema).min(1, "At least one field is required"),
|
|
161
|
+
timestamps: z.boolean().optional(),
|
|
162
|
+
softDelete: z.boolean().optional(),
|
|
163
|
+
description: z.string().optional(),
|
|
164
|
+
visual_prompt: z.string().optional(),
|
|
165
|
+
assetRef: SemanticAssetRefSchema.optional()
|
|
166
|
+
});
|
|
167
|
+
var EntitySchema = OrbitalEntitySchema;
|
|
168
|
+
function deriveCollection(entity) {
|
|
169
|
+
if (entity.persistence !== "persistent") {
|
|
170
|
+
return void 0;
|
|
171
|
+
}
|
|
172
|
+
return entity.name.toLowerCase() + "s";
|
|
173
|
+
}
|
|
174
|
+
function isRuntimeEntity(entity) {
|
|
175
|
+
return entity.persistence === "runtime";
|
|
176
|
+
}
|
|
177
|
+
function isSingletonEntity(entity) {
|
|
178
|
+
return entity.persistence === "singleton";
|
|
179
|
+
}
|
|
180
|
+
var ViewTypeSchema = z.enum([
|
|
181
|
+
"list",
|
|
182
|
+
"detail",
|
|
183
|
+
"create",
|
|
184
|
+
"edit",
|
|
185
|
+
"dashboard",
|
|
186
|
+
"custom"
|
|
187
|
+
]);
|
|
188
|
+
var PageTraitRefSchema = z.object({
|
|
189
|
+
ref: z.string().min(1, "Trait ref is required"),
|
|
190
|
+
linkedEntity: z.string().optional(),
|
|
191
|
+
config: z.record(z.unknown()).optional()
|
|
192
|
+
});
|
|
193
|
+
var OrbitalPageStrictSchema = z.object({
|
|
194
|
+
name: z.string().min(1, "Page name is required"),
|
|
195
|
+
path: z.string().min(1, "Page path is required").startsWith("/", "Path must start with /"),
|
|
196
|
+
primaryEntity: z.string().min(1, "Primary entity is required"),
|
|
197
|
+
traits: z.array(PageTraitRefSchema).min(1, "Page must have at least one trait"),
|
|
198
|
+
title: z.string().optional()
|
|
199
|
+
}).strict();
|
|
200
|
+
var OrbitalPageSchema = z.object({
|
|
201
|
+
name: z.string().min(1, "Page name is required"),
|
|
202
|
+
path: z.string().min(1, "Page path is required").startsWith("/", "Path must start with /"),
|
|
203
|
+
viewType: ViewTypeSchema.optional(),
|
|
204
|
+
title: z.string().optional(),
|
|
205
|
+
primaryEntity: z.string().optional(),
|
|
206
|
+
traits: z.array(PageTraitRefSchema).optional(),
|
|
207
|
+
isInitial: z.boolean().optional()
|
|
208
|
+
}).strict();
|
|
209
|
+
var PageSchema = OrbitalPageSchema;
|
|
210
|
+
var UI_SLOTS = [
|
|
211
|
+
"main",
|
|
212
|
+
"sidebar",
|
|
213
|
+
"modal",
|
|
214
|
+
"drawer",
|
|
215
|
+
"overlay",
|
|
216
|
+
"center",
|
|
217
|
+
"toast",
|
|
218
|
+
"hud-top",
|
|
219
|
+
"hud-bottom",
|
|
220
|
+
"floating",
|
|
221
|
+
"system"
|
|
222
|
+
// For invisible system components (InputListener, CollisionDetector)
|
|
223
|
+
];
|
|
224
|
+
var UISlotSchema = z.enum(UI_SLOTS);
|
|
225
|
+
var EffectSchema = z.array(z.unknown()).min(1).refine(
|
|
226
|
+
(arr) => typeof arr[0] === "string",
|
|
227
|
+
{ message: "Effect must be an S-expression with a string operator as first element" }
|
|
228
|
+
);
|
|
229
|
+
function isEffect(value) {
|
|
230
|
+
return Array.isArray(value) && value.length > 0 && typeof value[0] === "string";
|
|
231
|
+
}
|
|
232
|
+
var isSExprEffect = isEffect;
|
|
233
|
+
function set(binding, value) {
|
|
234
|
+
return ["set", binding, value];
|
|
235
|
+
}
|
|
236
|
+
function emit(event, payload) {
|
|
237
|
+
return payload ? ["emit", event, payload] : ["emit", event];
|
|
238
|
+
}
|
|
239
|
+
function navigate(path, params) {
|
|
240
|
+
return params ? ["navigate", path, params] : ["navigate", path];
|
|
241
|
+
}
|
|
242
|
+
function renderUI(target, pattern, props) {
|
|
243
|
+
const patternObj = pattern ? { ...pattern } : null;
|
|
244
|
+
return props ? ["render-ui", target, patternObj, props] : ["render-ui", target, patternObj];
|
|
245
|
+
}
|
|
246
|
+
function persist(action, entity, data) {
|
|
247
|
+
return data ? ["persist", action, entity, data] : ["persist", action, entity];
|
|
248
|
+
}
|
|
249
|
+
function callService(service, config) {
|
|
250
|
+
return ["call-service", service, config];
|
|
251
|
+
}
|
|
252
|
+
function spawn(entity, initialState) {
|
|
253
|
+
return initialState ? ["spawn", entity, initialState] : ["spawn", entity];
|
|
254
|
+
}
|
|
255
|
+
function despawn(entityId) {
|
|
256
|
+
return ["despawn", entityId];
|
|
257
|
+
}
|
|
258
|
+
function doEffects(...effects) {
|
|
259
|
+
return ["do", ...effects];
|
|
260
|
+
}
|
|
261
|
+
function notify(channel, message, recipient) {
|
|
262
|
+
return recipient ? ["notify", channel, message, recipient] : ["notify", channel, message];
|
|
263
|
+
}
|
|
264
|
+
var SExprAtomSchema = z.union([
|
|
265
|
+
z.string(),
|
|
266
|
+
z.number(),
|
|
267
|
+
z.boolean(),
|
|
268
|
+
z.null(),
|
|
269
|
+
z.record(z.unknown())
|
|
270
|
+
// Objects for payload data
|
|
271
|
+
]);
|
|
272
|
+
var SExprSchema = z.lazy(
|
|
273
|
+
() => z.union([
|
|
274
|
+
SExprAtomSchema,
|
|
275
|
+
z.array(z.lazy(() => SExprSchema)).min(1).refine(
|
|
276
|
+
(arr) => typeof arr[0] === "string",
|
|
277
|
+
{ message: "S-expression array must have a string operator as first element" }
|
|
278
|
+
)
|
|
279
|
+
])
|
|
280
|
+
);
|
|
281
|
+
var ExpressionSchema = SExprSchema;
|
|
282
|
+
function isSExpr(value) {
|
|
283
|
+
return Array.isArray(value) && value.length > 0 && typeof value[0] === "string";
|
|
284
|
+
}
|
|
285
|
+
function isSExprAtom(value) {
|
|
286
|
+
if (value === null) return true;
|
|
287
|
+
if (Array.isArray(value)) return false;
|
|
288
|
+
const type = typeof value;
|
|
289
|
+
return type === "string" || type === "number" || type === "boolean" || type === "object";
|
|
290
|
+
}
|
|
291
|
+
function isBinding(value) {
|
|
292
|
+
return typeof value === "string" && value.startsWith("@");
|
|
293
|
+
}
|
|
294
|
+
function isSExprCall(value) {
|
|
295
|
+
return isSExpr(value);
|
|
296
|
+
}
|
|
297
|
+
var CORE_BINDINGS = ["entity", "payload", "state", "now", "config", "computed", "trait"];
|
|
298
|
+
function parseBinding(binding) {
|
|
299
|
+
if (!binding.startsWith("@")) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
const withoutPrefix = binding.slice(1);
|
|
303
|
+
const parts = withoutPrefix.split(".");
|
|
304
|
+
if (parts.length === 0 || parts[0] === "") {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
const root = parts[0];
|
|
308
|
+
const path = parts.slice(1);
|
|
309
|
+
const isCore = CORE_BINDINGS.includes(root);
|
|
310
|
+
return {
|
|
311
|
+
type: isCore ? "core" : "entity",
|
|
312
|
+
root,
|
|
313
|
+
path,
|
|
314
|
+
original: binding
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function isValidBinding(binding) {
|
|
318
|
+
const parsed = parseBinding(binding);
|
|
319
|
+
if (!parsed) return false;
|
|
320
|
+
if (parsed.type === "core") {
|
|
321
|
+
if (parsed.root === "state" || parsed.root === "now") {
|
|
322
|
+
return parsed.path.length === 0;
|
|
323
|
+
}
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
return parsed.path.length > 0;
|
|
327
|
+
}
|
|
328
|
+
function getOperator(expr) {
|
|
329
|
+
if (!isSExpr(expr)) return null;
|
|
330
|
+
return expr[0];
|
|
331
|
+
}
|
|
332
|
+
function getArgs(expr) {
|
|
333
|
+
if (!isSExpr(expr)) return [];
|
|
334
|
+
return expr.slice(1);
|
|
335
|
+
}
|
|
336
|
+
function sexpr(operator, ...args) {
|
|
337
|
+
return [operator, ...args];
|
|
338
|
+
}
|
|
339
|
+
function walkSExpr(expr, visitor, parent = null, index = 0) {
|
|
340
|
+
visitor(expr, parent, index);
|
|
341
|
+
if (isSExpr(expr)) {
|
|
342
|
+
for (let i = 0; i < expr.length; i++) {
|
|
343
|
+
walkSExpr(expr[i], visitor, expr, i);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function collectBindings(expr) {
|
|
348
|
+
const bindings = [];
|
|
349
|
+
walkSExpr(expr, (node) => {
|
|
350
|
+
if (isBinding(node)) {
|
|
351
|
+
bindings.push(node);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
return bindings;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/types/state-machine.ts
|
|
358
|
+
var StateSchema = z.object({
|
|
359
|
+
name: z.string().min(1, "State name is required"),
|
|
360
|
+
isInitial: z.boolean().optional(),
|
|
361
|
+
isTerminal: z.boolean().optional(),
|
|
362
|
+
isFinal: z.boolean().optional(),
|
|
363
|
+
description: z.string().optional(),
|
|
364
|
+
onEntry: z.array(z.string()).optional(),
|
|
365
|
+
onExit: z.array(z.string()).optional()
|
|
366
|
+
});
|
|
367
|
+
var PayloadFieldSchema = z.object({
|
|
368
|
+
name: z.string().min(1),
|
|
369
|
+
type: z.enum(["string", "number", "boolean", "object", "array"]),
|
|
370
|
+
required: z.boolean().optional()
|
|
371
|
+
});
|
|
372
|
+
var EventSchema = z.object({
|
|
373
|
+
key: z.string().min(1, "Event key is required"),
|
|
374
|
+
name: z.string().min(1, "Event name is required"),
|
|
375
|
+
description: z.string().optional(),
|
|
376
|
+
payloadSchema: z.array(PayloadFieldSchema).optional(),
|
|
377
|
+
classification: z.enum(["domain", "system"]).optional(),
|
|
378
|
+
semanticRole: z.string().optional()
|
|
379
|
+
});
|
|
380
|
+
var GuardSchema = z.object({
|
|
381
|
+
name: z.string().min(1, "Guard name is required"),
|
|
382
|
+
expression: ExpressionSchema,
|
|
383
|
+
description: z.string().optional()
|
|
384
|
+
});
|
|
385
|
+
var TransitionSchema = z.object({
|
|
386
|
+
from: z.string().min(1, "Transition source state is required"),
|
|
387
|
+
to: z.string().min(1, "Transition target state is required"),
|
|
388
|
+
event: z.string().min(1, "Transition event is required"),
|
|
389
|
+
guard: ExpressionSchema.nullish(),
|
|
390
|
+
effects: z.array(EffectSchema).optional(),
|
|
391
|
+
description: z.string().nullish()
|
|
392
|
+
});
|
|
393
|
+
var StateMachineSchema = z.object({
|
|
394
|
+
states: z.array(StateSchema).min(1, "At least one state is required"),
|
|
395
|
+
events: z.array(EventSchema),
|
|
396
|
+
transitions: z.array(TransitionSchema),
|
|
397
|
+
guards: z.array(GuardSchema).optional()
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// src/types/trait.ts
|
|
401
|
+
var TraitCategorySchema = z.enum([
|
|
402
|
+
"lifecycle",
|
|
403
|
+
"temporal",
|
|
404
|
+
"validation",
|
|
405
|
+
"notification",
|
|
406
|
+
"integration",
|
|
407
|
+
"interaction",
|
|
408
|
+
"game-core",
|
|
409
|
+
"game-character",
|
|
410
|
+
"game-ai",
|
|
411
|
+
"game-combat",
|
|
412
|
+
"game-items",
|
|
413
|
+
"game-cards",
|
|
414
|
+
"game-board",
|
|
415
|
+
"game-puzzle"
|
|
416
|
+
]);
|
|
417
|
+
var TraitEntityFieldSchema = z.object({
|
|
418
|
+
name: z.string().min(1),
|
|
419
|
+
type: z.enum([
|
|
420
|
+
"string",
|
|
421
|
+
"number",
|
|
422
|
+
"boolean",
|
|
423
|
+
"date",
|
|
424
|
+
"array",
|
|
425
|
+
"object",
|
|
426
|
+
"timestamp",
|
|
427
|
+
"datetime",
|
|
428
|
+
"enum"
|
|
429
|
+
]),
|
|
430
|
+
required: z.boolean().optional(),
|
|
431
|
+
default: z.unknown().optional(),
|
|
432
|
+
values: z.array(z.string()).optional()
|
|
433
|
+
});
|
|
434
|
+
var TraitDataEntitySchema = z.object({
|
|
435
|
+
name: z.string().min(1),
|
|
436
|
+
collection: z.string().optional(),
|
|
437
|
+
fields: z.array(TraitEntityFieldSchema).min(1),
|
|
438
|
+
timestamps: z.boolean().optional(),
|
|
439
|
+
description: z.string().optional(),
|
|
440
|
+
runtime: z.boolean().optional(),
|
|
441
|
+
singleton: z.boolean().optional(),
|
|
442
|
+
pages: z.array(z.string()).optional()
|
|
443
|
+
});
|
|
444
|
+
var TraitTickSchema = z.object({
|
|
445
|
+
name: z.string().min(1),
|
|
446
|
+
description: z.string().optional(),
|
|
447
|
+
priority: z.number().optional(),
|
|
448
|
+
interval: z.union([z.literal("frame"), z.number().positive()]),
|
|
449
|
+
appliesTo: z.array(z.string()).optional(),
|
|
450
|
+
pages: z.array(z.string()).optional(),
|
|
451
|
+
guard: ExpressionSchema.optional(),
|
|
452
|
+
effects: z.array(EffectSchema).min(1),
|
|
453
|
+
emits: z.array(z.string()).optional()
|
|
454
|
+
});
|
|
455
|
+
var EventScopeSchema = z.enum(["internal", "external"]);
|
|
456
|
+
var EventPayloadFieldSchema = z.object({
|
|
457
|
+
name: z.string().min(1),
|
|
458
|
+
type: z.enum(["string", "number", "boolean", "object", "array", "entity"]),
|
|
459
|
+
required: z.boolean().optional(),
|
|
460
|
+
description: z.string().optional(),
|
|
461
|
+
entityType: z.string().optional()
|
|
462
|
+
});
|
|
463
|
+
var TraitEventContractSchema = z.object({
|
|
464
|
+
event: z.string().min(1).regex(
|
|
465
|
+
/^[A-Z][A-Z0-9_]*$/,
|
|
466
|
+
"Event name must be UPPER_SNAKE_CASE"
|
|
467
|
+
),
|
|
468
|
+
description: z.string().optional(),
|
|
469
|
+
payload: z.array(EventPayloadFieldSchema).optional(),
|
|
470
|
+
scope: EventScopeSchema.optional()
|
|
471
|
+
});
|
|
472
|
+
var TraitEventListenerSchema = z.object({
|
|
473
|
+
event: z.string().min(1),
|
|
474
|
+
triggers: z.string().min(1),
|
|
475
|
+
guard: ExpressionSchema.optional(),
|
|
476
|
+
scope: EventScopeSchema.optional(),
|
|
477
|
+
payloadMapping: z.record(z.string()).optional()
|
|
478
|
+
});
|
|
479
|
+
var RequiredFieldSchema = z.object({
|
|
480
|
+
name: z.string().min(1),
|
|
481
|
+
type: z.enum(["string", "number", "boolean", "date", "array", "object", "timestamp", "datetime", "enum"]),
|
|
482
|
+
description: z.string().optional()
|
|
483
|
+
});
|
|
484
|
+
var TraitReferenceSchema = z.object({
|
|
485
|
+
ref: z.string().min(1),
|
|
486
|
+
linkedEntity: z.string().optional(),
|
|
487
|
+
config: z.record(z.record(z.unknown())).optional(),
|
|
488
|
+
appliesTo: z.array(z.string()).optional()
|
|
489
|
+
});
|
|
490
|
+
var TraitSchema = z.object({
|
|
491
|
+
name: z.string().min(1),
|
|
492
|
+
description: z.string().optional(),
|
|
493
|
+
description_visual_prompt: z.string().optional(),
|
|
494
|
+
category: TraitCategorySchema.optional(),
|
|
495
|
+
requiredFields: z.array(RequiredFieldSchema).optional(),
|
|
496
|
+
dataEntities: z.array(TraitDataEntitySchema).optional(),
|
|
497
|
+
stateMachine: StateMachineSchema.optional(),
|
|
498
|
+
initialEffects: z.array(EffectSchema).optional(),
|
|
499
|
+
ticks: z.array(TraitTickSchema).optional(),
|
|
500
|
+
emits: z.array(TraitEventContractSchema).optional(),
|
|
501
|
+
listens: z.array(TraitEventListenerSchema).optional(),
|
|
502
|
+
ui: z.record(z.unknown()).optional()
|
|
503
|
+
});
|
|
504
|
+
var TraitRefSchema = z.union([
|
|
505
|
+
z.string().min(1),
|
|
506
|
+
z.object({
|
|
507
|
+
ref: z.string().min(1),
|
|
508
|
+
config: z.record(z.unknown()).optional(),
|
|
509
|
+
linkedEntity: z.string().optional()
|
|
510
|
+
}),
|
|
511
|
+
TraitSchema
|
|
512
|
+
// Allow inline trait definitions
|
|
513
|
+
]);
|
|
514
|
+
function isInlineTrait(traitRef) {
|
|
515
|
+
return typeof traitRef === "object" && "name" in traitRef && !("ref" in traitRef);
|
|
516
|
+
}
|
|
517
|
+
function getTraitName(traitRef) {
|
|
518
|
+
if (typeof traitRef === "string") {
|
|
519
|
+
return traitRef;
|
|
520
|
+
}
|
|
521
|
+
if (isInlineTrait(traitRef)) {
|
|
522
|
+
return traitRef.name;
|
|
523
|
+
}
|
|
524
|
+
return traitRef.ref;
|
|
525
|
+
}
|
|
526
|
+
function getTraitConfig(traitRef) {
|
|
527
|
+
if (typeof traitRef === "string") {
|
|
528
|
+
return void 0;
|
|
529
|
+
}
|
|
530
|
+
if (isInlineTrait(traitRef)) {
|
|
531
|
+
return void 0;
|
|
532
|
+
}
|
|
533
|
+
return traitRef.config;
|
|
534
|
+
}
|
|
535
|
+
function normalizeTraitRef(traitRef) {
|
|
536
|
+
if (typeof traitRef === "string") {
|
|
537
|
+
return { ref: traitRef };
|
|
538
|
+
}
|
|
539
|
+
if (isInlineTrait(traitRef)) {
|
|
540
|
+
return { ref: traitRef.name };
|
|
541
|
+
}
|
|
542
|
+
return traitRef;
|
|
543
|
+
}
|
|
544
|
+
var OrbitalTraitRefSchema = TraitRefSchema;
|
|
545
|
+
var DomainCategorySchema = z.enum([
|
|
546
|
+
"healthcare",
|
|
547
|
+
"education",
|
|
548
|
+
"finance",
|
|
549
|
+
"ecommerce",
|
|
550
|
+
"real-estate",
|
|
551
|
+
"logistics",
|
|
552
|
+
"hospitality",
|
|
553
|
+
"hr-management",
|
|
554
|
+
"project-management",
|
|
555
|
+
"social",
|
|
556
|
+
"content-management",
|
|
557
|
+
"iot",
|
|
558
|
+
"analytics",
|
|
559
|
+
"game",
|
|
560
|
+
"custom"
|
|
561
|
+
]);
|
|
562
|
+
var GameSubCategorySchema = z.enum([
|
|
563
|
+
"platformer",
|
|
564
|
+
"shooter",
|
|
565
|
+
"puzzle",
|
|
566
|
+
"rpg",
|
|
567
|
+
"board",
|
|
568
|
+
"racing",
|
|
569
|
+
"fighting",
|
|
570
|
+
"tower-defense",
|
|
571
|
+
"endless-runner",
|
|
572
|
+
"simulation",
|
|
573
|
+
"arcade",
|
|
574
|
+
"adventure"
|
|
575
|
+
]);
|
|
576
|
+
var NodeClassificationSchema = z.enum(["domain", "system"]);
|
|
577
|
+
var StateSemanticRoleSchema = z.enum([
|
|
578
|
+
"pending",
|
|
579
|
+
"active",
|
|
580
|
+
"completed",
|
|
581
|
+
"cancelled",
|
|
582
|
+
"error",
|
|
583
|
+
"suspended",
|
|
584
|
+
"blocked",
|
|
585
|
+
"domain_workflow",
|
|
586
|
+
"domain_status",
|
|
587
|
+
"system_loading",
|
|
588
|
+
"system_error",
|
|
589
|
+
"system_idle",
|
|
590
|
+
"system_editing",
|
|
591
|
+
"system_confirming"
|
|
592
|
+
]);
|
|
593
|
+
var EventSemanticRoleSchema = z.enum([
|
|
594
|
+
"domain_action",
|
|
595
|
+
"domain_trigger",
|
|
596
|
+
"system_crud",
|
|
597
|
+
"system_navigation",
|
|
598
|
+
"system_form",
|
|
599
|
+
"system_ui"
|
|
600
|
+
]);
|
|
601
|
+
var EntitySemanticRoleSchema = z.enum([
|
|
602
|
+
"domain_core",
|
|
603
|
+
"domain_supporting",
|
|
604
|
+
"domain_reference",
|
|
605
|
+
"system_user",
|
|
606
|
+
"system_config",
|
|
607
|
+
"system_audit"
|
|
608
|
+
]);
|
|
609
|
+
var DomainVocabularySchema = z.record(z.string(), z.string()).optional();
|
|
610
|
+
var UserPersonaSchema = z.object({
|
|
611
|
+
name: z.string().min(1),
|
|
612
|
+
role: z.string().optional(),
|
|
613
|
+
device: z.enum(["mobile", "tablet", "desktop"]).optional()
|
|
614
|
+
});
|
|
615
|
+
var DomainContextSchema = z.object({
|
|
616
|
+
request: z.string().min(1, "Original request is required"),
|
|
617
|
+
requestFragment: z.string().optional(),
|
|
618
|
+
category: z.enum([
|
|
619
|
+
"game",
|
|
620
|
+
"business",
|
|
621
|
+
"dashboard",
|
|
622
|
+
"form",
|
|
623
|
+
"content",
|
|
624
|
+
"social"
|
|
625
|
+
]),
|
|
626
|
+
subDomain: z.string().optional(),
|
|
627
|
+
personas: z.array(UserPersonaSchema).optional(),
|
|
628
|
+
vocabulary: DomainVocabularySchema.optional()
|
|
629
|
+
});
|
|
630
|
+
var UXHintsSchema = z.object({
|
|
631
|
+
flowPattern: z.string().optional(),
|
|
632
|
+
listPattern: z.string().optional(),
|
|
633
|
+
formPattern: z.string().optional(),
|
|
634
|
+
detailPattern: z.string().optional(),
|
|
635
|
+
relatedLinks: z.array(z.lazy(() => RelatedLinkSchema)).optional()
|
|
636
|
+
});
|
|
637
|
+
var RelatedLinkSchema = z.object({
|
|
638
|
+
relation: z.string().min(1),
|
|
639
|
+
label: z.string().min(1),
|
|
640
|
+
targetView: z.enum(["list", "detail"]).optional()
|
|
641
|
+
});
|
|
642
|
+
var SuggestedGuardSchema = z.object({
|
|
643
|
+
id: z.string().min(1),
|
|
644
|
+
description: z.string().min(1),
|
|
645
|
+
appliesTo: z.array(z.string().min(1))
|
|
646
|
+
});
|
|
647
|
+
var DesignPreferencesSchema = z.object({
|
|
648
|
+
style: z.enum(["minimal", "modern", "playful", "data-driven", "immersive"]).optional(),
|
|
649
|
+
primaryColor: z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Must be valid hex color").optional(),
|
|
650
|
+
device: z.enum(["mobile", "tablet", "desktop", "all"]).optional(),
|
|
651
|
+
darkMode: z.boolean().optional(),
|
|
652
|
+
uxHints: UXHintsSchema.optional()
|
|
653
|
+
});
|
|
654
|
+
var ThemeTokensSchema = z.object({
|
|
655
|
+
colors: z.record(z.string(), z.string()).optional(),
|
|
656
|
+
radii: z.record(z.string(), z.string()).optional(),
|
|
657
|
+
spacing: z.record(z.string(), z.string()).optional(),
|
|
658
|
+
typography: z.record(z.string(), z.string()).optional(),
|
|
659
|
+
shadows: z.record(z.string(), z.string()).optional()
|
|
660
|
+
});
|
|
661
|
+
var ThemeVariantSchema = z.object({
|
|
662
|
+
colors: z.record(z.string(), z.string()).optional(),
|
|
663
|
+
radii: z.record(z.string(), z.string()).optional(),
|
|
664
|
+
spacing: z.record(z.string(), z.string()).optional(),
|
|
665
|
+
typography: z.record(z.string(), z.string()).optional(),
|
|
666
|
+
shadows: z.record(z.string(), z.string()).optional()
|
|
667
|
+
});
|
|
668
|
+
var ThemeDefinitionSchema = z.object({
|
|
669
|
+
name: z.string().min(1, "Theme name is required"),
|
|
670
|
+
tokens: ThemeTokensSchema,
|
|
671
|
+
variants: z.record(z.string(), ThemeVariantSchema).optional()
|
|
672
|
+
});
|
|
673
|
+
function isThemeReference(theme) {
|
|
674
|
+
return typeof theme === "string";
|
|
675
|
+
}
|
|
676
|
+
var ThemeRefStringSchema = z.string().regex(
|
|
677
|
+
/^[A-Z][a-zA-Z0-9]*\.theme$/,
|
|
678
|
+
'Theme reference must be in format "Alias.theme" (e.g., "Ocean.theme")'
|
|
679
|
+
);
|
|
680
|
+
var ThemeRefSchema = z.union([
|
|
681
|
+
ThemeDefinitionSchema,
|
|
682
|
+
ThemeRefStringSchema
|
|
683
|
+
]);
|
|
684
|
+
var DesignTokensSchema = z.record(z.string(), z.record(z.string(), z.string())).optional();
|
|
685
|
+
var ALLOWED_CUSTOM_COMPONENTS = [
|
|
686
|
+
"div",
|
|
687
|
+
"span",
|
|
688
|
+
"button",
|
|
689
|
+
"a",
|
|
690
|
+
"p",
|
|
691
|
+
"h1",
|
|
692
|
+
"h2",
|
|
693
|
+
"h3",
|
|
694
|
+
"h4",
|
|
695
|
+
"h5",
|
|
696
|
+
"h6",
|
|
697
|
+
"header",
|
|
698
|
+
"footer",
|
|
699
|
+
"section",
|
|
700
|
+
"article",
|
|
701
|
+
"nav",
|
|
702
|
+
"main",
|
|
703
|
+
"aside",
|
|
704
|
+
"ul",
|
|
705
|
+
"ol",
|
|
706
|
+
"li",
|
|
707
|
+
"img",
|
|
708
|
+
"label",
|
|
709
|
+
"input",
|
|
710
|
+
"form"
|
|
711
|
+
];
|
|
712
|
+
var CustomPatternDefinitionSchema = z.object({
|
|
713
|
+
type: z.literal("custom"),
|
|
714
|
+
component: z.enum(ALLOWED_CUSTOM_COMPONENTS),
|
|
715
|
+
className: z.string(),
|
|
716
|
+
slots: z.array(z.string()).optional(),
|
|
717
|
+
props: z.array(z.string()).optional()
|
|
718
|
+
});
|
|
719
|
+
var CustomPatternMapSchema = z.record(z.string(), CustomPatternDefinitionSchema).optional();
|
|
720
|
+
var SERVICE_TYPES = ["rest", "socket", "mcp"];
|
|
721
|
+
var ServiceTypeSchema = z.enum(SERVICE_TYPES);
|
|
722
|
+
var RestAuthConfigSchema = z.object({
|
|
723
|
+
type: z.enum(["api-key", "bearer", "basic", "oauth2"]),
|
|
724
|
+
keyName: z.string().optional(),
|
|
725
|
+
location: z.enum(["query", "header"]).optional(),
|
|
726
|
+
secretEnv: z.string().optional()
|
|
727
|
+
});
|
|
728
|
+
var RestServiceDefSchema = z.object({
|
|
729
|
+
name: z.string().min(1, "Service name is required"),
|
|
730
|
+
type: z.literal("rest"),
|
|
731
|
+
description: z.string().optional(),
|
|
732
|
+
baseUrl: z.string().url("Base URL must be a valid URL"),
|
|
733
|
+
headers: z.record(z.string()).optional(),
|
|
734
|
+
auth: RestAuthConfigSchema.optional(),
|
|
735
|
+
timeout: z.number().positive().optional()
|
|
736
|
+
});
|
|
737
|
+
var SocketEventsSchema = z.object({
|
|
738
|
+
inbound: z.array(z.string()),
|
|
739
|
+
outbound: z.array(z.string())
|
|
740
|
+
});
|
|
741
|
+
var SocketServiceDefSchema = z.object({
|
|
742
|
+
name: z.string().min(1, "Service name is required"),
|
|
743
|
+
type: z.literal("socket"),
|
|
744
|
+
description: z.string().optional(),
|
|
745
|
+
url: z.string().url("WebSocket URL must be valid"),
|
|
746
|
+
events: SocketEventsSchema,
|
|
747
|
+
reconnect: z.object({
|
|
748
|
+
enabled: z.boolean(),
|
|
749
|
+
maxAttempts: z.number().positive().optional(),
|
|
750
|
+
delayMs: z.number().positive().optional()
|
|
751
|
+
}).optional()
|
|
752
|
+
});
|
|
753
|
+
var McpServiceDefSchema = z.object({
|
|
754
|
+
name: z.string().min(1, "Service name is required"),
|
|
755
|
+
type: z.literal("mcp"),
|
|
756
|
+
description: z.string().optional(),
|
|
757
|
+
serverPath: z.string().min(1, "Server path is required"),
|
|
758
|
+
capabilities: z.array(z.string()).min(1, "At least one capability is required"),
|
|
759
|
+
env: z.record(z.string()).optional()
|
|
760
|
+
});
|
|
761
|
+
var ServiceDefinitionSchema = z.discriminatedUnion("type", [
|
|
762
|
+
RestServiceDefSchema,
|
|
763
|
+
SocketServiceDefSchema,
|
|
764
|
+
McpServiceDefSchema
|
|
765
|
+
]);
|
|
766
|
+
function isServiceReference(service) {
|
|
767
|
+
return typeof service === "string";
|
|
768
|
+
}
|
|
769
|
+
var ServiceRefStringSchema = z.string().regex(
|
|
770
|
+
/^[A-Z][a-zA-Z0-9]*\.services\.[a-zA-Z][a-zA-Z0-9]*$/,
|
|
771
|
+
'Service reference must be in format "Alias.services.ServiceName" (e.g., "Weather.services.openweather")'
|
|
772
|
+
);
|
|
773
|
+
var ServiceRefSchema = z.union([
|
|
774
|
+
ServiceDefinitionSchema,
|
|
775
|
+
ServiceRefStringSchema
|
|
776
|
+
]);
|
|
777
|
+
function parseServiceRef(ref) {
|
|
778
|
+
const match = ref.match(
|
|
779
|
+
/^([A-Z][a-zA-Z0-9]*)\.services\.([a-zA-Z][a-zA-Z0-9]*)$/
|
|
780
|
+
);
|
|
781
|
+
if (!match) return null;
|
|
782
|
+
return { alias: match[1], serviceName: match[2] };
|
|
783
|
+
}
|
|
784
|
+
function isRestService(service) {
|
|
785
|
+
return service.type === "rest";
|
|
786
|
+
}
|
|
787
|
+
function isSocketService(service) {
|
|
788
|
+
return service.type === "socket";
|
|
789
|
+
}
|
|
790
|
+
function isMcpService(service) {
|
|
791
|
+
return service.type === "mcp";
|
|
792
|
+
}
|
|
793
|
+
function getServiceNames(services) {
|
|
794
|
+
return services.map((s) => s.name);
|
|
795
|
+
}
|
|
796
|
+
function findService(services, name) {
|
|
797
|
+
return services.find((s) => s.name.toLowerCase() === name.toLowerCase());
|
|
798
|
+
}
|
|
799
|
+
function hasService(services, name) {
|
|
800
|
+
return services.some((s) => s.name.toLowerCase() === name.toLowerCase());
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// src/types/orbital.ts
|
|
804
|
+
var UseDeclarationSchema = z.object({
|
|
805
|
+
from: z.string().min(1, "Import source is required"),
|
|
806
|
+
as: z.string().min(1, "Alias is required").regex(
|
|
807
|
+
/^[A-Z][a-zA-Z0-9]*$/,
|
|
808
|
+
'Alias must be PascalCase (e.g., "Health", "GameCore")'
|
|
809
|
+
)
|
|
810
|
+
});
|
|
811
|
+
function isEntityReference(entity) {
|
|
812
|
+
return typeof entity === "string";
|
|
813
|
+
}
|
|
814
|
+
var EntityRefStringSchema = z.string().regex(
|
|
815
|
+
/^[A-Z][a-zA-Z0-9]*\.entity$/,
|
|
816
|
+
'Entity reference must be in format "Alias.entity" (e.g., "Goblin.entity")'
|
|
817
|
+
);
|
|
818
|
+
var EntityRefSchema = z.union([EntitySchema, EntityRefStringSchema]);
|
|
819
|
+
function isPageReferenceString(page) {
|
|
820
|
+
return typeof page === "string";
|
|
821
|
+
}
|
|
822
|
+
function isPageReferenceObject(page) {
|
|
823
|
+
return typeof page === "object" && "ref" in page && !("name" in page);
|
|
824
|
+
}
|
|
825
|
+
function isPageReference(page) {
|
|
826
|
+
return isPageReferenceString(page) || isPageReferenceObject(page);
|
|
827
|
+
}
|
|
828
|
+
var PageRefStringSchema = z.string().regex(
|
|
829
|
+
/^[A-Z][a-zA-Z0-9]*\.pages\.[A-Z][a-zA-Z0-9]*$/,
|
|
830
|
+
'Page reference must be in format "Alias.pages.PageName" (e.g., "User.pages.Profile")'
|
|
831
|
+
);
|
|
832
|
+
var PageRefObjectSchema = z.object({
|
|
833
|
+
ref: PageRefStringSchema,
|
|
834
|
+
path: z.string().startsWith("/").optional()
|
|
835
|
+
});
|
|
836
|
+
var PageRefSchema = z.union([
|
|
837
|
+
PageSchema,
|
|
838
|
+
PageRefStringSchema,
|
|
839
|
+
PageRefObjectSchema
|
|
840
|
+
]);
|
|
841
|
+
z.string().regex(
|
|
842
|
+
/^([A-Z][a-zA-Z0-9]*\.traits\.)?[A-Z][a-zA-Z0-9]*$/,
|
|
843
|
+
'Trait reference must be "TraitName" or "Alias.traits.TraitName"'
|
|
844
|
+
);
|
|
845
|
+
function isImportedTraitRef(ref) {
|
|
846
|
+
return /^[A-Z][a-zA-Z0-9]*\.traits\.[A-Z][a-zA-Z0-9]*$/.test(ref);
|
|
847
|
+
}
|
|
848
|
+
function parseImportedTraitRef(ref) {
|
|
849
|
+
const match = ref.match(/^([A-Z][a-zA-Z0-9]*)\.traits\.([A-Z][a-zA-Z0-9]*)$/);
|
|
850
|
+
if (!match) return null;
|
|
851
|
+
return { alias: match[1], traitName: match[2] };
|
|
852
|
+
}
|
|
853
|
+
function parseEntityRef(ref) {
|
|
854
|
+
const match = ref.match(/^([A-Z][a-zA-Z0-9]*)\.entity$/);
|
|
855
|
+
if (!match) return null;
|
|
856
|
+
return { alias: match[1] };
|
|
857
|
+
}
|
|
858
|
+
function parsePageRef(ref) {
|
|
859
|
+
const match = ref.match(/^([A-Z][a-zA-Z0-9]*)\.pages\.([A-Z][a-zA-Z0-9]*)$/);
|
|
860
|
+
if (!match) return null;
|
|
861
|
+
return { alias: match[1], pageName: match[2] };
|
|
862
|
+
}
|
|
863
|
+
var EventListenerSchema = z.object({
|
|
864
|
+
event: z.string().min(1),
|
|
865
|
+
triggers: z.string().min(1),
|
|
866
|
+
guard: z.string().optional()
|
|
867
|
+
});
|
|
868
|
+
var EventSourceSchema = z.object({
|
|
869
|
+
trait: z.string().min(1),
|
|
870
|
+
transition: z.string().optional(),
|
|
871
|
+
tick: z.string().optional()
|
|
872
|
+
});
|
|
873
|
+
var ComputedEventContractSchema = z.object({
|
|
874
|
+
event: z.string().min(1),
|
|
875
|
+
originalEvent: z.string().min(1),
|
|
876
|
+
source: EventSourceSchema,
|
|
877
|
+
description: z.string().optional(),
|
|
878
|
+
payload: z.array(EventPayloadFieldSchema).optional()
|
|
879
|
+
});
|
|
880
|
+
var ComputedEventListenerSchema = z.object({
|
|
881
|
+
event: z.string().min(1),
|
|
882
|
+
source: EventSourceSchema,
|
|
883
|
+
triggers: z.string().min(1),
|
|
884
|
+
guard: ExpressionSchema.optional(),
|
|
885
|
+
payloadMapping: z.record(z.string()).optional()
|
|
886
|
+
});
|
|
887
|
+
var OrbitalDefinitionSchema = z.object({
|
|
888
|
+
name: z.string().min(1, "Orbital name is required"),
|
|
889
|
+
description: z.string().optional(),
|
|
890
|
+
visual_prompt: z.string().optional(),
|
|
891
|
+
// Import system
|
|
892
|
+
uses: z.array(UseDeclarationSchema).optional(),
|
|
893
|
+
// Theme & Services
|
|
894
|
+
theme: ThemeRefSchema.optional(),
|
|
895
|
+
services: z.array(ServiceRefSchema).optional(),
|
|
896
|
+
// Components (inline or reference)
|
|
897
|
+
entity: EntityRefSchema,
|
|
898
|
+
traits: z.array(TraitRefSchema),
|
|
899
|
+
pages: z.array(PageRefSchema),
|
|
900
|
+
// Event interface (trait-centric model) - computed by resolver
|
|
901
|
+
emits: z.array(ComputedEventContractSchema).optional(),
|
|
902
|
+
listens: z.array(ComputedEventListenerSchema).optional(),
|
|
903
|
+
// Filter for exposed events (trait-centric model)
|
|
904
|
+
exposes: z.array(z.string()).optional(),
|
|
905
|
+
// Context fields - persisted throughout orbital lifecycle
|
|
906
|
+
domainContext: DomainContextSchema.optional(),
|
|
907
|
+
design: DesignPreferencesSchema.optional(),
|
|
908
|
+
suggestedGuards: z.array(SuggestedGuardSchema).optional()
|
|
909
|
+
});
|
|
910
|
+
var OrbitalSchema = OrbitalDefinitionSchema;
|
|
911
|
+
function isOrbitalDefinition(orbital) {
|
|
912
|
+
return "entity" in orbital;
|
|
913
|
+
}
|
|
914
|
+
var OrbitalUnitSchema = OrbitalSchema;
|
|
915
|
+
var OrbitalConfigSchema = z.object({
|
|
916
|
+
theme: z.object({
|
|
917
|
+
primary: z.string().optional(),
|
|
918
|
+
secondary: z.string().optional(),
|
|
919
|
+
mode: z.enum(["light", "dark", "system"]).optional()
|
|
920
|
+
}).optional(),
|
|
921
|
+
features: z.record(z.boolean()).optional(),
|
|
922
|
+
api: z.object({
|
|
923
|
+
baseUrl: z.string().optional(),
|
|
924
|
+
timeout: z.number().optional()
|
|
925
|
+
}).optional()
|
|
926
|
+
});
|
|
927
|
+
var OrbitalSchemaSchema = z.object({
|
|
928
|
+
name: z.string().min(1, "Schema name is required"),
|
|
929
|
+
description: z.string().optional(),
|
|
930
|
+
version: z.string().optional(),
|
|
931
|
+
domainContext: DomainContextSchema.optional(),
|
|
932
|
+
design: DesignPreferencesSchema.optional(),
|
|
933
|
+
designTokens: DesignTokensSchema,
|
|
934
|
+
customPatterns: CustomPatternMapSchema,
|
|
935
|
+
orbitals: z.array(OrbitalSchema).min(1, "At least one orbital is required"),
|
|
936
|
+
services: z.array(ServiceDefinitionSchema).optional(),
|
|
937
|
+
config: OrbitalConfigSchema.optional()
|
|
938
|
+
});
|
|
939
|
+
function parseOrbitalSchema(data) {
|
|
940
|
+
return OrbitalSchemaSchema.parse(data);
|
|
941
|
+
}
|
|
942
|
+
function safeParseOrbitalSchema(data) {
|
|
943
|
+
return OrbitalSchemaSchema.safeParse(data);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// src/types/operators.ts
|
|
947
|
+
var OPERATOR_CATEGORIES = [
|
|
948
|
+
"arithmetic",
|
|
949
|
+
"comparison",
|
|
950
|
+
"logic",
|
|
951
|
+
"control",
|
|
952
|
+
"effect",
|
|
953
|
+
"collection",
|
|
954
|
+
// Standard library categories
|
|
955
|
+
"std-math",
|
|
956
|
+
"std-str",
|
|
957
|
+
"std-array",
|
|
958
|
+
"std-object",
|
|
959
|
+
"std-validate",
|
|
960
|
+
"std-time",
|
|
961
|
+
"std-format",
|
|
962
|
+
"std-async",
|
|
963
|
+
"std-nn",
|
|
964
|
+
"std-tensor",
|
|
965
|
+
"std-train"
|
|
966
|
+
];
|
|
967
|
+
var OPERATORS = {
|
|
968
|
+
// ============================================================================
|
|
969
|
+
// Arithmetic Operators
|
|
970
|
+
// ============================================================================
|
|
971
|
+
"+": {
|
|
972
|
+
category: "arithmetic",
|
|
973
|
+
minArity: 2,
|
|
974
|
+
maxArity: null,
|
|
975
|
+
description: "Add numbers",
|
|
976
|
+
hasSideEffects: false,
|
|
977
|
+
returnType: "number"
|
|
978
|
+
},
|
|
979
|
+
"-": {
|
|
980
|
+
category: "arithmetic",
|
|
981
|
+
minArity: 1,
|
|
982
|
+
maxArity: 2,
|
|
983
|
+
description: "Subtract numbers or negate",
|
|
984
|
+
hasSideEffects: false,
|
|
985
|
+
returnType: "number"
|
|
986
|
+
},
|
|
987
|
+
"*": {
|
|
988
|
+
category: "arithmetic",
|
|
989
|
+
minArity: 2,
|
|
990
|
+
maxArity: null,
|
|
991
|
+
description: "Multiply numbers",
|
|
992
|
+
hasSideEffects: false,
|
|
993
|
+
returnType: "number"
|
|
994
|
+
},
|
|
995
|
+
"/": {
|
|
996
|
+
category: "arithmetic",
|
|
997
|
+
minArity: 2,
|
|
998
|
+
maxArity: 2,
|
|
999
|
+
description: "Divide numbers",
|
|
1000
|
+
hasSideEffects: false,
|
|
1001
|
+
returnType: "number"
|
|
1002
|
+
},
|
|
1003
|
+
"%": {
|
|
1004
|
+
category: "arithmetic",
|
|
1005
|
+
minArity: 2,
|
|
1006
|
+
maxArity: 2,
|
|
1007
|
+
description: "Modulo (remainder)",
|
|
1008
|
+
hasSideEffects: false,
|
|
1009
|
+
returnType: "number"
|
|
1010
|
+
},
|
|
1011
|
+
abs: {
|
|
1012
|
+
category: "arithmetic",
|
|
1013
|
+
minArity: 1,
|
|
1014
|
+
maxArity: 1,
|
|
1015
|
+
description: "Absolute value",
|
|
1016
|
+
hasSideEffects: false,
|
|
1017
|
+
returnType: "number"
|
|
1018
|
+
},
|
|
1019
|
+
min: {
|
|
1020
|
+
category: "arithmetic",
|
|
1021
|
+
minArity: 2,
|
|
1022
|
+
maxArity: null,
|
|
1023
|
+
description: "Minimum of values",
|
|
1024
|
+
hasSideEffects: false,
|
|
1025
|
+
returnType: "number"
|
|
1026
|
+
},
|
|
1027
|
+
max: {
|
|
1028
|
+
category: "arithmetic",
|
|
1029
|
+
minArity: 2,
|
|
1030
|
+
maxArity: null,
|
|
1031
|
+
description: "Maximum of values",
|
|
1032
|
+
hasSideEffects: false,
|
|
1033
|
+
returnType: "number"
|
|
1034
|
+
},
|
|
1035
|
+
floor: {
|
|
1036
|
+
category: "arithmetic",
|
|
1037
|
+
minArity: 1,
|
|
1038
|
+
maxArity: 1,
|
|
1039
|
+
description: "Round down to integer",
|
|
1040
|
+
hasSideEffects: false,
|
|
1041
|
+
returnType: "number"
|
|
1042
|
+
},
|
|
1043
|
+
ceil: {
|
|
1044
|
+
category: "arithmetic",
|
|
1045
|
+
minArity: 1,
|
|
1046
|
+
maxArity: 1,
|
|
1047
|
+
description: "Round up to integer",
|
|
1048
|
+
hasSideEffects: false,
|
|
1049
|
+
returnType: "number"
|
|
1050
|
+
},
|
|
1051
|
+
round: {
|
|
1052
|
+
category: "arithmetic",
|
|
1053
|
+
minArity: 1,
|
|
1054
|
+
maxArity: 1,
|
|
1055
|
+
description: "Round to nearest integer",
|
|
1056
|
+
hasSideEffects: false,
|
|
1057
|
+
returnType: "number"
|
|
1058
|
+
},
|
|
1059
|
+
clamp: {
|
|
1060
|
+
category: "arithmetic",
|
|
1061
|
+
minArity: 3,
|
|
1062
|
+
maxArity: 3,
|
|
1063
|
+
description: "Clamp value between min and max",
|
|
1064
|
+
hasSideEffects: false,
|
|
1065
|
+
returnType: "number"
|
|
1066
|
+
},
|
|
1067
|
+
// ============================================================================
|
|
1068
|
+
// Comparison Operators
|
|
1069
|
+
// ============================================================================
|
|
1070
|
+
"=": {
|
|
1071
|
+
category: "comparison",
|
|
1072
|
+
minArity: 2,
|
|
1073
|
+
maxArity: 2,
|
|
1074
|
+
description: "Equal to",
|
|
1075
|
+
hasSideEffects: false,
|
|
1076
|
+
returnType: "boolean"
|
|
1077
|
+
},
|
|
1078
|
+
"!=": {
|
|
1079
|
+
category: "comparison",
|
|
1080
|
+
minArity: 2,
|
|
1081
|
+
maxArity: 2,
|
|
1082
|
+
description: "Not equal to",
|
|
1083
|
+
hasSideEffects: false,
|
|
1084
|
+
returnType: "boolean"
|
|
1085
|
+
},
|
|
1086
|
+
"<": {
|
|
1087
|
+
category: "comparison",
|
|
1088
|
+
minArity: 2,
|
|
1089
|
+
maxArity: 2,
|
|
1090
|
+
description: "Less than",
|
|
1091
|
+
hasSideEffects: false,
|
|
1092
|
+
returnType: "boolean"
|
|
1093
|
+
},
|
|
1094
|
+
">": {
|
|
1095
|
+
category: "comparison",
|
|
1096
|
+
minArity: 2,
|
|
1097
|
+
maxArity: 2,
|
|
1098
|
+
description: "Greater than",
|
|
1099
|
+
hasSideEffects: false,
|
|
1100
|
+
returnType: "boolean"
|
|
1101
|
+
},
|
|
1102
|
+
"<=": {
|
|
1103
|
+
category: "comparison",
|
|
1104
|
+
minArity: 2,
|
|
1105
|
+
maxArity: 2,
|
|
1106
|
+
description: "Less than or equal to",
|
|
1107
|
+
hasSideEffects: false,
|
|
1108
|
+
returnType: "boolean"
|
|
1109
|
+
},
|
|
1110
|
+
">=": {
|
|
1111
|
+
category: "comparison",
|
|
1112
|
+
minArity: 2,
|
|
1113
|
+
maxArity: 2,
|
|
1114
|
+
description: "Greater than or equal to",
|
|
1115
|
+
hasSideEffects: false,
|
|
1116
|
+
returnType: "boolean"
|
|
1117
|
+
},
|
|
1118
|
+
// ============================================================================
|
|
1119
|
+
// Logic Operators
|
|
1120
|
+
// ============================================================================
|
|
1121
|
+
and: {
|
|
1122
|
+
category: "logic",
|
|
1123
|
+
minArity: 2,
|
|
1124
|
+
maxArity: null,
|
|
1125
|
+
description: "Logical AND (short-circuit)",
|
|
1126
|
+
hasSideEffects: false,
|
|
1127
|
+
returnType: "boolean"
|
|
1128
|
+
},
|
|
1129
|
+
or: {
|
|
1130
|
+
category: "logic",
|
|
1131
|
+
minArity: 2,
|
|
1132
|
+
maxArity: null,
|
|
1133
|
+
description: "Logical OR (short-circuit)",
|
|
1134
|
+
hasSideEffects: false,
|
|
1135
|
+
returnType: "boolean"
|
|
1136
|
+
},
|
|
1137
|
+
not: {
|
|
1138
|
+
category: "logic",
|
|
1139
|
+
minArity: 1,
|
|
1140
|
+
maxArity: 1,
|
|
1141
|
+
description: "Logical NOT",
|
|
1142
|
+
hasSideEffects: false,
|
|
1143
|
+
returnType: "boolean"
|
|
1144
|
+
},
|
|
1145
|
+
if: {
|
|
1146
|
+
category: "logic",
|
|
1147
|
+
minArity: 3,
|
|
1148
|
+
maxArity: 3,
|
|
1149
|
+
description: "Conditional expression (if condition then else)",
|
|
1150
|
+
hasSideEffects: false,
|
|
1151
|
+
returnType: "any"
|
|
1152
|
+
},
|
|
1153
|
+
// ============================================================================
|
|
1154
|
+
// Control Operators
|
|
1155
|
+
// ============================================================================
|
|
1156
|
+
let: {
|
|
1157
|
+
category: "control",
|
|
1158
|
+
minArity: 2,
|
|
1159
|
+
maxArity: 2,
|
|
1160
|
+
description: "Bind local variables: [let, [[name, value], ...], body]",
|
|
1161
|
+
hasSideEffects: false,
|
|
1162
|
+
returnType: "any"
|
|
1163
|
+
},
|
|
1164
|
+
do: {
|
|
1165
|
+
category: "control",
|
|
1166
|
+
minArity: 1,
|
|
1167
|
+
maxArity: null,
|
|
1168
|
+
description: "Execute expressions in sequence, return last",
|
|
1169
|
+
hasSideEffects: true,
|
|
1170
|
+
returnType: "any"
|
|
1171
|
+
},
|
|
1172
|
+
when: {
|
|
1173
|
+
category: "control",
|
|
1174
|
+
minArity: 2,
|
|
1175
|
+
maxArity: 2,
|
|
1176
|
+
description: "Execute effect only when condition is true",
|
|
1177
|
+
hasSideEffects: true,
|
|
1178
|
+
returnType: "void"
|
|
1179
|
+
},
|
|
1180
|
+
fn: {
|
|
1181
|
+
category: "control",
|
|
1182
|
+
minArity: 2,
|
|
1183
|
+
maxArity: 2,
|
|
1184
|
+
description: "Lambda expression: [fn, varName, body] or [fn, [vars], body]",
|
|
1185
|
+
hasSideEffects: false,
|
|
1186
|
+
returnType: "any"
|
|
1187
|
+
},
|
|
1188
|
+
// ============================================================================
|
|
1189
|
+
// Effect Operators
|
|
1190
|
+
// ============================================================================
|
|
1191
|
+
set: {
|
|
1192
|
+
category: "effect",
|
|
1193
|
+
minArity: 2,
|
|
1194
|
+
maxArity: 2,
|
|
1195
|
+
description: "Set a binding to a value",
|
|
1196
|
+
hasSideEffects: true,
|
|
1197
|
+
returnType: "void"
|
|
1198
|
+
},
|
|
1199
|
+
emit: {
|
|
1200
|
+
category: "effect",
|
|
1201
|
+
minArity: 1,
|
|
1202
|
+
maxArity: 2,
|
|
1203
|
+
description: "Emit an event with optional payload",
|
|
1204
|
+
hasSideEffects: true,
|
|
1205
|
+
returnType: "void"
|
|
1206
|
+
},
|
|
1207
|
+
persist: {
|
|
1208
|
+
category: "effect",
|
|
1209
|
+
minArity: 2,
|
|
1210
|
+
maxArity: 3,
|
|
1211
|
+
description: "Persist data (create/update/delete)",
|
|
1212
|
+
hasSideEffects: true,
|
|
1213
|
+
returnType: "void"
|
|
1214
|
+
},
|
|
1215
|
+
navigate: {
|
|
1216
|
+
category: "effect",
|
|
1217
|
+
minArity: 1,
|
|
1218
|
+
maxArity: 2,
|
|
1219
|
+
description: "Navigate to a route",
|
|
1220
|
+
hasSideEffects: true,
|
|
1221
|
+
returnType: "void"
|
|
1222
|
+
},
|
|
1223
|
+
notify: {
|
|
1224
|
+
category: "effect",
|
|
1225
|
+
minArity: 1,
|
|
1226
|
+
maxArity: 2,
|
|
1227
|
+
description: "Show a notification",
|
|
1228
|
+
hasSideEffects: true,
|
|
1229
|
+
returnType: "void"
|
|
1230
|
+
},
|
|
1231
|
+
spawn: {
|
|
1232
|
+
category: "effect",
|
|
1233
|
+
minArity: 1,
|
|
1234
|
+
maxArity: 2,
|
|
1235
|
+
description: "Spawn a new entity instance",
|
|
1236
|
+
hasSideEffects: true,
|
|
1237
|
+
returnType: "void"
|
|
1238
|
+
},
|
|
1239
|
+
despawn: {
|
|
1240
|
+
category: "effect",
|
|
1241
|
+
minArity: 0,
|
|
1242
|
+
maxArity: 1,
|
|
1243
|
+
description: "Despawn an entity instance",
|
|
1244
|
+
hasSideEffects: true,
|
|
1245
|
+
returnType: "void"
|
|
1246
|
+
},
|
|
1247
|
+
"call-service": {
|
|
1248
|
+
category: "effect",
|
|
1249
|
+
minArity: 2,
|
|
1250
|
+
maxArity: 3,
|
|
1251
|
+
description: "Call an external service",
|
|
1252
|
+
hasSideEffects: true,
|
|
1253
|
+
returnType: "void"
|
|
1254
|
+
},
|
|
1255
|
+
"render-ui": {
|
|
1256
|
+
category: "effect",
|
|
1257
|
+
minArity: 2,
|
|
1258
|
+
maxArity: 3,
|
|
1259
|
+
description: "Render UI to a slot",
|
|
1260
|
+
hasSideEffects: true,
|
|
1261
|
+
returnType: "void"
|
|
1262
|
+
},
|
|
1263
|
+
// ============================================================================
|
|
1264
|
+
// Collection Operators
|
|
1265
|
+
// ============================================================================
|
|
1266
|
+
map: {
|
|
1267
|
+
category: "collection",
|
|
1268
|
+
minArity: 2,
|
|
1269
|
+
maxArity: 2,
|
|
1270
|
+
description: "Transform each element in collection",
|
|
1271
|
+
hasSideEffects: false,
|
|
1272
|
+
returnType: "array"
|
|
1273
|
+
},
|
|
1274
|
+
filter: {
|
|
1275
|
+
category: "collection",
|
|
1276
|
+
minArity: 2,
|
|
1277
|
+
maxArity: 2,
|
|
1278
|
+
description: "Filter collection by predicate",
|
|
1279
|
+
hasSideEffects: false,
|
|
1280
|
+
returnType: "array"
|
|
1281
|
+
},
|
|
1282
|
+
find: {
|
|
1283
|
+
category: "collection",
|
|
1284
|
+
minArity: 2,
|
|
1285
|
+
maxArity: 2,
|
|
1286
|
+
description: "Find first element matching predicate",
|
|
1287
|
+
hasSideEffects: false,
|
|
1288
|
+
returnType: "any"
|
|
1289
|
+
},
|
|
1290
|
+
count: {
|
|
1291
|
+
category: "collection",
|
|
1292
|
+
minArity: 1,
|
|
1293
|
+
maxArity: 1,
|
|
1294
|
+
description: "Count elements in collection",
|
|
1295
|
+
hasSideEffects: false,
|
|
1296
|
+
returnType: "number"
|
|
1297
|
+
},
|
|
1298
|
+
sum: {
|
|
1299
|
+
category: "collection",
|
|
1300
|
+
minArity: 1,
|
|
1301
|
+
maxArity: 2,
|
|
1302
|
+
description: "Sum values in collection",
|
|
1303
|
+
hasSideEffects: false,
|
|
1304
|
+
returnType: "number"
|
|
1305
|
+
},
|
|
1306
|
+
first: {
|
|
1307
|
+
category: "collection",
|
|
1308
|
+
minArity: 1,
|
|
1309
|
+
maxArity: 1,
|
|
1310
|
+
description: "Get first element",
|
|
1311
|
+
hasSideEffects: false,
|
|
1312
|
+
returnType: "any"
|
|
1313
|
+
},
|
|
1314
|
+
last: {
|
|
1315
|
+
category: "collection",
|
|
1316
|
+
minArity: 1,
|
|
1317
|
+
maxArity: 1,
|
|
1318
|
+
description: "Get last element",
|
|
1319
|
+
hasSideEffects: false,
|
|
1320
|
+
returnType: "any"
|
|
1321
|
+
},
|
|
1322
|
+
nth: {
|
|
1323
|
+
category: "collection",
|
|
1324
|
+
minArity: 2,
|
|
1325
|
+
maxArity: 2,
|
|
1326
|
+
description: "Get element at index",
|
|
1327
|
+
hasSideEffects: false,
|
|
1328
|
+
returnType: "any"
|
|
1329
|
+
},
|
|
1330
|
+
concat: {
|
|
1331
|
+
category: "collection",
|
|
1332
|
+
minArity: 2,
|
|
1333
|
+
maxArity: null,
|
|
1334
|
+
description: "Concatenate collections",
|
|
1335
|
+
hasSideEffects: false,
|
|
1336
|
+
returnType: "array"
|
|
1337
|
+
},
|
|
1338
|
+
includes: {
|
|
1339
|
+
category: "collection",
|
|
1340
|
+
minArity: 2,
|
|
1341
|
+
maxArity: 2,
|
|
1342
|
+
description: "Check if collection includes element",
|
|
1343
|
+
hasSideEffects: false,
|
|
1344
|
+
returnType: "boolean"
|
|
1345
|
+
},
|
|
1346
|
+
empty: {
|
|
1347
|
+
category: "collection",
|
|
1348
|
+
minArity: 1,
|
|
1349
|
+
maxArity: 1,
|
|
1350
|
+
description: "Check if collection is empty",
|
|
1351
|
+
hasSideEffects: false,
|
|
1352
|
+
returnType: "boolean"
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
function getOperatorMeta(operator) {
|
|
1356
|
+
return OPERATORS[operator];
|
|
1357
|
+
}
|
|
1358
|
+
function isKnownOperator(operator) {
|
|
1359
|
+
return operator in OPERATORS;
|
|
1360
|
+
}
|
|
1361
|
+
function isEffectOperator(operator) {
|
|
1362
|
+
const meta = OPERATORS[operator];
|
|
1363
|
+
return meta?.hasSideEffects ?? false;
|
|
1364
|
+
}
|
|
1365
|
+
function isGuardOperator(operator) {
|
|
1366
|
+
const meta = OPERATORS[operator];
|
|
1367
|
+
return meta !== void 0 && !meta.hasSideEffects;
|
|
1368
|
+
}
|
|
1369
|
+
function getOperatorsByCategory(category) {
|
|
1370
|
+
return Object.entries(OPERATORS).filter(([_, meta]) => meta.category === category).map(([name]) => name);
|
|
1371
|
+
}
|
|
1372
|
+
function getAllOperators() {
|
|
1373
|
+
return Object.keys(OPERATORS);
|
|
1374
|
+
}
|
|
1375
|
+
function validateOperatorArity(operator, argCount) {
|
|
1376
|
+
const meta = OPERATORS[operator];
|
|
1377
|
+
if (!meta) {
|
|
1378
|
+
return `Unknown operator: ${operator}`;
|
|
1379
|
+
}
|
|
1380
|
+
if (argCount < meta.minArity) {
|
|
1381
|
+
return `Operator '${operator}' requires at least ${meta.minArity} argument(s), got ${argCount}`;
|
|
1382
|
+
}
|
|
1383
|
+
if (meta.maxArity !== null && argCount > meta.maxArity) {
|
|
1384
|
+
return `Operator '${operator}' accepts at most ${meta.maxArity} argument(s), got ${argCount}`;
|
|
1385
|
+
}
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
var BindingSchema = z.string().refine(
|
|
1389
|
+
(val) => {
|
|
1390
|
+
if (!val.startsWith("@")) return false;
|
|
1391
|
+
const parts = val.slice(1).split(".");
|
|
1392
|
+
if (parts.length === 0 || parts[0] === "") return false;
|
|
1393
|
+
return parts.every((part) => /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(part));
|
|
1394
|
+
},
|
|
1395
|
+
{ message: "Invalid binding format. Must be @name or @name.path.to.field" }
|
|
1396
|
+
);
|
|
1397
|
+
var BINDING_DOCS = {
|
|
1398
|
+
entity: {
|
|
1399
|
+
description: "Reference to the linked entity for this trait",
|
|
1400
|
+
examples: ["@entity.health", "@entity.x", "@entity.status"],
|
|
1401
|
+
requiresPath: true
|
|
1402
|
+
},
|
|
1403
|
+
payload: {
|
|
1404
|
+
description: "Reference to the event payload data",
|
|
1405
|
+
examples: ["@payload.amount", "@payload.targetId", "@payload.action"],
|
|
1406
|
+
requiresPath: true
|
|
1407
|
+
},
|
|
1408
|
+
state: {
|
|
1409
|
+
description: "Current state machine state name",
|
|
1410
|
+
examples: ["@state"],
|
|
1411
|
+
requiresPath: false
|
|
1412
|
+
},
|
|
1413
|
+
now: {
|
|
1414
|
+
description: "Current timestamp in milliseconds",
|
|
1415
|
+
examples: ["@now"],
|
|
1416
|
+
requiresPath: false
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
var BINDING_CONTEXT_RULES = {
|
|
1420
|
+
guard: {
|
|
1421
|
+
allowed: ["entity", "payload", "state", "now"],
|
|
1422
|
+
description: "Guards can access entity fields, event payload, current state, and time"
|
|
1423
|
+
},
|
|
1424
|
+
effect: {
|
|
1425
|
+
allowed: ["entity", "payload", "state", "now"],
|
|
1426
|
+
description: "Effects can access and modify entity fields, use payload data"
|
|
1427
|
+
},
|
|
1428
|
+
tick: {
|
|
1429
|
+
allowed: ["entity", "state", "now"],
|
|
1430
|
+
description: "Ticks can access entity fields, current state, and time (no payload)"
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
1433
|
+
function validateBindingInContext(binding, context) {
|
|
1434
|
+
const rules = BINDING_CONTEXT_RULES[context];
|
|
1435
|
+
if (binding.type === "core") {
|
|
1436
|
+
if (!rules.allowed.includes(binding.root)) {
|
|
1437
|
+
return `Binding @${binding.root} is not allowed in ${context} context. Allowed: ${rules.allowed.join(", ")}`;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
return null;
|
|
1441
|
+
}
|
|
1442
|
+
function getBindingExamples(context) {
|
|
1443
|
+
const rules = BINDING_CONTEXT_RULES[context];
|
|
1444
|
+
const examples = [];
|
|
1445
|
+
for (const binding of rules.allowed) {
|
|
1446
|
+
const doc = BINDING_DOCS[binding];
|
|
1447
|
+
examples.push(...doc.examples);
|
|
1448
|
+
}
|
|
1449
|
+
examples.push("@GameConfig.gravity", "@Filter.searchTerm");
|
|
1450
|
+
return examples;
|
|
1451
|
+
}
|
|
1452
|
+
var InteractionModelSchema = z.object({
|
|
1453
|
+
createFlow: z.enum(["modal", "page", "inline", "none"]),
|
|
1454
|
+
editFlow: z.enum(["modal", "page", "inline", "none"]),
|
|
1455
|
+
viewFlow: z.enum(["drawer", "page", "modal", "inline", "none"]),
|
|
1456
|
+
deleteFlow: z.enum(["confirm", "instant", "none"]),
|
|
1457
|
+
listInteraction: z.enum(["click-to-view", "click-to-edit", "inline-edit"]).optional(),
|
|
1458
|
+
bulkActions: z.boolean().optional(),
|
|
1459
|
+
realtime: z.boolean().optional()
|
|
1460
|
+
});
|
|
1461
|
+
var DEFAULT_INTERACTION_MODELS = {
|
|
1462
|
+
business: {
|
|
1463
|
+
createFlow: "modal",
|
|
1464
|
+
editFlow: "modal",
|
|
1465
|
+
viewFlow: "drawer",
|
|
1466
|
+
deleteFlow: "confirm",
|
|
1467
|
+
listInteraction: "click-to-view",
|
|
1468
|
+
bulkActions: true
|
|
1469
|
+
},
|
|
1470
|
+
game: {
|
|
1471
|
+
createFlow: "none",
|
|
1472
|
+
editFlow: "none",
|
|
1473
|
+
viewFlow: "none",
|
|
1474
|
+
deleteFlow: "none",
|
|
1475
|
+
realtime: true
|
|
1476
|
+
},
|
|
1477
|
+
form: {
|
|
1478
|
+
createFlow: "inline",
|
|
1479
|
+
editFlow: "inline",
|
|
1480
|
+
viewFlow: "none",
|
|
1481
|
+
deleteFlow: "none"
|
|
1482
|
+
},
|
|
1483
|
+
dashboard: {
|
|
1484
|
+
createFlow: "modal",
|
|
1485
|
+
editFlow: "modal",
|
|
1486
|
+
viewFlow: "drawer",
|
|
1487
|
+
deleteFlow: "confirm",
|
|
1488
|
+
listInteraction: "click-to-view"
|
|
1489
|
+
},
|
|
1490
|
+
content: {
|
|
1491
|
+
createFlow: "page",
|
|
1492
|
+
editFlow: "page",
|
|
1493
|
+
viewFlow: "page",
|
|
1494
|
+
deleteFlow: "confirm",
|
|
1495
|
+
listInteraction: "click-to-view"
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
function getInteractionModelForDomain(domain) {
|
|
1499
|
+
return DEFAULT_INTERACTION_MODELS[domain] ?? DEFAULT_INTERACTION_MODELS.business;
|
|
1500
|
+
}
|
|
1501
|
+
var PATTERN_TYPES = [
|
|
1502
|
+
// Display patterns
|
|
1503
|
+
"entity-table",
|
|
1504
|
+
"entity-list",
|
|
1505
|
+
"entity-cards",
|
|
1506
|
+
"entity-grid",
|
|
1507
|
+
// Form patterns
|
|
1508
|
+
"form",
|
|
1509
|
+
"form-section",
|
|
1510
|
+
// Header patterns
|
|
1511
|
+
"page-header",
|
|
1512
|
+
// Stats patterns
|
|
1513
|
+
"stats",
|
|
1514
|
+
"stat-card",
|
|
1515
|
+
// Layout patterns
|
|
1516
|
+
"master-detail",
|
|
1517
|
+
"dashboard-grid",
|
|
1518
|
+
// Game patterns
|
|
1519
|
+
"game-canvas",
|
|
1520
|
+
"game-hud",
|
|
1521
|
+
"game-controls"
|
|
1522
|
+
];
|
|
1523
|
+
var PatternTypeSchema = z.string();
|
|
1524
|
+
function getAllPatternTypes() {
|
|
1525
|
+
return [...PATTERN_TYPES];
|
|
1526
|
+
}
|
|
1527
|
+
function isValidPatternType(patternType) {
|
|
1528
|
+
return PATTERN_TYPES.includes(patternType);
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
// src/types/ir.ts
|
|
1532
|
+
function createEmptyResolvedTrait(name, source) {
|
|
1533
|
+
return {
|
|
1534
|
+
name,
|
|
1535
|
+
source,
|
|
1536
|
+
states: [],
|
|
1537
|
+
events: [],
|
|
1538
|
+
transitions: [],
|
|
1539
|
+
guards: [],
|
|
1540
|
+
ticks: [],
|
|
1541
|
+
listens: [],
|
|
1542
|
+
dataEntities: []
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
function createEmptyResolvedPage(name) {
|
|
1546
|
+
return {
|
|
1547
|
+
name,
|
|
1548
|
+
path: `/${name.toLowerCase()}`,
|
|
1549
|
+
featureName: name.toLowerCase(),
|
|
1550
|
+
sections: [],
|
|
1551
|
+
traits: [],
|
|
1552
|
+
entityBindings: [],
|
|
1553
|
+
navigation: [],
|
|
1554
|
+
singletonEntities: []
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
function inferTsType(schemaType) {
|
|
1558
|
+
const typeMap = {
|
|
1559
|
+
string: "string",
|
|
1560
|
+
number: "number",
|
|
1561
|
+
boolean: "boolean",
|
|
1562
|
+
date: "Date",
|
|
1563
|
+
datetime: "Date",
|
|
1564
|
+
timestamp: "number",
|
|
1565
|
+
array: "unknown[]",
|
|
1566
|
+
object: "Record<string, unknown>",
|
|
1567
|
+
any: "unknown"
|
|
1568
|
+
};
|
|
1569
|
+
if (schemaType.endsWith("[]")) {
|
|
1570
|
+
const baseType = schemaType.slice(0, -2);
|
|
1571
|
+
return `${typeMap[baseType] || baseType}[]`;
|
|
1572
|
+
}
|
|
1573
|
+
return typeMap[schemaType] || schemaType;
|
|
1574
|
+
}
|
|
1575
|
+
function createResolvedField(field) {
|
|
1576
|
+
return {
|
|
1577
|
+
name: field.name,
|
|
1578
|
+
type: field.type,
|
|
1579
|
+
tsType: inferTsType(field.type),
|
|
1580
|
+
description: field.description,
|
|
1581
|
+
default: field.default,
|
|
1582
|
+
required: field.required ?? false,
|
|
1583
|
+
validation: field.validation,
|
|
1584
|
+
values: field.values
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
function isResolvedIR(ir) {
|
|
1588
|
+
if (!ir || typeof ir !== "object") return false;
|
|
1589
|
+
const r = ir;
|
|
1590
|
+
return typeof r.appName === "string" && r.traits instanceof Map && r.pages instanceof Map;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
export { ALLOWED_CUSTOM_COMPONENTS, AnimationDefSchema, AssetMapSchema, AssetMappingSchema, BINDING_CONTEXT_RULES, BINDING_DOCS, BindingSchema, CORE_BINDINGS, ComputedEventContractSchema, ComputedEventListenerSchema, CustomPatternDefinitionSchema, CustomPatternMapSchema, DEFAULT_INTERACTION_MODELS, DesignPreferencesSchema, DesignTokensSchema, DomainCategorySchema, DomainContextSchema, DomainVocabularySchema, ENTITY_ROLES, EffectSchema, EntityFieldSchema, EntityPersistenceSchema, EntityRefSchema, EntityRefStringSchema, EntityRoleSchema, EntitySchema, EntitySemanticRoleSchema, EventListenerSchema, EventPayloadFieldSchema, EventSchema, EventScopeSchema, EventSemanticRoleSchema, EventSourceSchema, ExpressionSchema, FieldFormatSchema, FieldSchema, FieldTypeSchema, GAME_TYPES, GameSubCategorySchema, GameTypeSchema, GuardSchema, InteractionModelSchema, McpServiceDefSchema, NodeClassificationSchema, OPERATORS, OPERATOR_CATEGORIES, OrbitalConfigSchema, OrbitalDefinitionSchema, OrbitalEntitySchema, OrbitalPageSchema, OrbitalPageStrictSchema, OrbitalSchemaSchema, OrbitalTraitRefSchema, OrbitalUnitSchema, OrbitalSchema as OrbitalZodSchema, PATTERN_TYPES, PageRefObjectSchema, PageRefSchema, PageRefStringSchema, PageSchema, PageTraitRefSchema, PatternTypeSchema, PayloadFieldSchema, RelatedLinkSchema, RelationConfigSchema, RequiredFieldSchema, ResolvedAssetSchema, RestAuthConfigSchema, RestServiceDefSchema, SERVICE_TYPES, SExprAtomSchema, SExprSchema, SemanticAssetRefSchema, ServiceDefinitionSchema, ServiceRefSchema, ServiceRefStringSchema, ServiceTypeSchema, SocketEventsSchema, SocketServiceDefSchema, StateMachineSchema, StateSchema, StateSemanticRoleSchema, SuggestedGuardSchema, ThemeDefinitionSchema, ThemeRefSchema, ThemeRefStringSchema, ThemeTokensSchema, ThemeVariantSchema, TraitCategorySchema, TraitDataEntitySchema, TraitEntityFieldSchema, TraitEventContractSchema, TraitEventListenerSchema, TraitRefSchema, TraitReferenceSchema, TraitSchema, TraitTickSchema, TransitionSchema, UISlotSchema, UI_SLOTS, UXHintsSchema, UseDeclarationSchema, UserPersonaSchema, VISUAL_STYLES, ViewTypeSchema, VisualStyleSchema, callService, collectBindings, createAssetKey, createEmptyResolvedPage, createEmptyResolvedTrait, createResolvedField, deriveCollection, despawn, doEffects, emit, findService, getAllOperators, getAllPatternTypes, getArgs, getBindingExamples, getDefaultAnimationsForRole, getInteractionModelForDomain, getOperator, getOperatorMeta, getOperatorsByCategory, getServiceNames, getTraitConfig, getTraitName, hasService, inferTsType, isBinding, isEffect, isEffectOperator, isEntityReference, isGuardOperator, isImportedTraitRef, isInlineTrait, isKnownOperator, isMcpService, isOrbitalDefinition, isPageReference, isPageReferenceObject, isPageReferenceString, isResolvedIR, isRestService, isRuntimeEntity, isSExpr, isSExprAtom, isSExprCall, isSExprEffect, isServiceReference, isSingletonEntity, isSocketService, isThemeReference, isValidBinding, isValidPatternType, navigate, normalizeTraitRef, notify, parseAssetKey, parseBinding, parseEntityRef, parseImportedTraitRef, parseOrbitalSchema, parsePageRef, parseServiceRef, persist, renderUI, safeParseOrbitalSchema, set, sexpr, spawn, validateAssetAnimations, validateBindingInContext, validateOperatorArity, walkSExpr };
|
|
1594
|
+
//# sourceMappingURL=index.js.map
|
|
1595
|
+
//# sourceMappingURL=index.js.map
|