@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.
Files changed (273) hide show
  1. package/README.md +61 -22
  2. package/lib/actor/address.d.ts +1 -1
  3. package/lib/actor/address.js +24 -28
  4. package/lib/actor/address.js.map +1 -1
  5. package/lib/actor/address.ts +28 -44
  6. package/lib/actor/api.d.ts +47 -0
  7. package/lib/actor/api.ts +57 -0
  8. package/lib/actor/framework/index.d.ts +1 -0
  9. package/lib/actor/framework/index.js +7 -0
  10. package/lib/actor/framework/index.js.map +1 -0
  11. package/lib/actor/framework/index.ts +1 -0
  12. package/lib/actor/framework/process.d.ts +31 -0
  13. package/lib/actor/framework/process.js +68 -0
  14. package/lib/actor/framework/process.js.map +1 -0
  15. package/lib/actor/framework/process.ts +87 -0
  16. package/lib/actor/framework/resident.d.ts +53 -0
  17. package/lib/actor/framework/resident.js +72 -0
  18. package/lib/actor/framework/resident.js.map +1 -0
  19. package/lib/actor/framework/resident.ts +92 -0
  20. package/lib/actor/index.d.ts +17 -41
  21. package/lib/actor/index.ts +17 -48
  22. package/lib/actor/system/vm/allocator/index.d.ts +36 -0
  23. package/lib/actor/system/vm/allocator/index.ts +43 -0
  24. package/lib/actor/system/vm/allocator/map.d.ts +60 -0
  25. package/lib/actor/system/vm/allocator/map.js +140 -0
  26. package/lib/actor/system/vm/allocator/map.js.map +1 -0
  27. package/lib/actor/system/vm/allocator/map.ts +256 -0
  28. package/lib/actor/system/vm/conf.d.ts +25 -29
  29. package/lib/actor/system/vm/conf.js +0 -14
  30. package/lib/actor/system/vm/conf.js.map +1 -1
  31. package/lib/actor/system/vm/conf.ts +26 -47
  32. package/lib/actor/system/vm/event/dispatcher.d.ts +45 -0
  33. package/lib/actor/system/vm/event/dispatcher.js +71 -0
  34. package/lib/actor/system/vm/event/dispatcher.js.map +1 -0
  35. package/lib/actor/system/vm/event/dispatcher.ts +85 -0
  36. package/lib/actor/system/vm/event/index.d.ts +118 -0
  37. package/lib/actor/system/vm/event/index.js +133 -0
  38. package/lib/actor/system/vm/event/index.js.map +1 -0
  39. package/lib/actor/system/vm/event/index.ts +143 -0
  40. package/lib/actor/system/vm/{runtime/stack/frame.d.ts → frame.d.ts} +12 -11
  41. package/lib/actor/system/vm/{runtime/stack/frame.js → frame.js} +32 -31
  42. package/lib/actor/system/vm/frame.js.map +1 -0
  43. package/lib/actor/system/vm/{runtime/stack/frame.ts → frame.ts} +72 -154
  44. package/lib/actor/system/vm/group.d.ts +27 -0
  45. package/lib/actor/system/vm/group.js +46 -0
  46. package/lib/actor/system/vm/group.js.map +1 -0
  47. package/lib/actor/system/vm/group.ts +46 -0
  48. package/lib/actor/system/vm/index.d.ts +64 -102
  49. package/lib/actor/system/vm/index.js +68 -288
  50. package/lib/actor/system/vm/index.js.map +1 -1
  51. package/lib/actor/system/vm/index.ts +141 -556
  52. package/lib/actor/system/vm/log/index.d.ts +57 -0
  53. package/lib/actor/system/vm/log/index.js +37 -0
  54. package/lib/actor/system/vm/log/index.js.map +1 -0
  55. package/lib/actor/system/vm/log/index.ts +73 -0
  56. package/lib/actor/system/vm/log/writer.d.ts +46 -0
  57. package/lib/actor/system/vm/log/writer.js +48 -0
  58. package/lib/actor/system/vm/log/writer.js.map +1 -0
  59. package/lib/actor/system/vm/log/writer.ts +96 -0
  60. package/lib/actor/system/vm/object/foreign.d.ts +9 -0
  61. package/lib/actor/system/vm/object/foreign.js +13 -0
  62. package/lib/actor/system/vm/object/foreign.js.map +1 -0
  63. package/lib/actor/system/vm/object/foreign.ts +10 -0
  64. package/lib/actor/system/vm/object/index.d.ts +5 -0
  65. package/lib/actor/system/vm/object/index.ts +4 -0
  66. package/lib/actor/system/vm/object/list.d.ts +8 -0
  67. package/lib/actor/system/vm/object/list.js +12 -0
  68. package/lib/actor/system/vm/object/list.js.map +1 -0
  69. package/lib/actor/system/vm/object/list.ts +8 -0
  70. package/lib/actor/system/vm/op/actor.d.ts +69 -0
  71. package/lib/actor/system/vm/{runtime/op → op}/actor.js +22 -28
  72. package/lib/actor/system/vm/op/actor.js.map +1 -0
  73. package/lib/actor/system/vm/op/actor.ts +126 -0
  74. package/lib/actor/system/vm/{runtime/op → op}/base.d.ts +21 -21
  75. package/lib/actor/system/vm/{runtime/op → op}/base.js +8 -9
  76. package/lib/actor/system/vm/op/base.js.map +1 -0
  77. package/lib/actor/system/vm/{runtime/op → op}/base.ts +60 -111
  78. package/lib/actor/system/vm/{runtime/op → op}/index.d.ts +21 -7
  79. package/lib/actor/system/vm/{runtime/op → op}/index.js +31 -10
  80. package/lib/actor/system/vm/op/index.js.map +1 -0
  81. package/lib/actor/system/vm/{runtime/op → op}/index.ts +78 -113
  82. package/lib/actor/system/vm/{runtime/op → op}/object.d.ts +6 -6
  83. package/lib/actor/system/vm/{runtime/op → op}/object.js +27 -15
  84. package/lib/actor/system/vm/op/object.js.map +1 -0
  85. package/lib/actor/system/vm/{runtime/op → op}/object.ts +28 -33
  86. package/lib/actor/system/vm/registry.d.ts +126 -0
  87. package/lib/actor/system/vm/registry.js +191 -0
  88. package/lib/actor/system/vm/registry.js.map +1 -0
  89. package/lib/actor/system/vm/registry.ts +223 -0
  90. package/lib/actor/system/vm/runtime/error.d.ts +46 -24
  91. package/lib/actor/system/vm/runtime/error.js +52 -27
  92. package/lib/actor/system/vm/runtime/error.js.map +1 -1
  93. package/lib/actor/system/vm/runtime/error.ts +80 -123
  94. package/lib/actor/system/vm/runtime.d.ts +28 -0
  95. package/lib/actor/system/vm/runtime.js +3 -0
  96. package/lib/actor/system/vm/runtime.js.map +1 -0
  97. package/lib/actor/system/vm/runtime.ts +31 -0
  98. package/lib/actor/system/vm/scheduler.d.ts +54 -0
  99. package/lib/actor/system/vm/scheduler.js +98 -0
  100. package/lib/actor/system/vm/scheduler.js.map +1 -0
  101. package/lib/actor/system/vm/scheduler.ts +111 -0
  102. package/lib/actor/system/vm/script/index.d.ts +3 -3
  103. package/lib/actor/system/vm/script/index.js.map +1 -1
  104. package/lib/actor/system/vm/script/index.ts +11 -17
  105. package/lib/actor/system/vm/script/info.d.ts +1 -1
  106. package/lib/actor/system/vm/script/info.js +3 -3
  107. package/lib/actor/system/vm/script/info.js.map +1 -1
  108. package/lib/actor/system/vm/script/info.ts +48 -73
  109. package/lib/actor/system/vm/strategy/error.d.ts +28 -0
  110. package/lib/actor/system/vm/strategy/error.js +57 -0
  111. package/lib/actor/system/vm/strategy/error.js.map +1 -0
  112. package/lib/actor/system/vm/strategy/error.ts +88 -0
  113. package/lib/actor/system/vm/thread/factory.d.ts +15 -0
  114. package/lib/actor/system/vm/thread/factory.js +22 -0
  115. package/lib/actor/system/vm/thread/factory.js.map +1 -0
  116. package/lib/actor/system/vm/thread/factory.ts +29 -0
  117. package/lib/actor/system/vm/thread/index.d.ts +17 -98
  118. package/lib/actor/system/vm/thread/index.js +2 -6
  119. package/lib/actor/system/vm/thread/index.js.map +1 -1
  120. package/lib/actor/system/vm/thread/index.ts +17 -114
  121. package/lib/actor/system/vm/thread/process.d.ts +45 -0
  122. package/lib/actor/system/vm/thread/process.js +105 -0
  123. package/lib/actor/system/vm/thread/process.js.map +1 -0
  124. package/lib/actor/system/vm/thread/process.ts +134 -0
  125. package/lib/actor/system/vm/thread/shared/index.d.ts +35 -52
  126. package/lib/actor/system/vm/thread/shared/index.js +18 -159
  127. package/lib/actor/system/vm/thread/shared/index.js.map +1 -1
  128. package/lib/actor/system/vm/thread/shared/index.ts +37 -244
  129. package/lib/actor/system/vm/thread/shared/js.d.ts +35 -0
  130. package/lib/actor/system/vm/thread/shared/js.js +114 -0
  131. package/lib/actor/system/vm/thread/shared/js.js.map +1 -0
  132. package/lib/actor/system/vm/thread/shared/js.ts +151 -0
  133. package/lib/actor/system/vm/type.d.ts +41 -68
  134. package/lib/actor/system/vm/type.js +7 -5
  135. package/lib/actor/system/vm/type.js.map +1 -1
  136. package/lib/actor/system/vm/type.ts +39 -83
  137. package/lib/actor/template.d.ts +99 -54
  138. package/lib/actor/template.js +28 -1
  139. package/lib/actor/template.js.map +1 -1
  140. package/lib/actor/template.ts +118 -60
  141. package/lib/tsconfig.json +2 -3
  142. package/package.json +17 -8
  143. package/lib/actor/flags.d.ts +0 -32
  144. package/lib/actor/flags.js +0 -36
  145. package/lib/actor/flags.js.map +0 -1
  146. package/lib/actor/flags.ts +0 -43
  147. package/lib/actor/mailbox.d.ts +0 -16
  148. package/lib/actor/mailbox.js +0 -17
  149. package/lib/actor/mailbox.js.map +0 -1
  150. package/lib/actor/mailbox.ts +0 -20
  151. package/lib/actor/message.d.ts +0 -15
  152. package/lib/actor/message.js +0 -17
  153. package/lib/actor/message.js.map +0 -1
  154. package/lib/actor/message.ts +0 -19
  155. package/lib/actor/remote/index.d.ts +0 -62
  156. package/lib/actor/remote/index.js +0 -79
  157. package/lib/actor/remote/index.js.map +0 -1
  158. package/lib/actor/remote/index.ts +0 -102
  159. package/lib/actor/remote/process/index.d.ts +0 -145
  160. package/lib/actor/remote/process/index.js +0 -232
  161. package/lib/actor/remote/process/index.js.map +0 -1
  162. package/lib/actor/remote/process/index.ts +0 -344
  163. package/lib/actor/remote/process/script.d.ts +0 -1
  164. package/lib/actor/remote/process/script.js +0 -5
  165. package/lib/actor/remote/process/script.js.map +0 -1
  166. package/lib/actor/remote/process/script.ts +0 -3
  167. package/lib/actor/remote/process/vm.d.ts +0 -31
  168. package/lib/actor/remote/process/vm.js +0 -78
  169. package/lib/actor/remote/process/vm.js.map +0 -1
  170. package/lib/actor/remote/process/vm.ts +0 -115
  171. package/lib/actor/resident/api.d.ts +0 -49
  172. package/lib/actor/resident/api.ts +0 -65
  173. package/lib/actor/resident/case/function.d.ts +0 -24
  174. package/lib/actor/resident/case/function.js +0 -34
  175. package/lib/actor/resident/case/function.js.map +0 -1
  176. package/lib/actor/resident/case/function.ts +0 -40
  177. package/lib/actor/resident/case/index.d.ts +0 -60
  178. package/lib/actor/resident/case/index.js +0 -48
  179. package/lib/actor/resident/case/index.js.map +0 -1
  180. package/lib/actor/resident/case/index.ts +0 -101
  181. package/lib/actor/resident/immutable/callback.d.ts +0 -9
  182. package/lib/actor/resident/immutable/callback.js +0 -14
  183. package/lib/actor/resident/immutable/callback.js.map +0 -1
  184. package/lib/actor/resident/immutable/callback.ts +0 -9
  185. package/lib/actor/resident/immutable/index.d.ts +0 -17
  186. package/lib/actor/resident/immutable/index.js +0 -28
  187. package/lib/actor/resident/immutable/index.js.map +0 -1
  188. package/lib/actor/resident/immutable/index.ts +0 -38
  189. package/lib/actor/resident/index.d.ts +0 -49
  190. package/lib/actor/resident/index.js +0 -89
  191. package/lib/actor/resident/index.js.map +0 -1
  192. package/lib/actor/resident/index.ts +0 -173
  193. package/lib/actor/resident/mutable/index.d.ts +0 -18
  194. package/lib/actor/resident/mutable/index.js +0 -31
  195. package/lib/actor/resident/mutable/index.js.map +0 -1
  196. package/lib/actor/resident/mutable/index.ts +0 -39
  197. package/lib/actor/resident/scripts.d.ts +0 -44
  198. package/lib/actor/resident/scripts.js +0 -137
  199. package/lib/actor/resident/scripts.js.map +0 -1
  200. package/lib/actor/resident/scripts.ts +0 -194
  201. package/lib/actor/resident/task.d.ts +0 -11
  202. package/lib/actor/resident/task.js +0 -19
  203. package/lib/actor/resident/task.js.map +0 -1
  204. package/lib/actor/resident/task.ts +0 -21
  205. package/lib/actor/system/error.d.ts +0 -8
  206. package/lib/actor/system/error.js +0 -13
  207. package/lib/actor/system/error.js.map +0 -1
  208. package/lib/actor/system/error.ts +0 -10
  209. package/lib/actor/system/index.d.ts +0 -15
  210. package/lib/actor/system/index.ts +0 -18
  211. package/lib/actor/system/vm/event.d.ts +0 -54
  212. package/lib/actor/system/vm/event.js +0 -36
  213. package/lib/actor/system/vm/event.js.map +0 -1
  214. package/lib/actor/system/vm/event.ts +0 -85
  215. package/lib/actor/system/vm/groups.d.ts +0 -16
  216. package/lib/actor/system/vm/groups.js +0 -23
  217. package/lib/actor/system/vm/groups.js.map +0 -1
  218. package/lib/actor/system/vm/groups.ts +0 -32
  219. package/lib/actor/system/vm/log.d.ts +0 -76
  220. package/lib/actor/system/vm/log.js +0 -90
  221. package/lib/actor/system/vm/log.js.map +0 -1
  222. package/lib/actor/system/vm/log.ts +0 -207
  223. package/lib/actor/system/vm/map.d.ts +0 -30
  224. package/lib/actor/system/vm/map.js +0 -42
  225. package/lib/actor/system/vm/map.js.map +0 -1
  226. package/lib/actor/system/vm/map.ts +0 -56
  227. package/lib/actor/system/vm/routers.d.ts +0 -13
  228. package/lib/actor/system/vm/routers.js +0 -21
  229. package/lib/actor/system/vm/routers.js.map +0 -1
  230. package/lib/actor/system/vm/routers.ts +0 -25
  231. package/lib/actor/system/vm/runtime/context.d.ts +0 -61
  232. package/lib/actor/system/vm/runtime/context.js +0 -17
  233. package/lib/actor/system/vm/runtime/context.js.map +0 -1
  234. package/lib/actor/system/vm/runtime/context.ts +0 -94
  235. package/lib/actor/system/vm/runtime/heap/index.d.ts +0 -4
  236. package/lib/actor/system/vm/runtime/heap/index.ts +0 -5
  237. package/lib/actor/system/vm/runtime/heap/ledger.d.ts +0 -142
  238. package/lib/actor/system/vm/runtime/heap/ledger.js +0 -99
  239. package/lib/actor/system/vm/runtime/heap/ledger.js.map +0 -1
  240. package/lib/actor/system/vm/runtime/heap/ledger.ts +0 -304
  241. package/lib/actor/system/vm/runtime/index.d.ts +0 -19
  242. package/lib/actor/system/vm/runtime/index.js +0 -12
  243. package/lib/actor/system/vm/runtime/index.js.map +0 -1
  244. package/lib/actor/system/vm/runtime/index.ts +0 -30
  245. package/lib/actor/system/vm/runtime/op/actor.d.ts +0 -69
  246. package/lib/actor/system/vm/runtime/op/actor.js.map +0 -1
  247. package/lib/actor/system/vm/runtime/op/actor.ts +0 -154
  248. package/lib/actor/system/vm/runtime/op/base.js.map +0 -1
  249. package/lib/actor/system/vm/runtime/op/index.js.map +0 -1
  250. package/lib/actor/system/vm/runtime/op/object.js.map +0 -1
  251. package/lib/actor/system/vm/runtime/stack/frame.js.map +0 -1
  252. package/lib/actor/system/vm/scripts/factory.d.ts +0 -12
  253. package/lib/actor/system/vm/scripts/factory.js +0 -40
  254. package/lib/actor/system/vm/scripts/factory.js.map +0 -1
  255. package/lib/actor/system/vm/scripts/factory.ts +0 -55
  256. package/lib/actor/system/vm/scripts/index.d.ts +0 -32
  257. package/lib/actor/system/vm/scripts/index.js +0 -47
  258. package/lib/actor/system/vm/scripts/index.js.map +0 -1
  259. package/lib/actor/system/vm/scripts/index.ts +0 -49
  260. package/lib/actor/system/vm/table.d.ts +0 -44
  261. package/lib/actor/system/vm/table.js +0 -68
  262. package/lib/actor/system/vm/table.js.map +0 -1
  263. package/lib/actor/system/vm/table.ts +0 -113
  264. package/lib/actor/system/vm/thread/shared/scheduler.d.ts +0 -38
  265. package/lib/actor/system/vm/thread/shared/scheduler.js +0 -62
  266. package/lib/actor/system/vm/thread/shared/scheduler.js.map +0 -1
  267. package/lib/actor/system/vm/thread/shared/scheduler.ts +0 -84
  268. /package/lib/actor/{resident/api.js → api.js} +0 -0
  269. /package/lib/actor/{resident/api.js.map → api.js.map} +0 -0
  270. /package/lib/actor/system/{index.js → vm/allocator/index.js} +0 -0
  271. /package/lib/actor/system/{index.js.map → vm/allocator/index.js.map} +0 -0
  272. /package/lib/actor/system/vm/{runtime/heap → object}/index.js +0 -0
  273. /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 application message passing system inspired by the actor model.
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 constructing an actor system within frontend or
11
- backend applications.
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
- It is implemented as a virtual machine (PVM) that is usually embeded into the
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
- Actors can either be "resident" or "remote". Resident actors share the JS event
19
- loop with the VM and use its API to execute message passing instructions. Remote
20
- actors that do not share the event loop and can be in another process or even
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
- The [API](src/resident/index.ts) interface describes the methods available to
24
- resident actors. Extend the `Immutable` or `Mutable` classes to create an
25
- implementation or `AbstractResident` if you need more customisation.
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
- Currently the only remote actors supported are [Process](src/actor/process/index.ts)
28
- which uses the Node.js child_process API to run a separate `PVM` instance.
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
- There are plans however to support web sockets, web workers and possibly green
31
- thread actors.
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
- Consult the tests folder for now.
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) 2022 Quenk Technologies Limited
84
+ Apache-2.0 (C) 2024 Quenk Technologies Limited
@@ -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 declare type Address = string;
12
+ export type Address = string;
13
13
  /**
14
14
  * AddressMap
15
15
  */
@@ -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) => ((exports.ADDRESS_RESTRICTED.some(a => id.indexOf(a) > -1)) && (id !== exports.SEPERATOR));
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) => ((parent === exports.SEPERATOR) || (parent === exports.ADDRESS_EMPTY)) ?
24
- `${parent}${id}` :
25
- (parent === exports.ADDRESS_SYSTEM) ?
26
- id :
27
- `${parent}${exports.SEPERATOR}${id}`;
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 (((addr === exports.ADDRESS_SYSTEM) ||
34
- (addr === exports.ADDRESS_EMPTY) ||
35
- (addr === exports.ADDRESS_DISCARD) || (addr === exports.SEPERATOR))) {
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 ((b4.length === 2) && (b4[0] === '')) {
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) => ((addr === exports.ADDRESS_SYSTEM) ||
58
- (addr === exports.ADDRESS_DISCARD) ||
59
- (addr === exports.ADDRESS_EMPTY) ||
60
- (addr === exports.SEPERATOR)) ?
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) => ((parent === exports.ADDRESS_SYSTEM) && (child !== parent)) ||
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) => ((addr[0] === '$') && (addr !== '$'));
69
+ const isGroup = (addr) => addr[0] === '$' && addr !== '$';
74
70
  exports.isGroup = isGroup;
75
71
  //# sourceMappingURL=address.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"address.js","sourceRoot":"","sources":["address.ts"],"names":[],"mappings":"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"}
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"}
@@ -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
- ((ADDRESS_RESTRICTED.some(a => id.indexOf(a) > -1)) && (id !== SEPERATOR));
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
- ((parent === SEPERATOR) || (parent === ADDRESS_EMPTY)) ?
43
- `${parent}${id}` :
44
- (parent === ADDRESS_SYSTEM) ?
45
- id :
46
- `${parent}${SEPERATOR}${id}`;
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
- if (((addr === ADDRESS_SYSTEM) ||
54
- (addr === ADDRESS_EMPTY) ||
55
- (addr === ADDRESS_DISCARD) || (addr === SEPERATOR))) {
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 ((b4.length === 2) && (b4[0] === '')) {
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
- ((addr === ADDRESS_SYSTEM) ||
89
- (addr === ADDRESS_DISCARD) ||
90
- (addr === ADDRESS_EMPTY) ||
91
- (addr === SEPERATOR)) ?
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
- ((parent === ADDRESS_SYSTEM) && (child !== parent)) ||
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
- ((addr[0] === '$') && (addr !== '$'))
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
+ }
@@ -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();