@quenk/potoo 3.1.7-0 → 4.0.3
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/README.md +61 -22
- package/lib/actor/address.d.ts +1 -1
- package/lib/actor/address.js +24 -28
- package/lib/actor/address.js.map +1 -1
- package/lib/actor/address.ts +28 -44
- package/lib/actor/api.d.ts +47 -0
- package/lib/actor/api.ts +57 -0
- package/lib/actor/framework/index.d.ts +1 -0
- package/lib/actor/framework/index.js +7 -0
- package/lib/actor/framework/index.js.map +1 -0
- package/lib/actor/framework/index.ts +1 -0
- package/lib/actor/framework/process.d.ts +31 -0
- package/lib/actor/framework/process.js +68 -0
- package/lib/actor/framework/process.js.map +1 -0
- package/lib/actor/framework/process.ts +87 -0
- package/lib/actor/framework/resident.d.ts +53 -0
- package/lib/actor/framework/resident.js +72 -0
- package/lib/actor/framework/resident.js.map +1 -0
- package/lib/actor/framework/resident.ts +92 -0
- package/lib/actor/index.d.ts +17 -41
- package/lib/actor/index.ts +17 -48
- package/lib/actor/system/vm/allocator/index.d.ts +36 -0
- package/lib/actor/system/vm/allocator/index.ts +43 -0
- package/lib/actor/system/vm/allocator/map.d.ts +60 -0
- package/lib/actor/system/vm/allocator/map.js +140 -0
- package/lib/actor/system/vm/allocator/map.js.map +1 -0
- package/lib/actor/system/vm/allocator/map.ts +256 -0
- package/lib/actor/system/vm/conf.d.ts +25 -29
- package/lib/actor/system/vm/conf.js +0 -14
- package/lib/actor/system/vm/conf.js.map +1 -1
- package/lib/actor/system/vm/conf.ts +26 -47
- package/lib/actor/system/vm/event/dispatcher.d.ts +45 -0
- package/lib/actor/system/vm/event/dispatcher.js +71 -0
- package/lib/actor/system/vm/event/dispatcher.js.map +1 -0
- package/lib/actor/system/vm/event/dispatcher.ts +85 -0
- package/lib/actor/system/vm/event/index.d.ts +118 -0
- package/lib/actor/system/vm/event/index.js +133 -0
- package/lib/actor/system/vm/event/index.js.map +1 -0
- package/lib/actor/system/vm/event/index.ts +143 -0
- package/lib/actor/system/vm/{runtime/stack/frame.d.ts → frame.d.ts} +12 -11
- package/lib/actor/system/vm/{runtime/stack/frame.js → frame.js} +32 -31
- package/lib/actor/system/vm/frame.js.map +1 -0
- package/lib/actor/system/vm/{runtime/stack/frame.ts → frame.ts} +72 -154
- package/lib/actor/system/vm/group.d.ts +27 -0
- package/lib/actor/system/vm/group.js +46 -0
- package/lib/actor/system/vm/group.js.map +1 -0
- package/lib/actor/system/vm/group.ts +46 -0
- package/lib/actor/system/vm/index.d.ts +64 -102
- package/lib/actor/system/vm/index.js +68 -288
- package/lib/actor/system/vm/index.js.map +1 -1
- package/lib/actor/system/vm/index.ts +141 -556
- package/lib/actor/system/vm/log/index.d.ts +57 -0
- package/lib/actor/system/vm/log/index.js +37 -0
- package/lib/actor/system/vm/log/index.js.map +1 -0
- package/lib/actor/system/vm/log/index.ts +73 -0
- package/lib/actor/system/vm/log/writer.d.ts +46 -0
- package/lib/actor/system/vm/log/writer.js +48 -0
- package/lib/actor/system/vm/log/writer.js.map +1 -0
- package/lib/actor/system/vm/log/writer.ts +96 -0
- package/lib/actor/system/vm/object/foreign.d.ts +9 -0
- package/lib/actor/system/vm/object/foreign.js +13 -0
- package/lib/actor/system/vm/object/foreign.js.map +1 -0
- package/lib/actor/system/vm/object/foreign.ts +10 -0
- package/lib/actor/system/vm/object/index.d.ts +5 -0
- package/lib/actor/system/vm/object/index.ts +4 -0
- package/lib/actor/system/vm/object/list.d.ts +8 -0
- package/lib/actor/system/vm/object/list.js +12 -0
- package/lib/actor/system/vm/object/list.js.map +1 -0
- package/lib/actor/system/vm/object/list.ts +8 -0
- package/lib/actor/system/vm/op/actor.d.ts +69 -0
- package/lib/actor/system/vm/{runtime/op → op}/actor.js +22 -28
- package/lib/actor/system/vm/op/actor.js.map +1 -0
- package/lib/actor/system/vm/op/actor.ts +126 -0
- package/lib/actor/system/vm/{runtime/op → op}/base.d.ts +21 -21
- package/lib/actor/system/vm/{runtime/op → op}/base.js +8 -9
- package/lib/actor/system/vm/op/base.js.map +1 -0
- package/lib/actor/system/vm/{runtime/op → op}/base.ts +60 -111
- package/lib/actor/system/vm/{runtime/op → op}/index.d.ts +21 -7
- package/lib/actor/system/vm/{runtime/op → op}/index.js +31 -10
- package/lib/actor/system/vm/op/index.js.map +1 -0
- package/lib/actor/system/vm/{runtime/op → op}/index.ts +78 -113
- package/lib/actor/system/vm/{runtime/op → op}/object.d.ts +6 -6
- package/lib/actor/system/vm/{runtime/op → op}/object.js +27 -15
- package/lib/actor/system/vm/op/object.js.map +1 -0
- package/lib/actor/system/vm/{runtime/op → op}/object.ts +28 -33
- package/lib/actor/system/vm/registry.d.ts +126 -0
- package/lib/actor/system/vm/registry.js +191 -0
- package/lib/actor/system/vm/registry.js.map +1 -0
- package/lib/actor/system/vm/registry.ts +223 -0
- package/lib/actor/system/vm/runtime/error.d.ts +46 -24
- package/lib/actor/system/vm/runtime/error.js +52 -27
- package/lib/actor/system/vm/runtime/error.js.map +1 -1
- package/lib/actor/system/vm/runtime/error.ts +80 -123
- package/lib/actor/system/vm/runtime.d.ts +28 -0
- package/lib/actor/system/vm/runtime.js +3 -0
- package/lib/actor/system/vm/runtime.js.map +1 -0
- package/lib/actor/system/vm/runtime.ts +31 -0
- package/lib/actor/system/vm/scheduler.d.ts +54 -0
- package/lib/actor/system/vm/scheduler.js +98 -0
- package/lib/actor/system/vm/scheduler.js.map +1 -0
- package/lib/actor/system/vm/scheduler.ts +111 -0
- package/lib/actor/system/vm/script/index.d.ts +3 -3
- package/lib/actor/system/vm/script/index.js.map +1 -1
- package/lib/actor/system/vm/script/index.ts +11 -17
- package/lib/actor/system/vm/script/info.d.ts +1 -1
- package/lib/actor/system/vm/script/info.js +3 -3
- package/lib/actor/system/vm/script/info.js.map +1 -1
- package/lib/actor/system/vm/script/info.ts +48 -73
- package/lib/actor/system/vm/strategy/error.d.ts +28 -0
- package/lib/actor/system/vm/strategy/error.js +57 -0
- package/lib/actor/system/vm/strategy/error.js.map +1 -0
- package/lib/actor/system/vm/strategy/error.ts +88 -0
- package/lib/actor/system/vm/thread/factory.d.ts +15 -0
- package/lib/actor/system/vm/thread/factory.js +22 -0
- package/lib/actor/system/vm/thread/factory.js.map +1 -0
- package/lib/actor/system/vm/thread/factory.ts +29 -0
- package/lib/actor/system/vm/thread/index.d.ts +17 -98
- package/lib/actor/system/vm/thread/index.js +2 -6
- package/lib/actor/system/vm/thread/index.js.map +1 -1
- package/lib/actor/system/vm/thread/index.ts +17 -114
- package/lib/actor/system/vm/thread/process.d.ts +45 -0
- package/lib/actor/system/vm/thread/process.js +105 -0
- package/lib/actor/system/vm/thread/process.js.map +1 -0
- package/lib/actor/system/vm/thread/process.ts +134 -0
- package/lib/actor/system/vm/thread/shared/index.d.ts +35 -52
- package/lib/actor/system/vm/thread/shared/index.js +18 -159
- package/lib/actor/system/vm/thread/shared/index.js.map +1 -1
- package/lib/actor/system/vm/thread/shared/index.ts +37 -244
- package/lib/actor/system/vm/thread/shared/js.d.ts +35 -0
- package/lib/actor/system/vm/thread/shared/js.js +114 -0
- package/lib/actor/system/vm/thread/shared/js.js.map +1 -0
- package/lib/actor/system/vm/thread/shared/js.ts +151 -0
- package/lib/actor/system/vm/type.d.ts +41 -68
- package/lib/actor/system/vm/type.js +7 -5
- package/lib/actor/system/vm/type.js.map +1 -1
- package/lib/actor/system/vm/type.ts +39 -83
- package/lib/actor/template.d.ts +99 -54
- package/lib/actor/template.js +28 -1
- package/lib/actor/template.js.map +1 -1
- package/lib/actor/template.ts +118 -60
- package/lib/tsconfig.json +2 -3
- package/package.json +17 -8
- package/lib/actor/flags.d.ts +0 -32
- package/lib/actor/flags.js +0 -36
- package/lib/actor/flags.js.map +0 -1
- package/lib/actor/flags.ts +0 -43
- package/lib/actor/mailbox.d.ts +0 -16
- package/lib/actor/mailbox.js +0 -17
- package/lib/actor/mailbox.js.map +0 -1
- package/lib/actor/mailbox.ts +0 -20
- package/lib/actor/message.d.ts +0 -15
- package/lib/actor/message.js +0 -17
- package/lib/actor/message.js.map +0 -1
- package/lib/actor/message.ts +0 -19
- package/lib/actor/remote/index.d.ts +0 -62
- package/lib/actor/remote/index.js +0 -79
- package/lib/actor/remote/index.js.map +0 -1
- package/lib/actor/remote/index.ts +0 -102
- package/lib/actor/remote/process/index.d.ts +0 -145
- package/lib/actor/remote/process/index.js +0 -232
- package/lib/actor/remote/process/index.js.map +0 -1
- package/lib/actor/remote/process/index.ts +0 -344
- package/lib/actor/remote/process/script.d.ts +0 -1
- package/lib/actor/remote/process/script.js +0 -5
- package/lib/actor/remote/process/script.js.map +0 -1
- package/lib/actor/remote/process/script.ts +0 -3
- package/lib/actor/remote/process/vm.d.ts +0 -31
- package/lib/actor/remote/process/vm.js +0 -78
- package/lib/actor/remote/process/vm.js.map +0 -1
- package/lib/actor/remote/process/vm.ts +0 -115
- package/lib/actor/resident/api.d.ts +0 -49
- package/lib/actor/resident/api.ts +0 -65
- package/lib/actor/resident/case/function.d.ts +0 -24
- package/lib/actor/resident/case/function.js +0 -34
- package/lib/actor/resident/case/function.js.map +0 -1
- package/lib/actor/resident/case/function.ts +0 -40
- package/lib/actor/resident/case/index.d.ts +0 -60
- package/lib/actor/resident/case/index.js +0 -48
- package/lib/actor/resident/case/index.js.map +0 -1
- package/lib/actor/resident/case/index.ts +0 -101
- package/lib/actor/resident/immutable/callback.d.ts +0 -9
- package/lib/actor/resident/immutable/callback.js +0 -14
- package/lib/actor/resident/immutable/callback.js.map +0 -1
- package/lib/actor/resident/immutable/callback.ts +0 -9
- package/lib/actor/resident/immutable/index.d.ts +0 -17
- package/lib/actor/resident/immutable/index.js +0 -28
- package/lib/actor/resident/immutable/index.js.map +0 -1
- package/lib/actor/resident/immutable/index.ts +0 -38
- package/lib/actor/resident/index.d.ts +0 -49
- package/lib/actor/resident/index.js +0 -89
- package/lib/actor/resident/index.js.map +0 -1
- package/lib/actor/resident/index.ts +0 -173
- package/lib/actor/resident/mutable/index.d.ts +0 -18
- package/lib/actor/resident/mutable/index.js +0 -31
- package/lib/actor/resident/mutable/index.js.map +0 -1
- package/lib/actor/resident/mutable/index.ts +0 -39
- package/lib/actor/resident/scripts.d.ts +0 -44
- package/lib/actor/resident/scripts.js +0 -137
- package/lib/actor/resident/scripts.js.map +0 -1
- package/lib/actor/resident/scripts.ts +0 -194
- package/lib/actor/resident/task.d.ts +0 -11
- package/lib/actor/resident/task.js +0 -19
- package/lib/actor/resident/task.js.map +0 -1
- package/lib/actor/resident/task.ts +0 -21
- package/lib/actor/system/error.d.ts +0 -8
- package/lib/actor/system/error.js +0 -13
- package/lib/actor/system/error.js.map +0 -1
- package/lib/actor/system/error.ts +0 -10
- package/lib/actor/system/index.d.ts +0 -15
- package/lib/actor/system/index.ts +0 -18
- package/lib/actor/system/vm/event.d.ts +0 -54
- package/lib/actor/system/vm/event.js +0 -36
- package/lib/actor/system/vm/event.js.map +0 -1
- package/lib/actor/system/vm/event.ts +0 -85
- package/lib/actor/system/vm/groups.d.ts +0 -16
- package/lib/actor/system/vm/groups.js +0 -23
- package/lib/actor/system/vm/groups.js.map +0 -1
- package/lib/actor/system/vm/groups.ts +0 -32
- package/lib/actor/system/vm/log.d.ts +0 -76
- package/lib/actor/system/vm/log.js +0 -90
- package/lib/actor/system/vm/log.js.map +0 -1
- package/lib/actor/system/vm/log.ts +0 -207
- package/lib/actor/system/vm/map.d.ts +0 -30
- package/lib/actor/system/vm/map.js +0 -42
- package/lib/actor/system/vm/map.js.map +0 -1
- package/lib/actor/system/vm/map.ts +0 -56
- package/lib/actor/system/vm/routers.d.ts +0 -13
- package/lib/actor/system/vm/routers.js +0 -21
- package/lib/actor/system/vm/routers.js.map +0 -1
- package/lib/actor/system/vm/routers.ts +0 -25
- package/lib/actor/system/vm/runtime/context.d.ts +0 -61
- package/lib/actor/system/vm/runtime/context.js +0 -17
- package/lib/actor/system/vm/runtime/context.js.map +0 -1
- package/lib/actor/system/vm/runtime/context.ts +0 -94
- package/lib/actor/system/vm/runtime/heap/index.d.ts +0 -4
- package/lib/actor/system/vm/runtime/heap/index.ts +0 -5
- package/lib/actor/system/vm/runtime/heap/ledger.d.ts +0 -142
- package/lib/actor/system/vm/runtime/heap/ledger.js +0 -99
- package/lib/actor/system/vm/runtime/heap/ledger.js.map +0 -1
- package/lib/actor/system/vm/runtime/heap/ledger.ts +0 -304
- package/lib/actor/system/vm/runtime/index.d.ts +0 -19
- package/lib/actor/system/vm/runtime/index.js +0 -12
- package/lib/actor/system/vm/runtime/index.js.map +0 -1
- package/lib/actor/system/vm/runtime/index.ts +0 -30
- package/lib/actor/system/vm/runtime/op/actor.d.ts +0 -69
- package/lib/actor/system/vm/runtime/op/actor.js.map +0 -1
- package/lib/actor/system/vm/runtime/op/actor.ts +0 -154
- package/lib/actor/system/vm/runtime/op/base.js.map +0 -1
- package/lib/actor/system/vm/runtime/op/index.js.map +0 -1
- package/lib/actor/system/vm/runtime/op/object.js.map +0 -1
- package/lib/actor/system/vm/runtime/stack/frame.js.map +0 -1
- package/lib/actor/system/vm/scripts/factory.d.ts +0 -12
- package/lib/actor/system/vm/scripts/factory.js +0 -40
- package/lib/actor/system/vm/scripts/factory.js.map +0 -1
- package/lib/actor/system/vm/scripts/factory.ts +0 -55
- package/lib/actor/system/vm/scripts/index.d.ts +0 -32
- package/lib/actor/system/vm/scripts/index.js +0 -47
- package/lib/actor/system/vm/scripts/index.js.map +0 -1
- package/lib/actor/system/vm/scripts/index.ts +0 -49
- package/lib/actor/system/vm/table.d.ts +0 -44
- package/lib/actor/system/vm/table.js +0 -68
- package/lib/actor/system/vm/table.js.map +0 -1
- package/lib/actor/system/vm/table.ts +0 -113
- package/lib/actor/system/vm/thread/shared/scheduler.d.ts +0 -38
- package/lib/actor/system/vm/thread/shared/scheduler.js +0 -62
- package/lib/actor/system/vm/thread/shared/scheduler.js.map +0 -1
- package/lib/actor/system/vm/thread/shared/scheduler.ts +0 -84
- /package/lib/actor/{resident/api.js → api.js} +0 -0
- /package/lib/actor/{resident/api.js.map → api.js.map} +0 -0
- /package/lib/actor/system/{index.js → vm/allocator/index.js} +0 -0
- /package/lib/actor/system/{index.js.map → vm/allocator/index.js.map} +0 -0
- /package/lib/actor/system/vm/{runtime/heap → object}/index.js +0 -0
- /package/lib/actor/system/vm/{runtime/heap → object}/index.js.map +0 -0
package/README.md
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
Potoo
|
|
2
2
|
=====
|
|
3
3
|
|
|
4
|
-
In
|
|
5
|
-
|
|
6
|
-
[!Diagram of Potoo internals](v3.png)
|
|
4
|
+
In app message passing framework inspired the actor model.
|
|
7
5
|
|
|
8
6
|
# Introduction
|
|
9
7
|
|
|
10
|
-
Potoo provides a framework for
|
|
11
|
-
|
|
8
|
+
Potoo provides a framework for creating a network of actors within your
|
|
9
|
+
applications for easy message passing.
|
|
10
|
+
|
|
11
|
+
## Why?
|
|
12
|
+
|
|
13
|
+
Message passing allows us to de-couple our applications and thus scale more
|
|
14
|
+
effectively. This is true for traditional networks and distributed computing
|
|
15
|
+
but it can also be applied to the UI components of an ordinary web app.
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
main class of an application. PVM is used to spawn child "actors" that each
|
|
15
|
-
execute some unit of work on behalf of the application. Actors are able to
|
|
16
|
-
communicate with each other via message passing.
|
|
17
|
+
## How?
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
actors
|
|
21
|
-
another machine.
|
|
19
|
+
This framework allows you to create 1 or more actors that together form a system.
|
|
20
|
+
Behind the scenes, the framework provides machinery to deliver messages to and
|
|
21
|
+
from actors given the respective address.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
Think of an actor as a unit of computation or the refinement of a feature within
|
|
24
|
+
your application. Each actor has its own state that it does not share with other
|
|
25
|
+
actors, instead they communicate via messages.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
When an actor receives a message, it can typically:
|
|
28
|
+
1. Spawn a new actor to handle the message.
|
|
29
|
+
2. Change it's internally behaviour based on the contents of the message.
|
|
30
|
+
3. Send a message to another actor.
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
By honoring these 3 points we are able to distribute the work of our applications
|
|
33
|
+
in a scalable way, without the complexity.
|
|
32
34
|
|
|
33
35
|
# Installation
|
|
34
36
|
|
|
@@ -38,8 +40,45 @@ npm install --save @quenk/potoo
|
|
|
38
40
|
|
|
39
41
|
# Usage
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
```js
|
|
44
|
+
import { PVM } from '@quenk/potoo';
|
|
45
|
+
|
|
46
|
+
// This is your system and serves as the root actor.
|
|
47
|
+
let vm = PVM.create();
|
|
48
|
+
|
|
49
|
+
vm.spawn({
|
|
50
|
+
|
|
51
|
+
id: 'a',
|
|
52
|
+
|
|
53
|
+
run: async actor => {
|
|
54
|
+
|
|
55
|
+
await actor.tell('b', 'ready');
|
|
56
|
+
|
|
57
|
+
while(actor.isValid()) {
|
|
58
|
+
let msg = await actor.receive();
|
|
59
|
+
if(msg === 'done') {
|
|
60
|
+
await actor.exit();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
vm.spawn({
|
|
67
|
+
id: 'b',
|
|
68
|
+
|
|
69
|
+
run: async actor => {
|
|
70
|
+
|
|
71
|
+
setTimeout(()=> { actor.tell('a', 'done'); }, 5000);
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
More examples in the test folder.
|
|
80
|
+
|
|
42
81
|
|
|
43
82
|
# License
|
|
44
83
|
|
|
45
|
-
Apache-2.0 (C)
|
|
84
|
+
Apache-2.0 (C) 2024 Quenk Technologies Limited
|
package/lib/actor/address.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const ADDRESS_RESTRICTED: string[];
|
|
|
9
9
|
* Addresses are used to properly route messages between actors in the system
|
|
10
10
|
* and conform to the path part of a URL.
|
|
11
11
|
*/
|
|
12
|
-
export
|
|
12
|
+
export type Address = string;
|
|
13
13
|
/**
|
|
14
14
|
* AddressMap
|
|
15
15
|
*/
|
package/lib/actor/address.js
CHANGED
|
@@ -7,45 +7,41 @@ exports.SEPERATOR = '/';
|
|
|
7
7
|
exports.ADDRESS_DISCARD = '?';
|
|
8
8
|
exports.ADDRESS_SYSTEM = '$';
|
|
9
9
|
exports.ADDRESS_EMPTY = '';
|
|
10
|
-
exports.ADDRESS_RESTRICTED = [
|
|
11
|
-
exports.ADDRESS_DISCARD,
|
|
12
|
-
exports.ADDRESS_SYSTEM,
|
|
13
|
-
exports.SEPERATOR
|
|
14
|
-
];
|
|
10
|
+
exports.ADDRESS_RESTRICTED = [exports.ADDRESS_DISCARD, exports.ADDRESS_SYSTEM, exports.SEPERATOR];
|
|
15
11
|
/**
|
|
16
12
|
* isRestricted indicates whether an actor id is restricted or not.
|
|
17
13
|
*/
|
|
18
|
-
const isRestricted = (id) =>
|
|
14
|
+
const isRestricted = (id) => exports.ADDRESS_RESTRICTED.some(a => id.indexOf(a) > -1) && id !== exports.SEPERATOR;
|
|
19
15
|
exports.isRestricted = isRestricted;
|
|
20
16
|
/**
|
|
21
17
|
* make a child address given its id and parent address.
|
|
22
18
|
*/
|
|
23
|
-
const make = (parent, id) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
id
|
|
27
|
-
|
|
19
|
+
const make = (parent, id) => {
|
|
20
|
+
id = id.trim();
|
|
21
|
+
return parent === exports.SEPERATOR || parent === exports.ADDRESS_EMPTY
|
|
22
|
+
? `${parent}${id}`
|
|
23
|
+
: parent === exports.ADDRESS_SYSTEM
|
|
24
|
+
? id
|
|
25
|
+
: `${parent}${exports.SEPERATOR}${id}`;
|
|
26
|
+
};
|
|
28
27
|
exports.make = make;
|
|
29
28
|
/**
|
|
30
29
|
* getParent computes the parent of an Address.
|
|
31
30
|
*/
|
|
32
31
|
const getParent = (addr) => {
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
if (addr === exports.ADDRESS_SYSTEM ||
|
|
33
|
+
addr === exports.ADDRESS_EMPTY ||
|
|
34
|
+
addr === exports.ADDRESS_DISCARD ||
|
|
35
|
+
addr === exports.SEPERATOR) {
|
|
36
36
|
return exports.ADDRESS_SYSTEM;
|
|
37
37
|
}
|
|
38
38
|
else {
|
|
39
39
|
let b4 = addr.split(exports.SEPERATOR);
|
|
40
|
-
if (
|
|
40
|
+
if (b4.length === 2 && b4[0] === '') {
|
|
41
41
|
return exports.SEPERATOR;
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
|
-
let a = b4
|
|
45
|
-
.reverse()
|
|
46
|
-
.slice(1)
|
|
47
|
-
.reverse()
|
|
48
|
-
.join(exports.SEPERATOR);
|
|
44
|
+
let a = b4.reverse().slice(1).reverse().join(exports.SEPERATOR);
|
|
49
45
|
return a === exports.ADDRESS_EMPTY ? exports.ADDRESS_SYSTEM : a;
|
|
50
46
|
}
|
|
51
47
|
}
|
|
@@ -54,22 +50,22 @@ exports.getParent = getParent;
|
|
|
54
50
|
/**
|
|
55
51
|
* getId provides the id part of an actor address.
|
|
56
52
|
*/
|
|
57
|
-
const getId = (addr) =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
addr
|
|
62
|
-
(0, array_1.tail)(addr.split(exports.SEPERATOR));
|
|
53
|
+
const getId = (addr) => addr === exports.ADDRESS_SYSTEM ||
|
|
54
|
+
addr === exports.ADDRESS_DISCARD ||
|
|
55
|
+
addr === exports.ADDRESS_EMPTY ||
|
|
56
|
+
addr === exports.SEPERATOR
|
|
57
|
+
? addr
|
|
58
|
+
: (0, array_1.tail)(addr.split(exports.SEPERATOR));
|
|
63
59
|
exports.getId = getId;
|
|
64
60
|
/**
|
|
65
61
|
* isChild tests whether an address is a child of the parent address.
|
|
66
62
|
*/
|
|
67
|
-
const isChild = (parent, child) => (
|
|
63
|
+
const isChild = (parent, child) => (parent === exports.ADDRESS_SYSTEM && child !== parent) ||
|
|
68
64
|
(0, string_1.startsWith)(child, `${parent}${exports.SEPERATOR}`);
|
|
69
65
|
exports.isChild = isChild;
|
|
70
66
|
/**
|
|
71
67
|
* isGroup determines if an address is a group reference.
|
|
72
68
|
*/
|
|
73
|
-
const isGroup = (addr) =>
|
|
69
|
+
const isGroup = (addr) => addr[0] === '$' && addr !== '$';
|
|
74
70
|
exports.isGroup = isGroup;
|
|
75
71
|
//# sourceMappingURL=address.js.map
|
package/lib/actor/address.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.js","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":";;;AAAA,sDAAkD;AAClD,wDAAyD;AAE5C,QAAA,SAAS,GAAG,GAAG,CAAC;AAEhB,QAAA,eAAe,GAAG,GAAG,CAAC;AACtB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,kBAAkB,GAAG
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":";;;AAAA,sDAAkD;AAClD,wDAAyD;AAE5C,QAAA,SAAS,GAAG,GAAG,CAAC;AAEhB,QAAA,eAAe,GAAG,GAAG,CAAC;AACtB,QAAA,cAAc,GAAG,GAAG,CAAC;AACrB,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,kBAAkB,GAAG,CAAC,uBAAe,EAAE,sBAAc,EAAE,iBAAS,CAAC,CAAC;AAiB/E;;GAEG;AACI,MAAM,YAAY,GAAG,CAAC,EAAU,EAAE,EAAE,CACvC,0BAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,iBAAS,CAAC;AAD5D,QAAA,YAAY,gBACgD;AAEzE;;GAEG;AACI,MAAM,IAAI,GAAG,CAAC,MAAe,EAAE,EAAU,EAAW,EAAE;IACzD,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,MAAM,KAAK,iBAAS,IAAI,MAAM,KAAK,qBAAa;QACnD,CAAC,CAAC,GAAG,MAAM,GAAG,EAAE,EAAE;QAClB,CAAC,CAAC,MAAM,KAAK,sBAAc;YACzB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,GAAG,MAAM,GAAG,iBAAS,GAAG,EAAE,EAAE,CAAC;AACzC,CAAC,CAAC;AAPW,QAAA,IAAI,QAOf;AAEF;;GAEG;AACI,MAAM,SAAS,GAAG,CAAC,IAAa,EAAW,EAAE;IAChD,IACI,IAAI,KAAK,sBAAc;QACvB,IAAI,KAAK,qBAAa;QACtB,IAAI,KAAK,uBAAe;QACxB,IAAI,KAAK,iBAAS,EACpB,CAAC;QACC,OAAO,sBAAc,CAAC;IAC1B,CAAC;SAAM,CAAC;QACJ,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAS,CAAC,CAAC;QAE/B,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YAClC,OAAO,iBAAS,CAAC;QACrB,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,iBAAS,CAAC,CAAC;YAExD,OAAO,CAAC,KAAK,qBAAa,CAAC,CAAC,CAAC,sBAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;AACL,CAAC,CAAC;AAnBW,QAAA,SAAS,aAmBpB;AAEF;;GAEG;AACI,MAAM,KAAK,GAAG,CAAC,IAAa,EAAU,EAAE,CAC3C,IAAI,KAAK,sBAAc;IACvB,IAAI,KAAK,uBAAe;IACxB,IAAI,KAAK,qBAAa;IACtB,IAAI,KAAK,iBAAS;IACd,CAAC,CAAC,IAAI;IACN,CAAC,CAAC,IAAA,YAAI,EAAC,IAAI,CAAC,KAAK,CAAC,iBAAS,CAAC,CAAC,CAAC;AANzB,QAAA,KAAK,SAMoB;AAEtC;;GAEG;AACI,MAAM,OAAO,GAAG,CAAC,MAAe,EAAE,KAAc,EAAW,EAAE,CAChE,CAAC,MAAM,KAAK,sBAAc,IAAI,KAAK,KAAK,MAAM,CAAC;IAC/C,IAAA,mBAAU,EAAC,KAAK,EAAE,GAAG,MAAM,GAAG,iBAAS,EAAE,CAAC,CAAC;AAFlC,QAAA,OAAO,WAE2B;AAE/C;;GAEG;AACI,MAAM,OAAO,GAAG,CAAC,IAAa,EAAW,EAAE,CAC9C,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC;AADvB,QAAA,OAAO,WACgB"}
|
package/lib/actor/address.ts
CHANGED
|
@@ -6,11 +6,7 @@ export const SEPERATOR = '/';
|
|
|
6
6
|
export const ADDRESS_DISCARD = '?';
|
|
7
7
|
export const ADDRESS_SYSTEM = '$';
|
|
8
8
|
export const ADDRESS_EMPTY = '';
|
|
9
|
-
export const ADDRESS_RESTRICTED = [
|
|
10
|
-
ADDRESS_DISCARD,
|
|
11
|
-
ADDRESS_SYSTEM,
|
|
12
|
-
SEPERATOR
|
|
13
|
-
];
|
|
9
|
+
export const ADDRESS_RESTRICTED = [ADDRESS_DISCARD, ADDRESS_SYSTEM, SEPERATOR];
|
|
14
10
|
|
|
15
11
|
/**
|
|
16
12
|
* Address of an actor.
|
|
@@ -24,83 +20,71 @@ export type Address = string;
|
|
|
24
20
|
* AddressMap
|
|
25
21
|
*/
|
|
26
22
|
export interface AddressMap {
|
|
27
|
-
|
|
28
|
-
[key: string]: Address
|
|
29
|
-
|
|
23
|
+
[key: string]: Address;
|
|
30
24
|
}
|
|
31
25
|
|
|
32
26
|
/**
|
|
33
27
|
* isRestricted indicates whether an actor id is restricted or not.
|
|
34
28
|
*/
|
|
35
29
|
export const isRestricted = (id: string) =>
|
|
36
|
-
|
|
30
|
+
ADDRESS_RESTRICTED.some(a => id.indexOf(a) > -1) && id !== SEPERATOR;
|
|
37
31
|
|
|
38
32
|
/**
|
|
39
33
|
* make a child address given its id and parent address.
|
|
40
34
|
*/
|
|
41
|
-
export const make = (parent: Address, id: string): Address =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
export const make = (parent: Address, id: string): Address => {
|
|
36
|
+
id = id.trim();
|
|
37
|
+
return parent === SEPERATOR || parent === ADDRESS_EMPTY
|
|
38
|
+
? `${parent}${id}`
|
|
39
|
+
: parent === ADDRESS_SYSTEM
|
|
40
|
+
? id
|
|
41
|
+
: `${parent}${SEPERATOR}${id}`;
|
|
42
|
+
};
|
|
47
43
|
|
|
48
44
|
/**
|
|
49
45
|
* getParent computes the parent of an Address.
|
|
50
46
|
*/
|
|
51
47
|
export const getParent = (addr: Address): Address => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
if (
|
|
49
|
+
addr === ADDRESS_SYSTEM ||
|
|
50
|
+
addr === ADDRESS_EMPTY ||
|
|
51
|
+
addr === ADDRESS_DISCARD ||
|
|
52
|
+
addr === SEPERATOR
|
|
53
|
+
) {
|
|
57
54
|
return ADDRESS_SYSTEM;
|
|
58
|
-
|
|
59
55
|
} else {
|
|
60
|
-
|
|
61
56
|
let b4 = addr.split(SEPERATOR);
|
|
62
57
|
|
|
63
|
-
if (
|
|
64
|
-
|
|
58
|
+
if (b4.length === 2 && b4[0] === '') {
|
|
65
59
|
return SEPERATOR;
|
|
66
|
-
|
|
67
60
|
} else {
|
|
68
|
-
|
|
69
|
-
let a = b4
|
|
70
|
-
.reverse()
|
|
71
|
-
.slice(1)
|
|
72
|
-
.reverse()
|
|
73
|
-
.join(SEPERATOR);
|
|
61
|
+
let a = b4.reverse().slice(1).reverse().join(SEPERATOR);
|
|
74
62
|
|
|
75
63
|
return a === ADDRESS_EMPTY ? ADDRESS_SYSTEM : a;
|
|
76
|
-
|
|
77
|
-
|
|
78
64
|
}
|
|
79
|
-
|
|
80
65
|
}
|
|
81
|
-
|
|
82
|
-
}
|
|
66
|
+
};
|
|
83
67
|
|
|
84
68
|
/**
|
|
85
69
|
* getId provides the id part of an actor address.
|
|
86
70
|
*/
|
|
87
71
|
export const getId = (addr: Address): string =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
addr
|
|
93
|
-
tail(addr.split(SEPERATOR));
|
|
72
|
+
addr === ADDRESS_SYSTEM ||
|
|
73
|
+
addr === ADDRESS_DISCARD ||
|
|
74
|
+
addr === ADDRESS_EMPTY ||
|
|
75
|
+
addr === SEPERATOR
|
|
76
|
+
? addr
|
|
77
|
+
: tail(addr.split(SEPERATOR));
|
|
94
78
|
|
|
95
79
|
/**
|
|
96
80
|
* isChild tests whether an address is a child of the parent address.
|
|
97
81
|
*/
|
|
98
82
|
export const isChild = (parent: Address, child: Address): boolean =>
|
|
99
|
-
(
|
|
83
|
+
(parent === ADDRESS_SYSTEM && child !== parent) ||
|
|
100
84
|
startsWith(child, `${parent}${SEPERATOR}`);
|
|
101
85
|
|
|
102
86
|
/**
|
|
103
87
|
* isGroup determines if an address is a group reference.
|
|
104
88
|
*/
|
|
105
89
|
export const isGroup = (addr: Address): boolean =>
|
|
106
|
-
|
|
90
|
+
addr[0] === '$' && addr !== '$';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Err } from '@quenk/noni/lib/control/error';
|
|
2
|
+
import { Address } from './address';
|
|
3
|
+
import { Spawnable } from './template';
|
|
4
|
+
import { Message } from '.';
|
|
5
|
+
import { TypeCase } from '@quenk/noni/lib/control/match/case';
|
|
6
|
+
/**
|
|
7
|
+
* Parent is any object capable of spawning a child actor.
|
|
8
|
+
*/
|
|
9
|
+
export interface Parent {
|
|
10
|
+
/**
|
|
11
|
+
* spawn an actor give its template.
|
|
12
|
+
*/
|
|
13
|
+
spawn(t: Spawnable): Promise<Address>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Api is the interface provided by objects that can send/receive messages to
|
|
17
|
+
* actors within the system.
|
|
18
|
+
*
|
|
19
|
+
* This interface is separate from the Actor interface because the system is
|
|
20
|
+
* not directly concerned with their implementation. Instead, they exist to
|
|
21
|
+
* provide a way for user land code to interact with other actors within the
|
|
22
|
+
* system.
|
|
23
|
+
*/
|
|
24
|
+
export interface Api extends Parent {
|
|
25
|
+
self: Address;
|
|
26
|
+
/**
|
|
27
|
+
* raise an error triggering the system's error handling machinery.
|
|
28
|
+
*/
|
|
29
|
+
raise(e: Err): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* kill sends a stop signal to a child actor.
|
|
32
|
+
*
|
|
33
|
+
* An actor can only specify itself or a child as the target.
|
|
34
|
+
*/
|
|
35
|
+
kill(target: Address): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* tell a message to an actor address.
|
|
38
|
+
*/
|
|
39
|
+
tell(ref: string, msg: Message): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* receive a message from the actor's mailbox.
|
|
42
|
+
*
|
|
43
|
+
* If TypeCases are provided, the message will be matched against them
|
|
44
|
+
* first and the result provided.
|
|
45
|
+
*/
|
|
46
|
+
receive<T>(cases?: TypeCase<T>[]): Promise<T>;
|
|
47
|
+
}
|
package/lib/actor/api.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Err } from '@quenk/noni/lib/control/error';
|
|
2
|
+
|
|
3
|
+
import { Address } from './address';
|
|
4
|
+
import { Spawnable } from './template';
|
|
5
|
+
import { Message } from '.';
|
|
6
|
+
import { TypeCase } from '@quenk/noni/lib/control/match/case';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parent is any object capable of spawning a child actor.
|
|
10
|
+
*/
|
|
11
|
+
export interface Parent {
|
|
12
|
+
/**
|
|
13
|
+
* spawn an actor give its template.
|
|
14
|
+
*/
|
|
15
|
+
spawn(t: Spawnable): Promise<Address>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Api is the interface provided by objects that can send/receive messages to
|
|
20
|
+
* actors within the system.
|
|
21
|
+
*
|
|
22
|
+
* This interface is separate from the Actor interface because the system is
|
|
23
|
+
* not directly concerned with their implementation. Instead, they exist to
|
|
24
|
+
* provide a way for user land code to interact with other actors within the
|
|
25
|
+
* system.
|
|
26
|
+
*/
|
|
27
|
+
export interface Api extends Parent {
|
|
28
|
+
/*
|
|
29
|
+
* self is the address for the actor within the system
|
|
30
|
+
*/
|
|
31
|
+
self: Address;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* raise an error triggering the system's error handling machinery.
|
|
35
|
+
*/
|
|
36
|
+
raise(e: Err): Promise<void>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* kill sends a stop signal to a child actor.
|
|
40
|
+
*
|
|
41
|
+
* An actor can only specify itself or a child as the target.
|
|
42
|
+
*/
|
|
43
|
+
kill(target: Address): Promise<void>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* tell a message to an actor address.
|
|
47
|
+
*/
|
|
48
|
+
tell(ref: string, msg: Message): Promise<void>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* receive a message from the actor's mailbox.
|
|
52
|
+
*
|
|
53
|
+
* If TypeCases are provided, the message will be matched against them
|
|
54
|
+
* first and the result provided.
|
|
55
|
+
*/
|
|
56
|
+
receive<T>(cases?: TypeCase<T>[]): Promise<T>;
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TypeCase, Case, Default } from '@quenk/noni/lib/control/match/case';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Default = exports.Case = void 0;
|
|
4
|
+
var case_1 = require("@quenk/noni/lib/control/match/case");
|
|
5
|
+
Object.defineProperty(exports, "Case", { enumerable: true, get: function () { return case_1.Case; } });
|
|
6
|
+
Object.defineProperty(exports, "Default", { enumerable: true, get: function () { return case_1.Default; } });
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,2DAA6E;AAA1D,4FAAA,IAAI,OAAA;AAAE,+FAAA,OAAO,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TypeCase, Case, Default } from '@quenk/noni/lib/control/match/case';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { TypeCase } from '@quenk/noni/lib/control/match/case';
|
|
2
|
+
import { Address } from '../address';
|
|
3
|
+
/**
|
|
4
|
+
* init should be called as early as possible in the child process if using the
|
|
5
|
+
* direct API (Process).
|
|
6
|
+
*
|
|
7
|
+
* It sets up a listener for incoming messages to the child_process that can
|
|
8
|
+
* be read later via receive() or select().
|
|
9
|
+
*/
|
|
10
|
+
export declare const init: () => void;
|
|
11
|
+
/**
|
|
12
|
+
* self provides the address for this child actor.
|
|
13
|
+
*/
|
|
14
|
+
export declare const self: string;
|
|
15
|
+
/**
|
|
16
|
+
* tell sends a message to another actor in the system using the VM in the
|
|
17
|
+
* parent process.
|
|
18
|
+
*/
|
|
19
|
+
export declare const tell: <M>(to: Address, message: M) => any;
|
|
20
|
+
/**
|
|
21
|
+
* receive the next message in the message queue.
|
|
22
|
+
*
|
|
23
|
+
* TODO: drop messages that do not match any cases.
|
|
24
|
+
*/
|
|
25
|
+
export declare const receive: <T>(cases?: TypeCase<T>[]) => Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* exit the actor, ending the process as a result.
|
|
28
|
+
*
|
|
29
|
+
* This is simply a wrapper around process.exit();
|
|
30
|
+
*/
|
|
31
|
+
export declare const exit: () => never;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exit = exports.receive = exports.tell = exports.self = exports.init = void 0;
|
|
4
|
+
const array_1 = require("@quenk/noni/lib/data/array");
|
|
5
|
+
const case_1 = require("@quenk/noni/lib/control/match/case");
|
|
6
|
+
const function_1 = require("@quenk/noni/lib/data/function");
|
|
7
|
+
const address_1 = require("../address");
|
|
8
|
+
const messages = [];
|
|
9
|
+
/**
|
|
10
|
+
* init should be called as early as possible in the child process if using the
|
|
11
|
+
* direct API (Process).
|
|
12
|
+
*
|
|
13
|
+
* It sets up a listener for incoming messages to the child_process that can
|
|
14
|
+
* be read later via receive() or select().
|
|
15
|
+
*/
|
|
16
|
+
const init = () => {
|
|
17
|
+
if (!process.send)
|
|
18
|
+
throw new Error('process: direct API is meant to ' + 'be used in a child process!');
|
|
19
|
+
process.on('message', (m) => {
|
|
20
|
+
messages.unshift(m);
|
|
21
|
+
drain();
|
|
22
|
+
});
|
|
23
|
+
process.on('uncaughtExceptionMonitor', err => process.send(err));
|
|
24
|
+
};
|
|
25
|
+
exports.init = init;
|
|
26
|
+
/**
|
|
27
|
+
* self provides the address for this child actor.
|
|
28
|
+
*/
|
|
29
|
+
exports.self = process.env.POTOO_ACTOR_ADDRESS || address_1.ADDRESS_DISCARD;
|
|
30
|
+
/**
|
|
31
|
+
* tell sends a message to another actor in the system using the VM in the
|
|
32
|
+
* parent process.
|
|
33
|
+
*/
|
|
34
|
+
const tell = (to, message) => process.send({ from: exports.self, to, message });
|
|
35
|
+
exports.tell = tell;
|
|
36
|
+
const receivers = [];
|
|
37
|
+
const defaultCases = [new case_1.Default(function_1.identity)];
|
|
38
|
+
/**
|
|
39
|
+
* receive the next message in the message queue.
|
|
40
|
+
*
|
|
41
|
+
* TODO: drop messages that do not match any cases.
|
|
42
|
+
*/
|
|
43
|
+
const receive = async (cases = defaultCases) => new Promise(resolve => {
|
|
44
|
+
let matcher = new case_1.CaseFunction(cases || defaultCases);
|
|
45
|
+
let receiver = async (msg) => {
|
|
46
|
+
if (matcher.test(msg)) {
|
|
47
|
+
resolve(await matcher.apply(msg));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
receivers.push(receiver);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
receivers.push(receiver);
|
|
54
|
+
drain();
|
|
55
|
+
});
|
|
56
|
+
exports.receive = receive;
|
|
57
|
+
const drain = () => {
|
|
58
|
+
if (!(0, array_1.empty)(messages) && !(0, array_1.empty)(receivers))
|
|
59
|
+
receivers.pop()(messages.shift());
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* exit the actor, ending the process as a result.
|
|
63
|
+
*
|
|
64
|
+
* This is simply a wrapper around process.exit();
|
|
65
|
+
*/
|
|
66
|
+
const exit = () => process.exit();
|
|
67
|
+
exports.exit = exit;
|
|
68
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["process.ts"],"names":[],"mappings":";;;AACA,sDAAmD;AACnD,6DAI4C;AAC5C,4DAAyD;AAEzD,wCAAsD;AAGtD,MAAM,QAAQ,GAAc,EAAE,CAAC;AAE/B;;;;;;GAMG;AACI,MAAM,IAAI,GAAG,GAAG,EAAE;IACrB,IAAI,CAAC,OAAO,CAAC,IAAI;QACb,MAAM,IAAI,KAAK,CACX,kCAAkC,GAAG,6BAA6B,CACrE,CAAC;IAEN,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAU,EAAE,EAAE;QACjC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpB,KAAK,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,0BAA0B,EAAE,GAAG,CAAC,EAAE,CAC9B,OAAO,CAAC,IAAK,CAAC,GAAG,CAAC,CAChC,CAAC;AACN,CAAC,CAAC;AAdW,QAAA,IAAI,QAcf;AAEF;;GAEG;AACU,QAAA,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,yBAAe,CAAC;AAEvE;;;GAGG;AACI,MAAM,IAAI,GAAG,CAAI,EAAW,EAAE,OAAU,EAAE,EAAE,CACpC,OAAO,CAAC,IAAK,CAAC,EAAE,IAAI,EAAE,YAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AAD7C,QAAA,IAAI,QACyC;AAI1D,MAAM,SAAS,GAAc,EAAE,CAAC;AAEhC,MAAM,YAAY,GAAG,CAAC,IAAI,cAAO,CAAC,mBAAQ,CAAC,CAAC,CAAC;AAE7C;;;;GAIG;AACI,MAAM,OAAO,GAAG,KAAK,EACxB,QAAuB,YAAY,EACzB,EAAE,CACZ,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;IAClB,IAAI,OAAO,GAAG,IAAI,mBAAY,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC;IACtD,IAAI,QAAQ,GAAG,KAAK,EAAE,GAAY,EAAE,EAAE;QAClC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACJ,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC,CAAC;IACF,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,KAAK,EAAE,CAAC;AACZ,CAAC,CAAC,CAAC;AAdM,QAAA,OAAO,WAcb;AAEP,MAAM,KAAK,GAAG,GAAG,EAAE;IACf,IAAI,CAAC,IAAA,aAAK,EAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,aAAK,EAAC,SAAS,CAAC;QAC3B,SAAS,CAAC,GAAG,EAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF;;;;GAIG;AACI,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;AAA5B,QAAA,IAAI,QAAwB"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Type } from '@quenk/noni/lib/data/type';
|
|
2
|
+
import { empty } from '@quenk/noni/lib/data/array';
|
|
3
|
+
import {
|
|
4
|
+
CaseFunction,
|
|
5
|
+
Default,
|
|
6
|
+
TypeCase
|
|
7
|
+
} from '@quenk/noni/lib/control/match/case';
|
|
8
|
+
import { identity } from '@quenk/noni/lib/data/function';
|
|
9
|
+
|
|
10
|
+
import { Address, ADDRESS_DISCARD } from '../address';
|
|
11
|
+
import { Message } from '../';
|
|
12
|
+
|
|
13
|
+
const messages: Message[] = [];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* init should be called as early as possible in the child process if using the
|
|
17
|
+
* direct API (Process).
|
|
18
|
+
*
|
|
19
|
+
* It sets up a listener for incoming messages to the child_process that can
|
|
20
|
+
* be read later via receive() or select().
|
|
21
|
+
*/
|
|
22
|
+
export const init = () => {
|
|
23
|
+
if (!process.send)
|
|
24
|
+
throw new Error(
|
|
25
|
+
'process: direct API is meant to ' + 'be used in a child process!'
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
process.on('message', (m: Message) => {
|
|
29
|
+
messages.unshift(m);
|
|
30
|
+
drain();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
process.on('uncaughtExceptionMonitor', err =>
|
|
34
|
+
(<Function>process.send)(err)
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* self provides the address for this child actor.
|
|
40
|
+
*/
|
|
41
|
+
export const self = process.env.POTOO_ACTOR_ADDRESS || ADDRESS_DISCARD;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* tell sends a message to another actor in the system using the VM in the
|
|
45
|
+
* parent process.
|
|
46
|
+
*/
|
|
47
|
+
export const tell = <M>(to: Address, message: M) =>
|
|
48
|
+
(<Function>process.send)({ from: self, to, message });
|
|
49
|
+
|
|
50
|
+
type Handler = (value: Type) => Promise<void>;
|
|
51
|
+
|
|
52
|
+
const receivers: Handler[] = [];
|
|
53
|
+
|
|
54
|
+
const defaultCases = [new Default(identity)];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* receive the next message in the message queue.
|
|
58
|
+
*
|
|
59
|
+
* TODO: drop messages that do not match any cases.
|
|
60
|
+
*/
|
|
61
|
+
export const receive = async <T>(
|
|
62
|
+
cases: TypeCase<T>[] = defaultCases
|
|
63
|
+
): Promise<T> =>
|
|
64
|
+
new Promise(resolve => {
|
|
65
|
+
let matcher = new CaseFunction(cases || defaultCases);
|
|
66
|
+
let receiver = async (msg: Message) => {
|
|
67
|
+
if (matcher.test(msg)) {
|
|
68
|
+
resolve(await matcher.apply(msg));
|
|
69
|
+
} else {
|
|
70
|
+
receivers.push(receiver);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
receivers.push(receiver);
|
|
74
|
+
drain();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const drain = () => {
|
|
78
|
+
if (!empty(messages) && !empty(receivers))
|
|
79
|
+
(<Handler>receivers.pop())(messages.shift());
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* exit the actor, ending the process as a result.
|
|
84
|
+
*
|
|
85
|
+
* This is simply a wrapper around process.exit();
|
|
86
|
+
*/
|
|
87
|
+
export const exit = () => process.exit();
|