@phreshos/node 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { gatewayAddress } from "./address.js";
2
2
  export { Client, ClientService, Endpoint, Process, Program, Server, ServerService, System, type ProgramProcessRunEvent, type ProgramProcessRunOptions } from "./system.js";
3
- export { Service, type ServiceKey, type ServiceLifecycle, type ServiceLifecycleEvents } from "@phreshos/core";
3
+ export { Service, type ClientLaunch, type Launch, type ProgramDefinition, type ServerLaunch, type ServiceKey, } from "@phreshos/core";
4
4
  export { resolveHome } from "./home.js";
5
5
  export { Project, type Manifest, type PackedProject, type ProjectMode, type ProjectOptions, type ProjectRunOptions } from "./project.js";
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { gatewayAddress } from "./address.js";
2
2
  export { Client, ClientService, Endpoint, Process, Program, Server, ServerService, System } from "./system.js";
3
- export { Service } from "@phreshos/core";
3
+ export { Service, } from "@phreshos/core";
4
4
  export { resolveHome } from "./home.js";
5
5
  export { Project } from "./project.js";
package/dist/project.js CHANGED
@@ -70,6 +70,7 @@ export class Project {
70
70
  ...server && { server: {
71
71
  location: resolve(this.directory, server.location),
72
72
  start: server.start,
73
+ service: server.service,
73
74
  installCommand: config.server?.installCommand,
74
75
  uninstallCommand: config.server?.uninstallCommand,
75
76
  ...serverExecution(server)
@@ -77,6 +78,7 @@ export class Project {
77
78
  ...client && { client: {
78
79
  location: /^https?:\/\//i.test(client.location) ? client.location : resolve(this.directory, client.location),
79
80
  start: client.start,
81
+ service: client.service,
80
82
  title: config.client?.title,
81
83
  size: config.client?.size,
82
84
  position: config.client?.position,
@@ -203,6 +205,8 @@ function validateConfig(config) {
203
205
  throw new Error(`A declared ${half} half must have a location`);
204
206
  if (declared.start !== undefined && typeof declared.start !== "boolean")
205
207
  throw new Error(`A declared ${half} Endpoint's start default must be true or false`);
208
+ if (declared.service !== undefined && typeof declared.service !== "boolean")
209
+ throw new Error(`A declared ${half} Endpoint's service default must be true or false`);
206
210
  }
207
211
  if (!(config.server && (config.server.start ?? true)) && !(config.client && (config.client.start ?? true))) {
208
212
  throw new Error("A Program's default Process must start a Server Endpoint, a Client Endpoint, or both");
@@ -269,6 +273,7 @@ function packageDefinition(config, version) {
269
273
  ...config.server && { server: {
270
274
  location: "server",
271
275
  start: config.server.start,
276
+ service: config.server.service,
272
277
  installCommand: config.server.installCommand,
273
278
  uninstallCommand: config.server.uninstallCommand,
274
279
  ...serverExecution(config.server)
@@ -276,6 +281,7 @@ function packageDefinition(config, version) {
276
281
  ...config.client && { client: {
277
282
  location: "client",
278
283
  start: config.client.start,
284
+ service: config.client.service,
279
285
  title: config.client.title,
280
286
  size: config.client.size,
281
287
  position: config.client.position,
package/dist/system.js CHANGED
@@ -62,8 +62,12 @@ export class System {
62
62
  requireConnected(this);
63
63
  if (!isServiceKey(key))
64
64
  throw new Error("A complete service key is required");
65
- const normalized = Object.freeze({ program: key.program, endpoint: key.endpoint, name: key.name });
66
- const identity = JSON.stringify([normalized.program, normalized.endpoint, normalized.name]);
65
+ const normalized = Object.freeze({
66
+ ...(key.program === undefined ? {} : { program: key.program }),
67
+ process: key.process,
68
+ endpoint: key.endpoint
69
+ });
70
+ const identity = JSON.stringify([key.program ?? null, key.process, key.endpoint]);
67
71
  return systemState(this).handles.obtain(`service:${identity}`, () => normalized.endpoint === "server"
68
72
  ? new ServerServiceHandle(this, normalized)
69
73
  : new ClientServiceHandle(this, normalized));
@@ -153,7 +157,7 @@ class ProgramRegistry extends Events {
153
157
  const waited = value;
154
158
  if (waited.event === "uninstall") {
155
159
  const payload = waited.payload;
156
- return { program: programHandle(this.system, required(payload.program)), everythingRemoved: payload.everythingRemoved === true };
160
+ return { program: programHandle(this.system, required(payload.program)), everything: payload.everything === true };
157
161
  }
158
162
  return programHandle(this.system, required(waited.payload));
159
163
  }
@@ -171,7 +175,7 @@ class ProgramHandle extends ProgramBase {
171
175
  this.snapshot = snapshot;
172
176
  bindEvents(this, new Events(["forget", "uninstall"], (event, signal, timeout) => transport(system).control({
173
177
  capability: "program", operation: "wait", input: { program: snapshot.identity, event, timeout }
174
- }, signal).then(value => value.payload)));
178
+ }, signal).then(value => programEntityEvent(event, value))));
175
179
  this.reference = snapshot.reference;
176
180
  this.identity = snapshot.identity;
177
181
  this.process = new ProgramProcesses(system, this);
@@ -182,11 +186,15 @@ class ProgramHandle extends ProgramBase {
182
186
  get description() { return this.snapshot.description; }
183
187
  get hasAgent() { return this.snapshot.hasAgent; }
184
188
  get server() {
185
- return this.snapshot.server ? Object.freeze({ start: this.snapshot.server.start }) : null;
189
+ return this.snapshot.server ? Object.freeze({
190
+ start: this.snapshot.server.start,
191
+ service: this.snapshot.server.service
192
+ }) : null;
186
193
  }
187
194
  get client() {
188
195
  return this.snapshot.client ? Object.freeze({
189
196
  start: this.snapshot.client.start,
197
+ service: this.snapshot.client.service,
190
198
  title: this.snapshot.client.title,
191
199
  size: this.snapshot.client.size,
192
200
  position: this.snapshot.client.position,
@@ -255,7 +263,7 @@ class ProgramProcesses extends Events {
255
263
  system;
256
264
  program;
257
265
  constructor(system, program) {
258
- super(["endpointStart", "endpointStop", "create", "exit"], (event, signal, timeout) => transport(system).control({
266
+ super(["create", "exit"], (event, signal, timeout) => transport(system).control({
259
267
  capability: "process", operation: "wait", input: { program: program.identity, event, timeout }
260
268
  }, signal).then(value => processEvent(system, value)));
261
269
  this.system = system;
@@ -328,7 +336,7 @@ class ProgramProcesses extends Events {
328
336
  class ProcessRegistry extends Events {
329
337
  system;
330
338
  constructor(system) {
331
- super(["endpointStart", "endpointStop", "create", "exit"], (event, signal, timeout) => transport(system).control({
339
+ super(["create", "exit"], (event, signal, timeout) => transport(system).control({
332
340
  capability: "process", operation: "wait", input: { event, timeout }
333
341
  }, signal).then(value => processEvent(system, value)));
334
342
  this.system = system;
@@ -358,9 +366,9 @@ class ProcessHandle extends ProcessBase {
358
366
  super();
359
367
  this.system = system;
360
368
  this.snapshot = snapshot;
361
- bindEvents(this, new Events(["endpointStart", "endpointStop", "exit"], (event, signal, timeout) => transport(system).control({
369
+ bindEvents(this, new Events(["exit"], (event, signal, timeout) => transport(system).control({
362
370
  capability: "process", operation: "wait", input: { process: snapshot.identity, event, timeout }
363
- }, signal).then(value => processEvent(system, value))));
371
+ }, signal).then(exactProcessEvent)));
364
372
  this.identity = snapshot.identity;
365
373
  this.name = snapshot.name;
366
374
  this.startedAt = new Date(snapshot.startedAt);
@@ -396,11 +404,12 @@ class EndpointOperations extends Events {
396
404
  const value = await this.inspect();
397
405
  return value.running;
398
406
  }
399
- async start(client) { await this.operation("start", client); }
407
+ async start(launch = {}) { await this.operation("start", launch); }
400
408
  async stop() { await this.operation("stop"); }
401
- async service() {
402
- const key = await transport(this.system).api({ capability: "endpoint", operation: "service", process: this.owner.identity, endpoint: this.endpoint });
403
- return key ? this.system.service(key) : null;
409
+ async isService() {
410
+ return await transport(this.system).api({
411
+ capability: "endpoint", operation: "isService", process: this.owner.identity, endpoint: this.endpoint
412
+ });
404
413
  }
405
414
  publish(event, payload) {
406
415
  void transport(this.system).control({ capability: "endpoint", operation: "publish", input: {
@@ -412,9 +421,9 @@ class EndpointOperations extends Events {
412
421
  process: this.owner.identity, endpoint: this.endpoint
413
422
  } });
414
423
  }
415
- async operation(operation, client) {
424
+ async operation(operation, launch) {
416
425
  await transport(this.system).control({ capability: "endpoint", operation, input: {
417
- process: this.owner.identity, endpoint: this.endpoint, ...(client ? { client } : {})
426
+ process: this.owner.identity, endpoint: this.endpoint, ...(launch ? { launch } : {})
418
427
  } });
419
428
  }
420
429
  }
@@ -434,7 +443,8 @@ class ServerEndpoint extends ServerBase {
434
443
  }
435
444
  process() { return this.base.process(); }
436
445
  exists() { return this.base.exists(); }
437
- start() { return this.base.start(); }
446
+ isService() { return this.base.isService(); }
447
+ start(launch) { return this.base.start(launch); }
438
448
  stop() { return this.base.stop(); }
439
449
  publish(event, payload) { return this.base.publish(event, payload); }
440
450
  async ask(event, payload) {
@@ -450,9 +460,6 @@ class ServerEndpoint extends ServerBase {
450
460
  async waitReady(timeout) {
451
461
  await transport(this.system).control({ capability: "endpoint", operation: "waitReady", input: { process: this.owner.identity, endpoint: "server", timeout } });
452
462
  }
453
- async service() {
454
- return await this.base.service();
455
- }
456
463
  }
457
464
  class ClientEndpoint extends ClientBase {
458
465
  endpoint = "client";
@@ -468,12 +475,10 @@ class ClientEndpoint extends ClientBase {
468
475
  }
469
476
  process() { return this.base.process(); }
470
477
  exists() { return this.base.exists(); }
471
- start(overrides) { return this.base.start(overrides); }
478
+ isService() { return this.base.isService(); }
479
+ start(launch) { return this.base.start(launch); }
472
480
  stop() { return this.base.stop(); }
473
481
  publish(event, payload) { return this.base.publish(event, payload); }
474
- async service() {
475
- return await this.base.service();
476
- }
477
482
  }
478
483
  class SystemWindow extends Events {
479
484
  system;
@@ -508,18 +513,18 @@ class SystemWindow extends Events {
508
513
  class ServiceBase {
509
514
  system;
510
515
  key;
511
- name;
512
516
  lifecycle;
513
517
  constructor(system, key) {
514
518
  this.system = system;
515
519
  this.key = key;
516
- this.lifecycle = new Events(["enable", "disable"], (event, signal, timeout) => transport(system).api({
520
+ this.lifecycle = new Events(["start", "stop"], (event, signal, timeout) => transport(system).api({
517
521
  capability: "service", operation: "wait", scope: "lifecycle", key, event, timeout
518
522
  }, signal));
519
- this.name = key.name;
520
523
  }
521
- async enabled() { return await transport(this.system).api({ capability: "service", operation: "enabled", key: this.key }); }
522
- async waitReady(timeout) { await transport(this.system).api({ capability: "service", operation: "waitReady", key: this.key, timeout }); }
524
+ async exists() { return await transport(this.system).api({ capability: "service", operation: "exists", key: this.key }); }
525
+ publish(event, payload) {
526
+ void transport(this.system).api({ capability: "service", operation: "publish", key: this.key, event, payload });
527
+ }
523
528
  }
524
529
  /** Node-SDK handle for a Service provided by a Server Endpoint. */
525
530
  export class ServerService extends CoreServerService {
@@ -528,7 +533,6 @@ export class ServerService extends CoreServerService {
528
533
  class ServerServiceHandle extends ServerService {
529
534
  system;
530
535
  key;
531
- name;
532
536
  lifecycle;
533
537
  base;
534
538
  constructor(system, key) {
@@ -536,17 +540,16 @@ class ServerServiceHandle extends ServerService {
536
540
  this.system = system;
537
541
  this.key = key;
538
542
  this.base = new ServiceBase(system, key);
539
- this.name = key.name;
540
543
  this.lifecycle = this.base.lifecycle;
541
544
  bindEvents(this, new Events([], (event, signal, timeout) => transport(system).api({
542
545
  capability: "service", operation: "wait", scope: "events", key, event, timeout
543
546
  }, signal)));
544
547
  }
545
- enabled() { return this.base.enabled(); }
546
- waitReady(timeout) { return this.base.waitReady(timeout); }
547
- publish = (event, payload) => {
548
- void transport(this.system).api({ capability: "service", operation: "publish", key: this.key, event, payload });
549
- };
548
+ exists() { return this.base.exists(); }
549
+ async waitReady(timeout) {
550
+ await transport(this.system).api({ capability: "service", operation: "waitReady", key: this.key, timeout });
551
+ }
552
+ publish = (event, payload) => this.base.publish(event, payload);
550
553
  async ask(event, payload) {
551
554
  return await transport(this.system).api({ capability: "service", operation: "ask", key: this.key, event, payload });
552
555
  }
@@ -561,20 +564,18 @@ export class ClientService extends CoreClientService {
561
564
  constructor() { super(); }
562
565
  }
563
566
  class ClientServiceHandle extends ClientService {
564
- name;
565
567
  lifecycle;
566
568
  base;
567
569
  constructor(system, key) {
568
570
  super();
569
571
  this.base = new ServiceBase(system, key);
570
- this.name = key.name;
571
572
  this.lifecycle = this.base.lifecycle;
572
573
  bindEvents(this, new Events([], (event, signal, timeout) => transport(system).api({
573
574
  capability: "service", operation: "wait", scope: "events", key, event, timeout
574
575
  }, signal)));
575
576
  }
576
- enabled() { return this.base.enabled(); }
577
- waitReady(timeout) { return this.base.waitReady(timeout); }
577
+ exists() { return this.base.exists(); }
578
+ publish = (event, payload) => this.base.publish(event, payload);
578
579
  }
579
580
  async function listProcesses(system, program) {
580
581
  const processes = [];
@@ -599,18 +600,15 @@ async function* command(system, request) {
599
600
  async function waitEndpointLifecycle(system, owner, endpoint, event, signal, timeout = 10_000) {
600
601
  if (event !== "start" && event !== "stop")
601
602
  throw new Error(`An Endpoint lifecycle has no "${event}" event`);
602
- const processEventName = event === "start" ? "endpointStart" : "endpointStop";
603
- const deadline = Date.now() + timeout;
604
- while (true) {
605
- const value = await transport(system).control({
606
- capability: "process",
607
- operation: "wait",
608
- input: { process: owner.identity, event: processEventName, timeout: Math.max(0, deadline - Date.now()) }
609
- }, signal);
610
- const changed = processEvent(system, value);
611
- if (changed === owner[endpoint])
612
- return undefined;
613
- }
603
+ await transport(system).control({
604
+ capability: "endpoint",
605
+ operation: "waitLifecycle",
606
+ input: { process: owner.identity, endpoint, event, timeout }
607
+ }, signal);
608
+ }
609
+ function programEntityEvent(event, value) {
610
+ const payload = value.payload;
611
+ return event === "uninstall" ? payload?.everything === true : undefined;
614
612
  }
615
613
  function processEvent(system, value) {
616
614
  const waited = value;
@@ -622,14 +620,20 @@ function processEvent(system, value) {
622
620
  code: payload.code,
623
621
  signal: payload.signal
624
622
  };
625
- if ((waited.event === "endpointStart" || waited.event === "endpointStop") && payload?.processSnapshot) {
626
- const process = processHandle(system, payload.processSnapshot);
627
- return payload.endpoint === "client" ? process.client : process.server;
628
- }
629
623
  if (payload && typeof payload.identity === "string")
630
624
  return processHandle(system, payload);
631
625
  return payload;
632
626
  }
627
+ function exactProcessEvent(value) {
628
+ const payload = value.payload;
629
+ if (!payload)
630
+ return payload;
631
+ return {
632
+ status: payload.status,
633
+ code: payload.code,
634
+ signal: payload.signal
635
+ };
636
+ }
633
637
  function bindEvents(target, events) {
634
638
  Object.assign(target, eventsOf(events));
635
639
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/node",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Node.js access to PhreshOS and Program projects.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -11,7 +11,11 @@
11
11
  "default": "./dist/main.js"
12
12
  }
13
13
  },
14
- "files": ["dist", "LICENSE", "README.md"],
14
+ "files": [
15
+ "dist",
16
+ "LICENSE",
17
+ "README.md"
18
+ ],
15
19
  "author": "Zohayr SLILEH",
16
20
  "license": "MIT",
17
21
  "repository": {
@@ -32,7 +36,7 @@
32
36
  "prepack": "node --run build"
33
37
  },
34
38
  "dependencies": {
35
- "@phreshos/core": "^0.1.26",
39
+ "@phreshos/core": "^0.1.29",
36
40
  "adm-zip": "^0.6.0",
37
41
  "jiti": "^2.7.0"
38
42
  },