From 7ba4040e840fcf6e2972edf9b4ae318438039f21 Mon Sep 17 00:00:00 2001 From: David Sheldrick Date: Mon, 15 Jul 2024 12:18:59 +0100 Subject: [PATCH] Split @tldraw/state into @tldraw/state and @tldraw/state-react (#4170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backend code uses `@tldraw/state`, which is fine, but the package has a peer dependency on `react`, which is not fine to impose on backend consumers. So let's split this up again. ### Change type - [ ] `bugfix` - [ ] `improvement` - [ ] `feature` - [x] `api` - [x] `other` ### Test plan 1. Create a shape... 2. - [ ] Unit tests - [ ] End to end tests ### Release notes - Fixed a bug with… --- packages/editor/api-report.md | 12 +-- packages/editor/package.json | 1 + packages/editor/src/index.ts | 12 +-- .../lib/components/GeometryDebuggingView.tsx | 2 +- .../src/lib/components/LiveCollaborators.tsx | 2 +- packages/editor/src/lib/components/Shape.tsx | 2 +- .../default-components/DefaultCanvas.tsx | 3 +- .../DefaultErrorFallback.tsx | 2 +- .../DefaultSelectionForeground.tsx | 2 +- .../DefaultShapeIndicator.tsx | 2 +- .../DefaultShapeIndicators.tsx | 2 +- .../editor/shapes/group/DashedOutlineBox.tsx | 2 +- packages/editor/src/lib/hooks/useCursor.ts | 2 +- packages/editor/src/lib/hooks/useDarkMode.ts | 2 +- .../editor/src/lib/hooks/useDocumentEvents.ts | 2 +- .../editor/src/lib/hooks/useIsCropping.ts | 2 +- .../editor/src/lib/hooks/useIsDarkMode.ts | 2 +- packages/editor/src/lib/hooks/useIsEditing.ts | 2 +- packages/editor/src/lib/hooks/usePeerIds.ts | 2 +- packages/editor/src/lib/hooks/usePresence.ts | 2 +- packages/editor/tsconfig.json | 4 +- packages/state-react/LICENSE.md | 1 + packages/state-react/README.md | 3 + packages/state-react/api-extractor.json | 4 + packages/state-react/api-report.md | 47 ++++++++++++ packages/state-react/package.json | 74 +++++++++++++++++++ packages/state-react/src/index.ts | 7 ++ .../src/lib}/track.test.tsx | 2 +- .../react => state-react/src/lib}/track.ts | 0 .../src/lib}/useAtom.test.tsx | 2 +- .../react => state-react/src/lib}/useAtom.ts | 2 +- .../src/lib}/useComputed.test.tsx | 3 +- .../src/lib}/useComputed.ts | 2 +- .../src/lib}/useQuickReactor.ts | 2 +- .../src/lib}/useReactor.ts | 2 +- .../src/lib}/useStateTracking.test.tsx | 2 +- .../src/lib}/useStateTracking.ts | 2 +- .../src/lib}/useValue.test.tsx | 3 +- .../react => state-react/src/lib}/useValue.ts | 2 +- packages/state-react/tsconfig.json | 14 ++++ packages/state/api-report.md | 33 --------- packages/state/package.json | 8 +- packages/state/src/index.ts | 36 ++++++++- packages/state/src/lib/{core => }/ArraySet.ts | 0 packages/state/src/lib/{core => }/Atom.ts | 0 packages/state/src/lib/{core => }/Computed.ts | 0 .../src/lib/{core => }/EffectScheduler.ts | 0 .../state/src/lib/{core => }/HistoryBuffer.ts | 0 .../__tests__/EffectScheduler.test.ts | 0 .../__tests__/HistoryBuffer.test.ts | 0 .../lib/{core => }/__tests__/arraySet.test.ts | 0 .../src/lib/{core => }/__tests__/atom.test.ts | 0 .../lib/{core => }/__tests__/capture.test.ts | 0 .../lib/{core => }/__tests__/computed.test.ts | 0 .../lib/{core => }/__tests__/errors.test.ts | 0 .../{core => }/__tests__/fuzz.tlstate.test.ts | 0 .../lib/{core => }/__tests__/reactor.test.ts | 0 .../{core => }/__tests__/transactions.test.ts | 0 packages/state/src/lib/{core => }/capture.ts | 0 .../state/src/lib/{core => }/constants.ts | 0 packages/state/src/lib/core/index.ts | 27 ------- packages/state/src/lib/{core => }/helpers.ts | 0 packages/state/src/lib/{core => }/isSignal.ts | 0 packages/state/src/lib/react/index.ts | 7 -- .../state/src/lib/{core => }/transactions.ts | 0 packages/state/src/lib/{core => }/types.ts | 0 packages/state/src/lib/{core => }/warnings.ts | 0 yarn.lock | 15 +++- 68 files changed, 243 insertions(+), 121 deletions(-) create mode 100644 packages/state-react/LICENSE.md create mode 100644 packages/state-react/README.md create mode 100644 packages/state-react/api-extractor.json create mode 100644 packages/state-react/api-report.md create mode 100644 packages/state-react/package.json create mode 100644 packages/state-react/src/index.ts rename packages/{state/src/lib/react => state-react/src/lib}/track.test.tsx (99%) rename packages/{state/src/lib/react => state-react/src/lib}/track.ts (100%) rename packages/{state/src/lib/react => state-react/src/lib}/useAtom.test.tsx (97%) rename packages/{state/src/lib/react => state-react/src/lib}/useAtom.ts (95%) rename packages/{state/src/lib/react => state-react/src/lib}/useComputed.test.tsx (97%) rename packages/{state/src/lib/react => state-react/src/lib}/useComputed.ts (94%) rename packages/{state/src/lib/react => state-react/src/lib}/useQuickReactor.ts (86%) rename packages/{state/src/lib/react => state-react/src/lib}/useReactor.ts (92%) rename packages/{state/src/lib/react => state-react/src/lib}/useStateTracking.test.tsx (98%) rename packages/{state/src/lib/react => state-react/src/lib}/useStateTracking.ts (98%) rename packages/{state/src/lib/react => state-react/src/lib}/useValue.test.tsx (97%) rename packages/{state/src/lib/react => state-react/src/lib}/useValue.ts (98%) create mode 100644 packages/state-react/tsconfig.json rename packages/state/src/lib/{core => }/ArraySet.ts (100%) rename packages/state/src/lib/{core => }/Atom.ts (100%) rename packages/state/src/lib/{core => }/Computed.ts (100%) rename packages/state/src/lib/{core => }/EffectScheduler.ts (100%) rename packages/state/src/lib/{core => }/HistoryBuffer.ts (100%) rename packages/state/src/lib/{core => }/__tests__/EffectScheduler.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/HistoryBuffer.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/arraySet.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/atom.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/capture.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/computed.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/errors.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/fuzz.tlstate.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/reactor.test.ts (100%) rename packages/state/src/lib/{core => }/__tests__/transactions.test.ts (100%) rename packages/state/src/lib/{core => }/capture.ts (100%) rename packages/state/src/lib/{core => }/constants.ts (100%) delete mode 100644 packages/state/src/lib/core/index.ts rename packages/state/src/lib/{core => }/helpers.ts (100%) rename packages/state/src/lib/{core => }/isSignal.ts (100%) delete mode 100644 packages/state/src/lib/react/index.ts rename packages/state/src/lib/{core => }/transactions.ts (100%) rename packages/state/src/lib/{core => }/types.ts (100%) rename packages/state/src/lib/{core => }/warnings.ts (100%) diff --git a/packages/editor/api-report.md b/packages/editor/api-report.md index a0365c4b7..f0040ee4c 100644 --- a/packages/editor/api-report.md +++ b/packages/editor/api-report.md @@ -79,15 +79,15 @@ import { TLStoreSnapshot } from '@tldraw/tlschema'; import { TLUnknownBinding } from '@tldraw/tlschema'; import { TLUnknownShape } from '@tldraw/tlschema'; import { TLVideoAsset } from '@tldraw/tlschema'; -import { track } from '@tldraw/state'; +import { track } from '@tldraw/state-react'; import { transact } from '@tldraw/state'; import { transaction } from '@tldraw/state'; import { UnknownRecord } from '@tldraw/store'; -import { useComputed } from '@tldraw/state'; -import { useQuickReactor } from '@tldraw/state'; -import { useReactor } from '@tldraw/state'; -import { useStateTracking } from '@tldraw/state'; -import { useValue } from '@tldraw/state'; +import { useComputed } from '@tldraw/state-react'; +import { useQuickReactor } from '@tldraw/state-react'; +import { useReactor } from '@tldraw/state-react'; +import { useStateTracking } from '@tldraw/state-react'; +import { useValue } from '@tldraw/state-react'; import { VecModel } from '@tldraw/tlschema'; import { whyAmIRunning } from '@tldraw/state'; diff --git a/packages/editor/package.json b/packages/editor/package.json index 1e85f7b44..d6e3c23e3 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -46,6 +46,7 @@ }, "dependencies": { "@tldraw/state": "workspace:*", + "@tldraw/state-react": "workspace:*", "@tldraw/store": "workspace:*", "@tldraw/tlschema": "workspace:*", "@tldraw/utils": "workspace:*", diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index 81dd0688a..5134f33c5 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -22,18 +22,20 @@ export { atom, computed, react, - track, transact, transaction, + whyAmIRunning, + type Atom, + type Signal, +} from '@tldraw/state' +export { + track, useComputed, useQuickReactor, useReactor, useStateTracking, useValue, - whyAmIRunning, - type Atom, - type Signal, -} from '@tldraw/state' +} from '@tldraw/state-react' export { ErrorScreen, LoadingScreen, diff --git a/packages/editor/src/lib/components/GeometryDebuggingView.tsx b/packages/editor/src/lib/components/GeometryDebuggingView.tsx index 2e3097fb1..a7925ec9b 100644 --- a/packages/editor/src/lib/components/GeometryDebuggingView.tsx +++ b/packages/editor/src/lib/components/GeometryDebuggingView.tsx @@ -1,4 +1,4 @@ -import { track } from '@tldraw/state' +import { track } from '@tldraw/state-react' import { modulate } from '@tldraw/utils' import { useEffect, useState } from 'react' import { useEditor } from '../hooks/useEditor' diff --git a/packages/editor/src/lib/components/LiveCollaborators.tsx b/packages/editor/src/lib/components/LiveCollaborators.tsx index e4d21f04f..e6854bc98 100644 --- a/packages/editor/src/lib/components/LiveCollaborators.tsx +++ b/packages/editor/src/lib/components/LiveCollaborators.tsx @@ -1,4 +1,4 @@ -import { track } from '@tldraw/state' +import { track } from '@tldraw/state-react' import { TLInstancePresence } from '@tldraw/tlschema' import { useEffect, useRef, useState } from 'react' import { Editor } from '../editor/Editor' diff --git a/packages/editor/src/lib/components/Shape.tsx b/packages/editor/src/lib/components/Shape.tsx index aab6e97b4..0908ece05 100644 --- a/packages/editor/src/lib/components/Shape.tsx +++ b/packages/editor/src/lib/components/Shape.tsx @@ -1,4 +1,4 @@ -import { useQuickReactor, useStateTracking } from '@tldraw/state' +import { useQuickReactor, useStateTracking } from '@tldraw/state-react' import { TLShape, TLShapeId } from '@tldraw/tlschema' import { memo, useCallback, useRef } from 'react' import { ShapeUtil } from '../editor/shapes/ShapeUtil' diff --git a/packages/editor/src/lib/components/default-components/DefaultCanvas.tsx b/packages/editor/src/lib/components/default-components/DefaultCanvas.tsx index 855da6abe..a9504945d 100644 --- a/packages/editor/src/lib/components/default-components/DefaultCanvas.tsx +++ b/packages/editor/src/lib/components/default-components/DefaultCanvas.tsx @@ -1,4 +1,5 @@ -import { react, useQuickReactor, useValue } from '@tldraw/state' +import { react } from '@tldraw/state' +import { useQuickReactor, useValue } from '@tldraw/state-react' import { TLHandle, TLShapeId } from '@tldraw/tlschema' import { dedupe, modulate, objectMapValues } from '@tldraw/utils' import classNames from 'classnames' diff --git a/packages/editor/src/lib/components/default-components/DefaultErrorFallback.tsx b/packages/editor/src/lib/components/default-components/DefaultErrorFallback.tsx index 61b74d19e..65460d54c 100644 --- a/packages/editor/src/lib/components/default-components/DefaultErrorFallback.tsx +++ b/packages/editor/src/lib/components/default-components/DefaultErrorFallback.tsx @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { noop } from '@tldraw/utils' import classNames from 'classnames' import { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react' diff --git a/packages/editor/src/lib/components/default-components/DefaultSelectionForeground.tsx b/packages/editor/src/lib/components/default-components/DefaultSelectionForeground.tsx index 9a8f1df89..67b3bc1a6 100644 --- a/packages/editor/src/lib/components/default-components/DefaultSelectionForeground.tsx +++ b/packages/editor/src/lib/components/default-components/DefaultSelectionForeground.tsx @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import classNames from 'classnames' import { useRef } from 'react' import { useEditor } from '../../hooks/useEditor' diff --git a/packages/editor/src/lib/components/default-components/DefaultShapeIndicator.tsx b/packages/editor/src/lib/components/default-components/DefaultShapeIndicator.tsx index 8834410e4..743db898b 100644 --- a/packages/editor/src/lib/components/default-components/DefaultShapeIndicator.tsx +++ b/packages/editor/src/lib/components/default-components/DefaultShapeIndicator.tsx @@ -1,4 +1,4 @@ -import { useQuickReactor, useStateTracking, useValue } from '@tldraw/state' +import { useQuickReactor, useStateTracking, useValue } from '@tldraw/state-react' import { TLShape, TLShapeId } from '@tldraw/tlschema' import classNames from 'classnames' import { memo, useLayoutEffect, useRef } from 'react' diff --git a/packages/editor/src/lib/components/default-components/DefaultShapeIndicators.tsx b/packages/editor/src/lib/components/default-components/DefaultShapeIndicators.tsx index cfd6fac71..82f312ab8 100644 --- a/packages/editor/src/lib/components/default-components/DefaultShapeIndicators.tsx +++ b/packages/editor/src/lib/components/default-components/DefaultShapeIndicators.tsx @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { TLShapeId } from '@tldraw/tlschema' import { memo, useRef } from 'react' import { useEditor } from '../../hooks/useEditor' diff --git a/packages/editor/src/lib/editor/shapes/group/DashedOutlineBox.tsx b/packages/editor/src/lib/editor/shapes/group/DashedOutlineBox.tsx index d55a501e0..162f320d2 100644 --- a/packages/editor/src/lib/editor/shapes/group/DashedOutlineBox.tsx +++ b/packages/editor/src/lib/editor/shapes/group/DashedOutlineBox.tsx @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { useEditor } from '../../../hooks/useEditor' import { Box } from '../../../primitives/Box' import { getPerfectDashProps } from '../shared/getPerfectDashProps' diff --git a/packages/editor/src/lib/hooks/useCursor.ts b/packages/editor/src/lib/hooks/useCursor.ts index e7d280a2e..18c133385 100644 --- a/packages/editor/src/lib/hooks/useCursor.ts +++ b/packages/editor/src/lib/hooks/useCursor.ts @@ -1,4 +1,4 @@ -import { useQuickReactor } from '@tldraw/state' +import { useQuickReactor } from '@tldraw/state-react' import { TLCursorType } from '@tldraw/tlschema' import { PI, radiansToDegrees } from '../primitives/utils' import { useContainer } from './useContainer' diff --git a/packages/editor/src/lib/hooks/useDarkMode.ts b/packages/editor/src/lib/hooks/useDarkMode.ts index 6c3283d62..cecf192f7 100644 --- a/packages/editor/src/lib/hooks/useDarkMode.ts +++ b/packages/editor/src/lib/hooks/useDarkMode.ts @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import React from 'react' import { debugFlags } from '../utils/debug-flags' import { useContainer } from './useContainer' diff --git a/packages/editor/src/lib/hooks/useDocumentEvents.ts b/packages/editor/src/lib/hooks/useDocumentEvents.ts index d76f8e779..e0da6aa2c 100644 --- a/packages/editor/src/lib/hooks/useDocumentEvents.ts +++ b/packages/editor/src/lib/hooks/useDocumentEvents.ts @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { useEffect } from 'react' import { TLKeyboardEventInfo } from '../editor/types/event-types' import { preventDefault } from '../utils/dom' diff --git a/packages/editor/src/lib/hooks/useIsCropping.ts b/packages/editor/src/lib/hooks/useIsCropping.ts index 045074e72..abe5ea9a1 100644 --- a/packages/editor/src/lib/hooks/useIsCropping.ts +++ b/packages/editor/src/lib/hooks/useIsCropping.ts @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { TLShapeId } from '@tldraw/tlschema' import { useEditor } from './useEditor' diff --git a/packages/editor/src/lib/hooks/useIsDarkMode.ts b/packages/editor/src/lib/hooks/useIsDarkMode.ts index 5fef12bf8..c0ebfa544 100644 --- a/packages/editor/src/lib/hooks/useIsDarkMode.ts +++ b/packages/editor/src/lib/hooks/useIsDarkMode.ts @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { useSvgExportContext } from '../editor/types/SvgExportContext' import { useEditor } from './useEditor' diff --git a/packages/editor/src/lib/hooks/useIsEditing.ts b/packages/editor/src/lib/hooks/useIsEditing.ts index 1cc29afec..221a21cce 100644 --- a/packages/editor/src/lib/hooks/useIsEditing.ts +++ b/packages/editor/src/lib/hooks/useIsEditing.ts @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { TLShapeId } from '@tldraw/tlschema' import { useEditor } from './useEditor' diff --git a/packages/editor/src/lib/hooks/usePeerIds.ts b/packages/editor/src/lib/hooks/usePeerIds.ts index add0bb996..6e4aaa671 100644 --- a/packages/editor/src/lib/hooks/usePeerIds.ts +++ b/packages/editor/src/lib/hooks/usePeerIds.ts @@ -1,4 +1,4 @@ -import { useComputed, useValue } from '@tldraw/state' +import { useComputed, useValue } from '@tldraw/state-react' import { uniq } from '../utils/uniq' import { useEditor } from './useEditor' diff --git a/packages/editor/src/lib/hooks/usePresence.ts b/packages/editor/src/lib/hooks/usePresence.ts index 7b92018f3..584124b47 100644 --- a/packages/editor/src/lib/hooks/usePresence.ts +++ b/packages/editor/src/lib/hooks/usePresence.ts @@ -1,4 +1,4 @@ -import { useValue } from '@tldraw/state' +import { useValue } from '@tldraw/state-react' import { TLInstancePresence } from '@tldraw/tlschema' import { useEditor } from './useEditor' diff --git a/packages/editor/tsconfig.json b/packages/editor/tsconfig.json index f19f69e45..766de9fb4 100644 --- a/packages/editor/tsconfig.json +++ b/packages/editor/tsconfig.json @@ -4,7 +4,6 @@ "compilerOptions": { "outDir": "./.tsbuild", "rootDir": "src", - // TODO: enable these two options "noImplicitOverride": false, "noImplicitReturns": false, "types": ["node", "@types/jest"] @@ -13,6 +12,9 @@ { "path": "../state" }, + { + "path": "../state-react" + }, { "path": "../store" }, diff --git a/packages/state-react/LICENSE.md b/packages/state-react/LICENSE.md new file mode 100644 index 000000000..0ad7260cb --- /dev/null +++ b/packages/state-react/LICENSE.md @@ -0,0 +1 @@ +This code is licensed under the [tldraw license](https://github.com/tldraw/tldraw/blob/main/LICENSE.md) diff --git a/packages/state-react/README.md b/packages/state-react/README.md new file mode 100644 index 000000000..565c1831e --- /dev/null +++ b/packages/state-react/README.md @@ -0,0 +1,3 @@ +# @tldraw/state + +... diff --git a/packages/state-react/api-extractor.json b/packages/state-react/api-extractor.json new file mode 100644 index 000000000..f1ed80e93 --- /dev/null +++ b/packages/state-react/api-extractor.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + "extends": "../../config/api-extractor.json" +} diff --git a/packages/state-react/api-report.md b/packages/state-react/api-report.md new file mode 100644 index 000000000..f786b4228 --- /dev/null +++ b/packages/state-react/api-report.md @@ -0,0 +1,47 @@ +## API Report File for "@tldraw/state-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Atom } from '@tldraw/state'; +import { AtomOptions } from '@tldraw/state'; +import { Computed } from '@tldraw/state'; +import { ComputedOptions } from '@tldraw/state'; +import { FunctionComponent } from 'react'; +import { default as React_2 } from 'react'; +import { Signal } from '@tldraw/state'; + +// @public +export function track>(baseComponent: T): React_2.NamedExoticComponent>; + +// @public +export function useAtom( +name: string, +valueOrInitialiser: (() => Value) | Value, +options?: AtomOptions): Atom; + +// @public +export function useComputed(name: string, compute: () => Value, deps: any[]): Computed; + +// @public (undocumented) +export function useComputed(name: string, compute: () => Value, opts: ComputedOptions, deps: any[]): Computed; + +// @public (undocumented) +export function useQuickReactor(name: string, reactFn: () => void, deps?: any[]): void; + +// @public (undocumented) +export function useReactor(name: string, reactFn: () => void, deps?: any[] | undefined): void; + +// @public +export function useStateTracking(name: string, render: () => T): T; + +// @public +export function useValue(value: Signal): Value; + +// @public (undocumented) +export function useValue(name: string, fn: () => Value, deps: unknown[]): Value; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/state-react/package.json b/packages/state-react/package.json new file mode 100644 index 000000000..b5e1883d2 --- /dev/null +++ b/packages/state-react/package.json @@ -0,0 +1,74 @@ +{ + "name": "@tldraw/state-react", + "description": "A tiny little drawing app (react bindings for state).", + "version": "2.3.0", + "author": { + "name": "tldraw Inc.", + "email": "hello@tldraw.com" + }, + "homepage": "https://tldraw.dev", + "license": "SEE LICENSE IN LICENSE.md", + "repository": { + "type": "git", + "url": "https://github.com/tldraw/tldraw" + }, + "bugs": { + "url": "https://github.com/tldraw/tldraw/issues" + }, + "keywords": [ + "tldraw", + "drawing", + "app", + "development", + "whiteboard", + "canvas", + "infinite" + ], + "/* NOTE */": "These `main` and `types` fields are rewritten by the build script. They are not the actual values we publish", + "main": "./src/index.ts", + "types": "./.tsbuild/index.d.ts", + "/* GOTCHA */": "files will include ./dist and index.d.ts by default, add any others you want to include in here", + "files": [], + "scripts": { + "test-ci": "lazy inherit", + "test": "yarn run -T jest", + "test-coverage": "lazy inherit", + "build": "yarn run -T tsx ../../scripts/build-package.ts", + "build-api": "yarn run -T tsx ../../scripts/build-api.ts", + "prepack": "yarn run -T tsx ../../scripts/prepack.ts", + "postpack": "../../scripts/postpack.sh", + "pack-tarball": "yarn pack", + "lint": "yarn run -T tsx ../../scripts/lint.ts" + }, + "jest": { + "preset": "config/jest/node", + "setupFiles": [ + "raf/polyfill" + ], + "moduleNameMapper": { + "^~(.*)": "/src/$1" + }, + "transformIgnorePatterns": [ + "node_modules/(?!(nanoid)/)" + ] + }, + "dependencies": { + "@tldraw/state": "workspace:*" + }, + "devDependencies": { + "@types/lodash": "^4.14.188", + "@types/react": "^18.2.47", + "@types/react-test-renderer": "^18.0.0", + "lodash": "^4.17.21", + "react-test-renderer": "^18.2.0" + }, + "peerDependencies": { + "react": "^18" + }, + "typedoc": { + "readmeFile": "none", + "entryPoint": "./src/index.ts", + "displayName": "@tldraw/state", + "tsconfig": "./tsconfig.json" + } +} diff --git a/packages/state-react/src/index.ts b/packages/state-react/src/index.ts new file mode 100644 index 000000000..61418cba9 --- /dev/null +++ b/packages/state-react/src/index.ts @@ -0,0 +1,7 @@ +export { track } from './lib/track' +export { useAtom } from './lib/useAtom' +export { useComputed } from './lib/useComputed' +export { useQuickReactor } from './lib/useQuickReactor' +export { useReactor } from './lib/useReactor' +export { useStateTracking } from './lib/useStateTracking' +export { useValue } from './lib/useValue' diff --git a/packages/state/src/lib/react/track.test.tsx b/packages/state-react/src/lib/track.test.tsx similarity index 99% rename from packages/state/src/lib/react/track.test.tsx rename to packages/state-react/src/lib/track.test.tsx index 714843373..a2cc69ee1 100644 --- a/packages/state/src/lib/react/track.test.tsx +++ b/packages/state-react/src/lib/track.test.tsx @@ -1,6 +1,6 @@ +import { atom } from '@tldraw/state' import { createRef, forwardRef, memo, useEffect, useImperativeHandle } from 'react' import { ReactTestRenderer, act, create } from 'react-test-renderer' -import { atom } from '../core/Atom' import { track } from './track' test("tracked components are memo'd", async () => { diff --git a/packages/state/src/lib/react/track.ts b/packages/state-react/src/lib/track.ts similarity index 100% rename from packages/state/src/lib/react/track.ts rename to packages/state-react/src/lib/track.ts diff --git a/packages/state/src/lib/react/useAtom.test.tsx b/packages/state-react/src/lib/useAtom.test.tsx similarity index 97% rename from packages/state/src/lib/react/useAtom.test.tsx rename to packages/state-react/src/lib/useAtom.test.tsx index 8521804d2..865cebf5c 100644 --- a/packages/state/src/lib/react/useAtom.test.tsx +++ b/packages/state-react/src/lib/useAtom.test.tsx @@ -1,5 +1,5 @@ +import { Atom } from '@tldraw/state' import ReactTestRenderer from 'react-test-renderer' -import { Atom } from '../core/Atom' import { useAtom } from './useAtom' import { useValue } from './useValue' diff --git a/packages/state/src/lib/react/useAtom.ts b/packages/state-react/src/lib/useAtom.ts similarity index 95% rename from packages/state/src/lib/react/useAtom.ts rename to packages/state-react/src/lib/useAtom.ts index 35d059d22..634839f7a 100644 --- a/packages/state/src/lib/react/useAtom.ts +++ b/packages/state-react/src/lib/useAtom.ts @@ -1,5 +1,5 @@ +import { Atom, AtomOptions, atom } from '@tldraw/state' import { useState } from 'react' -import { Atom, AtomOptions, atom } from '../core' /** * Creates a new atom and returns it. The atom will be created only once. diff --git a/packages/state/src/lib/react/useComputed.test.tsx b/packages/state-react/src/lib/useComputed.test.tsx similarity index 97% rename from packages/state/src/lib/react/useComputed.test.tsx rename to packages/state-react/src/lib/useComputed.test.tsx index d9aba5d17..0b66a995e 100644 --- a/packages/state/src/lib/react/useComputed.test.tsx +++ b/packages/state-react/src/lib/useComputed.test.tsx @@ -1,7 +1,6 @@ +import { Atom, Computed } from '@tldraw/state' import { useState } from 'react' import ReactTestRenderer from 'react-test-renderer' -import { Atom } from '../core/Atom' -import { Computed } from '../core/Computed' import { useAtom } from './useAtom' import { useComputed } from './useComputed' import { useValue } from './useValue' diff --git a/packages/state/src/lib/react/useComputed.ts b/packages/state-react/src/lib/useComputed.ts similarity index 94% rename from packages/state/src/lib/react/useComputed.ts rename to packages/state-react/src/lib/useComputed.ts index d2b2ac8ad..7dcbe21d8 100644 --- a/packages/state/src/lib/react/useComputed.ts +++ b/packages/state-react/src/lib/useComputed.ts @@ -1,6 +1,6 @@ /* eslint-disable prefer-rest-params */ +import { Computed, ComputedOptions, computed } from '@tldraw/state' import { useMemo } from 'react' -import { Computed, ComputedOptions, computed } from '../core' /** * Creates a new computed signal and returns it. The computed signal will be created only once. diff --git a/packages/state/src/lib/react/useQuickReactor.ts b/packages/state-react/src/lib/useQuickReactor.ts similarity index 86% rename from packages/state/src/lib/react/useQuickReactor.ts rename to packages/state-react/src/lib/useQuickReactor.ts index fac95bba1..0ee7e1d2b 100644 --- a/packages/state/src/lib/react/useQuickReactor.ts +++ b/packages/state-react/src/lib/useQuickReactor.ts @@ -1,5 +1,5 @@ +import { EMPTY_ARRAY, EffectScheduler } from '@tldraw/state' import { useEffect } from 'react' -import { EMPTY_ARRAY, EffectScheduler } from '../core' /** @public */ export function useQuickReactor(name: string, reactFn: () => void, deps: any[] = EMPTY_ARRAY) { diff --git a/packages/state/src/lib/react/useReactor.ts b/packages/state-react/src/lib/useReactor.ts similarity index 92% rename from packages/state/src/lib/react/useReactor.ts rename to packages/state-react/src/lib/useReactor.ts index f3a8fd05e..ef90beded 100644 --- a/packages/state/src/lib/react/useReactor.ts +++ b/packages/state-react/src/lib/useReactor.ts @@ -1,5 +1,5 @@ +import { EffectScheduler } from '@tldraw/state' import { useEffect, useMemo, useRef } from 'react' -import { EffectScheduler } from '../core' /** @public */ export function useReactor(name: string, reactFn: () => void, deps: undefined | any[] = []) { diff --git a/packages/state/src/lib/react/useStateTracking.test.tsx b/packages/state-react/src/lib/useStateTracking.test.tsx similarity index 98% rename from packages/state/src/lib/react/useStateTracking.test.tsx rename to packages/state-react/src/lib/useStateTracking.test.tsx index c9a5c4d66..4ad23376b 100644 --- a/packages/state/src/lib/react/useStateTracking.test.tsx +++ b/packages/state-react/src/lib/useStateTracking.test.tsx @@ -1,6 +1,6 @@ +import { atom } from '@tldraw/state' import * as React from 'react' import { act, create, ReactTestRenderer } from 'react-test-renderer' -import { atom } from '../core/Atom' import { useStateTracking } from './useStateTracking' describe('useStateTracking', () => { diff --git a/packages/state/src/lib/react/useStateTracking.ts b/packages/state-react/src/lib/useStateTracking.ts similarity index 98% rename from packages/state/src/lib/react/useStateTracking.ts rename to packages/state-react/src/lib/useStateTracking.ts index 65dc1a10e..697a52873 100644 --- a/packages/state/src/lib/react/useStateTracking.ts +++ b/packages/state-react/src/lib/useStateTracking.ts @@ -1,5 +1,5 @@ +import { EffectScheduler } from '@tldraw/state' import React from 'react' -import { EffectScheduler } from '../core' /** * Wraps some synchronous react render logic in a reactive tracking context. diff --git a/packages/state/src/lib/react/useValue.test.tsx b/packages/state-react/src/lib/useValue.test.tsx similarity index 97% rename from packages/state/src/lib/react/useValue.test.tsx rename to packages/state-react/src/lib/useValue.test.tsx index 198351433..2da7f6211 100644 --- a/packages/state/src/lib/react/useValue.test.tsx +++ b/packages/state-react/src/lib/useValue.test.tsx @@ -1,7 +1,6 @@ +import { Atom, Computed, atom } from '@tldraw/state' import { useState } from 'react' import ReactTestRenderer from 'react-test-renderer' -import { Atom, atom } from '../core/Atom' -import { Computed } from '../core/Computed' import { useAtom } from './useAtom' import { useComputed } from './useComputed' import { useValue } from './useValue' diff --git a/packages/state/src/lib/react/useValue.ts b/packages/state-react/src/lib/useValue.ts similarity index 98% rename from packages/state/src/lib/react/useValue.ts rename to packages/state-react/src/lib/useValue.ts index 8d4384a5b..ad6ab1c46 100644 --- a/packages/state/src/lib/react/useValue.ts +++ b/packages/state-react/src/lib/useValue.ts @@ -1,6 +1,6 @@ /* eslint-disable prefer-rest-params */ +import { Signal, computed, react } from '@tldraw/state' import { useMemo, useRef, useSyncExternalStore } from 'react' -import { Signal, computed, react } from '../core' /** * Extracts the value from a signal and subscribes to it. diff --git a/packages/state-react/tsconfig.json b/packages/state-react/tsconfig.json new file mode 100644 index 000000000..1aa7c8cee --- /dev/null +++ b/packages/state-react/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../config/tsconfig.base.json", + "include": ["src"], + "exclude": ["node_modules", "dist", ".tsbuild*"], + "compilerOptions": { + "outDir": "./.tsbuild", + "rootDir": "src" + }, + "references": [ + { + "path": "../state" + } + ] +} diff --git a/packages/state/api-report.md b/packages/state/api-report.md index 96795fc88..d0a0e5bcb 100644 --- a/packages/state/api-report.md +++ b/packages/state/api-report.md @@ -4,9 +4,6 @@ ```ts -import { FunctionComponent } from 'react'; -import { default as React_2 } from 'react'; - // @internal export class ArraySet { add(elem: T): boolean; @@ -162,9 +159,6 @@ export interface Signal { name: string; } -// @public -export function track>(baseComponent: T): React_2.NamedExoticComponent>; - // @public export function transact(fn: () => T): T; @@ -180,33 +174,6 @@ export type UNINITIALIZED = typeof UNINITIALIZED; // @public export function unsafe__withoutCapture(fn: () => T): T; -// @public -export function useAtom( -name: string, -valueOrInitialiser: (() => Value) | Value, -options?: AtomOptions): Atom; - -// @public -export function useComputed(name: string, compute: () => Value, deps: any[]): Computed; - -// @public (undocumented) -export function useComputed(name: string, compute: () => Value, opts: ComputedOptions, deps: any[]): Computed; - -// @public (undocumented) -export function useQuickReactor(name: string, reactFn: () => void, deps?: any[]): void; - -// @public (undocumented) -export function useReactor(name: string, reactFn: () => void, deps?: any[] | undefined): void; - -// @public -export function useStateTracking(name: string, render: () => T): T; - -// @public -export function useValue(value: Signal): Value; - -// @public (undocumented) -export function useValue(name: string, fn: () => Value, deps: unknown[]): Value; - // @public export function whyAmIRunning(): void; diff --git a/packages/state/package.json b/packages/state/package.json index c6a881ae8..93f069774 100644 --- a/packages/state/package.json +++ b/packages/state/package.json @@ -54,13 +54,7 @@ }, "devDependencies": { "@types/lodash": "^4.14.188", - "@types/react": "^18.2.47", - "@types/react-test-renderer": "^18.0.0", - "lodash": "^4.17.21", - "react-test-renderer": "^18.2.0" - }, - "peerDependencies": { - "react": "^18" + "lodash": "^4.17.21" }, "typedoc": { "readmeFile": "none", diff --git a/packages/state/src/index.ts b/packages/state/src/index.ts index f56786f8a..8a0532923 100644 --- a/packages/state/src/index.ts +++ b/packages/state/src/index.ts @@ -1,3 +1,33 @@ -/* eslint-disable local/no-export-star */ -export * from './lib/core' -export * from './lib/react' +import { singleton } from './lib/helpers' + +export { ArraySet } from './lib/ArraySet' +export { atom, isAtom } from './lib/Atom' +export type { Atom, AtomOptions } from './lib/Atom' +export { + UNINITIALIZED, + computed, + getComputedInstance, + isUninitialized, + withDiff, +} from './lib/Computed' +export type { Computed, ComputedOptions, WithDiff } from './lib/Computed' +export { EffectScheduler, react, reactor } from './lib/EffectScheduler' +export type { EffectSchedulerOptions, Reactor } from './lib/EffectScheduler' +export { unsafe__withoutCapture, whyAmIRunning } from './lib/capture' +export { EMPTY_ARRAY } from './lib/helpers' +export { isSignal } from './lib/isSignal' +export { transact, transaction } from './lib/transactions' +export { RESET_VALUE } from './lib/types' +export type { Child, ComputeDiff, Signal } from './lib/types' + +// This should be incremented any time an API change is made. i.e. for additions or removals. +// Bugfixes need not increment this. +const currentApiVersion = 1 + +const actualApiVersion = singleton('apiVersion', () => currentApiVersion) + +if (actualApiVersion !== currentApiVersion) { + throw new Error( + `You have multiple incompatible versions of @tldraw/state in your app. Please deduplicate the package.` + ) +} diff --git a/packages/state/src/lib/core/ArraySet.ts b/packages/state/src/lib/ArraySet.ts similarity index 100% rename from packages/state/src/lib/core/ArraySet.ts rename to packages/state/src/lib/ArraySet.ts diff --git a/packages/state/src/lib/core/Atom.ts b/packages/state/src/lib/Atom.ts similarity index 100% rename from packages/state/src/lib/core/Atom.ts rename to packages/state/src/lib/Atom.ts diff --git a/packages/state/src/lib/core/Computed.ts b/packages/state/src/lib/Computed.ts similarity index 100% rename from packages/state/src/lib/core/Computed.ts rename to packages/state/src/lib/Computed.ts diff --git a/packages/state/src/lib/core/EffectScheduler.ts b/packages/state/src/lib/EffectScheduler.ts similarity index 100% rename from packages/state/src/lib/core/EffectScheduler.ts rename to packages/state/src/lib/EffectScheduler.ts diff --git a/packages/state/src/lib/core/HistoryBuffer.ts b/packages/state/src/lib/HistoryBuffer.ts similarity index 100% rename from packages/state/src/lib/core/HistoryBuffer.ts rename to packages/state/src/lib/HistoryBuffer.ts diff --git a/packages/state/src/lib/core/__tests__/EffectScheduler.test.ts b/packages/state/src/lib/__tests__/EffectScheduler.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/EffectScheduler.test.ts rename to packages/state/src/lib/__tests__/EffectScheduler.test.ts diff --git a/packages/state/src/lib/core/__tests__/HistoryBuffer.test.ts b/packages/state/src/lib/__tests__/HistoryBuffer.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/HistoryBuffer.test.ts rename to packages/state/src/lib/__tests__/HistoryBuffer.test.ts diff --git a/packages/state/src/lib/core/__tests__/arraySet.test.ts b/packages/state/src/lib/__tests__/arraySet.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/arraySet.test.ts rename to packages/state/src/lib/__tests__/arraySet.test.ts diff --git a/packages/state/src/lib/core/__tests__/atom.test.ts b/packages/state/src/lib/__tests__/atom.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/atom.test.ts rename to packages/state/src/lib/__tests__/atom.test.ts diff --git a/packages/state/src/lib/core/__tests__/capture.test.ts b/packages/state/src/lib/__tests__/capture.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/capture.test.ts rename to packages/state/src/lib/__tests__/capture.test.ts diff --git a/packages/state/src/lib/core/__tests__/computed.test.ts b/packages/state/src/lib/__tests__/computed.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/computed.test.ts rename to packages/state/src/lib/__tests__/computed.test.ts diff --git a/packages/state/src/lib/core/__tests__/errors.test.ts b/packages/state/src/lib/__tests__/errors.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/errors.test.ts rename to packages/state/src/lib/__tests__/errors.test.ts diff --git a/packages/state/src/lib/core/__tests__/fuzz.tlstate.test.ts b/packages/state/src/lib/__tests__/fuzz.tlstate.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/fuzz.tlstate.test.ts rename to packages/state/src/lib/__tests__/fuzz.tlstate.test.ts diff --git a/packages/state/src/lib/core/__tests__/reactor.test.ts b/packages/state/src/lib/__tests__/reactor.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/reactor.test.ts rename to packages/state/src/lib/__tests__/reactor.test.ts diff --git a/packages/state/src/lib/core/__tests__/transactions.test.ts b/packages/state/src/lib/__tests__/transactions.test.ts similarity index 100% rename from packages/state/src/lib/core/__tests__/transactions.test.ts rename to packages/state/src/lib/__tests__/transactions.test.ts diff --git a/packages/state/src/lib/core/capture.ts b/packages/state/src/lib/capture.ts similarity index 100% rename from packages/state/src/lib/core/capture.ts rename to packages/state/src/lib/capture.ts diff --git a/packages/state/src/lib/core/constants.ts b/packages/state/src/lib/constants.ts similarity index 100% rename from packages/state/src/lib/core/constants.ts rename to packages/state/src/lib/constants.ts diff --git a/packages/state/src/lib/core/index.ts b/packages/state/src/lib/core/index.ts deleted file mode 100644 index ef7d61601..000000000 --- a/packages/state/src/lib/core/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { singleton } from './helpers' - -export { ArraySet } from './ArraySet' -export { atom, isAtom } from './Atom' -export type { Atom, AtomOptions } from './Atom' -export { UNINITIALIZED, computed, getComputedInstance, isUninitialized, withDiff } from './Computed' -export type { Computed, ComputedOptions, WithDiff } from './Computed' -export { EffectScheduler, react, reactor } from './EffectScheduler' -export type { EffectSchedulerOptions, Reactor } from './EffectScheduler' -export { unsafe__withoutCapture, whyAmIRunning } from './capture' -export { EMPTY_ARRAY } from './helpers' -export { isSignal } from './isSignal' -export { transact, transaction } from './transactions' -export { RESET_VALUE } from './types' -export type { Child, ComputeDiff, Signal } from './types' - -// This should be incremented any time an API change is made. i.e. for additions or removals. -// Bugfixes need not increment this. -const currentApiVersion = 1 - -const actualApiVersion = singleton('apiVersion', () => currentApiVersion) - -if (actualApiVersion !== currentApiVersion) { - throw new Error( - `You have multiple incompatible versions of @tldraw/state in your app. Please deduplicate the package.` - ) -} diff --git a/packages/state/src/lib/core/helpers.ts b/packages/state/src/lib/helpers.ts similarity index 100% rename from packages/state/src/lib/core/helpers.ts rename to packages/state/src/lib/helpers.ts diff --git a/packages/state/src/lib/core/isSignal.ts b/packages/state/src/lib/isSignal.ts similarity index 100% rename from packages/state/src/lib/core/isSignal.ts rename to packages/state/src/lib/isSignal.ts diff --git a/packages/state/src/lib/react/index.ts b/packages/state/src/lib/react/index.ts deleted file mode 100644 index c56b51d82..000000000 --- a/packages/state/src/lib/react/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { track } from './track' -export { useAtom } from './useAtom' -export { useComputed } from './useComputed' -export { useQuickReactor } from './useQuickReactor' -export { useReactor } from './useReactor' -export { useStateTracking } from './useStateTracking' -export { useValue } from './useValue' diff --git a/packages/state/src/lib/core/transactions.ts b/packages/state/src/lib/transactions.ts similarity index 100% rename from packages/state/src/lib/core/transactions.ts rename to packages/state/src/lib/transactions.ts diff --git a/packages/state/src/lib/core/types.ts b/packages/state/src/lib/types.ts similarity index 100% rename from packages/state/src/lib/core/types.ts rename to packages/state/src/lib/types.ts diff --git a/packages/state/src/lib/core/warnings.ts b/packages/state/src/lib/warnings.ts similarity index 100% rename from packages/state/src/lib/core/warnings.ts rename to packages/state/src/lib/warnings.ts diff --git a/yarn.lock b/yarn.lock index f5fb5c7fd..a20ad2c7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6110,6 +6110,7 @@ __metadata: "@testing-library/jest-dom": "npm:^5.16.5" "@testing-library/react": "npm:^14.0.0" "@tldraw/state": "workspace:*" + "@tldraw/state-react": "workspace:*" "@tldraw/store": "workspace:*" "@tldraw/tlschema": "workspace:*" "@tldraw/utils": "workspace:*" @@ -6224,10 +6225,11 @@ __metadata: languageName: unknown linkType: soft -"@tldraw/state@workspace:*, @tldraw/state@workspace:packages/state": +"@tldraw/state-react@workspace:*, @tldraw/state-react@workspace:packages/state-react": version: 0.0.0-use.local - resolution: "@tldraw/state@workspace:packages/state" + resolution: "@tldraw/state-react@workspace:packages/state-react" dependencies: + "@tldraw/state": "workspace:*" "@types/lodash": "npm:^4.14.188" "@types/react": "npm:^18.2.47" "@types/react-test-renderer": "npm:^18.0.0" @@ -6238,6 +6240,15 @@ __metadata: languageName: unknown linkType: soft +"@tldraw/state@workspace:*, @tldraw/state@workspace:packages/state": + version: 0.0.0-use.local + resolution: "@tldraw/state@workspace:packages/state" + dependencies: + "@types/lodash": "npm:^4.14.188" + lodash: "npm:^4.17.21" + languageName: unknown + linkType: soft + "@tldraw/store@workspace:*, @tldraw/store@workspace:packages/store": version: 0.0.0-use.local resolution: "@tldraw/store@workspace:packages/store"