sass-embedded 0.18.4 → 0.19.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25068693aab079cc3ec673b99407a0b9edfcf905c8afea7985ee06f9bbc3bb87
4
- data.tar.gz: 6af725ccc88495167bf0704d6a1789355e6d0a85280176342499e92e965cc35c
3
+ metadata.gz: 573a157ee6e0c3fa51cefec5c011649717718133d934e031a339d32a84838a13
4
+ data.tar.gz: ef27dd3177b8f58f3dd19180340686901597e9ac05efa77e2f9cc12b7784dbbb
5
5
  SHA512:
6
- metadata.gz: 577d34e39cf3adb245f39bf49ea2e621558e9d8714dc39efa8a4584f8728aed5ddb944251c9d82ffcc101d4e4788f795cade2e70a5729e84b9628a10538e22ab
7
- data.tar.gz: 3d4b4a936b6fe3d5bcb200e54e990ddb15cc668b98b6cb11db4ee93058ad469c77879dceae45dd2ba32c6bc6902b0adee120b8fb71a4908f391fc4bb0faafb68
6
+ metadata.gz: 538de1728de2da841ce66648d669acec38a4a3c3f15357e5d33e1d5dac773f246b43f29d244ec39076fc3d18504f6935374f9a5277baac7a1c400548b44aef5b
7
+ data.tar.gz: 26db551dd98592327a0c7e4fc9ee39c5917b1aff92431bfc7cdac6eea3c79899439c976512c7bed393493f564fd00e0ccafe735fe8cd8a514827d7a42b689d58
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ # The {Async} class.
6
+ #
7
+ # It awaits until the promise is resolved or rejected.
8
+ class Async
9
+ module State
10
+ PENDING = 0
11
+ FULFILLED = 1
12
+ REJECTED = 2
13
+ end
14
+
15
+ private_constant :State
16
+
17
+ def initialize
18
+ @error = nil
19
+ @result = nil
20
+ @state = State::PENDING
21
+
22
+ @condition_variable = ConditionVariable.new
23
+ @mutex = Mutex.new
24
+
25
+ begin
26
+ yield if block_given?
27
+ rescue StandardError => e
28
+ reject e
29
+ end
30
+ end
31
+
32
+ def resolve(value)
33
+ @mutex.synchronize do
34
+ return unless @state == State::PENDING
35
+
36
+ @state = State::FULFILLED
37
+ @result = value
38
+ @condition_variable.broadcast
39
+ end
40
+ end
41
+
42
+ def reject(reason)
43
+ @mutex.synchronize do
44
+ return unless @state == State::PENDING
45
+
46
+ @state = State::REJECTED
47
+ @error = reason
48
+ @condition_variable.broadcast
49
+ end
50
+ end
51
+
52
+ def await
53
+ @mutex.synchronize do
54
+ @condition_variable.wait(@mutex) if @state == State::PENDING
55
+
56
+ raise @error if @state == State::REJECTED
57
+
58
+ @result
59
+ end
60
+ end
61
+ end
62
+
63
+ private_constant :Async
64
+ end
65
+ end
@@ -2,59 +2,58 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- # The {Channel} for {Compiler} calls. Each instance creates its own
6
- # {Compiler}. A new {Compiler} is automatically created when the existing
7
- # {Compiler} runs out of unique request id.
5
+ # The {Channel} class.
6
+ #
7
+ # It establishes connection between {Host} and {Dispatcher}.
8
8
  class Channel
9
9
  def initialize
10
10
  @mutex = Mutex.new
11
- @compiler = Compiler.new
11
+ @dispatcher = Dispatcher.new
12
12
  end
13
13
 
14
14
  def close
15
15
  @mutex.synchronize do
16
- @compiler.close
16
+ @dispatcher.close
17
17
  end
18
18
  end
19
19
 
20
20
  def closed?
21
21
  @mutex.synchronize do
22
- @compiler.closed?
22
+ @dispatcher.closed?
23
23
  end
24
24
  end
25
25
 
26
- def subscribe(observer)
26
+ def connect(observer)
27
27
  @mutex.synchronize do
28
28
  begin
29
- id = @compiler.add_observer(observer)
30
- rescue ProtocolError
31
- @compiler = Compiler.new
32
- id = @compiler.add_observer(observer)
29
+ id = @dispatcher.subscribe(observer)
30
+ rescue EOFError
31
+ @dispatcher = Dispatcher.new
32
+ id = @dispatcher.subscribe(observer)
33
33
  end
34
- Subscription.new @compiler, observer, id
34
+ Connection.new(@dispatcher, id)
35
35
  end
36
36
  end
37
37
 
38
- # The {Subscription} between {Compiler} and {Observer}.
39
- class Subscription
38
+ # The {Connection} between {Host} to {Dispatcher}.
39
+ class Connection
40
40
  attr_reader :id
41
41
 
42
- def initialize(compiler, observer, id)
43
- @compiler = compiler
44
- @observer = observer
42
+ def initialize(dispatcher, id)
43
+ @dispatcher = dispatcher
45
44
  @id = id
46
45
  end
47
46
 
48
- def unsubscribe
49
- @compiler.delete_observer(@observer)
47
+ def disconnect
48
+ @dispatcher.unsubscribe(id)
50
49
  end
51
50
 
52
- def send_message(*args)
53
- @compiler.send_message(*args)
51
+ def send_message(message)
52
+ @dispatcher.send_message(message)
54
53
  end
55
54
  end
56
55
 
57
- private_constant :Subscription
56
+ private_constant :Connection
58
57
  end
59
58
 
60
59
  private_constant :Channel
@@ -1,65 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'observer'
4
3
  require 'open3'
5
4
 
6
5
  module Sass
7
6
  class Embedded
8
- # The {::Observable} {Compiler} for low level communication with
9
- # `dart-sass-embedded` using protocol buffers via stdio. Received messages
10
- # can be observed by an {Observer}.
7
+ # The {Compiler} class.
8
+ #
9
+ # It runs the `dart-sass-embedded` process.
11
10
  class Compiler
12
- include Observable
13
-
14
11
  PATH = File.absolute_path(
15
12
  "../../../ext/sass/sass_embedded/dart-sass-embedded#{Gem.win_platform? ? '.bat' : ''}", __dir__
16
13
  )
17
14
 
18
- PROTOCOL_ERROR_ID = 4_294_967_295
19
-
20
15
  def initialize
21
- @observerable_mutex = Mutex.new
22
- @id = 0
23
16
  @stdin_mutex = Mutex.new
17
+ @stdout_mutex = Mutex.new
24
18
  @stdin, @stdout, @stderr, @wait_thread = Open3.popen3(PATH)
25
19
 
26
20
  [@stdin, @stdout].each(&:binmode)
27
21
 
28
- poll do
29
- warn(@stderr.readline, uplevel: 1)
30
- end
31
- poll do
32
- receive_message Protofier.from_proto_message read
33
- end
34
- end
35
-
36
- def add_observer(*)
37
- @observerable_mutex.synchronize do
38
- raise ProtocolError, 'half-closed compiler' if half_closed?
39
-
40
- super
41
-
42
- id = @id
43
- @id = @id.next
44
- id
45
- end
46
- end
47
-
48
- def delete_observer(*)
49
- @observerable_mutex.synchronize do
50
- super
51
-
52
- close if half_closed? && count_observers.zero?
22
+ Thread.new do
23
+ loop do
24
+ warn(@stderr.readline, uplevel: 1)
25
+ rescue IOError
26
+ break
27
+ end
53
28
  end
54
29
  end
55
30
 
56
- def send_message(message)
57
- write Protofier.to_proto_message message
58
- end
59
-
60
31
  def close
61
- delete_observers
62
-
63
32
  @stdin_mutex.synchronize do
64
33
  @stdin.close unless @stdin.closed?
65
34
  @stdout.close unless @stdout.closed?
@@ -75,54 +44,19 @@ module Sass
75
44
  end
76
45
  end
77
46
 
78
- private
79
-
80
- def half_closed?
81
- @id == PROTOCOL_ERROR_ID
82
- end
83
-
84
- def poll
85
- Thread.new do
86
- loop do
87
- yield
88
- rescue StandardError
89
- break
90
- end
91
- end
92
- end
93
-
94
- def notify_observers(*args)
95
- @observerable_mutex.synchronize do
96
- changed
97
- super(*args)
98
- end
99
- end
100
-
101
- def receive_message(message)
102
- case message
103
- when EmbeddedProtocol::ProtocolError
104
- notify_observers(ProtocolError.new(message.message), nil)
105
- close
106
- else
107
- notify_observers(nil, message)
108
- end
109
- end
110
-
111
- def read
112
- length = Varint.read(@stdout)
113
- @stdout.read(length)
114
- rescue IOError => e
115
- notify_observers(e, nil)
116
- close
117
- raise e
118
- end
119
-
120
47
  def write(payload)
121
48
  @stdin_mutex.synchronize do
122
49
  Varint.write(@stdin, payload.length)
123
50
  @stdin.write(payload)
124
51
  end
125
52
  end
53
+
54
+ def read
55
+ @stdout_mutex.synchronize do
56
+ length = Varint.read(@stdout)
57
+ @stdout.read(length)
58
+ end
59
+ end
126
60
  end
127
61
 
128
62
  private_constant :Compiler
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ # The {Dispatcher} class.
6
+ #
7
+ # It dispatches messages between mutliple instances of {Host} and a single {Compiler}.
8
+ class Dispatcher
9
+ PROTOCOL_ERROR_ID = 4_294_967_295
10
+
11
+ def initialize
12
+ @compiler = Compiler.new
13
+ @observers = {}
14
+ @id = 0
15
+ @mutex = Mutex.new
16
+
17
+ Thread.new do
18
+ loop do
19
+ receive_message EmbeddedProtocol::OutboundMessage.decode @compiler.read
20
+ rescue IOError => e
21
+ half_close
22
+ @observers.each_value do |observer|
23
+ observer.error e
24
+ end
25
+ break
26
+ end
27
+ end
28
+ end
29
+
30
+ def subscribe(observer)
31
+ @mutex.synchronize do
32
+ raise EOFError if half_closed?
33
+
34
+ id = @id
35
+ @id = id.next
36
+ @observers.store(id, observer)
37
+ id
38
+ end
39
+ end
40
+
41
+ def unsubscribe(id)
42
+ @observers.delete(id)
43
+
44
+ close if half_closed? && @observers.empty?
45
+ end
46
+
47
+ def close
48
+ @compiler.close
49
+ end
50
+
51
+ def closed?
52
+ @compiler.closed?
53
+ end
54
+
55
+ def send_message(inbound_message)
56
+ @compiler.write(inbound_message.to_proto)
57
+ end
58
+
59
+ private
60
+
61
+ def half_close
62
+ @mutex.synchronize do
63
+ @id = PROTOCOL_ERROR_ID
64
+ end
65
+ end
66
+
67
+ def half_closed?
68
+ @id == PROTOCOL_ERROR_ID
69
+ end
70
+
71
+ def receive_message(outbound_message)
72
+ message = outbound_message.send(outbound_message.message)
73
+
74
+ case outbound_message.message
75
+ when :error
76
+ half_close
77
+ @observers[message.id]&.send(outbound_message.message, message)
78
+ when :compile_response, :version_response
79
+ @observers[message.id]&.send(outbound_message.message, message)
80
+ when :log_event, :canonicalize_request, :import_request, :file_import_request, :function_call_request
81
+ @observers[message.compilation_id]&.send(outbound_message.message, message)
82
+ else
83
+ raise ArgumentError, "Unknown OutboundMessage.message #{message}"
84
+ end
85
+ end
86
+ end
87
+
88
+ private_constant :Dispatcher
89
+ end
90
+ end
@@ -2,12 +2,14 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- class CompileContext
6
- # The {FunctionRegistry} for {CompileContext}.
5
+ class Host
6
+ # The {FunctionRegistry} class.
7
+ #
8
+ # It stores sass custom functions and handles function calls.
7
9
  class FunctionRegistry
8
10
  attr_reader :global_functions
9
11
 
10
- def initialize(functions, highlight:)
12
+ def initialize(functions, alert_color:)
11
13
  functions = functions.transform_keys(&:to_s)
12
14
 
13
15
  @global_functions = functions.keys
@@ -25,7 +27,7 @@ module Sass
25
27
  @functions_by_id = {}
26
28
  @ids_by_function = {}
27
29
 
28
- @highlight = highlight
30
+ @highlight = alert_color
29
31
  end
30
32
 
31
33
  def register(function)
@@ -2,12 +2,14 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- class CompileContext
6
- # The {ImporterRegistry} for {CompileContext}.
5
+ class Host
6
+ # The {ImporterRegistry} class.
7
+ #
8
+ # It stores importers and handles import requests.
7
9
  class ImporterRegistry
8
10
  attr_reader :importers
9
11
 
10
- def initialize(importers, load_paths, highlight:)
12
+ def initialize(importers, load_paths, alert_color:)
11
13
  @id = 0
12
14
  @importers_by_id = {}
13
15
  @importers = importers
@@ -20,7 +22,7 @@ module Sass
20
22
  end
21
23
  )
22
24
 
23
- @highlight = highlight
25
+ @highlight = alert_color
24
26
  end
25
27
 
26
28
  def register(importer)
@@ -2,8 +2,10 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- class CompileContext
6
- # The {LoggerRegistry} for {CompileContext}.
5
+ class Host
6
+ # The {LoggerRegistry} class.
7
+ #
8
+ # It stores logger and handles log events.
7
9
  class LoggerRegistry
8
10
  attr_reader :logger
9
11
 
@@ -2,8 +2,10 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- class CompileContext
6
- # The {ValueProtofier} between Pure Ruby types and Protobuf Ruby types.
5
+ class Host
6
+ # The {ValueProtofier} class.
7
+ #
8
+ # It converts Pure Ruby types and Protobuf Ruby types.
7
9
  class ValueProtofier
8
10
  def initialize(function_registry)
9
11
  @function_registry = function_registry
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ # The {Host} class.
6
+ #
7
+ # It communicates with {Dispatcher} and handles the host logic.
8
+ class Host
9
+ def initialize(channel)
10
+ @channel = channel
11
+ @mutex = Mutex.new
12
+ end
13
+
14
+ def id
15
+ @connection.id
16
+ end
17
+
18
+ def send_message(message)
19
+ @connection.send_message(message)
20
+ end
21
+
22
+ def compile_request(path:,
23
+ source:,
24
+ importer:,
25
+ load_paths:,
26
+ syntax:,
27
+ url:,
28
+ source_map:,
29
+ source_map_include_sources:,
30
+ style:,
31
+ functions:,
32
+ importers:,
33
+ alert_ascii:,
34
+ alert_color:,
35
+ logger:,
36
+ quiet_deps:,
37
+ verbose:)
38
+ async do
39
+ @function_registry = FunctionRegistry.new(functions, alert_color: alert_color)
40
+ @importer_registry = ImporterRegistry.new(importers, load_paths, alert_color: alert_color)
41
+ @logger_registry = LoggerRegistry.new(logger)
42
+
43
+ send_message EmbeddedProtocol::InboundMessage.new(
44
+ compile_request: EmbeddedProtocol::InboundMessage::CompileRequest.new(
45
+ id: id,
46
+ string: unless source.nil?
47
+ EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
48
+ source: source,
49
+ url: url&.to_s,
50
+ syntax: Protofier.to_proto_syntax(syntax),
51
+ importer: importer.nil? ? nil : @importer_registry.register(importer)
52
+ )
53
+ end,
54
+ path: path,
55
+ style: Protofier.to_proto_output_style(style),
56
+ source_map: source_map,
57
+ source_map_include_sources: source_map_include_sources,
58
+ importers: @importer_registry.importers,
59
+ global_functions: @function_registry.global_functions,
60
+ alert_ascii: alert_ascii,
61
+ alert_color: alert_color,
62
+ quiet_deps: quiet_deps,
63
+ verbose: verbose
64
+ )
65
+ )
66
+ end
67
+ end
68
+
69
+ def version_request
70
+ async do
71
+ send_message EmbeddedProtocol::InboundMessage.new(
72
+ version_request: EmbeddedProtocol::InboundMessage::VersionRequest.new(
73
+ id: id
74
+ )
75
+ )
76
+ end
77
+ end
78
+
79
+ def log_event(message)
80
+ @logger_registry.log(message)
81
+ end
82
+
83
+ def compile_response(message)
84
+ @async.resolve(message)
85
+ end
86
+
87
+ def version_response(message)
88
+ @async.resolve(message)
89
+ end
90
+
91
+ def canonicalize_request(message)
92
+ send_message EmbeddedProtocol::InboundMessage.new(
93
+ canonicalize_response: @importer_registry.canonicalize(message)
94
+ )
95
+ end
96
+
97
+ def import_request(message)
98
+ send_message EmbeddedProtocol::InboundMessage.new(
99
+ import_response: @importer_registry.import(message)
100
+ )
101
+ end
102
+
103
+ def file_import_request(message)
104
+ send_message EmbeddedProtocol::InboundMessage.new(
105
+ file_import_response: @importer_registry.file_import(message)
106
+ )
107
+ end
108
+
109
+ def function_call_request(message)
110
+ send_message EmbeddedProtocol::InboundMessage.new(
111
+ function_call_response: @function_registry.function_call(message)
112
+ )
113
+ end
114
+
115
+ def error(message)
116
+ @async.reject(CompileError.new(message.message, nil, nil, nil))
117
+ end
118
+
119
+ private
120
+
121
+ def async
122
+ @mutex.synchronize do
123
+ @connection = @channel.connect(self)
124
+ @async = Async.new
125
+ yield
126
+ @async.await
127
+ ensure
128
+ @connection.disconnect
129
+ end
130
+ end
131
+ end
132
+
133
+ private_constant :Host
134
+ end
135
+ end
@@ -40,7 +40,6 @@ module Sass
40
40
  # @example
41
41
  # Sass.render(file: 'style.css')
42
42
  # @return [Result]
43
- # @raise [ProtocolError]
44
43
  # @raise [RenderError]
45
44
  def render(**kwargs)
46
45
  instance.render(**kwargs)
@@ -71,7 +70,6 @@ module Sass
71
70
  # See {file:README.md#options} for supported options.
72
71
  #
73
72
  # @return [RenderResult]
74
- # @raise [ProtocolError]
75
73
  # @raise [RenderError]
76
74
  def render(data: nil,
77
75
  file: nil,
@@ -2,17 +2,10 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- # The {Protofier} between Pure Ruby types and Protobuf Ruby types.
5
+ # The {Protofier} module.
6
+ #
7
+ # It converts Pure Ruby types and Protobuf Ruby types.
6
8
  module Protofier
7
- ONEOF_MESSAGE = EmbeddedProtocol::InboundMessage
8
- .descriptor
9
- .lookup_oneof('message')
10
- .to_h do |field_descriptor|
11
- [field_descriptor.subtype, field_descriptor.name]
12
- end
13
-
14
- private_constant :ONEOF_MESSAGE
15
-
16
9
  module_function
17
10
 
18
11
  def from_proto_compile_response(compile_response)
@@ -50,17 +43,6 @@ module Sass
50
43
  source_location.column)
51
44
  end
52
45
 
53
- def from_proto_message(proto)
54
- message = EmbeddedProtocol::OutboundMessage.decode(proto)
55
- message.send(message.message)
56
- end
57
-
58
- def to_proto_message(message)
59
- EmbeddedProtocol::InboundMessage.new(
60
- ONEOF_MESSAGE[message.class.descriptor] => message
61
- ).to_proto
62
- end
63
-
64
46
  def to_proto_syntax(syntax)
65
47
  case syntax&.to_sym
66
48
  when :scss
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- # The {Structifier} that convert {::Hash} to {Struct}-like object.
5
+ # The {Structifier} module.
6
+ #
7
+ # It converts {::Hash} to {Struct}-like objects.
6
8
  module Structifier
7
9
  module_function
8
10
 
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- # Read and write {Varint} from {::IO}.
5
+ # The {Varint} module.
6
+ #
7
+ # It reads and writes varints.
6
8
  module Varint
7
9
  module_function
8
10
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- VERSION = '0.18.4'
5
+ VERSION = '0.19.0'
6
6
  end
7
7
  end
data/lib/sass/embedded.rb CHANGED
@@ -18,7 +18,6 @@ module Sass
18
18
  #
19
19
  # @return [CompileResult]
20
20
  # @raise [CompileError]
21
- # @raise [ProtocolError]
22
21
  def compile(path,
23
22
  load_paths: [],
24
23
 
@@ -38,23 +37,24 @@ module Sass
38
37
  raise ArgumentError, 'path must be set' if path.nil?
39
38
 
40
39
  Protofier.from_proto_compile_response(
41
- CompileContext.new(@channel,
42
- path: path,
43
- source: nil,
44
- importer: nil,
45
- load_paths: load_paths,
46
- syntax: nil,
47
- url: nil,
48
- source_map: source_map,
49
- source_map_include_sources: source_map_include_sources,
50
- style: style,
51
- functions: functions,
52
- importers: importers,
53
- alert_color: alert_color,
54
- alert_ascii: alert_ascii,
55
- logger: logger,
56
- quiet_deps: quiet_deps,
57
- verbose: verbose).receive_message
40
+ Host.new(@channel).compile_request(
41
+ path: path,
42
+ source: nil,
43
+ importer: nil,
44
+ load_paths: load_paths,
45
+ syntax: nil,
46
+ url: nil,
47
+ source_map: source_map,
48
+ source_map_include_sources: source_map_include_sources,
49
+ style: style,
50
+ functions: functions,
51
+ importers: importers,
52
+ alert_color: alert_color,
53
+ alert_ascii: alert_ascii,
54
+ logger: logger,
55
+ quiet_deps: quiet_deps,
56
+ verbose: verbose
57
+ )
58
58
  )
59
59
  end
60
60
 
@@ -62,7 +62,6 @@ module Sass
62
62
  #
63
63
  # @return [CompileResult]
64
64
  # @raise [CompileError]
65
- # @raise [ProtocolError]
66
65
  def compile_string(source,
67
66
  importer: nil,
68
67
  load_paths: [],
@@ -84,31 +83,30 @@ module Sass
84
83
  raise ArgumentError, 'source must be set' if source.nil?
85
84
 
86
85
  Protofier.from_proto_compile_response(
87
- CompileContext.new(@channel,
88
- path: nil,
89
- source: source,
90
- importer: importer,
91
- load_paths: load_paths,
92
- syntax: syntax,
93
- url: url,
94
- source_map: source_map,
95
- source_map_include_sources: source_map_include_sources,
96
- style: style,
97
- functions: functions,
98
- importers: importers,
99
- alert_color: alert_color,
100
- alert_ascii: alert_ascii,
101
- logger: logger,
102
- quiet_deps: quiet_deps,
103
- verbose: verbose).receive_message
86
+ Host.new(@channel).compile_request(
87
+ path: nil,
88
+ source: source,
89
+ importer: importer,
90
+ load_paths: load_paths,
91
+ syntax: syntax,
92
+ url: url,
93
+ source_map: source_map,
94
+ source_map_include_sources: source_map_include_sources,
95
+ style: style,
96
+ functions: functions,
97
+ importers: importers,
98
+ alert_color: alert_color,
99
+ alert_ascii: alert_ascii,
100
+ logger: logger,
101
+ quiet_deps: quiet_deps,
102
+ verbose: verbose
103
+ )
104
104
  )
105
105
  end
106
106
 
107
107
  # The {Embedded#info} method.
108
- #
109
- # @raise [ProtocolError]
110
108
  def info
111
- @info ||= "sass-embedded\t#{VersionContext.new(@channel).receive_message.implementation_version}"
109
+ @info ||= "sass-embedded\t#{Host.new(@channel).version_request.implementation_version}"
112
110
  end
113
111
 
114
112
  def close
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's argument list type.
6
6
  #
7
7
  # An argument list comes from a rest argument. It's distinct from a normal {List} in that it may contain a keyword
8
8
  # map as well as the positional arguments.
9
- class ArgumentList < Sass::Value::List
9
+ class ArgumentList < Value::List
10
10
  def initialize(contents = [], keywords = {}, separator = ',')
11
11
  super(contents, separator: separator)
12
12
 
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's boolean type.
6
- class Boolean < Sass::Value
7
- def initialize(value) # rubocop:disable Lint/MissingSuper
6
+ class Boolean
7
+ include Value
8
+
9
+ def initialize(value)
8
10
  @value = value
9
11
  end
10
12
 
@@ -1,14 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's color type.
6
6
  #
7
7
  # No matter what representation was originally used to create this color, all of its channels are accessible.
8
- class Color < Sass::Value
9
- def initialize(red: nil, green: nil, blue: nil, # rubocop:disable Lint/MissingSuper
10
- hue: nil, saturation: nil, lightness: nil,
11
- whiteness: nil, blackness: nil,
8
+ class Color
9
+ include Value
10
+
11
+ def initialize(red: nil,
12
+ green: nil,
13
+ blue: nil,
14
+ hue: nil,
15
+ saturation: nil,
16
+ lightness: nil,
17
+ whiteness: nil,
18
+ blackness: nil,
12
19
  alpha: nil)
13
20
  @alpha = alpha.nil? ? 1 : FuzzyMath.assert_between(alpha, 0, 1, 'alpha')
14
21
  if red && green && blue
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's function type.
6
- class Function < Sass::Value
7
- def initialize(id_or_signature, callback = nil) # rubocop:disable Lint/MissingSuper
6
+ class Function
7
+ include Value
8
+
9
+ def initialize(id_or_signature, callback = nil)
8
10
  if id_or_signature.is_a? Numeric
9
11
  @id = id_or_signature
10
12
  else
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's {FuzzyMath} module.
6
6
  module FuzzyMath
7
7
  PRECISION = 10
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's list type.
6
- class List < Sass::Value
7
- def initialize(contents = [], separator: ',', bracketed: false) # rubocop:disable Lint/MissingSuper
6
+ class List
7
+ include Value
8
+
9
+ def initialize(contents = [], separator: ',', bracketed: false)
8
10
  if separator.nil? && contents.length > 1
9
11
  raise error 'A list with more than one element must have an explicit separator'
10
12
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's map type.
6
- class Map < Sass::Value
7
- def initialize(contents = {}) # rubocop:disable Lint/MissingSuper
6
+ class Map
7
+ include Value
8
+
9
+ def initialize(contents = {})
8
10
  @contents = contents.freeze
9
11
  end
10
12
 
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's null type.
6
- class Null < Sass::Value
7
- def initialize # rubocop:disable Lint/MissingSuper
6
+ class Null
7
+ include Value
8
+
9
+ def initialize
8
10
  @value = nil
9
11
  end
10
12
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  class Number
6
6
  # The {Unit} module.
7
7
  module Unit
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's number type.
6
- class Number < Sass::Value
7
- def initialize(value, numerator_units = [], denominator_units = []) # rubocop:disable Lint/MissingSuper
6
+ class Number
7
+ include Value
8
+
9
+ def initialize(value, numerator_units = [], denominator_units = [])
8
10
  numerator_units = [numerator_units] if numerator_units.is_a?(::String)
9
11
  denominator_units = [denominator_units] if denominator_units.is_a?(::String)
10
12
 
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Value
4
+ module Value
5
5
  # Sass's string type.
6
- class String < Sass::Value
7
- def initialize(text = '', quoted: true) # rubocop:disable Lint/MissingSuper
6
+ class String
7
+ include Value
8
+
9
+ def initialize(text = '', quoted: true)
8
10
  @text = text.freeze
9
11
  @quoted = quoted
10
12
  end
data/lib/sass/value.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Sass
4
4
  # The abstract base class of Sass's value types.
5
- class Value
5
+ module Value
6
6
  def to_a
7
7
  [self]
8
8
  end
data/lib/sass.rb CHANGED
@@ -3,22 +3,21 @@
3
3
  require_relative 'sass/compile_error'
4
4
  require_relative 'sass/compile_result'
5
5
  require_relative 'sass/embedded'
6
+ require_relative 'sass/embedded/async'
6
7
  require_relative 'sass/embedded/channel'
7
- require_relative 'sass/embedded/observer'
8
- require_relative 'sass/embedded/compile_context'
9
- require_relative 'sass/embedded/compile_context/function_registry'
10
- require_relative 'sass/embedded/compile_context/importer_registry'
11
- require_relative 'sass/embedded/compile_context/logger_registry'
12
- require_relative 'sass/embedded/compile_context/value_protofier'
13
8
  require_relative 'sass/embedded/compiler'
14
- require_relative 'sass/embedded_protocol'
9
+ require_relative 'sass/embedded/dispatcher'
10
+ require_relative 'sass/embedded/host'
11
+ require_relative 'sass/embedded/host/function_registry'
12
+ require_relative 'sass/embedded/host/importer_registry'
13
+ require_relative 'sass/embedded/host/logger_registry'
14
+ require_relative 'sass/embedded/host/value_protofier'
15
15
  require_relative 'sass/embedded/legacy'
16
- require_relative 'sass/embedded/protocol_error'
17
16
  require_relative 'sass/embedded/protofier'
18
17
  require_relative 'sass/embedded/structifier'
19
18
  require_relative 'sass/embedded/varint'
20
19
  require_relative 'sass/embedded/version'
21
- require_relative 'sass/embedded/version_context'
20
+ require_relative 'sass/embedded_protocol'
22
21
  require_relative 'sass/logger'
23
22
  require_relative 'sass/logger/source_location'
24
23
  require_relative 'sass/logger/source_span'
@@ -51,7 +50,6 @@ module Sass
51
50
  # Sass.compile('style.scss')
52
51
  # @return [CompileResult]
53
52
  # @raise [CompileError]
54
- # @raise [Embedded::ProtocolError]
55
53
  def compile(path, **kwargs)
56
54
  instance.compile(path, **kwargs)
57
55
  end
@@ -66,7 +64,6 @@ module Sass
66
64
  # Sass.compile_string('h1 { font-size: 40px; }')
67
65
  # @return [CompileResult]
68
66
  # @raise [CompileError]
69
- # @raise [Embedded::ProtocolError]
70
67
  def compile_string(source, **kwargs)
71
68
  instance.compile_string(source, **kwargs)
72
69
  end
@@ -74,8 +71,6 @@ module Sass
74
71
  # The global {.info} method.
75
72
  #
76
73
  # This instantiates a global {Embedded} instance and calls {Embedded#info}.
77
- #
78
- # @raise [Embedded::ProtocolError]
79
74
  def info
80
75
  instance.info
81
76
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass-embedded
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.4
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - なつき
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-21 00:00:00.000000000 Z
11
+ date: 2022-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -128,21 +128,20 @@ files:
128
128
  - lib/sass/compile_error.rb
129
129
  - lib/sass/compile_result.rb
130
130
  - lib/sass/embedded.rb
131
+ - lib/sass/embedded/async.rb
131
132
  - lib/sass/embedded/channel.rb
132
- - lib/sass/embedded/compile_context.rb
133
- - lib/sass/embedded/compile_context/function_registry.rb
134
- - lib/sass/embedded/compile_context/importer_registry.rb
135
- - lib/sass/embedded/compile_context/logger_registry.rb
136
- - lib/sass/embedded/compile_context/value_protofier.rb
137
133
  - lib/sass/embedded/compiler.rb
134
+ - lib/sass/embedded/dispatcher.rb
135
+ - lib/sass/embedded/host.rb
136
+ - lib/sass/embedded/host/function_registry.rb
137
+ - lib/sass/embedded/host/importer_registry.rb
138
+ - lib/sass/embedded/host/logger_registry.rb
139
+ - lib/sass/embedded/host/value_protofier.rb
138
140
  - lib/sass/embedded/legacy.rb
139
- - lib/sass/embedded/observer.rb
140
- - lib/sass/embedded/protocol_error.rb
141
141
  - lib/sass/embedded/protofier.rb
142
142
  - lib/sass/embedded/structifier.rb
143
143
  - lib/sass/embedded/varint.rb
144
144
  - lib/sass/embedded/version.rb
145
- - lib/sass/embedded/version_context.rb
146
145
  - lib/sass/embedded_protocol.rb
147
146
  - lib/sass/logger.rb
148
147
  - lib/sass/logger/source_location.rb
@@ -164,8 +163,8 @@ homepage: https://github.com/ntkme/sass-embedded-host-ruby
164
163
  licenses:
165
164
  - MIT
166
165
  metadata:
167
- documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.18.4
168
- source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.18.4
166
+ documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.19.0
167
+ source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.19.0
169
168
  funding_uri: https://github.com/sponsors/ntkme
170
169
  post_install_message:
171
170
  rdoc_options: []
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- class Embedded
5
- # The {Observer} for {Embedded#compile}.
6
- class CompileContext
7
- include Observer
8
-
9
- def initialize(channel,
10
- path:,
11
- source:,
12
-
13
- importer:,
14
- load_paths:,
15
- syntax:,
16
- url:,
17
-
18
- source_map:,
19
- source_map_include_sources:,
20
- style:,
21
-
22
- functions:,
23
- importers:,
24
-
25
- alert_ascii:,
26
- alert_color:,
27
- logger:,
28
- quiet_deps:,
29
- verbose:)
30
- @function_registery = FunctionRegistry.new(functions, highlight: alert_color)
31
- @importer_registery = ImporterRegistry.new(importers, load_paths, highlight: alert_color)
32
- @logger_registery = LoggerRegistry.new(logger)
33
-
34
- super(channel)
35
-
36
- send_message EmbeddedProtocol::InboundMessage::CompileRequest.new(
37
- id: id,
38
- string: unless source.nil?
39
- EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
40
- source: source,
41
- url: url&.to_s,
42
- syntax: Protofier.to_proto_syntax(syntax),
43
- importer: importer.nil? ? nil : @importer_registery.register(importer)
44
- )
45
- end,
46
- path: path,
47
- style: Protofier.to_proto_output_style(style),
48
- source_map: source_map,
49
- source_map_include_sources: source_map_include_sources,
50
- importers: @importer_registery.importers,
51
- global_functions: @function_registery.global_functions,
52
- alert_ascii: alert_ascii,
53
- alert_color: alert_color,
54
- quiet_deps: quiet_deps,
55
- verbose: verbose
56
- )
57
- end
58
-
59
- def update(error, message)
60
- raise error unless error.nil?
61
-
62
- case message
63
- when EmbeddedProtocol::OutboundMessage::CompileResponse
64
- return unless message.id == id
65
-
66
- Thread.new do
67
- super(nil, message)
68
- end
69
- when EmbeddedProtocol::OutboundMessage::LogEvent
70
- return unless message.compilation_id == id
71
-
72
- @logger_registery.log message
73
- when EmbeddedProtocol::OutboundMessage::CanonicalizeRequest
74
- return unless message.compilation_id == id
75
-
76
- Thread.new do
77
- send_message @importer_registery.canonicalize message
78
- end
79
- when EmbeddedProtocol::OutboundMessage::ImportRequest
80
- return unless message.compilation_id == id
81
-
82
- Thread.new do
83
- send_message @importer_registery.import message
84
- end
85
- when EmbeddedProtocol::OutboundMessage::FileImportRequest
86
- return unless message.compilation_id == id
87
-
88
- Thread.new do
89
- send_message @importer_registery.file_import message
90
- end
91
- when EmbeddedProtocol::OutboundMessage::FunctionCallRequest
92
- return unless message.compilation_id == id
93
-
94
- Thread.new do
95
- send_message @function_registery.function_call message
96
- end
97
- end
98
- rescue StandardError => e
99
- Thread.new do
100
- super(e, nil)
101
- end
102
- end
103
- end
104
-
105
- private_constant :CompileContext
106
- end
107
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- class Embedded
5
- # The {Observer} module for communicating with {Compiler}.
6
- module Observer
7
- def initialize(channel)
8
- @mutex = Mutex.new
9
- @condition_variable = ConditionVariable.new
10
- @error = nil
11
- @message = nil
12
-
13
- @subscription = channel.subscribe(self)
14
- end
15
-
16
- def receive_message
17
- @mutex.synchronize do
18
- @condition_variable.wait(@mutex) if @error.nil? && @message.nil?
19
- end
20
-
21
- raise @error unless @error.nil?
22
-
23
- @message
24
- end
25
-
26
- def update(error, message)
27
- @subscription.unsubscribe
28
-
29
- @mutex.synchronize do
30
- @error = error
31
- @message = message
32
- @condition_variable.broadcast
33
- end
34
- end
35
-
36
- private
37
-
38
- def id
39
- @subscription.id
40
- end
41
-
42
- def send_message(*args)
43
- @subscription.send_message(*args)
44
- end
45
- end
46
-
47
- private_constant :Observer
48
- end
49
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- class Embedded
5
- class ProtocolError < StandardError; end
6
- end
7
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- class Embedded
5
- # The {Observer} for {Embedded#info}.
6
- class VersionContext
7
- include Observer
8
-
9
- def initialize(channel)
10
- super(channel)
11
-
12
- send_message EmbeddedProtocol::InboundMessage::VersionRequest.new(id: id)
13
- end
14
-
15
- def update(error, message)
16
- raise error unless error.nil?
17
-
18
- case message
19
- when EmbeddedProtocol::OutboundMessage::VersionResponse
20
- return unless message.id == id
21
-
22
- Thread.new do
23
- super(nil, message)
24
- end
25
- end
26
- rescue StandardError => e
27
- Thread.new do
28
- super(e, nil)
29
- end
30
- end
31
- end
32
-
33
- private_constant :VersionContext
34
- end
35
- end