// modules/core.ts
var NUMBER = "number";
var BOOLEAN = "boolean";
var STRING = "string";
var ANY = "any";
var SEXPR = { kind: "sexpr" };
var BINDING = { kind: "binding" };
var ENTITY_REF = { kind: "entityRef" };
var EVENT_KEY = { kind: "eventKey" };
var UI_SLOT = { kind: "uiSlot" };
var PATTERN_TYPE = { kind: "patternType" };
var PERSIST_ACTION = {
  kind: "union",
  of: [
    { kind: "literal", value: "create" },
    { kind: "literal", value: "update" },
    { kind: "literal", value: "delete" },
    { kind: "literal", value: "clear" },
    { kind: "literal", value: "batch" }
  ]
};
var SET_OPERATION = {
  kind: "union",
  of: [
    { kind: "literal", value: "increment" },
    { kind: "literal", value: "decrement" },
    { kind: "literal", value: "multiply" },
    { kind: "literal", value: "append" },
    { kind: "literal", value: "remove" }
  ]
};
var NOTIFY_CHANNEL = {
  kind: "union",
  of: [
    { kind: "literal", value: "email" },
    { kind: "literal", value: "push" },
    { kind: "literal", value: "sms" },
    { kind: "literal", value: "in_app" }
  ]
};
var CORE_OPERATORS = {
  // --- arithmetic primitives --------------------------------------------------
  "+": {
    module: "core",
    category: "arithmetic",
    minArity: 2,
    maxArity: null,
    description: "Add numbers",
    hasSideEffects: false,
    returnType: "number",
    params: [{ name: "...nums", type: NUMBER, description: "Numbers to sum" }],
    example: '["+", 1, 2, 3] // => 6'
  },
  "-": {
    module: "core",
    category: "arithmetic",
    minArity: 1,
    maxArity: 2,
    description: "Subtract or negate",
    hasSideEffects: false,
    returnType: "number",
    params: [
      { name: "a", type: NUMBER, description: "Left operand or value to negate" },
      { name: "b", type: NUMBER, description: "Right operand", optional: true }
    ],
    example: '["-", 5, 2] // => 3; ["-", 5] // => -5'
  },
  "*": {
    module: "core",
    category: "arithmetic",
    minArity: 2,
    maxArity: null,
    description: "Multiply numbers",
    hasSideEffects: false,
    returnType: "number",
    params: [{ name: "...nums", type: NUMBER, description: "Numbers to multiply" }],
    example: '["*", 2, 3, 4] // => 24'
  },
  "/": {
    module: "core",
    category: "arithmetic",
    minArity: 2,
    maxArity: 2,
    description: "Divide numbers",
    hasSideEffects: false,
    returnType: "number",
    params: [
      { name: "a", type: NUMBER, description: "Numerator" },
      { name: "b", type: NUMBER, description: "Denominator" }
    ],
    example: '["/", 10, 2] // => 5'
  },
  "%": {
    module: "core",
    category: "arithmetic",
    minArity: 2,
    maxArity: 2,
    description: "Modulo (remainder)",
    hasSideEffects: false,
    returnType: "number",
    params: [
      { name: "a", type: NUMBER, description: "Dividend" },
      { name: "b", type: NUMBER, description: "Divisor" }
    ],
    example: '["%", 10, 3] // => 1'
  },
  // --- comparison -------------------------------------------------------------
  "=": {
    module: "core",
    category: "comparison",
    minArity: 2,
    maxArity: 2,
    description: "Equal to",
    hasSideEffects: false,
    returnType: "boolean",
    params: [
      { name: "a", type: ANY, description: "Left operand" },
      { name: "b", type: ANY, description: "Right operand" }
    ],
    example: '["=", "@entity.status", "active"]'
  },
  "!=": {
    module: "core",
    category: "comparison",
    minArity: 2,
    maxArity: 2,
    description: "Not equal to",
    hasSideEffects: false,
    returnType: "boolean",
    params: [
      { name: "a", type: ANY, description: "Left operand" },
      { name: "b", type: ANY, description: "Right operand" }
    ],
    example: '["!=", "@entity.id", null]'
  },
  "<": {
    module: "core",
    category: "comparison",
    minArity: 2,
    maxArity: 2,
    description: "Less than",
    hasSideEffects: false,
    returnType: "boolean",
    params: [
      { name: "a", type: NUMBER, description: "Left operand" },
      { name: "b", type: NUMBER, description: "Right operand" }
    ],
    example: '["<", "@entity.health", 10]'
  },
  ">": {
    module: "core",
    category: "comparison",
    minArity: 2,
    maxArity: 2,
    description: "Greater than",
    hasSideEffects: false,
    returnType: "boolean",
    params: [
      { name: "a", type: NUMBER, description: "Left operand" },
      { name: "b", type: NUMBER, description: "Right operand" }
    ],
    example: '[">", "@entity.score", 0]'
  },
  "<=": {
    module: "core",
    category: "comparison",
    minArity: 2,
    maxArity: 2,
    description: "Less than or equal",
    hasSideEffects: false,
    returnType: "boolean",
    params: [
      { name: "a", type: NUMBER, description: "Left operand" },
      { name: "b", type: NUMBER, description: "Right operand" }
    ],
    example: '["<=", "@entity.count", 100]'
  },
  ">=": {
    module: "core",
    category: "comparison",
    minArity: 2,
    maxArity: 2,
    description: "Greater than or equal",
    hasSideEffects: false,
    returnType: "boolean",
    params: [
      { name: "a", type: NUMBER, description: "Left operand" },
      { name: "b", type: NUMBER, description: "Right operand" }
    ],
    example: '[">=", "@entity.age", 18]'
  },
  // --- logic ------------------------------------------------------------------
  and: {
    module: "core",
    category: "logic",
    minArity: 2,
    maxArity: null,
    description: "Logical AND (returns the last truthy value, NOT a boolean \u2014 short-circuit)",
    hasSideEffects: false,
    returnType: "boolean",
    returnSemantics: "last-truthy-of-args",
    params: [{ name: "...conds", type: BOOLEAN, description: "Boolean expressions to AND" }],
    example: '["and", ["=", "@entity.active", true], [">", "@entity.score", 0]]'
  },
  or: {
    module: "core",
    category: "logic",
    minArity: 2,
    maxArity: null,
    description: "Logical OR (returns the first truthy value, NOT a boolean \u2014 short-circuit)",
    hasSideEffects: false,
    returnType: "boolean",
    returnSemantics: "first-truthy-of-args",
    params: [{ name: "...conds", type: BOOLEAN, description: "Boolean expressions to OR" }],
    example: '["or", ["=", "@entity.role", "admin"], ["=", "@entity.role", "owner"]]'
  },
  not: {
    module: "core",
    category: "logic",
    minArity: 1,
    maxArity: 1,
    description: "Logical NOT",
    hasSideEffects: false,
    returnType: "boolean",
    params: [{ name: "cond", type: BOOLEAN, description: "Boolean to negate" }],
    example: '["not", "@entity.disabled"]'
  },
  if: {
    module: "core",
    category: "logic",
    minArity: 3,
    maxArity: 3,
    description: "Conditional expression (ternary). Return type is union of branch types.",
    hasSideEffects: false,
    returnType: "any",
    returnSemantics: "branch-union",
    params: [
      { name: "cond", type: BOOLEAN, description: "Condition to evaluate" },
      { name: "then", type: ANY, description: "Value or effect if true" },
      { name: "else", type: ANY, description: "Value or effect if false" }
    ],
    example: '["if", [">", "@entity.health", 0], "alive", "dead"]'
  },
  // --- control ----------------------------------------------------------------
  let: {
    module: "core",
    category: "control",
    minArity: 2,
    maxArity: 2,
    description: "Bind local variables for a body expression",
    hasSideEffects: false,
    returnType: "any",
    params: [
      {
        name: "bindings",
        type: { kind: "array", of: { kind: "array", of: ANY } },
        description: "Array of [name, value] pairs"
      },
      { name: "body", type: SEXPR, description: "Expression or effect list using the bindings" }
    ],
    example: '["let", [["x", 10]], ["+", "x", 1]]'
  },
  do: {
    module: "core",
    category: "control",
    minArity: 1,
    maxArity: null,
    description: "Sequential execution of multiple effects/expressions",
    hasSideEffects: false,
    returnType: "any",
    params: [{ name: "...exprs", type: SEXPR, description: "Effects/expressions to run in order" }],
    example: '["do", ["set", "@entity.x", 0], ["set", "@entity.y", 0]]'
  },
  list: {
    module: "core",
    category: "control",
    minArity: 0,
    maxArity: null,
    description: "Literal array constructor \u2014 evaluates each argument and returns them as an array. Lowering wraps a literal list bound for a literal-array slot in `list` so it is unambiguously data, never a call (disambiguates a list whose first element collides with an operator name, e.g. [path method \u2026]).",
    hasSideEffects: false,
    returnType: "array",
    params: [{ name: "...items", type: SEXPR, description: "Items to collect into a literal array" }],
    example: '["list", "path", "method", "status"] // => ["path", "method", "status"]'
  },
  when: {
    module: "core",
    category: "control",
    minArity: 2,
    maxArity: 2,
    description: "Conditional effect without an else branch",
    hasSideEffects: false,
    returnType: "void",
    params: [
      { name: "cond", type: BOOLEAN, description: "Guard expression" },
      { name: "effect", type: SEXPR, description: "Effect to run if cond is true" }
    ],
    example: '["when", [">", "@entity.health", 0], ["emit", "ALIVE"]]'
  },
  fn: {
    module: "core",
    category: "control",
    minArity: 2,
    maxArity: 2,
    description: "Lambda expression (used for per-item renders and transforms)",
    hasSideEffects: false,
    returnType: "function",
    acceptsLambda: true,
    lambdaArgPosition: 1,
    params: [
      { name: "paramName", type: STRING, description: "Name of the parameter binding" },
      { name: "body", type: SEXPR, description: "Expression evaluated per invocation" }
    ],
    example: '["fn", "item", { "type": "typography", "content": "@item.title" }]'
  },
  // --- effect -----------------------------------------------------------------
  set: {
    module: "core",
    category: "effect",
    minArity: 2,
    maxArity: 2,
    description: "Set a binding to a value",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "binding", type: BINDING, description: 'Target binding (e.g. "@entity.field")' },
      { name: "value", type: ANY, description: "Value to assign (literal or expression)" }
    ],
    example: '["set", "@entity.health", 100]',
    effect: {
      kind: "set",
      // success emit carries the written value; the evaluator coerces to the
      // binding's declared type, so 'any' is the general shape. A future pass
      // can narrow per-binding via resolveBinding.
      produces: ANY,
      config: { operation: SET_OPERATION }
    }
  },
  emit: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Emit an event onto the bus",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "event", type: EVENT_KEY, description: "Event key" },
      { name: "payload", type: ENTITY_REF, description: "Optional payload", optional: true }
    ],
    example: '["emit", "PLAYER_DIED", { "playerId": "@entity.id" }]',
    effect: {
      kind: "emit",
      produces: {
        kind: "object",
        fields: { event: EVENT_KEY, payload: ANY },
        open: true
      }
    }
  },
  persist: {
    module: "core",
    category: "effect",
    minArity: 2,
    maxArity: 4,
    description: "Create, update, delete, clear, or batch entity records. Optional trailing { emit: { success, failure } } options object attaches closed-circuit emit routing.",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "action", type: PERSIST_ACTION, description: "Persist action" },
      { name: "entity", type: { kind: "entity" }, description: "Target entity name" },
      { name: "data", type: ENTITY_REF, description: "Payload (create/update) or entity id (delete)", optional: true },
      {
        name: "options",
        type: {
          kind: "object",
          fields: {
            emit: { kind: "object", fields: {}, open: true }
          },
          open: true
        },
        description: "Optional trailing options object carrying { emit: { success, failure } } closed-circuit routing",
        optional: true
      }
    ],
    example: '["persist", "create", "Task", { "title": "@payload.title" }, { "emit": { "success": "TASK_CREATED" } }]',
    effect: {
      kind: "persist",
      // Action-discriminated union. The compiler narrows at the call site
      // based on the action arg literal to pick the right branch when
      // checking the emit.success event's declared payload.
      //   create/update -> the resulting entity record
      //   delete/clear  -> { id, deleted }
      //   batch         -> summary of operations
      produces: {
        kind: "union",
        of: [
          { kind: "entity" },
          {
            kind: "object",
            fields: { id: STRING, deleted: BOOLEAN },
            open: false
          },
          {
            kind: "object",
            fields: {
              operations: { kind: "array", of: ANY },
              completedCount: NUMBER,
              totalCount: NUMBER
            },
            open: false
          }
        ]
      }
    }
  },
  navigate: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Navigate to a route",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "path", type: STRING, description: "Route path (supports :param placeholders)" },
      {
        name: "params",
        type: { kind: "object", fields: {}, open: true },
        description: "Optional route params",
        optional: true
      }
    ],
    example: '["navigate", "/tasks/:id", { "id": "@entity.id" }]',
    effect: { kind: "navigate" }
  },
  notify: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Show a notification (in-app, email, push, sms)",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "channel", type: NOTIFY_CHANNEL, description: "Delivery channel" },
      { name: "message", type: STRING, description: "Message body", optional: true }
    ],
    example: '["notify", "in_app", "Task created successfully"]',
    effect: { kind: "notify" }
  },
  log: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 1,
    description: "Emit a structured info log line (compiled + runtime)",
    hasSideEffects: true,
    returnType: "void",
    params: [{ name: "message", type: STRING, description: "Log message" }],
    example: '["log", "Context below compact threshold"]',
    effect: { kind: "log" }
  },
  spawn: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Spawn a new entity instance (games)",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "entity", type: { kind: "entity" }, description: "Entity name to spawn" },
      {
        name: "initialState",
        type: { kind: "object", fields: {}, open: true },
        description: "Initial field values",
        optional: true
      }
    ],
    example: '["spawn", "Bullet", { "x": "@entity.x", "y": "@entity.y" }]',
    effect: { kind: "spawn" }
  },
  despawn: {
    module: "core",
    category: "effect",
    minArity: 0,
    maxArity: 1,
    description: "Despawn an entity instance (games)",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "entityId", type: STRING, description: "Target entity id (defaults to @entity.id)", optional: true }
    ],
    example: '["despawn", "@entity.id"]',
    effect: { kind: "despawn" }
  },
  fetch: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Fetch an entity (by id) or a collection (by filter) from persistence",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "entity", type: { kind: "entity" }, description: "Target entity name" },
      {
        name: "options",
        type: {
          kind: "object",
          fields: {
            id: STRING,
            filter: ANY,
            limit: NUMBER,
            offset: NUMBER,
            include: { kind: "array", of: STRING },
            emit: { kind: "object", fields: {}, open: true }
          },
          open: true
        },
        description: "Fetch options: id | filter | limit | offset | include | emit",
        optional: true
      }
    ],
    example: '["fetch", "Task", { "id": "@payload.taskId", "emit": { "success": "TASK_LOADED" } }]',
    effect: {
      kind: "fetch",
      // Call-site-discriminated union: options.id present -> single entity;
      // otherwise -> array of entity. The compiler narrows at the call site
      // when checking emit.success against the declared event payload.
      produces: {
        kind: "union",
        of: [
          { kind: "entity" },
          { kind: "array", of: { kind: "entity" } }
        ]
      }
    }
  },
  "fetch-stream": {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Stream an LLM or HTTP response, emitting on_message per chunk, success on completion, failure on error",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "entity", type: { kind: "entity" }, description: "Target entity name" },
      {
        name: "options",
        type: {
          kind: "object",
          fields: {
            id: STRING,
            filter: ANY,
            emit: { kind: "object", fields: {}, open: true }
          },
          open: true
        },
        description: "Stream options: id | filter | emit",
        optional: true
      }
    ],
    example: '["fetch-stream", "Message", { "emit": { "on_message": "CHUNK_RECEIVED", "success": "STREAM_DONE", "failure": "STREAM_FAILED" } }]',
    effect: {
      kind: "fetch-stream",
      produces: { kind: "entity" }
    }
  },
  "send-server": {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Send an orbital event to the server over WebSocket (client-side; chat/real-time trigger)",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "event", type: EVENT_KEY, description: "Target orbital event name on the server" },
      {
        name: "payload",
        type: { kind: "object", fields: {}, open: true },
        description: "Event payload to forward to the server",
        optional: true
      }
    ],
    example: '["send-server", "CHAT_MESSAGE", { "text": "@input.text" }]',
    effect: { kind: "send-server" }
  },
  ref: {
    module: "core",
    category: "effect",
    minArity: 1,
    maxArity: 2,
    description: "Reactive entity reference (deprecated, use fetch with listens in V2)",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "entity", type: { kind: "entity" }, description: "Target entity name" },
      {
        name: "options",
        type: {
          kind: "object",
          fields: {
            id: STRING,
            filter: ANY,
            include: { kind: "array", of: STRING },
            emit: { kind: "object", fields: {}, open: true }
          },
          open: true
        },
        description: "Ref options: id | filter | include | emit",
        optional: true
      }
    ],
    example: '["ref", "Task"]',
    effect: {
      kind: "ref",
      // Same call-site shape as fetch. Kept for the V2 transition period;
      // scheduled for deprecation in a later phase (see Almadar_Entity_V2_Plan.md).
      produces: {
        kind: "union",
        of: [
          { kind: "entity" },
          { kind: "array", of: { kind: "entity" } }
        ]
      }
    }
  },
  "call-service": {
    module: "core",
    category: "effect",
    minArity: 2,
    maxArity: 4,
    description: "Invoke an external service action. Optional trailing { emit: { success, failure } } options object attaches closed-circuit emit routing (V2 frame contract).",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "service", type: STRING, description: 'Service name (e.g. "llm", "stripe")' },
      { name: "action", type: STRING, description: 'Service action (e.g. "generate", "charge")' },
      {
        name: "params",
        type: { kind: "object", fields: {}, open: true },
        description: "Service-specific params",
        optional: true
      },
      {
        name: "options",
        type: { kind: "object", fields: {}, open: true },
        description: 'Optional trailing options object. Set `{ emit: { success: "...", failure: "..." } }` to wire closed-circuit result routing (V2 frame).',
        optional: true
      }
    ],
    example: '["call-service", "llm", "generate", { "userPrompt": "@entity.inputText" }, { "emit": { "success": "LlmCompleted", "failure": "LlmFailed" } }]',
    effect: {
      kind: "call-service",
      // TODO(entity-v2): narrow to the declared service return type once
      // per-service return shapes live on the orbital services block.
      // Today the emit.success payload is whatever the service adapter returns.
      produces: ANY
    }
  },
  "render-ui": {
    module: "core",
    category: "effect",
    minArity: 2,
    maxArity: 3,
    description: "Render a pattern into a UI slot",
    hasSideEffects: true,
    returnType: "void",
    params: [
      { name: "slot", type: UI_SLOT, description: "Target UI slot (main, sidebar, modal, hud, ...)" },
      {
        name: "pattern",
        type: {
          kind: "union",
          of: [
            { kind: "object", fields: { patternType: PATTERN_TYPE }, open: true },
            { kind: "literal", value: null }
          ]
        },
        description: "Pattern config (or null to clear the slot)"
      },
      {
        name: "props",
        type: { kind: "object", fields: {}, open: true },
        description: "Extra props forwarded to the pattern",
        optional: true
      }
    ],
    example: '["render-ui", "main", { "patternType": "entity-table", "columns": ["name"] }]',
    effect: { kind: "render-ui" }
  }
};
function getCoreOperators() {
  return Object.keys(CORE_OPERATORS);
}

export { CORE_OPERATORS, getCoreOperators };
//# sourceMappingURL=core.js.map
//# sourceMappingURL=core.js.map