extism 0.3.0 → 0.4.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 +4 -4
- data/example.rb +11 -17
- data/lib/extism/version.rb +5 -5
- data/lib/extism.rb +267 -264
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21688f8f388970bd00387e58e091cdb71eeef9e8f5bf864dd152229926752ee2
|
4
|
+
data.tar.gz: 180199c53864f904220ceba2a796ec0105960e9d0243f5d4293c8080bc72c342
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7dc0b31d1ca8ce1d79edd7894cd178a35ea0e4b02ec9f70f09d3fd77c8fa55129f7660d3e5f557493757eb90437426479ef957e6359106b52694e42fb6a808f
|
7
|
+
data.tar.gz: 314c6f702820fe6f0e9efa08d02a745fcfdf2aa8b6492477dc77a31da7f3a07c28436339365ecb483ebca60093b91962dabf39e7f69d38f94e117f8f935ac4a2
|
data/example.rb
CHANGED
@@ -1,17 +1,11 @@
|
|
1
|
-
require "./lib/extism"
|
2
|
-
require "json"
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Extism.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
plugin = ctx.plugin(manifest)
|
14
|
-
res = JSON.parse(plugin.call("count_vowels", ARGV[0] || "this is a test"))
|
15
|
-
|
16
|
-
puts res["count"]
|
17
|
-
end
|
1
|
+
require "./lib/extism"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
manifest = {
|
5
|
+
:wasm => [{ :path => "../wasm/code.wasm" }],
|
6
|
+
}
|
7
|
+
|
8
|
+
plugin = Extism::Plugin.new(manifest)
|
9
|
+
res = JSON.parse(plugin.call("count_vowels", ARGV[0] || "this is a test"))
|
10
|
+
|
11
|
+
puts res["count"]
|
data/lib/extism/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Extism
|
4
|
-
VERSION = "0.
|
5
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Extism
|
4
|
+
VERSION = "0.4.0"
|
5
|
+
end
|
data/lib/extism.rb
CHANGED
@@ -1,264 +1,267 @@
|
|
1
|
-
require "ffi"
|
2
|
-
require "json"
|
3
|
-
require_relative "./extism/version"
|
4
|
-
|
5
|
-
module Extism
|
6
|
-
class Error < StandardError
|
7
|
-
end
|
8
|
-
|
9
|
-
# Return the version of Extism
|
10
|
-
#
|
11
|
-
# @return [String] The version string of the Extism runtime
|
12
|
-
def self.extism_version
|
13
|
-
C.extism_version
|
14
|
-
end
|
15
|
-
|
16
|
-
# Set log file and level, this is a global configuration
|
17
|
-
# @param name [String] The path to the logfile
|
18
|
-
# @param level [String] The log level. One of {"debug", "error", "info", "trace" }
|
19
|
-
def self.set_log_file(name, level = nil)
|
20
|
-
if level
|
21
|
-
level = FFI::MemoryPointer::from_string(level)
|
22
|
-
end
|
23
|
-
C.extism_log_file(name, level)
|
24
|
-
end
|
25
|
-
|
26
|
-
$PLUGINS = {}
|
27
|
-
$FREE_PLUGIN = proc { |id|
|
28
|
-
x = $PLUGINS[id]
|
29
|
-
if !x.nil?
|
30
|
-
C.extism_plugin_free(x[:context].pointer, x[:plugin])
|
31
|
-
$PLUGINS.delete(id)
|
32
|
-
end
|
33
|
-
}
|
34
|
-
|
35
|
-
$CONTEXTS = {}
|
36
|
-
$FREE_CONTEXT = proc { |id|
|
37
|
-
x = $CONTEXTS[id]
|
38
|
-
if !x.nil?
|
39
|
-
C.extism_context_free($CONTEXTS[id])
|
40
|
-
$CONTEXTS.delete(id)
|
41
|
-
end
|
42
|
-
}
|
43
|
-
|
44
|
-
# A Context is needed to create plugins. The Context
|
45
|
-
# is where your plugins live. Freeing the context
|
46
|
-
# frees all of the plugins in its scope.
|
47
|
-
#
|
48
|
-
# @example Create and free a context
|
49
|
-
# ctx = Extism::Context.new
|
50
|
-
# plugin = ctx.plugin(my_manifest)
|
51
|
-
# puts plugin.call("my_func", "my-input")
|
52
|
-
# ctx.free # frees any plugins
|
53
|
-
#
|
54
|
-
# @example Use with_context to auto-free
|
55
|
-
# Extism.with_context do |ctx|
|
56
|
-
# plugin = ctx.plugin(my_manifest)
|
57
|
-
# puts plugin.call("my_func", "my-input")
|
58
|
-
# end # frees context after exiting this block
|
59
|
-
#
|
60
|
-
# @attr_reader pointer [FFI::Pointer] Pointer to the Extism context. *Used internally*.
|
61
|
-
class Context
|
62
|
-
attr_reader :pointer
|
63
|
-
|
64
|
-
# Initialize a new context
|
65
|
-
def initialize
|
66
|
-
@pointer = C.extism_context_new()
|
67
|
-
$CONTEXTS[self.object_id] = @pointer
|
68
|
-
ObjectSpace.define_finalizer(self, $FREE_CONTEXT)
|
69
|
-
end
|
70
|
-
|
71
|
-
# Remove all registered plugins in this context
|
72
|
-
# @return [void]
|
73
|
-
def reset
|
74
|
-
C.extism_context_reset(@pointer)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Free the context, this should be called when it is no longer needed
|
78
|
-
# @return [void]
|
79
|
-
def free
|
80
|
-
return if @pointer.nil?
|
81
|
-
|
82
|
-
$CONTEXTS.delete(self.object_id)
|
83
|
-
C.extism_context_free(@pointer)
|
84
|
-
@pointer = nil
|
85
|
-
end
|
86
|
-
|
87
|
-
# Create a new plugin from a WASM module or JSON encoded manifest
|
88
|
-
#
|
89
|
-
# @
|
90
|
-
# @param
|
91
|
-
# @param
|
92
|
-
# @
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
# @
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
#
|
134
|
-
#
|
135
|
-
# @param
|
136
|
-
# @param
|
137
|
-
# @param
|
138
|
-
# @param
|
139
|
-
def initialize(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
#
|
168
|
-
#
|
169
|
-
# @
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
#
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
#
|
205
|
-
#
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
attach_function :
|
252
|
-
attach_function :
|
253
|
-
attach_function :
|
254
|
-
attach_function :
|
255
|
-
attach_function :
|
256
|
-
attach_function :
|
257
|
-
attach_function :
|
258
|
-
attach_function :
|
259
|
-
attach_function :
|
260
|
-
attach_function :
|
261
|
-
attach_function :
|
262
|
-
attach_function :
|
263
|
-
|
264
|
-
|
1
|
+
require "ffi"
|
2
|
+
require "json"
|
3
|
+
require_relative "./extism/version"
|
4
|
+
|
5
|
+
module Extism
|
6
|
+
class Error < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
# Return the version of Extism
|
10
|
+
#
|
11
|
+
# @return [String] The version string of the Extism runtime
|
12
|
+
def self.extism_version
|
13
|
+
C.extism_version
|
14
|
+
end
|
15
|
+
|
16
|
+
# Set log file and level, this is a global configuration
|
17
|
+
# @param name [String] The path to the logfile
|
18
|
+
# @param level [String] The log level. One of {"debug", "error", "info", "trace" }
|
19
|
+
def self.set_log_file(name, level = nil)
|
20
|
+
if level
|
21
|
+
level = FFI::MemoryPointer::from_string(level)
|
22
|
+
end
|
23
|
+
C.extism_log_file(name, level)
|
24
|
+
end
|
25
|
+
|
26
|
+
$PLUGINS = {}
|
27
|
+
$FREE_PLUGIN = proc { |id|
|
28
|
+
x = $PLUGINS[id]
|
29
|
+
if !x.nil?
|
30
|
+
C.extism_plugin_free(x[:context].pointer, x[:plugin])
|
31
|
+
$PLUGINS.delete(id)
|
32
|
+
end
|
33
|
+
}
|
34
|
+
|
35
|
+
$CONTEXTS = {}
|
36
|
+
$FREE_CONTEXT = proc { |id|
|
37
|
+
x = $CONTEXTS[id]
|
38
|
+
if !x.nil?
|
39
|
+
C.extism_context_free($CONTEXTS[id])
|
40
|
+
$CONTEXTS.delete(id)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
# A Context is needed to create plugins. The Context
|
45
|
+
# is where your plugins live. Freeing the context
|
46
|
+
# frees all of the plugins in its scope.
|
47
|
+
#
|
48
|
+
# @example Create and free a context
|
49
|
+
# ctx = Extism::Context.new
|
50
|
+
# plugin = ctx.plugin(my_manifest)
|
51
|
+
# puts plugin.call("my_func", "my-input")
|
52
|
+
# ctx.free # frees any plugins
|
53
|
+
#
|
54
|
+
# @example Use with_context to auto-free
|
55
|
+
# Extism.with_context do |ctx|
|
56
|
+
# plugin = ctx.plugin(my_manifest)
|
57
|
+
# puts plugin.call("my_func", "my-input")
|
58
|
+
# end # frees context after exiting this block
|
59
|
+
#
|
60
|
+
# @attr_reader pointer [FFI::Pointer] Pointer to the Extism context. *Used internally*.
|
61
|
+
class Context
|
62
|
+
attr_reader :pointer
|
63
|
+
|
64
|
+
# Initialize a new context
|
65
|
+
def initialize
|
66
|
+
@pointer = C.extism_context_new()
|
67
|
+
$CONTEXTS[self.object_id] = @pointer
|
68
|
+
ObjectSpace.define_finalizer(self, $FREE_CONTEXT)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Remove all registered plugins in this context
|
72
|
+
# @return [void]
|
73
|
+
def reset
|
74
|
+
C.extism_context_reset(@pointer)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Free the context, this should be called when it is no longer needed
|
78
|
+
# @return [void]
|
79
|
+
def free
|
80
|
+
return if @pointer.nil?
|
81
|
+
|
82
|
+
$CONTEXTS.delete(self.object_id)
|
83
|
+
C.extism_context_free(@pointer)
|
84
|
+
@pointer = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# Create a new plugin from a WASM module or JSON encoded manifest
|
88
|
+
#
|
89
|
+
# @see Plugin#new
|
90
|
+
# @param wasm [Hash, String] The manifest for the plugin. See https://extism.org/docs/concepts/manifest/.
|
91
|
+
# @param wasi [Boolean] Enable WASI support
|
92
|
+
# @param config [Hash] The plugin config
|
93
|
+
# @return [Plugin]
|
94
|
+
def plugin(wasm, wasi = false, config = nil)
|
95
|
+
Plugin.new(wasm, wasi, config, self)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# A context manager to create contexts and ensure that they get freed.
|
100
|
+
#
|
101
|
+
# @example Use with_context to auto-free
|
102
|
+
# Extism.with_context do |ctx|
|
103
|
+
# plugin = ctx.plugin(my_manifest)
|
104
|
+
# puts plugin.call("my_func", "my-input")
|
105
|
+
# end # frees context after exiting this block
|
106
|
+
#
|
107
|
+
# @yield [ctx] Yields the created Context
|
108
|
+
# @return [Object] returns whatever your block returns
|
109
|
+
def self.with_context(&block)
|
110
|
+
ctx = Context.new
|
111
|
+
begin
|
112
|
+
x = block.call(ctx)
|
113
|
+
return x
|
114
|
+
ensure
|
115
|
+
ctx.free
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# A CancelHandle can be used to cancel a running plugin from another thread
|
120
|
+
class CancelHandle
|
121
|
+
def initialize(handle)
|
122
|
+
@handle = handle
|
123
|
+
end
|
124
|
+
|
125
|
+
# Cancel the plugin used to generate the handle
|
126
|
+
def cancel
|
127
|
+
return C.extism_plugin_cancel(@handle)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# A Plugin represents an instance of your WASM program from the given manifest.
|
132
|
+
class Plugin
|
133
|
+
# Intialize a plugin
|
134
|
+
#
|
135
|
+
# @param wasm [Hash, String] The manifest or WASM binary. See https://extism.org/docs/concepts/manifest/.
|
136
|
+
# @param wasi [Boolean] Enable WASI support
|
137
|
+
# @param config [Hash] The plugin config
|
138
|
+
# @param context [Context] The context to manager this plugin
|
139
|
+
def initialize(wasm, wasi = false, config = nil, context = nil)
|
140
|
+
if context.nil? then
|
141
|
+
context = Context.new
|
142
|
+
end
|
143
|
+
@context = context
|
144
|
+
if wasm.class == Hash
|
145
|
+
wasm = JSON.generate(wasm)
|
146
|
+
end
|
147
|
+
code = FFI::MemoryPointer.new(:char, wasm.bytesize)
|
148
|
+
code.put_bytes(0, wasm)
|
149
|
+
@plugin = C.extism_plugin_new(context.pointer, code, wasm.bytesize, nil, 0, wasi)
|
150
|
+
if @plugin < 0
|
151
|
+
err = C.extism_error(@context.pointer, -1)
|
152
|
+
if err&.empty?
|
153
|
+
raise Error.new "extism_plugin_new failed"
|
154
|
+
else
|
155
|
+
raise Error.new err
|
156
|
+
end
|
157
|
+
end
|
158
|
+
$PLUGINS[self.object_id] = { :plugin => @plugin, :context => context }
|
159
|
+
ObjectSpace.define_finalizer(self, $FREE_PLUGIN)
|
160
|
+
if config != nil and @plugin >= 0
|
161
|
+
s = JSON.generate(config)
|
162
|
+
ptr = FFI::MemoryPointer::from_string(s)
|
163
|
+
C.extism_plugin_config(@context.pointer, @plugin, ptr, s.bytesize)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Update a plugin with new WASM module or manifest
|
168
|
+
#
|
169
|
+
# @param wasm [Hash, String] The manifest or WASM binary. See https://extism.org/docs/concepts/manifest/.
|
170
|
+
# @param wasi [Boolean] Enable WASI support
|
171
|
+
# @param config [Hash] The plugin config
|
172
|
+
# @return [void]
|
173
|
+
def update(wasm, wasi = false, config = nil)
|
174
|
+
if wasm.class == Hash
|
175
|
+
wasm = JSON.generate(wasm)
|
176
|
+
end
|
177
|
+
code = FFI::MemoryPointer.new(:char, wasm.bytesize)
|
178
|
+
code.put_bytes(0, wasm)
|
179
|
+
ok = C.extism_plugin_update(@context.pointer, @plugin, code, wasm.bytesize, nil, 0, wasi)
|
180
|
+
if !ok
|
181
|
+
err = C.extism_error(@context.pointer, @plugin)
|
182
|
+
if err&.empty?
|
183
|
+
raise Error.new "extism_plugin_update failed"
|
184
|
+
else
|
185
|
+
raise Error.new err
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
if config != nil
|
190
|
+
s = JSON.generate(config)
|
191
|
+
ptr = FFI::MemoryPointer::from_string(s)
|
192
|
+
C.extism_plugin_config(@context.pointer, @plugin, ptr, s.bytesize)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Check if a function exists
|
197
|
+
#
|
198
|
+
# @param name [String] The name of the function
|
199
|
+
# @return [Boolean] Returns true if function exists
|
200
|
+
def has_function?(name)
|
201
|
+
C.extism_plugin_function_exists(@context.pointer, @plugin, name)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Call a function by name
|
205
|
+
#
|
206
|
+
# @param name [String] The function name
|
207
|
+
# @param data [String] The input data for the function
|
208
|
+
# @return [String] The output from the function in String form
|
209
|
+
def call(name, data, &block)
|
210
|
+
# If no block was passed then use Pointer::read_string
|
211
|
+
block ||= ->(buf, len) { buf.read_string(len) }
|
212
|
+
input = FFI::MemoryPointer::from_string(data)
|
213
|
+
rc = C.extism_plugin_call(@context.pointer, @plugin, name, input, data.bytesize)
|
214
|
+
if rc != 0
|
215
|
+
err = C.extism_error(@context.pointer, @plugin)
|
216
|
+
if err&.empty?
|
217
|
+
raise Error.new "extism_call failed"
|
218
|
+
else
|
219
|
+
raise Error.new err
|
220
|
+
end
|
221
|
+
end
|
222
|
+
out_len = C.extism_plugin_output_length(@context.pointer, @plugin)
|
223
|
+
buf = C.extism_plugin_output_data(@context.pointer, @plugin)
|
224
|
+
block.call(buf, out_len)
|
225
|
+
end
|
226
|
+
|
227
|
+
# Free a plugin, this should be called when the plugin is no longer needed
|
228
|
+
#
|
229
|
+
# @return [void]
|
230
|
+
def free
|
231
|
+
return if @context.pointer.nil?
|
232
|
+
|
233
|
+
$PLUGINS.delete(self.object_id)
|
234
|
+
C.extism_plugin_free(@context.pointer, @plugin)
|
235
|
+
@plugin = -1
|
236
|
+
end
|
237
|
+
|
238
|
+
# Get a CancelHandle for a plugin
|
239
|
+
def cancel_handle
|
240
|
+
return CancelHandle.new(C.extism_plugin_cancel_handle(@context.pointer, @plugin))
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
# Private module used to interface with the Extism runtime.
|
247
|
+
# *Warning*: Do not use or rely on this directly.
|
248
|
+
module C
|
249
|
+
extend FFI::Library
|
250
|
+
ffi_lib "extism"
|
251
|
+
attach_function :extism_context_new, [], :pointer
|
252
|
+
attach_function :extism_context_free, [:pointer], :void
|
253
|
+
attach_function :extism_plugin_new, [:pointer, :pointer, :uint64, :pointer, :uint64, :bool], :int32
|
254
|
+
attach_function :extism_plugin_update, [:pointer, :int32, :pointer, :uint64, :pointer, :uint64, :bool], :bool
|
255
|
+
attach_function :extism_error, [:pointer, :int32], :string
|
256
|
+
attach_function :extism_plugin_call, [:pointer, :int32, :string, :pointer, :uint64], :int32
|
257
|
+
attach_function :extism_plugin_function_exists, [:pointer, :int32, :string], :bool
|
258
|
+
attach_function :extism_plugin_output_length, [:pointer, :int32], :uint64
|
259
|
+
attach_function :extism_plugin_output_data, [:pointer, :int32], :pointer
|
260
|
+
attach_function :extism_log_file, [:string, :pointer], :void
|
261
|
+
attach_function :extism_plugin_free, [:pointer, :int32], :void
|
262
|
+
attach_function :extism_context_reset, [:pointer], :void
|
263
|
+
attach_function :extism_version, [], :string
|
264
|
+
attach_function :extism_plugin_cancel_handle, [:pointer, :int32], :pointer
|
265
|
+
attach_function :extism_plugin_cancel, [:pointer], :bool
|
266
|
+
end
|
267
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: extism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zach
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -48,7 +48,7 @@ metadata:
|
|
48
48
|
homepage_uri: https://github.com/extism/extism
|
49
49
|
source_code_uri: https://github.com/extism/extism
|
50
50
|
changelog_uri: https://github.com/extism/extism
|
51
|
-
post_install_message:
|
51
|
+
post_install_message:
|
52
52
|
rdoc_options: []
|
53
53
|
require_paths:
|
54
54
|
- lib
|
@@ -63,8 +63,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
63
|
- !ruby/object:Gem::Version
|
64
64
|
version: '0'
|
65
65
|
requirements: []
|
66
|
-
rubygems_version: 3.
|
67
|
-
signing_key:
|
66
|
+
rubygems_version: 3.4.10
|
67
|
+
signing_key:
|
68
68
|
specification_version: 4
|
69
69
|
summary: Extism WASM SDK
|
70
70
|
test_files: []
|