Skip to content

Commit

Permalink
feat: solid-js adapter (#25)
Browse files Browse the repository at this point in the history
* feat: add solid-js adapter

* build: move solid-js dependency to root

* update eslint and tsconfig opts

* test(solid): add basic test

* chore: remove extra log

* test(solid): add setter test

* test(solid): update setter test

* test(solid): add not working test

* test(solid): remove unused async keywords
  • Loading branch information
wobsoriano authored Oct 9, 2023
1 parent 5d93d53 commit cfda5c5
Show file tree
Hide file tree
Showing 9 changed files with 638 additions and 507 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.3",
"@testing-library/vue": "^7.0.0",
"@solidjs/testing-library": "^0.8.4",
"@tsconfig/svelte": "^3.0.0",
"@types/eslint": "^8.44.2",
"@types/luxon": "^3.3.0",
Expand Down Expand Up @@ -92,6 +93,7 @@
"typescript": "^5.1.6",
"vite": "^4.4.4",
"vitest": "^0.33.0",
"vue": "^3.3.4"
"vue": "^3.3.4",
"solid-js": "^1.7.11"
}
}
14 changes: 14 additions & 0 deletions packages/solid-store/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// @ts-check

/** @type {import('eslint').Linter.Config} */
const config = {
parserOptions: {
tsconfigRootDir: __dirname,
project: './tsconfig.json',
},
rules: {
'no-unused-vars': 'off',
},
}

module.exports = config
58 changes: 58 additions & 0 deletions packages/solid-store/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"name": "@tanstack/solid-store",
"author": "Tanner Linsley",
"version": "0.0.0",
"license": "MIT",
"repository": "tanstack/solid-store",
"homepage": "https://tanstack.com/",
"description": "",
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"keywords": [
"store",
"solid",
"typescript"
],
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"scripts": {
"clean": "rimraf ./build && rimraf ./coverage",
"test:eslint": "eslint --ext .ts,.tsx ./src",
"test:types": "tsc",
"test:lib": "vitest run --coverage",
"test:lib:dev": "pnpm run test:lib --watch",
"test:build": "publint --strict",
"build": "tsup"
},
"files": [
"build",
"src"
],
"type": "module",
"types": "build/legacy/index.d.ts",
"main": "build/legacy/index.cjs",
"module": "build/legacy/index.js",
"exports": {
".": {
"import": {
"types": "./build/modern/index.d.ts",
"default": "./build/modern/index.js"
},
"require": {
"types": "./build/modern/index.d.cts",
"default": "./build/modern/index.cjs"
}
},
"./package.json": "./package.json"
},
"sideEffects": false,
"peerDependencies": {
"solid-js": "^1.6.0"
},
"dependencies": {
"@tanstack/store": "workspace:*"
}
}
43 changes: 43 additions & 0 deletions packages/solid-store/src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { render, renderHook } from '@solidjs/testing-library'
import '@testing-library/jest-dom'
import { Store } from '@tanstack/store'
import { useStore } from '../index'

describe('useStore', () => {
it.todo('allows us to select state using a selector', async () => {
const store = new Store({
select: 0,
ignored: 1,
})

function Comp() {
const storeVal = useStore(store, (state) => state.select)

return <p>Store: {storeVal()}</p>
}

const { getByText } = render(() => <Comp />)
expect(getByText('Store: 0')).toBeInTheDocument()
})

it('allows us to select state using a selector', () => {
const store = new Store({
select: 0,
ignored: 1,
})

const { result } = renderHook(() => useStore(store, (state) => state.select))

expect(result()).toBe(0)
})

it('updates accessor value when state is updated', () => {
const store = new Store(0)

const { result } = renderHook(() => useStore(store))

store.setState((prev) => prev + 1)

expect(result()).toBe(1)
})
})
32 changes: 32 additions & 0 deletions packages/solid-store/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { AnyUpdater, Store } from '@tanstack/store'
import type { Accessor} from 'solid-js';
import { onCleanup } from 'solid-js'
import { createStore, reconcile } from 'solid-js/store'

export * from '@tanstack/store'

export type NoInfer<T> = [T][T extends any ? 0 : never]

export function useStore<
TState,
TSelected = NoInfer<TState>,
TUpdater extends AnyUpdater = AnyUpdater,
>(
store: Store<TState, TUpdater>,
selector: (state: NoInfer<TState>) => TSelected = (d) => d as any,
): Accessor<TSelected> {
const [slice, setSlice] = createStore({
value: selector(store.state)
})

const unsub = store.subscribe(() => {
const newValue = selector(store.state)
setSlice('value', reconcile(newValue))
})

onCleanup(() => {
unsub()
})

return () => slice.value
}
9 changes: 9 additions & 0 deletions packages/solid-store/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "solid-js",
"types": ["vitest/globals"]
},
"include": ["src/**/*.ts", "src/**/*.tsx", ".eslintrc.cjs", "tsup.config.js"]
}
9 changes: 9 additions & 0 deletions packages/solid-store/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @ts-check

import { defineConfig } from 'tsup'
import { legacyConfig, modernConfig } from '../../scripts/getTsupConfig.js'

export default defineConfig([
modernConfig({ entry: ['src/*.ts', 'src/*.tsx'] }),
legacyConfig({ entry: ['src/*.ts', 'src/*.tsx'] }),
])
12 changes: 12 additions & 0 deletions packages/solid-store/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
name: 'solid-store',
dir: './src',
watch: false,
environment: 'jsdom',
globals: true,
coverage: { provider: 'istanbul' },
}
})
Loading

0 comments on commit cfda5c5

Please sign in to comment.