sass-embedded 1.63.3-x86_64-linux-android → 1.63.5-x86_64-linux-android

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: b3a1ea0e2666c8f3a46f59c38a6bfb885158766bb509c707d53591a4c9a4080c
4
- data.tar.gz: 793b04bfdcb026c421d805867f5c3141ed241e55d44c79b4511a69751993f63d
3
+ metadata.gz: e210a4c43c3ce95dc054757a426eaa5fafdf2725a2d541ef313c4b356c7b954e
4
+ data.tar.gz: f02f5acab67b1e5a622824d11317f8d3c44b397bab9f80533dfc4ee20b000bb8
5
5
  SHA512:
6
- metadata.gz: 7225b54f551aa19a2e2aa5a55722d53be7e184c79e315cae81ab3f08467c2829f8065b45c9a0d2f55ee13e0790170ff65083ce3aebc5229c983a561ec18df649
7
- data.tar.gz: 4b25aad05251ccb79dd6920e95c9e424ca4a763de9a4498dd21e7db911751a66328801abc6f664439f5e773849131197c5d50a61e18f8512ed68a60bd81c14d7
6
+ metadata.gz: 576b94c43c73106ffa14ecc184c35e9189bde8750adab64b4acf2b52bc948e1595e61183e97d2ab1f46b2898718fef4a6a6f2341cbd543379406fb024d36862f
7
+ data.tar.gz: daf59255aa9c87988c2f8bd41edf40b98e7e53f11993b5c718104b5d647f491cd86d5fa51b712f2d5f7ff0200a88019fe099274e990c1e2a6d9be860219fea6e
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![build](https://github.com/ntkme/sass-embedded-host-ruby/actions/workflows/build.yml/badge.svg)](https://github.com/ntkme/sass-embedded-host-ruby/actions/workflows/build.yml)
4
4
  [![gem](https://badge.fury.io/rb/sass-embedded.svg)](https://rubygems.org/gems/sass-embedded)
5
5
 
6
- This is a Ruby library that implements the host side of the [Embedded Sass protocol](https://github.com/sass/embedded-protocol).
6
+ This is a Ruby library that implements the host side of the [Embedded Sass protocol](https://github.com/sass/sass/blob/HEAD/spec/embedded-protocol.md).
7
7
 
8
8
  It exposes a Ruby API for Sass that's backed by a native [Dart Sass](https://sass-lang.com/dart-sass) executable.
9
9
 
Binary file
Binary file
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fiddle'
4
+
5
+ # @!visibility private
6
+ # @see https://learn.microsoft.com/en-us/windows/win32/api/
7
+ module Win32API
8
+ Kernel32 = Fiddle.dlopen('Kernel32.dll')
9
+
10
+ # @see https://learn.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants
11
+ module ImageFileMachineConstants
12
+ IMAGE_FILE_MACHINE_I386 = 0x014c
13
+ IMAGE_FILE_MACHINE_ARMNT = 0x01c4
14
+ IMAGE_FILE_MACHINE_AMD64 = 0x8664
15
+ IMAGE_FILE_MACHINE_ARM64 = 0xaa64
16
+ end
17
+
18
+ private_constant :ImageFileMachineConstants
19
+
20
+ # @see https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ne-processthreadsapi-machine_attributes
21
+ module MachineAttributes
22
+ USER_ENABLED = 0x00000001
23
+ KERNEL_ENABLED = 0x00000002
24
+ WOW64_CONTAINER = 0x00000004
25
+ end
26
+
27
+ private_constant :MachineAttributes
28
+
29
+ # Specifies the ways in which an architecture of code can run on a host operating system.
30
+ class MachineTypeAttributes
31
+ def initialize(machine_type_attributes)
32
+ @machine_type_attributes = machine_type_attributes
33
+ end
34
+
35
+ # The specified architecture of code can run in user mode.
36
+ def user_enabled?
37
+ @machine_type_attributes & MachineAttributes::USER_ENABLED == MachineAttributes::USER_ENABLED
38
+ end
39
+
40
+ # The specified architecture of code can run in kernel mode.
41
+ def kernel_enabled?
42
+ @machine_type_attributes & MachineAttributes::KERNEL_ENABLED == MachineAttributes::KERNEL_ENABLED
43
+ end
44
+
45
+ # The specified architecture of code runs on WOW64.
46
+ def wow64_container?
47
+ @machine_type_attributes & MachineAttributes::WOW64_CONTAINER == MachineAttributes::WOW64_CONTAINER
48
+ end
49
+ end
50
+
51
+ private_constant :MachineTypeAttributes
52
+
53
+ class << self
54
+ def x86?
55
+ get_machine_type_attributes(ImageFileMachineConstants::IMAGE_FILE_MACHINE_I386).user_enabled?
56
+ end
57
+
58
+ def arm?
59
+ get_machine_type_attributes(ImageFileMachineConstants::IMAGE_FILE_MACHINE_ARMNT).user_enabled?
60
+ end
61
+
62
+ def x64?
63
+ get_machine_type_attributes(ImageFileMachineConstants::IMAGE_FILE_MACHINE_AMD64).user_enabled?
64
+ end
65
+
66
+ def arm64?
67
+ get_machine_type_attributes(ImageFileMachineConstants::IMAGE_FILE_MACHINE_ARM64).user_enabled?
68
+ end
69
+
70
+ private
71
+
72
+ begin
73
+ # @see https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getmachinetypeattributes
74
+ GetMachineTypeAttributes = Fiddle::Function.new(
75
+ Kernel32['GetMachineTypeAttributes'],
76
+ [-Fiddle::TYPE_SHORT, Fiddle::TYPE_VOIDP],
77
+ Fiddle::TYPE_LONG
78
+ )
79
+
80
+ def get_machine_type_attributes(machine)
81
+ p_machine_type_attributes = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT, Fiddle::RUBY_FREE)
82
+ raise Fiddle.win32_last_error unless GetMachineTypeAttributes.call(machine, p_machine_type_attributes).zero?
83
+
84
+ MachineTypeAttributes.new(p_machine_type_attributes.to_str.unpack1('i'))
85
+ end
86
+ rescue Fiddle::DLError
87
+ # @see https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocess
88
+ GetCurrentProcess = Fiddle::Function.new(
89
+ Kernel32['GetCurrentProcess'],
90
+ [],
91
+ Fiddle::TYPE_VOIDP
92
+ )
93
+
94
+ # @see https://learn.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64process2
95
+ IsWow64Process2 = Fiddle::Function.new(
96
+ Kernel32['IsWow64Process2'],
97
+ [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
98
+ Fiddle::TYPE_CHAR
99
+ )
100
+
101
+ # @see https://learn.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-iswow64guestmachinesupported
102
+ IsWow64GuestMachineSupported = Fiddle::Function.new(
103
+ Kernel32['IsWow64GuestMachineSupported'],
104
+ [-Fiddle::TYPE_SHORT, Fiddle::TYPE_VOIDP],
105
+ Fiddle::TYPE_LONG
106
+ )
107
+
108
+ def get_machine_type_attributes(machine)
109
+ h_process = GetCurrentProcess.call
110
+ p_process_machine = Fiddle::Pointer.malloc(Fiddle::SIZEOF_SHORT, Fiddle::RUBY_FREE)
111
+ p_native_machine = Fiddle::Pointer.malloc(Fiddle::SIZEOF_SHORT, Fiddle::RUBY_FREE)
112
+ raise Fiddle.win32_last_error if IsWow64Process2.call(h_process, p_process_machine, p_native_machine).zero?
113
+
114
+ if p_native_machine.to_str.unpack1('S!') == machine
115
+ return MachineTypeAttributes.new(MachineAttributes::USER_ENABLED | MachineAttributes::KERNEL_ENABLED)
116
+ end
117
+
118
+ p_machine_is_supported = Fiddle::Pointer.malloc(Fiddle::SIZEOF_CHAR, Fiddle::RUBY_FREE)
119
+ raise Fiddle.win32_last_error unless IsWow64GuestMachineSupported.call(machine, p_machine_is_supported).zero?
120
+
121
+ if p_machine_is_supported.to_str.unpack1('c').zero?
122
+ MachineTypeAttributes.new(0)
123
+ else
124
+ MachineTypeAttributes.new(MachineAttributes::USER_ENABLED | MachineAttributes::WOW64_CONTAINER)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -4,10 +4,10 @@ require 'open3'
4
4
 
5
5
  module Sass
6
6
  class Embedded
7
- # The {Compiler} class.
7
+ # The stdio based {Connection} between the {Dispatcher} and the compiler.
8
8
  #
9
- # It runs the `sass --embedded` process.
10
- class Compiler
9
+ # It runs the `sass --embedded` command.
10
+ class Connection
11
11
  def initialize
12
12
  @stdin, @stdout, @stderr, @wait_thread = begin
13
13
  Open3.popen3(*CLI::COMMAND, '--embedded', chdir: __dir__)
@@ -67,6 +67,6 @@ module Sass
67
67
  end
68
68
  end
69
69
 
70
- private_constant :Compiler
70
+ private_constant :Connection
71
71
  end
72
72
  end
@@ -4,12 +4,12 @@ module Sass
4
4
  class Embedded
5
5
  # The {Dispatcher} class.
6
6
  #
7
- # It dispatches messages between mutliple instances of {Host} and a single {Compiler}.
7
+ # It dispatches messages between mutliple instances of {Host} and a single {Connection} to the compiler.
8
8
  class Dispatcher
9
9
  UINT_MAX = 0xffffffff
10
10
 
11
11
  def initialize
12
- @compiler = Compiler.new
12
+ @connection = Connection.new
13
13
  @observers = {}
14
14
  @id = 1
15
15
  @mutex = Mutex.new
@@ -46,34 +46,34 @@ module Sass
46
46
 
47
47
  return unless @observers.empty?
48
48
 
49
- # if @id == UINT_MAX
50
- # close
51
- # else
52
- # @id = 1
53
- # end
54
-
55
- # Resetting @id can cause a race condition in compiler
56
- # See: https://github.com/sass/dart-sass/issues/2004
57
- close if @id == UINT_MAX
49
+ if @id == UINT_MAX
50
+ close
51
+ else
52
+ @id = 1
53
+ end
58
54
  end
59
55
  end
60
56
 
57
+ def connect(host)
58
+ Channel.new(self, host)
59
+ end
60
+
61
61
  def close
62
- @compiler.close
62
+ @connection.close
63
63
  end
64
64
 
65
65
  def closed?
66
- @compiler.closed?
66
+ @connection.closed?
67
67
  end
68
68
 
69
69
  def send_proto(...)
70
- @compiler.write(...)
70
+ @connection.write(...)
71
71
  end
72
72
 
73
73
  private
74
74
 
75
75
  def receive_proto
76
- id, proto = @compiler.read
76
+ id, proto = @connection.read
77
77
  case id
78
78
  when 1...UINT_MAX
79
79
  @mutex.synchronize { @observers[id] }.receive_proto(proto)
@@ -91,6 +91,26 @@ module Sass
91
91
  raise Errno::EPROTO
92
92
  end
93
93
  end
94
+
95
+ # The {Channel} between {Dispatcher} and {Host}.
96
+ class Channel
97
+ attr_reader :id
98
+
99
+ def initialize(dispatcher, host)
100
+ @dispatcher = dispatcher
101
+ @id = @dispatcher.subscribe(host)
102
+ end
103
+
104
+ def disconnect
105
+ @dispatcher.unsubscribe(id)
106
+ end
107
+
108
+ def send_proto(...)
109
+ @dispatcher.send_proto(...)
110
+ end
111
+ end
112
+
113
+ private_constant :Channel
94
114
  end
95
115
 
96
116
  private_constant :Dispatcher
@@ -11,8 +11,8 @@ module Sass
11
11
  #
12
12
  # It communicates with {Dispatcher} and handles the host logic.
13
13
  class Host
14
- def initialize(channel)
15
- @channel = channel
14
+ def initialize(dispatcher)
15
+ @dispatcher = dispatcher
16
16
  end
17
17
 
18
18
  def compile_request(path:,
@@ -117,7 +117,7 @@ module Sass
117
117
  private
118
118
 
119
119
  def await0
120
- @connection = @channel.connect(self)
120
+ @channel = @dispatcher.connect(self)
121
121
  @queue = Queue.new
122
122
 
123
123
  yield
@@ -128,11 +128,11 @@ module Sass
128
128
 
129
129
  @result
130
130
  ensure
131
- @connection&.disconnect
131
+ @channel&.disconnect
132
132
  end
133
133
 
134
134
  def await
135
- @connection = @channel.connect(self)
135
+ @channel = @dispatcher.connect(self)
136
136
  @queue = Queue.new
137
137
 
138
138
  yield
@@ -148,21 +148,21 @@ module Sass
148
148
 
149
149
  @result
150
150
  ensure
151
- @connection&.disconnect
151
+ @channel&.disconnect
152
152
  end
153
153
 
154
154
  def id
155
- @connection.id
155
+ @channel.id
156
156
  end
157
157
 
158
158
  def send_message0(...)
159
159
  inbound_message = EmbeddedProtocol::InboundMessage.new(...)
160
- @connection.send_proto(0, inbound_message.to_proto)
160
+ @channel.send_proto(0, inbound_message.to_proto)
161
161
  end
162
162
 
163
163
  def send_message(...)
164
164
  inbound_message = EmbeddedProtocol::InboundMessage.new(...)
165
- @connection.send_proto(id, inbound_message.to_proto)
165
+ @channel.send_proto(id, inbound_message.to_proto)
166
166
  end
167
167
  end
168
168
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ class Embedded
5
+ # The {ResilientDispatcher} class.
6
+ #
7
+ # It recovers from failures and continues to function.
8
+ class ResilientDispatcher
9
+ def initialize
10
+ @dispatcher = Dispatcher.new
11
+ @mutex = Mutex.new
12
+ end
13
+
14
+ def close
15
+ @mutex.synchronize do
16
+ @dispatcher.close
17
+ end
18
+ end
19
+
20
+ def closed?
21
+ @mutex.synchronize do
22
+ @dispatcher.closed?
23
+ end
24
+ end
25
+
26
+ def connect(host)
27
+ @dispatcher.connect(host)
28
+ rescue Errno::EBUSY
29
+ @mutex.synchronize do
30
+ @dispatcher.connect(host)
31
+ rescue Errno::EBUSY
32
+ @dispatcher = Dispatcher.new
33
+ @dispatcher.connect(host)
34
+ end
35
+ end
36
+ end
37
+
38
+ private_constant :ResilientDispatcher
39
+ end
40
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sass
4
4
  class Embedded
5
- VERSION = '1.63.3'
5
+ VERSION = '1.63.5'
6
6
  end
7
7
  end
data/lib/sass/embedded.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../ext/sass/cli'
4
- require_relative '../../ext/sass/embedded_sass_pb'
5
4
  require_relative 'compile_error'
6
5
  require_relative 'compile_result'
7
- require_relative 'embedded/channel'
8
- require_relative 'embedded/compiler'
6
+ require_relative 'embedded/connection'
9
7
  require_relative 'embedded/dispatcher'
10
8
  require_relative 'embedded/host'
11
9
  require_relative 'embedded/protofier'
10
+ require_relative 'embedded/resilient_dispatcher'
12
11
  require_relative 'embedded/structifier'
13
12
  require_relative 'embedded/varint'
14
13
  require_relative 'embedded/version'
14
+ require_relative 'embedded_protocol'
15
15
  require_relative 'logger/silent'
16
16
  require_relative 'logger/source_location'
17
17
  require_relative 'logger/source_span'
@@ -80,7 +80,7 @@ module Sass
80
80
  # rubocop:enable Layout/LineLength
81
81
 
82
82
  # The {Embedded} host for using dart-sass. Each instance creates its own
83
- # communication {Channel} with a dedicated compiler process.
83
+ # communication {Dispatcher} with a dedicated compiler process.
84
84
  #
85
85
  # @example
86
86
  # embedded = Sass::Embedded.new
@@ -89,7 +89,7 @@ module Sass
89
89
  # embedded.close
90
90
  class Embedded
91
91
  def initialize
92
- @channel = Channel.new
92
+ @dispatcher = ResilientDispatcher.new
93
93
  end
94
94
 
95
95
  # Compiles the Sass file at +path+ to CSS.
@@ -138,7 +138,7 @@ module Sass
138
138
  verbose: false)
139
139
  raise ArgumentError, 'path must be set' if path.nil?
140
140
 
141
- Host.new(@channel).compile_request(
141
+ Host.new(@dispatcher).compile_request(
142
142
  path: path,
143
143
  source: nil,
144
144
  importer: nil,
@@ -212,7 +212,7 @@ module Sass
212
212
  verbose: false)
213
213
  raise ArgumentError, 'source must be set' if source.nil?
214
214
 
215
- Host.new(@channel).compile_request(
215
+ Host.new(@dispatcher).compile_request(
216
216
  path: nil,
217
217
  source: source,
218
218
  importer: importer,
@@ -236,17 +236,15 @@ module Sass
236
236
  # @return [String] Information about the Sass implementation.
237
237
  # @see https://sass-lang.com/documentation/js-api/modules#info
238
238
  def info
239
- @info ||= Host.new(@channel).version_request
239
+ @info ||= Host.new(@dispatcher).version_request
240
240
  end
241
241
 
242
242
  def close
243
- @channel.close
243
+ @dispatcher.close
244
244
  end
245
245
 
246
246
  def closed?
247
- @channel.closed?
247
+ @dispatcher.closed?
248
248
  end
249
249
  end
250
-
251
- private_constant :EmbeddedProtocol
252
250
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # @see https://github.com/sass/sass/blob/HEAD/spec/embedded-protocol.md
5
+ module EmbeddedProtocol
6
+ require_relative '../../ext/sass/embedded_sass_pb'
7
+ end
8
+
9
+ private_constant :EmbeddedProtocol
10
+ 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: 1.63.3
4
+ version: 1.63.5
5
5
  platform: x86_64-linux-android
6
6
  authors:
7
7
  - なつき
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-09 00:00:00.000000000 Z
11
+ date: 2023-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -42,13 +42,13 @@ files:
42
42
  - ext/sass/dart-sass/src/dart
43
43
  - ext/sass/dart-sass/src/sass.snapshot
44
44
  - ext/sass/embedded_sass_pb.rb
45
+ - ext/sass/win32_api.rb
45
46
  - lib/sass-embedded.rb
46
47
  - lib/sass/compile_error.rb
47
48
  - lib/sass/compile_result.rb
48
49
  - lib/sass/elf.rb
49
50
  - lib/sass/embedded.rb
50
- - lib/sass/embedded/channel.rb
51
- - lib/sass/embedded/compiler.rb
51
+ - lib/sass/embedded/connection.rb
52
52
  - lib/sass/embedded/dispatcher.rb
53
53
  - lib/sass/embedded/host.rb
54
54
  - lib/sass/embedded/host/function_registry.rb
@@ -56,9 +56,11 @@ files:
56
56
  - lib/sass/embedded/host/logger_registry.rb
57
57
  - lib/sass/embedded/host/value_protofier.rb
58
58
  - lib/sass/embedded/protofier.rb
59
+ - lib/sass/embedded/resilient_dispatcher.rb
59
60
  - lib/sass/embedded/structifier.rb
60
61
  - lib/sass/embedded/varint.rb
61
62
  - lib/sass/embedded/version.rb
63
+ - lib/sass/embedded_protocol.rb
62
64
  - lib/sass/logger/silent.rb
63
65
  - lib/sass/logger/source_location.rb
64
66
  - lib/sass/logger/source_span.rb
@@ -79,8 +81,8 @@ homepage: https://github.com/ntkme/sass-embedded-host-ruby
79
81
  licenses:
80
82
  - MIT
81
83
  metadata:
82
- documentation_uri: https://rubydoc.info/gems/sass-embedded/1.63.3
83
- source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v1.63.3
84
+ documentation_uri: https://rubydoc.info/gems/sass-embedded/1.63.5
85
+ source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v1.63.5
84
86
  funding_uri: https://github.com/sponsors/ntkme
85
87
  post_install_message:
86
88
  rdoc_options: []
@@ -97,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
99
  - !ruby/object:Gem::Version
98
100
  version: 3.3.22
99
101
  requirements: []
100
- rubygems_version: 3.4.13
102
+ rubygems_version: 3.4.14
101
103
  signing_key:
102
104
  specification_version: 4
103
105
  summary: Use dart-sass with Ruby!
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Sass
4
- class Embedded
5
- # The {Channel} class.
6
- #
7
- # It establishes connection between {Host} and {Dispatcher}.
8
- class Channel
9
- def initialize
10
- @dispatcher = Dispatcher.new
11
- @mutex = Mutex.new
12
- end
13
-
14
- def close
15
- @mutex.synchronize do
16
- @dispatcher.close
17
- end
18
- end
19
-
20
- def closed?
21
- @mutex.synchronize do
22
- @dispatcher.closed?
23
- end
24
- end
25
-
26
- def connect(observer)
27
- @mutex.synchronize do
28
- begin
29
- id = @dispatcher.subscribe(observer)
30
- rescue Errno::EBUSY
31
- @dispatcher = Dispatcher.new
32
- id = @dispatcher.subscribe(observer)
33
- end
34
- Connection.new(@dispatcher, id)
35
- end
36
- end
37
-
38
- # The {Connection} between {Host} to {Dispatcher}.
39
- class Connection
40
- attr_reader :id
41
-
42
- def initialize(dispatcher, id)
43
- @dispatcher = dispatcher
44
- @id = id
45
- end
46
-
47
- def disconnect
48
- @dispatcher.unsubscribe(id)
49
- end
50
-
51
- def send_proto(...)
52
- @dispatcher.send_proto(...)
53
- end
54
- end
55
-
56
- private_constant :Connection
57
- end
58
-
59
- private_constant :Channel
60
- end
61
- end