@quenk/potoo 4.0.7 → 4.0.11

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 (89) hide show
  1. package/lib/actor/address.js.map +1 -1
  2. package/lib/actor/api.d.ts +2 -2
  3. package/lib/actor/api.js.map +1 -1
  4. package/lib/actor/framework/index.js +2 -2
  5. package/lib/actor/framework/index.js.map +1 -1
  6. package/lib/actor/framework/process.d.ts +3 -2
  7. package/lib/actor/framework/process.js.map +1 -1
  8. package/lib/actor/framework/resident.d.ts +5 -3
  9. package/lib/actor/framework/resident.js +2 -0
  10. package/lib/actor/framework/resident.js.map +1 -1
  11. package/lib/actor/index.js.map +1 -1
  12. package/lib/actor/system/vm/allocator/index.js.map +1 -1
  13. package/lib/actor/system/vm/allocator/map.js +7 -4
  14. package/lib/actor/system/vm/allocator/map.js.map +1 -1
  15. package/lib/actor/system/vm/conf.js.map +1 -1
  16. package/lib/actor/system/vm/event/dispatcher.d.ts +31 -12
  17. package/lib/actor/system/vm/event/dispatcher.js +72 -20
  18. package/lib/actor/system/vm/event/dispatcher.js.map +1 -1
  19. package/lib/actor/system/vm/event/index.js.map +1 -1
  20. package/lib/actor/system/vm/frame.js.map +1 -1
  21. package/lib/actor/system/vm/group.js.map +1 -1
  22. package/lib/actor/system/vm/index.js +2 -2
  23. package/lib/actor/system/vm/index.js.map +1 -1
  24. package/lib/actor/system/vm/log/index.js.map +1 -1
  25. package/lib/actor/system/vm/log/writer.js.map +1 -1
  26. package/lib/actor/system/vm/object/foreign.js.map +1 -1
  27. package/lib/actor/system/vm/object/index.js.map +1 -1
  28. package/lib/actor/system/vm/object/list.js.map +1 -1
  29. package/lib/actor/system/vm/op/actor.js.map +1 -1
  30. package/lib/actor/system/vm/op/base.js.map +1 -1
  31. package/lib/actor/system/vm/op/index.js.map +1 -1
  32. package/lib/actor/system/vm/op/object.js.map +1 -1
  33. package/lib/actor/system/vm/registry.js.map +1 -1
  34. package/lib/actor/system/vm/runtime/error.js.map +1 -1
  35. package/lib/actor/system/vm/runtime.js.map +1 -1
  36. package/lib/actor/system/vm/scheduler.js.map +1 -1
  37. package/lib/actor/system/vm/script/index.js.map +1 -1
  38. package/lib/actor/system/vm/script/info.js.map +1 -1
  39. package/lib/actor/system/vm/strategy/error.js.map +1 -1
  40. package/lib/actor/system/vm/thread/factory.js.map +1 -1
  41. package/lib/actor/system/vm/thread/index.js.map +1 -1
  42. package/lib/actor/system/vm/thread/process.js.map +1 -1
  43. package/lib/actor/system/vm/thread/shared/index.js.map +1 -1
  44. package/lib/actor/system/vm/thread/shared/js.d.ts +2 -2
  45. package/lib/actor/system/vm/thread/shared/js.js +3 -3
  46. package/lib/actor/system/vm/thread/shared/js.js.map +1 -1
  47. package/lib/actor/system/vm/type.js.map +1 -1
  48. package/lib/actor/template.d.ts +20 -0
  49. package/lib/actor/template.js +17 -1
  50. package/lib/actor/template.js.map +1 -1
  51. package/package.json +11 -9
  52. package/lib/actor/address.ts +0 -90
  53. package/lib/actor/api.ts +0 -57
  54. package/lib/actor/framework/index.ts +0 -1
  55. package/lib/actor/framework/process.ts +0 -87
  56. package/lib/actor/framework/resident.ts +0 -90
  57. package/lib/actor/index.ts +0 -35
  58. package/lib/actor/system/vm/allocator/index.ts +0 -43
  59. package/lib/actor/system/vm/allocator/map.ts +0 -256
  60. package/lib/actor/system/vm/conf.ts +0 -33
  61. package/lib/actor/system/vm/event/dispatcher.ts +0 -85
  62. package/lib/actor/system/vm/event/index.ts +0 -143
  63. package/lib/actor/system/vm/frame.ts +0 -484
  64. package/lib/actor/system/vm/group.ts +0 -46
  65. package/lib/actor/system/vm/index.ts +0 -230
  66. package/lib/actor/system/vm/log/index.ts +0 -73
  67. package/lib/actor/system/vm/log/writer.ts +0 -96
  68. package/lib/actor/system/vm/object/foreign.ts +0 -10
  69. package/lib/actor/system/vm/object/index.ts +0 -4
  70. package/lib/actor/system/vm/object/list.ts +0 -8
  71. package/lib/actor/system/vm/op/actor.ts +0 -126
  72. package/lib/actor/system/vm/op/base.ts +0 -243
  73. package/lib/actor/system/vm/op/index.ts +0 -388
  74. package/lib/actor/system/vm/op/object.ts +0 -81
  75. package/lib/actor/system/vm/registry.ts +0 -223
  76. package/lib/actor/system/vm/runtime/error.ts +0 -248
  77. package/lib/actor/system/vm/runtime.ts +0 -31
  78. package/lib/actor/system/vm/scheduler.ts +0 -108
  79. package/lib/actor/system/vm/script/index.ts +0 -64
  80. package/lib/actor/system/vm/script/info.ts +0 -359
  81. package/lib/actor/system/vm/strategy/error.ts +0 -88
  82. package/lib/actor/system/vm/thread/factory.ts +0 -29
  83. package/lib/actor/system/vm/thread/index.ts +0 -29
  84. package/lib/actor/system/vm/thread/process.ts +0 -134
  85. package/lib/actor/system/vm/thread/shared/index.ts +0 -50
  86. package/lib/actor/system/vm/thread/shared/js.ts +0 -151
  87. package/lib/actor/system/vm/type.ts +0 -115
  88. package/lib/actor/template.ts +0 -170
  89. package/lib/tsconfig.json +0 -22
@@ -1,230 +0,0 @@
1
- import * as template from '../../template';
2
- import * as errors from './runtime/error';
3
- import * as events from './event';
4
-
5
- import { Err } from '@quenk/noni/lib/control/error';
6
- import { Future } from '@quenk/noni/lib/control/monad/future';
7
- import { diff, empty } from '@quenk/noni/lib/data/array';
8
- import { merge } from '@quenk/noni/lib/data/record';
9
-
10
- import { Address, ADDRESS_SYSTEM, isChild, isGroup } from '../../address';
11
- import { fromSpawnable } from '../../template';
12
- import { Actor, Message } from '../../';
13
- import { MapAllocator } from './allocator/map';
14
- import { ErrorStrategy, SupervisorErrorStrategy } from './strategy/error';
15
- import { Thread } from './thread';
16
- import { GroupMap } from './group';
17
- import { Scheduler } from './scheduler';
18
- import { RegistrySet } from './registry';
19
- import { Allocator } from './allocator';
20
- import { Api } from '../../api';
21
- import { LogWritable, LogWriter } from './log/writer';
22
- import { EventDispatcher } from './event/dispatcher';
23
- import { Conf, PartialConf } from './conf';
24
- import { toLogLevelValue } from './log';
25
-
26
- /**
27
- * VM is the interface for a virtual machine.
28
- *
29
- * It provides methods for manipulating the state of the actors of the system.
30
- * Some opcode handlers depend on this interface to do their work.
31
- */
32
- export interface VM extends Actor, Thread, Api {
33
- /**
34
- * allocator used to manage thread resources for an actor.
35
- */
36
- allocator: Allocator;
37
-
38
- /**
39
- * scheduler used for co-ordinating actor thread execution.
40
- */
41
- scheduler: Scheduler;
42
-
43
- /**
44
- * errors strategy used to handle errors that occur within the system.
45
- */
46
- errors: ErrorStrategy;
47
-
48
- /**
49
- * log service for the VM.
50
- *
51
- * Used to access the internal logging API.
52
- */
53
- log: LogWritable;
54
-
55
- /**
56
- * events service for the VM.
57
- *
58
- * Used to publish VM events to interested listeners.
59
- */
60
- events: EventDispatcher;
61
-
62
- /**
63
- * registry used to store internal VM objects.
64
- */
65
- registry: RegistrySet;
66
-
67
- /**
68
- * groups holds the mapping of group names to actor addresses.
69
- */
70
- groups: GroupMap;
71
-
72
- /**
73
- * sendMessage to the actor act the destination address.
74
- *
75
- * This is used by the threads to communicate.
76
- */
77
- sendMessage(from: Thread, to: Address, msg: Message): void;
78
-
79
- /**
80
- * sendKillSignal initiates the deallocation of the actor at the
81
- * specified address.
82
- *
83
- * Actual deallocation only occurs if the source thread is allowed to.
84
- */
85
- sendKillSignal(src: Thread, target: Address): Promise<void>;
86
-
87
- /**
88
- * runTask allows an async function to be executed on behalf of a Thread.
89
- *
90
- * If the Promise rejects, the error is raised with the Thread.
91
- */
92
- runTask(thread: Thread, task: () => Promise<void>): Promise<void>;
93
- }
94
-
95
- /**
96
- * PVM (Potoo Virtual Machine) is a JavaScript implemented virtual machine that
97
- * functions as a message delivery system between target actors.
98
- *
99
- * Actors known to the VM are considered to be part of a system and may or may
100
- * not reside on the same process/worker/thread depending on the underlying
101
- * platform and individual actor implementations.
102
- */
103
- export class PVM implements VM {
104
- constructor(
105
- public allocator: Allocator = new MapAllocator(() => this),
106
- public scheduler: Scheduler = new Scheduler(),
107
- public errors: ErrorStrategy = new SupervisorErrorStrategy(allocator),
108
- public log: LogWritable = new LogWriter(console),
109
- public events = new EventDispatcher(log),
110
- public registry = new RegistrySet(),
111
- public groups: GroupMap = new GroupMap(),
112
- public address = ADDRESS_SYSTEM,
113
- public self = ADDRESS_SYSTEM
114
- ) {}
115
-
116
- /**
117
- * create a new PVM instance using the provided configuration.
118
- */
119
- static create(conf: PartialConf = {}): PVM {
120
- let config: Conf = {
121
- log: merge({ level: 'info', sink: console }, conf.log ?? {})
122
- };
123
-
124
- let vm: PVM;
125
-
126
- let allocator = new MapAllocator(() => vm);
127
- let log = new LogWriter(
128
- config.log.sink,
129
- toLogLevelValue(config.log.level)
130
- );
131
-
132
- vm = new PVM(
133
- allocator,
134
- new Scheduler(),
135
- new SupervisorErrorStrategy(allocator),
136
- log,
137
- new EventDispatcher(log),
138
- new RegistrySet(),
139
- new GroupMap()
140
- );
141
- return vm;
142
- }
143
-
144
- // Actor
145
-
146
- async start() {}
147
-
148
- //TODO: events.OnRootMessage.dispatch();
149
- async notify() {}
150
-
151
- //TODO: stop all actors?
152
- async stop() {}
153
-
154
- // Api
155
-
156
- get vm() {
157
- return this;
158
- }
159
-
160
- async spawn(tmpl: template.Spawnable): Promise<Address> {
161
- return this.allocator.allocate(this, fromSpawnable(tmpl));
162
- }
163
-
164
- async tell(to: Address, msg: Message) {
165
- this.sendMessage(this, to, msg);
166
- }
167
-
168
- async raise(err: Err) {
169
- await this.errors.raise(this, err);
170
- }
171
-
172
- async kill(addr: Address) {
173
- await this.sendKillSignal(this, addr);
174
- }
175
-
176
- async receive<T>() {
177
- return <Promise<T>>Future.raise(new Error('Not implemented'));
178
- }
179
-
180
- // Platform
181
-
182
- sendMessage(from: Thread, to: Address, msg: Message) {
183
- let targets = isGroup(to) ? this.groups.getMembers(to) : [to];
184
-
185
- let threads = this.allocator.getThreads(targets);
186
-
187
- let missing = diff(
188
- targets,
189
- threads.map(t => t.address)
190
- );
191
-
192
- if (!empty(missing)) {
193
- for (let address of missing)
194
- this.events.dispatchMessageEvent(
195
- events.EVENT_MESSAGE_BOUNCE,
196
- from.address,
197
- address,
198
- msg
199
- );
200
- }
201
-
202
- for (let thread of threads) {
203
- this.events.dispatchMessageEvent(
204
- events.EVENT_MESSGAE_SEND,
205
- from.address,
206
- to,
207
- msg
208
- );
209
- thread.notify(msg).catch(err => thread.raise(err));
210
- }
211
- }
212
-
213
- async sendKillSignal(src: Thread, target: Address): Promise<void> {
214
- if (src.address !== target && !isChild(src.address, target)) {
215
- return Future.raise(new errors.IllegalStopErr(src.address, target));
216
- }
217
-
218
- let mtargetThread = this.allocator.getThread(target);
219
-
220
- if (mtargetThread.isNothing()) {
221
- return;
222
- }
223
-
224
- await this.allocator.deallocate(mtargetThread.get());
225
- }
226
-
227
- runTask(thread: Thread, task: () => Promise<void>): Promise<void> {
228
- return Future.do(task).catch(err => thread.raise(err));
229
- }
230
- }
@@ -1,73 +0,0 @@
1
- import { Type } from '@quenk/noni/lib/data/type';
2
-
3
- /**
4
- * LogLevel is a string indicating the maximum level of messages that should
5
- * be written to the log sink.
6
- */
7
- export type LogLevel = 'trace' | 'debug' | 'info' | 'notice' | 'warn' | 'error';
8
-
9
- /**
10
- * LogLevelValue is a numeric representation of a LogLevel.
11
- */
12
- export enum LogLevelValue {
13
- trace = 8,
14
- debug = 7,
15
- info = 6,
16
- notice = 5,
17
- warn = 4,
18
- error = 3
19
- }
20
-
21
- /**
22
- * LogSink is the interface expected of log message destinations.
23
- *
24
- * This is based on the JS console API and as a result `console` is a valid
25
- * LogSink.
26
- */
27
- export interface LogSink {
28
- /**
29
- * debug level.
30
- */
31
- debug(...e: Type[]): void;
32
-
33
- /**
34
- * info level.
35
- */
36
- info(...e: Type[]): void;
37
-
38
- /**
39
- * warn level.
40
- */
41
- warn(...e: Type[]): void;
42
-
43
- /**
44
- * error level.
45
- */
46
- error(...e: Type[]): void;
47
-
48
- /**
49
- * log level.
50
- */
51
- log(...e: Type[]): void;
52
- }
53
-
54
- const logLevelValueEntries = Object.entries(LogLevelValue);
55
-
56
- /**
57
- * toLogLevel converts a LogLevelValue to a LogLevel string.
58
- *
59
- * If the value is not valid '<void>' is returned.
60
- */
61
- export const toLogLevel = (level: LogLevelValue): LogLevel => {
62
- let entry = logLevelValueEntries.find(([, v]) => v === level);
63
- return <LogLevel>(entry ? entry[0] : '<void>');
64
- };
65
-
66
- /**
67
- * toLogLevelValue converts a LogLevel to a LogLevelValue.
68
- *
69
- * I the LogLevel is not valid LogLevelValue.info is returned.
70
- */
71
- export const toLogLevelValue = (level: LogLevel | string): LogLevelValue => {
72
- return LogLevelValue[<LogLevel>level] ?? LogLevelValue.info;
73
- };
@@ -1,96 +0,0 @@
1
- import * as events from '../event';
2
-
3
- import { isString, Type } from '@quenk/noni/lib/data/type';
4
- import { Record } from '@quenk/noni/lib/data/record';
5
- import { interpolate } from '@quenk/noni/lib/data/string';
6
-
7
- import { InternalEvent } from '../event';
8
- import { LogLevelValue, LogSink } from '.';
9
-
10
- /**
11
- * LogWritable is the interface used by the VM for logging.
12
- *
13
- * It provides convenience methods for writing various types of messages to the
14
- * log sink.
15
- */
16
- export interface LogWritable {
17
- /**
18
- * level is the current log level.
19
- */
20
- level: LogLevelValue;
21
-
22
- /**
23
- * sink is the destination logs will be written to.
24
- */
25
- sink: LogSink;
26
-
27
- /**
28
- * write a message to the log if the level is less than or equal to the
29
- * current log level.
30
- */
31
- write(level: LogLevelValue, ...args: Type[]): void;
32
-
33
- /**
34
- * writeEvent writes an InternalEvent to the log.
35
- *
36
- * This uses internal logic to format a message for each event.
37
- */
38
- writeEvent<E extends InternalEvent>(event: E): void;
39
- }
40
-
41
- /**
42
- * LogTemplate used to format event log messages.
43
- */
44
- export type LogTemplates = Record<string>;
45
-
46
- const defaultTemplates: LogTemplates = {
47
- [events.EVENT_MESSAGE_BOUNCE]: 'Message from {from} to {to} bounced!',
48
-
49
- [events.EVENT_MESSGAE_SEND]:
50
- 'Message from {from} to {to} delivered successfully!'
51
- };
52
-
53
- /**
54
- * LogWriter provides an implementation of [[LogWritable]] for the VM.
55
- */
56
- export class LogWriter implements LogWritable {
57
- constructor(
58
- public sink: LogSink,
59
- public level: LogLevelValue = LogLevelValue.error,
60
- public templates: LogTemplates = defaultTemplates
61
- ) {}
62
-
63
- write(level: LogLevelValue, ...args: Type[]) {
64
- if (level > this.level) return;
65
-
66
- let { sink } = this;
67
-
68
- switch (level) {
69
- case LogLevelValue.debug:
70
- case LogLevelValue.trace:
71
- sink.debug(...args);
72
- break;
73
-
74
- case LogLevelValue.notice:
75
- case LogLevelValue.warn:
76
- sink.warn(...args);
77
- break;
78
-
79
- case LogLevelValue.error:
80
- sink.error(...args);
81
- break;
82
-
83
- default:
84
- sink.info(...args);
85
- break;
86
- }
87
- }
88
-
89
- writeEvent(evt: InternalEvent) {
90
- let message = this.templates[evt.type] || evt;
91
- this.write(
92
- evt.level,
93
- isString(message) ? interpolate(message, evt) : message
94
- );
95
- }
96
- }
@@ -1,10 +0,0 @@
1
- import { Type } from '@quenk/noni/lib/data/type';
2
-
3
- import { PTObject } from '.';
4
-
5
- /**
6
- * PTForeign contains an opaque value whose type is external to the VM.
7
- */
8
- export class PTForeign implements PTObject {
9
- constructor(public value: Type) {}
10
- }
@@ -1,4 +0,0 @@
1
- /**
2
- * PTObject is the base interface for all objects in the PT library.
3
- */
4
- export interface PTObject {}
@@ -1,8 +0,0 @@
1
- import { PTObject } from '.';
2
-
3
- /**
4
- * PTList is the interface of objects stored in the object pool.
5
- *
6
- * TODO: Make useable by the VM.
7
- */
8
- export class PTList implements PTObject {}
@@ -1,126 +0,0 @@
1
- import { Frame } from '../frame';
2
- import { Template } from '../../../template';
3
- import { Operand } from '.';
4
- import { JSThread } from '../thread/shared/js';
5
-
6
- /**
7
- * alloc allocates resources for a new child actor.
8
- *
9
- * TOS must be an instance of PTTemplate or an error will be raised.
10
- * The address of the new actor is pushed onto the stack.
11
- *
12
- * Stack:
13
- * <template> -> <address>
14
- */
15
- export const alloc = (thread: JSThread, frame: Frame, _: Operand) => {
16
- let eTemp = frame.popObject();
17
-
18
- if (eTemp.isLeft()) return thread.raise(eTemp.takeLeft());
19
-
20
- let tmpl = eTemp.takeRight();
21
-
22
- //TODO: if(!isTemplateLike(tmpl)) return thread.raise(new Error('alloc: Cannot allocate non-template!'));
23
-
24
- //TODO: this is async
25
- thread.spawn(<Template>tmpl);
26
-
27
- /*
28
- if (eresult.isLeft()) {
29
- thread.raise(eresult.takeLeft());
30
- } else {
31
- frame.push(thread.vm.registry.addString(eresult.takeRight()));
32
- }*/
33
- };
34
-
35
- /**
36
- * self puts the address of the current actor on to the stack.
37
- * TODO: make self an automatic variable
38
- */
39
- export const self = (_: JSThread, f: Frame, __: Operand) => {
40
- f.pushSelf();
41
- };
42
-
43
- /**
44
- * send a message to another actor.
45
- *
46
- * Stack:
47
- * <message>,<address> -> <uint8>
48
- */
49
- export const send = (r: JSThread, f: Frame, _: Operand) => {
50
- let eMsg = f.popValue();
51
-
52
- if (eMsg.isLeft()) return r.raise(eMsg.takeLeft());
53
-
54
- let eAddr = f.popString();
55
-
56
- if (eAddr.isLeft()) return r.raise(eAddr.takeLeft());
57
-
58
- r.vm.sendMessage(r, eAddr.takeRight(), eMsg.takeRight());
59
- };
60
-
61
- /**
62
- * recv schedules a receiver function for the next available message.
63
- *
64
- * Currently only supports foreign functions.
65
- * Will invoke the actor's notify() method if there are pending
66
- * messages.
67
- *
68
- * Stack:
69
- * <function> ->
70
- */
71
- export const recv = (r: JSThread, f: Frame, _: Operand) => {
72
- let einfo = f.popFunction();
73
-
74
- if (einfo.isLeft()) return r.raise(einfo.takeLeft());
75
-
76
- // r.watch(r.receive());
77
- };
78
-
79
- /**
80
- * recvcount pushes the total count of pending receives to the top of the stack.
81
- *
82
- * Stack:
83
- * -> <uint32>
84
- */
85
- export const recvcount = (_r: JSThread, _f: Frame, _: Operand) => {
86
- //f.push(r.context.receivers.length);
87
- };
88
-
89
- /**
90
- * mailcount pushes the number of messages in the actor's mailbox onto the top
91
- * of the stack.
92
- *
93
- * Stack:
94
- * -> <uint32>
95
- */
96
- export const mailcount = (r: JSThread, f: Frame, _: Operand) => {
97
- f.push(r.mailbox.length);
98
- };
99
-
100
- /**
101
- * maildq pushes the earliest message in the mailbox (if any).
102
- *
103
- * Stack:
104
- *
105
- * -> <message>?
106
- */
107
- export const maildq = (_: JSThread, f: Frame, __: Operand) => {
108
- f.pushMessage();
109
- };
110
-
111
- /**
112
- * stop an actor in the system.
113
- *
114
- * The actor will be removed.
115
- *
116
- * Stack:
117
- *
118
- * <address> ->
119
- */
120
- export const stop = (r: JSThread, f: Frame, _: Operand) => {
121
- let eaddr = f.popString();
122
-
123
- if (eaddr.isLeft()) return r.raise(eaddr.takeLeft());
124
-
125
- // r.watch(r.kill(eaddr.takeRight()));
126
- };