@actor-system/behaviors 0.0.1
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/__bundle__/shared/dist/types.d.ts +9 -0
- package/dist/__bundle__/shared/dist/types.internal.d.ts +9 -0
- package/dist/empty.d.ts +5 -0
- package/dist/empty.internal.d.ts +5 -0
- package/dist/empty.js +5 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.internal.d.ts +11 -0
- package/dist/index.js +10 -0
- package/dist/intercept.d.ts +10 -0
- package/dist/intercept.internal.d.ts +10 -0
- package/dist/intercept.js +23 -0
- package/dist/receive.d.ts +15 -0
- package/dist/receive.internal.d.ts +15 -0
- package/dist/receive.js +18 -0
- package/dist/restart.d.ts +5 -0
- package/dist/restart.internal.d.ts +5 -0
- package/dist/restart.js +7 -0
- package/dist/same.d.ts +5 -0
- package/dist/same.internal.d.ts +5 -0
- package/dist/same.js +5 -0
- package/dist/setup.d.ts +8 -0
- package/dist/setup.internal.d.ts +8 -0
- package/dist/setup.js +6 -0
- package/dist/stopped.d.ts +5 -0
- package/dist/stopped.internal.d.ts +5 -0
- package/dist/stopped.js +7 -0
- package/dist/supervise.d.ts +14 -0
- package/dist/supervise.internal.d.ts +14 -0
- package/dist/supervise.js +36 -0
- package/dist/with-stash.d.ts +12 -0
- package/dist/with-stash.internal.d.ts +12 -0
- package/dist/with-stash.js +45 -0
- package/dist/with-timers.d.ts +11 -0
- package/dist/with-timers.internal.d.ts +11 -0
- package/dist/with-timers.js +50 -0
- package/package.json +38 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bivariance hack for ergonomic action and guard typing in strict TypeScript mode.
|
|
3
|
+
* Allows config-based functions to be less strictly parameterized.
|
|
4
|
+
*/
|
|
5
|
+
type Bivariant<Fn extends (...args: any[]) => any> = {
|
|
6
|
+
bivarianceHack(...args: Parameters<Fn>): ReturnType<Fn>;
|
|
7
|
+
}["bivarianceHack"];
|
|
8
|
+
|
|
9
|
+
export type { Bivariant };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bivariance hack for ergonomic action and guard typing in strict TypeScript mode.
|
|
3
|
+
* Allows config-based functions to be less strictly parameterized.
|
|
4
|
+
*/
|
|
5
|
+
type Bivariant<Fn extends (...args: any[]) => any> = {
|
|
6
|
+
bivarianceHack(...args: Parameters<Fn>): ReturnType<Fn>;
|
|
7
|
+
}["bivarianceHack"];
|
|
8
|
+
|
|
9
|
+
export type { Bivariant };
|
package/dist/empty.d.ts
ADDED
package/dist/empty.js
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { empty } from './empty.js';
|
|
2
|
+
export { intercept } from './intercept.js';
|
|
3
|
+
export { ReceiveMessage, ReceiveSignal, receive, receiveMessage, receiveSignal } from './receive.js';
|
|
4
|
+
export { restart } from './restart.js';
|
|
5
|
+
export { same } from './same.js';
|
|
6
|
+
export { setup } from './setup.js';
|
|
7
|
+
export { stopped } from './stopped.js';
|
|
8
|
+
export { supervise } from './supervise.js';
|
|
9
|
+
export { Stash, withStash } from './with-stash.js';
|
|
10
|
+
export { Timers, withTimers } from './with-timers.js';
|
|
11
|
+
export { Behavior } from '@actor-system/core';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { empty } from './empty.internal.js';
|
|
2
|
+
export { intercept } from './intercept.internal.js';
|
|
3
|
+
export { ReceiveMessage, ReceiveSignal, receive, receiveMessage, receiveSignal } from './receive.internal.js';
|
|
4
|
+
export { restart } from './restart.internal.js';
|
|
5
|
+
export { same } from './same.internal.js';
|
|
6
|
+
export { setup } from './setup.internal.js';
|
|
7
|
+
export { stopped } from './stopped.internal.js';
|
|
8
|
+
export { supervise } from './supervise.internal.js';
|
|
9
|
+
export { Stash, withStash } from './with-stash.internal.js';
|
|
10
|
+
export { Timers, withTimers } from './with-timers.internal.js';
|
|
11
|
+
export { Behavior } from '@actor-system/core/internal';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { empty } from './empty.js';
|
|
2
|
+
export { intercept } from './intercept.js';
|
|
3
|
+
export { receive, receiveMessage, receiveSignal } from './receive.js';
|
|
4
|
+
export { restart } from './restart.js';
|
|
5
|
+
export { same } from './same.js';
|
|
6
|
+
export { setup } from './setup.js';
|
|
7
|
+
export { stopped } from './stopped.js';
|
|
8
|
+
export { supervise } from './supervise.js';
|
|
9
|
+
export { withStash } from './with-stash.js';
|
|
10
|
+
export { withTimers } from './with-timers.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { behavior, signal, ActorContext } from '@actor-system/core';
|
|
2
|
+
import { Bivariant } from './__bundle__/shared/dist/types.js';
|
|
3
|
+
|
|
4
|
+
type Interceptor<Input, Output = Input> = Bivariant<(post: Output | signal.Signal, context: ActorContext<Output>) => Input | signal.Signal | behavior.Behavior<Input>>;
|
|
5
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Folded<Input>, interceptor: Interceptor<Input, Output>): behavior.Folded<Output>;
|
|
6
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Control<Input>, interceptor: Interceptor<Input, Output>): behavior.Control<Output>;
|
|
7
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Receive<Input>, interceptor: Interceptor<Input, Output>): behavior.Receive<Output>;
|
|
8
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Behavior<Input>, interceptor: Interceptor<Input, Output>): behavior.Behavior<Output>;
|
|
9
|
+
|
|
10
|
+
export { intercept };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { behavior, signal, ActorContext } from '@actor-system/core/internal';
|
|
2
|
+
import { Bivariant } from './__bundle__/shared/dist/types.internal.js';
|
|
3
|
+
|
|
4
|
+
type Interceptor<Input, Output = Input> = Bivariant<(post: Output | signal.Signal, context: ActorContext<Output>) => Input | signal.Signal | behavior.Behavior<Input>>;
|
|
5
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Folded<Input>, interceptor: Interceptor<Input, Output>): behavior.Folded<Output>;
|
|
6
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Control<Input>, interceptor: Interceptor<Input, Output>): behavior.Control<Output>;
|
|
7
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Receive<Input>, interceptor: Interceptor<Input, Output>): behavior.Receive<Output>;
|
|
8
|
+
declare function intercept<Input, Output = Input>(inner: behavior.Behavior<Input>, interceptor: Interceptor<Input, Output>): behavior.Behavior<Output>;
|
|
9
|
+
|
|
10
|
+
export { intercept };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { behavior } from '@actor-system/core';
|
|
2
|
+
import { receive } from './receive.js';
|
|
3
|
+
import { setup } from './setup.js';
|
|
4
|
+
|
|
5
|
+
function intercept(inner, interceptor) {
|
|
6
|
+
if (behavior.isControl(inner)) {
|
|
7
|
+
return inner;
|
|
8
|
+
}
|
|
9
|
+
if (behavior.isFolded(inner)) {
|
|
10
|
+
return setup((ctx) => intercept(behavior.unfold(inner, ctx), interceptor));
|
|
11
|
+
}
|
|
12
|
+
if (behavior.isReceive(inner)) {
|
|
13
|
+
return receive((message, context) => {
|
|
14
|
+
const intercepted = interceptor(message, context);
|
|
15
|
+
return behavior.isBehavior(intercepted)
|
|
16
|
+
? intercept(intercepted, interceptor)
|
|
17
|
+
: intercept(behavior.delegate(inner, intercepted, context), interceptor);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Cannot intercept behavior of type ${inner} with interceptor`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { intercept };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { signal, ActorContext, behavior } from '@actor-system/core';
|
|
2
|
+
import { Bivariant } from './__bundle__/shared/dist/types.js';
|
|
3
|
+
|
|
4
|
+
interface ReceiveMessage<T> extends behavior.Receive<T> {
|
|
5
|
+
receiveSignal(handler: Bivariant<(signal: signal.Signal, ctx: ActorContext<T>) => behavior.Behavior<T> | void>): behavior.Receive<T>;
|
|
6
|
+
}
|
|
7
|
+
interface ReceiveSignal<T> extends behavior.Receive<T> {
|
|
8
|
+
receiveMessage(handler: Bivariant<(message: T, ctx: ActorContext<T>) => behavior.Behavior<T> | void>): behavior.Receive<T>;
|
|
9
|
+
}
|
|
10
|
+
declare const receiveMessage: <T>(onMessage: Bivariant<(message: T, context: ActorContext<T>) => behavior.Behavior<T> | void>) => ReceiveMessage<T>;
|
|
11
|
+
declare const receiveSignal: <T>(onSignal: Bivariant<(signal: signal.Signal, context: ActorContext<T>) => behavior.Behavior<T> | void>) => ReceiveSignal<T>;
|
|
12
|
+
declare const receive: <T>(handler: Bivariant<(messageOrSignal: T | signal.Signal, context: ActorContext<T>) => behavior.Behavior<T> | void>) => behavior.Receive<T>;
|
|
13
|
+
|
|
14
|
+
export { receive, receiveMessage, receiveSignal };
|
|
15
|
+
export type { ReceiveMessage, ReceiveSignal };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { signal, ActorContext, behavior } from '@actor-system/core/internal';
|
|
2
|
+
import { Bivariant } from './__bundle__/shared/dist/types.internal.js';
|
|
3
|
+
|
|
4
|
+
interface ReceiveMessage<T> extends behavior.Receive<T> {
|
|
5
|
+
receiveSignal(handler: Bivariant<(signal: signal.Signal, ctx: ActorContext<T>) => behavior.Behavior<T> | void>): behavior.Receive<T>;
|
|
6
|
+
}
|
|
7
|
+
interface ReceiveSignal<T> extends behavior.Receive<T> {
|
|
8
|
+
receiveMessage(handler: Bivariant<(message: T, ctx: ActorContext<T>) => behavior.Behavior<T> | void>): behavior.Receive<T>;
|
|
9
|
+
}
|
|
10
|
+
declare const receiveMessage: <T>(onMessage: Bivariant<(message: T, context: ActorContext<T>) => behavior.Behavior<T> | void>) => ReceiveMessage<T>;
|
|
11
|
+
declare const receiveSignal: <T>(onSignal: Bivariant<(signal: signal.Signal, context: ActorContext<T>) => behavior.Behavior<T> | void>) => ReceiveSignal<T>;
|
|
12
|
+
declare const receive: <T>(handler: Bivariant<(messageOrSignal: T | signal.Signal, context: ActorContext<T>) => behavior.Behavior<T> | void>) => behavior.Receive<T>;
|
|
13
|
+
|
|
14
|
+
export { receive, receiveMessage, receiveSignal };
|
|
15
|
+
export type { ReceiveMessage, ReceiveSignal };
|
package/dist/receive.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { behavior, signal } from '@actor-system/core';
|
|
2
|
+
import { same } from './same.js';
|
|
3
|
+
|
|
4
|
+
const receiveMessage = (onMessage) => ({
|
|
5
|
+
...behavior.receive((message, ctx) => !signal.isSignal(message) ? (onMessage(message, ctx) ?? same) : same),
|
|
6
|
+
receiveSignal: (onSignal) => behavior.receive((message, context) => (!signal.isSignal(message)
|
|
7
|
+
? onMessage(message, context)
|
|
8
|
+
: onSignal(message, context)) ?? same),
|
|
9
|
+
});
|
|
10
|
+
const receiveSignal = (onSignal) => ({
|
|
11
|
+
...behavior.receive((message, ctx) => signal.isSignal(message) ? (onSignal(message, ctx) ?? same) : same),
|
|
12
|
+
receiveMessage: (onMessage) => behavior.receive((message, context) => (signal.isSignal(message)
|
|
13
|
+
? onSignal(message, context)
|
|
14
|
+
: onMessage(message, context)) ?? same),
|
|
15
|
+
});
|
|
16
|
+
const receive = (handler) => behavior.receive((message, ctx) => handler(message, ctx) ?? same);
|
|
17
|
+
|
|
18
|
+
export { receive, receiveMessage, receiveSignal };
|
package/dist/restart.js
ADDED
package/dist/same.d.ts
ADDED
package/dist/same.js
ADDED
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActorContext, behavior } from '@actor-system/core';
|
|
2
|
+
import { Bivariant } from './__bundle__/shared/dist/types.js';
|
|
3
|
+
|
|
4
|
+
type SetupFactory<T> = Bivariant<(context: ActorContext<T>) => behavior.Behavior<T> | void>;
|
|
5
|
+
declare const setup: <T>(factory: SetupFactory<T>) => behavior.Folded<T>;
|
|
6
|
+
|
|
7
|
+
export { setup };
|
|
8
|
+
export type { SetupFactory };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ActorContext, behavior } from '@actor-system/core/internal';
|
|
2
|
+
import { Bivariant } from './__bundle__/shared/dist/types.internal.js';
|
|
3
|
+
|
|
4
|
+
type SetupFactory<T> = Bivariant<(context: ActorContext<T>) => behavior.Behavior<T> | void>;
|
|
5
|
+
declare const setup: <T>(factory: SetupFactory<T>) => behavior.Folded<T>;
|
|
6
|
+
|
|
7
|
+
export { setup };
|
|
8
|
+
export type { SetupFactory };
|
package/dist/setup.js
ADDED
package/dist/stopped.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { behavior, ActorContext } from '@actor-system/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Supervision Decision Types
|
|
5
|
+
*/
|
|
6
|
+
type SupervisionDecision = "restart" | "resume" | "stop" | "escalate";
|
|
7
|
+
type SupervisionStrategy<T> = (error: unknown, ctx: ActorContext<T>) => SupervisionDecision;
|
|
8
|
+
declare function supervise<T>(inner: behavior.Control<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Control<T>;
|
|
9
|
+
declare function supervise<T>(inner: behavior.Receive<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Receive<T>;
|
|
10
|
+
declare function supervise<T>(inner: behavior.Folded<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Folded<T>;
|
|
11
|
+
declare function supervise<T>(inner: behavior.Behavior<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Behavior<T>;
|
|
12
|
+
|
|
13
|
+
export { supervise };
|
|
14
|
+
export type { SupervisionDecision, SupervisionStrategy };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { behavior, ActorContext } from '@actor-system/core/internal';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Supervision Decision Types
|
|
5
|
+
*/
|
|
6
|
+
type SupervisionDecision = "restart" | "resume" | "stop" | "escalate";
|
|
7
|
+
type SupervisionStrategy<T> = (error: unknown, ctx: ActorContext<T>) => SupervisionDecision;
|
|
8
|
+
declare function supervise<T>(inner: behavior.Control<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Control<T>;
|
|
9
|
+
declare function supervise<T>(inner: behavior.Receive<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Receive<T>;
|
|
10
|
+
declare function supervise<T>(inner: behavior.Folded<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Folded<T>;
|
|
11
|
+
declare function supervise<T>(inner: behavior.Behavior<T>, strategy: SupervisionStrategy<T> | SupervisionDecision): behavior.Behavior<T>;
|
|
12
|
+
|
|
13
|
+
export { supervise };
|
|
14
|
+
export type { SupervisionDecision, SupervisionStrategy };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { behavior } from '@actor-system/core';
|
|
2
|
+
import { restart } from './restart.js';
|
|
3
|
+
import { stopped } from './stopped.js';
|
|
4
|
+
|
|
5
|
+
function supervise(inner, strategy) {
|
|
6
|
+
if (behavior.isControl(inner)) {
|
|
7
|
+
return inner;
|
|
8
|
+
}
|
|
9
|
+
if (behavior.isFolded(inner)) {
|
|
10
|
+
return behavior.folded((context) => supervise(behavior.unfold(inner, context), strategy));
|
|
11
|
+
}
|
|
12
|
+
if (behavior.isReceive(inner)) {
|
|
13
|
+
return behavior.receive((message, context) => {
|
|
14
|
+
try {
|
|
15
|
+
const nextBehavior = inner._receive(message, context);
|
|
16
|
+
return supervise(nextBehavior, strategy);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const decision = typeof strategy === "string" ? strategy : strategy(error, context);
|
|
20
|
+
switch (decision) {
|
|
21
|
+
case "restart":
|
|
22
|
+
return restart(supervise(inner, strategy));
|
|
23
|
+
case "resume":
|
|
24
|
+
return supervise(inner, strategy);
|
|
25
|
+
case "stop":
|
|
26
|
+
return stopped;
|
|
27
|
+
case "escalate":
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Unknown behavior type: ${inner}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { supervise };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ActorContext, behavior } from '@actor-system/core';
|
|
2
|
+
|
|
3
|
+
interface Stash<T> {
|
|
4
|
+
push(msg: T): void;
|
|
5
|
+
dropAll(): void;
|
|
6
|
+
popAll(): void;
|
|
7
|
+
readonly size: number;
|
|
8
|
+
}
|
|
9
|
+
declare const withStash: <T>(factory: (stash: Stash<T>, context: ActorContext<T>) => behavior.Behavior<T>) => behavior.Behavior<T>;
|
|
10
|
+
|
|
11
|
+
export { withStash };
|
|
12
|
+
export type { Stash };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ActorContext, behavior } from '@actor-system/core/internal';
|
|
2
|
+
|
|
3
|
+
interface Stash<T> {
|
|
4
|
+
push(msg: T): void;
|
|
5
|
+
dropAll(): void;
|
|
6
|
+
popAll(): void;
|
|
7
|
+
readonly size: number;
|
|
8
|
+
}
|
|
9
|
+
declare const withStash: <T>(factory: (stash: Stash<T>, context: ActorContext<T>) => behavior.Behavior<T>) => behavior.Behavior<T>;
|
|
10
|
+
|
|
11
|
+
export { withStash };
|
|
12
|
+
export type { Stash };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { signal } from '@actor-system/core';
|
|
2
|
+
import { setup } from './setup.js';
|
|
3
|
+
import { intercept } from './intercept.js';
|
|
4
|
+
|
|
5
|
+
const $stash = Symbol("stash");
|
|
6
|
+
const withStash = (factory) => setup((context) => {
|
|
7
|
+
const stash = useStash(context);
|
|
8
|
+
const innerBehavior = factory(stash, context);
|
|
9
|
+
return intercept(innerBehavior, (post) => {
|
|
10
|
+
if (signal.isPostStop(post)) {
|
|
11
|
+
stash.dropAll();
|
|
12
|
+
}
|
|
13
|
+
return post;
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
const useStash = (context, capacity = 100) => {
|
|
17
|
+
if (context[$stash])
|
|
18
|
+
return context[$stash];
|
|
19
|
+
const stack = [];
|
|
20
|
+
const stash = {
|
|
21
|
+
/** Stash a message for later processing */
|
|
22
|
+
push: (msg) => {
|
|
23
|
+
if (stack.length < capacity) {
|
|
24
|
+
stack.push(msg);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
/** Drop all stashed messages */
|
|
28
|
+
dropAll: () => {
|
|
29
|
+
stack.length = 0;
|
|
30
|
+
},
|
|
31
|
+
/** Unstash all messages, sending them to the actor's mailbox */
|
|
32
|
+
popAll: () => {
|
|
33
|
+
stack.forEach((msg) => context.self.tell(msg));
|
|
34
|
+
stack.length = 0;
|
|
35
|
+
},
|
|
36
|
+
/** Get current stash size */
|
|
37
|
+
get size() {
|
|
38
|
+
return stack.length;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
context[$stash] = stash;
|
|
42
|
+
return stash;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { useStash, withStash };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ActorContext, behavior } from '@actor-system/core';
|
|
2
|
+
|
|
3
|
+
interface Timers<T> {
|
|
4
|
+
startSingleTimer(key: PropertyKey, post: T, delay: number): void;
|
|
5
|
+
cancel(key: PropertyKey): void;
|
|
6
|
+
cancelAll(): void;
|
|
7
|
+
}
|
|
8
|
+
declare const withTimers: <T>(factory: (timers: Timers<T>, context: ActorContext<T>) => behavior.Behavior<T>) => behavior.Folded<T>;
|
|
9
|
+
|
|
10
|
+
export { withTimers };
|
|
11
|
+
export type { Timers };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ActorContext, behavior } from '@actor-system/core/internal';
|
|
2
|
+
|
|
3
|
+
interface Timers<T> {
|
|
4
|
+
startSingleTimer(key: PropertyKey, post: T, delay: number): void;
|
|
5
|
+
cancel(key: PropertyKey): void;
|
|
6
|
+
cancelAll(): void;
|
|
7
|
+
}
|
|
8
|
+
declare const withTimers: <T>(factory: (timers: Timers<T>, context: ActorContext<T>) => behavior.Behavior<T>) => behavior.Folded<T>;
|
|
9
|
+
|
|
10
|
+
export { withTimers };
|
|
11
|
+
export type { Timers };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { signal } from '@actor-system/core';
|
|
2
|
+
import { intercept } from './intercept.js';
|
|
3
|
+
import { setup } from './setup.js';
|
|
4
|
+
|
|
5
|
+
const $timers = Symbol("timers");
|
|
6
|
+
const withTimers = (factory) => setup((context) => {
|
|
7
|
+
const timers = useTimers(context);
|
|
8
|
+
const innerBehavior = factory(timers, context);
|
|
9
|
+
return intercept(innerBehavior, (post) => {
|
|
10
|
+
if (signal.isPostStop(post)) {
|
|
11
|
+
timers.cancelAll();
|
|
12
|
+
}
|
|
13
|
+
return post;
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
const useTimers = (context) => {
|
|
17
|
+
if (context[$timers])
|
|
18
|
+
return context[$timers];
|
|
19
|
+
const buffer = new Map();
|
|
20
|
+
const timers = {
|
|
21
|
+
startSingleTimer: (key, post, delay) => {
|
|
22
|
+
if (buffer.has(key)) {
|
|
23
|
+
clearTimeout(buffer.get(key));
|
|
24
|
+
}
|
|
25
|
+
const timeout = setTimeout(() => {
|
|
26
|
+
context.self.tell(post);
|
|
27
|
+
buffer.delete(key);
|
|
28
|
+
}, delay);
|
|
29
|
+
buffer.set(key, timeout);
|
|
30
|
+
},
|
|
31
|
+
cancel: (key) => {
|
|
32
|
+
const timeout = buffer.get(key);
|
|
33
|
+
if (timeout) {
|
|
34
|
+
clearTimeout(timeout);
|
|
35
|
+
buffer.delete(key);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
cancelAll() {
|
|
39
|
+
for (const timeout of buffer.values()) {
|
|
40
|
+
clearTimeout(timeout);
|
|
41
|
+
}
|
|
42
|
+
buffer.clear();
|
|
43
|
+
return;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
context[$timers] = timers;
|
|
47
|
+
return timers;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { useTimers, withTimers };
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@actor-system/behaviors",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"type-check": "tsc -b src",
|
|
7
|
+
"lint": "eslint src",
|
|
8
|
+
"lint:fix": "eslint src --fix",
|
|
9
|
+
"publint": "publint",
|
|
10
|
+
"build:tsc:internal": "tsc -b src/tsconfig.lib.json",
|
|
11
|
+
"build:tsc:trimmed": "tsc -b src/tsconfig.lib.trimmed.json",
|
|
12
|
+
"build:rollup": "rollup -c node:config/rollup-config"
|
|
13
|
+
},
|
|
14
|
+
"module": "./dist/index.js",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"bundleDependencies": [
|
|
28
|
+
"@actor-system/shared"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@actor-system/core": "0.0.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@actor-system/testing": "0.0.1",
|
|
35
|
+
"@actor-system/shared": "0.0.1",
|
|
36
|
+
"config": "^1.0.0"
|
|
37
|
+
}
|
|
38
|
+
}
|