Skip to content

Commit

Permalink
✨ Standard Library a.k.a StdLib
Browse files Browse the repository at this point in the history
  • Loading branch information
TheEEs committed Jun 21, 2021
1 parent db37410 commit edf5266
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
26 changes: 26 additions & 0 deletions spec/stdlib/task_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require "../spec_helper"
require "socket"
require "colorize"
require "json"

describe StdLib::Task do
it "exists" do
eval_js <<-JS
typeof(window["StdLib::Task"])
JS
ret = String.new JSC.to_string script_result
ret.should eq "function"
end

it "works" do
eval_js <<-JS
var a = new MyFileReader("README.md");
var task = a.read_content_async();
var message = "";
while(!(message = task.await())); //uses `task.yield();` if build without -Dpreview_mt
message;
JS
msg = String.new JSC.to_string script_result
msg.should eq File.read("README.md")
end
end
16 changes: 16 additions & 0 deletions src/components/web_extension/stdlib/jsc_class.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Hah? Now you're wondering how to create Javascript classes. I know it.
# Actually, macro `WebExtension.register_class` had been introduced since version 0.3.1 to help you enroll a plain Crystal' class into JavaScriptCore environment and uses it directly in your JS code.
module JSCClass
macro included
INSTANCES = [] of Void*
@@kconstructor : Pointer(Void)? = nil

def self.last_created_instance
Box({{@type}}).unbox(INSTANCES.last)
end

def self.constructor
@@kconstructor ||= WebExtension.register_class({{@type}})
end
end
end
41 changes: 41 additions & 0 deletions src/components/web_extension/stdlib/task.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
include WebExtension

alias JSCTypes = JSCFunction | JSCPrimative | JSCObject | JSC::JSValue

class StdLib::Task < Channel(JSCTypes)
include JSCClass

def initialize(p)
super 0
end

def send(p)
super(p.to_jsc)
true
end

@[JSCInstanceMethod]
def wait(p)
while true
i, m = Channel.non_blocking_select(self.receive_select_action)
if m.is_a?(JSCTypes)
return m
end
end
end

@[JSCInstanceMethod]
def await(p)
select
when m = self.receive
return m
else
return nil
end
end

@[JSCInstanceMethod]
def yield(p)
Fiber.yield
end
end

0 comments on commit edf5266

Please sign in to comment.