chore: prepare release, set up workflows

This commit is contained in:
Richard 2024-10-12 17:46:07 -07:00
parent 0416717f6c
commit a5d38b0d6d
58 changed files with 261 additions and 110 deletions

View file

@ -22,15 +22,10 @@ jobs:
uses: CompeyDev/setup-rokit@v0.1.2 uses: CompeyDev/setup-rokit@v0.1.2
- name: Install dependencies - name: Install dependencies
run: | run: pnpm install
pnpm install
pnpm wally
- name: Check code quality - name: Check code quality
run: pnpm lint run: pnpm lint
- name: Run ESLint - name: Build models
run: pnpm eslint run: pnpm build
- name: Build model
run: rojo build -o charm.rbxm

View file

@ -16,10 +16,17 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: wally install run: wally install
- name: Build model - name: Build models
run: rojo build -o charm.rbxm run: pnpm build
- uses: AButler/upload-release-assets@v3.0 - name: Upload release assets
uses: AButler/upload-release-assets@v3.0
with: with:
files: "charm.rbxm" files: "build/*"
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish to NPM
run: pnpm --recursive publish --access public
- name: Publish to Wally
run: pnpm --recursive publish:wally

12
.gitignore vendored
View file

@ -1,11 +1,13 @@
/node_modules /node_modules
/build
/devpackages /devpackages
/packages/**/node_modules /packages
/packages/**/packages /modules/**/node_modules
/packages/**/wally.lock /modules/**/wally.lock
/packages/**/README.md /modules/**/README.md
/packages/**/LICENSE.md /modules/**/LICENSE.md
/sourcemap.json /sourcemap.json
*.tsbuildinfo *.tsbuildinfo
*.tgz *.tgz
*.rbxm
.DS_Store .DS_Store

View file

@ -1,5 +1,4 @@
{ {
"luau-lsp.sourcemap.rojoProjectFile": "dev.project.json", "luau-lsp.sourcemap.rojoProjectFile": "dev.project.json",
"luau-lsp.types.definitionFiles": ["bin/testez.d.luau"], "luau-lsp.types.definitionFiles": ["bin/testez.d.luau"]
"luau-lsp.completion.imports.requireStyle": "alwaysRelative"
} }

5
bin/build.sh Normal file
View file

@ -0,0 +1,5 @@
mkdir build
rojo build modules/charm -o build/charm.rbxm
rojo build modules/charm-sync -o build/charm-sync.rbxm
rojo build modules/react -o build/react-charm.rbxm
rojo build modules/vide -o build/vide-charm.rbxm

View file

@ -2,17 +2,24 @@ curl -o bin/roblox.d.luau https://raw.githubusercontent.com/JohnnyMorganz/luau-l
rojo sourcemap dev.project.json -o sourcemap.json rojo sourcemap dev.project.json -o sourcemap.json
luau-lsp analyze \ check() {
--defs=bin/roblox.d.luau \ echo "Checking $1"
--defs=bin/testez.d.luau \
--flag:LuauFixIndexerSubtypingOrdering=true \
--flag:LuauInstantiateInSubtyping=true \
--flag:LuauTinyControlFlowAnalysis=true \
--sourcemap=sourcemap.json \
--ignore="**/_Index/**" src
selene src luau-lsp analyze \
stylua --check src --defs=bin/roblox.d.luau \
eslint src --defs=bin/testez.d.luau \
--flag:LuauFixIndexerSubtypingOrdering=true \
--flag:LuauInstantiateInSubtyping=true \
--sourcemap=sourcemap.json \
--ignore="**/_Index/**" \
$1
selene $1
stylua --check $1
}
eslint modules
check modules/*/src
check tests
rm bin/roblox.d.luau rm bin/roblox.d.luau

View file

@ -7,23 +7,23 @@
"DevPackages": { "DevPackages": {
"$path": "DevPackages", "$path": "DevPackages",
"Charm": { "Charm": {
"$path": "packages/charm" "$path": "modules/charm"
}, },
"CharmSync": { "CharmSync": {
"$path": "packages/charm-sync" "$path": "modules/charm-sync"
}, },
"ReactCharm": { "ReactCharm": {
"$path": "packages/react" "$path": "modules/react"
},
"VideCharm": {
"$path": "modules/vide"
} }
} }
}, },
"TestService": { "ServerScriptService": {
"$className": "TestService", "$className": "ServerScriptService",
"$properties": {
"ExecuteWithStudioRun": true
},
"Tests": { "Tests": {
"$path": "tests" "$path": "Tests"
} }
} }
} }

View file

@ -8,7 +8,7 @@
"types": "src/index.d.ts", "types": "src/index.d.ts",
"scripts": { "scripts": {
"prepare": "cp ../../LICENSE.md . && cp ../../README.md .", "prepare": "cp ../../LICENSE.md . && cp ../../README.md .",
"wally:install": "wally install" "publish:wally": "wally publish"
}, },
"dependencies": { "dependencies": {
"@rbxts/charm": "workspace:*" "@rbxts/charm": "workspace:*"

View file

@ -8,6 +8,6 @@
"types": "src/index.d.ts", "types": "src/index.d.ts",
"scripts": { "scripts": {
"prepare": "cp ../../LICENSE.md . && cp ../../README.md .", "prepare": "cp ../../LICENSE.md . && cp ../../README.md .",
"wally:install": "wally install" "publish:wally": "wally publish"
} }
} }

View file

@ -1,5 +1,3 @@
_G[script.modules.Promise] = _G[script]
local atom = require(script.atom) local atom = require(script.atom)
local computed = require(script.computed) local computed = require(script.computed)
local effect = require(script.effect) local effect = require(script.effect)

View file

@ -8,9 +8,12 @@
"types": "src/index.d.ts", "types": "src/index.d.ts",
"scripts": { "scripts": {
"prepare": "cp ../../LICENSE.md . && cp ../../README.md .", "prepare": "cp ../../LICENSE.md . && cp ../../README.md .",
"wally:install": "wally install" "publish:wally": "wally publish"
}, },
"dependencies": { "dependencies": {
"@rbxts/charm": "workspace:*" "@rbxts/charm": "workspace:*"
},
"peerDependencies": {
"@rbxts/react": "*"
} }
} }

3
modules/vide/.luaurc Normal file
View file

@ -0,0 +1,3 @@
{
"languageMode": "strict"
}

View file

@ -0,0 +1,6 @@
{
"name": "vide-charm",
"tree": {
"$path": "src"
}
}

19
modules/vide/package.json Normal file
View file

@ -0,0 +1,19 @@
{
"name": "@rbxts/vide-charm",
"version": "0.1.0",
"description": "Vide bindings for Charm",
"repository": "littensy/charm",
"license": "MIT",
"main": "src/init.luau",
"types": "src/index.d.ts",
"scripts": {
"prepare": "cp ../../LICENSE.md . && cp ../../README.md .",
"publish:wally": "wally publish"
},
"dependencies": {
"@rbxts/charm": "workspace:*"
},
"peerDependencies": {
"@rbxts/vide": "*"
}
}

9
modules/vide/src/index.d.ts vendored Normal file
View file

@ -0,0 +1,9 @@
import { Molecule } from "@rbxts/charm";
/**
* Subscribes to the state of an atom and returns a Vide source.
*
* @param molecule The atom or molecule to subscribe to.
* @returns The reactive source.
*/
export function useAtom<T>(atom: Molecule<T>): () => T;

View file

@ -0,0 +1,23 @@
local Charm = require(script.Parent.Charm)
local Vide = require(script.Parent.Vide)
--[=[
Subscribes to the state of an atom and returns a Vide source.
@param molecule The atom or molecule to subscribe to.
@return The reactive source.
]=]
local function useAtom<State>(molecule: () -> State): State
local state = Vide.source(molecule())
local unsubscribe = Charm.subscribe(molecule, function(value)
task.spawn(state, value)
end)
Vide.cleanup(unsubscribe)
return state
end
return {
useAtom = useAtom,
}

7
modules/vide/wally.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "littensy/vide-charm"
version = "0.1.0"
registry = "https://github.com/UpliftGames/wally-index"
realm = "shared"
[dependencies]

View file

@ -2,7 +2,8 @@
"private": true, "private": true,
"scripts": { "scripts": {
"lint": "sh bin/check.sh", "lint": "sh bin/check.sh",
"wally:install": "pnpm recursive run wally:install && rojo sourcemap dev.project.json --output sourcemap.json" "build": "sh bin/build.sh",
"wally": "wally install && rojo sourcemap dev.project.json --output sourcemap.json"
}, },
"devDependencies": { "devDependencies": {
"@rbxts/compiler-types": "3.0.0-types.0", "@rbxts/compiler-types": "3.0.0-types.0",
@ -15,6 +16,6 @@
"eslint-plugin-roblox-ts": "^0.0.36", "eslint-plugin-roblox-ts": "^0.0.36",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"roblox-ts": "^3.0.0", "roblox-ts": "^3.0.0",
"typescript": "^5.6.2" "typescript": "^5.5.3"
} }
} }

86
pnpm-lock.yaml generated
View file

@ -16,10 +16,10 @@ importers:
version: 1.0.809 version: 1.0.809
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^7.18.0 specifier: ^7.18.0
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2) version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: ^7.18.0 specifier: ^7.18.0
version: 7.18.0(eslint@8.57.1)(typescript@5.6.2) version: 7.18.0(eslint@8.57.1)(typescript@5.5.3)
eslint: eslint:
specifier: ^8.57.1 specifier: ^8.57.1
version: 8.57.1 version: 8.57.1
@ -39,22 +39,34 @@ importers:
specifier: ^3.0.0 specifier: ^3.0.0
version: 3.0.0 version: 3.0.0
typescript: typescript:
specifier: ^5.6.2 specifier: ^5.5.3
version: 5.6.2 version: 5.5.3
packages/charm: {} modules/charm: {}
packages/charm-sync: modules/charm-sync:
dependencies: dependencies:
'@rbxts/charm': '@rbxts/charm':
specifier: workspace:* specifier: workspace:*
version: link:../charm version: link:../charm
packages/react: modules/react:
dependencies: dependencies:
'@rbxts/charm': '@rbxts/charm':
specifier: workspace:* specifier: workspace:*
version: link:../charm version: link:../charm
'@rbxts/react':
specifier: '*'
version: 17.2.1
modules/vide:
dependencies:
'@rbxts/charm':
specifier: workspace:*
version: link:../charm
'@rbxts/vide':
specifier: '*'
version: 0.4.6
packages: packages:
@ -108,9 +120,18 @@ packages:
'@rbxts/compiler-types@3.0.0-types.0': '@rbxts/compiler-types@3.0.0-types.0':
resolution: {integrity: sha512-VGOHJPoL7+56NTatMGqQj3K7xWuzEV+aP4QD5vZiHu+bcff3kiTmtoadaF6NkJrmwfFAvbsd4Dg764ZjWNceag==} resolution: {integrity: sha512-VGOHJPoL7+56NTatMGqQj3K7xWuzEV+aP4QD5vZiHu+bcff3kiTmtoadaF6NkJrmwfFAvbsd4Dg764ZjWNceag==}
'@rbxts/react-vendor@17.2.1':
resolution: {integrity: sha512-7DxFweCbhhso4M4tl1pO7Kil9SZrvOl1SoZ4lnwUfoxdHvSmWgeKgaUqd+ZS3/u1E8kRraqGQ56Q8zjUEEUzlA==}
'@rbxts/react@17.2.1':
resolution: {integrity: sha512-iu0RsVvfHroI7l+QXjwE0FiWV2rXoKMxuznDZ8vnx2BsFqrPnCqFjXuNeGYZwibibZC6jbyq7uKl+/8cz7XlsA==}
'@rbxts/types@1.0.809': '@rbxts/types@1.0.809':
resolution: {integrity: sha512-COmNdE5VKq44tU1Sqbj0b70qDcUpBY1Uu5BhNb25v1yJATwcoVjsmYTyaxmRO4EVdqOATjOUBU2jbxZa4K83uw==} resolution: {integrity: sha512-COmNdE5VKq44tU1Sqbj0b70qDcUpBY1Uu5BhNb25v1yJATwcoVjsmYTyaxmRO4EVdqOATjOUBU2jbxZa4K83uw==}
'@rbxts/vide@0.4.6':
resolution: {integrity: sha512-xYtvCS05nGq1YU7fyQVmp4z1CcvuOR+VKpKj/Y7lFPvKobQ3oHTQEzZiJFEMZ+iSeHxwZhwpzVjrP+6+e2EoQw==}
'@roblox-ts/luau-ast@2.0.0': '@roblox-ts/luau-ast@2.0.0':
resolution: {integrity: sha512-cmMi093IdwBOLVxwuordhM8AmtbyTIyRpsTbB0D/JauidW4SXsQRQowSwWjHo4QP0DRJBXvOIlxtqEQi50uNzQ==} resolution: {integrity: sha512-cmMi093IdwBOLVxwuordhM8AmtbyTIyRpsTbB0D/JauidW4SXsQRQowSwWjHo4QP0DRJBXvOIlxtqEQi50uNzQ==}
@ -375,6 +396,7 @@ packages:
eslint@8.57.1: eslint@8.57.1:
resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
hasBin: true hasBin: true
espree@9.6.1: espree@9.6.1:
@ -884,8 +906,16 @@ snapshots:
'@rbxts/compiler-types@3.0.0-types.0': {} '@rbxts/compiler-types@3.0.0-types.0': {}
'@rbxts/react-vendor@17.2.1': {}
'@rbxts/react@17.2.1':
dependencies:
'@rbxts/react-vendor': 17.2.1
'@rbxts/types@1.0.809': {} '@rbxts/types@1.0.809': {}
'@rbxts/vide@0.4.6': {}
'@roblox-ts/luau-ast@2.0.0': {} '@roblox-ts/luau-ast@2.0.0': {}
'@roblox-ts/path-translator@1.1.0': '@roblox-ts/path-translator@1.1.0':
@ -906,21 +936,21 @@ snapshots:
'@types/semver@7.5.8': {} '@types/semver@7.5.8': {}
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)': '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.3))(eslint@8.57.1)(typescript@5.5.3)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.11.1 '@eslint-community/regexpp': 4.11.1
'@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.6.2) '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.5.3)
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.6.2) '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.5.3)
'@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.2) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.5.3)
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
eslint: 8.57.1 eslint: 8.57.1
graphemer: 1.4.0 graphemer: 1.4.0
ignore: 5.3.2 ignore: 5.3.2
natural-compare: 1.4.0 natural-compare: 1.4.0
ts-api-utils: 1.3.0(typescript@5.6.2) ts-api-utils: 1.3.0(typescript@5.5.3)
optionalDependencies: optionalDependencies:
typescript: 5.6.2 typescript: 5.5.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -932,16 +962,16 @@ snapshots:
- supports-color - supports-color
- typescript - typescript
'@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.6.2)': '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.5.3)':
dependencies: dependencies:
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.3)
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
debug: 4.3.7 debug: 4.3.7
eslint: 8.57.1 eslint: 8.57.1
optionalDependencies: optionalDependencies:
typescript: 5.6.2 typescript: 5.5.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -955,15 +985,15 @@ snapshots:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
'@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.6.2)': '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.5.3)':
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.3)
'@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.6.2) '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.5.3)
debug: 4.3.7 debug: 4.3.7
eslint: 8.57.1 eslint: 8.57.1
ts-api-utils: 1.3.0(typescript@5.6.2) ts-api-utils: 1.3.0(typescript@5.5.3)
optionalDependencies: optionalDependencies:
typescript: 5.6.2 typescript: 5.5.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -985,7 +1015,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.2)': '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.3)':
dependencies: dependencies:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0
@ -994,9 +1024,9 @@ snapshots:
is-glob: 4.0.3 is-glob: 4.0.3
minimatch: 9.0.5 minimatch: 9.0.5
semver: 7.6.3 semver: 7.6.3
ts-api-utils: 1.3.0(typescript@5.6.2) ts-api-utils: 1.3.0(typescript@5.5.3)
optionalDependencies: optionalDependencies:
typescript: 5.6.2 typescript: 5.5.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -1015,12 +1045,12 @@ snapshots:
- supports-color - supports-color
- typescript - typescript
'@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.6.2)': '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.5.3)':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1)
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 7.18.0
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 7.18.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2) '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.3)
eslint: 8.57.1 eslint: 8.57.1
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -1564,9 +1594,9 @@ snapshots:
dependencies: dependencies:
is-number: 7.0.0 is-number: 7.0.0
ts-api-utils@1.3.0(typescript@5.6.2): ts-api-utils@1.3.0(typescript@5.5.3):
dependencies: dependencies:
typescript: 5.6.2 typescript: 5.5.3
tslib@1.14.1: {} tslib@1.14.1: {}

View file

@ -1,2 +1,2 @@
packages: packages:
- packages/* - modules/*

View file

@ -1 +1 @@
roots = ["TestService/Tests"] roots = ["ServerScriptService/Tests"]

View file

@ -3,14 +3,12 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
local store = require(ReplicatedStorage.DevPackages.Charm.store) local store = require(ReplicatedStorage.DevPackages.Charm.store)
return function() return function()
local previous = _G.__DEV__
beforeAll(function() beforeAll(function()
_G.__DEV__ = true _G.__DEV__ = true
end) end)
afterAll(function() afterAll(function()
_G.__DEV__ = previous _G.__DEV__ = nil
end) end)
afterEach(function() afterEach(function()

View file

@ -79,7 +79,7 @@ return function()
local patches = serdes(patch.diff(prevState, nextState)) local patches = serdes(patch.diff(prevState, nextState))
local applied = patch.apply(prevState, patches) local applied = patch.apply(prevState, patches)
assert(os.clock() - start < 1e-3, `Performance is not acceptable ({(os.clock() - start) * 1e3}ms)`) assert(os.clock() - start < 10e-3, `Performance is not acceptable ({(os.clock() - start) * 1e3}ms)`)
for index in next, prevState do for index in next, prevState do
expect(applied[index]).to.equal(nextState[index]) expect(applied[index]).to.equal(nextState[index])

View file

@ -1,17 +1,14 @@
local ReplicatedStorage = game:GetService("ReplicatedStorage") local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Charm = require(ReplicatedStorage.DevPackages.Charm) local store = require(ReplicatedStorage.DevPackages.Charm.store)
local store = Charm.store
return function() return function()
local previous = _G.__DEV__
beforeAll(function() beforeAll(function()
_G.__DEV__ = true _G.__DEV__ = true
end) end)
afterAll(function() afterAll(function()
_G.__DEV__ = previous _G.__DEV__ = nil
end) end)
afterEach(function() afterEach(function()

View file

@ -2,4 +2,4 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TestEZ = require(ReplicatedStorage.DevPackages.TestEZ) local TestEZ = require(ReplicatedStorage.DevPackages.TestEZ)
TestEZ.TestBootstrap:run({ script }, TestEZ.Reporters.TextReporter) TestEZ.TestBootstrap:run({ script.Parent }, TestEZ.Reporters.TextReporter)

View file

@ -8,39 +8,39 @@ local renderHook = require(script.Parent.Parent.utils.renderHook)
return function() return function()
it("tracks atom state", function() it("tracks atom state", function()
local source = atom(0) local state = atom(0)
local hook = renderHook(function() local hook = renderHook(function()
return useAtom(source) return useAtom(state)
end) end)
expect(hook.result).to.equal(0) expect(hook.result).to.equal(0)
source(1) state(1)
expect(hook.result).to.equal(1) expect(hook.result).to.equal(1)
end) end)
it("accepts a molecule", function() it("accepts a molecule", function()
local source = atom(0) local state = atom(0)
local hook = renderHook(function() local hook = renderHook(function()
return useAtom(function() return useAtom(function()
return 2 * source() return 2 * state()
end) end)
end) end)
expect(hook.result).to.equal(0) expect(hook.result).to.equal(0)
source(1) state(1)
expect(hook.result).to.equal(2) expect(hook.result).to.equal(2)
end) end)
it("tracks dependencies", function() it("tracks dependencies", function()
local source = atom(0) local state = atom(0)
local hook = renderHook(function() local hook = renderHook(function()
return useAtom(source, { source }) return useAtom(state, { state })
end) end)
expect(hook.result).to.equal(0) expect(hook.result).to.equal(0)
source(1) state(1)
expect(hook.result).to.equal(1) expect(hook.result).to.equal(1)
source = atom(0) state = atom(0)
hook.rerender() hook.rerender()
expect(hook.result).to.equal(0) expect(hook.result).to.equal(0)
source(1) state(1)
expect(hook.result).to.equal(1) expect(hook.result).to.equal(1)
end) end)
end end

View file

@ -0,0 +1,36 @@
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Charm = require(ReplicatedStorage.DevPackages.Charm)
local atom = Charm.atom
local Vide = require(ReplicatedStorage.DevPackages.Vide)
local root = Vide.root
local VideCharm = require(ReplicatedStorage.DevPackages.VideCharm)
local useAtom = VideCharm.useAtom
return function()
it("tracks atom state", function()
local state = atom(0)
local source
local cleanup = root(function()
source = useAtom(state)
end)
expect(source()).to.equal(0)
state(1)
expect(source()).to.equal(1)
cleanup()
end)
it("accepts a molecule", function()
local state = atom(0)
local source
local cleanup = root(function()
source = useAtom(function()
return 2 * state()
end)
end)
expect(source()).to.equal(0)
state(1)
expect(source()).to.equal(2)
cleanup()
end)
end

View file

@ -18,7 +18,7 @@
"typeRoots": ["node_modules/@rbxts"], "typeRoots": ["node_modules/@rbxts"],
// configurable // configurable
"rootDir": "packages", "rootDir": "modules",
"outDir": "out", "outDir": "out",
"incremental": true, "incremental": true,
"tsBuildInfoFile": "out/tsconfig.tsbuildinfo", "tsBuildInfoFile": "out/tsconfig.tsbuildinfo",

View file

@ -2,6 +2,11 @@
# It is not intended for manual editing. # It is not intended for manual editing.
registry = "test" registry = "test"
[[package]]
name = "centau/vide"
version = "0.3.1"
dependencies = []
[[package]] [[package]]
name = "jsdotlua/boolean" name = "jsdotlua/boolean"
version = "1.2.6" version = "1.2.6"
@ -49,27 +54,27 @@ dependencies = []
[[package]] [[package]]
name = "jsdotlua/react" name = "jsdotlua/react"
version = "17.1.0" version = "17.2.0"
dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["shared", "jsdotlua/shared@17.1.0"]] dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["shared", "jsdotlua/shared@17.2.0"]]
[[package]] [[package]]
name = "jsdotlua/react-reconciler" name = "jsdotlua/react-reconciler"
version = "17.1.0" version = "17.2.0"
dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["promise", "jsdotlua/promise@3.5.2"], ["react", "jsdotlua/react@17.1.0"], ["scheduler", "jsdotlua/scheduler@17.1.0"], ["shared", "jsdotlua/shared@17.1.0"]] dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["promise", "jsdotlua/promise@3.5.2"], ["react", "jsdotlua/react@17.2.0"], ["scheduler", "jsdotlua/scheduler@17.2.0"], ["shared", "jsdotlua/shared@17.2.0"]]
[[package]] [[package]]
name = "jsdotlua/react-roblox" name = "jsdotlua/react-roblox"
version = "17.1.0" version = "17.2.0"
dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["react", "jsdotlua/react@17.1.0"], ["react-reconciler", "jsdotlua/react-reconciler@17.1.0"], ["scheduler", "jsdotlua/scheduler@17.1.0"], ["shared", "jsdotlua/shared@17.1.0"]] dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["react", "jsdotlua/react@17.2.0"], ["react-reconciler", "jsdotlua/react-reconciler@17.2.0"], ["scheduler", "jsdotlua/scheduler@17.2.0"], ["shared", "jsdotlua/shared@17.2.0"]]
[[package]] [[package]]
name = "jsdotlua/scheduler" name = "jsdotlua/scheduler"
version = "17.1.0" version = "17.2.0"
dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["shared", "jsdotlua/shared@17.1.0"]] dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"], ["shared", "jsdotlua/shared@17.2.0"]]
[[package]] [[package]]
name = "jsdotlua/shared" name = "jsdotlua/shared"
version = "17.1.0" version = "17.2.0"
dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"]] dependencies = [["luau-polyfill", "jsdotlua/luau-polyfill@1.2.6"]]
[[package]] [[package]]
@ -90,7 +95,7 @@ dependencies = [["collections", "jsdotlua/collections@1.2.6"]]
[[package]] [[package]]
name = "littensy/charm" name = "littensy/charm"
version = "0.1.0" version = "0.1.0"
dependencies = [["React", "jsdotlua/react@17.1.0"], ["ReactRoblox", "jsdotlua/react-roblox@17.1.0"], ["TestEZ", "roblox/testez@0.4.1"]] dependencies = [["React", "jsdotlua/react@17.2.0"], ["ReactRoblox", "jsdotlua/react-roblox@17.2.0"], ["TestEZ", "roblox/testez@0.4.1"], ["Vide", "centau/vide@0.3.1"]]
[[package]] [[package]]
name = "roblox/testez" name = "roblox/testez"

View file

@ -5,6 +5,7 @@ registry = "https://github.com/UpliftGames/wally-index"
realm = "shared" realm = "shared"
[dev-dependencies] [dev-dependencies]
React = "jsdotlua/react@17.1.0" React = "jsdotlua/react@17.2.0"
ReactRoblox = "jsdotlua/react-roblox@17.1.0" ReactRoblox = "jsdotlua/react-roblox@17.2.0"
TestEZ = "roblox/testez@0.4.1" TestEZ = "roblox/testez@0.4.1"
Vide = "centau/vide@0.3.1"