Skip to content

Commit 8b206e6

Browse files
authored
feat!: remove atoms package's dependency on core package (#191)
@affects atoms, core, immer, machines, react
1 parent 78de30c commit 8b206e6

33 files changed

+153
-98
lines changed

packages/atoms/README.md

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# `@zedux/atoms`
22

3-
The core atomic model of Zedux. This is a standalone package, meaning it's the only package you need to install to use Zedux's atomic model. It includes the Zedux core store package as well as all APIs related to signals, atoms, and ecosystems.
3+
The core atomic model of Zedux. This is a standalone package, meaning it's the only package you need to install to use Zedux's atomic model. It includes all APIs related to signals, atoms, and ecosystems.
44

55
This package is framework-independent, though many of its APIs are heavily inspired by React.
66

@@ -16,8 +16,6 @@ pnpm add @zedux/atoms # pnpm
1616

1717
If you're using React, you probably want to install the [`@zedux/react` package](https://www.npmjs.com/package/@zedux/react) instead, which includes everything from this package and more.
1818

19-
This package has a direct dependency on the [`@zedux/core` package](https://www.npmjs.com/package/@zedux/core). If you install that directly, ensure its version exactly matches your `@zedux/atoms` version to prevent installing duplicate packages.
20-
2119
## Usage
2220

2321
See the [top-level README](https://github.com/Omnistac/zedux) for a general overview of Zedux.
@@ -41,11 +39,7 @@ instance.destroy()
4139

4240
## Exports
4341

44-
This package includes and re-exports everything from the following package:
45-
46-
- [`@zedux/core`](https://www.npmjs.com/package/@zedux/core)
47-
48-
On top of this, `@zedux/atoms` exports the following APIs and many helper types for working with them in TypeScript:
42+
`@zedux/atoms` exports the following APIs and many helper types for working with them in TypeScript:
4943

5044
### Classes
5145

@@ -86,11 +80,10 @@ On top of this, `@zedux/atoms` exports the following APIs and many helper types
8680

8781
### Utils
8882

89-
- [`getEcosystem()`](https://omnistac.github.io/zedux/docs/api/utils/internal-utils#getecosystem)
83+
- [`getDefaultEcosystem()`](https://omnistac.github.io/zedux/docs/api/utils/getDefaultEcosystem)
9084
- [`getInternals()`](https://omnistac.github.io/zedux/docs/api/utils/internal-utils#getinternals)
9185
- [`setInternals()`](https://omnistac.github.io/zedux/docs/api/utils/internal-utils#setinternals)
9286
- [`untrack()`](https://omnistac.github.io/zedux/docs/api/utils/internal-utils#untrack)
93-
- [`wipe()`](https://omnistac.github.io/zedux/docs/api/utils/internal-utils#wipe)
9487

9588
## For Authors
9689

packages/atoms/package.json

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
"bugs": {
1010
"url": "https://github.com/Omnistac/zedux/issues"
1111
},
12-
"dependencies": {
13-
"@zedux/core": "2.0.0-beta.4"
14-
},
1512
"exports": {
1613
".": {
1714
"import": "./dist/esm/index.js",

packages/atoms/src/classes/AtomApi.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { is } from '@zedux/core'
21
import {
32
AtomInstanceTtl,
43
AtomApiGenerics,
54
Prettify,
65
ExportsConfig,
76
} from '@zedux/atoms/types/index'
8-
import { INITIALIZING, prefix } from '@zedux/atoms/utils/general'
7+
import { INITIALIZING, is, prefix } from '@zedux/atoms/utils/general'
98
import { getEvaluationContext } from '../utils/evaluationContext'
109

1110
const wrapExports = <T extends Record<string, any>>(

packages/atoms/src/classes/Ecosystem.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { is, isPlainObject, Job } from '@zedux/core'
21
import {
32
AnyAtomInstance,
43
AnyAtomTemplate,
@@ -31,6 +30,7 @@ import {
3130
EcosystemEvents,
3231
InternalEvaluationReason,
3332
GetNode,
33+
Job,
3434
} from '../types/index'
3535
import {
3636
External,
@@ -48,6 +48,7 @@ import {
4848
RUN_START,
4949
RESET_START,
5050
RUN_END,
51+
is,
5152
} from '../utils/general'
5253
import { IdGenerator } from './IdGenerator'
5354
import { Scheduler } from './Scheduler'
@@ -552,10 +553,10 @@ export class Ecosystem<Context extends Record<string, any> | undefined = any>
552553
dehydratedState: Record<string, any>,
553554
config?: { retroactive?: boolean }
554555
) {
555-
if (DEV && !isPlainObject(dehydratedState)) {
556-
throw new TypeError(
557-
'Zedux: ecosystem.hydrate() - first parameter must be a plain object'
558-
)
556+
if (DEV && (!dehydratedState || typeof dehydratedState !== 'object')) {
557+
throw new TypeError('Zedux: Expected an object', {
558+
cause: dehydratedState,
559+
})
559560
}
560561

561562
this.hydration = { ...this.hydration, ...dehydratedState }

packages/atoms/src/classes/GraphNode.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import {
66
GraphEdge,
77
GraphEdgeConfig,
88
InternalEvaluationReason,
9+
Job,
910
ListenerConfig,
1011
NodeFilter,
1112
NodeFilterOptions,
1213
NodeGenerics,
1314
} from '@zedux/atoms/types/index'
14-
import { is, Job } from '@zedux/core'
1515
import { Ecosystem } from './Ecosystem'
1616
import {
1717
ACTIVE,
@@ -21,6 +21,7 @@ import {
2121
ExplicitExternal,
2222
INITIALIZING,
2323
InternalLifecycleStatus,
24+
is,
2425
statusMap,
2526
} from '../utils/general'
2627
import { AtomTemplateBase } from './templates/AtomTemplateBase'

packages/atoms/src/classes/IdGenerator.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { isPlainObject } from '@zedux/core'
21
import { GraphNode } from './GraphNode'
32

43
/**
@@ -49,7 +48,9 @@ export class IdGenerator {
4948
return JSON.stringify(params, (_, param) => {
5049
if (!param) return param
5150
if (param.izn) return (param as GraphNode).id
52-
if (!isPlainObject(param)) {
51+
52+
// if the prototype has no prototype, it's likely not a plain object:
53+
if (Object.getPrototypeOf(param.constructor.prototype)) {
5354
if (!acceptComplexParams || Array.isArray(param)) return param
5455
if (typeof param === 'function') return this.cacheFn(param)
5556
if (typeof param === 'object') return this.cacheClass(param)

packages/atoms/src/classes/MappedSignal.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { Settable } from '@zedux/core'
21
import {
32
AnyNodeGenerics,
43
AtomGenerics,
54
InternalEvaluationReason,
65
Mutatable,
76
SendableEvents,
7+
Settable,
88
Transaction,
99
UndefinedEvents,
1010
} from '../types/index'

packages/atoms/src/classes/Scheduler.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
import { Job, Scheduler as SchedulerInterface } from '@zedux/core'
1+
import { Job } from '@zedux/atoms/types/index'
22
import { Ecosystem } from './Ecosystem'
33

4+
// temporarily copied from @zedux/core. TODO: remove
5+
interface SchedulerInterface {
6+
scheduleNow(newJob: Job): void
7+
}
8+
49
export class Scheduler implements SchedulerInterface {
510
/**
611
* `I`nterrupt - currently interrupt jobs only have one use - to defer `set`

packages/atoms/src/classes/Signal.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { Settable } from '@zedux/core'
21
import {
32
AtomGenerics,
43
Mutatable,
54
NodeGenerics,
65
SendableEvents,
6+
Settable,
77
Transaction,
88
UndefinedEvents,
99
} from '../types/index'

packages/atoms/src/classes/instances/AtomInstance.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { is, Observable, Settable } from '@zedux/core'
21
import {
32
Mutatable,
43
SendableEvents,
@@ -14,6 +13,7 @@ import {
1413
DehydrationOptions,
1514
AnyAtomGenerics,
1615
InternalEvaluationReason,
16+
Settable,
1717
} from '@zedux/atoms/types/index'
1818
import {
1919
ACTIVE,
@@ -22,6 +22,7 @@ import {
2222
INITIALIZING,
2323
INVALIDATE,
2424
Invalidate,
25+
is,
2526
prefix,
2627
PROMISE_CHANGE,
2728
PromiseChange,
@@ -533,7 +534,9 @@ export class AtomInstance<
533534
}
534535

535536
// ttl is an observable; destroy as soon as it emits
536-
const subscription = (ttl as Observable).subscribe(() => {
537+
const subscription = (
538+
ttl as { subscribe: (cb: () => void) => { unsubscribe: () => void } }
539+
).subscribe(() => {
537540
this.c = undefined
538541
this.destroy()
539542
})

packages/atoms/src/classes/proxies.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { RecursivePartial } from '@zedux/core'
2-
import { Transaction, MutatableTypes } from '../types/index'
1+
import { Transaction, MutatableTypes, RecursivePartial } from '../types/index'
32

43
export type ParentProxy<State> = {
54
t: Transaction[]

packages/atoms/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ import {
2020
scheduleStaticDependents,
2121
} from './utils/graph'
2222

23-
export * from '@zedux/core'
2423
export * from './classes/index'
2524
export * from './factories/index'
2625
export * from './injectors/index'
2726
export * from './types/index'
2827
export { untrack } from './utils/evaluationContext'
28+
export { is } from './utils/general'
2929

3030
type Internals = { c: EvaluationContext; g: Ecosystem }
3131

packages/atoms/src/injectors/injectPromise.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { detailedTypeof, RecursivePartial } from '@zedux/core'
21
import { api } from '../factories/api'
32
import {
43
getErrorPromiseState,
@@ -13,6 +12,7 @@ import {
1312
MapEvents,
1413
None,
1514
PromiseState,
15+
RecursivePartial,
1616
} from '../types/index'
1717
import { injectEffect } from './injectEffect'
1818
import { injectMemo } from './injectMemo'
@@ -134,9 +134,8 @@ export const injectPromise: {
134134

135135
if (DEV && typeof promise?.then !== 'function') {
136136
throw new TypeError(
137-
`Zedux: injectPromise expected callback to return a promise. Received ${detailedTypeof(
138-
promise
139-
)}`
137+
'Zedux: injectPromise expected callback to return a promise',
138+
{ cause: promise }
140139
)
141140
}
142141

packages/atoms/src/injectors/injectSelf.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { is } from '@zedux/core'
21
import { AnyAtomInstance, PartialAtomInstance } from '../types/index'
32
import { getEvaluationContext } from '../utils/evaluationContext'
43
import { AtomInstance } from '../classes/instances/AtomInstance'
4+
import { is } from '../utils/general'
55

66
/**
77
* An unrestricted injector (can actually be used in loops and if statements).

packages/atoms/src/types/events.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { RecursivePartial } from '@zedux/core'
21
import { GraphNode } from '../classes/GraphNode'
32
import {
43
AnyNodeGenerics,
@@ -8,6 +7,7 @@ import {
87
ListenerConfig,
98
NodeGenerics,
109
Prettify,
10+
RecursivePartial,
1111
} from './index'
1212

1313
export type CatchAllListener<G extends NodeGenerics> = (

packages/atoms/src/types/index.ts

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { Observable, Settable } from '@zedux/core'
21
import { AtomTemplateBase } from '../classes/templates/AtomTemplateBase'
32
import { AtomApi } from '../classes/AtomApi'
43
import { Ecosystem } from '../classes/Ecosystem'
@@ -319,6 +318,31 @@ export type IonStateFactory<G extends Omit<AtomGenerics, 'Node' | 'Template'>> =
319318
...params: G['Params']
320319
) => AtomApi<AtomGenericsToAtomApiGenerics<G>> | Signal<G> | G['State']
321320

321+
export interface Job {
322+
/**
323+
* `W`eight - the weight of the node (for EvaluateGraphNode jobs).
324+
* UpdateExternalDependent jobs also use this to track the order they were
325+
* added as dependents, since that's the order they should evaluate in.
326+
*/
327+
W?: number
328+
329+
/**
330+
* `j`ob - the actual task to run.
331+
*/
332+
j: () => void
333+
334+
/**
335+
* `T`ype - the job type. Different types get different priorities in the
336+
* scheduler.
337+
*
338+
* 0 - UpdateStore
339+
* 1 - InformSubscribers
340+
* 2 - EvaluateGraphNode
341+
* 3 - UpdateExternalDependent
342+
*/
343+
T: 0 | 1 | 2 | 3
344+
}
345+
322346
export type LifecycleStatus = 'Active' | 'Destroyed' | 'Initializing' | 'Stale'
323347

324348
export interface ListenerConfig {
@@ -335,6 +359,10 @@ export interface MutableRefObject<T = any> {
335359
current: T
336360
}
337361

362+
export interface Observable<T = any> {
363+
subscribe(subscriber: (value: T) => any): { unsubscribe: () => void }
364+
}
365+
338366
export interface NodeFilterOptions {
339367
exclude?: (AnyAtomTemplate | AtomSelectorOrConfig | string)[]
340368
excludeTags?: string[]
@@ -389,6 +417,10 @@ export interface PromiseState<T> {
389417

390418
export type PromiseStatus = 'error' | 'loading' | 'success'
391419

420+
export type RecursivePartial<T> = T extends Record<string, any>
421+
? { [P in keyof T]?: RecursivePartial<T[P]> }
422+
: T
423+
392424
export type Ref<T = any> = MutableRefObject<T>
393425

394426
export interface RefObject<T = any> {
@@ -403,6 +435,10 @@ export type Selectable<State = any, Params extends any[] = any> =
403435
Template: AtomSelectorOrConfig<State, Params>
404436
}>
405437

438+
export type Settable<State = any, StateIn = State> =
439+
| ((state: StateIn) => State)
440+
| State
441+
406442
export type StateHookTuple<State, Exports> = [
407443
State,
408444
ExportsInfusedSetter<State, Exports>

packages/atoms/src/utils/ecosystem.ts

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { detailedTypeof, is } from '@zedux/core'
21
import {
32
AnyAtomInstance,
43
AnyAtomTemplate,
@@ -13,7 +12,7 @@ import type { Ecosystem } from '../classes/Ecosystem'
1312
import { GraphNode } from '../classes/GraphNode'
1413
import { getSelectorKey, SelectorInstance } from '../classes/SelectorInstance'
1514
import { getEvaluationContext } from './evaluationContext'
16-
import { DESTROYED } from './general'
15+
import { DESTROYED, is } from './general'
1716

1817
const getContextualizedId = (
1918
ecosystem: Ecosystem,
@@ -61,11 +60,9 @@ export const getNode = <G extends AtomGenerics>(
6160

6261
if (DEV) {
6362
if (typeof params !== 'undefined' && !Array.isArray(params)) {
64-
throw new TypeError(
65-
`Zedux: Expected atom params to be an array. Received ${detailedTypeof(
66-
params
67-
)}`
68-
)
63+
throw new TypeError('Zedux: Expected atom params to be an array', {
64+
cause: params,
65+
})
6966
}
7067
}
7168

@@ -165,9 +162,9 @@ export const getNode = <G extends AtomGenerics>(
165162
}
166163
}
167164

168-
throw new TypeError(
169-
`Zedux: Expected a template or node. Received ${detailedTypeof(template)}`
170-
)
165+
throw new TypeError('Zedux: Expected a template, selector, or graph node', {
166+
cause: template,
167+
})
171168
}
172169

173170
const resolveAtom = <A extends AnyAtomTemplate>(

0 commit comments

Comments
 (0)