diff --git a/packages/atom-solid/.gitignore b/packages/atom-solid/.gitignore new file mode 100644 index 0000000..6140ecf --- /dev/null +++ b/packages/atom-solid/.gitignore @@ -0,0 +1,14 @@ +coverage/ +*.tsbuildinfo +node_modules/ +.ultra.cache.json +.DS_Store +tmp/ +build/ +dist/ +.direnv/ + +# files +/src/tsconfig.json +/dist + diff --git a/packages/atom-solid/.prettierignore b/packages/atom-solid/.prettierignore new file mode 100644 index 0000000..df19601 --- /dev/null +++ b/packages/atom-solid/.prettierignore @@ -0,0 +1,3 @@ +*.js +*.ts + diff --git a/packages/atom-solid/CHANGELOG.md b/packages/atom-solid/CHANGELOG.md new file mode 100644 index 0000000..4dc68c6 --- /dev/null +++ b/packages/atom-solid/CHANGELOG.md @@ -0,0 +1,2 @@ +# Changelog + diff --git a/packages/atom-solid/LICENSE b/packages/atom-solid/LICENSE new file mode 100644 index 0000000..c8c4a82 --- /dev/null +++ b/packages/atom-solid/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2023-present The Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/packages/atom-solid/README.md b/packages/atom-solid/README.md new file mode 100644 index 0000000..22f23d9 --- /dev/null +++ b/packages/atom-solid/README.md @@ -0,0 +1,4 @@ +# `@effect-atom/atom-solid` + +SolidJS bindings for `@effect-atom/atom`. + diff --git a/packages/atom-solid/docgen.json b/packages/atom-solid/docgen.json new file mode 100644 index 0000000..ef8e5ee --- /dev/null +++ b/packages/atom-solid/docgen.json @@ -0,0 +1,25 @@ +{ + "exclude": ["src/internal/**/*.ts"], + "theme": "mikearnaldi/just-the-docs", + "parseCompilerOptions": { + "noEmit": true, + "strict": true, + "target": "es2015", + "lib": ["es2015"], + "paths": { + "@effect-atom/atom": ["./src/index.ts"], + "@effect-atom/atom/*": ["./src/*"] + } + }, + "examplesCompilerOptions": { + "noEmit": true, + "strict": true, + "target": "es2015", + "lib": ["es2015"], + "paths": { + "@effect-atom/atom": ["./src/index.ts"], + "@effect-atom/atom/*": ["./src/*"] + } + } +} + diff --git a/packages/atom-solid/package.json b/packages/atom-solid/package.json new file mode 100644 index 0000000..491303f --- /dev/null +++ b/packages/atom-solid/package.json @@ -0,0 +1,37 @@ +{ + "name": "@effect-atom/atom-solid", + "version": "0.4.5", + "description": "Reactive toolkit for Effect", + "type": "module", + "publishConfig": { + "access": "public", + "directory": "dist" + }, + "repository": { + "type": "git", + "url": "https://github.com/tim-smart/effect-atom.git" + }, + "homepage": "https://github.com/tim-smart/effect-atom", + "scripts": { + "build": "pnpm build-esm && pnpm build-cjs && pnpm build-annotate && build-utils pack-v2", + "build-esm": "tsc -b tsconfig.build.json", + "build-cjs": "babel build/esm --plugins @babel/transform-export-namespace-from --plugins @babel/transform-modules-commonjs --out-dir build/cjs --source-maps", + "build-annotate": "babel build --plugins annotate-pure-calls --out-dir build --source-maps" + }, + "keywords": [], + "author": "Effect contributors", + "license": "MIT", + "sideEffects": [], + "devDependencies": { + "effect": "^3.19.0", + "solid-js": "^1.9.0" + }, + "peerDependencies": { + "effect": "^3.19", + "solid-js": ">=1 <2" + }, + "dependencies": { + "@effect-atom/atom": "workspace:^" + } +} + diff --git a/packages/atom-solid/src/Hooks.ts b/packages/atom-solid/src/Hooks.ts new file mode 100644 index 0000000..eeb218c --- /dev/null +++ b/packages/atom-solid/src/Hooks.ts @@ -0,0 +1,201 @@ +/** + * @since 1.0.0 + */ +import * as Atom from "@effect-atom/atom/Atom" +import type * as AtomRef from "@effect-atom/atom/AtomRef" +import * as Registry from "@effect-atom/atom/Registry" +import type * as Result from "@effect-atom/atom/Result" +import * as Cause from "effect/Cause" +import * as Effect from "effect/Effect" +import * as Exit from "effect/Exit" +import { globalValue } from "effect/GlobalValue" +import type { Accessor } from "solid-js" +import { createSignal, onCleanup, useContext } from "solid-js" +import { RegistryContext } from "./RegistryContext.js" + +const initialValuesSet = globalValue( + "@effect-atom/atom-solid/initialValuesSet", + () => new WeakMap>>() +) + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomInitialValues = (initialValues: Iterable, any]>): void => { + const registry = useContext(RegistryContext) + let set = initialValuesSet.get(registry) + if (set === undefined) { + set = new WeakSet() + initialValuesSet.set(registry, set) + } + for (const [atom, value] of initialValues) { + if (!set.has(atom)) { + set.add(atom) + ;(registry as any).ensureNode(atom).setValue(value) + } + } +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomValue: { + (atom: Atom.Atom): Accessor + (atom: Atom.Atom, f: (_: A) => B): Accessor +} = (atom: Atom.Atom, f?: (_: A) => A): Accessor => { + const registry = useContext(RegistryContext) + return createAtomAccessor(registry, f ? Atom.map(atom, f) : atom) +} + +function createAtomAccessor(registry: Registry.Registry, atom: Atom.Atom): Accessor { + const [value, setValue] = createSignal(registry.get(atom)) + onCleanup(registry.subscribe(atom, setValue as any)) + return value +} + +function mountAtom(registry: Registry.Registry, atom: Atom.Atom): void { + onCleanup(registry.mount(atom)) +} + +function setAtom( + registry: Registry.Registry, + atom: Atom.Writable, + options?: { + readonly mode?: ([R] extends [Result.Result] ? Mode : "value") | undefined + } +): "promise" extends Mode ? ( + (value: W) => Promise> + ) : + "promiseExit" extends Mode ? ( + (value: W) => Promise, Result.Result.Failure>> + ) : + ((value: W | ((value: R) => W)) => void) +{ + if (options?.mode === "promise" || options?.mode === "promiseExit") { + return ((value: W) => { + registry.set(atom, value) + const promise = Effect.runPromiseExit( + Registry.getResult(registry, atom as Atom.Atom>, { suspendOnWaiting: true }) + ) + return options!.mode === "promise" ? promise.then(flattenExit) : promise + }) as any + } + return ((value: W | ((value: R) => W)) => { + registry.set(atom, typeof value === "function" ? (value as any)(registry.get(atom)) : value) + }) as any +} + +const flattenExit = (exit: Exit.Exit): A => { + if (Exit.isSuccess(exit)) return exit.value + throw Cause.squash(exit.cause) +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomMount = (atom: Atom.Atom): void => { + const registry = useContext(RegistryContext) + mountAtom(registry, atom) +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomSet = < + R, + W, + Mode extends "value" | "promise" | "promiseExit" = never +>( + atom: Atom.Writable, + options?: { + readonly mode?: ([R] extends [Result.Result] ? Mode : "value") | undefined + } +): "promise" extends Mode ? ( + (value: W) => Promise> + ) : + "promiseExit" extends Mode ? ( + (value: W) => Promise, Result.Result.Failure>> + ) : + ((value: W | ((value: R) => W)) => void) => +{ + const registry = useContext(RegistryContext) + mountAtom(registry, atom) + return setAtom(registry, atom, options) +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomRefresh = (atom: Atom.Atom): () => void => { + const registry = useContext(RegistryContext) + mountAtom(registry, atom) + return () => registry.refresh(atom) +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtom = ( + atom: Atom.Writable, + options?: { + readonly mode?: ([R] extends [Result.Result] ? Mode : "value") | undefined + } +): readonly [ + value: Accessor, + write: "promise" extends Mode ? ( + (value: W) => Promise> + ) : + "promiseExit" extends Mode ? ( + (value: W) => Promise, Result.Result.Failure>> + ) : + ((value: W | ((value: R) => W)) => void) +] => { + const registry = useContext(RegistryContext) + return [ + createAtomAccessor(registry, atom), + setAtom(registry, atom, options) + ] as const +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomSubscribe = ( + atom: Atom.Atom, + f: (_: A) => void, + options?: { readonly immediate?: boolean } +): void => { + const registry = useContext(RegistryContext) + onCleanup(registry.subscribe(atom, f, options)) +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomRef = (ref: AtomRef.ReadonlyRef): Accessor => { + const [value, setValue] = createSignal(ref.value) + onCleanup(ref.subscribe(setValue)) + return value +} + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomRefProp = (ref: AtomRef.AtomRef, prop: K): AtomRef.AtomRef => + ref.prop(prop) + +/** + * @since 1.0.0 + * @category hooks + */ +export const useAtomRefPropValue = (ref: AtomRef.AtomRef, prop: K): Accessor => + useAtomRef(useAtomRefProp(ref, prop)) diff --git a/packages/atom-solid/src/RegistryContext.ts b/packages/atom-solid/src/RegistryContext.ts new file mode 100644 index 0000000..18dc8fd --- /dev/null +++ b/packages/atom-solid/src/RegistryContext.ts @@ -0,0 +1,43 @@ +/** + * @since 1.0.0 + */ +import type * as Atom from "@effect-atom/atom/Atom" +import * as Registry from "@effect-atom/atom/Registry" +import type { JSX } from "solid-js" +import { createComponent, createContext, onCleanup } from "solid-js" + +const defaultScheduleTask = (f: () => void) => queueMicrotask(f) + +/** + * @since 1.0.0 + * @category context + */ +export const RegistryContext = createContext(Registry.make({ + scheduleTask: defaultScheduleTask +})) + +/** + * @since 1.0.0 + * @category context + */ +export const RegistryProvider = (options: { + readonly children?: JSX.Element | undefined + readonly initialValues?: Iterable, any]> | undefined + readonly scheduleTask?: ((f: () => void) => void) | undefined + readonly timeoutResolution?: number | undefined + readonly defaultIdleTTL?: number | undefined +}) => { + const registry = Registry.make({ + scheduleTask: options.scheduleTask ?? defaultScheduleTask, + initialValues: options.initialValues, + timeoutResolution: options.timeoutResolution, + defaultIdleTTL: options.defaultIdleTTL + }) + onCleanup(() => registry.dispose()) + return createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return options.children + } + }) +} diff --git a/packages/atom-solid/src/index.ts b/packages/atom-solid/src/index.ts new file mode 100644 index 0000000..e3ccf76 --- /dev/null +++ b/packages/atom-solid/src/index.ts @@ -0,0 +1,57 @@ +/** + * @since 1.0.0 + */ + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as Atom from "@effect-atom/atom/Atom" + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as Registry from "@effect-atom/atom/Registry" + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as Result from "@effect-atom/atom/Result" + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as AtomRef from "@effect-atom/atom/AtomRef" + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as AtomHttpApi from "@effect-atom/atom/AtomHttpApi" + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as AtomRpc from "@effect-atom/atom/AtomRpc" + +/** + * @since 1.0.0 + * @category re-exports + */ +export * as Hydration from "@effect-atom/atom/Hydration" + +/** + * @since 1.0.0 + * @category hooks + */ +export * from "./Hooks.js" + +/** + * @since 1.0.0 + * @category context + */ +export * from "./RegistryContext.js" diff --git a/packages/atom-solid/test/index.test.ts b/packages/atom-solid/test/index.test.ts new file mode 100644 index 0000000..cc4d1a1 --- /dev/null +++ b/packages/atom-solid/test/index.test.ts @@ -0,0 +1,264 @@ +import * as Atom from "@effect-atom/atom/Atom" +import * as AtomRef from "@effect-atom/atom/AtomRef" +import * as Registry from "@effect-atom/atom/Registry" +import type * as Result from "@effect-atom/atom/Result" +import * as Effect from "effect/Effect" +import * as Exit from "effect/Exit" +import { createComponent, createRoot } from "solid-js" +import { describe, expect, it, vi } from "vitest" +import { + RegistryContext, + useAtom, + useAtomInitialValues, + useAtomMount, + useAtomRef, + useAtomRefProp, + useAtomRefPropValue, + useAtomRefresh, + useAtomSet, + useAtomSubscribe, + useAtomValue +} from "../src/index.js" + +describe("atom-solid", () => { + it("useAtomValue reads and updates", () => { + const atom = Atom.make(42) + const registry = Registry.make() + + createRoot((dispose) => { + let value!: () => number + + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + value = useAtomValue(atom) + return null as any + }, {}) + } + }) + + expect(value()).toBe(42) + registry.set(atom, 100) + expect(value()).toBe(100) + + dispose() + }) + }) + + it("useAtom returns accessor + setter", () => { + const atom = Atom.make(0) + const registry = Registry.make() + + createRoot((dispose) => { + let value!: () => number + let set!: (value: number | ((n: number) => number)) => void + + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + ;[value, set] = useAtom(atom) + return null as any + }, {}) + } + }) + + expect(value()).toBe(0) + set(1) + expect(value()).toBe(1) + set((n) => n + 1) + expect(value()).toBe(2) + + dispose() + }) + }) + + it("useAtomSet writes values", () => { + const atom = Atom.make(0) + const registry = Registry.make() + + createRoot((dispose) => { + let set!: (value: number | ((n: number) => number)) => void + + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + set = useAtomSet(atom) + return null as any + }, {}) + } + }) + + set(1) + expect(registry.get(atom)).toBe(1) + set((n) => n + 1) + expect(registry.get(atom)).toBe(2) + + dispose() + }) + }) + + it("useAtomSubscribe receives updates (immediate)", () => { + const atom = Atom.make("a") + const registry = Registry.make() + + createRoot((dispose) => { + const spy = vi.fn<(value: string) => void>() + + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + useAtomSubscribe(atom, spy, { immediate: true }) + return null as any + }, {}) + } + }) + + expect(spy).toHaveBeenCalledTimes(1) + expect(spy).toHaveBeenCalledWith("a") + + registry.set(atom, "b") + expect(spy).toHaveBeenCalledTimes(2) + expect(spy).toHaveBeenLastCalledWith("b") + + dispose() + }) + }) + + it("useAtomRefresh triggers recomputation", () => { + const nowAtom = Atom.make(Effect.sync(() => Date.now())) + const registry = Registry.make() + + createRoot((dispose) => { + let now!: () => number + let refresh!: () => void + + const originalNow = Date.now + let n = 0 + // Deterministic timestamps so we can assert a change. + Date.now = () => ++n + + try { + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + now = useAtomValue(nowAtom, (r) => (r._tag === "Success" ? r.value : -1)) + refresh = useAtomRefresh(nowAtom) + useAtomMount(nowAtom) + return null as any + }, {}) + } + }) + + const first = now() + refresh() + const second = now() + expect(second).not.toBe(first) + } finally { + Date.now = originalNow + dispose() + } + }) + }) + + it("useAtomRef + prop helpers", () => { + const ref = AtomRef.make({ a: 1, b: 2 }) + + createRoot((dispose) => { + let whole!: () => { a: number; b: number } + let aRef!: AtomRef.AtomRef + let aValue!: () => number + + createComponent(() => { + whole = useAtomRef(ref) + aRef = useAtomRefProp(ref, "a") + aValue = useAtomRefPropValue(ref, "a") + return null as any + }, {}) + + expect(whole().a).toBe(1) + expect(aRef.value).toBe(1) + expect(aValue()).toBe(1) + + ref.set({ a: 10, b: 2 }) + expect(whole().a).toBe(10) + expect(aRef.value).toBe(10) + expect(aValue()).toBe(10) + + dispose() + }) + }) + + it("useAtomSet supports Result atoms (promise + promiseExit)", async () => { + const fnAtom = Atom.fn((n: number) => Effect.succeed(n * 2)) + const registry = Registry.make() + + await new Promise((outerResolve, outerReject) => { + createRoot((dispose) => { + let run!: (n: number) => Promise + let runExit!: (n: number) => Promise> + let last!: () => Result.Result + + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + run = useAtomSet(fnAtom, { mode: "promise" as const }) + runExit = useAtomSet(fnAtom, { mode: "promiseExit" as const }) as any + last = useAtomValue(fnAtom) + return null as any + }, {}) + } + }) + + Promise.resolve() + .then(async () => { + expect(last()._tag).toBe("Initial") + + const value = await run(21) + expect(value).toBe(42) + expect(last()._tag).toBe("Success") + + const exit = await runExit(10) + expect(Exit.isSuccess(exit)).toBe(true) + if (Exit.isSuccess(exit)) { + expect(exit.value).toBe(20) + } + }) + .then(() => { + dispose() + outerResolve() + }) + .catch((e) => { + dispose() + outerReject(e) + }) + }) + }) + }) + + it("useAtomInitialValues only applies once per atom per registry", () => { + const atom = Atom.make(0) + const registry = Registry.make() + + createRoot((dispose) => { + createComponent(RegistryContext.Provider, { + value: registry, + get children() { + return createComponent(() => { + useAtomInitialValues([[atom, 1]]) + useAtomInitialValues([[atom, 2]]) + return null as any + }, {}) + } + }) + + expect(registry.get(atom)).toBe(1) + dispose() + }) + }) +}) diff --git a/packages/atom-solid/tsconfig.build.json b/packages/atom-solid/tsconfig.build.json new file mode 100644 index 0000000..e7b7f06 --- /dev/null +++ b/packages/atom-solid/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.src.json", + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/build.tsbuildinfo", + "outDir": "build/esm", + "declarationDir": "build/dts", + "stripInternal": true + }, + "references": [{ "path": "../atom" }] +} + diff --git a/packages/atom-solid/tsconfig.examples.json b/packages/atom-solid/tsconfig.examples.json new file mode 100644 index 0000000..2815f41 --- /dev/null +++ b/packages/atom-solid/tsconfig.examples.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.base.json", + "include": [ + "examples" + ], + "references": [ + { + "path": "tsconfig.build.json" + } + ], + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/examples.tsbuildinfo", + "rootDir": "examples", + "noEmit": true + } +} + diff --git a/packages/atom-solid/tsconfig.json b/packages/atom-solid/tsconfig.json new file mode 100644 index 0000000..6591e4a --- /dev/null +++ b/packages/atom-solid/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.base.json", + "references": [ + { + "path": "tsconfig.src.json" + }, + { + "path": "tsconfig.test.json" + }, + { + "path": "tsconfig.examples.json" + } + ] +} + diff --git a/packages/atom-solid/tsconfig.src.json b/packages/atom-solid/tsconfig.src.json new file mode 100644 index 0000000..4f235a6 --- /dev/null +++ b/packages/atom-solid/tsconfig.src.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src"], + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/src.tsbuildinfo", + "rootDir": "src", + "outDir": "build/src" + }, + "references": [{ "path": "../atom" }] +} + diff --git a/packages/atom-solid/tsconfig.test.json b/packages/atom-solid/tsconfig.test.json new file mode 100644 index 0000000..8c03632 --- /dev/null +++ b/packages/atom-solid/tsconfig.test.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["test"], + "references": [ + { + "path": "tsconfig.src.json" + } + ], + "compilerOptions": { + "tsBuildInfoFile": ".tsbuildinfo/test.tsbuildinfo", + "rootDir": "test", + "noEmit": true + } +} + diff --git a/packages/atom-solid/vitest.config.ts b/packages/atom-solid/vitest.config.ts new file mode 100644 index 0000000..a872133 --- /dev/null +++ b/packages/atom-solid/vitest.config.ts @@ -0,0 +1,17 @@ +import * as path from "path" +import { defineConfig } from "vitest/config" + +export default defineConfig({ + test: { + include: ["./test/**/*.test.ts"] + }, + resolve: { + alias: { + "@effect-atom/atom/test": path.join(__dirname, "../atom/test"), + "@effect-atom/atom": path.join(__dirname, "../atom/src"), + "@effect-atom/atom-solid/test": path.join(__dirname, "test"), + "@effect-atom/atom-solid": path.join(__dirname, "src") + } + } +}) + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6d1eb1..9143eaa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -179,6 +179,20 @@ importers: version: 0.27.0 publishDirectory: dist + packages/atom-solid: + dependencies: + '@effect-atom/atom': + specifier: workspace:^ + version: link:../atom/dist + devDependencies: + effect: + specifier: ^3.19.0 + version: 3.19.15 + solid-js: + specifier: ^1.9.0 + version: 1.9.11 + publishDirectory: dist + packages/atom-vue: dependencies: '@effect-atom/atom': @@ -3738,6 +3752,16 @@ packages: engines: {node: '>=10'} hasBin: true + seroval-plugins@1.5.0: + resolution: {integrity: sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.0: + resolution: {integrity: sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw==} + engines: {node: '>=10'} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -3796,6 +3820,9 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + solid-js@1.9.11: + resolution: {integrity: sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -8227,6 +8254,12 @@ snapshots: semver@7.7.3: {} + seroval-plugins@1.5.0(seroval@1.5.0): + dependencies: + seroval: 1.5.0 + + seroval@1.5.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -8297,6 +8330,12 @@ snapshots: slash@3.0.0: {} + solid-js@1.9.11: + dependencies: + csstype: 3.2.3 + seroval: 1.5.0 + seroval-plugins: 1.5.0(seroval@1.5.0) + source-map-js@1.2.1: {} source-map@0.6.1: {} diff --git a/tsconfig.base.json b/tsconfig.base.json index 2f66daf..ac77fd6 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -43,7 +43,10 @@ "@effect-atom/atom-react/*": ["./packages/atom-react/src/*.js"], "@effect-atom/atom-react": ["./packages/atom-react/src/index.js"], "@effect-atom/atom-vue/test/*": ["./packages/atom-vue/test/*.js"], - "@effect-atom/atom-vue/*": ["./packages/atom-vue/src/*.js"] + "@effect-atom/atom-vue/*": ["./packages/atom-vue/src/*.js"], + "@effect-atom/atom-solid/test/*": ["./packages/atom-solid/test/*.js"], + "@effect-atom/atom-solid/*": ["./packages/atom-solid/src/*.js"], + "@effect-atom/atom-solid": ["./packages/atom-solid/src/index.js"] }, "plugins": [{ "name": "@effect/language-service" }] } diff --git a/tsconfig.build.json b/tsconfig.build.json index 2fc0c7e..623cee5 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -9,6 +9,9 @@ }, { "path": "packages/atom-vue/tsconfig.build.json" + }, + { + "path": "packages/atom-solid/tsconfig.build.json" } ] } diff --git a/tsconfig.json b/tsconfig.json index d2c1067..9bfd519 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,9 @@ }, { "path": "packages/atom-vue" + }, + { + "path": "packages/atom-solid" } ] }