start incorporating Roact

This commit is contained in:
2024-04-04 21:22:31 -04:00
parent 2b17d60a41
commit 414af47f09
5 changed files with 2332 additions and 0 deletions

View File

@@ -1,5 +1,9 @@
{ {
"name": "ElevatorGame", "name": "ElevatorGame",
"globIgnorePaths": [
"**/package.json",
"**/tsconfig.json"
],
"tree": { "tree": {
"$className": "DataModel", "$className": "DataModel",
"ReplicatedStorage": { "ReplicatedStorage": {

2048
include/Promise.lua Normal file

File diff suppressed because it is too large Load Diff

231
include/RuntimeLib.lua Normal file
View File

@@ -0,0 +1,231 @@
local Promise = require(script.Parent.Promise)
local RunService = game:GetService("RunService")
local OUTPUT_PREFIX = "roblox-ts: "
local NODE_MODULES = "node_modules"
local DEFAULT_SCOPE = "@rbxts"
local TS = {}
TS.Promise = Promise
local function isPlugin(context)
return RunService:IsStudio() and context:FindFirstAncestorWhichIsA("Plugin") ~= nil
end
function TS.getModule(context, scope, moduleName)
-- legacy call signature
if moduleName == nil then
moduleName = scope
scope = DEFAULT_SCOPE
end
-- ensure modules have fully replicated
if RunService:IsRunning() and RunService:IsClient() and not isPlugin(context) and not game:IsLoaded() then
game.Loaded:Wait()
end
local object = context
repeat
local nodeModulesFolder = object:FindFirstChild(NODE_MODULES)
if nodeModulesFolder then
local scopeFolder = nodeModulesFolder:FindFirstChild(scope)
if scopeFolder then
local module = scopeFolder:FindFirstChild(moduleName)
if module then
return module
end
end
end
object = object.Parent
until object == nil
error(OUTPUT_PREFIX .. "Could not find module: " .. moduleName, 2)
end
-- This is a hash which TS.import uses as a kind of linked-list-like history of [Script who Loaded] -> Library
local currentlyLoading = {}
local registeredLibraries = {}
function TS.import(context, module, ...)
for i = 1, select("#", ...) do
module = module:WaitForChild((select(i, ...)))
end
if module.ClassName ~= "ModuleScript" then
error(OUTPUT_PREFIX .. "Failed to import! Expected ModuleScript, got " .. module.ClassName, 2)
end
currentlyLoading[context] = module
-- Check to see if a case like this occurs:
-- module -> Module1 -> Module2 -> module
-- WHERE currentlyLoading[module] is Module1
-- and currentlyLoading[Module1] is Module2
-- and currentlyLoading[Module2] is module
local currentModule = module
local depth = 0
while currentModule do
depth = depth + 1
currentModule = currentlyLoading[currentModule]
if currentModule == module then
local str = currentModule.Name -- Get the string traceback
for _ = 1, depth do
currentModule = currentlyLoading[currentModule]
str = str .. "" .. currentModule.Name
end
error(OUTPUT_PREFIX .. "Failed to import! Detected a circular dependency chain: " .. str, 2)
end
end
if not registeredLibraries[module] then
if _G[module] then
error(
OUTPUT_PREFIX
.. "Invalid module access! Do you have multiple TS runtimes trying to import this? "
.. module:GetFullName(),
2
)
end
_G[module] = TS
registeredLibraries[module] = true -- register as already loaded for subsequent calls
end
local data = require(module)
if currentlyLoading[context] == module then -- Thread-safe cleanup!
currentlyLoading[context] = nil
end
return data
end
function TS.instanceof(obj, class)
-- custom Class.instanceof() check
if type(class) == "table" and type(class.instanceof) == "function" then
return class.instanceof(obj)
end
-- metatable check
if type(obj) == "table" then
obj = getmetatable(obj)
while obj ~= nil do
if obj == class then
return true
end
local mt = getmetatable(obj)
if mt then
obj = mt.__index
else
obj = nil
end
end
end
return false
end
function TS.async(callback)
return function(...)
local n = select("#", ...)
local args = { ... }
return Promise.new(function(resolve, reject)
coroutine.wrap(function()
local ok, result = pcall(callback, unpack(args, 1, n))
if ok then
resolve(result)
else
reject(result)
end
end)()
end)
end
end
function TS.await(promise)
if not Promise.is(promise) then
return promise
end
local status, value = promise:awaitStatus()
if status == Promise.Status.Resolved then
return value
elseif status == Promise.Status.Rejected then
error(value, 2)
else
error("The awaited Promise was cancelled", 2)
end
end
local SIGN = 2 ^ 31
local COMPLEMENT = 2 ^ 32
local function bit_sign(num)
-- Restores the sign after an unsigned conversion according to 2s complement.
if bit32.btest(num, SIGN) then
return num - COMPLEMENT
else
return num
end
end
function TS.bit_lrsh(a, b)
return bit_sign(bit32.arshift(a, b))
end
TS.TRY_RETURN = 1
TS.TRY_BREAK = 2
TS.TRY_CONTINUE = 3
function TS.try(func, catch, finally)
local err, traceback
local success, exitType, returns = xpcall(
func,
function(errInner)
err = errInner
traceback = debug.traceback()
end
)
if not success and catch then
local newExitType, newReturns = catch(err, traceback)
if newExitType then
exitType, returns = newExitType, newReturns
end
end
if finally then
local newExitType, newReturns = finally()
if newExitType then
exitType, returns = newExitType, newReturns
end
end
return exitType, returns
end
function TS.generator(callback)
local co = coroutine.create(callback)
return {
next = function(...)
if coroutine.status(co) == "dead" then
return { done = true }
else
local success, value = coroutine.resume(co, ...)
if success == false then
error(value, 2)
end
return {
value = value,
done = coroutine.status(co) == "dead",
}
end
end,
}
end
return TS

22
package.json Normal file
View File

@@ -0,0 +1,22 @@
{
"name": "roblox-ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "rbxtsc",
"watch": "rbxtsc -w"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@rbxts/compiler-types": "^2.3.0-types.0",
"@rbxts/types": "^1.0.767",
"roblox-ts": "^2.3.0",
"typescript": "^5.4.4"
},
"dependencies": {
"@rbxts/roact": "^1.4.4-ts.0"
}
}

27
tsconfig.json Normal file
View File

@@ -0,0 +1,27 @@
{
"compilerOptions": {
// required
"allowSyntheticDefaultImports": true,
"downlevelIteration": true,
"jsx": "react",
"jsxFactory": "Roact.createElement",
"jsxFragmentFactory": "Roact.createFragment",
"module": "commonjs",
"moduleResolution": "Node",
"noLib": true,
"resolveJsonModule": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"moduleDetection": "force",
"strict": true,
"target": "ESNext",
"typeRoots": ["node_modules/@rbxts"],
// configurable
"rootDir": "src",
"outDir": "out",
"baseUrl": "src",
"incremental": true,
"tsBuildInfoFile": "out/tsconfig.tsbuildinfo"
}
}