@mantaq/sugar 0.3.0 → 0.4.0

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/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyActor, AnyEventRef, EffectInput, EventRef, InternalEvent, Snapshot, StateRef } from "@mantaq/core";
1
+ import { Actor, ActorBuilder, ActorOptions, AnyActor, AnyEventRef, AnyStateRef, Clock, EffectInput, EventRef, InitialState, InternalEvent, Snapshot, StateRef } from "@mantaq/core";
2
2
  //#region src/actors/matches.d.ts
3
3
  declare function matches(actor: {
4
4
  snapshot(): Snapshot;
@@ -95,8 +95,52 @@ interface Tag {
95
95
  }
96
96
  declare function tag(...stateNames: StateRef<string, unknown>[]): Tag;
97
97
  //#endregion
98
+ //#region src/parts.d.ts
99
+ interface ActorSpec {
100
+ states: readonly AnyStateRef[];
101
+ inputs: readonly AnyEventRef[];
102
+ internal?: readonly AnyEventRef[];
103
+ outputs?: readonly AnyEventRef[];
104
+ context?: unknown;
105
+ initial: AnyStateRef | {
106
+ state: AnyStateRef;
107
+ payload?: unknown;
108
+ };
109
+ clock?: Clock;
110
+ regions?: Record<string, AnyActor>;
111
+ internalBudget?: number;
112
+ }
113
+ type NotUndef<T> = [Exclude<T, undefined>] extends [never] ? never : Exclude<T, undefined>;
114
+ type InternalOf<S extends ActorSpec> = "internal" extends keyof S ? [NotUndef<S["internal"]>] extends [never] ? readonly [] : NotUndef<S["internal"]> : readonly [];
115
+ type OutputsOf<S extends ActorSpec> = "outputs" extends keyof S ? [NotUndef<S["outputs"]>] extends [never] ? readonly [] : NotUndef<S["outputs"]> : readonly [];
116
+ type ContextOf<S extends ActorSpec> = "context" extends keyof S ? [NotUndef<S["context"]>] extends [never] ? Record<string, unknown> : NotUndef<S["context"]> : Record<string, unknown>;
117
+ type BuilderOf<S extends ActorSpec> = ActorBuilder<S["states"], S["inputs"], InternalOf<S>, OutputsOf<S>, ContextOf<S>>;
118
+ type Fragment<S extends ActorSpec> = (m: BuilderOf<S>) => void;
119
+ declare function definePart<S extends ActorSpec = never>(fn: (m: BuilderOf<S>) => void): Fragment<S>;
120
+ declare function use<S extends ActorSpec>(m: BuilderOf<S>, part: Fragment<S>): void;
121
+ type Part<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext> = (m: ActorBuilder<States, Inputs, Internal, Outputs, ActorContext>) => void;
122
+ type SpecValue<States extends readonly AnyStateRef[], Inputs extends readonly AnyEventRef[], Internal extends readonly AnyEventRef[], Outputs extends readonly AnyEventRef[], ActorContext, Initial> = {
123
+ states: States;
124
+ inputs: Inputs;
125
+ internal?: Internal;
126
+ outputs?: Outputs;
127
+ context?: ActorContext;
128
+ clock?: Clock;
129
+ regions?: Record<string, AnyActor>;
130
+ internalBudget?: number;
131
+ initial: Initial;
132
+ };
133
+ /**
134
+ * Construct the actor's static spec — states, inputs, internal/output events,
135
+ * context, initial state, clock, regions and budget. State/event tuples and
136
+ * the initial ref narrow to literals; the context stays mutable, so
137
+ * `definePart` handlers read and write it with no `as` casts.
138
+ */
139
+ declare function actorSpec<const States extends readonly AnyStateRef[], const Inputs extends readonly AnyEventRef[], const Internal extends readonly AnyEventRef[] = readonly [], const Outputs extends readonly AnyEventRef[] = readonly [], ActorContext = Record<string, unknown>, const Initial extends InitialState<States[number]> = InitialState<States[number]>>(spec: SpecValue<States, Inputs, Internal, Outputs, ActorContext, Initial>): SpecValue<States, Inputs, Internal, Outputs, ActorContext, Initial>;
140
+ declare function withParts<const States extends readonly AnyStateRef[], const Inputs extends readonly AnyEventRef[], const Internal extends readonly AnyEventRef[] = readonly [], const Outputs extends readonly AnyEventRef[] = readonly [], ActorContext = Record<string, unknown>>(base: Omit<ActorOptions<States, Inputs, Internal, Outputs, ActorContext>, "setup">, parts: Part<States, Inputs, Internal, Outputs, ActorContext> | readonly Part<States, Inputs, Internal, Outputs, ActorContext>[]): Actor<States, Inputs, Internal, Outputs, ActorContext>;
141
+ //#endregion
98
142
  //#region src/snapshot.d.ts
99
143
  declare function isIn(snapshot: Snapshot, stateRefName: string): boolean;
100
144
  declare function activeLeaves(snapshot: Snapshot): string[];
101
145
  //#endregion
102
- export { ActorMap, type EventLike, type SendableEvent, type SendableMap, activeLeaves, broadcast, events, isIn, matches, onOutput, states, tag, withPromise, withTimeout };
146
+ export { ActorMap, type ActorSpec, type BuilderOf, type EventLike, type Fragment, type Part, type SendableEvent, type SendableMap, activeLeaves, actorSpec, broadcast, definePart, events, isIn, matches, onOutput, states, tag, use, withParts, withPromise, withTimeout };
package/dist/index.mjs CHANGED
@@ -1,6 +1,4 @@
1
- import { abortEffects, setOutputHandler } from "@mantaq/core/internal";
2
- import { Either } from "@mantaq/utils";
3
- import { event, state } from "@mantaq/core";
1
+ import { Actor, event, state } from "@mantaq/core";
4
2
  //#region src/actors/matches.ts
5
3
  function matchSnapshot(snapshot, parts, index) {
6
4
  const stateName = snapshot.path[0];
@@ -54,10 +52,7 @@ var ActorMap = class {
54
52
  this.#actors.get(key)?.send(event);
55
53
  }
56
54
  kill(key) {
57
- const actor = this.#actors.get(key);
58
- if (actor) Either.match(abortEffects(actor), (err) => {
59
- throw new Error(err.message);
60
- }, () => {});
55
+ this.#actors.get(key)?.dispose();
61
56
  this.#reapers.get(key)?.();
62
57
  this.#reapers.delete(key);
63
58
  this.#actors.delete(key);
@@ -106,7 +101,7 @@ function events(...names) {
106
101
  * factory connects a child's declared outputs to a receiver.
107
102
  */
108
103
  function onOutput(actor, handler) {
109
- setOutputHandler(actor, handler);
104
+ actor.on("output", handler);
110
105
  }
111
106
  //#endregion
112
107
  //#region src/effects/promise.ts
@@ -150,4 +145,30 @@ function tag(...stateNames) {
150
145
  return { has: (snapshot) => names.some((name) => isIn(snapshot, name)) };
151
146
  }
152
147
  //#endregion
153
- export { ActorMap, activeLeaves, broadcast, events, isIn, matches, onOutput, states, tag, withPromise, withTimeout };
148
+ //#region src/parts.ts
149
+ function definePart(fn) {
150
+ return fn;
151
+ }
152
+ function use(m, part) {
153
+ part(m);
154
+ }
155
+ /**
156
+ * Construct the actor's static spec — states, inputs, internal/output events,
157
+ * context, initial state, clock, regions and budget. State/event tuples and
158
+ * the initial ref narrow to literals; the context stays mutable, so
159
+ * `definePart` handlers read and write it with no `as` casts.
160
+ */
161
+ function actorSpec(spec) {
162
+ return spec;
163
+ }
164
+ function withParts(base, parts) {
165
+ const list = Array.isArray(parts) ? parts : [parts];
166
+ return new Actor({
167
+ ...base,
168
+ setup: (m) => {
169
+ for (const part of list) part(m);
170
+ }
171
+ });
172
+ }
173
+ //#endregion
174
+ export { ActorMap, activeLeaves, actorSpec, broadcast, definePart, events, isIn, matches, onOutput, states, tag, use, withParts, withPromise, withTimeout };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantaq/sugar",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Userland sugar for mantaq actors — matches, effect helpers, transition utilities.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,8 +20,7 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@mantaq/utils": "0.0.2",
24
- "@mantaq/core": "0.2.0"
23
+ "@mantaq/core": "0.3.0"
25
24
  },
26
25
  "devDependencies": {
27
26
  "@stryker-mutator/core": "^9",