caixanegra 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4296a7a3ef7cd55657a83b6fd6f4cf9389c8ba731a539191a6e6c16e853b6848
4
- data.tar.gz: 8805ae26d4cbb6a37c98a22b5fba5b11a3f14a88de9fa685d313bfc58d22e4ed
3
+ metadata.gz: c291dfc1c33d2c17e87093eff1bceff3c061ef8c7230a561ace088cd9e23f279
4
+ data.tar.gz: e812c3f4c1d202902f926115162c0b9b46885b35af56db52db3aa94ab8e53ac8
5
5
  SHA512:
6
- metadata.gz: c866e8d7614824e7a82bd8fe26dc0a434be293a6e317142169724c24a00f5c60b7e4ff804836053a0f75a865f6df1943464ae5c5dbfad8c2500ce31ea820b306
7
- data.tar.gz: 0d12dc642122961304bb47ec2840560e6da603f83c575b8e3e0604e5527743a54ce43c950ca372763018658da8f9a9ba2a06e88da6a31bb62bb18e45e128e7e3
6
+ metadata.gz: c6276bd14d36c832729b8a717a15ad5a8c6b9e6223343d6169fa1c153dc0389d0d0ef73ed61b0eb4f19a9dfc1936683b59b80e994b740df4cc670958fbc21833
7
+ data.tar.gz: 70059940599beff0f5cf09bbb73defa53fc31e336166a15a0262902f194862cd318b5bb8fb7bcb22a7934960411c7dce14f997816a0430fc943ba6d0dceddb88
data/README.md CHANGED
@@ -51,7 +51,7 @@ uid = Caixanegra::Manager.handler(my_flow || {})
51
51
  You can then safely navigate to the designer.
52
52
 
53
53
  ```ruby
54
- link_to "Some flow", "/caixanegra/design/#{@uid}?unit_scope=optional_scope", target: :blank
54
+ link_to "Some flow", "/caixanegra/design/#{@uid}?unit_scope=optional_scope,another_optional_scope", target: :_blank
55
55
  ```
56
56
 
57
57
  Saved changes will update the flow definition on Redis, and you must then persist them. You can get the flow definition for any specified **caixanegra** handled UID:
@@ -63,7 +63,7 @@ persist_flow(updated_flow) # your own persistence or transport solution. It's a
63
63
 
64
64
  **NOTE:** There's currently no managed way to set callbacks on save actions from the designer. Working on it
65
65
 
66
- Please, refer to [the wiki](https://github.com/sergiorribeiro/caixanegra/wiki) to get to know more about [creating your units](https://github.com/sergiorribeiro/caixanegra/wiki/Creating-units).
66
+ Please, refer to [the wiki](https://github.com/sergiorribeiro/caixanegra/wiki) to get to know more about [units](https://github.com/sergiorribeiro/caixanegra/wiki/Anatomy-of-a-unit).
67
67
 
68
68
  # License
69
69
  **caixanegra** is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -166,9 +166,9 @@ window.Caixanegra.Designer = {
166
166
  ctx.beginPath();
167
167
  ctx.moveTo(this.#drawValues.position.x + this.size.x, exit.markerY);
168
168
  ctx.lineTo(this.#drawValues.position.x + this.size.x + 25, exit.markerY);
169
-
169
+
170
170
  if (this.connectingExit === exit && context.mouse.move) {
171
- ctx.lineTo(context.mouse.move.x, context.mouse.move.y);
171
+ ctx.lineTo(context.mouse.move.x + context.referential.x, context.mouse.move.y + context.referential.y);
172
172
  } else if (exit.reference.target) {
173
173
  const targetCenter = exit.reference.target.getCenter(context.referential);
174
174
  ctx.lineTo(targetCenter.x, targetCenter.y);
@@ -382,10 +382,10 @@ window.Caixanegra.Designer = {
382
382
  }
383
383
 
384
384
  deleteUnit() {
385
- this.removeUnit(this.selectedUnit.oid);
386
- this.toggleDeleteConfirmation();
387
385
  this.unitDetailPane.classList.remove("-open");
388
386
  this.unitDebugHitsPane.classList.remove("-open");
387
+ this.removeUnit(this.selectedUnit.oid);
388
+ this.toggleDeleteConfirmation();
389
389
  }
390
390
 
391
391
  flushToConsole(entries) {
@@ -522,33 +522,63 @@ window.Caixanegra.Designer = {
522
522
  this.#catalog = response;
523
523
  const unitMenu = document.querySelector("#unitMenu");
524
524
  unitMenu.innerHTML = "";
525
- this.#catalog.forEach((unitData) => {
526
- const item = document.createElement("div");
527
- const content = document.createElement("div");
528
- const colorCode = document.createElement("div");
529
- const header = document.createElement("div");
530
- const name = document.createElement("span");
531
- const type = document.createElement("span");
532
- const description = document.createElement("div");
533
- description.classList.add("description");
534
- item.classList.add("unit");
535
- header.classList.add("header");
536
- content.classList.add("content");
537
- colorCode.classList.add("color-code");
538
- name.classList.add("name");
539
- type.classList.add("type");
540
-
541
- name.innerHTML = unitData.title;
542
- type.innerHTML = unitData.type;
543
- description.innerHTML = unitData.description;
544
- colorCode.style.backgroundColor = Caixanegra.Designer.typeColor(unitData.type);
545
-
546
- header.append(name, type);
547
- content.append(header, description);
548
- item.append(colorCode, content);
549
- item.addEventListener("click", this.createUnit.bind(this, unitData));
550
- unitMenu.appendChild(item);
525
+
526
+ const scopes = [];
527
+
528
+ this.#catalog.forEach(unit => {
529
+ if (unit.hasOwnProperty("scope") && Array.isArray(unit.scope)) {
530
+ scopes.push(...unit.scope);
531
+ } else {
532
+ scopes.push("_unscoped");
533
+ }
534
+ });
535
+
536
+ [...new Set(scopes)].sort().forEach(scope => {
537
+ const scopeWrapper = document.createElement("div");
538
+ const scopeTitle = document.createElement("div");
539
+ const scopeUnits = document.createElement("div");
540
+
541
+ scopeWrapper.classList.add("unit-wrapper");
542
+ scopeTitle.classList.add("title");
543
+
544
+ scopeTitle.innerHTML = scope === "_unscoped" ? "unscoped" : scope.replace(/_/g, " ");
545
+ scopeWrapper.appendChild(scopeTitle);
546
+ scopeWrapper.appendChild(scopeUnits);
547
+
548
+ const filteredUnits = this.#catalog.filter(unit => {
549
+ return (unit.scope === null && scope === "_unscoped") || (unit.scope || []).includes(scope)
550
+ });
551
+
552
+ filteredUnits.forEach((unitData) => {
553
+ const item = document.createElement("div");
554
+ const content = document.createElement("div");
555
+ const colorCode = document.createElement("div");
556
+ const header = document.createElement("div");
557
+ const name = document.createElement("span");
558
+ const type = document.createElement("span");
559
+ const description = document.createElement("div");
560
+ description.classList.add("description");
561
+ item.classList.add("unit");
562
+ header.classList.add("header");
563
+ content.classList.add("content");
564
+ colorCode.classList.add("color-code");
565
+ name.classList.add("name");
566
+ type.classList.add("type");
567
+
568
+ name.innerHTML = unitData.title;
569
+ type.innerHTML = unitData.type;
570
+ description.innerHTML = unitData.description;
571
+ colorCode.style.backgroundColor = Caixanegra.Designer.typeColor(unitData.type);
572
+
573
+ header.append(name, type);
574
+ content.append(header, description);
575
+ item.append(colorCode, content);
576
+ item.addEventListener("click", this.createUnit.bind(this, unitData));
577
+ scopeUnits.appendChild(item);
578
+ });
579
+ unitMenu.appendChild(scopeWrapper);
551
580
  });
581
+
552
582
  this.#loadedComponents.catalog = true;
553
583
  this.#reveal();
554
584
  });
@@ -119,6 +119,15 @@ $accent-contrast-color: darken($accent-color, 20%);
119
119
  transform: translateY(0%);
120
120
  }
121
121
 
122
+ .unit-wrapper {
123
+ .title {
124
+ font-family: Verdana, Geneva, Tahoma, sans-serif;
125
+ font-size: 0.7em;
126
+ color: rgba(0,0,0,.7);
127
+ margin-bottom: 5px;
128
+ }
129
+ }
130
+
122
131
  .unit {
123
132
  display: flex;
124
133
  flex-direction: row;
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Caixanegra
4
- module API
4
+ module Api
5
5
  module Designer
6
- class FlowsController < ::Caixanegra::APIController
6
+ class FlowsController < ::Caixanegra::ApiController
7
7
  before_action :set_flow, only: %i[show debug_run]
8
8
 
9
9
  def show
@@ -20,7 +20,6 @@ module Caixanegra
20
20
  execution = Caixanegra::Executor.new(
21
21
  initial_carryover: initial_carryover,
22
22
  flow_definition: @flow,
23
- unit_scope: params[:unit_scope],
24
23
  debug_mode: true
25
24
  ).run
26
25
 
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Caixanegra
4
- module API
4
+ module Api
5
5
  module Designer
6
- class UnitsController < ::Caixanegra::APIController
6
+ class UnitsController < ::Caixanegra::ApiController
7
7
  def index
8
8
  render json: units
9
9
  end
@@ -15,26 +15,21 @@ module Caixanegra
15
15
  end
16
16
 
17
17
  def units
18
- @units ||= begin
19
- base_units = Caixanegra.units.reject { |_, v| v.is_a? Hash }
20
- scope_units = Caixanegra.units[unit_scope] if unit_scope.present?
21
- all_units = base_units.merge(scope_units || {})
18
+ @units ||= ::Caixanegra::UnitHelper.scoped_units(unit_scope).map do |k, v|
19
+ base = {
20
+ scope: v.scope,
21
+ title: v.unit_name,
22
+ type: v.type,
23
+ description: v.description,
24
+ class: k,
25
+ exits: v.exits&.map { |e| { name: e } },
26
+ inputs: v.inputs,
27
+ assignments: v.assignments
28
+ }
22
29
 
23
- all_units.map do |k, v|
24
- base = {
25
- title: v.name,
26
- type: v.type,
27
- description: v.description,
28
- class: k,
29
- exits: v.exits&.map { |e| { name: e } },
30
- inputs: v.inputs,
31
- assignments: v.assignments
32
- }
30
+ base[:set] = v.set if base[:set]
33
31
 
34
- base[:set] = v.set if base[:set]
35
-
36
- base
37
- end
32
+ base
38
33
  end
39
34
  end
40
35
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Caixanegra
4
- class APIController < ActionController::API
4
+ class ApiController < ActionController::API
5
5
  end
6
6
  end
@@ -36,6 +36,12 @@ module Caixanegra
36
36
  }
37
37
  end
38
38
 
39
+ def exit_and_return
40
+ {
41
+ carry_over: @carry_over
42
+ }
43
+ end
44
+
39
45
  def flow
40
46
  exit_through exits.first
41
47
  end
@@ -64,11 +70,18 @@ module Caixanegra
64
70
 
65
71
  input_value = result
66
72
  end
73
+
67
74
  input_value.presence || @inputs[id][:default]
75
+ rescue StandardError
76
+ raise(UnitIOException.new, "Unable to fetch input '#{id}'")
77
+ end
78
+
79
+ def scope
80
+ self.class.scope
68
81
  end
69
82
 
70
- def name
71
- self.class.name
83
+ def unit_name
84
+ self.class.unit_name
72
85
  end
73
86
 
74
87
  def description
@@ -99,12 +112,16 @@ module Caixanegra
99
112
  end
100
113
 
101
114
  class << self
102
- attr_reader :name, :description, :inputs, :exits, :assignments, :type
115
+ attr_reader :unit_name, :description, :inputs, :exits, :assignments, :type, :scope
103
116
 
104
117
  @type = :passthrough
105
118
 
119
+ def configure_scope(value)
120
+ @scope = value
121
+ end
122
+
106
123
  def configure_name(value)
107
- @name = value
124
+ @unit_name = value
108
125
  end
109
126
 
110
127
  def configure_description(value)
@@ -2,4 +2,6 @@
2
2
 
3
3
  module Caixanegra
4
4
  class UnitScopedException < StandardError; end
5
+ class UnitIOException < StandardError; end
6
+ class ContinuityException < StandardError; end
5
7
  end
@@ -5,7 +5,6 @@ module Caixanegra
5
5
  def initialize(params)
6
6
  @initial_carryover = params[:initial_carryover] || {}
7
7
  @flow = (params[:flow_definition] || {}).deep_symbolize_keys
8
- @unit_scope = params[:unit_scope]
9
8
  @debug_mode = params[:debug_mode] == true
10
9
  @execution = { history: [], steps: [] }
11
10
  @storage = {}
@@ -113,6 +112,8 @@ module Caixanegra
113
112
  raise exception
114
113
  end
115
114
  next_unit = next_unit(result)
115
+ raise(ContinuityException.new, "Unable to choose a valid exit") if next_unit.nil?
116
+
116
117
  log_step_result(result, next_unit)
117
118
  @execution[:steps] += feeder_steps
118
119
  @step_unit = next_unit
@@ -143,11 +144,15 @@ module Caixanegra
143
144
  end
144
145
 
145
146
  def next_unit(result)
147
+ return nil if result.nil?
148
+
146
149
  exit_name = result[:exit_through]
147
150
  metadata = unit_metadata(@step_unit.oid)
148
- log_console_entry "Next unit found through '#{exit_name}': '#{@step_unit.oid}'"
149
151
  exit_metadata = metadata[:exits].find { |ex| ex[:name] == exit_name.to_s }
150
- unit(exit_metadata[:target], map_carry_over(result))
152
+ next_unit = unit(exit_metadata[:target], map_carry_over(result))
153
+ log_console_entry "Next unit found through '#{exit_name}': '#{next_unit.oid}'"
154
+
155
+ next_unit
151
156
  end
152
157
 
153
158
  def process_feeders
@@ -187,15 +192,13 @@ module Caixanegra
187
192
  unit_class = scoped_units[unit_data[:class].to_sym]
188
193
  inputs = unit_class.inputs
189
194
  unit_class.new(unit_data[:oid], inputs, mappings, carry_over, @storage)
195
+ rescue
196
+ log_console_entry "Unable to load unit instance of type '#{unit_data[:class]}'"
197
+ nil
190
198
  end
191
199
 
192
200
  def scoped_units
193
- @scoped_units ||= begin
194
- base_units = Caixanegra.units.reject { |_, v| v.is_a? Hash }
195
- scope_units = Caixanegra.units[@unit_scope] if @unit_scope.present?
196
-
197
- base_units.merge(scope_units || {})
198
- end
201
+ @scoped_units ||= UnitHelper.all_units
199
202
  end
200
203
  end
201
204
  end
@@ -0,0 +1,28 @@
1
+ module Caixanegra
2
+ class UnitHelper
3
+ class << self
4
+ def scoped_units(scope)
5
+ units = {}
6
+
7
+ scopes = (scope || "").split(",").map(&:to_sym)
8
+ Caixanegra.units.each do |unit|
9
+ if unit.scope.nil? || unit.scope.any? { |checking_scope| scopes.include?(checking_scope) }
10
+ units[unit.name.demodulize.underscore.to_sym] = unit
11
+ end
12
+ end
13
+
14
+ units
15
+ end
16
+
17
+ def all_units
18
+ units = {}
19
+
20
+ Caixanegra.units.each do |unit|
21
+ units[unit.name.demodulize.underscore.to_sym] = unit
22
+ end
23
+
24
+ units
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Caixanegra
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/caixanegra.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'caixanegra/exceptions'
4
+ require 'caixanegra/unit_helper'
4
5
  require 'caixanegra/engine'
5
6
  require 'caixanegra/version'
6
7
  require 'caixanegra/executor'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caixanegra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sergiorribeiro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-30 00:00:00.000000000 Z
11
+ date: 2023-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -61,7 +61,6 @@ files:
61
61
  - app/controllers/caixanegra/api_controller.rb
62
62
  - app/controllers/caixanegra/application_controller.rb
63
63
  - app/controllers/caixanegra/designer_controller.rb
64
- - app/helpers/caixanegra/application_helper.rb
65
64
  - app/models/caixanegra/unit.rb
66
65
  - app/views/caixanegra/designer/index.html.erb
67
66
  - app/views/layouts/caixanegra/application.html.erb
@@ -72,6 +71,7 @@ files:
72
71
  - lib/caixanegra/exceptions.rb
73
72
  - lib/caixanegra/executor.rb
74
73
  - lib/caixanegra/manager.rb
74
+ - lib/caixanegra/unit_helper.rb
75
75
  - lib/caixanegra/version.rb
76
76
  - lib/tasks/caixanegra_tasks.rake
77
77
  homepage: https://github.com/sergiorribeiro/caixanegra/wiki
@@ -86,7 +86,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 2.7.5
90
90
  required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - ">="
@@ -1,4 +0,0 @@
1
- module Caixanegra
2
- module ApplicationHelper
3
- end
4
- end