@akala/pm 3.3.4 → 3.5.0

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/src/container.ts CHANGED
@@ -5,18 +5,20 @@ namespace commands
5
5
  {
6
6
  export interface container
7
7
  {
8
- dispatch (cmd:'connect', ...args: [Argument0<typeof import('./commands/connect').default>, Argument1<typeof import('./commands/connect').default>]): ReturnType<typeof import('./commands/connect').default>
9
- dispatch (cmd:'config', ...args: [Argument0<typeof import('./commands/config').default>, Argument1<typeof import('./commands/config').default>]): ReturnType<typeof import('./commands/config').default>
10
- dispatch (cmd:'install', ...args: [Argument0<typeof import('./commands/install').default>]): ReturnType<typeof import('./commands/install').default>
11
8
  dispatch (cmd:'$init', ...args: [Argument1<typeof import('./commands/$init').default>]): ReturnType<typeof import('./commands/$init').default>
9
+ dispatch (cmd:'bridge', ...args: [Argument0<typeof import('./commands/bridge').default>, Argument1<typeof import('./commands/bridge').default>]): ReturnType<typeof import('./commands/bridge').default>
10
+ dispatch (cmd:'config', ...args: [Argument0<typeof import('./commands/config').default>, Argument1<typeof import('./commands/config').default>]): ReturnType<typeof import('./commands/config').default>
11
+ dispatch (cmd:'connect', ...args: [Argument0<typeof import('./commands/connect').default>, Argument1<typeof import('./commands/connect').default>]): ReturnType<typeof import('./commands/connect').default>
12
12
  dispatch (cmd:'discover', ...args: [Argument0<typeof import('./commands/discover').default>, Argument1<typeof import('./commands/discover').default>]): ReturnType<typeof import('./commands/discover').default>
13
+ dispatch (cmd:'install', ...args: [Argument0<typeof import('./commands/install').default>]): ReturnType<typeof import('./commands/install').default>
13
14
  dispatch (cmd:'link', ...args: [Argument0<typeof import('./commands/link').default>, Argument1<typeof import('./commands/link').default>]): ReturnType<typeof import('./commands/link').default>
14
- dispatch (cmd:'ls', ...args: []): ReturnType<typeof import('./commands/ls').default>
15
- dispatch (cmd:'name', ...args: [Argument0<typeof import('./commands/name').default>]): ReturnType<typeof import('./commands/name').default>
16
15
  dispatch (cmd:'log', ...args: [Argument0<typeof import('./commands/log').default>]): ReturnType<typeof import('./commands/log').default>
17
- dispatch (cmd:'reload-metadata', ...args: [Argument0<typeof import('./commands/reload-metadata').default>]): ReturnType<typeof import('./commands/reload-metadata').default>
16
+ dispatch (cmd:'ls', ...args: []): ReturnType<typeof import('./commands/ls').default>
18
17
  dispatch (cmd:'map', ...args: [Argument0<typeof import('./commands/map').default>, Argument1<typeof import('./commands/map').default>, Argument2<typeof import('./commands/map').default>, Argument3<typeof import('./commands/map').default>]): ReturnType<typeof import('./commands/map').default>
18
+ dispatch (cmd:'name', ...args: [Argument0<typeof import('./commands/name').default>]): ReturnType<typeof import('./commands/name').default>
19
+ dispatch (cmd:'proxy', ...args: [Argument0<typeof import('./commands/proxy').default>, Argument1<typeof import('./commands/proxy').default>]): ReturnType<typeof import('./commands/proxy').default>
19
20
  dispatch (cmd:'ready', ...args: []): ReturnType<typeof import('./commands/ready').default>
21
+ dispatch (cmd:'reload-metadata', ...args: [Argument0<typeof import('./commands/reload-metadata').default>]): ReturnType<typeof import('./commands/reload-metadata').default>
20
22
  dispatch (cmd:'start', ...args: [Argument1<typeof import('./commands/start').default>, Argument2<typeof import('./commands/start').default>]): ReturnType<typeof import('./commands/start').default>
21
23
  dispatch (cmd:'status', ...args: [Argument0<typeof import('./commands/status').default>]): ReturnType<typeof import('./commands/status').default>
22
24
  dispatch (cmd:'stop', ...args: [Argument0<typeof import('./commands/stop').default>]): ReturnType<typeof import('./commands/stop').default>
@@ -25,18 +27,20 @@ namespace commands
25
27
  }
26
28
  export interface proxy
27
29
  {
28
- 'connect'(...args: [Argument0<typeof import('./commands/connect').default>, Argument1<typeof import('./commands/connect').default>]): ReturnType<typeof import('./commands/connect').default>
29
- 'config'(...args: [Argument0<typeof import('./commands/config').default>, Argument1<typeof import('./commands/config').default>]): ReturnType<typeof import('./commands/config').default>
30
- 'install'(...args: [Argument0<typeof import('./commands/install').default>]): ReturnType<typeof import('./commands/install').default>
31
30
  '$init'(...args: [Argument1<typeof import('./commands/$init').default>]): ReturnType<typeof import('./commands/$init').default>
31
+ 'bridge'(...args: [Argument0<typeof import('./commands/bridge').default>, Argument1<typeof import('./commands/bridge').default>]): ReturnType<typeof import('./commands/bridge').default>
32
+ 'config'(...args: [Argument0<typeof import('./commands/config').default>, Argument1<typeof import('./commands/config').default>]): ReturnType<typeof import('./commands/config').default>
33
+ 'connect'(...args: [Argument0<typeof import('./commands/connect').default>, Argument1<typeof import('./commands/connect').default>]): ReturnType<typeof import('./commands/connect').default>
32
34
  'discover'(...args: [Argument0<typeof import('./commands/discover').default>, Argument1<typeof import('./commands/discover').default>]): ReturnType<typeof import('./commands/discover').default>
35
+ 'install'(...args: [Argument0<typeof import('./commands/install').default>]): ReturnType<typeof import('./commands/install').default>
33
36
  'link'(...args: [Argument0<typeof import('./commands/link').default>, Argument1<typeof import('./commands/link').default>]): ReturnType<typeof import('./commands/link').default>
34
- 'ls'(...args: []): ReturnType<typeof import('./commands/ls').default>
35
- 'name'(...args: [Argument0<typeof import('./commands/name').default>]): ReturnType<typeof import('./commands/name').default>
36
37
  'log'(...args: [Argument0<typeof import('./commands/log').default>]): ReturnType<typeof import('./commands/log').default>
37
- 'reload-metadata'(...args: [Argument0<typeof import('./commands/reload-metadata').default>]): ReturnType<typeof import('./commands/reload-metadata').default>
38
+ 'ls'(...args: []): ReturnType<typeof import('./commands/ls').default>
38
39
  'map'(...args: [Argument0<typeof import('./commands/map').default>, Argument1<typeof import('./commands/map').default>, Argument2<typeof import('./commands/map').default>, Argument3<typeof import('./commands/map').default>]): ReturnType<typeof import('./commands/map').default>
40
+ 'name'(...args: [Argument0<typeof import('./commands/name').default>]): ReturnType<typeof import('./commands/name').default>
41
+ 'proxy'(...args: [Argument0<typeof import('./commands/proxy').default>, Argument1<typeof import('./commands/proxy').default>]): ReturnType<typeof import('./commands/proxy').default>
39
42
  'ready'(...args: []): ReturnType<typeof import('./commands/ready').default>
43
+ 'reload-metadata'(...args: [Argument0<typeof import('./commands/reload-metadata').default>]): ReturnType<typeof import('./commands/reload-metadata').default>
40
44
  'start'(...args: [Argument1<typeof import('./commands/start').default>, Argument2<typeof import('./commands/start').default>]): ReturnType<typeof import('./commands/start').default>
41
45
  'status'(...args: [Argument0<typeof import('./commands/status').default>]): ReturnType<typeof import('./commands/status').default>
42
46
  'stop'(...args: [Argument0<typeof import('./commands/stop').default>]): ReturnType<typeof import('./commands/stop').default>
package/src/fork.ts CHANGED
@@ -4,12 +4,13 @@ sms.install();
4
4
  import * as path from 'path'
5
5
  import * as ac from '@akala/commands';
6
6
  import { lstat } from 'fs/promises';
7
- import { IpcAdapter } from './commands/start';
7
+ import { IpcAdapter } from "./ipc-adapter";
8
8
  import { Socket } from 'net';
9
9
  import { logger, Logger, module as coreModule } from '@akala/core';
10
10
  import program, { buildCliContextFromProcess, NamespaceMiddleware } from '@akala/cli';
11
11
  import { Stats } from 'fs';
12
- import { registerCommands } from '@akala/commands';
12
+ import { registerCommands, SelfDefinedCommand } from '@akala/commands';
13
+ import { parseMetadata } from '@akala/commands/src/serve-metadata';
13
14
 
14
15
  var isPm = false;
15
16
 
@@ -25,7 +26,7 @@ let folderOrFile: Stats;
25
26
  let cliContainer: ac.Container<unknown>;
26
27
  let processor: ac.CommandProcessor;
27
28
  let log: Logger;
28
- const logMiddleware = new NamespaceMiddleware<{ program: string, name: string }>(null).option<string, 'verbose'>('verbose', { aliases: ['v',] });
29
+ const logMiddleware = new NamespaceMiddleware<{ program: string, name: string, tls: boolean }>(null).option<string, 'verbose'>('verbose', { aliases: ['v',] });
29
30
  logMiddleware.preAction(async c =>
30
31
  {
31
32
  if (c.options.verbose)
@@ -37,8 +38,8 @@ logMiddleware.preAction(async c =>
37
38
 
38
39
  await ac.Processors.FileSystem.discoverCommands(c.options.program, cliContainer, { processor: processor, isDirectory: folderOrFile.isDirectory() });
39
40
  });
40
- const initMiddleware = new NamespaceMiddleware<{ program: string, name: string }>(null);
41
- program.option<string, 'program'>('program', { needsValue: true }).option<string, 'name'>('name', { needsValue: true }).
41
+ const initMiddleware = new NamespaceMiddleware<{ program: string, name: string, tls: boolean }>(null);
42
+ program.option<string, 'program'>('program', { needsValue: true }).option<string, 'name'>('name', { needsValue: true }).option<boolean, 'tls'>('tls', { needsValue: false }).
42
43
  use(async c => //If pure js file
43
44
  {
44
45
  folderOrFile = await lstat(c.options.program);
@@ -71,7 +72,10 @@ program.option<string, 'program'>('program', { needsValue: true }).option<string
71
72
 
72
73
  initMiddleware.option<string, 'pmSocket'>('pmSocket', { aliases: ['pm-socket', 'pm-sock'] }).action(async c =>
73
74
  {
75
+
74
76
  let pm: ac.Container<unknown>;
77
+ let pmConnectInfo: ac.ServeMetadata;
78
+
75
79
  if (!isPm)
76
80
  {
77
81
  if (process.connected)
@@ -81,25 +85,27 @@ program.option<string, 'program'>('program', { needsValue: true }).option<string
81
85
  else
82
86
  {
83
87
  const pmSocket = new Socket();
84
- await new Promise<void>((resolve, reject) =>
85
- {
86
- pmSocket.on('error', reject)
87
- const remote = /^(?:([^:]+):)?(\d+)$/.exec(c.options.pmSocket);
88
- if (!remote)
89
- {
90
- pmSocket.connect(c.options.pmSocket, resolve);
91
- }
92
- else
93
- {
94
- const host = remote[1];
95
- const port = remote[2];
96
- if (host)
97
- pmSocket.connect(Number(port), host, resolve);
98
- else
99
- pmSocket.connect(Number(port), resolve);
100
- }
101
- })
102
- pm = new ac.Container('pm', null, new ac.Processors.JsonRpc(ac.Processors.JsonRpc.getConnection(new ac.NetSocketAdapter(pmSocket), cliContainer), true));
88
+ const x = await ac.connectByPreference(pmConnectInfo = parseMetadata(c.options.pmSocket, c.options.tls), { container: cliContainer });
89
+ pm = x.container;
90
+ // await new Promise<void>((resolve, reject) =>
91
+ // {
92
+ // pmSocket.on('error', reject)
93
+ // const remote = /^(?:([^:]+):)?(\d+)$/.exec(c.options.pmSocket);
94
+ // if (!remote)
95
+ // {
96
+ // pmSocket.connect(c.options.pmSocket, resolve);
97
+ // }
98
+ // else
99
+ // {
100
+ // const host = remote[1];
101
+ // const port = remote[2];
102
+ // if (host)
103
+ // pmSocket.connect(Number(port), host, resolve);
104
+ // else
105
+ // pmSocket.connect(Number(port), resolve);
106
+ // }
107
+ // })
108
+ // pm = new ac.Container('pm', null, new ac.Processors.JsonRpc(ac.Processors.JsonRpc.getConnection(new ac.NetSocketAdapter(pmSocket), cliContainer), true));
103
109
  }
104
110
  // eslint-disable-next-line @typescript-eslint/no-var-requires
105
111
  registerCommands(require('../commands.json').commands.map(ac.Metadata.extractCommandMetadata), null, pm);
@@ -112,6 +118,15 @@ program.option<string, 'program'>('program', { needsValue: true }).option<string
112
118
 
113
119
  coreModule('@akala/pm').register('container', pm);
114
120
 
121
+ cliContainer.register(new SelfDefinedCommand(async (connectionId: string) =>
122
+ {
123
+ if (!pmConnectInfo)
124
+ pmConnectInfo = await pm.dispatch('connect', 'pm');
125
+ var pm2 = await ac.connectByPreference(pmConnectInfo, { container: cliContainer });
126
+ await pm2.container.dispatch('bridge', connectionId);
127
+ }, '$bridge'));
128
+
129
+
115
130
  if (init)
116
131
  await cliContainer.dispatch(init, { options: c.options, param: c.args, _trigger: 'cli', pm: pm, context: c });
117
132
 
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { connectByPreference, Container, Metadata, NetSocketAdapter, Processors, registerCommands, ServeMetadata, ConnectionPreference, Cli } from "@akala/commands";
1
+ import { Container, Metadata, NetSocketAdapter, Processors, registerCommands, ServeMetadata, ConnectionPreference, Cli } from "@akala/commands";
2
2
  import { Socket } from "net";
3
3
  import { module } from "@akala/core";
4
4
 
@@ -54,57 +54,9 @@ export function connect(name: string): Promise<{ connect: Promise<ServeMetadata>
54
54
  })();
55
55
  }
56
56
 
57
- const defaultOrders: (keyof ServeMetadata)[] = ['ssocket', 'socket', 'wss', 'ws'];
57
+ export const defaultOrders: (keyof ServeMetadata)[] = ['ssocket', 'socket', 'wss', 'ws'];
58
58
 
59
- type SideCarConnectionPreference = { [key in keyof SidecarMap]?: Partial<ConnectionPreference> & { orders?: (keyof ServeMetadata)[] } };
60
-
61
- export function sidecar(options?: Omit<ConnectionPreference, 'metadata'> | SideCarConnectionPreference | Omit<ConnectionPreference, 'metadata'> & SideCarConnectionPreference, noCache?: boolean): Sidecar
62
- {
63
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
- return new Proxy<Sidecar>({} as any, {
65
- get(target, property)
66
- {
67
- if (typeof (property) !== 'string')
68
- return Reflect.get(target, property);
69
-
70
- const orders = options && options[property] && options[property].orders || defaultOrders;
71
- if (!options)
72
- options = {};
73
- if (typeof options.preferRemote == 'undefined')
74
- options.preferRemote = !process.connected;
75
- if (noCache || typeof (target[property]) == 'undefined')
76
- Object.defineProperty(target, property, {
77
- value: connect(property).then(async meta =>
78
- {
79
- try
80
- {
81
- const c = await connectByPreference(await meta.connect, Object.assign({ metadata: meta.container }, options, options && options[property]), ...orders);
82
- return c.container;
83
- }
84
- catch (e)
85
- {
86
- if (e && e.statusCode == 404 || !meta.connect)
87
- {
88
- var c = new Container(meta.container.name, null, module('@akala/pm').resolve('container').processor);
89
- c.processor.useMiddleware(1, {
90
- handle(origin, cmd, param)
91
- {
92
- if (cmd.name.startsWith(meta.container.name + '.'))
93
- return undefined;
94
- return c.processor.handle(origin, Object.assign({}, cmd, { name: meta.container.name + '.' + cmd.name }), param);
95
- }
96
- });
97
- meta.container.commands.forEach(cmd => c.register(cmd));
98
- return c;
99
- }
100
- throw e;
101
- }
102
- })
103
- });
104
- return target[property];
105
- }
106
- });
107
- }
59
+ export type SideCarConnectionPreference = { [key in keyof SidecarMap]?: Partial<ConnectionPreference> & { orders?: (keyof ServeMetadata)[] } };
108
60
 
109
61
  export interface ContainerLite
110
62
  {
@@ -119,5 +71,8 @@ export interface SidecarMap
119
71
  pm: pmContainer
120
72
  }
121
73
 
74
+
122
75
  import getRandomName from './commands/name';
76
+ import sidecarSingleton, { sidecar } from "./sidecar";
77
+ export { sidecar, sidecarSingleton };
123
78
  export { getRandomName };
@@ -0,0 +1,65 @@
1
+ import { ChildProcess } from "child_process";
2
+ import * as jsonrpc from '@akala/json-rpc-ws';
3
+ import { SocketAdapterEventMap } from "@akala/json-rpc-ws";
4
+
5
+
6
+ export class IpcAdapter implements jsonrpc.SocketAdapter
7
+ {
8
+ get open(): boolean { return !!this.cp.pid; }
9
+
10
+
11
+ pipe(socket: jsonrpc.SocketAdapter<unknown>)
12
+ {
13
+ this.on('message', (message) => socket.send(message));
14
+ this.on('close', () => socket.close());
15
+ }
16
+
17
+ close(): void
18
+ {
19
+ this.cp.disconnect();
20
+ }
21
+ send(data: string): void
22
+ {
23
+ if (this.cp.send)
24
+ this.cp.send(data + '\n');
25
+
26
+ else
27
+ console.warn(`process ${this.cp.pid} does not support send over IPC`);
28
+ }
29
+ on<K extends keyof SocketAdapterEventMap>(event: K, handler: (ev: SocketAdapterEventMap[K]) => void): void
30
+ {
31
+ switch (event)
32
+ {
33
+ case 'message':
34
+ this.cp.on('message', handler);
35
+ break;
36
+ case 'open':
37
+ handler(null);
38
+ break;
39
+ case 'close':
40
+ this.cp.on('disconnect', handler);
41
+ break;
42
+ }
43
+ }
44
+
45
+ once<K extends keyof SocketAdapterEventMap>(event: K, handler: (ev: SocketAdapterEventMap[K]) => void): void
46
+ {
47
+ switch (event)
48
+ {
49
+ case 'message':
50
+ this.cp.once('message', handler);
51
+ break;
52
+ case 'open':
53
+ handler(null);
54
+ break;
55
+ case 'close':
56
+ this.cp.once('disconnect', () => handler(null));
57
+ break;
58
+ }
59
+ }
60
+
61
+ constructor(private cp: ChildProcess | NodeJS.Process)
62
+ {
63
+ }
64
+
65
+ }
package/src/sidecar.ts ADDED
@@ -0,0 +1,54 @@
1
+ import { connectByPreference, Container, ConnectionPreference, registerCommands } from "@akala/commands";
2
+ import { module } from "@akala/core";
3
+ import { SideCarConnectionPreference, Sidecar, defaultOrders, connect } from "./index";
4
+
5
+ let instance: Sidecar;
6
+
7
+ export default function (options?: Omit<ConnectionPreference, 'metadata'> | SideCarConnectionPreference | Omit<ConnectionPreference, 'metadata'> & SideCarConnectionPreference, noCache?: boolean): Sidecar
8
+ {
9
+ return instance || (instance = sidecar(options, noCache));
10
+ }
11
+
12
+ export function sidecar(options?: Omit<ConnectionPreference, 'metadata'> | SideCarConnectionPreference | Omit<ConnectionPreference, 'metadata'> & SideCarConnectionPreference, noCache?: boolean): Sidecar
13
+ {
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ return new Proxy<Sidecar>({} as any, {
16
+ get(target, property)
17
+ {
18
+ if (typeof (property) !== 'string')
19
+ return Reflect.get(target, property);
20
+
21
+ const orders = options && options[property] && options[property].orders || defaultOrders;
22
+ if (!options)
23
+ options = {};
24
+ if (typeof options.preferRemote == 'undefined')
25
+ options.preferRemote = !process.connected;
26
+ if (noCache || typeof (target[property]) == 'undefined')
27
+ Object.defineProperty(target, property, {
28
+ value: connect(property).then(async (meta) =>
29
+ {
30
+ try
31
+ {
32
+ const c = await connectByPreference(await meta.connect, Object.assign({ metadata: meta.container }, options, options && options[property]), ...orders);
33
+ return c.container;
34
+ }
35
+ catch (e)
36
+ {
37
+ if (e && e.statusCode == 404 || !meta.connect)
38
+ {
39
+ return await connect('pm').then(async (meta) =>
40
+ {
41
+ const c = await connectByPreference(await meta.connect, Object.assign({ metadata: meta.container }, options, options && options[property]), ...orders);
42
+ await c.container.dispatch('proxy', property);
43
+ registerCommands((await c.container.dispatch('$metadata', true)).commands, c.processor, c.container);
44
+ return c.container;
45
+ });
46
+ }
47
+ throw e;
48
+ }
49
+ })
50
+ });
51
+ return target[property];
52
+ }
53
+ });
54
+ }
package/src/state.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Container } from "@akala/commands";
2
2
  import { ChildProcess } from "child_process";
3
- import { Deferred, SerializableObject } from "@akala/json-rpc-ws";
3
+ import { Deferred, SerializableObject, SocketAdapter } from "@akala/json-rpc-ws";
4
4
  import { ServeMetadata } from "@akala/commands";
5
5
  import Configuration, { ProxyConfiguration } from "@akala/config";
6
6
 
@@ -9,6 +9,7 @@ export default interface State
9
9
  processes: { [key: string]: RunningContainer };
10
10
  isDaemon: boolean;
11
11
  config: ProxyConfiguration<StateConfiguration>
12
+ bridges: { [key: string]: SocketAdapter }
12
13
  }
13
14
 
14
15
  export interface StateConfiguration