@systemfsoftware/xstate-effect 0.0.0-bootstrap.0 → 0.1.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/LICENSE +22 -0
- package/README.md +262 -2
- package/dist/atom.d.ts +53 -0
- package/dist/atom.mjs +64 -0
- package/dist/index.d.ts +160 -0
- package/dist/index.mjs +429 -0
- package/dist/state-CNrCEIpU.mjs +607 -0
- package/dist/state-Ch1-WxXd.d.ts +447 -0
- package/package.json +58 -5
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { Cause, Context, Effect, Queue, Schema, Scope, Stream } from "effect";
|
|
2
|
+
import { ActorLogic, ActorLogicValidator, ActorOptions, ActorRef, AnyActor, AnyActorLogic, AnyActorRef, AnyActorSystem, AnyEventObject, AnyMachineSnapshot, AnyStateMachine, EmittedFrom, EventFromLogic, EventObject, InputFrom, InspectionEvent, MachineContext, MachineSnapshot, Observer, RequiredActorOptionsFor, RequiredActorOptionsKeys, SetupSchemas, SetupStateSchema, SetupStateSchemas, Snapshot, SnapshotFrom, StandardSchemaV1, StateContextFromStateValue, StateSchema, StateValueFromStateSchema, Subscription } from "@systemfsoftware/xstate";
|
|
3
|
+
/** A mailbox item that reports a failed fire-and-forget action. */
|
|
4
|
+
interface ActionFailure {
|
|
5
|
+
readonly [actionFailure]: true;
|
|
6
|
+
readonly error: unknown;
|
|
7
|
+
}
|
|
8
|
+
declare const actionFailure: unique symbol;
|
|
9
|
+
type MailboxItem<TEvent> = TEvent | ActionFailure;
|
|
10
|
+
declare const symbolObservable: typeof Symbol.observable;
|
|
11
|
+
/**
|
|
12
|
+
* The handle `createEffectActor` returns. It implements XState's `ActorRef`
|
|
13
|
+
* contract (`send`, `getSnapshot`, `subscribe`, `on`), so it works with
|
|
14
|
+
* `useSelector`, this package's actor functions and the inspection APIs, while
|
|
15
|
+
* the actor itself is driven by an Effect fiber over pure transitions.
|
|
16
|
+
*/
|
|
17
|
+
declare class EffectActor<TLogic extends AnyActorLogic> implements ActorRef<SnapshotFrom<TLogic>, EventFromLogic<TLogic>, EmittedFrom<TLogic>> {
|
|
18
|
+
readonly logic: TLogic;
|
|
19
|
+
private readonly _mailbox;
|
|
20
|
+
private readonly _stopExecution;
|
|
21
|
+
private readonly _inspectors;
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly address: string;
|
|
24
|
+
readonly sessionId: string | undefined;
|
|
25
|
+
/** The actor system that hosts this actor and its children. */
|
|
26
|
+
readonly system: AnyActor['system'];
|
|
27
|
+
private _snapshot;
|
|
28
|
+
private readonly _observers;
|
|
29
|
+
private readonly _listeners;
|
|
30
|
+
private _settled;
|
|
31
|
+
constructor(logic: TLogic, root: AnyActor, snapshot: SnapshotFrom<TLogic>, _mailbox: Queue.Queue<MailboxItem<EventFromLogic<TLogic>>>, _stopExecution: () => void, _inspectors: Set<(event: InspectionEvent) => void>);
|
|
32
|
+
getSnapshot(): SnapshotFrom<TLogic>;
|
|
33
|
+
getPersistedSnapshot(): Snapshot<unknown>;
|
|
34
|
+
/** Sends an event; the actor processes it on its own fiber. */
|
|
35
|
+
send(event: EventFromLogic<TLogic>): void;
|
|
36
|
+
/** Stops the actor, its children and every Effect it hosts. */
|
|
37
|
+
stop(): this;
|
|
38
|
+
subscribe(observer: Observer<SnapshotFrom<TLogic>>): Subscription;
|
|
39
|
+
subscribe(nextListener?: (snapshot: SnapshotFrom<TLogic>) => void, errorListener?: (error: any) => void, completeListener?: () => void): Subscription;
|
|
40
|
+
on<TType extends EmittedFrom<TLogic>['type'] | '*'>(type: TType, handler: (emitted: EmittedFrom<TLogic> & (TType extends '*' ? unknown : {
|
|
41
|
+
type: TType;
|
|
42
|
+
})) => void): Subscription;
|
|
43
|
+
/**
|
|
44
|
+
* Observes the inspection events of this actor and its children: every
|
|
45
|
+
* actor creation and transition of the execution.
|
|
46
|
+
*/
|
|
47
|
+
inspect(observer: Observer<InspectionEvent> | ((event: InspectionEvent) => void)): Subscription;
|
|
48
|
+
[symbolObservable](): this;
|
|
49
|
+
toJSON(): {
|
|
50
|
+
xstate$$type: number;
|
|
51
|
+
id: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
declare const ActorScopeService: Context.ServiceClass<ActorScope, "@systemfsoftware/xstate-effect/actorScope", Scope.Scope>;
|
|
55
|
+
/** The owning Effect actor's scope, supplied by `createEffectActor`. */
|
|
56
|
+
declare class ActorScope extends ActorScopeService {}
|
|
57
|
+
/**
|
|
58
|
+
* Acquires resources in the owning actor's scope. Their finalizers run when
|
|
59
|
+
* that actor stops, even if the invoking task finishes or is cancelled first.
|
|
60
|
+
*/
|
|
61
|
+
declare function withActorScope<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, Exclude<R, Scope.Scope> | ActorScope>;
|
|
62
|
+
declare const effectActionBrand: unique symbol;
|
|
63
|
+
/**
|
|
64
|
+
* An Effect `Schema` accepted by this package. `setupEffect`, `fromEffect`,
|
|
65
|
+
* `fromEffectStream` and `fromEffectEventStream` convert it to a Standard
|
|
66
|
+
* Schema, so XState infers the decoded `Schema.Type` without an explicit call
|
|
67
|
+
* to `Schema.toStandardSchemaV1`.
|
|
68
|
+
*/
|
|
69
|
+
type EffectSchema = Schema.ConstraintDecoder<unknown>;
|
|
70
|
+
/**
|
|
71
|
+
* Either an Effect {@link EffectSchema} or a Standard Schema. Every schema
|
|
72
|
+
* position in this package accepts both, so Effect schemas and schemas from
|
|
73
|
+
* other libraries can be mixed in one machine.
|
|
74
|
+
*/
|
|
75
|
+
type EffectSchemaLike = StandardSchemaV1 | EffectSchema;
|
|
76
|
+
interface RuntimeValidationDoesNotSupportTransformingSchemas {
|
|
77
|
+
readonly __xstate_effect_error: 'Runtime validation does not support schemas with different encoded and decoded types';
|
|
78
|
+
}
|
|
79
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
80
|
+
type ToStandardSchema<TSchema> = TSchema extends StandardSchemaV1 ? TSchema : TSchema extends EffectSchema ? StandardSchemaV1<TSchema['Encoded'], TSchema['Type']> & TSchema : never;
|
|
81
|
+
type AssertNonTransformingSchema<TSchema> = TSchema extends EffectSchemaLike ? IsAny<StandardSchemaV1.InferInput<ToStandardSchema<TSchema>>> extends true ? TSchema : IsAny<StandardSchemaV1.InferOutput<ToStandardSchema<TSchema>>> extends true ? TSchema : [StandardSchemaV1.InferInput<ToStandardSchema<TSchema>>, StandardSchemaV1.InferOutput<ToStandardSchema<TSchema>>] extends [StandardSchemaV1.InferOutput<ToStandardSchema<TSchema>>, StandardSchemaV1.InferInput<ToStandardSchema<TSchema>>] ? TSchema : RuntimeValidationDoesNotSupportTransformingSchemas : TSchema;
|
|
82
|
+
type EffectSchemaShape<TValue> = TValue extends StandardSchemaV1 ? EffectSchemaLike : TValue extends Record<string, unknown> ? { [K in keyof TValue]: EffectSchemaShape<TValue[K]>; } : TValue;
|
|
83
|
+
type ToStandardSchemaShape<TValue> = TValue extends EffectSchemaLike ? ToStandardSchema<TValue> : TValue extends Record<string, unknown> ? { [K in keyof TValue]: ToStandardSchemaShape<TValue[K]>; } : TValue;
|
|
84
|
+
/**
|
|
85
|
+
* The `schemas` option of `setupEffect`: XState's `SetupSchemas` with every
|
|
86
|
+
* schema position widened to {@link EffectSchemaLike}. Covers `context`,
|
|
87
|
+
* `input`, `output` and the per-key records for `events`, `internalEvents`,
|
|
88
|
+
* `emitted` and `children`.
|
|
89
|
+
*/
|
|
90
|
+
type EffectSetupSchemas = { [K in keyof SetupSchemas]?: EffectSchemaShape<NonNullable<SetupSchemas[K]>>; };
|
|
91
|
+
type ValidateEffectActorSchemas<TSchemas> = { [K in keyof TSchemas]: AssertNonTransformingSchema<TSchemas[K]>; };
|
|
92
|
+
type ValidateEffectSetupSchemas<TSchemas> = { [K in keyof TSchemas]: K extends 'events' | 'internalEvents' | 'emitted' | 'children' ? { [P in keyof TSchemas[K]]: AssertNonTransformingSchema<TSchemas[K][P]>; } : K extends 'context' | 'input' | 'output' ? AssertNonTransformingSchema<TSchemas[K]> : TSchemas[K]; };
|
|
93
|
+
type ToStandardSetupSchemas<TSchemas> = { [K in keyof TSchemas]: ToStandardSchemaShape<TSchemas[K]>; } extends (infer TStandardSchemas extends SetupSchemas) ? TStandardSchemas : never;
|
|
94
|
+
/**
|
|
95
|
+
* One node of the `states` option of `setupEffect`: the schemas declared for
|
|
96
|
+
* that state, and the same shape recursively for its child states. It is
|
|
97
|
+
* XState's `SetupStateSchema` with Effect schemas allowed in every schema
|
|
98
|
+
* position.
|
|
99
|
+
*/
|
|
100
|
+
interface EffectSetupStateSchema {
|
|
101
|
+
schemas?: EffectSchemaShape<SetupStateSchemas>;
|
|
102
|
+
states?: Record<string, EffectSetupStateSchema>;
|
|
103
|
+
}
|
|
104
|
+
type ValidateEffectSetupStates<TStates> = { [K in keyof TStates]: TStates[K] extends EffectSetupStateSchema ? { [P in keyof TStates[K]]: P extends 'schemas' ? TStates[K][P] extends Record<string, unknown> ? { [S in keyof TStates[K][P]]: AssertNonTransformingSchema<TStates[K][P][S]>; } : TStates[K][P] : P extends 'states' ? TStates[K][P] extends Record<string, EffectSetupStateSchema> ? ValidateEffectSetupStates<TStates[K][P]> : TStates[K][P] : TStates[K][P]; } : TStates[K]; };
|
|
105
|
+
type ToStandardSetupStateSchema<TStateSchema> = TStateSchema extends EffectSetupStateSchema ? { [K in keyof TStateSchema]: K extends 'schemas' ? ToStandardSchemaShape<TStateSchema[K]> : K extends 'states' ? TStateSchema[K] extends Record<string, EffectSetupStateSchema> ? ToStandardSetupStates<TStateSchema[K]> : TStateSchema[K] : TStateSchema[K]; } extends (infer TStandardStateSchema extends SetupStateSchema) ? TStandardStateSchema : never : never;
|
|
106
|
+
type ToStandardSetupStates<TStates> = { [K in keyof TStates]: ToStandardSetupStateSchema<TStates[K]>; };
|
|
107
|
+
declare const effectLogicBrand: unique symbol;
|
|
108
|
+
/**
|
|
109
|
+
* Type-level marker attached to logic created by `fromEffect`,
|
|
110
|
+
* `fromEffectStream` and `fromEffectEventStream`. It carries the logic's
|
|
111
|
+
* failure type and its Effect service requirements, which is how
|
|
112
|
+
* `RequirementsFrom` collects the `R` channel of `createEffectActor` without
|
|
113
|
+
* inspecting the logic at runtime.
|
|
114
|
+
*/
|
|
115
|
+
interface EffectLogicBrand<TError, TRequirements> {
|
|
116
|
+
readonly [effectLogicBrand]: {
|
|
117
|
+
readonly error: TError;
|
|
118
|
+
readonly requirements: TRequirements;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Snapshot of a `fromEffect` actor. The actor holds no context of its own: it
|
|
123
|
+
* is `active` while the Effect runs, `done` with the Effect's success value as
|
|
124
|
+
* `output`, or `error` with the Effect's failure, defect or
|
|
125
|
+
* `EffectInterruptedError` as `error`.
|
|
126
|
+
*/
|
|
127
|
+
type EffectSnapshot<TOutput, TError, TInput> = Snapshot<TOutput> & {
|
|
128
|
+
readonly context: undefined;
|
|
129
|
+
readonly input: TInput | undefined;
|
|
130
|
+
readonly error: TError | undefined;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Argument passed to the function form of an Effect source. It gives the
|
|
134
|
+
* source the actor's `input`, its own reference (`self`), the actor `system`,
|
|
135
|
+
* and `emit` for publishing events that `actor.on(...)` and `emitted(actor)`
|
|
136
|
+
* observe.
|
|
137
|
+
*/
|
|
138
|
+
type EffectSourceArgs<TInput> = {
|
|
139
|
+
readonly input: TInput;
|
|
140
|
+
readonly self: AnyActorRef;
|
|
141
|
+
readonly system: AnyActorSystem;
|
|
142
|
+
/** Emits an event that can be observed with `actor.on(...)` or `emitted(actor)`. */
|
|
143
|
+
readonly emit: (event: AnyEventObject) => void;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* What `fromEffect` accepts as its Effect: either an Effect value, or a
|
|
147
|
+
* function of {@link EffectSourceArgs} returning one. The function form is
|
|
148
|
+
* called once per actor start, so it sees that actor's input.
|
|
149
|
+
*/
|
|
150
|
+
type EffectSource<TOutput, TError, TInput, TRequirements> = Effect.Effect<TOutput, TError, TRequirements> | ((args: EffectSourceArgs<TInput>) => Effect.Effect<TOutput, TError, TRequirements>);
|
|
151
|
+
type EffectActorSchemas = {
|
|
152
|
+
readonly input?: EffectSchemaLike;
|
|
153
|
+
readonly output?: EffectSchemaLike;
|
|
154
|
+
};
|
|
155
|
+
type EffectSourceConfig<TOutput, TError, TInput, TRequirements, TSchemas extends EffectActorSchemas = EffectActorSchemas, TValidator extends ActorLogicValidator | undefined = ActorLogicValidator | undefined> = {
|
|
156
|
+
readonly id?: string;
|
|
157
|
+
readonly validator?: TValidator;
|
|
158
|
+
readonly schemas?: TSchemas & ([TValidator] extends [ActorLogicValidator] ? ValidateEffectActorSchemas<TSchemas> : unknown);
|
|
159
|
+
readonly effect: EffectSource<TOutput, TError, TInput, TRequirements>;
|
|
160
|
+
};
|
|
161
|
+
type SchemaOutput<TSchema extends EffectSchemaLike> = StandardSchemaV1.InferOutput<ToStandardSchema<TSchema>>;
|
|
162
|
+
type EffectSuccess<T> = T extends Effect.Effect<infer A, any, any> ? A : never;
|
|
163
|
+
type EffectFailure<T> = T extends Effect.Effect<any, infer E, any> ? E : never;
|
|
164
|
+
type EffectSchemaValidationConfig<TSchemas extends EffectActorSchemas> = {
|
|
165
|
+
readonly validator: ActorLogicValidator;
|
|
166
|
+
readonly schemas: TSchemas & ValidateEffectActorSchemas<TSchemas>;
|
|
167
|
+
} | {
|
|
168
|
+
readonly validator?: undefined;
|
|
169
|
+
readonly schemas: TSchemas;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Actor logic produced by `fromEffect` and `fromEffectEventStream`. It is
|
|
173
|
+
* ordinary XState actor logic carrying {@link EffectLogicBrand}, so a machine
|
|
174
|
+
* can invoke or spawn it, and `createEffectActor` can collect its
|
|
175
|
+
* requirements.
|
|
176
|
+
*/
|
|
177
|
+
type EffectActorLogic<TOutput, TError, TInput, TRequirements> = ActorLogic<EffectSnapshot<TOutput, TError, TInput>, EventObject, TInput, AnyActorSystem> & {
|
|
178
|
+
readonly id?: string;
|
|
179
|
+
} & EffectLogicBrand<TError, TRequirements>;
|
|
180
|
+
/**
|
|
181
|
+
* Snapshot of a `fromEffectStream` actor. `context` holds the most recent
|
|
182
|
+
* stream item, or `undefined` before the first one. The actor reaches `done`
|
|
183
|
+
* with no output when the stream completes, and `error` when it fails.
|
|
184
|
+
*/
|
|
185
|
+
type EffectStreamSnapshot<TItem, TError, TInput> = Snapshot<undefined> & {
|
|
186
|
+
readonly context: TItem | undefined;
|
|
187
|
+
readonly input: TInput | undefined;
|
|
188
|
+
readonly error: TError | undefined;
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Actor logic produced by `fromEffectStream`. Its snapshot is an
|
|
192
|
+
* {@link EffectStreamSnapshot}, so the parent reads the latest item from the
|
|
193
|
+
* child's `context` rather than from events.
|
|
194
|
+
*/
|
|
195
|
+
type EffectStreamActorLogic<TItem, TError, TInput, TRequirements> = ActorLogic<EffectStreamSnapshot<TItem, TError, TInput>, EventObject, TInput, AnyActorSystem> & {
|
|
196
|
+
readonly id?: string;
|
|
197
|
+
} & EffectLogicBrand<TError, TRequirements>;
|
|
198
|
+
/**
|
|
199
|
+
* Creates actor logic that runs an Effect. The actor completes with the
|
|
200
|
+
* Effect's success value as its output and fails with the Effect's error, its
|
|
201
|
+
* squashed defect, or an `EffectInterruptedError` when the Effect interrupts
|
|
202
|
+
* itself. Stopping the actor interrupts the Effect without an error. Accepts
|
|
203
|
+
* an Effect, a function of {@link EffectSourceArgs} returning one, or a config
|
|
204
|
+
* object with `id`, `schemas`, `validator` and `effect`. The logic must be run
|
|
205
|
+
* under `createEffectActor`, which provides the Effect services it declares.
|
|
206
|
+
* Resources belong to this task's scope and close on completion, failure or
|
|
207
|
+
* interruption. Use `withActorScope` to retain a resource until the owning
|
|
208
|
+
* Effect actor stops.
|
|
209
|
+
*/
|
|
210
|
+
declare function fromEffect<const TInputSchema extends EffectSchemaLike, const TOutputSchema extends EffectSchemaLike, TError = unknown, TRequirements = never>(config: Omit<EffectSourceConfig<SchemaOutput<TOutputSchema>, TError, SchemaOutput<TInputSchema>, TRequirements>, 'schemas' | 'validator'> & EffectSchemaValidationConfig<{
|
|
211
|
+
input: TInputSchema;
|
|
212
|
+
output: TOutputSchema;
|
|
213
|
+
}>): EffectActorLogic<SchemaOutput<TOutputSchema>, TError, SchemaOutput<TInputSchema>, TRequirements>;
|
|
214
|
+
declare function fromEffect<const TInputSchema extends EffectSchemaLike, TEffect extends Effect.Effect<any, any, any>>(config: Omit<EffectSourceConfig<EffectSuccess<TEffect>, EffectFailure<TEffect>, SchemaOutput<TInputSchema>, EffectRequirements<TEffect>, {
|
|
215
|
+
input: TInputSchema;
|
|
216
|
+
}>, 'effect' | 'schemas' | 'validator'> & EffectSchemaValidationConfig<{
|
|
217
|
+
input: TInputSchema;
|
|
218
|
+
output?: never;
|
|
219
|
+
}> & {
|
|
220
|
+
effect: TEffect | ((args: EffectSourceArgs<SchemaOutput<TInputSchema>>) => TEffect);
|
|
221
|
+
}): EffectActorLogic<EffectSuccess<TEffect>, EffectFailure<TEffect>, SchemaOutput<TInputSchema>, EffectRequirements<TEffect>>;
|
|
222
|
+
declare function fromEffect<const TOutputSchema extends EffectSchemaLike, TError = unknown, TInput = undefined, TRequirements = never>(config: Omit<EffectSourceConfig<SchemaOutput<TOutputSchema>, TError, TInput, TRequirements>, 'schemas' | 'validator'> & EffectSchemaValidationConfig<{
|
|
223
|
+
input?: never;
|
|
224
|
+
output: TOutputSchema;
|
|
225
|
+
}>): EffectActorLogic<SchemaOutput<TOutputSchema>, TError, TInput, TRequirements>;
|
|
226
|
+
declare function fromEffect<TOutput, TError = unknown, TInput = undefined, TRequirements = never>(config: EffectSourceConfig<TOutput, TError, TInput, TRequirements> & {
|
|
227
|
+
schemas?: undefined;
|
|
228
|
+
}): EffectActorLogic<TOutput, TError, TInput, TRequirements>;
|
|
229
|
+
declare function fromEffect<TOutput, TError = unknown, TRequirements = never>(effect: Effect.Effect<TOutput, TError, TRequirements>): EffectActorLogic<TOutput, TError, undefined, TRequirements>;
|
|
230
|
+
declare function fromEffect<TOutput, TError = unknown, TInput = undefined, TRequirements = never>(effect: (args: EffectSourceArgs<TInput>) => Effect.Effect<TOutput, TError, TRequirements>): EffectActorLogic<TOutput, TError, TInput, TRequirements>;
|
|
231
|
+
/**
|
|
232
|
+
* What `fromEffectStream` and `fromEffectEventStream` accept as their stream:
|
|
233
|
+
* either a Stream value, or a function of {@link EffectSourceArgs} returning
|
|
234
|
+
* one. The function form is called once per actor start.
|
|
235
|
+
*/
|
|
236
|
+
type EffectStreamSource<TItem, TError, TInput, TRequirements> = Stream.Stream<TItem, TError, TRequirements> | ((args: EffectSourceArgs<TInput>) => Stream.Stream<TItem, TError, TRequirements>);
|
|
237
|
+
type EffectStreamConfig<TItem, TError, TInput, TRequirements, TSchemas extends {
|
|
238
|
+
readonly input?: EffectSchemaLike;
|
|
239
|
+
} = {
|
|
240
|
+
readonly input?: EffectSchemaLike;
|
|
241
|
+
}, TValidator extends ActorLogicValidator | undefined = ActorLogicValidator | undefined> = {
|
|
242
|
+
readonly id?: string;
|
|
243
|
+
readonly validator?: TValidator;
|
|
244
|
+
readonly schemas?: TSchemas & ([TValidator] extends [ActorLogicValidator] ? ValidateEffectActorSchemas<TSchemas> : unknown);
|
|
245
|
+
readonly stream: EffectStreamSource<TItem, TError, TInput, TRequirements>;
|
|
246
|
+
};
|
|
247
|
+
type StreamItem<T> = T extends Stream.Stream<infer A, any, any> ? A : never;
|
|
248
|
+
type StreamError<T> = T extends Stream.Stream<any, infer E, any> ? E : never;
|
|
249
|
+
type StreamRequirements<T> = T extends Stream.Stream<any, any, infer R> ? R : never;
|
|
250
|
+
/**
|
|
251
|
+
* Creates actor logic that runs a Stream and exposes its most recent item as
|
|
252
|
+
* the actor's `context`. The actor reaches `done` when the stream completes
|
|
253
|
+
* and `error` when it fails. Accepts a Stream, a function of
|
|
254
|
+
* {@link EffectSourceArgs} returning one, or a config object with `id`,
|
|
255
|
+
* `schemas`, `validator` and `stream`. Its resources close when the stream
|
|
256
|
+
* completes, fails or is interrupted.
|
|
257
|
+
*/
|
|
258
|
+
declare function fromEffectStream<const TInputSchema extends EffectSchemaLike, TStream extends Stream.Stream<any, any, any>>(config: Omit<EffectStreamConfig<StreamItem<TStream>, StreamError<TStream>, SchemaOutput<TInputSchema>, StreamRequirements<TStream>>, 'stream' | 'schemas' | 'validator'> & EffectSchemaValidationConfig<{
|
|
259
|
+
input: TInputSchema;
|
|
260
|
+
}> & {
|
|
261
|
+
stream: TStream | ((args: EffectSourceArgs<SchemaOutput<TInputSchema>>) => TStream);
|
|
262
|
+
}): EffectStreamActorLogic<StreamItem<TStream>, StreamError<TStream>, SchemaOutput<TInputSchema>, StreamRequirements<TStream>>;
|
|
263
|
+
declare function fromEffectStream<TItem, TError = unknown, TInput = undefined, TRequirements = never>(config: EffectStreamConfig<TItem, TError, TInput, TRequirements> & {
|
|
264
|
+
schemas?: undefined;
|
|
265
|
+
}): EffectStreamActorLogic<TItem, TError, TInput, TRequirements>;
|
|
266
|
+
declare function fromEffectStream<TItem, TError = unknown, TInput = undefined, TRequirements = never>(stream: EffectStreamSource<TItem, TError, TInput, TRequirements>): EffectStreamActorLogic<TItem, TError, TInput, TRequirements>;
|
|
267
|
+
/**
|
|
268
|
+
* Creates actor logic that runs a Stream of events and relays each item to the
|
|
269
|
+
* parent machine as an event, the way `fromEventObservable` does. The actor
|
|
270
|
+
* has no output: it reaches `done` when the stream completes and `error` when
|
|
271
|
+
* it fails. Accepts the same forms as `fromEffectStream`. Its resources close
|
|
272
|
+
* when the stream completes, fails or is interrupted.
|
|
273
|
+
*/
|
|
274
|
+
declare function fromEffectEventStream<const TInputSchema extends EffectSchemaLike, TStream extends Stream.Stream<EventObject, any, any>>(config: Omit<EffectStreamConfig<StreamItem<TStream>, StreamError<TStream>, SchemaOutput<TInputSchema>, StreamRequirements<TStream>>, 'stream' | 'schemas' | 'validator'> & EffectSchemaValidationConfig<{
|
|
275
|
+
input: TInputSchema;
|
|
276
|
+
}> & {
|
|
277
|
+
stream: TStream | ((args: EffectSourceArgs<SchemaOutput<TInputSchema>>) => TStream);
|
|
278
|
+
}): EffectActorLogic<undefined, StreamError<TStream>, SchemaOutput<TInputSchema>, StreamRequirements<TStream>>;
|
|
279
|
+
declare function fromEffectEventStream<TEvent extends EventObject, TError = unknown, TInput = undefined, TRequirements = never>(config: EffectStreamConfig<TEvent, TError, TInput, TRequirements> & {
|
|
280
|
+
schemas?: undefined;
|
|
281
|
+
}): EffectActorLogic<undefined, TError, TInput, TRequirements>;
|
|
282
|
+
declare function fromEffectEventStream<TEvent extends EventObject, TError = unknown, TInput = undefined, TRequirements = never>(stream: EffectStreamSource<TEvent, TError, TInput, TRequirements>): EffectActorLogic<undefined, TError, TInput, TRequirements>;
|
|
283
|
+
/** The `R` channel of an Effect type, or `never` for anything else. */
|
|
284
|
+
type EffectRequirements<T> = T extends Effect.Effect<any, any, infer R> ? R : never;
|
|
285
|
+
type RequirementsFromActions<T> = T extends Record<string, (...args: any[]) => any> ? T[keyof T] extends (infer TAction) ? TAction extends {
|
|
286
|
+
readonly [effectActionBrand]?: infer R;
|
|
287
|
+
} ? unknown extends R ? EffectRequirements<TAction extends ((...args: any[]) => infer TResult) ? TResult : never> : Exclude<R, undefined> : EffectRequirements<TAction extends ((...args: any[]) => infer TResult) ? TResult : never> : never : never;
|
|
288
|
+
/**
|
|
289
|
+
* Recursion budget for walking registered child machines. A machine cannot
|
|
290
|
+
* contain itself as a registered actor type, but deeply nested machine trees
|
|
291
|
+
* are capped at this depth to keep the conditional type finite.
|
|
292
|
+
*/
|
|
293
|
+
type MaxDepth = 10;
|
|
294
|
+
type PrevDepth = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
295
|
+
type Depth = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
296
|
+
type RequirementsFromActors<T, TDepth extends Depth> = T extends Record<string, any> ? RequirementsFrom<T[keyof T], TDepth> : never;
|
|
297
|
+
/** `invoke` accepts a single config or an array of them. */
|
|
298
|
+
type InvokeEntry<TInvoke> = TInvoke extends readonly (infer U)[] ? U : TInvoke;
|
|
299
|
+
/**
|
|
300
|
+
* Requirements of the logic passed inline as `invoke.src`. A string `src`
|
|
301
|
+
* names an actor registered in `setup({ actors })`, whose requirements are
|
|
302
|
+
* already collected from the actor map, so it contributes nothing here.
|
|
303
|
+
*/
|
|
304
|
+
type RequirementsFromInvoke<TInvoke, TDepth extends Depth> = InvokeEntry<TInvoke> extends (infer TEntry) ? TEntry extends {
|
|
305
|
+
src: infer TSrc;
|
|
306
|
+
} ? TSrc extends string ? never : RequirementsFrom<TSrc, TDepth> : never : never;
|
|
307
|
+
/**
|
|
308
|
+
* Walks the machine's literal config tree (the state schema) collecting
|
|
309
|
+
* requirements from inline `invoke.src` logic at the root and in every
|
|
310
|
+
* descendant state node.
|
|
311
|
+
*/
|
|
312
|
+
type RequirementsFromStateSchema<TSchema, TDepth extends Depth> = (TSchema extends {
|
|
313
|
+
invoke: infer TInvoke;
|
|
314
|
+
} ? RequirementsFromInvoke<TInvoke, TDepth> : never) | (TSchema extends {
|
|
315
|
+
states: infer TStates;
|
|
316
|
+
} ? TStates extends Record<string, any> ? RequirementsFromStateSchema<TStates[keyof TStates], TDepth> : never : never);
|
|
317
|
+
/**
|
|
318
|
+
* Collects the Effect service requirements of an actor logic.
|
|
319
|
+
*
|
|
320
|
+
* Actor and invocation scopes are supplied by the host and excluded here.
|
|
321
|
+
* For Effect logic this is the remaining `R`. For a state machine it is the
|
|
322
|
+
* union of the requirements of its registered Effect actions, its registered
|
|
323
|
+
* Effect actors, the Effect logic passed inline as `invoke.src` anywhere in
|
|
324
|
+
* its state tree, and — recursively — the requirements of any child machine
|
|
325
|
+
* reached either way (capped at `MaxDepth` levels of machine nesting).
|
|
326
|
+
*/
|
|
327
|
+
type RequirementsFrom<T, TDepth extends Depth = MaxDepth> = T extends EffectLogicBrand<any, infer R> ? Exclude<R, ActorScope | Scope.Scope> : T extends {
|
|
328
|
+
readonly _actionMap: infer TActionMap;
|
|
329
|
+
readonly _actorMap: infer TActorMap;
|
|
330
|
+
readonly _stateSchema: infer TStateSchema;
|
|
331
|
+
} ? Exclude<RequirementsFromActions<TActionMap>, ActorScope | Scope.Scope> | ([TDepth] extends [0] ? never : RequirementsFromActors<TActorMap, PrevDepth[TDepth]> | RequirementsFromStateSchema<TStateSchema, PrevDepth[TDepth]>) : never;
|
|
332
|
+
/** Options for {@link createEffectActor}. */
|
|
333
|
+
type EffectActorOptions<TLogic extends AnyActorLogic> = {
|
|
334
|
+
readonly input?: InputFrom<TLogic>;
|
|
335
|
+
/**
|
|
336
|
+
* A snapshot from `actor.getPersistedSnapshot()`. The actor resumes in that
|
|
337
|
+
* state without re-running entry actions, and pending timers keep their
|
|
338
|
+
* original deadlines, as with XState's `createActor(logic, { snapshot })`.
|
|
339
|
+
* State-machine children resume their persisted state and completed
|
|
340
|
+
* children stay done. Effect tasks and streams that were running, at the
|
|
341
|
+
* root or as children, start again from the beginning. A restored actor
|
|
342
|
+
* does not need `input`.
|
|
343
|
+
*/
|
|
344
|
+
readonly snapshot?: ActorOptions<TLogic>['snapshot'];
|
|
345
|
+
} & RequiredActorOptionsFor<TLogic>;
|
|
346
|
+
type EffectActorOptionsArgs<TLogic extends AnyActorLogic> = [RequiredActorOptionsKeys<TLogic>] extends [never] ? [options?: EffectActorOptions<TLogic>] : [options: EffectActorOptions<TLogic>];
|
|
347
|
+
/**
|
|
348
|
+
* Creates and starts an actor as an Effect interpreter over pure transitions.
|
|
349
|
+
*
|
|
350
|
+
* Each step is `transition(snapshot, event)`, a pure function that returns
|
|
351
|
+
* the next snapshot and the actions to run. An Effect fiber owns the loop:
|
|
352
|
+
* the mailbox is a `Queue`, timers are `Effect.sleep` fibers on the Effect
|
|
353
|
+
* `Clock`, and declared Effect actions run as forked Effects in the actor's
|
|
354
|
+
* `Scope` with the services captured here. Child actors are started as live
|
|
355
|
+
* XState actors whose Effects run in the same host.
|
|
356
|
+
*
|
|
357
|
+
* The actor is a scoped resource: it stops, and every Effect it hosts is
|
|
358
|
+
* interrupted, when the enclosing `Scope` closes. The returned Effect never
|
|
359
|
+
* fails; the actor's own outcome is its snapshot status, read with `join`.
|
|
360
|
+
*/
|
|
361
|
+
declare function createEffectActor<TLogic extends AnyActorLogic>(logic: TLogic, ...[options]: EffectActorOptionsArgs<TLogic>): Effect.Effect<EffectActor<TLogic>, never, RequirementsFrom<TLogic> | Scope.Scope>;
|
|
362
|
+
declare const EffectInterruptedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
363
|
+
readonly _tag: "EffectInterruptedError";
|
|
364
|
+
} & Readonly<A>;
|
|
365
|
+
/**
|
|
366
|
+
* The failure an Effect-backed actor reports when its Effect was interrupted
|
|
367
|
+
* by something other than the actor being stopped, such as `Effect.interrupt`,
|
|
368
|
+
* losing an `Effect.race`, or an `Effect.timeout` that interrupts.
|
|
369
|
+
*/
|
|
370
|
+
declare class EffectInterruptedError extends EffectInterruptedError_base<{
|
|
371
|
+
readonly cause: Cause.Cause<never>;
|
|
372
|
+
}> {
|
|
373
|
+
get message(): string;
|
|
374
|
+
}
|
|
375
|
+
declare const ActorStoppedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
376
|
+
readonly _tag: "ActorStoppedError";
|
|
377
|
+
} & Readonly<A>;
|
|
378
|
+
/**
|
|
379
|
+
* Reported by `waitFor` when the actor stops or errors before a snapshot
|
|
380
|
+
* matches, and by `join` when the actor stops without output. `join` reports
|
|
381
|
+
* an errored actor's own `snapshot.error` instead.
|
|
382
|
+
*/
|
|
383
|
+
declare class ActorStoppedError extends ActorStoppedError_base<{
|
|
384
|
+
readonly actorId: string;
|
|
385
|
+
readonly snapshot: Snapshot<unknown>;
|
|
386
|
+
}> {
|
|
387
|
+
get message(): string;
|
|
388
|
+
}
|
|
389
|
+
declare const ActorFailedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
390
|
+
readonly _tag: "@systemfsoftware/xstate-effect/errors/ActorFailedError";
|
|
391
|
+
} & Readonly<A>;
|
|
392
|
+
declare class ActorFailedError<E = unknown> extends ActorFailedError_base<{
|
|
393
|
+
readonly cause: E;
|
|
394
|
+
}> {
|
|
395
|
+
get message(): string;
|
|
396
|
+
}
|
|
397
|
+
declare const NotReadyError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
398
|
+
readonly _tag: "NotReadyError";
|
|
399
|
+
} & Readonly<A>;
|
|
400
|
+
/**
|
|
401
|
+
* Reported by the `send` atom of `createActorAtoms` when an event is sent
|
|
402
|
+
* before the actor's runtime has finished building.
|
|
403
|
+
*/
|
|
404
|
+
declare class NotReadyError extends NotReadyError_base {
|
|
405
|
+
get message(): string;
|
|
406
|
+
}
|
|
407
|
+
type IsUnion<T, U = T> = T extends unknown ? [U] extends [T] ? false : true : never;
|
|
408
|
+
type Join<TPrefix extends string, TKey extends string> = TPrefix extends '' ? TKey : `${TPrefix}.${TKey}`;
|
|
409
|
+
/** The tag of the machine itself, used when the root state is parallel. */
|
|
410
|
+
declare const MACHINE_TAG = "(machine)";
|
|
411
|
+
/**
|
|
412
|
+
* The dotted path of a state value: `'idle'`, `'form.editing'`. A parallel
|
|
413
|
+
* state has no single path, so its tag stops at the parallel state, or is
|
|
414
|
+
* `'(machine)'` when the machine itself is parallel.
|
|
415
|
+
*/
|
|
416
|
+
type StateTag<TValue, TPrefix extends string = ''> = string extends TValue ? string : TValue extends string ? Join<TPrefix, TValue> : TValue extends object ? string extends keyof TValue ? string : IsUnion<keyof TValue & string> extends true ? TPrefix extends '' ? typeof MACHINE_TAG : TPrefix : { [K in keyof TValue & string]: StateTag<TValue[K], Join<TPrefix, K>>; }[keyof TValue & string] : never;
|
|
417
|
+
type TaggedStateOf<TSnapshot, TValue, TContext extends MachineContext, TSchema extends StateSchema> = TValue extends unknown ? {
|
|
418
|
+
readonly _tag: StateTag<TValue>;
|
|
419
|
+
readonly value: TValue;
|
|
420
|
+
readonly context: StateContextFromStateValue<TSchema, TContext, TValue>;
|
|
421
|
+
readonly snapshot: TSnapshot;
|
|
422
|
+
} : never;
|
|
423
|
+
/**
|
|
424
|
+
* A machine snapshot as a tagged union over its states. `_tag` is the state's
|
|
425
|
+
* dotted path and `context` is the context of that state, including any
|
|
426
|
+
* per-state context schema, so `Match.tag` narrows both.
|
|
427
|
+
*/
|
|
428
|
+
type TaggedStateFrom<TSnapshot> = TSnapshot extends MachineSnapshot<infer TContext, infer _TEvent, infer _TChildren, infer _TStateValue, infer _TTag, infer _TOutput, infer _TMeta, infer TSchema> ? TaggedStateOf<TSnapshot, StateValueFromStateSchema<TSchema>, TContext, TSchema> : never;
|
|
429
|
+
/** The tagged state union of a machine. */
|
|
430
|
+
type TaggedState<TMachine extends AnyStateMachine> = TaggedStateFrom<SnapshotFrom<TMachine>>;
|
|
431
|
+
/**
|
|
432
|
+
* Views a machine snapshot as a tagged union member for `Match.tag`,
|
|
433
|
+
* `Match.tags` or a `switch` on `_tag`.
|
|
434
|
+
*
|
|
435
|
+
* @example
|
|
436
|
+
*
|
|
437
|
+
* ```ts
|
|
438
|
+
* const view = Match.type<TaggedStateFrom<typeof snapshot>>().pipe(
|
|
439
|
+
* Match.tag('loading', ({ context }) => `Loading ${context.id}`),
|
|
440
|
+
* Match.tag('done', () => 'Done'),
|
|
441
|
+
* Match.exhaustive
|
|
442
|
+
* );
|
|
443
|
+
* view(taggedState(snapshot));
|
|
444
|
+
* ```
|
|
445
|
+
*/
|
|
446
|
+
declare function taggedState<TSnapshot extends AnyMachineSnapshot>(snapshot: TSnapshot): TaggedStateFrom<TSnapshot>;
|
|
447
|
+
export { ToStandardSetupStates as A, fromEffectEventStream as C, EffectSetupSchemas as D, EffectSchemaLike as E, withActorScope as F, EffectActor as I, ValidateEffectSetupStates as M, effectActionBrand as N, EffectSetupStateSchema as O, ActorScope as P, fromEffect as S, EffectSchema as T, EffectSource as _, ActorFailedError as a, EffectStreamSnapshot as b, NotReadyError as c, createEffectActor as d, EffectRequirements as f, EffectSnapshot as g, EffectLogicBrand as h, taggedState as i, ValidateEffectSetupSchemas as j, ToStandardSetupSchemas as k, EffectActorOptions as l, EffectActorLogic as m, TaggedState as n, ActorStoppedError as o, RequirementsFrom as p, TaggedStateFrom as r, EffectInterruptedError as s, StateTag as t, EffectActorOptionsArgs as u, EffectSourceArgs as v, fromEffectStream as w, EffectStreamSource as x, EffectStreamActorLogic as y };
|
package/package.json
CHANGED
|
@@ -1,10 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@systemfsoftware/xstate-effect",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "0.1.0-beta.8",
|
|
5
|
+
"author": "Ryan Lee <drdgvhbh@gmail.com>",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
|
-
"url": "git+https://github.com/systemfsoftware/xstate.git"
|
|
8
|
+
"url": "git+https://github.com/systemfsoftware/xstate.git",
|
|
9
|
+
"directory": "packages/xstate-effect"
|
|
8
10
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
+
"homepage": "https://github.com/systemfsoftware/xstate/tree/main/packages/xstate-effect#readme",
|
|
12
|
+
"bugs": "https://github.com/systemfsoftware/xstate/issues",
|
|
13
|
+
"description": "Effect 4 actors for XState machines: services, scopes, clocks and tracing from Effect — forked under systemfsoftware from statelyai/xstate (@xstate/effect at 2146ae26).",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@systemfsoftware/xstate": "^6.0.0-beta.65",
|
|
21
|
+
"effect": "^4.1.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@effect/tsgo": "0.64.1",
|
|
25
|
+
"@microsoft/api-extractor": "7.59.1",
|
|
26
|
+
"@systemfsoftware/arethetypeswrong-cli": "file:../../.deps/arethetypeswrong-cli.tgz",
|
|
27
|
+
"@systemfsoftware/tsconfig": "file:../../.deps/tsconfig.tgz",
|
|
28
|
+
"@systemfsoftware/vitest": "file:../../.deps/vitest.tgz",
|
|
29
|
+
"@systemfsoftware/xstate": "^6.0.0-beta.65",
|
|
30
|
+
"@types/node": "24.19.1",
|
|
31
|
+
"effect": "4.1.2",
|
|
32
|
+
"fast-check": "4.9.0",
|
|
33
|
+
"rimraf": "6.1.3",
|
|
34
|
+
"tsdown": "0.23.0",
|
|
35
|
+
"typescript": "7.0.2",
|
|
36
|
+
"vitest": "5.0.3"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public",
|
|
40
|
+
"provenance": true
|
|
41
|
+
},
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"default": "./dist/index.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./atom": {
|
|
48
|
+
"types": "./dist/atom.d.ts",
|
|
49
|
+
"default": "./dist/atom.mjs"
|
|
50
|
+
},
|
|
51
|
+
"./package.json": "./package.json"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"clean": "rimraf dist",
|
|
55
|
+
"build": "tsdown -l warn && pnpm api:check",
|
|
56
|
+
"typecheck": "tsc -b",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"lint:tsgo": "effect-tsgo diagnostics --project tsconfig.app.json --format ${TSGO_FORMAT:-text} && ../../scripts/tsgo-test-diagnostics.ts",
|
|
59
|
+
"attw": "attw --pack .",
|
|
60
|
+
"api:check": "api-extractor run && api-extractor run --config api-extractor.atom.json",
|
|
61
|
+
"api:update": "api-extractor run --local && api-extractor run --local --config api-extractor.atom.json"
|
|
62
|
+
}
|
|
63
|
+
}
|