mirror of
https://github.com/imezx/Warp.git
synced 2026-03-18 00:44:16 +00:00
Compare commits
128 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80646eeebb | ||
|
|
704942c979 | ||
|
|
b26d06fa3d | ||
|
|
4f92248187 | ||
|
|
8d114d3b51 | ||
|
|
c4a7934bc4 | ||
|
|
85f6aa8b77 | ||
|
|
1fdf90e00c | ||
|
|
189ac58d0d | ||
|
|
07e0a99577 | ||
|
|
8ceb5257ba | ||
|
|
211900d874 | ||
|
|
5e6433e892 | ||
|
|
71c66b6d23 | ||
|
|
bb120bfbef | ||
|
|
1200ff41f1 | ||
|
|
ff6a0c5cf4 | ||
|
|
1f9fe9dfd7 | ||
|
|
4d958a91fb | ||
|
|
492da9e607 | ||
|
|
d2e362fd8d | ||
|
|
b6fa3cf2d7 | ||
|
|
a34f161cfe | ||
|
|
9d76f53480 | ||
|
|
8b8b29e9a9 | ||
|
|
0271c0e86d | ||
|
|
b6fbc08111 | ||
|
|
e4184709bd | ||
|
|
a82b8fd532 | ||
|
|
83c8698b9f | ||
|
|
cd76d58c4d | ||
|
|
4d983a0756 | ||
|
|
81d3c540c1 | ||
|
|
4af26f4d41 | ||
|
|
5f5bb7938c | ||
|
|
36b03dec02 | ||
|
|
219b62b6d2 | ||
|
|
04e7f65a3a | ||
|
|
d2d02b8657 | ||
|
|
fcbd0d91d4 | ||
|
|
0578ed5d25 | ||
|
|
3d7ee22f88 | ||
|
|
f6b0e62880 | ||
|
|
e810c6e000 | ||
|
|
920bd21094 | ||
|
|
95a84bcaec | ||
|
|
d57d990256 | ||
|
|
8b845d5412 | ||
|
|
5337557164 | ||
|
|
d5107f93c0 | ||
|
|
4b70a12e79 | ||
|
|
3a82b748d2 | ||
|
|
d5e438ad27 | ||
|
|
f5f746b37a | ||
|
|
4f874ed34e | ||
|
|
8af04ad70c | ||
|
|
496cdbe6b6 | ||
|
|
5075ea7304 | ||
|
|
27e81f811c | ||
|
|
d603244b03 | ||
|
|
6e87a9838d | ||
|
|
3d2ccbc86b | ||
|
|
e510256c87 | ||
|
|
9c8b16c400 | ||
|
|
45802c930f | ||
|
|
a5bdd3987d | ||
|
|
017d2e8118 | ||
|
|
fd02dc26d5 | ||
|
|
ef25d2cf6c | ||
|
|
3e58ebc944 | ||
|
|
04216ce24b | ||
|
|
3d32c4c87f | ||
|
|
f687e486b0 | ||
|
|
6bc31cb363 | ||
|
|
b9bc52385c | ||
|
|
ab7132f22e | ||
|
|
f98a0a1cc8 | ||
|
|
391be2dbeb | ||
|
|
4be184815c | ||
|
|
3d075cd966 | ||
|
|
0b1304f4c5 | ||
|
|
d8526c7e25 | ||
|
|
d065bc2e50 | ||
|
|
925df47d4c | ||
|
|
f3b674b377 | ||
|
|
677d3fa675 | ||
|
|
91862a65fe | ||
|
|
8ba9540550 | ||
|
|
1d67954ef9 | ||
|
|
43c4a1594f | ||
|
|
22996c9357 | ||
|
|
a377788f22 | ||
|
|
3354324c5b | ||
|
|
20b97eeb54 | ||
|
|
dbed984eea | ||
|
|
064075fbd9 | ||
|
|
77de85b6b8 | ||
|
|
10de54608a | ||
|
|
5b2e36b7bb | ||
|
|
eba9f79655 | ||
|
|
7309840005 | ||
|
|
aa693aee4f | ||
|
|
44fa07df85 | ||
|
|
839a7af667 | ||
|
|
acb08a385c | ||
|
|
6acf92d913 | ||
|
|
b4ee5dc1e3 | ||
|
|
598c30c147 | ||
|
|
0fb349fe0f | ||
|
|
4cd0f3f2cf | ||
|
|
8fd9573b8a | ||
|
|
739e13537d | ||
|
|
46bbe5feb0 | ||
|
|
0bc8f56e11 | ||
|
|
69fc64d134 | ||
|
|
c8199d5744 | ||
|
|
ef4b741f85 | ||
|
|
e7b4ae2f61 | ||
|
|
9aaa382278 | ||
|
|
5cf44bd21f | ||
|
|
5b0d4ee690 | ||
|
|
7519839dd1 | ||
|
|
01c5533394 | ||
|
|
4b568356c8 | ||
|
|
ae1754d616 | ||
|
|
563af05c62 | ||
|
|
f5bb1df4b0 | ||
|
|
8cad93f2f5 |
1790 changed files with 222546 additions and 484160 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1 +1 @@
|
||||||
*.luau linguist-language=Lua
|
*.luau linguist-language=Luau
|
||||||
31
.github/workflows/deploy.yml
vendored
31
.github/workflows/deploy.yml
vendored
|
|
@ -16,28 +16,37 @@ jobs:
|
||||||
environment:
|
environment:
|
||||||
name: github-pages
|
name: github-pages
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v3
|
- name: Setup Bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
bun-version: latest
|
||||||
cache: npm
|
|
||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v3
|
uses: actions/configure-pages@v4
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: |
|
||||||
|
rm -f package-lock.json
|
||||||
|
rm -rf node_modules
|
||||||
|
bun install
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
npm run docs:build
|
bun run docs:build
|
||||||
touch docs/.vitepress/dist
|
touch docs/.vitepress/dist/.nojekyll
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v2
|
uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: docs/.vitepress/dist
|
path: docs/.vitepress/dist
|
||||||
|
|
||||||
- name: Deploy
|
- name: Deploy
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v2
|
uses: actions/deploy-pages@v4
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,4 +1,6 @@
|
||||||
node_modules
|
node_modules
|
||||||
docs/.vitepress/dist
|
docs/.vitepress/dist
|
||||||
docs/.vitepress/cache
|
docs/.vitepress/cache
|
||||||
wally.lock
|
*.lock
|
||||||
|
TestEZ
|
||||||
|
test.project.json
|
||||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"stylua.targetReleaseVersion": "latest"
|
||||||
|
}
|
||||||
12
README.md
12
README.md
|
|
@ -1,7 +1,7 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="docs/public/warp.png" alt="Warp icon" />
|
<img src="docs/public/warp.png" alt="Warp icon" />
|
||||||
<h1><span style="color:blue;">Warp</span></h1>
|
<h1><span style="color:blue;">Warp</span></h1>
|
||||||
<p><h1>A very-fast & powerful networking library for Roblox.</h1></p>
|
<p><h1>A rapidly-fast & powerful networking library.</h1></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -9,13 +9,13 @@
|
||||||
## Why Warp
|
## Why Warp
|
||||||
|
|
||||||
### ⚡ Performance
|
### ⚡ Performance
|
||||||
Warp is very-fast with much less bandwidth compared to native.
|
Warp is rapidly-fast with much less bandwidth compared to native.
|
||||||
|
|
||||||
### 🍃 Lightweight
|
### 🍃 Compact
|
||||||
Warp is a lightweight library for Roblox.
|
Warp is a simple, efficient & lightweight library.
|
||||||
|
|
||||||
### 📊 Task
|
### 📊 Dynamic
|
||||||
Warp optimized efficient for large-scale task.
|
Warp is dynamic by default. It serializes and deserializes data dynamically without requiring a user-defined schema, although schema support is available as an option.
|
||||||
|
|
||||||
### 🔎 Typing
|
### 🔎 Typing
|
||||||
Warp written with strictly-typed.
|
Warp written with strictly-typed.
|
||||||
|
|
|
||||||
26
TestEZ/Context.lua
Normal file
26
TestEZ/Context.lua
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
--[[
|
||||||
|
The Context object implements a write-once key-value store. It also allows
|
||||||
|
for a new Context object to inherit the entries from an existing one.
|
||||||
|
]]
|
||||||
|
local Context = {}
|
||||||
|
|
||||||
|
function Context.new(parent)
|
||||||
|
local meta = {}
|
||||||
|
local index = {}
|
||||||
|
meta.__index = index
|
||||||
|
|
||||||
|
if parent then
|
||||||
|
for key, value in pairs(getmetatable(parent).__index) do
|
||||||
|
index[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function meta.__newindex(_obj, key, value)
|
||||||
|
assert(index[key] == nil, string.format("Cannot reassign %s in context", tostring(key)))
|
||||||
|
index[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable({}, meta)
|
||||||
|
end
|
||||||
|
|
||||||
|
return Context
|
||||||
311
TestEZ/Expectation.lua
Normal file
311
TestEZ/Expectation.lua
Normal file
|
|
@ -0,0 +1,311 @@
|
||||||
|
--[[
|
||||||
|
Allows creation of expectation statements designed for behavior-driven
|
||||||
|
testing (BDD). See Chai (JS) or RSpec (Ruby) for examples of other BDD
|
||||||
|
frameworks.
|
||||||
|
|
||||||
|
The Expectation class is exposed to tests as a function called `expect`:
|
||||||
|
|
||||||
|
expect(5).to.equal(5)
|
||||||
|
expect(foo()).to.be.ok()
|
||||||
|
|
||||||
|
Expectations can be negated using .never:
|
||||||
|
|
||||||
|
expect(true).never.to.equal(false)
|
||||||
|
|
||||||
|
Expectations throw errors when their conditions are not met.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local Expectation = {}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
These keys don't do anything except make expectations read more cleanly
|
||||||
|
]]
|
||||||
|
local SELF_KEYS = {
|
||||||
|
to = true,
|
||||||
|
be = true,
|
||||||
|
been = true,
|
||||||
|
have = true,
|
||||||
|
was = true,
|
||||||
|
at = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
These keys invert the condition expressed by the Expectation.
|
||||||
|
]]
|
||||||
|
local NEGATION_KEYS = {
|
||||||
|
never = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Extension of Lua's 'assert' that lets you specify an error level.
|
||||||
|
]]
|
||||||
|
local function assertLevel(condition, message, level)
|
||||||
|
message = message or "Assertion failed!"
|
||||||
|
level = level or 1
|
||||||
|
|
||||||
|
if not condition then
|
||||||
|
error(message, level + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Returns a version of the given method that can be called with either . or :
|
||||||
|
]]
|
||||||
|
local function bindSelf(self, method)
|
||||||
|
return function(firstArg, ...)
|
||||||
|
if firstArg == self then
|
||||||
|
return method(self, ...)
|
||||||
|
else
|
||||||
|
return method(self, firstArg, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function formatMessage(result, trueMessage, falseMessage)
|
||||||
|
if result then
|
||||||
|
return trueMessage
|
||||||
|
else
|
||||||
|
return falseMessage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new expectation
|
||||||
|
]]
|
||||||
|
function Expectation.new(value)
|
||||||
|
local self = {
|
||||||
|
value = value,
|
||||||
|
successCondition = true,
|
||||||
|
condition = false,
|
||||||
|
matchers = {},
|
||||||
|
_boundMatchers = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(self, Expectation)
|
||||||
|
|
||||||
|
self.a = bindSelf(self, self.a)
|
||||||
|
self.an = self.a
|
||||||
|
self.ok = bindSelf(self, self.ok)
|
||||||
|
self.equal = bindSelf(self, self.equal)
|
||||||
|
self.throw = bindSelf(self, self.throw)
|
||||||
|
self.near = bindSelf(self, self.near)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function Expectation.checkMatcherNameCollisions(name)
|
||||||
|
if SELF_KEYS[name] or NEGATION_KEYS[name] or Expectation[name] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function Expectation:extend(matchers)
|
||||||
|
self.matchers = matchers or {}
|
||||||
|
|
||||||
|
for name, implementation in pairs(self.matchers) do
|
||||||
|
self._boundMatchers[name] = bindSelf(self, function(_self, ...)
|
||||||
|
local result = implementation(self.value, ...)
|
||||||
|
local pass = result.pass == self.successCondition
|
||||||
|
|
||||||
|
assertLevel(pass, result.message, 3)
|
||||||
|
self:_resetModifiers()
|
||||||
|
return self
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function Expectation.__index(self, key)
|
||||||
|
-- Keys that don't do anything except improve readability
|
||||||
|
if SELF_KEYS[key] then
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Invert your assertion
|
||||||
|
if NEGATION_KEYS[key] then
|
||||||
|
local newExpectation = Expectation.new(self.value):extend(self.matchers)
|
||||||
|
newExpectation.successCondition = not self.successCondition
|
||||||
|
|
||||||
|
return newExpectation
|
||||||
|
end
|
||||||
|
|
||||||
|
if self._boundMatchers[key] then
|
||||||
|
return self._boundMatchers[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Fall back to methods provided by Expectation
|
||||||
|
return Expectation[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Called by expectation terminators to reset modifiers in a statement.
|
||||||
|
|
||||||
|
This makes chains like:
|
||||||
|
|
||||||
|
expect(5)
|
||||||
|
.never.to.equal(6)
|
||||||
|
.to.equal(5)
|
||||||
|
|
||||||
|
Work as expected.
|
||||||
|
]]
|
||||||
|
function Expectation:_resetModifiers()
|
||||||
|
self.successCondition = true
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Assert that the expectation value is the given type.
|
||||||
|
|
||||||
|
expect(5).to.be.a("number")
|
||||||
|
]]
|
||||||
|
function Expectation:a(typeName)
|
||||||
|
local result = (type(self.value) == typeName) == self.successCondition
|
||||||
|
|
||||||
|
local message = formatMessage(self.successCondition,
|
||||||
|
("Expected value of type %q, got value %q of type %s"):format(
|
||||||
|
typeName,
|
||||||
|
tostring(self.value),
|
||||||
|
type(self.value)
|
||||||
|
),
|
||||||
|
("Expected value not of type %q, got value %q of type %s"):format(
|
||||||
|
typeName,
|
||||||
|
tostring(self.value),
|
||||||
|
type(self.value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertLevel(result, message, 3)
|
||||||
|
self:_resetModifiers()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Make alias public on class
|
||||||
|
Expectation.an = Expectation.a
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Assert that our expectation value is truthy
|
||||||
|
]]
|
||||||
|
function Expectation:ok()
|
||||||
|
local result = (self.value ~= nil) == self.successCondition
|
||||||
|
|
||||||
|
local message = formatMessage(self.successCondition,
|
||||||
|
("Expected value %q to be non-nil"):format(
|
||||||
|
tostring(self.value)
|
||||||
|
),
|
||||||
|
("Expected value %q to be nil"):format(
|
||||||
|
tostring(self.value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertLevel(result, message, 3)
|
||||||
|
self:_resetModifiers()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Assert that our expectation value is equal to another value
|
||||||
|
]]
|
||||||
|
function Expectation:equal(otherValue)
|
||||||
|
local result = (self.value == otherValue) == self.successCondition
|
||||||
|
|
||||||
|
local message = formatMessage(self.successCondition,
|
||||||
|
("Expected value %q (%s), got %q (%s) instead"):format(
|
||||||
|
tostring(otherValue),
|
||||||
|
type(otherValue),
|
||||||
|
tostring(self.value),
|
||||||
|
type(self.value)
|
||||||
|
),
|
||||||
|
("Expected anything but value %q (%s)"):format(
|
||||||
|
tostring(otherValue),
|
||||||
|
type(otherValue)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertLevel(result, message, 3)
|
||||||
|
self:_resetModifiers()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Assert that our expectation value is equal to another value within some
|
||||||
|
inclusive limit.
|
||||||
|
]]
|
||||||
|
function Expectation:near(otherValue, limit)
|
||||||
|
assert(type(self.value) == "number", "Expectation value must be a number to use 'near'")
|
||||||
|
assert(type(otherValue) == "number", "otherValue must be a number")
|
||||||
|
assert(type(limit) == "number" or limit == nil, "limit must be a number or nil")
|
||||||
|
|
||||||
|
limit = limit or 1e-7
|
||||||
|
|
||||||
|
local result = (math.abs(self.value - otherValue) <= limit) == self.successCondition
|
||||||
|
|
||||||
|
local message = formatMessage(self.successCondition,
|
||||||
|
("Expected value to be near %f (within %f) but got %f instead"):format(
|
||||||
|
otherValue,
|
||||||
|
limit,
|
||||||
|
self.value
|
||||||
|
),
|
||||||
|
("Expected value to not be near %f (within %f) but got %f instead"):format(
|
||||||
|
otherValue,
|
||||||
|
limit,
|
||||||
|
self.value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertLevel(result, message, 3)
|
||||||
|
self:_resetModifiers()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Assert that our functoid expectation value throws an error when called.
|
||||||
|
An optional error message can be passed to assert that the error message
|
||||||
|
contains the given value.
|
||||||
|
]]
|
||||||
|
function Expectation:throw(messageSubstring)
|
||||||
|
local ok, err = pcall(self.value)
|
||||||
|
local result = ok ~= self.successCondition
|
||||||
|
|
||||||
|
if messageSubstring and not ok then
|
||||||
|
if self.successCondition then
|
||||||
|
result = err:find(messageSubstring, 1, true) ~= nil
|
||||||
|
else
|
||||||
|
result = err:find(messageSubstring, 1, true) == nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local message
|
||||||
|
|
||||||
|
if messageSubstring then
|
||||||
|
message = formatMessage(self.successCondition,
|
||||||
|
("Expected function to throw an error containing %q, but it %s"):format(
|
||||||
|
messageSubstring,
|
||||||
|
err and ("threw: %s"):format(err) or "did not throw."
|
||||||
|
),
|
||||||
|
("Expected function to never throw an error containing %q, but it threw: %s"):format(
|
||||||
|
messageSubstring,
|
||||||
|
tostring(err)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else
|
||||||
|
message = formatMessage(self.successCondition,
|
||||||
|
"Expected function to throw an error, but it did not throw.",
|
||||||
|
("Expected function to succeed, but it threw an error: %s"):format(
|
||||||
|
tostring(err)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
assertLevel(result, message, 3)
|
||||||
|
self:_resetModifiers()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
return Expectation
|
||||||
38
TestEZ/ExpectationContext.lua
Normal file
38
TestEZ/ExpectationContext.lua
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
local Expectation = require(script.Parent.Expectation)
|
||||||
|
local checkMatcherNameCollisions = Expectation.checkMatcherNameCollisions
|
||||||
|
|
||||||
|
local function copy(t)
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
for key, value in pairs(t) do
|
||||||
|
result[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local ExpectationContext = {}
|
||||||
|
ExpectationContext.__index = ExpectationContext
|
||||||
|
|
||||||
|
function ExpectationContext.new(parent)
|
||||||
|
local self = {
|
||||||
|
_extensions = parent and copy(parent._extensions) or {},
|
||||||
|
}
|
||||||
|
|
||||||
|
return setmetatable(self, ExpectationContext)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ExpectationContext:startExpectationChain(...)
|
||||||
|
return Expectation.new(...):extend(self._extensions)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ExpectationContext:extend(config)
|
||||||
|
for key, value in pairs(config) do
|
||||||
|
assert(self._extensions[key] == nil, string.format("Cannot reassign %q in expect.extend", key))
|
||||||
|
assert(checkMatcherNameCollisions(key), string.format("Cannot overwrite matcher %q; it already exists", key))
|
||||||
|
|
||||||
|
self._extensions[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ExpectationContext
|
||||||
89
TestEZ/LifecycleHooks.lua
Normal file
89
TestEZ/LifecycleHooks.lua
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
local TestEnum = require(script.Parent.TestEnum)
|
||||||
|
|
||||||
|
local LifecycleHooks = {}
|
||||||
|
LifecycleHooks.__index = LifecycleHooks
|
||||||
|
|
||||||
|
function LifecycleHooks.new()
|
||||||
|
local self = {
|
||||||
|
_stack = {},
|
||||||
|
}
|
||||||
|
return setmetatable(self, LifecycleHooks)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Returns an array of `beforeEach` hooks in FIFO order
|
||||||
|
]]
|
||||||
|
function LifecycleHooks:getBeforeEachHooks()
|
||||||
|
local key = TestEnum.NodeType.BeforeEach
|
||||||
|
local hooks = {}
|
||||||
|
|
||||||
|
for _, level in ipairs(self._stack) do
|
||||||
|
for _, hook in ipairs(level[key]) do
|
||||||
|
table.insert(hooks, hook)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return hooks
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Returns an array of `afterEach` hooks in FILO order
|
||||||
|
]]
|
||||||
|
function LifecycleHooks:getAfterEachHooks()
|
||||||
|
local key = TestEnum.NodeType.AfterEach
|
||||||
|
local hooks = {}
|
||||||
|
|
||||||
|
for _, level in ipairs(self._stack) do
|
||||||
|
for _, hook in ipairs(level[key]) do
|
||||||
|
table.insert(hooks, 1, hook)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return hooks
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Pushes uncalled beforeAll and afterAll hooks back up the stack
|
||||||
|
]]
|
||||||
|
function LifecycleHooks:popHooks()
|
||||||
|
table.remove(self._stack, #self._stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
function LifecycleHooks:pushHooksFrom(planNode)
|
||||||
|
assert(planNode ~= nil)
|
||||||
|
|
||||||
|
table.insert(self._stack, {
|
||||||
|
[TestEnum.NodeType.BeforeAll] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.BeforeAll),
|
||||||
|
[TestEnum.NodeType.AfterAll] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.AfterAll),
|
||||||
|
[TestEnum.NodeType.BeforeEach] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.BeforeEach),
|
||||||
|
[TestEnum.NodeType.AfterEach] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.AfterEach),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Get the beforeAll hooks from the current level.
|
||||||
|
]]
|
||||||
|
function LifecycleHooks:getBeforeAllHooks()
|
||||||
|
return self._stack[#self._stack][TestEnum.NodeType.BeforeAll]
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Get the afterAll hooks from the current level.
|
||||||
|
]]
|
||||||
|
function LifecycleHooks:getAfterAllHooks()
|
||||||
|
return self._stack[#self._stack][TestEnum.NodeType.AfterAll]
|
||||||
|
end
|
||||||
|
|
||||||
|
function LifecycleHooks:_getHooksOfType(nodes, key)
|
||||||
|
local hooks = {}
|
||||||
|
|
||||||
|
for _, node in ipairs(nodes) do
|
||||||
|
if node.type == key then
|
||||||
|
table.insert(hooks, node.callback)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return hooks
|
||||||
|
end
|
||||||
|
|
||||||
|
return LifecycleHooks
|
||||||
102
TestEZ/Reporters/TeamCityReporter.lua
Normal file
102
TestEZ/Reporters/TeamCityReporter.lua
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
local TestService = game:GetService("TestService")
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.Parent.TestEnum)
|
||||||
|
|
||||||
|
local TeamCityReporter = {}
|
||||||
|
|
||||||
|
local function teamCityEscape(str)
|
||||||
|
str = string.gsub(str, "([]|'[])","|%1")
|
||||||
|
str = string.gsub(str, "\r", "|r")
|
||||||
|
str = string.gsub(str, "\n", "|n")
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
local function teamCityEnterSuite(suiteName)
|
||||||
|
return string.format("##teamcity[testSuiteStarted name='%s']", teamCityEscape(suiteName))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function teamCityLeaveSuite(suiteName)
|
||||||
|
return string.format("##teamcity[testSuiteFinished name='%s']", teamCityEscape(suiteName))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function teamCityEnterCase(caseName)
|
||||||
|
return string.format("##teamcity[testStarted name='%s']", teamCityEscape(caseName))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function teamCityLeaveCase(caseName)
|
||||||
|
return string.format("##teamcity[testFinished name='%s']", teamCityEscape(caseName))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function teamCityFailCase(caseName, errorMessage)
|
||||||
|
return string.format("##teamcity[testFailed name='%s' message='%s']",
|
||||||
|
teamCityEscape(caseName), teamCityEscape(errorMessage))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reportNode(node, buffer, level)
|
||||||
|
buffer = buffer or {}
|
||||||
|
level = level or 0
|
||||||
|
if node.status == TestEnum.TestStatus.Skipped then
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
if node.planNode.type == TestEnum.NodeType.Describe then
|
||||||
|
table.insert(buffer, teamCityEnterSuite(node.planNode.phrase))
|
||||||
|
for _, child in ipairs(node.children) do
|
||||||
|
reportNode(child, buffer, level + 1)
|
||||||
|
end
|
||||||
|
table.insert(buffer, teamCityLeaveSuite(node.planNode.phrase))
|
||||||
|
else
|
||||||
|
table.insert(buffer, teamCityEnterCase(node.planNode.phrase))
|
||||||
|
if node.status == TestEnum.TestStatus.Failure then
|
||||||
|
table.insert(buffer, teamCityFailCase(node.planNode.phrase, table.concat(node.errors,"\n")))
|
||||||
|
end
|
||||||
|
table.insert(buffer, teamCityLeaveCase(node.planNode.phrase))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reportRoot(node)
|
||||||
|
local buffer = {}
|
||||||
|
|
||||||
|
for _, child in ipairs(node.children) do
|
||||||
|
reportNode(child, buffer, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local function report(root)
|
||||||
|
local buffer = reportRoot(root)
|
||||||
|
|
||||||
|
return table.concat(buffer, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TeamCityReporter.report(results)
|
||||||
|
local resultBuffer = {
|
||||||
|
"Test results:",
|
||||||
|
report(results),
|
||||||
|
("%d passed, %d failed, %d skipped"):format(
|
||||||
|
results.successCount,
|
||||||
|
results.failureCount,
|
||||||
|
results.skippedCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
print(table.concat(resultBuffer, "\n"))
|
||||||
|
|
||||||
|
if results.failureCount > 0 then
|
||||||
|
print(("%d test nodes reported failures."):format(results.failureCount))
|
||||||
|
end
|
||||||
|
|
||||||
|
if #results.errors > 0 then
|
||||||
|
print("Errors reported by tests:")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
for _, message in ipairs(results.errors) do
|
||||||
|
TestService:Error(message)
|
||||||
|
|
||||||
|
-- Insert a blank line after each error
|
||||||
|
print("")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TeamCityReporter
|
||||||
106
TestEZ/Reporters/TextReporter.lua
Normal file
106
TestEZ/Reporters/TextReporter.lua
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
--[[
|
||||||
|
The TextReporter uses the results from a completed test to output text to
|
||||||
|
standard output and TestService.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestService = game:GetService("TestService")
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.Parent.TestEnum)
|
||||||
|
|
||||||
|
local INDENT = (" "):rep(3)
|
||||||
|
local STATUS_SYMBOLS = {
|
||||||
|
[TestEnum.TestStatus.Success] = "+",
|
||||||
|
[TestEnum.TestStatus.Failure] = "-",
|
||||||
|
[TestEnum.TestStatus.Skipped] = "~"
|
||||||
|
}
|
||||||
|
local UNKNOWN_STATUS_SYMBOL = "?"
|
||||||
|
|
||||||
|
local TextReporter = {}
|
||||||
|
|
||||||
|
local function compareNodes(a, b)
|
||||||
|
return a.planNode.phrase:lower() < b.planNode.phrase:lower()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reportNode(node, buffer, level)
|
||||||
|
buffer = buffer or {}
|
||||||
|
level = level or 0
|
||||||
|
|
||||||
|
if node.status == TestEnum.TestStatus.Skipped then
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local line
|
||||||
|
|
||||||
|
if node.status then
|
||||||
|
local symbol = STATUS_SYMBOLS[node.status] or UNKNOWN_STATUS_SYMBOL
|
||||||
|
|
||||||
|
line = ("%s[%s] %s"):format(
|
||||||
|
INDENT:rep(level),
|
||||||
|
symbol,
|
||||||
|
node.planNode.phrase
|
||||||
|
)
|
||||||
|
else
|
||||||
|
line = ("%s%s"):format(
|
||||||
|
INDENT:rep(level),
|
||||||
|
node.planNode.phrase
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(buffer, line)
|
||||||
|
table.sort(node.children, compareNodes)
|
||||||
|
|
||||||
|
for _, child in ipairs(node.children) do
|
||||||
|
reportNode(child, buffer, level + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reportRoot(node)
|
||||||
|
local buffer = {}
|
||||||
|
table.sort(node.children, compareNodes)
|
||||||
|
|
||||||
|
for _, child in ipairs(node.children) do
|
||||||
|
reportNode(child, buffer, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local function report(root)
|
||||||
|
local buffer = reportRoot(root)
|
||||||
|
|
||||||
|
return table.concat(buffer, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TextReporter.report(results)
|
||||||
|
local resultBuffer = {
|
||||||
|
"Test results:",
|
||||||
|
report(results),
|
||||||
|
("%d passed, %d failed, %d skipped"):format(
|
||||||
|
results.successCount,
|
||||||
|
results.failureCount,
|
||||||
|
results.skippedCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
print(table.concat(resultBuffer, "\n"))
|
||||||
|
|
||||||
|
if results.failureCount > 0 then
|
||||||
|
print(("%d test nodes reported failures."):format(results.failureCount))
|
||||||
|
end
|
||||||
|
|
||||||
|
if #results.errors > 0 then
|
||||||
|
print("Errors reported by tests:")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
for _, message in ipairs(results.errors) do
|
||||||
|
TestService:Error(message)
|
||||||
|
|
||||||
|
-- Insert a blank line after each error
|
||||||
|
print("")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TextReporter
|
||||||
97
TestEZ/Reporters/TextReporterQuiet.lua
Normal file
97
TestEZ/Reporters/TextReporterQuiet.lua
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
--[[
|
||||||
|
Copy of TextReporter that doesn't output successful tests.
|
||||||
|
|
||||||
|
This should be temporary, it's just a workaround to make CI environments
|
||||||
|
happy in the short-term.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestService = game:GetService("TestService")
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.Parent.TestEnum)
|
||||||
|
|
||||||
|
local INDENT = (" "):rep(3)
|
||||||
|
local STATUS_SYMBOLS = {
|
||||||
|
[TestEnum.TestStatus.Success] = "+",
|
||||||
|
[TestEnum.TestStatus.Failure] = "-",
|
||||||
|
[TestEnum.TestStatus.Skipped] = "~"
|
||||||
|
}
|
||||||
|
local UNKNOWN_STATUS_SYMBOL = "?"
|
||||||
|
|
||||||
|
local TextReporterQuiet = {}
|
||||||
|
|
||||||
|
local function reportNode(node, buffer, level)
|
||||||
|
buffer = buffer or {}
|
||||||
|
level = level or 0
|
||||||
|
|
||||||
|
if node.status == TestEnum.TestStatus.Skipped then
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local line
|
||||||
|
|
||||||
|
if node.status ~= TestEnum.TestStatus.Success then
|
||||||
|
local symbol = STATUS_SYMBOLS[node.status] or UNKNOWN_STATUS_SYMBOL
|
||||||
|
|
||||||
|
line = ("%s[%s] %s"):format(
|
||||||
|
INDENT:rep(level),
|
||||||
|
symbol,
|
||||||
|
node.planNode.phrase
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(buffer, line)
|
||||||
|
|
||||||
|
for _, child in ipairs(node.children) do
|
||||||
|
reportNode(child, buffer, level + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reportRoot(node)
|
||||||
|
local buffer = {}
|
||||||
|
|
||||||
|
for _, child in ipairs(node.children) do
|
||||||
|
reportNode(child, buffer, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
return buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
local function report(root)
|
||||||
|
local buffer = reportRoot(root)
|
||||||
|
|
||||||
|
return table.concat(buffer, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function TextReporterQuiet.report(results)
|
||||||
|
local resultBuffer = {
|
||||||
|
"Test results:",
|
||||||
|
report(results),
|
||||||
|
("%d passed, %d failed, %d skipped"):format(
|
||||||
|
results.successCount,
|
||||||
|
results.failureCount,
|
||||||
|
results.skippedCount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
print(table.concat(resultBuffer, "\n"))
|
||||||
|
|
||||||
|
if results.failureCount > 0 then
|
||||||
|
print(("%d test nodes reported failures."):format(results.failureCount))
|
||||||
|
end
|
||||||
|
|
||||||
|
if #results.errors > 0 then
|
||||||
|
print("Errors reported by tests:")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
for _, message in ipairs(results.errors) do
|
||||||
|
TestService:Error(message)
|
||||||
|
|
||||||
|
-- Insert a blank line after each error
|
||||||
|
print("")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return TextReporterQuiet
|
||||||
147
TestEZ/TestBootstrap.lua
Normal file
147
TestEZ/TestBootstrap.lua
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
--[[
|
||||||
|
Provides an interface to quickly run and report tests from a given object.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestPlanner = require(script.Parent.TestPlanner)
|
||||||
|
local TestRunner = require(script.Parent.TestRunner)
|
||||||
|
local TextReporter = require(script.Parent.Reporters.TextReporter)
|
||||||
|
|
||||||
|
local TestBootstrap = {}
|
||||||
|
|
||||||
|
local function stripSpecSuffix(name)
|
||||||
|
return (name:gsub("%.spec$", ""))
|
||||||
|
end
|
||||||
|
local function isSpecScript(aScript)
|
||||||
|
return aScript:IsA("ModuleScript") and aScript.Name:match("%.spec$")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getPath(module, root)
|
||||||
|
root = root or game
|
||||||
|
|
||||||
|
local path = {}
|
||||||
|
local last = module
|
||||||
|
|
||||||
|
if last.Name == "init.spec" then
|
||||||
|
-- Use the directory's node for init.spec files.
|
||||||
|
last = last.Parent
|
||||||
|
end
|
||||||
|
|
||||||
|
while last ~= nil and last ~= root do
|
||||||
|
table.insert(path, stripSpecSuffix(last.Name))
|
||||||
|
last = last.Parent
|
||||||
|
end
|
||||||
|
table.insert(path, stripSpecSuffix(root.Name))
|
||||||
|
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
|
||||||
|
local function toStringPath(tablePath)
|
||||||
|
local stringPath = ""
|
||||||
|
local first = true
|
||||||
|
for _, element in ipairs(tablePath) do
|
||||||
|
if first then
|
||||||
|
stringPath = element
|
||||||
|
first = false
|
||||||
|
else
|
||||||
|
stringPath = element .. " " .. stringPath
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return stringPath
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestBootstrap:getModulesImpl(root, modules, current)
|
||||||
|
modules = modules or {}
|
||||||
|
current = current or root
|
||||||
|
|
||||||
|
if isSpecScript(current) then
|
||||||
|
local method = require(current)
|
||||||
|
local path = getPath(current, root)
|
||||||
|
local pathString = toStringPath(path)
|
||||||
|
|
||||||
|
table.insert(modules, {
|
||||||
|
method = method,
|
||||||
|
path = path,
|
||||||
|
pathStringForSorting = pathString:lower()
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Find all the ModuleScripts in this tree that are tests.
|
||||||
|
]]
|
||||||
|
function TestBootstrap:getModules(root)
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
self:getModulesImpl(root, modules)
|
||||||
|
|
||||||
|
for _, child in ipairs(root:GetDescendants()) do
|
||||||
|
self:getModulesImpl(root, modules, child)
|
||||||
|
end
|
||||||
|
|
||||||
|
return modules
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Runs all test and reports the results using the given test reporter.
|
||||||
|
|
||||||
|
If no reporter is specified, a reasonable default is provided.
|
||||||
|
|
||||||
|
This function demonstrates the expected workflow with this testing system:
|
||||||
|
1. Locate test modules
|
||||||
|
2. Generate test plan
|
||||||
|
3. Run test plan
|
||||||
|
4. Report test results
|
||||||
|
|
||||||
|
This means we could hypothetically present a GUI to the developer that shows
|
||||||
|
the test plan before we execute it, allowing them to toggle specific tests
|
||||||
|
before they're run, but after they've been identified!
|
||||||
|
]]
|
||||||
|
function TestBootstrap:run(roots, reporter, otherOptions)
|
||||||
|
reporter = reporter or TextReporter
|
||||||
|
|
||||||
|
otherOptions = otherOptions or {}
|
||||||
|
local showTimingInfo = otherOptions["showTimingInfo"] or false
|
||||||
|
local testNamePattern = otherOptions["testNamePattern"]
|
||||||
|
local extraEnvironment = otherOptions["extraEnvironment"] or {}
|
||||||
|
|
||||||
|
if type(roots) ~= "table" then
|
||||||
|
error(("Bad argument #1 to TestBootstrap:run. Expected table, got %s"):format(typeof(roots)), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local startTime = tick()
|
||||||
|
|
||||||
|
local modules = {}
|
||||||
|
for _, subRoot in ipairs(roots) do
|
||||||
|
local newModules = self:getModules(subRoot)
|
||||||
|
|
||||||
|
for _, newModule in ipairs(newModules) do
|
||||||
|
table.insert(modules, newModule)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local afterModules = tick()
|
||||||
|
|
||||||
|
local plan = TestPlanner.createPlan(modules, testNamePattern, extraEnvironment)
|
||||||
|
local afterPlan = tick()
|
||||||
|
|
||||||
|
local results = TestRunner.runPlan(plan)
|
||||||
|
local afterRun = tick()
|
||||||
|
|
||||||
|
reporter.report(results)
|
||||||
|
local afterReport = tick()
|
||||||
|
|
||||||
|
if showTimingInfo then
|
||||||
|
local timing = {
|
||||||
|
("Took %f seconds to locate test modules"):format(afterModules - startTime),
|
||||||
|
("Took %f seconds to create test plan"):format(afterPlan - afterModules),
|
||||||
|
("Took %f seconds to run tests"):format(afterRun - afterPlan),
|
||||||
|
("Took %f seconds to report tests"):format(afterReport - afterRun),
|
||||||
|
}
|
||||||
|
|
||||||
|
print(table.concat(timing, "\n"))
|
||||||
|
end
|
||||||
|
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
return TestBootstrap
|
||||||
28
TestEZ/TestEnum.lua
Normal file
28
TestEZ/TestEnum.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
--[[
|
||||||
|
Constants used throughout the testing framework.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestEnum = {}
|
||||||
|
|
||||||
|
TestEnum.TestStatus = {
|
||||||
|
Success = "Success",
|
||||||
|
Failure = "Failure",
|
||||||
|
Skipped = "Skipped"
|
||||||
|
}
|
||||||
|
|
||||||
|
TestEnum.NodeType = {
|
||||||
|
Describe = "Describe",
|
||||||
|
It = "It",
|
||||||
|
BeforeAll = "BeforeAll",
|
||||||
|
AfterAll = "AfterAll",
|
||||||
|
BeforeEach = "BeforeEach",
|
||||||
|
AfterEach = "AfterEach"
|
||||||
|
}
|
||||||
|
|
||||||
|
TestEnum.NodeModifier = {
|
||||||
|
None = "None",
|
||||||
|
Skip = "Skip",
|
||||||
|
Focus = "Focus"
|
||||||
|
}
|
||||||
|
|
||||||
|
return TestEnum
|
||||||
304
TestEZ/TestPlan.lua
Normal file
304
TestEZ/TestPlan.lua
Normal file
|
|
@ -0,0 +1,304 @@
|
||||||
|
--[[
|
||||||
|
Represents a tree of tests that have been loaded but not necessarily
|
||||||
|
executed yet.
|
||||||
|
|
||||||
|
TestPlan objects are produced by TestPlanner.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.TestEnum)
|
||||||
|
local Expectation = require(script.Parent.Expectation)
|
||||||
|
|
||||||
|
local function newEnvironment(currentNode, extraEnvironment)
|
||||||
|
local env = {}
|
||||||
|
|
||||||
|
if extraEnvironment then
|
||||||
|
if type(extraEnvironment) ~= "table" then
|
||||||
|
error(("Bad argument #2 to newEnvironment. Expected table, got %s"):format(
|
||||||
|
typeof(extraEnvironment)), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
for key, value in pairs(extraEnvironment) do
|
||||||
|
env[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function addChild(phrase, callback, nodeType, nodeModifier)
|
||||||
|
local node = currentNode:addChild(phrase, nodeType, nodeModifier)
|
||||||
|
node.callback = callback
|
||||||
|
if nodeType == TestEnum.NodeType.Describe then
|
||||||
|
node:expand()
|
||||||
|
end
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.describeFOCUS(phrase, callback)
|
||||||
|
addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Focus)
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.describeSKIP(phrase, callback)
|
||||||
|
addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Skip)
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.describe(phrase, callback, nodeModifier)
|
||||||
|
addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.None)
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.itFOCUS(phrase, callback)
|
||||||
|
addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Focus)
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.itSKIP(phrase, callback)
|
||||||
|
addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.itFIXME(phrase, callback)
|
||||||
|
local node = addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
|
||||||
|
warn("FIXME: broken test", node:getFullName())
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.it(phrase, callback, nodeModifier)
|
||||||
|
addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.None)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Incrementing counter used to ensure that beforeAll, afterAll, beforeEach, afterEach have unique phrases
|
||||||
|
local lifecyclePhaseId = 0
|
||||||
|
|
||||||
|
local lifecycleHooks = {
|
||||||
|
[TestEnum.NodeType.BeforeAll] = "beforeAll",
|
||||||
|
[TestEnum.NodeType.AfterAll] = "afterAll",
|
||||||
|
[TestEnum.NodeType.BeforeEach] = "beforeEach",
|
||||||
|
[TestEnum.NodeType.AfterEach] = "afterEach"
|
||||||
|
}
|
||||||
|
|
||||||
|
for nodeType, name in pairs(lifecycleHooks) do
|
||||||
|
env[name] = function(callback)
|
||||||
|
addChild(name .. "_" .. tostring(lifecyclePhaseId), callback, nodeType, TestEnum.NodeModifier.None)
|
||||||
|
lifecyclePhaseId = lifecyclePhaseId + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.FIXME(optionalMessage)
|
||||||
|
warn("FIXME: broken test", currentNode:getFullName(), optionalMessage or "")
|
||||||
|
|
||||||
|
currentNode.modifier = TestEnum.NodeModifier.Skip
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.FOCUS()
|
||||||
|
currentNode.modifier = TestEnum.NodeModifier.Focus
|
||||||
|
end
|
||||||
|
|
||||||
|
function env.SKIP()
|
||||||
|
currentNode.modifier = TestEnum.NodeModifier.Skip
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
This function is deprecated. Calling it is a no-op beyond generating a
|
||||||
|
warning.
|
||||||
|
]]
|
||||||
|
function env.HACK_NO_XPCALL()
|
||||||
|
warn("HACK_NO_XPCALL is deprecated. It is now safe to yield in an " ..
|
||||||
|
"xpcall, so this is no longer necessary. It can be safely deleted.")
|
||||||
|
end
|
||||||
|
|
||||||
|
env.fit = env.itFOCUS
|
||||||
|
env.xit = env.itSKIP
|
||||||
|
env.fdescribe = env.describeFOCUS
|
||||||
|
env.xdescribe = env.describeSKIP
|
||||||
|
|
||||||
|
env.expect = setmetatable({
|
||||||
|
extend = function(...)
|
||||||
|
error("Cannot call \"expect.extend\" from within a \"describe\" node.")
|
||||||
|
end,
|
||||||
|
}, {
|
||||||
|
__call = function(_self, ...)
|
||||||
|
return Expectation.new(...)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
return env
|
||||||
|
end
|
||||||
|
|
||||||
|
local TestNode = {}
|
||||||
|
TestNode.__index = TestNode
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new test node. A pointer to the test plan, a phrase to describe it
|
||||||
|
and the type of node it is are required. The modifier is optional and will
|
||||||
|
be None if left blank.
|
||||||
|
]]
|
||||||
|
function TestNode.new(plan, phrase, nodeType, nodeModifier)
|
||||||
|
nodeModifier = nodeModifier or TestEnum.NodeModifier.None
|
||||||
|
|
||||||
|
local node = {
|
||||||
|
plan = plan,
|
||||||
|
phrase = phrase,
|
||||||
|
type = nodeType,
|
||||||
|
modifier = nodeModifier,
|
||||||
|
children = {},
|
||||||
|
callback = nil,
|
||||||
|
parent = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
node.environment = newEnvironment(node, plan.extraEnvironment)
|
||||||
|
return setmetatable(node, TestNode)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getModifier(name, pattern, modifier)
|
||||||
|
if pattern and (modifier == nil or modifier == TestEnum.NodeModifier.None) then
|
||||||
|
if name:match(pattern) then
|
||||||
|
return TestEnum.NodeModifier.Focus
|
||||||
|
else
|
||||||
|
return TestEnum.NodeModifier.Skip
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return modifier
|
||||||
|
end
|
||||||
|
|
||||||
|
function TestNode:addChild(phrase, nodeType, nodeModifier)
|
||||||
|
if nodeType == TestEnum.NodeType.It then
|
||||||
|
for _, child in pairs(self.children) do
|
||||||
|
if child.phrase == phrase then
|
||||||
|
error("Duplicate it block found: " .. child:getFullName())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local childName = self:getFullName() .. " " .. phrase
|
||||||
|
nodeModifier = getModifier(childName, self.plan.testNamePattern, nodeModifier)
|
||||||
|
local child = TestNode.new(self.plan, phrase, nodeType, nodeModifier)
|
||||||
|
child.parent = self
|
||||||
|
table.insert(self.children, child)
|
||||||
|
return child
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Join the names of all the nodes back to the parent.
|
||||||
|
]]
|
||||||
|
function TestNode:getFullName()
|
||||||
|
if self.parent then
|
||||||
|
local parentPhrase = self.parent:getFullName()
|
||||||
|
if parentPhrase then
|
||||||
|
return parentPhrase .. " " .. self.phrase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self.phrase
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Expand a node by setting its callback environment and then calling it. Any
|
||||||
|
further it and describe calls within the callback will be added to the tree.
|
||||||
|
]]
|
||||||
|
function TestNode:expand()
|
||||||
|
local originalEnv = getfenv(self.callback)
|
||||||
|
local callbackEnv = setmetatable({}, { __index = originalEnv })
|
||||||
|
for key, value in pairs(self.environment) do
|
||||||
|
callbackEnv[key] = value
|
||||||
|
end
|
||||||
|
-- Copy 'script' directly to new env to make Studio debugger happy.
|
||||||
|
-- Studio debugger does not look into __index, because of security reasons
|
||||||
|
callbackEnv.script = originalEnv.script
|
||||||
|
setfenv(self.callback, callbackEnv)
|
||||||
|
|
||||||
|
local success, result = xpcall(self.callback, function(message)
|
||||||
|
return debug.traceback(tostring(message), 2)
|
||||||
|
end)
|
||||||
|
|
||||||
|
if not success then
|
||||||
|
self.loadError = result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local TestPlan = {}
|
||||||
|
TestPlan.__index = TestPlan
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new, empty TestPlan.
|
||||||
|
]]
|
||||||
|
function TestPlan.new(testNamePattern, extraEnvironment)
|
||||||
|
local plan = {
|
||||||
|
children = {},
|
||||||
|
testNamePattern = testNamePattern,
|
||||||
|
extraEnvironment = extraEnvironment,
|
||||||
|
}
|
||||||
|
|
||||||
|
return setmetatable(plan, TestPlan)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Add a new child under the test plan's root node.
|
||||||
|
]]
|
||||||
|
function TestPlan:addChild(phrase, nodeType, nodeModifier)
|
||||||
|
nodeModifier = getModifier(phrase, self.testNamePattern, nodeModifier)
|
||||||
|
local child = TestNode.new(self, phrase, nodeType, nodeModifier)
|
||||||
|
table.insert(self.children, child)
|
||||||
|
return child
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Add a new describe node with the given method as a callback. Generates or
|
||||||
|
reuses all the describe nodes along the path.
|
||||||
|
]]
|
||||||
|
function TestPlan:addRoot(path, method)
|
||||||
|
local curNode = self
|
||||||
|
for i = #path, 1, -1 do
|
||||||
|
local nextNode = nil
|
||||||
|
|
||||||
|
for _, child in ipairs(curNode.children) do
|
||||||
|
if child.phrase == path[i] then
|
||||||
|
nextNode = child
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if nextNode == nil then
|
||||||
|
nextNode = curNode:addChild(path[i], TestEnum.NodeType.Describe)
|
||||||
|
end
|
||||||
|
|
||||||
|
curNode = nextNode
|
||||||
|
end
|
||||||
|
|
||||||
|
curNode.callback = method
|
||||||
|
curNode:expand()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Calls the given callback on all nodes in the tree, traversed depth-first.
|
||||||
|
]]
|
||||||
|
function TestPlan:visitAllNodes(callback, root, level)
|
||||||
|
root = root or self
|
||||||
|
level = level or 0
|
||||||
|
|
||||||
|
for _, child in ipairs(root.children) do
|
||||||
|
callback(child, level)
|
||||||
|
|
||||||
|
self:visitAllNodes(callback, child, level + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Visualizes the test plan in a simple format, suitable for debugging the test
|
||||||
|
plan's structure.
|
||||||
|
]]
|
||||||
|
function TestPlan:visualize()
|
||||||
|
local buffer = {}
|
||||||
|
self:visitAllNodes(function(node, level)
|
||||||
|
table.insert(buffer, (" "):rep(3 * level) .. node.phrase)
|
||||||
|
end)
|
||||||
|
return table.concat(buffer, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Gets a list of all nodes in the tree for which the given callback returns
|
||||||
|
true.
|
||||||
|
]]
|
||||||
|
function TestPlan:findNodes(callback)
|
||||||
|
local results = {}
|
||||||
|
self:visitAllNodes(function(node)
|
||||||
|
if callback(node) then
|
||||||
|
table.insert(results, node)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
return TestPlan
|
||||||
40
TestEZ/TestPlanner.lua
Normal file
40
TestEZ/TestPlanner.lua
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
--[[
|
||||||
|
Turns a series of specification functions into a test plan.
|
||||||
|
|
||||||
|
Uses a TestPlanBuilder to keep track of the state of the tree being built.
|
||||||
|
]]
|
||||||
|
local TestPlan = require(script.Parent.TestPlan)
|
||||||
|
|
||||||
|
local TestPlanner = {}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new TestPlan from a list of specification functions.
|
||||||
|
|
||||||
|
These functions should call a combination of `describe` and `it` (and their
|
||||||
|
variants), which will be turned into a test plan to be executed.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- modulesList - list of tables describing test modules {
|
||||||
|
method, -- specification function described above
|
||||||
|
path, -- array of parent entires, first element is the leaf that owns `method`
|
||||||
|
pathStringForSorting -- a string representation of `path`, used for sorting of the test plan
|
||||||
|
}
|
||||||
|
- testNamePattern - Only tests matching this Lua pattern string will run. Pass empty or nil to run all tests
|
||||||
|
- extraEnvironment - Lua table holding additional functions and variables to be injected into the specification
|
||||||
|
function during execution
|
||||||
|
]]
|
||||||
|
function TestPlanner.createPlan(modulesList, testNamePattern, extraEnvironment)
|
||||||
|
local plan = TestPlan.new(testNamePattern, extraEnvironment)
|
||||||
|
|
||||||
|
table.sort(modulesList, function(a, b)
|
||||||
|
return a.pathStringForSorting < b.pathStringForSorting
|
||||||
|
end)
|
||||||
|
|
||||||
|
for _, module in ipairs(modulesList) do
|
||||||
|
plan:addRoot(module.path, module.method)
|
||||||
|
end
|
||||||
|
|
||||||
|
return plan
|
||||||
|
end
|
||||||
|
|
||||||
|
return TestPlanner
|
||||||
112
TestEZ/TestResults.lua
Normal file
112
TestEZ/TestResults.lua
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
--[[
|
||||||
|
Represents a tree of test results.
|
||||||
|
|
||||||
|
Each node in the tree corresponds directly to a node in a corresponding
|
||||||
|
TestPlan, accessible via the 'planNode' field.
|
||||||
|
|
||||||
|
TestResults objects are produced by TestRunner using TestSession as state.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.TestEnum)
|
||||||
|
|
||||||
|
local STATUS_SYMBOLS = {
|
||||||
|
[TestEnum.TestStatus.Success] = "+",
|
||||||
|
[TestEnum.TestStatus.Failure] = "-",
|
||||||
|
[TestEnum.TestStatus.Skipped] = "~"
|
||||||
|
}
|
||||||
|
|
||||||
|
local TestResults = {}
|
||||||
|
|
||||||
|
TestResults.__index = TestResults
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new TestResults tree that's linked to the given TestPlan.
|
||||||
|
]]
|
||||||
|
function TestResults.new(plan)
|
||||||
|
local self = {
|
||||||
|
successCount = 0,
|
||||||
|
failureCount = 0,
|
||||||
|
skippedCount = 0,
|
||||||
|
planNode = plan,
|
||||||
|
children = {},
|
||||||
|
errors = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(self, TestResults)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new result node that can be inserted into a TestResult tree.
|
||||||
|
]]
|
||||||
|
function TestResults.createNode(planNode)
|
||||||
|
local node = {
|
||||||
|
planNode = planNode,
|
||||||
|
children = {},
|
||||||
|
errors = {},
|
||||||
|
status = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Visit all test result nodes, depth-first.
|
||||||
|
]]
|
||||||
|
function TestResults:visitAllNodes(callback, root)
|
||||||
|
root = root or self
|
||||||
|
|
||||||
|
for _, child in ipairs(root.children) do
|
||||||
|
callback(child)
|
||||||
|
|
||||||
|
self:visitAllNodes(callback, child)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Creates a debug visualization of the test results.
|
||||||
|
]]
|
||||||
|
function TestResults:visualize(root, level)
|
||||||
|
root = root or self
|
||||||
|
level = level or 0
|
||||||
|
|
||||||
|
local buffer = {}
|
||||||
|
|
||||||
|
for _, child in ipairs(root.children) do
|
||||||
|
if child.planNode.type == TestEnum.NodeType.It then
|
||||||
|
local symbol = STATUS_SYMBOLS[child.status] or "?"
|
||||||
|
local str = ("%s[%s] %s"):format(
|
||||||
|
(" "):rep(3 * level),
|
||||||
|
symbol,
|
||||||
|
child.planNode.phrase
|
||||||
|
)
|
||||||
|
|
||||||
|
if child.messages and #child.messages > 0 then
|
||||||
|
str = str .. "\n " .. (" "):rep(3 * level) .. table.concat(child.messages, "\n " .. (" "):rep(3 * level))
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(buffer, str)
|
||||||
|
else
|
||||||
|
local str = ("%s%s"):format(
|
||||||
|
(" "):rep(3 * level),
|
||||||
|
child.planNode.phrase or ""
|
||||||
|
)
|
||||||
|
|
||||||
|
if child.status then
|
||||||
|
str = str .. (" (%s)"):format(child.status)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(buffer, str)
|
||||||
|
|
||||||
|
if #child.children > 0 then
|
||||||
|
local text = self:visualize(child, level + 1)
|
||||||
|
table.insert(buffer, text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(buffer, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
return TestResults
|
||||||
188
TestEZ/TestRunner.lua
Normal file
188
TestEZ/TestRunner.lua
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
--[[
|
||||||
|
Contains the logic to run a test plan and gather test results from it.
|
||||||
|
|
||||||
|
TestRunner accepts a TestPlan object, executes the planned tests, and
|
||||||
|
produces a TestResults object. While the tests are running, the system's
|
||||||
|
state is contained inside a TestSession object.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.TestEnum)
|
||||||
|
local TestSession = require(script.Parent.TestSession)
|
||||||
|
local LifecycleHooks = require(script.Parent.LifecycleHooks)
|
||||||
|
|
||||||
|
local RUNNING_GLOBAL = "__TESTEZ_RUNNING_TEST__"
|
||||||
|
|
||||||
|
local TestRunner = {
|
||||||
|
environment = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
local function wrapExpectContextWithPublicApi(expectationContext)
|
||||||
|
return setmetatable({
|
||||||
|
extend = function(...)
|
||||||
|
expectationContext:extend(...)
|
||||||
|
end,
|
||||||
|
}, {
|
||||||
|
__call = function(_self, ...)
|
||||||
|
return expectationContext:startExpectationChain(...)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Runs the given TestPlan and returns a TestResults object representing the
|
||||||
|
results of the run.
|
||||||
|
]]
|
||||||
|
function TestRunner.runPlan(plan)
|
||||||
|
local session = TestSession.new(plan)
|
||||||
|
local lifecycleHooks = LifecycleHooks.new()
|
||||||
|
|
||||||
|
local exclusiveNodes = plan:findNodes(function(node)
|
||||||
|
return node.modifier == TestEnum.NodeModifier.Focus
|
||||||
|
end)
|
||||||
|
|
||||||
|
session.hasFocusNodes = #exclusiveNodes > 0
|
||||||
|
|
||||||
|
TestRunner.runPlanNode(session, plan, lifecycleHooks)
|
||||||
|
|
||||||
|
return session:finalize()
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Run the given test plan node and its descendants, using the given test
|
||||||
|
session to store all of the results.
|
||||||
|
]]
|
||||||
|
function TestRunner.runPlanNode(session, planNode, lifecycleHooks)
|
||||||
|
local function runCallback(callback, messagePrefix)
|
||||||
|
local success = true
|
||||||
|
local errorMessage
|
||||||
|
-- Any code can check RUNNING_GLOBAL to fork behavior based on
|
||||||
|
-- whether a test is running. We use this to avoid accessing
|
||||||
|
-- protected APIs; it's a workaround that will go away someday.
|
||||||
|
_G[RUNNING_GLOBAL] = true
|
||||||
|
|
||||||
|
messagePrefix = messagePrefix or ""
|
||||||
|
|
||||||
|
local testEnvironment = getfenv(callback)
|
||||||
|
|
||||||
|
for key, value in pairs(TestRunner.environment) do
|
||||||
|
testEnvironment[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
testEnvironment.fail = function(message)
|
||||||
|
if message == nil then
|
||||||
|
message = "fail() was called."
|
||||||
|
end
|
||||||
|
|
||||||
|
success = false
|
||||||
|
errorMessage = messagePrefix .. debug.traceback(tostring(message), 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
testEnvironment.expect = wrapExpectContextWithPublicApi(session:getExpectationContext())
|
||||||
|
|
||||||
|
local context = session:getContext()
|
||||||
|
|
||||||
|
local nodeSuccess, nodeResult = xpcall(
|
||||||
|
function()
|
||||||
|
callback(context)
|
||||||
|
end,
|
||||||
|
function(message)
|
||||||
|
return messagePrefix .. debug.traceback(tostring(message), 2)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
-- If a node threw an error, we prefer to use that message over
|
||||||
|
-- one created by fail() if it was set.
|
||||||
|
if not nodeSuccess then
|
||||||
|
success = false
|
||||||
|
errorMessage = nodeResult
|
||||||
|
end
|
||||||
|
|
||||||
|
_G[RUNNING_GLOBAL] = nil
|
||||||
|
|
||||||
|
return success, errorMessage
|
||||||
|
end
|
||||||
|
|
||||||
|
local function runNode(childPlanNode)
|
||||||
|
-- Errors can be set either via `error` propagating upwards or
|
||||||
|
-- by a test calling fail([message]).
|
||||||
|
|
||||||
|
for _, hook in ipairs(lifecycleHooks:getBeforeEachHooks()) do
|
||||||
|
local success, errorMessage = runCallback(hook, "beforeEach hook: ")
|
||||||
|
if not success then
|
||||||
|
return false, errorMessage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local testSuccess, testErrorMessage = runCallback(childPlanNode.callback)
|
||||||
|
|
||||||
|
for _, hook in ipairs(lifecycleHooks:getAfterEachHooks()) do
|
||||||
|
local success, errorMessage = runCallback(hook, "afterEach hook: ")
|
||||||
|
if not success then
|
||||||
|
if not testSuccess then
|
||||||
|
return false, testErrorMessage .. "\nWhile cleaning up the failed test another error was found:\n" .. errorMessage
|
||||||
|
end
|
||||||
|
return false, errorMessage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not testSuccess then
|
||||||
|
return false, testErrorMessage
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
lifecycleHooks:pushHooksFrom(planNode)
|
||||||
|
|
||||||
|
local halt = false
|
||||||
|
for _, hook in ipairs(lifecycleHooks:getBeforeAllHooks()) do
|
||||||
|
local success, errorMessage = runCallback(hook, "beforeAll hook: ")
|
||||||
|
if not success then
|
||||||
|
session:addDummyError("beforeAll", errorMessage)
|
||||||
|
halt = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not halt then
|
||||||
|
for _, childPlanNode in ipairs(planNode.children) do
|
||||||
|
if childPlanNode.type == TestEnum.NodeType.It then
|
||||||
|
session:pushNode(childPlanNode)
|
||||||
|
if session:shouldSkip() then
|
||||||
|
session:setSkipped()
|
||||||
|
else
|
||||||
|
local success, errorMessage = runNode(childPlanNode)
|
||||||
|
|
||||||
|
if success then
|
||||||
|
session:setSuccess()
|
||||||
|
else
|
||||||
|
session:setError(errorMessage)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
session:popNode()
|
||||||
|
elseif childPlanNode.type == TestEnum.NodeType.Describe then
|
||||||
|
session:pushNode(childPlanNode)
|
||||||
|
TestRunner.runPlanNode(session, childPlanNode, lifecycleHooks)
|
||||||
|
|
||||||
|
-- Did we have an error trying build a test plan?
|
||||||
|
if childPlanNode.loadError then
|
||||||
|
local message = "Error during planning: " .. childPlanNode.loadError
|
||||||
|
session:setError(message)
|
||||||
|
else
|
||||||
|
session:setStatusFromChildren()
|
||||||
|
end
|
||||||
|
session:popNode()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, hook in ipairs(lifecycleHooks:getAfterAllHooks()) do
|
||||||
|
local success, errorMessage = runCallback(hook, "afterAll hook: ")
|
||||||
|
if not success then
|
||||||
|
session:addDummyError("afterAll", errorMessage)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
lifecycleHooks:popHooks()
|
||||||
|
end
|
||||||
|
|
||||||
|
return TestRunner
|
||||||
243
TestEZ/TestSession.lua
Normal file
243
TestEZ/TestSession.lua
Normal file
|
|
@ -0,0 +1,243 @@
|
||||||
|
--[[
|
||||||
|
Represents the state relevant while executing a test plan.
|
||||||
|
|
||||||
|
Used by TestRunner to produce a TestResults object.
|
||||||
|
|
||||||
|
Uses the same tree building structure as TestPlanBuilder; TestSession keeps
|
||||||
|
track of a stack of nodes that represent the current path through the tree.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TestEnum = require(script.Parent.TestEnum)
|
||||||
|
local TestResults = require(script.Parent.TestResults)
|
||||||
|
local Context = require(script.Parent.Context)
|
||||||
|
local ExpectationContext = require(script.Parent.ExpectationContext)
|
||||||
|
|
||||||
|
local TestSession = {}
|
||||||
|
|
||||||
|
TestSession.__index = TestSession
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a TestSession related to the given TestPlan.
|
||||||
|
|
||||||
|
The resulting TestResults object will be linked to this TestPlan.
|
||||||
|
]]
|
||||||
|
function TestSession.new(plan)
|
||||||
|
local self = {
|
||||||
|
results = TestResults.new(plan),
|
||||||
|
nodeStack = {},
|
||||||
|
contextStack = {},
|
||||||
|
expectationContextStack = {},
|
||||||
|
hasFocusNodes = false
|
||||||
|
}
|
||||||
|
|
||||||
|
setmetatable(self, TestSession)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Calculate success, failure, and skipped test counts in the tree at the
|
||||||
|
current point in the execution.
|
||||||
|
]]
|
||||||
|
function TestSession:calculateTotals()
|
||||||
|
local results = self.results
|
||||||
|
|
||||||
|
results.successCount = 0
|
||||||
|
results.failureCount = 0
|
||||||
|
results.skippedCount = 0
|
||||||
|
|
||||||
|
results:visitAllNodes(function(node)
|
||||||
|
local status = node.status
|
||||||
|
local nodeType = node.planNode.type
|
||||||
|
|
||||||
|
if nodeType == TestEnum.NodeType.It then
|
||||||
|
if status == TestEnum.TestStatus.Success then
|
||||||
|
results.successCount = results.successCount + 1
|
||||||
|
elseif status == TestEnum.TestStatus.Failure then
|
||||||
|
results.failureCount = results.failureCount + 1
|
||||||
|
elseif status == TestEnum.TestStatus.Skipped then
|
||||||
|
results.skippedCount = results.skippedCount + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Gathers all of the errors reported by tests and puts them at the top level
|
||||||
|
of the TestResults object.
|
||||||
|
]]
|
||||||
|
function TestSession:gatherErrors()
|
||||||
|
local results = self.results
|
||||||
|
|
||||||
|
results.errors = {}
|
||||||
|
|
||||||
|
results:visitAllNodes(function(node)
|
||||||
|
if #node.errors > 0 then
|
||||||
|
for _, message in ipairs(node.errors) do
|
||||||
|
table.insert(results.errors, message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Calculates test totals, verifies the tree is valid, and returns results.
|
||||||
|
]]
|
||||||
|
function TestSession:finalize()
|
||||||
|
if #self.nodeStack ~= 0 then
|
||||||
|
error("Cannot finalize TestResults with nodes still on the stack!", 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:calculateTotals()
|
||||||
|
self:gatherErrors()
|
||||||
|
|
||||||
|
return self.results
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Create a new test result node and push it onto the navigation stack.
|
||||||
|
]]
|
||||||
|
function TestSession:pushNode(planNode)
|
||||||
|
local node = TestResults.createNode(planNode)
|
||||||
|
local lastNode = self.nodeStack[#self.nodeStack] or self.results
|
||||||
|
table.insert(lastNode.children, node)
|
||||||
|
table.insert(self.nodeStack, node)
|
||||||
|
|
||||||
|
local lastContext = self.contextStack[#self.contextStack]
|
||||||
|
local context = Context.new(lastContext)
|
||||||
|
table.insert(self.contextStack, context)
|
||||||
|
|
||||||
|
local lastExpectationContext = self.expectationContextStack[#self.expectationContextStack]
|
||||||
|
local expectationContext = ExpectationContext.new(lastExpectationContext)
|
||||||
|
table.insert(self.expectationContextStack, expectationContext)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Pops a node off of the navigation stack.
|
||||||
|
]]
|
||||||
|
function TestSession:popNode()
|
||||||
|
assert(#self.nodeStack > 0, "Tried to pop from an empty node stack!")
|
||||||
|
table.remove(self.nodeStack, #self.nodeStack)
|
||||||
|
table.remove(self.contextStack, #self.contextStack)
|
||||||
|
table.remove(self.expectationContextStack, #self.expectationContextStack)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Gets the Context object for the current node.
|
||||||
|
]]
|
||||||
|
function TestSession:getContext()
|
||||||
|
assert(#self.contextStack > 0, "Tried to get context from an empty stack!")
|
||||||
|
return self.contextStack[#self.contextStack]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function TestSession:getExpectationContext()
|
||||||
|
assert(#self.expectationContextStack > 0, "Tried to get expectationContext from an empty stack!")
|
||||||
|
return self.expectationContextStack[#self.expectationContextStack]
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Tells whether the current test we're in should be skipped.
|
||||||
|
]]
|
||||||
|
function TestSession:shouldSkip()
|
||||||
|
-- If our test tree had any exclusive tests, then normal tests are skipped!
|
||||||
|
if self.hasFocusNodes then
|
||||||
|
for i = #self.nodeStack, 1, -1 do
|
||||||
|
local node = self.nodeStack[i]
|
||||||
|
|
||||||
|
-- Skipped tests are still skipped
|
||||||
|
if node.planNode.modifier == TestEnum.NodeModifier.Skip then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Focused tests are the only ones that aren't skipped
|
||||||
|
if node.planNode.modifier == TestEnum.NodeModifier.Focus then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
for i = #self.nodeStack, 1, -1 do
|
||||||
|
local node = self.nodeStack[i]
|
||||||
|
|
||||||
|
if node.planNode.modifier == TestEnum.NodeModifier.Skip then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Set the current node's status to Success.
|
||||||
|
]]
|
||||||
|
function TestSession:setSuccess()
|
||||||
|
assert(#self.nodeStack > 0, "Attempting to set success status on empty stack")
|
||||||
|
self.nodeStack[#self.nodeStack].status = TestEnum.TestStatus.Success
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Set the current node's status to Skipped.
|
||||||
|
]]
|
||||||
|
function TestSession:setSkipped()
|
||||||
|
assert(#self.nodeStack > 0, "Attempting to set skipped status on empty stack")
|
||||||
|
self.nodeStack[#self.nodeStack].status = TestEnum.TestStatus.Skipped
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Set the current node's status to Failure and adds a message to its list of
|
||||||
|
errors.
|
||||||
|
]]
|
||||||
|
function TestSession:setError(message)
|
||||||
|
assert(#self.nodeStack > 0, "Attempting to set error status on empty stack")
|
||||||
|
local last = self.nodeStack[#self.nodeStack]
|
||||||
|
last.status = TestEnum.TestStatus.Failure
|
||||||
|
table.insert(last.errors, message)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Add a dummy child node to the current node to hold the given error. This
|
||||||
|
allows an otherwise empty describe node to report an error in a more natural
|
||||||
|
way.
|
||||||
|
]]
|
||||||
|
function TestSession:addDummyError(phrase, message)
|
||||||
|
self:pushNode({type = TestEnum.NodeType.It, phrase = phrase})
|
||||||
|
self:setError(message)
|
||||||
|
self:popNode()
|
||||||
|
self.nodeStack[#self.nodeStack].status = TestEnum.TestStatus.Failure
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Set the current node's status based on that of its children. If all children
|
||||||
|
are skipped, mark it as skipped. If any are fails, mark it as failed.
|
||||||
|
Otherwise, mark it as success.
|
||||||
|
]]
|
||||||
|
function TestSession:setStatusFromChildren()
|
||||||
|
assert(#self.nodeStack > 0, "Attempting to set status from children on empty stack")
|
||||||
|
|
||||||
|
local last = self.nodeStack[#self.nodeStack]
|
||||||
|
local status = TestEnum.TestStatus.Success
|
||||||
|
local skipped = true
|
||||||
|
|
||||||
|
-- If all children were skipped, then we were skipped
|
||||||
|
-- If any child failed, then we failed!
|
||||||
|
for _, child in ipairs(last.children) do
|
||||||
|
if child.status ~= TestEnum.TestStatus.Skipped then
|
||||||
|
skipped = false
|
||||||
|
|
||||||
|
if child.status == TestEnum.TestStatus.Failure then
|
||||||
|
status = TestEnum.TestStatus.Failure
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if skipped then
|
||||||
|
status = TestEnum.TestStatus.Skipped
|
||||||
|
end
|
||||||
|
|
||||||
|
last.status = status
|
||||||
|
end
|
||||||
|
|
||||||
|
return TestSession
|
||||||
42
TestEZ/init.lua
Normal file
42
TestEZ/init.lua
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
--!native
|
||||||
|
--!optimize 2
|
||||||
|
local Expectation = require(script.Expectation)
|
||||||
|
local TestBootstrap = require(script.TestBootstrap)
|
||||||
|
local TestEnum = require(script.TestEnum)
|
||||||
|
local TestPlan = require(script.TestPlan)
|
||||||
|
local TestPlanner = require(script.TestPlanner)
|
||||||
|
local TestResults = require(script.TestResults)
|
||||||
|
local TestRunner = require(script.TestRunner)
|
||||||
|
local TestSession = require(script.TestSession)
|
||||||
|
local TextReporter = require(script.Reporters.TextReporter)
|
||||||
|
local TextReporterQuiet = require(script.Reporters.TextReporterQuiet)
|
||||||
|
local TeamCityReporter = require(script.Reporters.TeamCityReporter)
|
||||||
|
|
||||||
|
local function run(testRoot, callback)
|
||||||
|
local modules = TestBootstrap:getModules(testRoot)
|
||||||
|
local plan = TestPlanner.createPlan(modules)
|
||||||
|
local results = TestRunner.runPlan(plan)
|
||||||
|
|
||||||
|
callback(results)
|
||||||
|
end
|
||||||
|
|
||||||
|
local TestEZ = {
|
||||||
|
run = run,
|
||||||
|
|
||||||
|
Expectation = Expectation,
|
||||||
|
TestBootstrap = TestBootstrap,
|
||||||
|
TestEnum = TestEnum,
|
||||||
|
TestPlan = TestPlan,
|
||||||
|
TestPlanner = TestPlanner,
|
||||||
|
TestResults = TestResults,
|
||||||
|
TestRunner = TestRunner,
|
||||||
|
TestSession = TestSession,
|
||||||
|
|
||||||
|
Reporters = {
|
||||||
|
TextReporter = TextReporter,
|
||||||
|
TextReporterQuiet = TextReporterQuiet,
|
||||||
|
TeamCityReporter = TeamCityReporter,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return TestEZ
|
||||||
BIN
Warp.rbxm
BIN
Warp.rbxm
Binary file not shown.
|
|
@ -3,5 +3,5 @@
|
||||||
|
|
||||||
# To add a new tool, add an entry to this table.
|
# To add a new tool, add an entry to this table.
|
||||||
[tools]
|
[tools]
|
||||||
rojo = "rojo-rbx/rojo@7.4.0"
|
rojo = "rojo-rbx/rojo@7.6.1"
|
||||||
wally = "UpliftGames/wally@0.3.2"
|
wally = "UpliftGames/wally@0.3.2"
|
||||||
|
|
|
||||||
331
bun.lock
Normal file
331
bun.lock
Normal file
|
|
@ -0,0 +1,331 @@
|
||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 1,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"devDependencies": {
|
||||||
|
"vitepress": "^2.0.0-alpha.16",
|
||||||
|
"vue": "^3.5.28",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
||||||
|
|
||||||
|
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
|
||||||
|
|
||||||
|
"@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
|
||||||
|
|
||||||
|
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
|
||||||
|
|
||||||
|
"@docsearch/css": ["@docsearch/css@4.5.4", "", {}, "sha512-gzO4DJwyM9c4YEPHwaLV1nUCDC2N6yoh0QJj44dce2rcfN71mB+jpu3+F+Y/KMDF1EKV0C3m54leSWsraE94xg=="],
|
||||||
|
|
||||||
|
"@docsearch/js": ["@docsearch/js@4.5.4", "", {}, "sha512-jEBsIklNTevznLZouB0y6SZcaT897gRHnGTzCcH32ibPZRVj/9FyuAM2LUTk61sFdOY79LH4V9rYsIdOe6Wq2g=="],
|
||||||
|
|
||||||
|
"@docsearch/sidepanel-js": ["@docsearch/sidepanel-js@4.5.4", "", {}, "sha512-f4KE4cG+P09gJHQNfttfMNy+3gAGj8U0YEgiOOso0YCFI5nGoVvJQpxNMSPgXs4sG34A/oCfKhYwHJiqgHhxPw=="],
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="],
|
||||||
|
|
||||||
|
"@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="],
|
||||||
|
|
||||||
|
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="],
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="],
|
||||||
|
|
||||||
|
"@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.70", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-CYNRCgN6nBTjN4dNkrBCjHXNR2e4hQihdsZUs/afUNFOWLSYjfihca4EFN05rRvDk4Xoy2n8tym6IxBZmcn+Qg=="],
|
||||||
|
|
||||||
|
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||||
|
|
||||||
|
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.2", "", {}, "sha512-izyXV/v+cHiRfozX62W9htOAvwMo4/bXKDrQ+vom1L1qRuexPock/7VZDAhnpHCLNejd3NJ6hiab+tO0D44Rgw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.57.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.57.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.57.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.57.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.57.1", "", { "os": "linux", "cpu": "arm" }, "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.57.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.57.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.57.1", "", { "os": "linux", "cpu": "none" }, "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.57.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.57.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.57.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.57.1", "", { "os": "none", "cpu": "arm64" }, "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.57.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.57.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA=="],
|
||||||
|
|
||||||
|
"@shikijs/core": ["@shikijs/core@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="],
|
||||||
|
|
||||||
|
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="],
|
||||||
|
|
||||||
|
"@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="],
|
||||||
|
|
||||||
|
"@shikijs/langs": ["@shikijs/langs@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="],
|
||||||
|
|
||||||
|
"@shikijs/themes": ["@shikijs/themes@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="],
|
||||||
|
|
||||||
|
"@shikijs/transformers": ["@shikijs/transformers@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/types": "3.22.0" } }, "sha512-E7eRV7mwDBjueLF6852n2oYeJYxBq3NSsDk+uyruYAXONv4U8holGmIrT+mPRJQ1J1SNOH6L8G19KRzmBawrFw=="],
|
||||||
|
|
||||||
|
"@shikijs/types": ["@shikijs/types@3.22.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="],
|
||||||
|
|
||||||
|
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
|
||||||
|
|
||||||
|
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||||
|
|
||||||
|
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
|
||||||
|
|
||||||
|
"@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="],
|
||||||
|
|
||||||
|
"@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="],
|
||||||
|
|
||||||
|
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
||||||
|
|
||||||
|
"@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="],
|
||||||
|
|
||||||
|
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
|
||||||
|
|
||||||
|
"@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="],
|
||||||
|
|
||||||
|
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
||||||
|
|
||||||
|
"@vitejs/plugin-vue": ["@vitejs/plugin-vue@6.0.4", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.2" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "vue": "^3.2.25" } }, "sha512-uM5iXipgYIn13UUQCZNdWkYk+sysBeA97d5mHsAoAt1u/wpN3+zxOmsVJWosuzX+IMGRzeYUNytztrYznboIkQ=="],
|
||||||
|
|
||||||
|
"@vue/compiler-core": ["@vue/compiler-core@3.5.28", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/shared": "3.5.28", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-kviccYxTgoE8n6OCw96BNdYlBg2GOWfBuOW4Vqwrt7mSKWKwFVvI8egdTltqRgITGPsTFYtKYfxIG8ptX2PJHQ=="],
|
||||||
|
|
||||||
|
"@vue/compiler-dom": ["@vue/compiler-dom@3.5.28", "", { "dependencies": { "@vue/compiler-core": "3.5.28", "@vue/shared": "3.5.28" } }, "sha512-/1ZepxAb159jKR1btkefDP+J2xuWL5V3WtleRmxaT+K2Aqiek/Ab/+Ebrw2pPj0sdHO8ViAyyJWfhXXOP/+LQA=="],
|
||||||
|
|
||||||
|
"@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.28", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.28", "@vue/compiler-dom": "3.5.28", "@vue/compiler-ssr": "3.5.28", "@vue/shared": "3.5.28", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-6TnKMiNkd6u6VeVDhZn/07KhEZuBSn43Wd2No5zaP5s3xm8IqFTHBj84HJah4UepSUJTro5SoqqlOY22FKY96g=="],
|
||||||
|
|
||||||
|
"@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.28", "", { "dependencies": { "@vue/compiler-dom": "3.5.28", "@vue/shared": "3.5.28" } }, "sha512-JCq//9w1qmC6UGLWJX7RXzrGpKkroubey/ZFqTpvEIDJEKGgntuDMqkuWiZvzTzTA5h2qZvFBFHY7fAAa9475g=="],
|
||||||
|
|
||||||
|
"@vue/devtools-api": ["@vue/devtools-api@8.0.6", "", { "dependencies": { "@vue/devtools-kit": "^8.0.6" } }, "sha512-+lGBI+WTvJmnU2FZqHhEB8J1DXcvNlDeEalz77iYgOdY1jTj1ipSBaKj3sRhYcy+kqA8v/BSuvOz1XJucfQmUA=="],
|
||||||
|
|
||||||
|
"@vue/devtools-kit": ["@vue/devtools-kit@8.0.6", "", { "dependencies": { "@vue/devtools-shared": "^8.0.6", "birpc": "^2.6.1", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^2.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-9zXZPTJW72OteDXeSa5RVML3zWDCRcO5t77aJqSs228mdopYj5AiTpihozbsfFJ0IodfNs7pSgOGO3qfCuxDtw=="],
|
||||||
|
|
||||||
|
"@vue/devtools-shared": ["@vue/devtools-shared@8.0.6", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-Pp1JylTqlgMJvxW6MGyfTF8vGvlBSCAvMFaDCYa82Mgw7TT5eE5kkHgDvmOGHWeJE4zIDfCpCxHapsK2LtIAJg=="],
|
||||||
|
|
||||||
|
"@vue/reactivity": ["@vue/reactivity@3.5.28", "", { "dependencies": { "@vue/shared": "3.5.28" } }, "sha512-gr5hEsxvn+RNyu9/9o1WtdYdwDjg5FgjUSBEkZWqgTKlo/fvwZ2+8W6AfKsc9YN2k/+iHYdS9vZYAhpi10kNaw=="],
|
||||||
|
|
||||||
|
"@vue/runtime-core": ["@vue/runtime-core@3.5.28", "", { "dependencies": { "@vue/reactivity": "3.5.28", "@vue/shared": "3.5.28" } }, "sha512-POVHTdbgnrBBIpnbYU4y7pOMNlPn2QVxVzkvEA2pEgvzbelQq4ZOUxbp2oiyo+BOtiYlm8Q44wShHJoBvDPAjQ=="],
|
||||||
|
|
||||||
|
"@vue/runtime-dom": ["@vue/runtime-dom@3.5.28", "", { "dependencies": { "@vue/reactivity": "3.5.28", "@vue/runtime-core": "3.5.28", "@vue/shared": "3.5.28", "csstype": "^3.2.3" } }, "sha512-4SXxSF8SXYMuhAIkT+eBRqOkWEfPu6nhccrzrkioA6l0boiq7sp18HCOov9qWJA5HML61kW8p/cB4MmBiG9dSA=="],
|
||||||
|
|
||||||
|
"@vue/server-renderer": ["@vue/server-renderer@3.5.28", "", { "dependencies": { "@vue/compiler-ssr": "3.5.28", "@vue/shared": "3.5.28" }, "peerDependencies": { "vue": "3.5.28" } }, "sha512-pf+5ECKGj8fX95bNincbzJ6yp6nyzuLDhYZCeFxUNp8EBrQpPpQaLX3nNCp49+UbgbPun3CeVE+5CXVV1Xydfg=="],
|
||||||
|
|
||||||
|
"@vue/shared": ["@vue/shared@3.5.28", "", {}, "sha512-cfWa1fCGBxrvaHRhvV3Is0MgmrbSCxYTXCSCau2I0a1Xw1N1pHAvkWCiXPRAqjvToILvguNyEwjevUqAuBQWvQ=="],
|
||||||
|
|
||||||
|
"@vueuse/core": ["@vueuse/core@14.2.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "14.2.1", "@vueuse/shared": "14.2.1" }, "peerDependencies": { "vue": "^3.5.0" } }, "sha512-3vwDzV+GDUNpdegRY6kzpLm4Igptq+GA0QkJ3W61Iv27YWwW/ufSlOfgQIpN6FZRMG0mkaz4gglJRtq5SeJyIQ=="],
|
||||||
|
|
||||||
|
"@vueuse/integrations": ["@vueuse/integrations@14.2.1", "", { "dependencies": { "@vueuse/core": "14.2.1", "@vueuse/shared": "14.2.1" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7 || ^8", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7 || ^8", "vue": "^3.5.0" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "focus-trap", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-2LIUpBi/67PoXJGqSDQUF0pgQWpNHh7beiA+KG2AbybcNm+pTGWT6oPGlBgUoDWmYwfeQqM/uzOHqcILpKL7nA=="],
|
||||||
|
|
||||||
|
"@vueuse/metadata": ["@vueuse/metadata@14.2.1", "", {}, "sha512-1ButlVtj5Sb/HDtIy1HFr1VqCP4G6Ypqt5MAo0lCgjokrk2mvQKsK2uuy0vqu/Ks+sHfuHo0B9Y9jn9xKdjZsw=="],
|
||||||
|
|
||||||
|
"@vueuse/shared": ["@vueuse/shared@14.2.1", "", { "peerDependencies": { "vue": "^3.5.0" } }, "sha512-shTJncjV9JTI4oVNyF1FQonetYAiTBd+Qj7cY89SWbXSkx7gyhrgtEdF2ZAVWS1S3SHlaROO6F2IesJxQEkZBw=="],
|
||||||
|
|
||||||
|
"birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="],
|
||||||
|
|
||||||
|
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
||||||
|
|
||||||
|
"character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="],
|
||||||
|
|
||||||
|
"character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="],
|
||||||
|
|
||||||
|
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
|
||||||
|
|
||||||
|
"copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="],
|
||||||
|
|
||||||
|
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||||
|
|
||||||
|
"dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
|
||||||
|
|
||||||
|
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
|
||||||
|
|
||||||
|
"entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
|
||||||
|
|
||||||
|
"esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="],
|
||||||
|
|
||||||
|
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
|
"focus-trap": ["focus-trap@7.8.0", "", { "dependencies": { "tabbable": "^6.4.0" } }, "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA=="],
|
||||||
|
|
||||||
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
|
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
|
||||||
|
|
||||||
|
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
|
||||||
|
|
||||||
|
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
||||||
|
|
||||||
|
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
|
||||||
|
|
||||||
|
"is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="],
|
||||||
|
|
||||||
|
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||||
|
|
||||||
|
"mark.js": ["mark.js@8.11.1", "", {}, "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="],
|
||||||
|
|
||||||
|
"mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="],
|
||||||
|
|
||||||
|
"micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="],
|
||||||
|
|
||||||
|
"micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="],
|
||||||
|
|
||||||
|
"micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="],
|
||||||
|
|
||||||
|
"micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="],
|
||||||
|
|
||||||
|
"micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
|
||||||
|
|
||||||
|
"minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="],
|
||||||
|
|
||||||
|
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
|
||||||
|
|
||||||
|
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
|
"oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="],
|
||||||
|
|
||||||
|
"oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="],
|
||||||
|
|
||||||
|
"perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="],
|
||||||
|
|
||||||
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
|
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||||
|
|
||||||
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
|
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
||||||
|
|
||||||
|
"regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="],
|
||||||
|
|
||||||
|
"regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="],
|
||||||
|
|
||||||
|
"regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="],
|
||||||
|
|
||||||
|
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
|
||||||
|
|
||||||
|
"rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="],
|
||||||
|
|
||||||
|
"shiki": ["shiki@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="],
|
||||||
|
|
||||||
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
|
"space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
|
||||||
|
|
||||||
|
"speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="],
|
||||||
|
|
||||||
|
"stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
|
||||||
|
|
||||||
|
"superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="],
|
||||||
|
|
||||||
|
"tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="],
|
||||||
|
|
||||||
|
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||||
|
|
||||||
|
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
||||||
|
|
||||||
|
"unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
|
||||||
|
|
||||||
|
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
|
||||||
|
|
||||||
|
"unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
|
||||||
|
|
||||||
|
"unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
|
||||||
|
|
||||||
|
"unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="],
|
||||||
|
|
||||||
|
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
|
||||||
|
|
||||||
|
"vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
|
||||||
|
|
||||||
|
"vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
|
||||||
|
|
||||||
|
"vitepress": ["vitepress@2.0.0-alpha.16", "", { "dependencies": { "@docsearch/css": "^4.5.3", "@docsearch/js": "^4.5.3", "@docsearch/sidepanel-js": "^4.5.3", "@iconify-json/simple-icons": "^1.2.68", "@shikijs/core": "^3.21.0", "@shikijs/transformers": "^3.21.0", "@shikijs/types": "^3.21.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^6.0.3", "@vue/devtools-api": "^8.0.5", "@vue/shared": "^3.5.27", "@vueuse/core": "^14.1.0", "@vueuse/integrations": "^14.1.0", "focus-trap": "^7.8.0", "mark.js": "8.11.1", "minisearch": "^7.2.0", "shiki": "^3.21.0", "vite": "^7.3.1", "vue": "^3.5.27" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "oxc-minify": "*", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "oxc-minify", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-w1nwsefDVIsje7BZr2tsKxkZutDGjG0YoQ2yxO7+a9tvYVqfljYbwj5LMYkPy8Tb7YbPwa22HtIhk62jbrvuEQ=="],
|
||||||
|
|
||||||
|
"vue": ["vue@3.5.28", "", { "dependencies": { "@vue/compiler-dom": "3.5.28", "@vue/compiler-sfc": "3.5.28", "@vue/runtime-dom": "3.5.28", "@vue/server-renderer": "3.5.28", "@vue/shared": "3.5.28" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-BRdrNfeoccSoIZeIhyPBfvWSLFP4q8J3u8Ju8Ug5vu3LdD+yTM13Sg4sKtljxozbnuMu1NB1X5HBHRYUzFocKg=="],
|
||||||
|
|
||||||
|
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "Warp",
|
"name": "warp",
|
||||||
"tree": {
|
"tree": {
|
||||||
"$path": "src"
|
"$path": "src"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
34
docs/.vitepress/cache/deps/_metadata.json
vendored
34
docs/.vitepress/cache/deps/_metadata.json
vendored
|
|
@ -1,52 +1,52 @@
|
||||||
{
|
{
|
||||||
"hash": "64a640d4",
|
"hash": "681ef108",
|
||||||
"configHash": "3539395e",
|
"configHash": "a89fa9d8",
|
||||||
"lockfileHash": "16b933ee",
|
"lockfileHash": "482c3808",
|
||||||
"browserHash": "761a6f81",
|
"browserHash": "09b4e28f",
|
||||||
"optimized": {
|
"optimized": {
|
||||||
"vue": {
|
"vue": {
|
||||||
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
||||||
"file": "vue.js",
|
"file": "vue.js",
|
||||||
"fileHash": "2232d95d",
|
"fileHash": "0126683b",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > @vue/devtools-api": {
|
"vitepress > @vue/devtools-api": {
|
||||||
"src": "../../../../node_modules/@vue/devtools-api/lib/esm/index.js",
|
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
|
||||||
"file": "vitepress___@vue_devtools-api.js",
|
"file": "vitepress___@vue_devtools-api.js",
|
||||||
"fileHash": "ea18bfc8",
|
"fileHash": "83501de3",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > @vueuse/core": {
|
"vitepress > @vueuse/core": {
|
||||||
"src": "../../../../node_modules/@vueuse/core/index.mjs",
|
"src": "../../../../node_modules/@vueuse/core/dist/index.js",
|
||||||
"file": "vitepress___@vueuse_core.js",
|
"file": "vitepress___@vueuse_core.js",
|
||||||
"fileHash": "1889f635",
|
"fileHash": "95219540",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > @vueuse/integrations/useFocusTrap": {
|
"vitepress > @vueuse/integrations/useFocusTrap": {
|
||||||
"src": "../../../../node_modules/@vueuse/integrations/useFocusTrap.mjs",
|
"src": "../../../../node_modules/@vueuse/integrations/dist/useFocusTrap.js",
|
||||||
"file": "vitepress___@vueuse_integrations_useFocusTrap.js",
|
"file": "vitepress___@vueuse_integrations_useFocusTrap.js",
|
||||||
"fileHash": "84f193d7",
|
"fileHash": "3d5a642a",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > mark.js/src/vanilla.js": {
|
"vitepress > mark.js/src/vanilla.js": {
|
||||||
"src": "../../../../node_modules/mark.js/src/vanilla.js",
|
"src": "../../../../node_modules/mark.js/src/vanilla.js",
|
||||||
"file": "vitepress___mark__js_src_vanilla__js.js",
|
"file": "vitepress___mark__js_src_vanilla__js.js",
|
||||||
"fileHash": "3dbcfe04",
|
"fileHash": "bcd715ea",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"vitepress > minisearch": {
|
"vitepress > minisearch": {
|
||||||
"src": "../../../../node_modules/minisearch/dist/es/index.js",
|
"src": "../../../../node_modules/minisearch/dist/es/index.js",
|
||||||
"file": "vitepress___minisearch.js",
|
"file": "vitepress___minisearch.js",
|
||||||
"fileHash": "5c47da60",
|
"fileHash": "291618c6",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chunks": {
|
"chunks": {
|
||||||
"chunk-WFT6MZEP": {
|
"chunk-K7K3DSDG": {
|
||||||
"file": "chunk-WFT6MZEP.js"
|
"file": "chunk-K7K3DSDG.js"
|
||||||
},
|
},
|
||||||
"chunk-3YS4HNIT": {
|
"chunk-JLJ73CPZ": {
|
||||||
"file": "chunk-3YS4HNIT.js"
|
"file": "chunk-JLJ73CPZ.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
11367
docs/.vitepress/cache/deps/chunk-3YS4HNIT.js
vendored
11367
docs/.vitepress/cache/deps/chunk-3YS4HNIT.js
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
8965
docs/.vitepress/cache/deps/chunk-WFT6MZEP.js
vendored
8965
docs/.vitepress/cache/deps/chunk-WFT6MZEP.js
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -3,14 +3,19 @@ import {
|
||||||
StorageSerializers,
|
StorageSerializers,
|
||||||
TransitionPresets,
|
TransitionPresets,
|
||||||
assert,
|
assert,
|
||||||
|
asyncComputed,
|
||||||
|
autoResetRef,
|
||||||
breakpointsAntDesign,
|
breakpointsAntDesign,
|
||||||
breakpointsBootstrapV5,
|
breakpointsBootstrapV5,
|
||||||
|
breakpointsElement,
|
||||||
breakpointsMasterCss,
|
breakpointsMasterCss,
|
||||||
breakpointsPrimeFlex,
|
breakpointsPrimeFlex,
|
||||||
breakpointsQuasar,
|
breakpointsQuasar,
|
||||||
breakpointsSematic,
|
breakpointsSematic,
|
||||||
breakpointsTailwind,
|
breakpointsTailwind,
|
||||||
breakpointsVuetify,
|
breakpointsVuetify,
|
||||||
|
breakpointsVuetifyV2,
|
||||||
|
breakpointsVuetifyV3,
|
||||||
bypassFilter,
|
bypassFilter,
|
||||||
camelize,
|
camelize,
|
||||||
clamp,
|
clamp,
|
||||||
|
|
@ -20,12 +25,15 @@ import {
|
||||||
computedInject,
|
computedInject,
|
||||||
computedWithControl,
|
computedWithControl,
|
||||||
containsProp,
|
containsProp,
|
||||||
|
controlledComputed,
|
||||||
controlledRef,
|
controlledRef,
|
||||||
createEventHook,
|
createEventHook,
|
||||||
createFetch,
|
createFetch,
|
||||||
createFilterWrapper,
|
createFilterWrapper,
|
||||||
createGlobalState,
|
createGlobalState,
|
||||||
createInjectionState,
|
createInjectionState,
|
||||||
|
createReactiveFn,
|
||||||
|
createRef,
|
||||||
createReusableTemplate,
|
createReusableTemplate,
|
||||||
createSharedComposable,
|
createSharedComposable,
|
||||||
createSingletonPromise,
|
createSingletonPromise,
|
||||||
|
|
@ -33,21 +41,26 @@ import {
|
||||||
createUnrefFn,
|
createUnrefFn,
|
||||||
customStorageEventName,
|
customStorageEventName,
|
||||||
debounceFilter,
|
debounceFilter,
|
||||||
|
debouncedRef,
|
||||||
|
debouncedWatch,
|
||||||
defaultDocument,
|
defaultDocument,
|
||||||
defaultLocation,
|
defaultLocation,
|
||||||
defaultNavigator,
|
defaultNavigator,
|
||||||
defaultWindow,
|
defaultWindow,
|
||||||
directiveHooks,
|
eagerComputed,
|
||||||
executeTransition,
|
executeTransition,
|
||||||
extendRef,
|
extendRef,
|
||||||
formatDate,
|
formatDate,
|
||||||
formatTimeAgo,
|
formatTimeAgo,
|
||||||
|
formatTimeAgoIntl,
|
||||||
|
formatTimeAgoIntlParts,
|
||||||
get,
|
get,
|
||||||
getLifeCycleTarget,
|
getLifeCycleTarget,
|
||||||
getSSRHandler,
|
getSSRHandler,
|
||||||
hasOwn,
|
hasOwn,
|
||||||
hyphenate,
|
hyphenate,
|
||||||
identity,
|
identity,
|
||||||
|
ignorableWatch,
|
||||||
increaseWithUnit,
|
increaseWithUnit,
|
||||||
injectLocal,
|
injectLocal,
|
||||||
invoke,
|
invoke,
|
||||||
|
|
@ -67,6 +80,7 @@ import {
|
||||||
objectOmit,
|
objectOmit,
|
||||||
objectPick,
|
objectPick,
|
||||||
onClickOutside,
|
onClickOutside,
|
||||||
|
onElementRemoval,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
onKeyPressed,
|
onKeyPressed,
|
||||||
onKeyStroke,
|
onKeyStroke,
|
||||||
|
|
@ -74,8 +88,11 @@ import {
|
||||||
onLongPress,
|
onLongPress,
|
||||||
onStartTyping,
|
onStartTyping,
|
||||||
pausableFilter,
|
pausableFilter,
|
||||||
|
pausableWatch,
|
||||||
promiseTimeout,
|
promiseTimeout,
|
||||||
provideLocal,
|
provideLocal,
|
||||||
|
provideSSRWidth,
|
||||||
|
pxValue,
|
||||||
rand,
|
rand,
|
||||||
reactify,
|
reactify,
|
||||||
reactifyObject,
|
reactifyObject,
|
||||||
|
|
@ -85,21 +102,23 @@ import {
|
||||||
refAutoReset,
|
refAutoReset,
|
||||||
refDebounced,
|
refDebounced,
|
||||||
refDefault,
|
refDefault,
|
||||||
|
refManualReset,
|
||||||
refThrottled,
|
refThrottled,
|
||||||
refWithControl,
|
refWithControl,
|
||||||
resolveRef,
|
|
||||||
resolveUnref,
|
|
||||||
set,
|
set,
|
||||||
setSSRHandler,
|
setSSRHandler,
|
||||||
syncRef,
|
syncRef,
|
||||||
syncRefs,
|
syncRefs,
|
||||||
templateRef,
|
templateRef,
|
||||||
throttleFilter,
|
throttleFilter,
|
||||||
|
throttledRef,
|
||||||
|
throttledWatch,
|
||||||
timestamp,
|
timestamp,
|
||||||
|
toArray,
|
||||||
toReactive,
|
toReactive,
|
||||||
toRef,
|
toRef,
|
||||||
toRefs,
|
toRefs,
|
||||||
toValue,
|
transition,
|
||||||
tryOnBeforeMount,
|
tryOnBeforeMount,
|
||||||
tryOnBeforeUnmount,
|
tryOnBeforeUnmount,
|
||||||
tryOnMounted,
|
tryOnMounted,
|
||||||
|
|
@ -135,12 +154,15 @@ import {
|
||||||
useCloned,
|
useCloned,
|
||||||
useColorMode,
|
useColorMode,
|
||||||
useConfirmDialog,
|
useConfirmDialog,
|
||||||
|
useCountdown,
|
||||||
useCounter,
|
useCounter,
|
||||||
|
useCssSupports,
|
||||||
useCssVar,
|
useCssVar,
|
||||||
useCurrentElement,
|
useCurrentElement,
|
||||||
useCycleList,
|
useCycleList,
|
||||||
useDark,
|
useDark,
|
||||||
useDateFormat,
|
useDateFormat,
|
||||||
|
useDebounce,
|
||||||
useDebounceFn,
|
useDebounceFn,
|
||||||
useDebouncedRefHistory,
|
useDebouncedRefHistory,
|
||||||
useDeviceMotion,
|
useDeviceMotion,
|
||||||
|
|
@ -209,10 +231,12 @@ import {
|
||||||
usePreferredDark,
|
usePreferredDark,
|
||||||
usePreferredLanguages,
|
usePreferredLanguages,
|
||||||
usePreferredReducedMotion,
|
usePreferredReducedMotion,
|
||||||
|
usePreferredReducedTransparency,
|
||||||
usePrevious,
|
usePrevious,
|
||||||
useRafFn,
|
useRafFn,
|
||||||
useRefHistory,
|
useRefHistory,
|
||||||
useResizeObserver,
|
useResizeObserver,
|
||||||
|
useSSRWidth,
|
||||||
useScreenOrientation,
|
useScreenOrientation,
|
||||||
useScreenSafeArea,
|
useScreenSafeArea,
|
||||||
useScriptTag,
|
useScriptTag,
|
||||||
|
|
@ -233,9 +257,11 @@ import {
|
||||||
useTextDirection,
|
useTextDirection,
|
||||||
useTextSelection,
|
useTextSelection,
|
||||||
useTextareaAutosize,
|
useTextareaAutosize,
|
||||||
|
useThrottle,
|
||||||
useThrottleFn,
|
useThrottleFn,
|
||||||
useThrottledRefHistory,
|
useThrottledRefHistory,
|
||||||
useTimeAgo,
|
useTimeAgo,
|
||||||
|
useTimeAgoIntl,
|
||||||
useTimeout,
|
useTimeout,
|
||||||
useTimeoutFn,
|
useTimeoutFn,
|
||||||
useTimeoutPoll,
|
useTimeoutPoll,
|
||||||
|
|
@ -271,23 +297,26 @@ import {
|
||||||
watchTriggerable,
|
watchTriggerable,
|
||||||
watchWithFilter,
|
watchWithFilter,
|
||||||
whenever
|
whenever
|
||||||
} from "./chunk-WFT6MZEP.js";
|
} from "./chunk-K7K3DSDG.js";
|
||||||
import "./chunk-3YS4HNIT.js";
|
import "./chunk-JLJ73CPZ.js";
|
||||||
export {
|
export {
|
||||||
DefaultMagicKeysAliasMap,
|
DefaultMagicKeysAliasMap,
|
||||||
StorageSerializers,
|
StorageSerializers,
|
||||||
TransitionPresets,
|
TransitionPresets,
|
||||||
assert,
|
assert,
|
||||||
computedAsync as asyncComputed,
|
asyncComputed,
|
||||||
refAutoReset as autoResetRef,
|
autoResetRef,
|
||||||
breakpointsAntDesign,
|
breakpointsAntDesign,
|
||||||
breakpointsBootstrapV5,
|
breakpointsBootstrapV5,
|
||||||
|
breakpointsElement,
|
||||||
breakpointsMasterCss,
|
breakpointsMasterCss,
|
||||||
breakpointsPrimeFlex,
|
breakpointsPrimeFlex,
|
||||||
breakpointsQuasar,
|
breakpointsQuasar,
|
||||||
breakpointsSematic,
|
breakpointsSematic,
|
||||||
breakpointsTailwind,
|
breakpointsTailwind,
|
||||||
breakpointsVuetify,
|
breakpointsVuetify,
|
||||||
|
breakpointsVuetifyV2,
|
||||||
|
breakpointsVuetifyV3,
|
||||||
bypassFilter,
|
bypassFilter,
|
||||||
camelize,
|
camelize,
|
||||||
clamp,
|
clamp,
|
||||||
|
|
@ -297,14 +326,15 @@ export {
|
||||||
computedInject,
|
computedInject,
|
||||||
computedWithControl,
|
computedWithControl,
|
||||||
containsProp,
|
containsProp,
|
||||||
computedWithControl as controlledComputed,
|
controlledComputed,
|
||||||
controlledRef,
|
controlledRef,
|
||||||
createEventHook,
|
createEventHook,
|
||||||
createFetch,
|
createFetch,
|
||||||
createFilterWrapper,
|
createFilterWrapper,
|
||||||
createGlobalState,
|
createGlobalState,
|
||||||
createInjectionState,
|
createInjectionState,
|
||||||
reactify as createReactiveFn,
|
createReactiveFn,
|
||||||
|
createRef,
|
||||||
createReusableTemplate,
|
createReusableTemplate,
|
||||||
createSharedComposable,
|
createSharedComposable,
|
||||||
createSingletonPromise,
|
createSingletonPromise,
|
||||||
|
|
@ -312,25 +342,26 @@ export {
|
||||||
createUnrefFn,
|
createUnrefFn,
|
||||||
customStorageEventName,
|
customStorageEventName,
|
||||||
debounceFilter,
|
debounceFilter,
|
||||||
refDebounced as debouncedRef,
|
debouncedRef,
|
||||||
watchDebounced as debouncedWatch,
|
debouncedWatch,
|
||||||
defaultDocument,
|
defaultDocument,
|
||||||
defaultLocation,
|
defaultLocation,
|
||||||
defaultNavigator,
|
defaultNavigator,
|
||||||
defaultWindow,
|
defaultWindow,
|
||||||
directiveHooks,
|
eagerComputed,
|
||||||
computedEager as eagerComputed,
|
|
||||||
executeTransition,
|
executeTransition,
|
||||||
extendRef,
|
extendRef,
|
||||||
formatDate,
|
formatDate,
|
||||||
formatTimeAgo,
|
formatTimeAgo,
|
||||||
|
formatTimeAgoIntl,
|
||||||
|
formatTimeAgoIntlParts,
|
||||||
get,
|
get,
|
||||||
getLifeCycleTarget,
|
getLifeCycleTarget,
|
||||||
getSSRHandler,
|
getSSRHandler,
|
||||||
hasOwn,
|
hasOwn,
|
||||||
hyphenate,
|
hyphenate,
|
||||||
identity,
|
identity,
|
||||||
watchIgnorable as ignorableWatch,
|
ignorableWatch,
|
||||||
increaseWithUnit,
|
increaseWithUnit,
|
||||||
injectLocal,
|
injectLocal,
|
||||||
invoke,
|
invoke,
|
||||||
|
|
@ -350,6 +381,7 @@ export {
|
||||||
objectOmit,
|
objectOmit,
|
||||||
objectPick,
|
objectPick,
|
||||||
onClickOutside,
|
onClickOutside,
|
||||||
|
onElementRemoval,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
onKeyPressed,
|
onKeyPressed,
|
||||||
onKeyStroke,
|
onKeyStroke,
|
||||||
|
|
@ -357,9 +389,11 @@ export {
|
||||||
onLongPress,
|
onLongPress,
|
||||||
onStartTyping,
|
onStartTyping,
|
||||||
pausableFilter,
|
pausableFilter,
|
||||||
watchPausable as pausableWatch,
|
pausableWatch,
|
||||||
promiseTimeout,
|
promiseTimeout,
|
||||||
provideLocal,
|
provideLocal,
|
||||||
|
provideSSRWidth,
|
||||||
|
pxValue,
|
||||||
rand,
|
rand,
|
||||||
reactify,
|
reactify,
|
||||||
reactifyObject,
|
reactifyObject,
|
||||||
|
|
@ -369,23 +403,23 @@ export {
|
||||||
refAutoReset,
|
refAutoReset,
|
||||||
refDebounced,
|
refDebounced,
|
||||||
refDefault,
|
refDefault,
|
||||||
|
refManualReset,
|
||||||
refThrottled,
|
refThrottled,
|
||||||
refWithControl,
|
refWithControl,
|
||||||
resolveRef,
|
|
||||||
resolveUnref,
|
|
||||||
set,
|
set,
|
||||||
setSSRHandler,
|
setSSRHandler,
|
||||||
syncRef,
|
syncRef,
|
||||||
syncRefs,
|
syncRefs,
|
||||||
templateRef,
|
templateRef,
|
||||||
throttleFilter,
|
throttleFilter,
|
||||||
refThrottled as throttledRef,
|
throttledRef,
|
||||||
watchThrottled as throttledWatch,
|
throttledWatch,
|
||||||
timestamp,
|
timestamp,
|
||||||
|
toArray,
|
||||||
toReactive,
|
toReactive,
|
||||||
toRef,
|
toRef,
|
||||||
toRefs,
|
toRefs,
|
||||||
toValue,
|
transition,
|
||||||
tryOnBeforeMount,
|
tryOnBeforeMount,
|
||||||
tryOnBeforeUnmount,
|
tryOnBeforeUnmount,
|
||||||
tryOnMounted,
|
tryOnMounted,
|
||||||
|
|
@ -421,13 +455,15 @@ export {
|
||||||
useCloned,
|
useCloned,
|
||||||
useColorMode,
|
useColorMode,
|
||||||
useConfirmDialog,
|
useConfirmDialog,
|
||||||
|
useCountdown,
|
||||||
useCounter,
|
useCounter,
|
||||||
|
useCssSupports,
|
||||||
useCssVar,
|
useCssVar,
|
||||||
useCurrentElement,
|
useCurrentElement,
|
||||||
useCycleList,
|
useCycleList,
|
||||||
useDark,
|
useDark,
|
||||||
useDateFormat,
|
useDateFormat,
|
||||||
refDebounced as useDebounce,
|
useDebounce,
|
||||||
useDebounceFn,
|
useDebounceFn,
|
||||||
useDebouncedRefHistory,
|
useDebouncedRefHistory,
|
||||||
useDeviceMotion,
|
useDeviceMotion,
|
||||||
|
|
@ -496,10 +532,12 @@ export {
|
||||||
usePreferredDark,
|
usePreferredDark,
|
||||||
usePreferredLanguages,
|
usePreferredLanguages,
|
||||||
usePreferredReducedMotion,
|
usePreferredReducedMotion,
|
||||||
|
usePreferredReducedTransparency,
|
||||||
usePrevious,
|
usePrevious,
|
||||||
useRafFn,
|
useRafFn,
|
||||||
useRefHistory,
|
useRefHistory,
|
||||||
useResizeObserver,
|
useResizeObserver,
|
||||||
|
useSSRWidth,
|
||||||
useScreenOrientation,
|
useScreenOrientation,
|
||||||
useScreenSafeArea,
|
useScreenSafeArea,
|
||||||
useScriptTag,
|
useScriptTag,
|
||||||
|
|
@ -520,10 +558,11 @@ export {
|
||||||
useTextDirection,
|
useTextDirection,
|
||||||
useTextSelection,
|
useTextSelection,
|
||||||
useTextareaAutosize,
|
useTextareaAutosize,
|
||||||
refThrottled as useThrottle,
|
useThrottle,
|
||||||
useThrottleFn,
|
useThrottleFn,
|
||||||
useThrottledRefHistory,
|
useThrottledRefHistory,
|
||||||
useTimeAgo,
|
useTimeAgo,
|
||||||
|
useTimeAgoIntl,
|
||||||
useTimeout,
|
useTimeout,
|
||||||
useTimeoutFn,
|
useTimeoutFn,
|
||||||
useTimeoutPoll,
|
useTimeoutPoll,
|
||||||
|
|
@ -560,4 +599,3 @@ export {
|
||||||
watchWithFilter,
|
watchWithFilter,
|
||||||
whenever
|
whenever
|
||||||
};
|
};
|
||||||
//# sourceMappingURL=vitepress___@vueuse_core.js.map
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
import {
|
import {
|
||||||
|
notNullish,
|
||||||
|
toArray,
|
||||||
tryOnScopeDispose,
|
tryOnScopeDispose,
|
||||||
unrefElement
|
unrefElement
|
||||||
} from "./chunk-WFT6MZEP.js";
|
} from "./chunk-K7K3DSDG.js";
|
||||||
import {
|
import {
|
||||||
ref,
|
computed,
|
||||||
|
shallowRef,
|
||||||
|
toValue,
|
||||||
watch
|
watch
|
||||||
} from "./chunk-3YS4HNIT.js";
|
} from "./chunk-JLJ73CPZ.js";
|
||||||
|
|
||||||
// node_modules/tabbable/dist/index.esm.js
|
// node_modules/tabbable/dist/index.esm.js
|
||||||
var candidateSelectors = ["input:not([inert])", "select:not([inert])", "textarea:not([inert])", "a[href]:not([inert])", "button:not([inert])", "[tabindex]:not(slot):not([inert])", "audio[controls]:not([inert])", "video[controls]:not([inert])", '[contenteditable]:not([contenteditable="false"]):not([inert])', "details>summary:first-of-type:not([inert])", "details:not([inert])"];
|
var candidateSelectors = ["input:not([inert]):not([inert] *)", "select:not([inert]):not([inert] *)", "textarea:not([inert]):not([inert] *)", "a[href]:not([inert]):not([inert] *)", "button:not([inert]):not([inert] *)", "[tabindex]:not(slot):not([inert]):not([inert] *)", "audio[controls]:not([inert]):not([inert] *)", "video[controls]:not([inert]):not([inert] *)", '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)', "details>summary:first-of-type:not([inert]):not([inert] *)", "details:not([inert]):not([inert] *)"];
|
||||||
var candidateSelector = candidateSelectors.join(",");
|
var candidateSelector = candidateSelectors.join(",");
|
||||||
var NoElement = typeof Element === "undefined";
|
var NoElement = typeof Element === "undefined";
|
||||||
var matches = NoElement ? function() {
|
var matches = NoElement ? function() {
|
||||||
|
|
@ -19,14 +23,16 @@ var getRootNode = !NoElement && Element.prototype.getRootNode ? function(element
|
||||||
} : function(element) {
|
} : function(element) {
|
||||||
return element === null || element === void 0 ? void 0 : element.ownerDocument;
|
return element === null || element === void 0 ? void 0 : element.ownerDocument;
|
||||||
};
|
};
|
||||||
var isInert = function isInert2(node, lookUp) {
|
var _isInert = function isInert(node, lookUp) {
|
||||||
var _node$getAttribute;
|
var _node$getAttribute;
|
||||||
if (lookUp === void 0) {
|
if (lookUp === void 0) {
|
||||||
lookUp = true;
|
lookUp = true;
|
||||||
}
|
}
|
||||||
var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert");
|
var inertAtt = node === null || node === void 0 ? void 0 : (_node$getAttribute = node.getAttribute) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute.call(node, "inert");
|
||||||
var inert = inertAtt === "" || inertAtt === "true";
|
var inert = inertAtt === "" || inertAtt === "true";
|
||||||
var result = inert || lookUp && node && isInert2(node.parentNode);
|
var result = inert || lookUp && node && // closest does not exist on shadow roots, so we fall back to a manual
|
||||||
|
// lookup upward, in case it is not defined.
|
||||||
|
(typeof node.closest === "function" ? node.closest("[inert]") : _isInert(node.parentNode));
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
var isContentEditable = function isContentEditable2(node) {
|
var isContentEditable = function isContentEditable2(node) {
|
||||||
|
|
@ -35,7 +41,7 @@ var isContentEditable = function isContentEditable2(node) {
|
||||||
return attValue === "" || attValue === "true";
|
return attValue === "" || attValue === "true";
|
||||||
};
|
};
|
||||||
var getCandidates = function getCandidates2(el, includeContainer, filter) {
|
var getCandidates = function getCandidates2(el, includeContainer, filter) {
|
||||||
if (isInert(el)) {
|
if (_isInert(el)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
||||||
|
|
@ -45,18 +51,18 @@ var getCandidates = function getCandidates2(el, includeContainer, filter) {
|
||||||
candidates = candidates.filter(filter);
|
candidates = candidates.filter(filter);
|
||||||
return candidates;
|
return candidates;
|
||||||
};
|
};
|
||||||
var getCandidatesIteratively = function getCandidatesIteratively2(elements, includeContainer, options) {
|
var _getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
|
||||||
var candidates = [];
|
var candidates = [];
|
||||||
var elementsToCheck = Array.from(elements);
|
var elementsToCheck = Array.from(elements);
|
||||||
while (elementsToCheck.length) {
|
while (elementsToCheck.length) {
|
||||||
var element = elementsToCheck.shift();
|
var element = elementsToCheck.shift();
|
||||||
if (isInert(element, false)) {
|
if (_isInert(element, false)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (element.tagName === "SLOT") {
|
if (element.tagName === "SLOT") {
|
||||||
var assigned = element.assignedElements();
|
var assigned = element.assignedElements();
|
||||||
var content = assigned.length ? assigned : element.children;
|
var content = assigned.length ? assigned : element.children;
|
||||||
var nestedCandidates = getCandidatesIteratively2(content, true, options);
|
var nestedCandidates = _getCandidatesIteratively(content, true, options);
|
||||||
if (options.flatten) {
|
if (options.flatten) {
|
||||||
candidates.push.apply(candidates, nestedCandidates);
|
candidates.push.apply(candidates, nestedCandidates);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -72,9 +78,9 @@ var getCandidatesIteratively = function getCandidatesIteratively2(elements, incl
|
||||||
}
|
}
|
||||||
var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
|
var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
|
||||||
typeof options.getShadowRoot === "function" && options.getShadowRoot(element);
|
typeof options.getShadowRoot === "function" && options.getShadowRoot(element);
|
||||||
var validShadowRoot = !isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
|
var validShadowRoot = !_isInert(shadowRoot, false) && (!options.shadowRootFilter || options.shadowRootFilter(element));
|
||||||
if (shadowRoot && validShadowRoot) {
|
if (shadowRoot && validShadowRoot) {
|
||||||
var _nestedCandidates = getCandidatesIteratively2(shadowRoot === true ? element.children : shadowRoot.children, true, options);
|
var _nestedCandidates = _getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
|
||||||
if (options.flatten) {
|
if (options.flatten) {
|
||||||
candidates.push.apply(candidates, _nestedCandidates);
|
candidates.push.apply(candidates, _nestedCandidates);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -184,6 +190,24 @@ var isZeroArea = function isZeroArea2(node) {
|
||||||
};
|
};
|
||||||
var isHidden = function isHidden2(node, _ref) {
|
var isHidden = function isHidden2(node, _ref) {
|
||||||
var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot;
|
var displayCheck = _ref.displayCheck, getShadowRoot = _ref.getShadowRoot;
|
||||||
|
if (displayCheck === "full-native") {
|
||||||
|
if ("checkVisibility" in node) {
|
||||||
|
var visible = node.checkVisibility({
|
||||||
|
// Checking opacity might be desirable for some use cases, but natively,
|
||||||
|
// opacity zero elements _are_ focusable and tabbable.
|
||||||
|
checkOpacity: false,
|
||||||
|
opacityProperty: false,
|
||||||
|
contentVisibilityAuto: true,
|
||||||
|
visibilityProperty: true,
|
||||||
|
// This is an alias for `visibilityProperty`. Contemporary browsers
|
||||||
|
// support both. However, this alias has wider browser support (Chrome
|
||||||
|
// >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so
|
||||||
|
// we include it anyway.
|
||||||
|
checkVisibilityCSS: true
|
||||||
|
});
|
||||||
|
return !visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (getComputedStyle(node).visibility === "hidden") {
|
if (getComputedStyle(node).visibility === "hidden") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -192,7 +216,9 @@ var isHidden = function isHidden2(node, _ref) {
|
||||||
if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
|
if (matches.call(nodeUnderDetails, "details:not([open]) *")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!displayCheck || displayCheck === "full" || displayCheck === "legacy-full") {
|
if (!displayCheck || displayCheck === "full" || // full-native can run this branch when it falls through in case
|
||||||
|
// Element#checkVisibility is unsupported
|
||||||
|
displayCheck === "full-native" || displayCheck === "legacy-full") {
|
||||||
if (typeof getShadowRoot === "function") {
|
if (typeof getShadowRoot === "function") {
|
||||||
var originalNode = node;
|
var originalNode = node;
|
||||||
while (node) {
|
while (node) {
|
||||||
|
|
@ -240,10 +266,7 @@ var isDisabledFromFieldset = function isDisabledFromFieldset2(node) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
|
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2(options, node) {
|
||||||
if (node.disabled || // we must do an inert look up to filter out any elements inside an inert ancestor
|
if (node.disabled || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
|
||||||
// because we're limited in the type of selectors we can use in JSDom (see related
|
|
||||||
// note related to `candidateSelectors`)
|
|
||||||
isInert(node) || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
|
|
||||||
isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
|
isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -255,21 +278,21 @@ var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2(op
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
var isValidShadowRootTabbable = function isValidShadowRootTabbable2(shadowHostNode) {
|
var isShadowRootTabbable = function isShadowRootTabbable2(shadowHostNode) {
|
||||||
var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
|
var tabIndex = parseInt(shadowHostNode.getAttribute("tabindex"), 10);
|
||||||
if (isNaN(tabIndex) || tabIndex >= 0) {
|
if (isNaN(tabIndex) || tabIndex >= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
var sortByOrder = function sortByOrder2(candidates) {
|
var _sortByOrder = function sortByOrder(candidates) {
|
||||||
var regularTabbables = [];
|
var regularTabbables = [];
|
||||||
var orderedTabbables = [];
|
var orderedTabbables = [];
|
||||||
candidates.forEach(function(item, i) {
|
candidates.forEach(function(item, i) {
|
||||||
var isScope = !!item.scopeParent;
|
var isScope = !!item.scopeParent;
|
||||||
var element = isScope ? item.scopeParent : item;
|
var element = isScope ? item.scopeParent : item;
|
||||||
var candidateTabindex = getSortOrderTabIndex(element, isScope);
|
var candidateTabindex = getSortOrderTabIndex(element, isScope);
|
||||||
var elements = isScope ? sortByOrder2(item.candidates) : element;
|
var elements = isScope ? _sortByOrder(item.candidates) : element;
|
||||||
if (candidateTabindex === 0) {
|
if (candidateTabindex === 0) {
|
||||||
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
|
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -291,22 +314,22 @@ var tabbable = function tabbable2(container, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var candidates;
|
var candidates;
|
||||||
if (options.getShadowRoot) {
|
if (options.getShadowRoot) {
|
||||||
candidates = getCandidatesIteratively([container], options.includeContainer, {
|
candidates = _getCandidatesIteratively([container], options.includeContainer, {
|
||||||
filter: isNodeMatchingSelectorTabbable.bind(null, options),
|
filter: isNodeMatchingSelectorTabbable.bind(null, options),
|
||||||
flatten: false,
|
flatten: false,
|
||||||
getShadowRoot: options.getShadowRoot,
|
getShadowRoot: options.getShadowRoot,
|
||||||
shadowRootFilter: isValidShadowRootTabbable
|
shadowRootFilter: isShadowRootTabbable
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
|
candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
|
||||||
}
|
}
|
||||||
return sortByOrder(candidates);
|
return _sortByOrder(candidates);
|
||||||
};
|
};
|
||||||
var focusable = function focusable2(container, options) {
|
var focusable = function focusable2(container, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var candidates;
|
var candidates;
|
||||||
if (options.getShadowRoot) {
|
if (options.getShadowRoot) {
|
||||||
candidates = getCandidatesIteratively([container], options.includeContainer, {
|
candidates = _getCandidatesIteratively([container], options.includeContainer, {
|
||||||
filter: isNodeMatchingSelectorFocusable.bind(null, options),
|
filter: isNodeMatchingSelectorFocusable.bind(null, options),
|
||||||
flatten: true,
|
flatten: true,
|
||||||
getShadowRoot: options.getShadowRoot
|
getShadowRoot: options.getShadowRoot
|
||||||
|
|
@ -326,7 +349,7 @@ var isTabbable = function isTabbable2(node, options) {
|
||||||
}
|
}
|
||||||
return isNodeMatchingSelectorTabbable(options, node);
|
return isNodeMatchingSelectorTabbable(options, node);
|
||||||
};
|
};
|
||||||
var focusableCandidateSelector = candidateSelectors.concat("iframe").join(",");
|
var focusableCandidateSelector = candidateSelectors.concat("iframe:not([inert]):not([inert] *)").join(",");
|
||||||
var isFocusable = function isFocusable2(node, options) {
|
var isFocusable = function isFocusable2(node, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
|
@ -339,6 +362,74 @@ var isFocusable = function isFocusable2(node, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// node_modules/focus-trap/dist/focus-trap.esm.js
|
// node_modules/focus-trap/dist/focus-trap.esm.js
|
||||||
|
function _arrayLikeToArray(r, a) {
|
||||||
|
(null == a || a > r.length) && (a = r.length);
|
||||||
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
function _arrayWithoutHoles(r) {
|
||||||
|
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
||||||
|
}
|
||||||
|
function _createForOfIteratorHelper(r, e) {
|
||||||
|
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
||||||
|
if (!t) {
|
||||||
|
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
|
||||||
|
t && (r = t);
|
||||||
|
var n = 0, F = function() {
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
s: F,
|
||||||
|
n: function() {
|
||||||
|
return n >= r.length ? {
|
||||||
|
done: true
|
||||||
|
} : {
|
||||||
|
done: false,
|
||||||
|
value: r[n++]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
e: function(r2) {
|
||||||
|
throw r2;
|
||||||
|
},
|
||||||
|
f: F
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||||
|
}
|
||||||
|
var o, a = true, u = false;
|
||||||
|
return {
|
||||||
|
s: function() {
|
||||||
|
t = t.call(r);
|
||||||
|
},
|
||||||
|
n: function() {
|
||||||
|
var r2 = t.next();
|
||||||
|
return a = r2.done, r2;
|
||||||
|
},
|
||||||
|
e: function(r2) {
|
||||||
|
u = true, o = r2;
|
||||||
|
},
|
||||||
|
f: function() {
|
||||||
|
try {
|
||||||
|
a || null == t.return || t.return();
|
||||||
|
} finally {
|
||||||
|
if (u) throw o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function _defineProperty(e, r, t) {
|
||||||
|
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
||||||
|
value: t,
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
writable: true
|
||||||
|
}) : e[r] = t, e;
|
||||||
|
}
|
||||||
|
function _iterableToArray(r) {
|
||||||
|
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
||||||
|
}
|
||||||
|
function _nonIterableSpread() {
|
||||||
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||||||
|
}
|
||||||
function ownKeys(e, r) {
|
function ownKeys(e, r) {
|
||||||
var t = Object.keys(e);
|
var t = Object.keys(e);
|
||||||
if (Object.getOwnPropertySymbols) {
|
if (Object.getOwnPropertySymbols) {
|
||||||
|
|
@ -360,43 +451,43 @@ function _objectSpread2(e) {
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
function _defineProperty(obj, key, value) {
|
function _toConsumableArray(r) {
|
||||||
key = _toPropertyKey(key);
|
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
||||||
if (key in obj) {
|
|
||||||
Object.defineProperty(obj, key, {
|
|
||||||
value,
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
writable: true
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
obj[key] = value;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
function _toPrimitive(input, hint) {
|
function _toPrimitive(t, r) {
|
||||||
if (typeof input !== "object" || input === null)
|
if ("object" != typeof t || !t) return t;
|
||||||
return input;
|
var e = t[Symbol.toPrimitive];
|
||||||
var prim = input[Symbol.toPrimitive];
|
if (void 0 !== e) {
|
||||||
if (prim !== void 0) {
|
var i = e.call(t, r);
|
||||||
var res = prim.call(input, hint || "default");
|
if ("object" != typeof i) return i;
|
||||||
if (typeof res !== "object")
|
|
||||||
return res;
|
|
||||||
throw new TypeError("@@toPrimitive must return a primitive value.");
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
||||||
}
|
}
|
||||||
return (hint === "string" ? String : Number)(input);
|
return ("string" === r ? String : Number)(t);
|
||||||
}
|
}
|
||||||
function _toPropertyKey(arg) {
|
function _toPropertyKey(t) {
|
||||||
var key = _toPrimitive(arg, "string");
|
var i = _toPrimitive(t, "string");
|
||||||
return typeof key === "symbol" ? key : String(key);
|
return "symbol" == typeof i ? i : i + "";
|
||||||
|
}
|
||||||
|
function _unsupportedIterableToArray(r, a) {
|
||||||
|
if (r) {
|
||||||
|
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
||||||
|
var t = {}.toString.call(r).slice(8, -1);
|
||||||
|
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var activeFocusTraps = {
|
var activeFocusTraps = {
|
||||||
|
// Returns the trap from the top of the stack.
|
||||||
|
getActiveTrap: function getActiveTrap(trapStack) {
|
||||||
|
if ((trapStack === null || trapStack === void 0 ? void 0 : trapStack.length) > 0) {
|
||||||
|
return trapStack[trapStack.length - 1];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
// Pauses the currently active trap, then adds a new trap to the stack.
|
||||||
activateTrap: function activateTrap(trapStack, trap) {
|
activateTrap: function activateTrap(trapStack, trap) {
|
||||||
if (trapStack.length > 0) {
|
var activeTrap = activeFocusTraps.getActiveTrap(trapStack);
|
||||||
var activeTrap = trapStack[trapStack.length - 1];
|
if (trap !== activeTrap) {
|
||||||
if (activeTrap !== trap) {
|
activeFocusTraps.pauseTrap(trapStack);
|
||||||
activeTrap.pause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var trapIndex = trapStack.indexOf(trap);
|
var trapIndex = trapStack.indexOf(trap);
|
||||||
if (trapIndex === -1) {
|
if (trapIndex === -1) {
|
||||||
|
|
@ -406,13 +497,24 @@ var activeFocusTraps = {
|
||||||
trapStack.push(trap);
|
trapStack.push(trap);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Removes the trap from the top of the stack, then unpauses the next trap down.
|
||||||
deactivateTrap: function deactivateTrap(trapStack, trap) {
|
deactivateTrap: function deactivateTrap(trapStack, trap) {
|
||||||
var trapIndex = trapStack.indexOf(trap);
|
var trapIndex = trapStack.indexOf(trap);
|
||||||
if (trapIndex !== -1) {
|
if (trapIndex !== -1) {
|
||||||
trapStack.splice(trapIndex, 1);
|
trapStack.splice(trapIndex, 1);
|
||||||
}
|
}
|
||||||
if (trapStack.length > 0) {
|
activeFocusTraps.unpauseTrap(trapStack);
|
||||||
trapStack[trapStack.length - 1].unpause();
|
},
|
||||||
|
// Pauses the trap at the top of the stack.
|
||||||
|
pauseTrap: function pauseTrap(trapStack) {
|
||||||
|
var activeTrap = activeFocusTraps.getActiveTrap(trapStack);
|
||||||
|
activeTrap === null || activeTrap === void 0 || activeTrap._setPausedState(true);
|
||||||
|
},
|
||||||
|
// Unpauses the trap at the top of the stack.
|
||||||
|
unpauseTrap: function unpauseTrap(trapStack) {
|
||||||
|
var activeTrap = activeFocusTraps.getActiveTrap(trapStack);
|
||||||
|
if (activeTrap && !activeTrap._isManuallyPaused()) {
|
||||||
|
activeTrap._setPausedState(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -434,17 +536,6 @@ var isKeyBackward = function isKeyBackward2(e) {
|
||||||
var delay = function delay2(fn) {
|
var delay = function delay2(fn) {
|
||||||
return setTimeout(fn, 0);
|
return setTimeout(fn, 0);
|
||||||
};
|
};
|
||||||
var findIndex = function findIndex2(arr, fn) {
|
|
||||||
var idx = -1;
|
|
||||||
arr.every(function(value, i) {
|
|
||||||
if (fn(value)) {
|
|
||||||
idx = i;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
return idx;
|
|
||||||
};
|
|
||||||
var valueOrHandler = function valueOrHandler2(value) {
|
var valueOrHandler = function valueOrHandler2(value) {
|
||||||
for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||||
params[_key - 1] = arguments[_key];
|
params[_key - 1] = arguments[_key];
|
||||||
|
|
@ -462,29 +553,31 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
returnFocusOnDeactivate: true,
|
returnFocusOnDeactivate: true,
|
||||||
escapeDeactivates: true,
|
escapeDeactivates: true,
|
||||||
delayInitialFocus: true,
|
delayInitialFocus: true,
|
||||||
|
isolateSubtrees: false,
|
||||||
isKeyForward,
|
isKeyForward,
|
||||||
isKeyBackward
|
isKeyBackward
|
||||||
}, userOptions);
|
}, userOptions);
|
||||||
var state = {
|
var state = {
|
||||||
// containers given to createFocusTrap()
|
// containers given to createFocusTrap()
|
||||||
// @type {Array<HTMLElement>}
|
/** @type {Array<HTMLElement>} */
|
||||||
containers: [],
|
containers: [],
|
||||||
// list of objects identifying tabbable nodes in `containers` in the trap
|
// list of objects identifying tabbable nodes in `containers` in the trap
|
||||||
// NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
|
// NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
|
||||||
// is active, but the trap should never get to a state where there isn't at least one group
|
// is active, but the trap should never get to a state where there isn't at least one group
|
||||||
// with at least one tabbable node in it (that would lead to an error condition that would
|
// with at least one tabbable node in it (that would lead to an error condition that would
|
||||||
// result in an error being thrown)
|
// result in an error being thrown)
|
||||||
// @type {Array<{
|
/** @type {Array<{
|
||||||
// container: HTMLElement,
|
* container: HTMLElement,
|
||||||
// tabbableNodes: Array<HTMLElement>, // empty if none
|
* tabbableNodes: Array<HTMLElement>, // empty if none
|
||||||
// focusableNodes: Array<HTMLElement>, // empty if none
|
* focusableNodes: Array<HTMLElement>, // empty if none
|
||||||
// posTabIndexesFound: boolean,
|
* posTabIndexesFound: boolean,
|
||||||
// firstTabbableNode: HTMLElement|undefined,
|
* firstTabbableNode: HTMLElement|undefined,
|
||||||
// lastTabbableNode: HTMLElement|undefined,
|
* lastTabbableNode: HTMLElement|undefined,
|
||||||
// firstDomTabbableNode: HTMLElement|undefined,
|
* firstDomTabbableNode: HTMLElement|undefined,
|
||||||
// lastDomTabbableNode: HTMLElement|undefined,
|
* lastDomTabbableNode: HTMLElement|undefined,
|
||||||
// nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
|
* nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
|
||||||
// }>}
|
* }>}
|
||||||
|
*/
|
||||||
containerGroups: [],
|
containerGroups: [],
|
||||||
// same order/length as `containers` list
|
// same order/length as `containers` list
|
||||||
// references to objects in `containerGroups`, but only those that actually have
|
// references to objects in `containerGroups`, but only those that actually have
|
||||||
|
|
@ -492,10 +585,17 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
// NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
|
// NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
|
||||||
// the same length
|
// the same length
|
||||||
tabbableGroups: [],
|
tabbableGroups: [],
|
||||||
|
// references to nodes that are siblings to the ancestors of this trap's containers.
|
||||||
|
/** @type {Set<HTMLElement>} */
|
||||||
|
adjacentElements: /* @__PURE__ */ new Set(),
|
||||||
|
// references to nodes that were inert or aria-hidden before the trap was activated.
|
||||||
|
/** @type {Set<HTMLElement>} */
|
||||||
|
alreadySilent: /* @__PURE__ */ new Set(),
|
||||||
nodeFocusedBeforeActivation: null,
|
nodeFocusedBeforeActivation: null,
|
||||||
mostRecentlyFocusedNode: null,
|
mostRecentlyFocusedNode: null,
|
||||||
active: false,
|
active: false,
|
||||||
paused: false,
|
paused: false,
|
||||||
|
manuallyPaused: false,
|
||||||
// timer ID for when delayInitialFocus is true and initial focus in this trap
|
// timer ID for when delayInitialFocus is true and initial focus in this trap
|
||||||
// has been delayed during activation
|
// has been delayed during activation
|
||||||
delayInitialFocusTimer: void 0,
|
delayInitialFocusTimer: void 0,
|
||||||
|
|
@ -520,12 +620,10 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var getNodeForOption = function getNodeForOption2(optionName) {
|
var getNodeForOption = function getNodeForOption2(optionName) {
|
||||||
|
var _ref2 = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}, _ref2$hasFallback = _ref2.hasFallback, hasFallback = _ref2$hasFallback === void 0 ? false : _ref2$hasFallback, _ref2$params = _ref2.params, params = _ref2$params === void 0 ? [] : _ref2$params;
|
||||||
var optionValue = config[optionName];
|
var optionValue = config[optionName];
|
||||||
if (typeof optionValue === "function") {
|
if (typeof optionValue === "function") {
|
||||||
for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
optionValue = optionValue.apply(void 0, _toConsumableArray(params));
|
||||||
params[_key2 - 1] = arguments[_key2];
|
|
||||||
}
|
|
||||||
optionValue = optionValue.apply(void 0, params);
|
|
||||||
}
|
}
|
||||||
if (optionValue === true) {
|
if (optionValue === true) {
|
||||||
optionValue = void 0;
|
optionValue = void 0;
|
||||||
|
|
@ -538,19 +636,27 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
}
|
}
|
||||||
var node = optionValue;
|
var node = optionValue;
|
||||||
if (typeof optionValue === "string") {
|
if (typeof optionValue === "string") {
|
||||||
node = doc.querySelector(optionValue);
|
try {
|
||||||
|
node = doc.querySelector(optionValue);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error("`".concat(optionName, '` appears to be an invalid selector; error="').concat(err.message, '"'));
|
||||||
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
throw new Error("`".concat(optionName, "` as selector refers to no known node"));
|
if (!hasFallback) {
|
||||||
|
throw new Error("`".concat(optionName, "` as selector refers to no known node"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
var getInitialFocusNode = function getInitialFocusNode2() {
|
var getInitialFocusNode = function getInitialFocusNode2() {
|
||||||
var node = getNodeForOption("initialFocus");
|
var node = getNodeForOption("initialFocus", {
|
||||||
|
hasFallback: true
|
||||||
|
});
|
||||||
if (node === false) {
|
if (node === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (node === void 0 || !isFocusable(node, config.tabbableOptions)) {
|
if (node === void 0 || node && !isFocusable(node, config.tabbableOptions)) {
|
||||||
if (findContainerIndex(doc.activeElement) >= 0) {
|
if (findContainerIndex(doc.activeElement) >= 0) {
|
||||||
node = doc.activeElement;
|
node = doc.activeElement;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -558,6 +664,8 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
|
var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode;
|
||||||
node = firstTabbableNode || getNodeForOption("fallbackFocus");
|
node = firstTabbableNode || getNodeForOption("fallbackFocus");
|
||||||
}
|
}
|
||||||
|
} else if (node === null) {
|
||||||
|
node = getNodeForOption("fallbackFocus");
|
||||||
}
|
}
|
||||||
if (!node) {
|
if (!node) {
|
||||||
throw new Error("Your focus-trap needs to have at least one focusable element");
|
throw new Error("Your focus-trap needs to have at least one focusable element");
|
||||||
|
|
@ -637,25 +745,25 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.");
|
throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var getActiveElement = function getActiveElement2(el) {
|
var _getActiveElement = function getActiveElement(el) {
|
||||||
var activeElement = el.activeElement;
|
var activeElement = el.activeElement;
|
||||||
if (!activeElement) {
|
if (!activeElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) {
|
if (activeElement.shadowRoot && activeElement.shadowRoot.activeElement !== null) {
|
||||||
return getActiveElement2(activeElement.shadowRoot);
|
return _getActiveElement(activeElement.shadowRoot);
|
||||||
}
|
}
|
||||||
return activeElement;
|
return activeElement;
|
||||||
};
|
};
|
||||||
var tryFocus = function tryFocus2(node) {
|
var _tryFocus = function tryFocus(node) {
|
||||||
if (node === false) {
|
if (node === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node === getActiveElement(document)) {
|
if (node === _getActiveElement(document)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!node || !node.focus) {
|
if (!node || !node.focus) {
|
||||||
tryFocus2(getInitialFocusNode());
|
_tryFocus(getInitialFocusNode());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node.focus({
|
node.focus({
|
||||||
|
|
@ -667,11 +775,13 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) {
|
var getReturnFocusNode = function getReturnFocusNode2(previousActiveElement) {
|
||||||
var node = getNodeForOption("setReturnFocus", previousActiveElement);
|
var node = getNodeForOption("setReturnFocus", {
|
||||||
|
params: [previousActiveElement]
|
||||||
|
});
|
||||||
return node ? node : node === false ? false : previousActiveElement;
|
return node ? node : node === false ? false : previousActiveElement;
|
||||||
};
|
};
|
||||||
var findNextNavNode = function findNextNavNode2(_ref2) {
|
var findNextNavNode = function findNextNavNode2(_ref3) {
|
||||||
var target = _ref2.target, event = _ref2.event, _ref2$isBackward = _ref2.isBackward, isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward;
|
var target = _ref3.target, event = _ref3.event, _ref3$isBackward = _ref3.isBackward, isBackward = _ref3$isBackward === void 0 ? false : _ref3$isBackward;
|
||||||
target = target || getActualTarget(event);
|
target = target || getActualTarget(event);
|
||||||
updateTabbableNodes();
|
updateTabbableNodes();
|
||||||
var destinationNode = null;
|
var destinationNode = null;
|
||||||
|
|
@ -685,8 +795,8 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
destinationNode = state.tabbableGroups[0].firstTabbableNode;
|
destinationNode = state.tabbableGroups[0].firstTabbableNode;
|
||||||
}
|
}
|
||||||
} else if (isBackward) {
|
} else if (isBackward) {
|
||||||
var startOfGroupIndex = findIndex(state.tabbableGroups, function(_ref3) {
|
var startOfGroupIndex = state.tabbableGroups.findIndex(function(_ref4) {
|
||||||
var firstTabbableNode = _ref3.firstTabbableNode;
|
var firstTabbableNode = _ref4.firstTabbableNode;
|
||||||
return target === firstTabbableNode;
|
return target === firstTabbableNode;
|
||||||
});
|
});
|
||||||
if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
|
if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
|
||||||
|
|
@ -700,8 +810,8 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
destinationNode = containerGroup.nextTabbableNode(target, false);
|
destinationNode = containerGroup.nextTabbableNode(target, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var lastOfGroupIndex = findIndex(state.tabbableGroups, function(_ref4) {
|
var lastOfGroupIndex = state.tabbableGroups.findIndex(function(_ref5) {
|
||||||
var lastTabbableNode = _ref4.lastTabbableNode;
|
var lastTabbableNode = _ref5.lastTabbableNode;
|
||||||
return target === lastTabbableNode;
|
return target === lastTabbableNode;
|
||||||
});
|
});
|
||||||
if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
|
if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
|
||||||
|
|
@ -796,9 +906,9 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (nextNode) {
|
if (nextNode) {
|
||||||
tryFocus(nextNode);
|
_tryFocus(nextNode);
|
||||||
} else {
|
} else {
|
||||||
tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
|
_tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.recentNavEvent = void 0;
|
state.recentNavEvent = void 0;
|
||||||
|
|
@ -814,17 +924,18 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
if (isTabEvent(event)) {
|
if (isTabEvent(event)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
tryFocus(destinationNode);
|
_tryFocus(destinationNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var checkKey = function checkKey2(event) {
|
var checkTabKey = function checkTabKey2(event) {
|
||||||
|
if (config.isKeyForward(event) || config.isKeyBackward(event)) {
|
||||||
|
checkKeyNav(event, config.isKeyBackward(event));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var checkEscapeKey = function checkEscapeKey2(event) {
|
||||||
if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
|
if (isEscapeEvent(event) && valueOrHandler(config.escapeDeactivates, event) !== false) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
trap.deactivate();
|
trap.deactivate();
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (config.isKeyForward(event) || config.isKeyBackward(event)) {
|
|
||||||
checkKeyNav(event, config.isKeyBackward(event));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var checkClick = function checkClick2(e) {
|
var checkClick = function checkClick2(e) {
|
||||||
|
|
@ -847,8 +958,8 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
}
|
}
|
||||||
activeFocusTraps.activateTrap(trapStack, trap);
|
activeFocusTraps.activateTrap(trapStack, trap);
|
||||||
state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function() {
|
state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function() {
|
||||||
tryFocus(getInitialFocusNode());
|
_tryFocus(getInitialFocusNode());
|
||||||
}) : tryFocus(getInitialFocusNode());
|
}) : _tryFocus(getInitialFocusNode());
|
||||||
doc.addEventListener("focusin", checkFocusIn, true);
|
doc.addEventListener("focusin", checkFocusIn, true);
|
||||||
doc.addEventListener("mousedown", checkPointerDown, {
|
doc.addEventListener("mousedown", checkPointerDown, {
|
||||||
capture: true,
|
capture: true,
|
||||||
|
|
@ -862,12 +973,63 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
capture: true,
|
capture: true,
|
||||||
passive: false
|
passive: false
|
||||||
});
|
});
|
||||||
doc.addEventListener("keydown", checkKey, {
|
doc.addEventListener("keydown", checkTabKey, {
|
||||||
capture: true,
|
capture: true,
|
||||||
passive: false
|
passive: false
|
||||||
});
|
});
|
||||||
|
doc.addEventListener("keydown", checkEscapeKey);
|
||||||
return trap;
|
return trap;
|
||||||
};
|
};
|
||||||
|
var collectAdjacentElements = function collectAdjacentElements2(containers) {
|
||||||
|
if (state.active && !state.paused) {
|
||||||
|
trap._setSubtreeIsolation(false);
|
||||||
|
}
|
||||||
|
state.adjacentElements.clear();
|
||||||
|
state.alreadySilent.clear();
|
||||||
|
var containerAncestors = /* @__PURE__ */ new Set();
|
||||||
|
var adjacentElements = /* @__PURE__ */ new Set();
|
||||||
|
var _iterator = _createForOfIteratorHelper(containers), _step;
|
||||||
|
try {
|
||||||
|
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
|
||||||
|
var container = _step.value;
|
||||||
|
containerAncestors.add(container);
|
||||||
|
var insideShadowRoot = typeof ShadowRoot !== "undefined" && container.getRootNode() instanceof ShadowRoot;
|
||||||
|
var current = container;
|
||||||
|
while (current) {
|
||||||
|
containerAncestors.add(current);
|
||||||
|
var parent = current.parentElement;
|
||||||
|
var siblings = [];
|
||||||
|
if (parent) {
|
||||||
|
siblings = parent.children;
|
||||||
|
} else if (!parent && insideShadowRoot) {
|
||||||
|
siblings = current.getRootNode().children;
|
||||||
|
parent = current.getRootNode().host;
|
||||||
|
insideShadowRoot = typeof ShadowRoot !== "undefined" && parent.getRootNode() instanceof ShadowRoot;
|
||||||
|
}
|
||||||
|
var _iterator2 = _createForOfIteratorHelper(siblings), _step2;
|
||||||
|
try {
|
||||||
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
|
||||||
|
var child = _step2.value;
|
||||||
|
adjacentElements.add(child);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator2.e(err);
|
||||||
|
} finally {
|
||||||
|
_iterator2.f();
|
||||||
|
}
|
||||||
|
current = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_iterator.e(err);
|
||||||
|
} finally {
|
||||||
|
_iterator.f();
|
||||||
|
}
|
||||||
|
containerAncestors.forEach(function(el) {
|
||||||
|
adjacentElements["delete"](el);
|
||||||
|
});
|
||||||
|
state.adjacentElements = adjacentElements;
|
||||||
|
};
|
||||||
var removeListeners = function removeListeners2() {
|
var removeListeners = function removeListeners2() {
|
||||||
if (!state.active) {
|
if (!state.active) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -876,7 +1038,8 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
doc.removeEventListener("mousedown", checkPointerDown, true);
|
doc.removeEventListener("mousedown", checkPointerDown, true);
|
||||||
doc.removeEventListener("touchstart", checkPointerDown, true);
|
doc.removeEventListener("touchstart", checkPointerDown, true);
|
||||||
doc.removeEventListener("click", checkClick, true);
|
doc.removeEventListener("click", checkClick, true);
|
||||||
doc.removeEventListener("keydown", checkKey, true);
|
doc.removeEventListener("keydown", checkTabKey, true);
|
||||||
|
doc.removeEventListener("keydown", checkEscapeKey);
|
||||||
return trap;
|
return trap;
|
||||||
};
|
};
|
||||||
var checkDomRemoval = function checkDomRemoval2(mutations) {
|
var checkDomRemoval = function checkDomRemoval2(mutations) {
|
||||||
|
|
@ -887,7 +1050,7 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (isFocusedNodeRemoved) {
|
if (isFocusedNodeRemoved) {
|
||||||
tryFocus(getInitialFocusNode());
|
_tryFocus(getInitialFocusNode());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver(checkDomRemoval) : void 0;
|
var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver(checkDomRemoval) : void 0;
|
||||||
|
|
@ -919,26 +1082,44 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
var onActivate = getOption(activateOptions, "onActivate");
|
var onActivate = getOption(activateOptions, "onActivate");
|
||||||
var onPostActivate = getOption(activateOptions, "onPostActivate");
|
var onPostActivate = getOption(activateOptions, "onPostActivate");
|
||||||
var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap");
|
var checkCanFocusTrap = getOption(activateOptions, "checkCanFocusTrap");
|
||||||
if (!checkCanFocusTrap) {
|
var preexistingTrap = activeFocusTraps.getActiveTrap(trapStack);
|
||||||
updateTabbableNodes();
|
var revertState = false;
|
||||||
|
if (preexistingTrap && !preexistingTrap.paused) {
|
||||||
|
var _preexistingTrap$_set;
|
||||||
|
(_preexistingTrap$_set = preexistingTrap._setSubtreeIsolation) === null || _preexistingTrap$_set === void 0 || _preexistingTrap$_set.call(preexistingTrap, false);
|
||||||
|
revertState = true;
|
||||||
}
|
}
|
||||||
state.active = true;
|
try {
|
||||||
state.paused = false;
|
if (!checkCanFocusTrap) {
|
||||||
state.nodeFocusedBeforeActivation = doc.activeElement;
|
|
||||||
onActivate === null || onActivate === void 0 || onActivate();
|
|
||||||
var finishActivation = function finishActivation2() {
|
|
||||||
if (checkCanFocusTrap) {
|
|
||||||
updateTabbableNodes();
|
updateTabbableNodes();
|
||||||
}
|
}
|
||||||
addListeners();
|
state.active = true;
|
||||||
updateObservedNodes();
|
state.paused = false;
|
||||||
onPostActivate === null || onPostActivate === void 0 || onPostActivate();
|
state.nodeFocusedBeforeActivation = _getActiveElement(doc);
|
||||||
};
|
onActivate === null || onActivate === void 0 || onActivate();
|
||||||
if (checkCanFocusTrap) {
|
var finishActivation = function finishActivation2() {
|
||||||
checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
|
if (checkCanFocusTrap) {
|
||||||
return this;
|
updateTabbableNodes();
|
||||||
|
}
|
||||||
|
addListeners();
|
||||||
|
updateObservedNodes();
|
||||||
|
if (config.isolateSubtrees) {
|
||||||
|
trap._setSubtreeIsolation(true);
|
||||||
|
}
|
||||||
|
onPostActivate === null || onPostActivate === void 0 || onPostActivate();
|
||||||
|
};
|
||||||
|
if (checkCanFocusTrap) {
|
||||||
|
checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
finishActivation();
|
||||||
|
} catch (error) {
|
||||||
|
if (preexistingTrap === activeFocusTraps.getActiveTrap(trapStack) && revertState) {
|
||||||
|
var _preexistingTrap$_set2;
|
||||||
|
(_preexistingTrap$_set2 = preexistingTrap._setSubtreeIsolation) === null || _preexistingTrap$_set2 === void 0 || _preexistingTrap$_set2.call(preexistingTrap, true);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
finishActivation();
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
deactivate: function deactivate(deactivateOptions) {
|
deactivate: function deactivate(deactivateOptions) {
|
||||||
|
|
@ -952,6 +1133,10 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
}, deactivateOptions);
|
}, deactivateOptions);
|
||||||
clearTimeout(state.delayInitialFocusTimer);
|
clearTimeout(state.delayInitialFocusTimer);
|
||||||
state.delayInitialFocusTimer = void 0;
|
state.delayInitialFocusTimer = void 0;
|
||||||
|
if (!state.paused) {
|
||||||
|
trap._setSubtreeIsolation(false);
|
||||||
|
}
|
||||||
|
state.alreadySilent.clear();
|
||||||
removeListeners();
|
removeListeners();
|
||||||
state.active = false;
|
state.active = false;
|
||||||
state.paused = false;
|
state.paused = false;
|
||||||
|
|
@ -965,7 +1150,7 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
var finishDeactivation = function finishDeactivation2() {
|
var finishDeactivation = function finishDeactivation2() {
|
||||||
delay(function() {
|
delay(function() {
|
||||||
if (returnFocus) {
|
if (returnFocus) {
|
||||||
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
_tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
||||||
}
|
}
|
||||||
onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate();
|
onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate();
|
||||||
});
|
});
|
||||||
|
|
@ -978,54 +1163,121 @@ var createFocusTrap = function createFocusTrap2(elements, userOptions) {
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
pause: function pause(pauseOptions) {
|
pause: function pause(pauseOptions) {
|
||||||
if (state.paused || !state.active) {
|
if (!state.active) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
var onPause = getOption(pauseOptions, "onPause");
|
state.manuallyPaused = true;
|
||||||
var onPostPause = getOption(pauseOptions, "onPostPause");
|
return this._setPausedState(true, pauseOptions);
|
||||||
state.paused = true;
|
|
||||||
onPause === null || onPause === void 0 || onPause();
|
|
||||||
removeListeners();
|
|
||||||
updateObservedNodes();
|
|
||||||
onPostPause === null || onPostPause === void 0 || onPostPause();
|
|
||||||
return this;
|
|
||||||
},
|
},
|
||||||
unpause: function unpause(unpauseOptions) {
|
unpause: function unpause(unpauseOptions) {
|
||||||
if (!state.paused || !state.active) {
|
if (!state.active) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
var onUnpause = getOption(unpauseOptions, "onUnpause");
|
state.manuallyPaused = false;
|
||||||
var onPostUnpause = getOption(unpauseOptions, "onPostUnpause");
|
if (trapStack[trapStack.length - 1] !== this) {
|
||||||
state.paused = false;
|
return this;
|
||||||
onUnpause === null || onUnpause === void 0 || onUnpause();
|
}
|
||||||
updateTabbableNodes();
|
return this._setPausedState(false, unpauseOptions);
|
||||||
addListeners();
|
|
||||||
updateObservedNodes();
|
|
||||||
onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause();
|
|
||||||
return this;
|
|
||||||
},
|
},
|
||||||
updateContainerElements: function updateContainerElements(containerElements) {
|
updateContainerElements: function updateContainerElements(containerElements) {
|
||||||
var elementsAsArray = [].concat(containerElements).filter(Boolean);
|
var elementsAsArray = [].concat(containerElements).filter(Boolean);
|
||||||
state.containers = elementsAsArray.map(function(element) {
|
state.containers = elementsAsArray.map(function(element) {
|
||||||
return typeof element === "string" ? doc.querySelector(element) : element;
|
return typeof element === "string" ? doc.querySelector(element) : element;
|
||||||
});
|
});
|
||||||
|
if (config.isolateSubtrees) {
|
||||||
|
collectAdjacentElements(state.containers);
|
||||||
|
}
|
||||||
if (state.active) {
|
if (state.active) {
|
||||||
updateTabbableNodes();
|
updateTabbableNodes();
|
||||||
|
if (config.isolateSubtrees && !state.paused) {
|
||||||
|
trap._setSubtreeIsolation(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateObservedNodes();
|
updateObservedNodes();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Object.defineProperties(trap, {
|
||||||
|
_isManuallyPaused: {
|
||||||
|
value: function value() {
|
||||||
|
return state.manuallyPaused;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_setPausedState: {
|
||||||
|
value: function value(paused, options) {
|
||||||
|
if (state.paused === paused) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
state.paused = paused;
|
||||||
|
if (paused) {
|
||||||
|
var onPause = getOption(options, "onPause");
|
||||||
|
var onPostPause = getOption(options, "onPostPause");
|
||||||
|
onPause === null || onPause === void 0 || onPause();
|
||||||
|
removeListeners();
|
||||||
|
updateObservedNodes();
|
||||||
|
trap._setSubtreeIsolation(false);
|
||||||
|
onPostPause === null || onPostPause === void 0 || onPostPause();
|
||||||
|
} else {
|
||||||
|
var onUnpause = getOption(options, "onUnpause");
|
||||||
|
var onPostUnpause = getOption(options, "onPostUnpause");
|
||||||
|
onUnpause === null || onUnpause === void 0 || onUnpause();
|
||||||
|
trap._setSubtreeIsolation(true);
|
||||||
|
updateTabbableNodes();
|
||||||
|
addListeners();
|
||||||
|
updateObservedNodes();
|
||||||
|
onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_setSubtreeIsolation: {
|
||||||
|
value: function value(isEnabled) {
|
||||||
|
if (config.isolateSubtrees) {
|
||||||
|
state.adjacentElements.forEach(function(el) {
|
||||||
|
var _el$getAttribute;
|
||||||
|
if (isEnabled) {
|
||||||
|
switch (config.isolateSubtrees) {
|
||||||
|
case "aria-hidden":
|
||||||
|
if (el.ariaHidden === "true" || ((_el$getAttribute = el.getAttribute("aria-hidden")) === null || _el$getAttribute === void 0 ? void 0 : _el$getAttribute.toLowerCase()) === "true") {
|
||||||
|
state.alreadySilent.add(el);
|
||||||
|
}
|
||||||
|
el.setAttribute("aria-hidden", "true");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (el.inert || el.hasAttribute("inert")) {
|
||||||
|
state.alreadySilent.add(el);
|
||||||
|
}
|
||||||
|
el.setAttribute("inert", true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (state.alreadySilent.has(el)) ;
|
||||||
|
else {
|
||||||
|
switch (config.isolateSubtrees) {
|
||||||
|
case "aria-hidden":
|
||||||
|
el.removeAttribute("aria-hidden");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
el.removeAttribute("inert");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
trap.updateContainerElements(elements);
|
trap.updateContainerElements(elements);
|
||||||
return trap;
|
return trap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// node_modules/@vueuse/integrations/useFocusTrap.mjs
|
// node_modules/@vueuse/integrations/dist/useFocusTrap-lXZ_YG-8.js
|
||||||
function useFocusTrap(target, options = {}) {
|
function useFocusTrap(target, options = {}) {
|
||||||
let trap;
|
let trap;
|
||||||
const { immediate, ...focusTrapOptions } = options;
|
const { immediate, ...focusTrapOptions } = options;
|
||||||
const hasFocus = ref(false);
|
const hasFocus = shallowRef(false);
|
||||||
const isPaused = ref(false);
|
const isPaused = shallowRef(false);
|
||||||
const activate = (opts) => trap && trap.activate(opts);
|
const activate = (opts) => trap && trap.activate(opts);
|
||||||
const deactivate = (opts) => trap && trap.deactivate(opts);
|
const deactivate = (opts) => trap && trap.deactivate(opts);
|
||||||
const pause = () => {
|
const pause = () => {
|
||||||
|
|
@ -1040,29 +1292,32 @@ function useFocusTrap(target, options = {}) {
|
||||||
isPaused.value = false;
|
isPaused.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
watch(
|
watch(computed(() => {
|
||||||
() => unrefElement(target),
|
return toArray(toValue(target)).map((el) => {
|
||||||
(el) => {
|
const _el = toValue(el);
|
||||||
if (!el)
|
return typeof _el === "string" ? _el : unrefElement(_el);
|
||||||
return;
|
}).filter(notNullish);
|
||||||
trap = createFocusTrap(el, {
|
}), (els) => {
|
||||||
|
if (!els.length) return;
|
||||||
|
if (!trap) {
|
||||||
|
trap = createFocusTrap(els, {
|
||||||
...focusTrapOptions,
|
...focusTrapOptions,
|
||||||
onActivate() {
|
onActivate() {
|
||||||
hasFocus.value = true;
|
hasFocus.value = true;
|
||||||
if (options.onActivate)
|
if (options.onActivate) options.onActivate();
|
||||||
options.onActivate();
|
|
||||||
},
|
},
|
||||||
onDeactivate() {
|
onDeactivate() {
|
||||||
hasFocus.value = false;
|
hasFocus.value = false;
|
||||||
if (options.onDeactivate)
|
if (options.onDeactivate) options.onDeactivate();
|
||||||
options.onDeactivate();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (immediate)
|
if (immediate) activate();
|
||||||
activate();
|
} else {
|
||||||
},
|
const isActive = trap === null || trap === void 0 ? void 0 : trap.active;
|
||||||
{ flush: "post" }
|
trap === null || trap === void 0 || trap.updateContainerElements(els);
|
||||||
);
|
if (!isActive && immediate) activate();
|
||||||
|
}
|
||||||
|
}, { flush: "post" });
|
||||||
tryOnScopeDispose(() => deactivate());
|
tryOnScopeDispose(() => deactivate());
|
||||||
return {
|
return {
|
||||||
hasFocus,
|
hasFocus,
|
||||||
|
|
@ -1076,18 +1331,4 @@ function useFocusTrap(target, options = {}) {
|
||||||
export {
|
export {
|
||||||
useFocusTrap
|
useFocusTrap
|
||||||
};
|
};
|
||||||
/*! Bundled license information:
|
|
||||||
|
|
||||||
tabbable/dist/index.esm.js:
|
|
||||||
(*!
|
|
||||||
* tabbable 6.2.0
|
|
||||||
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
|
||||||
*)
|
|
||||||
|
|
||||||
focus-trap/dist/focus-trap.esm.js:
|
|
||||||
(*!
|
|
||||||
* focus-trap 7.5.4
|
|
||||||
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
|
|
||||||
*)
|
|
||||||
*/
|
|
||||||
//# sourceMappingURL=vitepress___@vueuse_integrations_useFocusTrap.js.map
|
//# sourceMappingURL=vitepress___@vueuse_integrations_useFocusTrap.js.map
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
3331
docs/.vitepress/cache/deps/vitepress___minisearch.js
vendored
3331
docs/.vitepress/cache/deps/vitepress___minisearch.js
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
27
docs/.vitepress/cache/deps/vue.js
vendored
27
docs/.vitepress/cache/deps/vue.js
vendored
|
|
@ -56,12 +56,17 @@ import {
|
||||||
effectScope,
|
effectScope,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
getCurrentScope,
|
getCurrentScope,
|
||||||
|
getCurrentWatcher,
|
||||||
getTransitionRawChildren,
|
getTransitionRawChildren,
|
||||||
guardReactiveProps,
|
guardReactiveProps,
|
||||||
h,
|
h,
|
||||||
handleError,
|
handleError,
|
||||||
hasInjectionContext,
|
hasInjectionContext,
|
||||||
hydrate,
|
hydrate,
|
||||||
|
hydrateOnIdle,
|
||||||
|
hydrateOnInteraction,
|
||||||
|
hydrateOnMediaQuery,
|
||||||
|
hydrateOnVisible,
|
||||||
initCustomFormatter,
|
initCustomFormatter,
|
||||||
initDirectivesForSSR,
|
initDirectivesForSSR,
|
||||||
inject,
|
inject,
|
||||||
|
|
@ -78,6 +83,7 @@ import {
|
||||||
mergeModels,
|
mergeModels,
|
||||||
mergeProps,
|
mergeProps,
|
||||||
nextTick,
|
nextTick,
|
||||||
|
nodeOps,
|
||||||
normalizeClass,
|
normalizeClass,
|
||||||
normalizeProps,
|
normalizeProps,
|
||||||
normalizeStyle,
|
normalizeStyle,
|
||||||
|
|
@ -94,7 +100,9 @@ import {
|
||||||
onServerPrefetch,
|
onServerPrefetch,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
onUpdated,
|
onUpdated,
|
||||||
|
onWatcherCleanup,
|
||||||
openBlock,
|
openBlock,
|
||||||
|
patchProp,
|
||||||
popScopeId,
|
popScopeId,
|
||||||
provide,
|
provide,
|
||||||
proxyRefs,
|
proxyRefs,
|
||||||
|
|
@ -134,9 +142,13 @@ import {
|
||||||
useAttrs,
|
useAttrs,
|
||||||
useCssModule,
|
useCssModule,
|
||||||
useCssVars,
|
useCssVars,
|
||||||
|
useHost,
|
||||||
|
useId,
|
||||||
useModel,
|
useModel,
|
||||||
useSSRContext,
|
useSSRContext,
|
||||||
|
useShadowRoot,
|
||||||
useSlots,
|
useSlots,
|
||||||
|
useTemplateRef,
|
||||||
useTransitionState,
|
useTransitionState,
|
||||||
vModelCheckbox,
|
vModelCheckbox,
|
||||||
vModelDynamic,
|
vModelDynamic,
|
||||||
|
|
@ -158,7 +170,7 @@ import {
|
||||||
withMemo,
|
withMemo,
|
||||||
withModifiers,
|
withModifiers,
|
||||||
withScopeId
|
withScopeId
|
||||||
} from "./chunk-3YS4HNIT.js";
|
} from "./chunk-JLJ73CPZ.js";
|
||||||
export {
|
export {
|
||||||
BaseTransition,
|
BaseTransition,
|
||||||
BaseTransitionPropsValidators,
|
BaseTransitionPropsValidators,
|
||||||
|
|
@ -217,12 +229,17 @@ export {
|
||||||
effectScope,
|
effectScope,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
getCurrentScope,
|
getCurrentScope,
|
||||||
|
getCurrentWatcher,
|
||||||
getTransitionRawChildren,
|
getTransitionRawChildren,
|
||||||
guardReactiveProps,
|
guardReactiveProps,
|
||||||
h,
|
h,
|
||||||
handleError,
|
handleError,
|
||||||
hasInjectionContext,
|
hasInjectionContext,
|
||||||
hydrate,
|
hydrate,
|
||||||
|
hydrateOnIdle,
|
||||||
|
hydrateOnInteraction,
|
||||||
|
hydrateOnMediaQuery,
|
||||||
|
hydrateOnVisible,
|
||||||
initCustomFormatter,
|
initCustomFormatter,
|
||||||
initDirectivesForSSR,
|
initDirectivesForSSR,
|
||||||
inject,
|
inject,
|
||||||
|
|
@ -239,6 +256,7 @@ export {
|
||||||
mergeModels,
|
mergeModels,
|
||||||
mergeProps,
|
mergeProps,
|
||||||
nextTick,
|
nextTick,
|
||||||
|
nodeOps,
|
||||||
normalizeClass,
|
normalizeClass,
|
||||||
normalizeProps,
|
normalizeProps,
|
||||||
normalizeStyle,
|
normalizeStyle,
|
||||||
|
|
@ -255,7 +273,9 @@ export {
|
||||||
onServerPrefetch,
|
onServerPrefetch,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
onUpdated,
|
onUpdated,
|
||||||
|
onWatcherCleanup,
|
||||||
openBlock,
|
openBlock,
|
||||||
|
patchProp,
|
||||||
popScopeId,
|
popScopeId,
|
||||||
provide,
|
provide,
|
||||||
proxyRefs,
|
proxyRefs,
|
||||||
|
|
@ -295,9 +315,13 @@ export {
|
||||||
useAttrs,
|
useAttrs,
|
||||||
useCssModule,
|
useCssModule,
|
||||||
useCssVars,
|
useCssVars,
|
||||||
|
useHost,
|
||||||
|
useId,
|
||||||
useModel,
|
useModel,
|
||||||
useSSRContext,
|
useSSRContext,
|
||||||
|
useShadowRoot,
|
||||||
useSlots,
|
useSlots,
|
||||||
|
useTemplateRef,
|
||||||
useTransitionState,
|
useTransitionState,
|
||||||
vModelCheckbox,
|
vModelCheckbox,
|
||||||
vModelDynamic,
|
vModelDynamic,
|
||||||
|
|
@ -320,4 +344,3 @@ export {
|
||||||
withModifiers,
|
withModifiers,
|
||||||
withScopeId
|
withScopeId
|
||||||
};
|
};
|
||||||
//# sourceMappingURL=vue.js.map
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ function nav() {
|
||||||
{
|
{
|
||||||
text: 'API Reference',
|
text: 'API Reference',
|
||||||
items: [
|
items: [
|
||||||
{ text: '1.0', link: '/api/1.0/warp' }
|
{ text: '1.1', link: '/api/1.1/warp' },
|
||||||
|
{ text: '1.0', link: '/api/1.0/warp' },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -17,6 +18,27 @@ function nav() {
|
||||||
|
|
||||||
function side() {
|
function side() {
|
||||||
return {
|
return {
|
||||||
|
'/api/1.1': [
|
||||||
|
{
|
||||||
|
text: 'API Reference',
|
||||||
|
items: [
|
||||||
|
{ text: 'Warp', link: '/api/1.1/warp' },
|
||||||
|
{
|
||||||
|
text: 'Event',
|
||||||
|
items: [
|
||||||
|
{ text: 'Server', link: '/api/1.1/server' },
|
||||||
|
{ text: 'Client', link: '/api/1.1/client' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Utilities',
|
||||||
|
items: [
|
||||||
|
{ text: 'Buffer', link: '/api/1.1/buffer' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
'/api/1.0': [
|
'/api/1.0': [
|
||||||
{
|
{
|
||||||
text: 'API Reference',
|
text: 'API Reference',
|
||||||
|
|
@ -60,7 +82,7 @@ function side() {
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
title: "Warp",
|
title: "Warp",
|
||||||
description: "Warp - A very-fast & powerful network library for Roblox.",
|
description: "Warp - A rapidly-fast & powerful network library for Roblox.",
|
||||||
lang: 'en-US',
|
lang: 'en-US',
|
||||||
head: [
|
head: [
|
||||||
['link', { rel: 'icon', href: 'favicon.ico' }],
|
['link', { rel: 'icon', href: 'favicon.ico' }],
|
||||||
|
|
|
||||||
13
docs/.vitepress/dist/404.html
vendored
13
docs/.vitepress/dist/404.html
vendored
File diff suppressed because one or more lines are too long
58
docs/.vitepress/dist/api/1.0/client.html
vendored
58
docs/.vitepress/dist/api/1.0/client.html
vendored
File diff suppressed because one or more lines are too long
31
docs/.vitepress/dist/api/1.0/ratelimit.html
vendored
31
docs/.vitepress/dist/api/1.0/ratelimit.html
vendored
File diff suppressed because one or more lines are too long
81
docs/.vitepress/dist/api/1.0/server.html
vendored
81
docs/.vitepress/dist/api/1.0/server.html
vendored
File diff suppressed because one or more lines are too long
23
docs/.vitepress/dist/api/1.0/warp.html
vendored
23
docs/.vitepress/dist/api/1.0/warp.html
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,21 +0,0 @@
|
||||||
import{_ as s,c as i,o as a,U as e}from"./chunks/framework.BouBWMxc.js";const g=JSON.parse('{"title":"Client","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/client.md","filePath":"api/1.0/client.md"}'),t={name:"api/1.0/client.md"},l=e(`<h1 id="client" tabindex="-1">Client <a class="header-anchor" href="#client" aria-label="Permalink to "Client""></a></h1><p>For Client-sided</p><h2 id="client-1" tabindex="-1"><code>.Client</code> <a class="header-anchor" href="#client-1" aria-label="Permalink to "\`.Client\`""></a></h2><p>Create new Warp event.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-WMTa-" id="tab-8fuJBYo" checked="checked"><label for="tab-8fuJBYo">Variable</label><input type="radio" name="group-WMTa-" id="tab-l7wfSlv"><label for="tab-l7wfSlv">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Identifier</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: string</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Remote </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">new</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Remote"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="connect" tabindex="-1"><code>:Connect</code> <a class="header-anchor" href="#connect" aria-label="Permalink to "\`:Connect\`""></a></h2><p>Connect event to receive incoming from server way.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-913OR" id="tab-Xvghcm2" checked="checked"><label for="tab-Xvghcm2">Variable</label><input type="radio" name="group-913OR" id="tab-Qq0qRYq"><label for="tab-Qq0qRYq">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">any) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ()</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(...)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="once" tabindex="-1"><code>:Once</code> <a class="header-anchor" href="#once" aria-label="Permalink to "\`:Once\`""></a></h2><p>This function likely <code>:Connect</code> but it disconnect the event once it fired.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-7bWhj" id="tab-qg9rt4C" checked="checked"><label for="tab-qg9rt4C">Variable</label><input type="radio" name="group-7bWhj" id="tab-wCFNoJJ"><label for="tab-wCFNoJJ">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">any) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ()</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Once</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(...)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="disconnect" tabindex="-1"><code>:Disconnect</code> <a class="header-anchor" href="#disconnect" aria-label="Permalink to "\`:Disconnect\`""></a></h2><p>Disconnect the event connection.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-jhZf-" id="tab-jQIB7cH" checked="checked"><label for="tab-jQIB7cH">Variable</label><input type="radio" name="group-jhZf-" id="tab-f1J_ZR8"><label for="tab-f1J_ZR8">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: string</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> connection </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, ...) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- store the key</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Disconnect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(connection)</span></span></code></pre></div></div></div><h2 id="disconnectall" tabindex="-1"><code>:DisconnectAll</code> <a class="header-anchor" href="#disconnectall" aria-label="Permalink to "\`:DisconnectAll\`""></a></h2><p>Disconnect All the event connection.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">DisconnectAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><h2 id="fire" tabindex="-1"><code>:Fire</code> <a class="header-anchor" href="#fire" aria-label="Permalink to "\`:Fire\`""></a></h2><p>Fire the event to the spesific server with data.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-_QDeh" id="tab-7pHqPfD" checked="checked"><label for="tab-7pHqPfD">Variable</label><input type="radio" name="group-_QDeh" id="tab-iNQzgEZ"><label for="tab-iNQzgEZ">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> reliable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: any</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fire</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Hello World!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>This function have rate limiting it self and configured from server.</p></div><h2 id="invoke" tabindex="-1"><code>:Invoke</code> <a class="header-anchor" href="#invoke" aria-label="Permalink to "\`:Invoke\`""></a></h2><p>Semiliar to <code>:InvokeServer</code>, its for Invoke to a server.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-OUXOZ" id="tab-3ch63Il" checked="checked"><label for="tab-3ch63Il">Variable</label><input type="radio" name="group-OUXOZ" id="tab-T2WBB5b"><label for="tab-T2WBB5b">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> timeout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: number,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: any</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">any)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Request </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Invoke</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Hello World!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>This function is yielded, once it timeout it will return nil.</p></div><h2 id="wait" tabindex="-1"><code>:Wait</code> <a class="header-anchor" href="#wait" aria-label="Permalink to "\`:Wait\`""></a></h2><p>Wait the event being triggered.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Wait</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>This function is yielded, Invoke might also ping this one and also causing error.</p></div><h2 id="destroy" tabindex="-1"><code>:Destroy</code> <a class="header-anchor" href="#destroy" aria-label="Permalink to "\`:Destroy\`""></a></h2><p>Disconnect all connection of event and remove the event from Warp</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Destroy</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div>`,32),n=[l];function p(h,k,d,c,o,r){return a(),i("div",null,n)}const u=s(t,[["render",p]]);export{g as __pageData,u as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as s,c as i,o as a,U as e}from"./chunks/framework.BouBWMxc.js";const g=JSON.parse('{"title":"Client","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/client.md","filePath":"api/1.0/client.md"}'),t={name:"api/1.0/client.md"},l=e("",32),n=[l];function p(h,k,d,c,o,r){return a(),i("div",null,n)}const u=s(t,[["render",p]]);export{g as __pageData,u as default};
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import{_ as i,c as s,o as a,U as e}from"./chunks/framework.BouBWMxc.js";const g=JSON.parse('{"title":"Rate Limit","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/ratelimit.md","filePath":"api/1.0/ratelimit.md"}'),t={name:"api/1.0/ratelimit.md"},n=e(`<h1 id="rate-limit" tabindex="-1">Rate Limit <a class="header-anchor" href="#rate-limit" aria-label="Permalink to "Rate Limit""></a></h1><p>Ratelimit is one of most useful feature.</p><p>( Configured on Server and For Client )</p><h2 id="setup" tabindex="-1"><code>Setup</code> <a class="header-anchor" href="#setup" aria-label="Permalink to "\`Setup\`""></a></h2><p>When creating a event on Server, you can add second argument as table <code>rateLimit</code> to limit the number of times the event can be called and the interval for reset the counter.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-8_4-Q" id="tab-2KM4Z7r" checked="checked"><label for="tab-2KM4Z7r">Server</label><input type="radio" name="group-8_4-Q" id="tab-rBfnYwa"><label for="tab-rBfnYwa">Client</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Server</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Let's make the event have ratelimit with max 50 entrance for 2 seconds.</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Remote </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Remote1"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, {</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> maxEntrance </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 50</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- maximum 50 fires.</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> interval </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- 2 seconds</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">})</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Now the Event RateLimit is configured, and ready to use.</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- No need anything to adds on client side.</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Client</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Remote </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Client</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Remote1"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- The Event will automatic it self for retreiving the rate limit configuration from the server.</span></span></code></pre></div></div></div>`,6),l=[n];function h(p,r,k,d,o,c){return a(),s("div",null,l)}const m=i(t,[["render",h]]);export{g as __pageData,m as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as i,c as s,o as a,U as e}from"./chunks/framework.BouBWMxc.js";const g=JSON.parse('{"title":"Rate Limit","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/ratelimit.md","filePath":"api/1.0/ratelimit.md"}'),t={name:"api/1.0/ratelimit.md"},n=e("",6),l=[n];function h(p,r,k,d,o,c){return a(),s("div",null,l)}const m=i(t,[["render",h]]);export{g as __pageData,m as default};
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import{_ as t,D as n,c as l,m as s,a as i,I as p,U as a,o as h}from"./chunks/framework.BouBWMxc.js";const B=JSON.parse('{"title":"Server","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/server.md","filePath":"api/1.0/server.md"}'),k={name:"api/1.0/server.md"},d=a(`<h1 id="server" tabindex="-1">Server <a class="header-anchor" href="#server" aria-label="Permalink to "Server""></a></h1><p>For Server-sided</p><h2 id="server-1" tabindex="-1"><code>.Server</code> <a class="header-anchor" href="#server-1" aria-label="Permalink to "\`.Server\`""></a></h2><p>Create new Warp event.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-57xOi" id="tab-NGm3bwT" checked="checked"><label for="tab-NGm3bwT">Variable</label><input type="radio" name="group-57xOi" id="tab-xJTaSRi"><label for="tab-xJTaSRi">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Identifier</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: string,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> rateLimit</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> maxEntrance</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: number,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> interval</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: number,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }?</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Remote </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">new</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Remote"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="connect" tabindex="-1"><code>:Connect</code> <a class="header-anchor" href="#connect" aria-label="Permalink to "\`:Connect\`""></a></h2><p>Connect event to receive incoming from client way.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-8yT3f" id="tab-2m4jbXs" checked="checked"><label for="tab-2m4jbXs">Variable</label><input type="radio" name="group-8yT3f" id="tab-jjbAh0p"><label for="tab-jjbAh0p">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> player</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: Player,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">any) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ()</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">): string</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, ...)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="once" tabindex="-1"><code>:Once</code> <a class="header-anchor" href="#once" aria-label="Permalink to "\`:Once\`""></a></h2><p>This function likely <code>:Connect</code> but it disconnect the event once it fired.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-0FKPj" id="tab-zbCqE2v" checked="checked"><label for="tab-zbCqE2v">Variable</label><input type="radio" name="group-0FKPj" id="tab-HOwRQsL"><label for="tab-HOwRQsL">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> player</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: Player,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> callback</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">any) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ()</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Once</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, ...)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="disconnect" tabindex="-1"><code>:Disconnect</code> <a class="header-anchor" href="#disconnect" aria-label="Permalink to "\`:Disconnect\`""></a></h2><p>Disconnect the event connection.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-Xa8q7" id="tab-TtFdp-Z" checked="checked"><label for="tab-TtFdp-Z">Variable</label><input type="radio" name="group-Xa8q7" id="tab-4XTxKsz"><label for="tab-4XTxKsz">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: string</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> connection </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, ...) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- store the key</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Disconnect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(connection)</span></span></code></pre></div></div></div><h2 id="disconnectall" tabindex="-1"><code>:DisconnectAll</code> <a class="header-anchor" href="#disconnectall" aria-label="Permalink to "\`:DisconnectAll\`""></a></h2><p>Disconnect All the event connection.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">DisconnectAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><h2 id="fire" tabindex="-1"><code>:Fire</code> <a class="header-anchor" href="#fire" aria-label="Permalink to "\`:Fire\`""></a></h2><p>Fire the event to a client.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-q2G3p" id="tab-QUgoIAc" checked="checked"><label for="tab-QUgoIAc">Variable</label><input type="radio" name="group-q2G3p" id="tab-SU77jnw"><label for="tab-SU77jnw">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> reliable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> player</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: Player,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: any</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fire</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, player, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Hello World!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div>`,20),r={id:"fires",tabindex:"-1"},o=s("code",null,":Fires",-1),c=s("a",{class:"header-anchor",href:"#fires","aria-label":'Permalink to "`:Fires` <Badge type="tip" text="Server Only" />"'},"",-1),E=a(`<p>Fire the event to all clients.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-54vBg" id="tab-uI0eydK" checked="checked"><label for="tab-uI0eydK">Variable</label><input type="radio" name="group-54vBg" id="tab-JmoxgRU"><label for="tab-JmoxgRU">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> reliable</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: boolean,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: any</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fires</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Hello World!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><h2 id="invoke" tabindex="-1"><code>:Invoke</code> <a class="header-anchor" href="#invoke" aria-label="Permalink to "\`:Invoke\`""></a></h2><p>Semiliar to <code>:InvokeClient</code>, its for Invoke to a client.</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-EVFwh" id="tab-80WyNJk" checked="checked"><label for="tab-80WyNJk">Variable</label><input type="radio" name="group-EVFwh" id="tab-SafarTi"><label for="tab-SafarTi">Example</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> timeout</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: number,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> player</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: Player,</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: any</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">any)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Request </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Invoke</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, player, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Hello World!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div></div></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>This function is yielded, once it timeout it will return nil.</p></div><h2 id="wait" tabindex="-1"><code>:Wait</code> <a class="header-anchor" href="#wait" aria-label="Permalink to "\`:Wait\`""></a></h2><p>Wait the event being triggered.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Wait</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>This function is yielded, Invoke might also ping this one and also causing error.</p></div><h2 id="destroy" tabindex="-1"><code>:Destroy</code> <a class="header-anchor" href="#destroy" aria-label="Permalink to "\`:Destroy\`""></a></h2><p>Disconnect all connection of event and remove the event from Warp.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Destroy</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span></code></pre></div>`,13);function g(y,u,v,b,F,C){const e=n("Badge");return h(),l("div",null,[d,s("h2",r,[o,i(),p(e,{type:"tip",text:"Server Only"}),i(),c]),E])}const f=t(k,[["render",g]]);export{B as __pageData,f as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as t,D as n,c as l,m as s,a as i,I as p,U as a,o as h}from"./chunks/framework.BouBWMxc.js";const B=JSON.parse('{"title":"Server","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/server.md","filePath":"api/1.0/server.md"}'),k={name:"api/1.0/server.md"},d=a("",20),r={id:"fires",tabindex:"-1"},o=s("code",null,":Fires",-1),c=s("a",{class:"header-anchor",href:"#fires","aria-label":'Permalink to "`:Fires` <Badge type="tip" text="Server Only" />"'},"",-1),E=a("",13);function g(y,u,v,b,F,C){const e=n("Badge");return h(),l("div",null,[d,s("h2",r,[o,i(),p(e,{type:"tip",text:"Server Only"}),i(),c]),E])}const f=t(k,[["render",g]]);export{B as __pageData,f as default};
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
import{_ as n,D as p,c as l,m as s,a as e,I as i,U as t,o as r}from"./chunks/framework.BouBWMxc.js";const B=JSON.parse('{"title":"Warp","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/warp.md","filePath":"api/1.0/warp.md"}'),h={name:"api/1.0/warp.md"},o={id:"warp",tabindex:"-1"},d=s("a",{class:"header-anchor",href:"#warp","aria-label":'Permalink to "Warp <Badge type="tip" text="1.0" />"'},"",-1),c=s("p",null,"The public main of the Warp library.",-1),k={id:"server",tabindex:"-1"},_=s("code",null,".Server",-1),E=s("a",{class:"header-anchor",href:"#server","aria-label":'Permalink to "`.Server` <Badge type="tip" text="server side" />"'},"",-1),g=t(`<p>Create a new event for Server-Side</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Server</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Event1 </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Event1"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div>`,2),y={id:"client",tabindex:"-1"},v=s("code",null,".Client",-1),u=s("a",{class:"header-anchor",href:"#client","aria-label":'Permalink to "`.Client` <Badge type="tip" text="client side" />"'},"",-1),C=t(`<p>Create a new event for Client-Side.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Client</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Event1 </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Client</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Event1"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div>`,2);function m(b,S,f,A,F,T){const a=p("Badge");return r(),l("div",null,[s("h1",o,[e("Warp "),i(a,{type:"tip",text:"1.0"}),e(),d]),c,s("h2",k,[_,e(),i(a,{type:"tip",text:"server side"}),e(),E]),g,s("h2",y,[v,e(),i(a,{type:"tip",text:"client side"}),e(),u]),C])}const D=n(h,[["render",m]]);export{B as __pageData,D as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as n,D as p,c as l,m as s,a as e,I as i,U as t,o as r}from"./chunks/framework.BouBWMxc.js";const B=JSON.parse('{"title":"Warp","description":"","frontmatter":{},"headers":[],"relativePath":"api/1.0/warp.md","filePath":"api/1.0/warp.md"}'),h={name:"api/1.0/warp.md"},o={id:"warp",tabindex:"-1"},d=s("a",{class:"header-anchor",href:"#warp","aria-label":'Permalink to "Warp <Badge type="tip" text="1.0" />"'},"",-1),c=s("p",null,"The public main of the Warp library.",-1),k={id:"server",tabindex:"-1"},_=s("code",null,".Server",-1),E=s("a",{class:"header-anchor",href:"#server","aria-label":'Permalink to "`.Server` <Badge type="tip" text="server side" />"'},"",-1),g=t("",2),y={id:"client",tabindex:"-1"},v=s("code",null,".Client",-1),u=s("a",{class:"header-anchor",href:"#client","aria-label":'Permalink to "`.Client` <Badge type="tip" text="client side" />"'},"",-1),C=t("",2);function m(b,S,f,A,F,T){const a=p("Badge");return r(),l("div",null,[s("h1",o,[e("Warp "),i(a,{type:"tip",text:"1.0"}),e(),d]),c,s("h2",k,[_,e(),i(a,{type:"tip",text:"server side"}),e(),E]),g,s("h2",y,[v,e(),i(a,{type:"tip",text:"client side"}),e(),u]),C])}const D=n(h,[["render",m]]);export{B as __pageData,D as default};
|
|
||||||
7
docs/.vitepress/dist/assets/app.hWp2if6e.js
vendored
7
docs/.vitepress/dist/assets/app.hWp2if6e.js
vendored
|
|
@ -1,7 +0,0 @@
|
||||||
import{j as o,a1 as p,a2 as u,a3 as c,a4 as l,a5 as f,a6 as d,a7 as m,a8 as h,a9 as A,aa as g,ab as v,d as P,u as y,l as C,z as w,ac as _,ad as b,ae as E,af as R}from"./chunks/framework.BouBWMxc.js";import{t as D}from"./chunks/theme.makJcAKq.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(D),j=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=y();return C(()=>{w(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&_(),b(),E(),s.setup&&s.setup(),()=>R(s.Layout)}});async function L(){const e=S(),a=O();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function O(){return h(j)}function S(){let e=o,a;return A(t=>{let n=g(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=v(()=>import(n),__vite__mapDeps([]))),o&&(e=!1),r},s.NotFound)}o&&L().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{L as createApp};
|
|
||||||
function __vite__mapDeps(indexes) {
|
|
||||||
if (!__vite__mapDeps.viteFileDeps) {
|
|
||||||
__vite__mapDeps.viteFileDeps = []
|
|
||||||
}
|
|
||||||
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,59 +0,0 @@
|
||||||
import{_ as s,c as i,o as a,U as n}from"./chunks/framework.BouBWMxc.js";const F=JSON.parse('{"title":"Example","description":"","frontmatter":{},"headers":[],"relativePath":"guide/example.md","filePath":"guide/example.md"}'),h={name:"guide/example.md"},l=n(`<h1 id="example" tabindex="-1">Example <a class="header-anchor" href="#example" aria-label="Permalink to "Example""></a></h1><p>Let's try and play something with Warp!</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-t9858" id="tab-019zFZN" checked="checked"><label for="tab-019zFZN">Server</label><input type="radio" name="group-t9858" id="tab-QUEGMRD"><label for="tab-QUEGMRD">Client</label></div><div class="blocks"><div class="language-lua vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"path.to.module"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Events</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Example </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Example"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Ping </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Ping"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Pong </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Pong"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PingAll </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"PingAll"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Example</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, arg1, arg2)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(arg1, arg2)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "Whooo!"</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Ping</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player, ping)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ping </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">then</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"PING!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Pong</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fire</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, player, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"pong!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> PingAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fires</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"ey!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> end</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Players </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> game</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GetService</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Players"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"path.to.module"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Events</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Example </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Client</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Example"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Ping </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Client</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Ping"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Pong </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Client</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Pong"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> PingAll </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Client</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"PingAll"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Connect the events</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> connection1</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">connection1 </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Pong</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(pong: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> pong </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">then</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"PONG!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> end</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">PingAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(isPing: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">boolean</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> isPing </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">then</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"I GET PINGED!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> end</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Try request a event from server!</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">print</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Example</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Invoke</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Hello!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"this is from > "</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">..</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Players.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">LocalPlayer</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">))</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Do a ping & pong to server!</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Ping</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fire</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"ping!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">task.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">wait</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- lets wait 1 seconds!</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Disconnect All the events</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Pong</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">DisconnectAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">PingAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">DisconnectAll</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- or Just disconnect spesific connection</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Pong</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Disconnect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(connection1)</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Destroying/Deleting a Event?</span></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">Pong</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Destroy</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">()</span></span>
|
|
||||||
<span class="line"></span>
|
|
||||||
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">-- Yay Done!</span></span></code></pre></div></div></div>`,3),k=[l];function p(t,e,E,r,d,g){return a(),i("div",null,k)}const o=s(h,[["render",p]]);export{F as __pageData,o as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as s,c as i,o as a,U as n}from"./chunks/framework.BouBWMxc.js";const F=JSON.parse('{"title":"Example","description":"","frontmatter":{},"headers":[],"relativePath":"guide/example.md","filePath":"guide/example.md"}'),h={name:"guide/example.md"},l=n("",3),k=[l];function p(t,e,E,r,d,g){return a(),i("div",null,k)}const o=s(h,[["render",p]]);export{F as __pageData,o as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as s,c as i,o as a,U as t}from"./chunks/framework.BouBWMxc.js";const c=JSON.parse('{"title":"Getting Started","description":"","frontmatter":{},"headers":[],"relativePath":"guide/getting-started.md","filePath":"guide/getting-started.md"}'),e={name:"guide/getting-started.md"},n=t('<h1 id="getting-started" tabindex="-1">Getting Started <a class="header-anchor" href="#getting-started" aria-label="Permalink to "Getting Started""></a></h1><h3 id="step-1" tabindex="-1"><code>Step 1:</code> <a class="header-anchor" href="#step-1" aria-label="Permalink to "`Step 1:`""></a></h3><p>First, you have to require the Warp module.</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> require</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">'path.to.module'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><h3 id="step-2" tabindex="-1"><code>Step 2:</code> <a class="header-anchor" href="#step-2" aria-label="Permalink to "`Step 2:`""></a></h3><p>Then, to create a new event you have to use <code>.Server</code> function</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Remote </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Warp.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Server</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"EventName"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span></code></pre></div><h3 id="step-3" tabindex="-1"><code>Step 3:</code> <a class="header-anchor" href="#step-3" aria-label="Permalink to "`Step 3:`""></a></h3><p>Firing event everytime player join</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">local</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Players </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> game</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">GetService</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Players"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>\n<span class="line"></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Players.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">PlayerAdded</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Connect</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">function</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(player)</span></span>\n<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> Remote</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">Fire</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, player, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Welcome!"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>\n<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">end</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div>',10),h=[n];function l(p,k,r,d,o,E){return a(),i("div",null,h)}const y=s(e,[["render",l]]);export{c as __pageData,y as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as s,c as i,o as a,U as t}from"./chunks/framework.BouBWMxc.js";const c=JSON.parse('{"title":"Getting Started","description":"","frontmatter":{},"headers":[],"relativePath":"guide/getting-started.md","filePath":"guide/getting-started.md"}'),e={name:"guide/getting-started.md"},n=t("",10),h=[n];function l(p,k,r,d,o,E){return a(),i("div",null,h)}const y=s(e,[["render",l]]);export{c as __pageData,y as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as a,c as e,o as t,U as r}from"./chunks/framework.BouBWMxc.js";const m=JSON.parse('{"title":"Overview","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md"}'),i={name:"guide/index.md"},o=r('<h1 id="overview" tabindex="-1">Overview <a class="header-anchor" href="#overview" aria-label="Permalink to "Overview""></a></h1><p>Warp is a networking library for Roblox that comes with very fast performance and efficient with Type to any-scale games.</p><h2 id="why-warp" tabindex="-1">Why Warp <a class="header-anchor" href="#why-warp" aria-label="Permalink to "Why Warp""></a></h2><h3 id="⚡-performance" tabindex="-1">⚡ Performance <a class="header-anchor" href="#⚡-performance" aria-label="Permalink to "⚡ Performance""></a></h3><p>Warp is very-fast with much less bandwidth compared to native.</p><h3 id="🍃-lightweight" tabindex="-1">🍃 Lightweight <a class="header-anchor" href="#🍃-lightweight" aria-label="Permalink to "🍃 Lightweight""></a></h3><p>Warp is a lightweight library for Roblox.</p><h3 id="📊-task" tabindex="-1">📊 Task <a class="header-anchor" href="#📊-task" aria-label="Permalink to "📊 Task""></a></h3><p>Warp optimized efficient for large-scale task.</p><h3 id="🔎-typing" tabindex="-1">🔎 Typing <a class="header-anchor" href="#🔎-typing" aria-label="Permalink to "🔎 Typing""></a></h3><p>Warp written with strictly-typed.</p>',11),n=[o];function h(s,l,c,d,p,f){return t(),e("div",null,n)}const g=a(i,[["render",h]]);export{m as __pageData,g as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as a,c as e,o as t,U as r}from"./chunks/framework.BouBWMxc.js";const m=JSON.parse('{"title":"Overview","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md"}'),i={name:"guide/index.md"},o=r("",11),n=[o];function h(s,l,c,d,p,f){return t(),e("div",null,n)}const g=a(i,[["render",h]]);export{m as __pageData,g as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as a,c as t,o as l,U as i}from"./chunks/framework.BouBWMxc.js";const k=JSON.parse('{"title":"Installation","description":"","frontmatter":{},"headers":[],"relativePath":"guide/installation.md","filePath":"guide/installation.md"}'),e={name:"guide/installation.md"},o=i('<h1 id="installation" tabindex="-1">Installation <a class="header-anchor" href="#installation" aria-label="Permalink to "Installation""></a></h1><h2 id="with-wally" tabindex="-1"><code>with Wally</code> <a class="header-anchor" href="#with-wally" aria-label="Permalink to "`with Wally`""></a></h2><ol><li>Get Rojo and Wally ready.</li><li>Add Warp to your <code>wally.toml</code>.</li></ol><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-YbSHN" id="tab-IZCWhd1" checked="checked"><label for="tab-IZCWhd1">wally.toml</label></div><div class="blocks"><div class="language-toml vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">toml</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">[</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">dependencies</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>\n<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">warp = </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"imezx/warp@1.0.0"</span></span></code></pre></div><ol start="3"><li>Run <code>wally install</code> in command.</li><li>Link the module and Your Done!</li></ol><h2 id="without-wally" tabindex="-1"><code>without Wally</code> <a class="header-anchor" href="#without-wally" aria-label="Permalink to "`without Wally`""></a></h2><ol><li>Get the <code>.rbxm</code> file from the <a href="https://github.com/imezx/Warp" target="_blank" rel="noreferrer">github</a></li><li>Import the <code>.rbxm</code> file into roblox studio manually and Done!</li></ol></div></div>',4),s=[o];function n(d,r,h,c,p,u){return l(),t("div",null,s)}const _=a(e,[["render",n]]);export{k as __pageData,_ as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as a,c as t,o as l,U as i}from"./chunks/framework.BouBWMxc.js";const k=JSON.parse('{"title":"Installation","description":"","frontmatter":{},"headers":[],"relativePath":"guide/installation.md","filePath":"guide/installation.md"}'),e={name:"guide/installation.md"},o=i("",4),s=[o];function n(d,r,h,c,p,u){return l(),t("div",null,s)}const _=a(e,[["render",n]]);export{k as __pageData,_ as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as e,c as t,o as i}from"./chunks/framework.BouBWMxc.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"image":{"src":"/warp.png"},"name":"Warp","text":"A very-fast & powerful networking library for Roblox.","actions":[{"theme":"brand","text":"Get Started","link":"/guide/"},{"theme":"alt","text":"API Reference","link":"/api/1.0/warp"},{"theme":"alt","text":"View on Github","link":"https://github.com/imezx/Warp"}]},"features":[{"icon":"⚡","title":"Performance","details":"Warp is very-fast with much less bandwidth compared to native."},{"icon":"🍃","title":"Lightweight","details":"Warp is a lightweight library for Roblox."},{"icon":"📊","title":"Task","details":"Warp optimized efficient for large-scale task."},{"icon":"🔎","title":"Type","details":"Warp written with strictly-typed."}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),a={name:"index.md"};function r(o,n,s,l,c,p){return i(),t("div")}const h=e(a,[["render",r]]);export{m as __pageData,h as default};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{_ as e,c as t,o as i}from"./chunks/framework.BouBWMxc.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"image":{"src":"/warp.png"},"name":"Warp","text":"A very-fast & powerful networking library for Roblox.","actions":[{"theme":"brand","text":"Get Started","link":"/guide/"},{"theme":"alt","text":"API Reference","link":"/api/1.0/warp"},{"theme":"alt","text":"View on Github","link":"https://github.com/imezx/Warp"}]},"features":[{"icon":"⚡","title":"Performance","details":"Warp is very-fast with much less bandwidth compared to native."},{"icon":"🍃","title":"Lightweight","details":"Warp is a lightweight library for Roblox."},{"icon":"📊","title":"Task","details":"Warp optimized efficient for large-scale task."},{"icon":"🔎","title":"Type","details":"Warp written with strictly-typed."}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),a={name:"index.md"};function r(o,n,s,l,c,p){return i(),t("div")}const h=e(a,[["render",r]]);export{m as __pageData,h as default};
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
23
docs/.vitepress/dist/guide/example.html
vendored
23
docs/.vitepress/dist/guide/example.html
vendored
File diff suppressed because one or more lines are too long
21
docs/.vitepress/dist/guide/getting-started.html
vendored
21
docs/.vitepress/dist/guide/getting-started.html
vendored
File diff suppressed because one or more lines are too long
19
docs/.vitepress/dist/guide/index.html
vendored
19
docs/.vitepress/dist/guide/index.html
vendored
File diff suppressed because one or more lines are too long
21
docs/.vitepress/dist/guide/installation.html
vendored
21
docs/.vitepress/dist/guide/installation.html
vendored
File diff suppressed because one or more lines are too long
2
docs/.vitepress/dist/hashmap.json
vendored
2
docs/.vitepress/dist/hashmap.json
vendored
|
|
@ -1 +1 @@
|
||||||
{"index.md":"Wvz5TWej","guide_getting-started.md":"MBXKETNI","guide_installation.md":"fMU35fgi","api_1.0_warp.md":"u63PLmMH","guide_index.md":"xfhCFaBM","api_1.0_server.md":"w4zn1XZZ","guide_example.md":"7eqi7edp","api_1.0_ratelimit.md":"gPb2PQ91","api_1.0_client.md":"FTim0Kz_"}
|
{"api_1.0_client.md":"DRlZL-Eb","api_1.0_ratelimit.md":"B4DFbcsX","api_1.0_server.md":"CjXNePVa","api_1.0_signal.md":"CSgtTcPk","api_1.0_warp.md":"Cc-7zjkV","api_1.1_buffer.md":"DIAM2o2w","api_1.1_client.md":"etzsFUJB","api_1.1_server.md":"yCvitiyi","api_1.1_warp.md":"D17D2VRV","guide_example.md":"35KFEfAU","guide_getting-started.md":"BJOTFozK","guide_index.md":"CZXHfmOy","guide_installation.md":"D6zv1RV7","index.md":"U4jwmyV2"}
|
||||||
|
|
|
||||||
BIN
docs/.vitepress/dist/header.png
vendored
BIN
docs/.vitepress/dist/header.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
19
docs/.vitepress/dist/index.html
vendored
19
docs/.vitepress/dist/index.html
vendored
File diff suppressed because one or more lines are too long
167
docs/.vitepress/theme/components/Typewriter.vue
Normal file
167
docs/.vitepress/theme/components/Typewriter.vue
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
<template>
|
||||||
|
<div class="hero-container">
|
||||||
|
<h1 v-if="staticTitle" class="hero-title">
|
||||||
|
{{ staticTitle }}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div class="typewriter-wrapper">
|
||||||
|
<p class="typewriter-text" aria-label="Animated hero text">
|
||||||
|
{{ displayedText }}<span class="cursor">|</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
staticTitle?: string
|
||||||
|
words?: string[]
|
||||||
|
typeSpeed?: number
|
||||||
|
deleteSpeed?: number
|
||||||
|
delay?: number
|
||||||
|
}>(), {
|
||||||
|
staticTitle: 'Warp',
|
||||||
|
words: () => [
|
||||||
|
'Rapidly-fast networking.',
|
||||||
|
'Remarkably simple.',
|
||||||
|
'It feels so powerful.',
|
||||||
|
'Type-safe and lightweight.',
|
||||||
|
'Tired of defining schemas?',
|
||||||
|
'Just use Warp.',
|
||||||
|
],
|
||||||
|
typeSpeed: 50,
|
||||||
|
deleteSpeed: 20,
|
||||||
|
delay: 2000
|
||||||
|
})
|
||||||
|
|
||||||
|
const displayedText = ref('')
|
||||||
|
const currentWordIndex = ref(0)
|
||||||
|
const isDeleting = ref(false)
|
||||||
|
let typingTimeout: any = null
|
||||||
|
|
||||||
|
const typeLoop = () => {
|
||||||
|
const currentWord = props.words[currentWordIndex.value]
|
||||||
|
|
||||||
|
let currentSpeed = props.typeSpeed
|
||||||
|
|
||||||
|
if (isDeleting.value) {
|
||||||
|
displayedText.value = currentWord.substring(0, displayedText.value.length - 1)
|
||||||
|
currentSpeed = props.deleteSpeed
|
||||||
|
} else {
|
||||||
|
displayedText.value = currentWord.substring(0, displayedText.value.length + 1)
|
||||||
|
currentSpeed = props.typeSpeed
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDeleting.value && displayedText.value === currentWord) {
|
||||||
|
currentSpeed = props.delay
|
||||||
|
isDeleting.value = true
|
||||||
|
} else if (isDeleting.value && displayedText.value === '') {
|
||||||
|
isDeleting.value = false
|
||||||
|
currentWordIndex.value = (currentWordIndex.value + 1) % props.words.length
|
||||||
|
currentSpeed = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
typingTimeout = setTimeout(typeLoop, currentSpeed)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
typeLoop()
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearTimeout(typingTimeout)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.hero-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 75px;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -1.5px;
|
||||||
|
|
||||||
|
background: -webkit-linear-gradient(120deg, #fe5234 30%, #fe9934);
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
|
||||||
|
text-shadow: 0 0 40px rgba(254,82,52,.3);
|
||||||
|
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typewriter-wrapper {
|
||||||
|
display: flex;
|
||||||
|
min-height: 120px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typewriter-text {
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 48px;
|
||||||
|
line-height: 1.2;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
color: var(--vp-c-text-1);
|
||||||
|
|
||||||
|
max-width: 800px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 4px;
|
||||||
|
width: 4px;
|
||||||
|
height: 1em;
|
||||||
|
background-color: var(--vp-c-brand-1);
|
||||||
|
animation: blink 1s step-end infinite;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 960px) {
|
||||||
|
.hero-title {
|
||||||
|
font-size: 64px;
|
||||||
|
}
|
||||||
|
.typewriter-text {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.hero-container {
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typewriter-text {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,4 +1,15 @@
|
||||||
import DefaultTheme from 'vitepress/theme'
|
import DefaultTheme from 'vitepress/theme'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import Typewriter from './components/Typewriter.vue'
|
||||||
import './style.css'
|
import './style.css'
|
||||||
|
|
||||||
export default DefaultTheme;
|
export default {
|
||||||
|
extends: DefaultTheme,
|
||||||
|
Layout() {
|
||||||
|
return h(DefaultTheme.Layout, null, {
|
||||||
|
'home-hero-info': () => h(Typewriter, {
|
||||||
|
staticTitle: 'Warp'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,9 +23,25 @@
|
||||||
--vp-c-danger-2: var(--vp-c-red-2);
|
--vp-c-danger-2: var(--vp-c-red-2);
|
||||||
--vp-c-danger-3: var(--vp-c-red-3);
|
--vp-c-danger-3: var(--vp-c-red-3);
|
||||||
--vp-c-danger-soft: var(--vp-c-red-soft);
|
--vp-c-danger-soft: var(--vp-c-red-soft);
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
--glass-nav-bg: rgba(255, 255, 255, 0.7);
|
||||||
|
--glass-sidebar-bg: rgba(255, 255, 255, 0.7);
|
||||||
|
|
||||||
|
--glass-bg: rgba(255, 255, 255, 0.8);
|
||||||
|
--glass-border: rgba(0, 0, 0, 0.08);
|
||||||
|
--glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.08);
|
||||||
|
--glass-shadow-2: 0 6px 24px 0 rgba(0, 0, 0, 0.08);
|
||||||
|
--glass-highlight: inset 0 1px 0 0 rgba(255, 255, 255, 0.6);
|
||||||
|
--glass-blur: 28px;
|
||||||
|
--glass-blur-2: 16px;
|
||||||
|
--glass-blur-3: 24px;
|
||||||
|
--glass-blur-4: 4px;
|
||||||
|
--glass-radius: 24px;
|
||||||
|
--glass-menu-radius: 12px;
|
||||||
|
|
||||||
|
--vp-c-bg: #ffffff;
|
||||||
|
--vp-c-bg-alt: #f8f9fa;
|
||||||
|
|
||||||
--vp-button-brand-border: transparent;
|
--vp-button-brand-border: transparent;
|
||||||
--vp-button-brand-text: var(--vp-c-white);
|
--vp-button-brand-text: var(--vp-c-white);
|
||||||
--vp-button-brand-bg: var(--vp-c-brand-3);
|
--vp-button-brand-bg: var(--vp-c-brand-3);
|
||||||
|
|
@ -35,18 +51,220 @@
|
||||||
--vp-button-brand-active-border: transparent;
|
--vp-button-brand-active-border: transparent;
|
||||||
--vp-button-brand-active-text: var(--vp-c-white);
|
--vp-button-brand-active-text: var(--vp-c-white);
|
||||||
--vp-button-brand-active-bg: var(--vp-c-brand-1);
|
--vp-button-brand-active-bg: var(--vp-c-brand-1);
|
||||||
|
|
||||||
|
--vp-home-hero-name-color: transparent;
|
||||||
|
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #fe5234 30%, #fe9934);
|
||||||
|
--vp-home-hero-image-background-image: linear-gradient(-45deg, #fe5234 50%, #fe9934 50%);
|
||||||
|
--vp-home-hero-image-filter: blur(40px);
|
||||||
|
|
||||||
|
--vp-custom-block-tip-border: transparent;
|
||||||
|
--vp-custom-block-tip-text: var(--vp-c-text-1);
|
||||||
|
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
|
||||||
|
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
.dark {
|
||||||
--vp-home-hero-name-color: transparent;
|
--glass-nav-bg: rgba(22, 22, 24, 0.6);
|
||||||
--vp-home-hero-name-background: -webkit-linear-gradient(120deg,
|
--glass-sidebar-bg: rgba(22, 22, 24, 0.6);
|
||||||
#fe5234 30%,
|
|
||||||
#fe9934);
|
|
||||||
|
|
||||||
--vp-home-hero-image-background-image: linear-gradient(-45deg,
|
--glass-bg: rgba(30, 30, 35, 0.6);
|
||||||
#fe5234 50%,
|
--glass-border: rgba(255, 255, 255, 0.1);
|
||||||
#fe9934 50%);
|
--glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5);
|
||||||
--vp-home-hero-image-filter: blur(40px);
|
--glass-highlight: inset 0 1px 0 0 rgba(255, 255, 255, 0.1);
|
||||||
|
|
||||||
|
--vp-c-bg: #0f0f11;
|
||||||
|
--vp-c-bg-alt: #161618;
|
||||||
|
--vp-c-gutter: rgba(255, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
body::before {
|
||||||
|
content: "";
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: -1;
|
||||||
|
pointer-events: none;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 100% 0%, rgba(254, 82, 52, 0.1), transparent 50%),
|
||||||
|
radial-gradient(circle at 0% 100%, rgba(79, 70, 229, 0.1), transparent 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark body::before {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 90% 10%, rgba(254, 82, 52, 0.15), transparent 60%),
|
||||||
|
radial-gradient(circle at 10% 90%, rgba(79, 70, 229, 0.12), transparent 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNav,
|
||||||
|
.VPLocalNav, .shell, .backdrop {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNavBar,
|
||||||
|
.VPLocalNav {
|
||||||
|
background-color: var(--glass-nav-bg) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
border-bottom: 1px solid var(--glass-border) !important;
|
||||||
|
box-shadow: var(--glass-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNav .content-body,
|
||||||
|
.VPLocalNav.container {
|
||||||
|
background-color: transparent !important;
|
||||||
|
backdrop-filter: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNavScreenAppearance {
|
||||||
|
background-color: transparent !important;
|
||||||
|
backdrop-filter: blur(var(--glass-blur)) !important;
|
||||||
|
border: 1px solid var(--glass-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNavScreenMenuLink, .VPNavScreenMenuGroup {
|
||||||
|
border-bottom: 1px solid var(--glass-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPLocalNav .outline {
|
||||||
|
background-color: rgba(24, 24, 29, 0.9) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
}
|
||||||
|
.VPLocalNav .header {
|
||||||
|
background-color: rgba(24, 24, 29, 0.95) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPSidebar,
|
||||||
|
.VPNavScreen {
|
||||||
|
background-color: transparent !important;
|
||||||
|
backdrop-filter: blur(var(--glass-blur-3)) !important;
|
||||||
|
border-right: 1px solid var(--glass-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shell {
|
||||||
|
background-color: var(--glass-bg) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur-2)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur-2)) !important;
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
box-shadow: var(--glass-shadow);
|
||||||
|
}
|
||||||
|
.backdrop {
|
||||||
|
background-color: transparent !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur-4)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur-4)) !important;
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
box-shadow: var(--glass-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPNavBar .divider {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPFlyout .menu {
|
||||||
|
background-color: var(--glass-bg) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
border-radius: var(--glass-menu-radius) !important;
|
||||||
|
box-shadow: var(--glass-shadow), var(--glass-highlight) !important;
|
||||||
|
|
||||||
|
padding: 6px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPFlyout .VPMenu {
|
||||||
|
background: transparent !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPFlyout .item.active .link,
|
||||||
|
.VPFlyout .item .link:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .VPFlyout .item.active .link,
|
||||||
|
.dark .VPFlyout .item .link:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vp-adaptive-theme {
|
||||||
|
background-color: var(--glass-bg) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
}
|
||||||
|
.custom-block {
|
||||||
|
backdrop-filter: blur(var(--glass-blur)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
border-radius: var(--glass-menu-radius) !important;
|
||||||
|
|
||||||
|
background-clip: padding-box !important;
|
||||||
|
box-shadow: var(--glass-shadow-2), var(--glass-highlight) !important;
|
||||||
|
|
||||||
|
transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1),
|
||||||
|
border-color 0.3s ease,
|
||||||
|
box-shadow 0.3s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPFeature {
|
||||||
|
background: var(--glass-bg) !important;
|
||||||
|
backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
-webkit-backdrop-filter: saturate(180%) blur(var(--glass-blur)) !important;
|
||||||
|
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
border-radius: var(--glass-radius) !important;
|
||||||
|
|
||||||
|
background-clip: padding-box !important;
|
||||||
|
box-shadow: var(--glass-shadow), var(--glass-highlight) !important;
|
||||||
|
|
||||||
|
transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1),
|
||||||
|
border-color 0.3s ease,
|
||||||
|
box-shadow 0.3s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPFeature:hover {
|
||||||
|
transform: translateY(-8px) scale(1.01);
|
||||||
|
border-color: rgba(255, 255, 255, 0.4) !important;
|
||||||
|
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.25),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPButton {
|
||||||
|
border-radius: 99px !important;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
font-weight: 600 !important;
|
||||||
|
transition: all 0.3s ease !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPButton.brand {
|
||||||
|
background: linear-gradient(135deg, var(--vp-c-brand-3), var(--vp-c-brand-1)) !important;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2) !important;
|
||||||
|
box-shadow: 0 4px 12px rgba(var(--vp-c-brand-rgb), 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPButton.brand:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 8px 24px rgba(var(--vp-c-brand-rgb), 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPButton.alt {
|
||||||
|
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||||
|
border: 1px solid var(--glass-border) !important;
|
||||||
|
color: var(--vp-c-text-1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPButton.alt:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.15) !important;
|
||||||
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
|
|
@ -61,22 +279,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
|
||||||
--vp-custom-block-tip-border: transparent;
|
|
||||||
--vp-custom-block-tip-text: var(--vp-c-text-1);
|
|
||||||
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
|
|
||||||
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
|
|
||||||
}
|
|
||||||
|
|
||||||
.DocSearch {
|
.DocSearch {
|
||||||
--docsearch-primary-color: var(--vp-c-brand-1) !important;
|
--docsearch-primary-color: var(--vp-c-brand-1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.VPNavBarTitle .title {
|
.VPNavBarTitle .title {
|
||||||
/* background: linear-gradient(120deg,
|
|
||||||
#6034fe 30%,
|
|
||||||
#fe3434);
|
|
||||||
-webkit-text-fill-color: transparent;
|
|
||||||
-webkit-background-clip: text; */
|
|
||||||
color: rgb(255, 153, 0);
|
color: rgb(255, 153, 0);
|
||||||
|
transition: color 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPHero .name {
|
||||||
|
text-shadow: 0 0 40px rgba(254, 82, 52, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPHero .image-src {
|
||||||
|
animation: float-premium 6s ease-in-out infinite;
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.VPHero .image-bg {
|
||||||
|
animation: pulse-glow-premium 5s ease-in-out infinite alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float-premium {
|
||||||
|
0% {
|
||||||
|
transform: translate(-50%, -50%) translateY(0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translate(-50%, -50%) translateY(-16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) translateY(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse-glow-premium {
|
||||||
|
0% {
|
||||||
|
opacity: 0.6;
|
||||||
|
transform: translate(-50%, -50%) scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, -50%) scale(1.1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,13 +7,13 @@ For Client-sided
|
||||||
Create new Warp event.
|
Create new Warp event.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
Identifier: string
|
Identifier: string
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Remote = Warp.Client("Remote")
|
local Remote = Warp.Client("Remote")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -23,13 +23,13 @@ local Remote = Warp.Client("Remote")
|
||||||
Create new Warp events with array.
|
Create new Warp events with array.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
{ any }
|
{ any }
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Events = Warp.fromClientArray({
|
local Events = Warp.fromClientArray({
|
||||||
"Remote1",
|
"Remote1",
|
||||||
"Remote2",
|
"Remote2",
|
||||||
|
|
@ -48,13 +48,13 @@ Events.Remote3:Connect(function(...) end)
|
||||||
Connect event to receive incoming from server way.
|
Connect event to receive incoming from server way.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
callback: (...any) -> ()
|
callback: (...any) -> ()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Connect(function(...)
|
Remote:Connect(function(...)
|
||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
@ -66,13 +66,13 @@ end)
|
||||||
This function likely `:Connect` but it disconnect the event once it fired.
|
This function likely `:Connect` but it disconnect the event once it fired.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
callback: (...any) -> ()
|
callback: (...any) -> ()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Once(function(...)
|
Remote:Once(function(...)
|
||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
@ -84,13 +84,13 @@ end)
|
||||||
Disconnect the event connection.
|
Disconnect the event connection.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
key: string
|
key: string
|
||||||
)
|
): boolean
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local connection = Remote:Connect(function(player, ...) end) -- store the key
|
local connection = Remote:Connect(function(player, ...) end) -- store the key
|
||||||
|
|
||||||
Remote:Disconnect(connection)
|
Remote:Disconnect(connection)
|
||||||
|
|
@ -101,7 +101,7 @@ Remote:Disconnect(connection)
|
||||||
|
|
||||||
Disconnect All the event connection.
|
Disconnect All the event connection.
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:DisconnectAll()
|
Remote:DisconnectAll()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -110,14 +110,14 @@ Remote:DisconnectAll()
|
||||||
Fire the event to the spesific server with data.
|
Fire the event to the spesific server with data.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
reliable: boolean,
|
reliable: boolean,
|
||||||
...: any
|
...: any
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Fire(true, "Hello World!")
|
Remote:Fire(true, "Hello World!")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -128,18 +128,18 @@ This function have rate limiting it self and configured from server.
|
||||||
|
|
||||||
## `:Invoke` <Badge type="warning" text="yield" />
|
## `:Invoke` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
Semiliar to `:InvokeServer`, its for Invoke to a server.
|
Semiliar to `:InvokeServer`, but it have timeout system that not exists on `RemoteFunction.InvokeServer`.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
timeout: number,
|
timeout: number,
|
||||||
...: any
|
...: any
|
||||||
) -> (...any)
|
) -> (...any)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Request = Remote:Invoke(2, "Hello World!")
|
local Request = Remote:Invoke(2, "Hello World!") -- this yield until it response
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|
@ -152,7 +152,7 @@ This function is yielded, once it timeout it will return nil.
|
||||||
Wait the event being triggered.
|
Wait the event being triggered.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
Remote:Wait()
|
Remote:Wait() -- :Wait return number value
|
||||||
```
|
```
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
@ -161,7 +161,7 @@ This function is yielded, Invoke might also ping this one and also causing error
|
||||||
|
|
||||||
## `:Destroy`
|
## `:Destroy`
|
||||||
|
|
||||||
Disconnect all connection of event and remove the event from Warp
|
Disconnect all connection of event and remove the event from Warp list
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
Remote:Destroy()
|
Remote:Destroy()
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,20 @@ Ratelimit is one of most useful feature.
|
||||||
When creating a event on Server, you can add second argument (optional) as table `rateLimit` to limit the number of times the event can be called and the interval for reset the counter on client-side.
|
When creating a event on Server, you can add second argument (optional) as table `rateLimit` to limit the number of times the event can be called and the interval for reset the counter on client-side.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Server]
|
```luau [Server]
|
||||||
-- Server
|
-- Server
|
||||||
-- Let's make the event have ratelimit with max 50 entrance for 2 seconds.
|
-- Let's make the event have ratelimit with max 50 entrance for 2 seconds.
|
||||||
local Remote = Warp.Server("Remote1", {
|
local Remote = Warp.Server("Remote1", {
|
||||||
maxEntrance = 50, -- maximum 50 fires.
|
rateLimit = {
|
||||||
interval = 2, -- 2 seconds
|
maxEntrance = 50, -- maximum 50 fires.
|
||||||
|
interval = 2, -- 2 seconds
|
||||||
|
}
|
||||||
})
|
})
|
||||||
-- Now the Event RateLimit is configured, and ready to use.
|
-- Now the Event RateLimit is configured, and ready to use.
|
||||||
-- No need anything to adds on client side.
|
-- No need anything to adds on client side.
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Client]
|
```luau [Client]
|
||||||
-- Client
|
-- Client
|
||||||
local Remote = Warp.Client("Remote1") -- Yields, retreive rateLimit configuration.
|
local Remote = Warp.Client("Remote1") -- Yields, retreive rateLimit configuration.
|
||||||
-- The Event will automatic it self for retreiving the rate limit configuration from the server.
|
-- The Event will automatic it self for retreiving the rate limit configuration from the server.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ For Server-sided
|
||||||
Create new Warp event.
|
Create new Warp event.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
Identifier: string,
|
Identifier: string,
|
||||||
rateLimit: {
|
rateLimit: {
|
||||||
|
|
@ -17,7 +17,7 @@ Create new Warp event.
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Remote = Warp.Server("Remote")
|
local Remote = Warp.Server("Remote")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -27,21 +27,25 @@ local Remote = Warp.Server("Remote")
|
||||||
Create new Warp events with array.
|
Create new Warp events with array.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
{ any }
|
{ any }
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Events = Warp.fromServerArray({
|
local Events = Warp.fromServerArray({
|
||||||
["Remote1"] = {
|
["Remote1"] = {
|
||||||
maxEntrance: 50,
|
rateLimit = {
|
||||||
interval: 1,
|
maxEntrance: 50,
|
||||||
|
interval: 1,
|
||||||
|
}
|
||||||
}, -- with rateLimit configuration
|
}, -- with rateLimit configuration
|
||||||
"Remote2", -- without rateLimit configuration
|
"Remote2", -- without rateLimit configuration
|
||||||
["Remote3"] = {
|
["Remote3"] = {
|
||||||
maxEntrance: 10,
|
rateLimit = {
|
||||||
|
maxEntrance: 10,
|
||||||
|
}
|
||||||
}, -- with rateLimit configuration
|
}, -- with rateLimit configuration
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -56,14 +60,14 @@ Events.Remote3:Connect(function(player, ...) end)
|
||||||
Connect event to receive incoming from client way.
|
Connect event to receive incoming from client way.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
player: Player,
|
player: Player,
|
||||||
callback: (...any) -> ()
|
callback: (...any) -> ()
|
||||||
): string
|
): string
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Connect(function(player, ...)
|
Remote:Connect(function(player, ...)
|
||||||
print(player, ...)
|
print(player, ...)
|
||||||
end)
|
end)
|
||||||
|
|
@ -75,14 +79,14 @@ end)
|
||||||
This function likely `:Connect` but it disconnect the event once it fired.
|
This function likely `:Connect` but it disconnect the event once it fired.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
player: Player,
|
player: Player,
|
||||||
callback: (...any) -> ()
|
callback: (...any) -> ()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Once(function(player, ...)
|
Remote:Once(function(player, ...)
|
||||||
print(player, ...)
|
print(player, ...)
|
||||||
end)
|
end)
|
||||||
|
|
@ -94,13 +98,13 @@ end)
|
||||||
Disconnect the event connection.
|
Disconnect the event connection.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
key: string
|
key: string
|
||||||
)
|
): boolean
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local connection = Remote:Connect(function(player, ...) end) -- store the key
|
local connection = Remote:Connect(function(player, ...) end) -- store the key
|
||||||
|
|
||||||
Remote:Disconnect(connection)
|
Remote:Disconnect(connection)
|
||||||
|
|
@ -111,7 +115,7 @@ Remote:Disconnect(connection)
|
||||||
|
|
||||||
Disconnect All the event connection.
|
Disconnect All the event connection.
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:DisconnectAll()
|
Remote:DisconnectAll()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -120,7 +124,7 @@ Remote:DisconnectAll()
|
||||||
Fire the event to a client.
|
Fire the event to a client.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
reliable: boolean,
|
reliable: boolean,
|
||||||
player: Player,
|
player: Player,
|
||||||
|
|
@ -128,7 +132,7 @@ Fire the event to a client.
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Fire(true, player, "Hello World!")
|
Remote:Fire(true, player, "Hello World!")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -138,24 +142,42 @@ Remote:Fire(true, player, "Hello World!")
|
||||||
Fire the event to all clients.
|
Fire the event to all clients.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
reliable: boolean,
|
reliable: boolean,
|
||||||
...: any
|
...: any
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Remote:Fires(true, "Hello World!")
|
Remote:Fires(true, "Hello World!")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
## `:FireExcept` <Badge type="tip" text="Server Only" />
|
||||||
|
|
||||||
|
Fire the event to all clients but except a players.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
reliable: boolean,
|
||||||
|
except: { Player },
|
||||||
|
...: any
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Remote:FireExcept(true, { Players.Eternity_Devs, Players.Player2 }, "Hello World!") -- this will sent to all players except { Players.Eternity_Devs, Players.Player2 }.
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
## `:Invoke` <Badge type="warning" text="yield" />
|
## `:Invoke` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
Semiliar to `:InvokeClient`, its for Invoke to a client.
|
Semiliar to `:InvokeClient`, but it have timeout system that not exists on `RemoteFunction.InvokeClient`.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
timeout: number,
|
timeout: number,
|
||||||
player: Player,
|
player: Player,
|
||||||
|
|
@ -163,7 +185,7 @@ Semiliar to `:InvokeClient`, its for Invoke to a client.
|
||||||
) -> (...any)
|
) -> (...any)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Request = Remote:Invoke(2, player, "Hello World!")
|
local Request = Remote:Invoke(2, player, "Hello World!")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -177,7 +199,7 @@ This function is yielded, once it timeout it will return nil.
|
||||||
Wait the event being triggered.
|
Wait the event being triggered.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
Remote:Wait()
|
Remote:Wait() -- :Wait return number value
|
||||||
```
|
```
|
||||||
|
|
||||||
::: warning
|
::: warning
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ A alternative of BindableEvent.
|
||||||
Create new Signal.
|
Create new Signal.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
Identifier: string
|
Identifier: string
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Signal1 = Warp.Signal("Signal1")
|
local Signal1 = Warp.Signal("Signal1")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -23,13 +23,13 @@ local Signal1 = Warp.Signal("Signal1")
|
||||||
Create new Signal.
|
Create new Signal.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
{ string }
|
{ string }
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local Signals = Warp.fromSignalArray({"Signal1", "Signal2"})
|
local Signals = Warp.fromSignalArray({"Signal1", "Signal2"})
|
||||||
Signals.Signal1:Connect(function(...) end)
|
Signals.Signal1:Connect(function(...) end)
|
||||||
Signals.Signal2:Connect(function(...) end)
|
Signals.Signal2:Connect(function(...) end)
|
||||||
|
|
@ -39,13 +39,13 @@ Signals.Signal2:Connect(function(...) end)
|
||||||
## `:Connect`
|
## `:Connect`
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
callback: (...any) -> ()
|
callback: (...any) -> ()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Signal1:Connect(function(...)
|
Signal1:Connect(function(...)
|
||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
@ -57,13 +57,13 @@ end)
|
||||||
This function likely `:Connect` but it disconnect the signal once it fired.
|
This function likely `:Connect` but it disconnect the signal once it fired.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
callback: (...any) -> ()
|
callback: (...any) -> ()
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Signal1:Once(function(...)
|
Signal1:Once(function(...)
|
||||||
print(...)
|
print(...)
|
||||||
end)
|
end)
|
||||||
|
|
@ -75,13 +75,13 @@ end)
|
||||||
Disconnect the signal connection.
|
Disconnect the signal connection.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
key: string
|
key: string
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local connection = Signal1:Connect(function(...) end) -- store the key
|
local connection = Signal1:Connect(function(...) end) -- store the key
|
||||||
|
|
||||||
Signal1:Disconnect(connection)
|
Signal1:Disconnect(connection)
|
||||||
|
|
@ -96,22 +96,38 @@ This requires `key` to disconnect a signal connection.
|
||||||
|
|
||||||
Disconnect All signal connections.
|
Disconnect All signal connections.
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Signal1:DisconnectAll()
|
Signal1:DisconnectAll()
|
||||||
```
|
```
|
||||||
|
|
||||||
## `:Fire`
|
## `:Fire`
|
||||||
|
|
||||||
Fire the signal.
|
Fire the signal (Immediate)
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
...: any
|
...: any
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
|
Signal1:Fire("Hello World!")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `:DeferFire`
|
||||||
|
|
||||||
|
Fire the signal (Deferred)
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
...: any
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
Signal1:Fire("Hello World!")
|
Signal1:Fire("Hello World!")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -122,17 +138,17 @@ This uses `pcall`, which means it never error (safe-mode, sacrificed debugging),
|
||||||
|
|
||||||
## `:FireTo`
|
## `:FireTo`
|
||||||
|
|
||||||
Fire to other signal, this also use `:Fire`.
|
Fire to other signal, this uses `:Fire`.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
signal: string,
|
signal: string,
|
||||||
...: any
|
...: any
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
Signals.Signal1:FireTo("Signal2", "Hello World!")
|
Signals.Signal1:FireTo("Signal2", "Hello World!")
|
||||||
```
|
```
|
||||||
:::
|
:::
|
||||||
|
|
@ -144,14 +160,14 @@ This requires `key`.
|
||||||
## `:Invoke` <Badge type="warning" text="yield" />
|
## `:Invoke` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
key: string,
|
key: string,
|
||||||
...: any
|
...: any
|
||||||
) -> (...any)
|
) -> (...any)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local connection = Signal1:Conenct(function(...) return "hey!" end)
|
local connection = Signal1:Conenct(function(...) return "hey!" end)
|
||||||
local Request = Signal1:Invoke(connection, "Hello World!")
|
local Request = Signal1:Invoke(connection, "Hello World!")
|
||||||
```
|
```
|
||||||
|
|
@ -162,7 +178,7 @@ local Request = Signal1:Invoke(connection, "Hello World!")
|
||||||
this use `:Invoke`.
|
this use `:Invoke`.
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Variable]
|
```luau [Variable]
|
||||||
(
|
(
|
||||||
signal: string,
|
signal: string,
|
||||||
key: string,
|
key: string,
|
||||||
|
|
@ -170,7 +186,7 @@ this use `:Invoke`.
|
||||||
) -> (...any)
|
) -> (...any)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Example]
|
```luau [Example]
|
||||||
local connection2 = Signals.Signal2:Conenct(function(...) return "hey!" end)
|
local connection2 = Signals.Signal2:Conenct(function(...) return "hey!" end)
|
||||||
local Request = Signals.Signal1:Invoke("Signal2", connection2, "Hello World!")
|
local Request = Signals.Signal1:Invoke("Signal2", connection2, "Hello World!")
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Warp <Badge type="tip" text="1.0" />
|
# Warp <Badge type="tip" text="1.0" /> <Badge type="warning" text="deprecated" />
|
||||||
|
|
||||||
The public main of the Warp library.
|
The public main of the Warp library.
|
||||||
|
|
||||||
|
|
|
||||||
176
docs/api/1.1/buffer.md
Normal file
176
docs/api/1.1/buffer.md
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
# Buffer <Badge type="tip" text="module" />
|
||||||
|
|
||||||
|
For efficient data serialization and schema definition with optimized packing.
|
||||||
|
|
||||||
|
## Getting the Buffer Object
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Schema System <Badge type="tip" text="v1.1" />
|
||||||
|
|
||||||
|
Define strict data schemas for optimized serialization and type safety.
|
||||||
|
|
||||||
|
### Available Schema Types
|
||||||
|
|
||||||
|
```lua
|
||||||
|
{
|
||||||
|
-- Basic types
|
||||||
|
"boolean",
|
||||||
|
"string",
|
||||||
|
"nil",
|
||||||
|
|
||||||
|
-- Numeric types
|
||||||
|
"u8", -- usigned-int
|
||||||
|
"u16",
|
||||||
|
"u32",
|
||||||
|
"i8", -- signed-int
|
||||||
|
"i16",
|
||||||
|
"i32",
|
||||||
|
"f16", -- floating-point
|
||||||
|
"f32",
|
||||||
|
"f64",
|
||||||
|
|
||||||
|
-- Roblox types
|
||||||
|
"buffer"
|
||||||
|
"vector2", -- f16
|
||||||
|
"vector3", -- f16
|
||||||
|
"cframe", -- f32 & f16
|
||||||
|
"color3", -- u8
|
||||||
|
"color3f16",
|
||||||
|
"instance",
|
||||||
|
|
||||||
|
-- other types
|
||||||
|
"optional",
|
||||||
|
"array",
|
||||||
|
"map",
|
||||||
|
"struct",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Custom Datatypes
|
||||||
|
|
||||||
|
### `.custom_datatype`
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
name: string,
|
||||||
|
object: { any },
|
||||||
|
writer: (w: Writer, v: any) -> (),
|
||||||
|
reader: (b: buffer, c: number, refs: { Instance }?) -> (buffer, number))
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
|
||||||
|
-- # this custom datatype must be registered on both server & client side
|
||||||
|
Buffer.Schema.custom_datatype("u64", {}, function(w: Buffer.Writer, value: any) -- just for reference
|
||||||
|
-- writing u64 logics here
|
||||||
|
end, function(b: buffer, cursor: number, refs)
|
||||||
|
-- reading u64 logics here
|
||||||
|
return b, cursor
|
||||||
|
end)
|
||||||
|
|
||||||
|
local DataSchema = Buffer.Schema.struct({
|
||||||
|
LongInteger = Buffer.Schema.u64, -- use the custom datatype
|
||||||
|
})
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## Writer and Reader Functions
|
||||||
|
|
||||||
|
### `.createWriter`
|
||||||
|
|
||||||
|
Create a new buffer writer for serializing data.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
capacity: number? -- Optional initial capacity (default: 64)
|
||||||
|
): Writer
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
local writer = Buffer.createWriter(256) -- Pre-allocate 256 bytes
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### `.build`
|
||||||
|
|
||||||
|
Build the final buffer for transmission.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
writer: Writer
|
||||||
|
): buffer -- Returns buffer
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
local writer = Buffer.createWriter()
|
||||||
|
|
||||||
|
-- Write some data
|
||||||
|
Buffer.packValue(writer, "Hello World")
|
||||||
|
Buffer.packValue(writer, 12345)
|
||||||
|
|
||||||
|
-- Build final buffer
|
||||||
|
local finalBuffer = Buffer.build(writer)
|
||||||
|
print(buffer.len(finalBuffer))
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### `.buildWithRefs`
|
||||||
|
|
||||||
|
Build the final buffer with instance references for transmission.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
writer: Writer
|
||||||
|
): (buffer, { Instance }?) -- Returns buffer and optional instance references
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
local writer = Buffer.createWriter()
|
||||||
|
|
||||||
|
-- Write some data with instances
|
||||||
|
Buffer.packValue(writer, workspace.Part)
|
||||||
|
Buffer.packValue(writer, game.Players.LocalPlayer)
|
||||||
|
|
||||||
|
-- Build final buffer
|
||||||
|
local finalBuffer, refs = Buffer.buildWithRefs(writer)
|
||||||
|
print(buffer.len(finalBuffer), refs)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
### `.reset`
|
||||||
|
|
||||||
|
Reset a writer for reuse, clearing all data.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
writer: Writer
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
local writer = Buffer.createWriter()
|
||||||
|
|
||||||
|
-- Use writer for first batch
|
||||||
|
Buffer.writeEvents(writer, events1)
|
||||||
|
local buffer1 = Buffer.build(writer)
|
||||||
|
|
||||||
|
-- Reset and reuse for second batch
|
||||||
|
Buffer.reset(writer)
|
||||||
|
Buffer.writeEvents(writer, events2)
|
||||||
|
local buffer2 = Buffer.build(writer)
|
||||||
|
```
|
||||||
|
:::
|
||||||
237
docs/api/1.1/client.md
Normal file
237
docs/api/1.1/client.md
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
# Client <Badge type="tip" text="1.1" />
|
||||||
|
|
||||||
|
For Client-sided operations.
|
||||||
|
|
||||||
|
## Getting the Client Object
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Client = Warp.Client()
|
||||||
|
```
|
||||||
|
|
||||||
|
## `.awaitReady` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
|
Yields the current thread until the client has successfully initialized and synchronized with the server's replication data (identifier).
|
||||||
|
|
||||||
|
::: info
|
||||||
|
Its optionally, but highly recommended to call this before firing or connecting to any events to ensure the network is fully ready.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
() -> ()
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Client = Warp.Client()
|
||||||
|
|
||||||
|
-- wait for the client to be fully initialized
|
||||||
|
Client.awaitReady()
|
||||||
|
|
||||||
|
print("Client is now ready to send and receive events! :D")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Connect`
|
||||||
|
|
||||||
|
Connect to an event to receive incoming data from the server.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
fn: (...any) -> ...any
|
||||||
|
) -> Connection
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local connection = Client.Connect("ServerNotify", function(message, sender)
|
||||||
|
print(`Server message from {sender}: {message}`)
|
||||||
|
end)
|
||||||
|
print(connection.Connected)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Once`
|
||||||
|
|
||||||
|
Similar to `:Connect` but automatically disconnects after the first firing.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
fn: (...any) -> ...any
|
||||||
|
) -> Connection
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Client.Once("WelcomeMessage", function(welcomeText)
|
||||||
|
print(`Welcome: {welcomeText}`)
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Wait` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
|
Wait for an event to be triggered.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string
|
||||||
|
) -> (number, ...any)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local elapsed, message = Client.Wait("ServerMessage")
|
||||||
|
print(`Received message after {elapsed} seconds: {message}`)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Disconnect`
|
||||||
|
|
||||||
|
Disconnect the event connection.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
()
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local connection = Client.Connect("ServerNotify", function(message, sender)
|
||||||
|
print(`Server message from {sender}: {message}`)
|
||||||
|
-- Disconnect the connection
|
||||||
|
connection:Disconnect()
|
||||||
|
end)
|
||||||
|
print(Connection.Connected)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.DisconnectAll`
|
||||||
|
|
||||||
|
Disconnect all connections for a specific event.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Client.DisconnectAll("ServerNotify")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Destroy`
|
||||||
|
|
||||||
|
Disconnect all connections and remove the event.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Client.Destroy("ServerNotify")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Fire`
|
||||||
|
|
||||||
|
Fire an event to the server.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
reliable: boolean,
|
||||||
|
...: any
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
-- (TCP) Reliable event (guaranteed delivery)
|
||||||
|
Client.Fire("PlayerAction", true, "jump", playerPosition)
|
||||||
|
|
||||||
|
-- (UDP) Unreliable event (faster but not guaranteed)
|
||||||
|
Client.Fire("PositionUpdate", false, currentPosition)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Invoke` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
|
Invoke the server with timeout support.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
timeout: number?,
|
||||||
|
...: any
|
||||||
|
) -> ...any
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Client = Warp.Client()
|
||||||
|
local response = Client.Invoke("RequestData", 3, "playerStats")
|
||||||
|
if response then
|
||||||
|
print("Server responded:", response)
|
||||||
|
else
|
||||||
|
print("Request timed out")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
This function is yielded. Returns `nil` if timeout occurs.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.useSchema`
|
||||||
|
|
||||||
|
Define a schema for strict data packing on a specific event.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
schema: Buffer.SchemaType
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Client = Warp.Client()
|
||||||
|
|
||||||
|
-- Define a schema for position updates
|
||||||
|
local positionSchema = Client.Schema.struct({
|
||||||
|
x = Client.Schema.f32,
|
||||||
|
y = Client.Schema.f32,
|
||||||
|
z = Client.Schema.f32,
|
||||||
|
timestamp = Client.Schema.u32
|
||||||
|
})
|
||||||
|
-- Define a schema for data updates
|
||||||
|
local dataSchema = Client.Schema.struct({
|
||||||
|
Coins = Client.Schema.u32,
|
||||||
|
Level = Client.Schema.u8,
|
||||||
|
Inventory = Client.Schema.array(Client.Schema.u32),
|
||||||
|
Settings = Client.Schema.struct({
|
||||||
|
VFX = Client.Schema.boolean,
|
||||||
|
Volume = Client.Schema.f32,
|
||||||
|
Language = Client.Schema.string,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Now this event will use the schema
|
||||||
|
Client.useSchema("DataReplication", dataSchema)
|
||||||
|
Client.useSchema("PositionUpdate", positionSchema)
|
||||||
|
Client.Connect("PositionUpdate", function(x, y, z, timestamp)
|
||||||
|
-- Data is automatically deserialized according to schema
|
||||||
|
updatePlayerPosition(x, y, z)
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Schema`
|
||||||
|
|
||||||
|
Access to Buffer.Schema for creating data schemas.
|
||||||
244
docs/api/1.1/server.md
Normal file
244
docs/api/1.1/server.md
Normal file
|
|
@ -0,0 +1,244 @@
|
||||||
|
# Server <Badge type="tip" text="1.1" />
|
||||||
|
|
||||||
|
For Server-sided operations.
|
||||||
|
|
||||||
|
## Getting the Server Object
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Server = Warp.Server()
|
||||||
|
```
|
||||||
|
|
||||||
|
## `.reg_namespaces`
|
||||||
|
|
||||||
|
Register namespaces to ensure all of the namespaces is being registered earlier on the server to prevent any unexpected issues on the client.
|
||||||
|
|
||||||
|
::: info
|
||||||
|
this is optional and conditional, you may have to use this if you had a problem with identifier namespace on client.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
namespaces: { string },
|
||||||
|
) -> Connection
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Server.reg_namespaces({
|
||||||
|
"ServerNotify",
|
||||||
|
"ServerMessage",
|
||||||
|
"WelcomeMessage",
|
||||||
|
"Broadcast",
|
||||||
|
"DataReplication",
|
||||||
|
"RequestData",
|
||||||
|
"Update"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Connect`
|
||||||
|
|
||||||
|
Connect to an event to receive incoming data from clients.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
fn: (player: Player, ...any) -> ...any
|
||||||
|
) -> Connection
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local connection = Server.Connect("ServerNotify", function(player, message)
|
||||||
|
print(`Client message from {player}: {message}`)
|
||||||
|
end)
|
||||||
|
print(connection.Connected)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Once`
|
||||||
|
|
||||||
|
Similar to `:Connect` but automatically disconnects after the first firing.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
fn: (player: Player, ...any) -> ...any
|
||||||
|
) -> Connection
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Server.Once("WelcomeMessage", function(welcomeText)
|
||||||
|
print(`Welcome: {welcomeText}`)
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Wait` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
|
Wait for an event to be triggered.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string
|
||||||
|
) -> (number, ...any)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local elapsed, message = Server.Wait("ServerMessage")
|
||||||
|
print(`Received message after {elapsed} seconds: {message}`)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.DisconnectAll`
|
||||||
|
|
||||||
|
Disconnect all connections for a specific event.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Server.DisconnectAll("ServerNotify")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Destroy`
|
||||||
|
|
||||||
|
Disconnect all connections and remove the event.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Server.Destroy("ServerNotify")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Fire`
|
||||||
|
|
||||||
|
Fire an event to a specific player.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
reliable: boolean,
|
||||||
|
player: Player,
|
||||||
|
...: any
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Server.Fire("ServerNotify", true, player, "Hello from server!")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Fires`
|
||||||
|
|
||||||
|
Fire an event to all connected players.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
reliable: boolean,
|
||||||
|
...: any
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
Server.Fires("Broadcast", true, "Server announcement!")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.FireExcept`
|
||||||
|
|
||||||
|
Fire an event to all players except specified ones.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
reliable: boolean,
|
||||||
|
except: { Player },
|
||||||
|
...: any
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local excludedPlayers = { player1, player2 }
|
||||||
|
Server.FireExcept("Update", true, excludedPlayers, "Game update")
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Invoke` <Badge type="warning" text="yield" />
|
||||||
|
|
||||||
|
Invoke a client with timeout support.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
player: Player,
|
||||||
|
timeout: number?,
|
||||||
|
...: any
|
||||||
|
) -> ...any
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local response = Server.Invoke("RequestData", player, 3, "userInfo")
|
||||||
|
if response then
|
||||||
|
print("Client responded:", response)
|
||||||
|
else
|
||||||
|
print("Request timed out")
|
||||||
|
end
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
This function is yielded. Returns `nil` if timeout occurs.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.useSchema`
|
||||||
|
|
||||||
|
Define a schema for strict data packing on a specific event.
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
```luau [Variable]
|
||||||
|
(
|
||||||
|
remoteName: string,
|
||||||
|
schema: Buffer.SchemaType
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```luau [Example]
|
||||||
|
local Server = Warp.Server()
|
||||||
|
|
||||||
|
local dataSchema = Server.Schema.struct({
|
||||||
|
Coins = Server.Schema.u32,
|
||||||
|
Level = Server.Schema.u8,
|
||||||
|
Inventory = Server.Schema.array(Server.Schema.u32),
|
||||||
|
Settings = Server.Schema.struct({
|
||||||
|
VFX = Server.Schema.boolean,
|
||||||
|
Volume = Server.Schema.f32,
|
||||||
|
Language = Server.Schema.string,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Server.useSchema("DataReplication", dataSchema)
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Schema`
|
||||||
|
|
||||||
|
Access to Buffer.Schema for creating data schemas.
|
||||||
34
docs/api/1.1/warp.md
Normal file
34
docs/api/1.1/warp.md
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Warp <Badge type="tip" text="1.1" /> <Badge type="warning" text="pre-release" />
|
||||||
|
|
||||||
|
The public main of the Warp library.
|
||||||
|
::: warning
|
||||||
|
This version (1.1.x) is not backward compatible with 1.0.x.
|
||||||
|
:::
|
||||||
|
|
||||||
|
## `.Server` <Badge type="tip" text="server side" />
|
||||||
|
|
||||||
|
Get the Server operation for server-side.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Server
|
||||||
|
local Server = Warp.Server()
|
||||||
|
```
|
||||||
|
|
||||||
|
## `.Client` <Badge type="tip" text="client side" />
|
||||||
|
|
||||||
|
Get the Client operation for client-side.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Client
|
||||||
|
local Client = Warp.Client()
|
||||||
|
```
|
||||||
|
|
||||||
|
## `.Buffer` <Badge type="tip" text="universal" />
|
||||||
|
|
||||||
|
Get the Buffer util for schema definition.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- Universal (Server & Client)
|
||||||
|
local Buffer = Warp.Buffer()
|
||||||
|
local schema = Buffer.Schema
|
||||||
|
```
|
||||||
|
|
@ -1 +1 @@
|
||||||
import{_ as e,o as a,c as t,Q as r}from"./chunks/framework.419948d5.js";const m=JSON.parse('{"title":"Overview","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md"}'),i={name:"guide/index.md"},o=r('<h1 id="overview" tabindex="-1">Overview <a class="header-anchor" href="#overview" aria-label="Permalink to "Overview""></a></h1><p>FastNet2 is a networking library for Roblox, where its very-fast performance and lightweight.</p><h2 id="why-fastnet2" tabindex="-1">Why FastNet2 <a class="header-anchor" href="#why-fastnet2" aria-label="Permalink to "Why FastNet2""></a></h2><h3 id="⚡-performance" tabindex="-1">⚡ Performance <a class="header-anchor" href="#⚡-performance" aria-label="Permalink to "⚡ Performance""></a></h3><p>FastNet2 is very-fast with high performance networking, only use a single remote event to reduce bandwidth usage and increase performance gain.</p><h3 id="🍃-lightweight" tabindex="-1">🍃 Lightweight <a class="header-anchor" href="#🍃-lightweight" aria-label="Permalink to "🍃 Lightweight""></a></h3><p>FastNet2 is a lightweight module for roblox games</p><h3 id="📊-task" tabindex="-1">📊 Task <a class="header-anchor" href="#📊-task" aria-label="Permalink to "📊 Task""></a></h3><p>FastNet2 been optimized for a game that have heavy usage and require optimizations</p><h3 id="🔒-secure" tabindex="-1">🔒 Secure <a class="header-anchor" href="#🔒-secure" aria-label="Permalink to "🔒 Secure""></a></h3><p>FastNet2 have built-in feature where it securing their data network to make exploiters harder to exploit it</p>',11),n=[o];function h(s,d,l,c,u,p){return a(),t("div",null,n)}const _=e(i,[["render",h]]);export{m as __pageData,_ as default};
|
import{_ as e,o as a,c as t,Q as r}from"./chunks/framework.419948d5.js";const m=JSON.parse('{"title":"Overview","description":"","frontmatter":{},"headers":[],"relativePath":"guide/index.md","filePath":"guide/index.md"}'),i={name:"guide/index.md"},o=r('<h1 id="overview" tabindex="-1">Overview <a class="header-anchor" href="#overview" aria-label="Permalink to "Overview""></a></h1><p>FastNet2 is a networking library for Roblox, where its rapidly-fast performance and lightweight.</p><h2 id="why-fastnet2" tabindex="-1">Why FastNet2 <a class="header-anchor" href="#why-fastnet2" aria-label="Permalink to "Why FastNet2""></a></h2><h3 id="⚡-performance" tabindex="-1">⚡ Performance <a class="header-anchor" href="#⚡-performance" aria-label="Permalink to "⚡ Performance""></a></h3><p>FastNet2 is very-fast with high performance networking, only use a single remote event to reduce bandwidth usage and increase performance gain.</p><h3 id="🍃-lightweight" tabindex="-1">🍃 Lightweight <a class="header-anchor" href="#🍃-lightweight" aria-label="Permalink to "🍃 Lightweight""></a></h3><p>FastNet2 is a lightweight module for roblox games</p><h3 id="📊-task" tabindex="-1">📊 Task <a class="header-anchor" href="#📊-task" aria-label="Permalink to "📊 Task""></a></h3><p>FastNet2 been optimized for a game that have heavy usage and require optimizations</p><h3 id="🔒-secure" tabindex="-1">🔒 Secure <a class="header-anchor" href="#🔒-secure" aria-label="Permalink to "🔒 Secure""></a></h3><p>FastNet2 have built-in feature where it securing their data network to make exploiters harder to exploit it</p>',11),n=[o];function h(s,d,l,c,u,p){return a(),t("div",null,n)}const _=e(i,[["render",h]]);export{m as __pageData,_ as default};
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,78 @@
|
||||||
# Example
|
# Example <Badge type="tip" text="1.1" />
|
||||||
|
|
||||||
Let's try and play something with Warp!
|
Let's try and play something with Warp!
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
```lua [Server]
|
```luau [Schemas]
|
||||||
local Warp = require("path.to.module")
|
local Schema = require(path.to.warp).Buffer.Schema
|
||||||
|
|
||||||
-- Events
|
return {
|
||||||
local Example = Warp.Server("Example")
|
Example = Schema.array(Schema.string),
|
||||||
local Ping = Warp.Server("Ping")
|
Ping = Schema.string,
|
||||||
local Pong = Warp.Server("Pong")
|
Pong = Schema.string,
|
||||||
local PingAll = Warp.Server("PingAll")
|
PingAll = Schema.string,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```luau [Server]
|
||||||
|
local Warp = require(path.to.warp).Server()
|
||||||
|
local Schemas = require(path.to.schemas)
|
||||||
|
|
||||||
Example:Connect(function(player, arg1, arg2)
|
-- Use schemas
|
||||||
print(arg1, arg2)
|
for eventName, schema in Schemas do
|
||||||
return "Whooo!"
|
Warp.useSchema(eventName, schema)
|
||||||
|
end
|
||||||
|
|
||||||
|
Warp.Connect("Example", function(player, arg)
|
||||||
|
print(table.unpack(arg))
|
||||||
|
return "Hey!"
|
||||||
end)
|
end)
|
||||||
|
Warp.Connect("Ping", function(player, ping)
|
||||||
Ping:Connect(function(player, ping)
|
if ping then
|
||||||
if ping then
|
print("PING!")
|
||||||
print("PING!")
|
Warp.Fire("Pong", true, player, "pong!") -- Fire to spesific player through reliable event
|
||||||
Pong:Fire(true, player, "pong!")
|
Warp.Fire("PingAll", true, "ey!") -- Fire to all clients through reliable event
|
||||||
PingAll:Fires(true, "ey!")
|
end
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
||||||
```lua [Client]
|
```luau [Client]
|
||||||
local Players = game:GetService("Players")
|
local Players = game:GetService("Players")
|
||||||
local Warp = require("path.to.module")
|
local Warp = require(path.to.warp).Client()
|
||||||
|
local Schemas = require(path.to.schemas)
|
||||||
|
|
||||||
-- Events
|
-- Use schemas
|
||||||
local Example = Warp.Client("Example")
|
for eventName, schema in Schemas do
|
||||||
local Ping = Warp.Client("Ping")
|
Warp.useSchema(eventName, schema)
|
||||||
local Pong = Warp.Client("Pong")
|
end
|
||||||
local PingAll = Warp.Client("PingAll")
|
|
||||||
|
|
||||||
-- Connect the events
|
-- Connect the events
|
||||||
local connection1
|
local connection1
|
||||||
connection1 = Pong:Connect(function(pong: boolean)
|
connection1 = Warp.Connect("Pong", function(pong: boolean) -- we store the connection so we can disconnect it later
|
||||||
if pong then
|
if pong then
|
||||||
print("PONG!")
|
print("PONG!")
|
||||||
end
|
end
|
||||||
|
end)
|
||||||
|
Warp.Connect("PingAll", function(isPing: boolean)
|
||||||
|
if isPing then
|
||||||
|
print("I GET PINGED!")
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
PingAll:Connect(function(isPing: boolean)
|
task.wait(3) -- lets wait a few seconds, let the server do the things first!
|
||||||
if isPing then
|
|
||||||
print("I GET PINGED!")
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Try request a event from server!
|
-- Try request a event from server!
|
||||||
print(Example:Invoke(5, "Hello!", "this is from > "..Players.LocalPlayer.Name))
|
print(Warp.Invoke("Example", 1, { "Hello!", `this is from: @{Players.LocalPlayer.Name}` }))
|
||||||
-- Do a ping & pong to server!
|
-- Do a ping & pong to server!
|
||||||
Ping:Fire(true, "ping!")
|
Warp.Fire("Ping", true, "ping!") -- we send through reliable event
|
||||||
|
|
||||||
task.wait(1) -- lets wait 1 seconds!
|
task.wait(1) -- lets wait for a second!
|
||||||
|
|
||||||
-- Disconnect All the events
|
-- Disconnect All the events
|
||||||
Pong:DisconnectAll()
|
connection1:Disconnect()
|
||||||
PingAll:DisconnectAll()
|
-- or just disconnect spesific connection
|
||||||
-- or Just disconnect spesific connection
|
Warp.DisconnectAll("PingAll")
|
||||||
Pong:Disconnect(connection1)
|
|
||||||
|
|
||||||
-- Destroying/Deleting a Event?
|
-- Destroying/Deleting a Event?
|
||||||
Pong:Destroy()
|
Warp.Destroy("Pong")
|
||||||
|
|
||||||
-- Yay Done!
|
|
||||||
```
|
```
|
||||||
|
:::
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue