Class: Eco::API::UseCases::GraphQL::Samples::Pages::Template::CommandEmitter
- Inherits:
-
Object
- Object
- Eco::API::UseCases::GraphQL::Samples::Pages::Template::CommandEmitter
- Defined in:
- lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb
Overview
Declarative build-from-scratch emitter for template (workflow) structure.
Mirrors the shape of the location diff->commands engine (samples/location/command), but the
id-threading is placeholder-based, not post-hoc newId-remap: each new node is given a
client-chosen placeholderId, and later commands in the SAME batch reference it. The gem's
executeWorkflowCommands resolves placeholders intra-batch. See the gem's PHASE0-FINDINGS.md.
Commands are emitted in dependency order via depth-first DSL evaluation: addStage -> (per section) addSection, addStageSection -> (per field) addField -> (per option) addSelectFieldOption ; then forces: addForce -> (per binding) addBinding.
Usage: emitter = CommandEmitter.new emitter.stage(name: 'Report', ordering: 0) do |stage| stage.section(layout: 'content') do |section| section.field(label: 'Notes', field_type: 'plain_text') section.field(label: 'Risk', field_type: 'select') do |field| field.option(label: 'High', weight: 10) end end end emitter.commands # => ordered Array of FINAL built { commandKey => kwargs } commands
The output is fed DIRECTLY to graphql.template.create(commands:) / update(model, commands:). It is already built via WorkflowCommand.build — do NOT re-run it through build_commands (that normaliser is for hand-authored raw specs and is non-idempotent for key-renaming commands such as addSelectFieldOption: data_field_id -> dataFieldId).
Defined Under Namespace
Classes: FieldBuilder, ForceBuilder, SectionBuilder, StageBuilder
Instance Attribute Summary collapse
-
#commands ⇒ Array<Hash>
readonly
Ordered command specs, each { commandKey => kwargs }.
Instance Method Summary collapse
-
#allocate(kind) ⇒ Object
Allocate the next placeholder id for a node kind (:stg, :sec, :fld, :frc, :bnd).
-
#emit(command_key, **kwargs) ⇒ Object
Build + append one command via the gem's WorkflowCommand contract.
-
#force(name:, custom_script: nil, url: nil, content_b64: nil, &block) ⇒ Object
Declare a force at template level.
-
#initialize ⇒ CommandEmitter
constructor
A new instance of CommandEmitter.
-
#stage(name:, ordering: nil, &block) ⇒ Object
Declare a stage.
Constructor Details
#initialize ⇒ CommandEmitter
Returns a new instance of CommandEmitter.
31 32 33 34 |
# File 'lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb', line 31 def initialize @commands = [] @counters = Hash.new(0) end |
Instance Attribute Details
#commands ⇒ Array<Hash> (readonly)
Returns ordered command specs, each { commandKey => kwargs }.
37 38 39 |
# File 'lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb', line 37 def commands @commands end |
Instance Method Details
#allocate(kind) ⇒ Object
Allocate the next placeholder id for a node kind (:stg, :sec, :fld, :frc, :bnd).
59 60 61 |
# File 'lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb', line 59 def allocate(kind) "#{kind}#{@counters[kind] += 1}" end |
#emit(command_key, **kwargs) ⇒ Object
Build + append one command via the gem's WorkflowCommand contract. The gem constant is resolved lazily (at call time, not load time) — the gem's GraphQL namespace is not yet loaded while this file is being required.
66 67 68 |
# File 'lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb', line 66 def emit(command_key, **kwargs) @commands << Ecoportal::API::GraphQL::Input::WorkflowCommand.build(command_key, **kwargs) end |
#force(name:, custom_script: nil, url: nil, content_b64: nil, &block) ⇒ Object
Declare a force at template level. Yields a ForceBuilder for bindings.
48 49 50 51 52 53 54 |
# File 'lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb', line 48 def force(name:, custom_script: nil, url: nil, content_b64: nil, &block) placeholder = allocate(:frc) emit(:addForce, placeholderId: placeholder, name: name, customScript: custom_script, url: url, contentB64: content_b64) ForceBuilder.new(self, placeholder).tap { |b| block&.call(b) } placeholder end |
#stage(name:, ordering: nil, &block) ⇒ Object
Declare a stage. Yields a StageBuilder for nested sections.
40 41 42 43 44 45 |
# File 'lib/eco/api/usecases/graphql/samples/pages/template/command_emitter.rb', line 40 def stage(name:, ordering: nil, &block) placeholder = allocate(:stg) emit(:addStage, placeholderId: placeholder, name: name, ordering: ordering) StageBuilder.new(self, placeholder).tap { |b| block&.call(b) } placeholder end |