@interopio/gateway-server 0.6.1-beta → 0.7.0-beta

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/changelog.md CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  # Change Log
4
4
 
5
+ ## 0.7.0-beta (2025-07-24)
6
+
7
+ ### Added
8
+ - web server api
9
+ - embeded broker in gateway-ent compat
10
+
11
+ ### Changed
12
+ - upgrade `ws` to 8.18.3
13
+ - upgrade `@interopio/gateway` to 0.11.1-beta
14
+ - updated @glue42/gateway-ent types from 3.1.3
15
+ - **BREAKING** mesh auto config removed. will be going to io.Bridge
16
+
17
+ ### Fixed
18
+ - min engine set in package.json
19
+
20
+ ## 0.6.2-beta (2025-07-19)
21
+
22
+ ### Fixed
23
+ - announce response failure (regression)
24
+
5
25
  ## 0.6.1-beta (2025-07-18)
6
26
 
7
27
  ### Fixed
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -17,11 +20,155 @@ var __copyProps = (to, from, except, desc) => {
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
22
 
23
+ // src/logger.ts
24
+ function getLogger(name) {
25
+ return import_gateway.IOGateway.Logging.getLogger(`gateway.server.${name}`);
26
+ }
27
+ var import_gateway;
28
+ var init_logger = __esm({
29
+ "src/logger.ts"() {
30
+ "use strict";
31
+ import_gateway = require("@interopio/gateway");
32
+ }
33
+ });
34
+
35
+ // src/mesh/ws/broker/core.ts
36
+ var core_exports = {};
37
+ __export(core_exports, {
38
+ default: () => core_default
39
+ });
40
+ function broadcastNodeAdded(nodes, newSocket, newNodeId) {
41
+ Object.entries(nodes.nodes).forEach(([nodeId, socket]) => {
42
+ if (nodeId !== newNodeId) {
43
+ newSocket.send(codec.encode({ type: "node-added", "node-id": newNodeId, "new-node": nodeId }));
44
+ socket.send(codec.encode({ type: "node-added", "node-id": nodeId, "new-node": newNodeId }));
45
+ }
46
+ });
47
+ }
48
+ function broadcastNodeRemoved(nodes, removedNodeId) {
49
+ Object.entries(nodes.nodes).forEach(([nodeId, socket]) => {
50
+ if (nodeId !== removedNodeId) {
51
+ socket.send(codec.encode({ type: "node-removed", "node-id": nodeId, "removed-node": removedNodeId }));
52
+ }
53
+ });
54
+ }
55
+ function onOpen(connectedNodes, key) {
56
+ logger.info(`[${key}] connection accepted`);
57
+ }
58
+ function onClose(connectedNodes, key, code, reason) {
59
+ logger.info(`[${key}] connected closed [${code}](${reason})`);
60
+ const nodeIds = connectedNodes.sockets[key];
61
+ if (nodeIds) {
62
+ delete connectedNodes.sockets[key];
63
+ for (const nodeId of nodeIds) {
64
+ delete connectedNodes.nodes[nodeId];
65
+ }
66
+ for (const nodeId of nodeIds) {
67
+ broadcastNodeRemoved(connectedNodes, nodeId);
68
+ }
69
+ }
70
+ }
71
+ function processMessage(connectedNodes, socket, key, msg) {
72
+ switch (msg.type) {
73
+ case "hello": {
74
+ const nodeId = msg["node-id"];
75
+ connectedNodes.nodes[nodeId] = socket;
76
+ connectedNodes.sockets[key] = connectedNodes.sockets[key] ?? [];
77
+ connectedNodes.sockets[key].push(nodeId);
78
+ logger.info(`[${key}] node ${nodeId} added.`);
79
+ broadcastNodeAdded(connectedNodes, socket, nodeId);
80
+ break;
81
+ }
82
+ case "bye": {
83
+ const nodeId = msg["node-id"];
84
+ delete connectedNodes[nodeId];
85
+ logger.info(`[${key}] node ${nodeId} removed.`);
86
+ broadcastNodeRemoved(connectedNodes, nodeId);
87
+ break;
88
+ }
89
+ case "data": {
90
+ const sourceNodeId = msg.from;
91
+ const targetNodeId = msg.to;
92
+ if ("all" === targetNodeId) {
93
+ Object.entries(connectedNodes.nodes).forEach(([nodeId, socket2]) => {
94
+ if (nodeId !== sourceNodeId) {
95
+ socket2.send(codec.encode(msg));
96
+ }
97
+ });
98
+ } else {
99
+ const socket2 = connectedNodes.nodes[targetNodeId];
100
+ if (socket2) {
101
+ socket2.send(codec.encode(msg));
102
+ } else {
103
+ logger.warn(`unable to send to node ${targetNodeId} message ${JSON.stringify(msg)}`);
104
+ }
105
+ }
106
+ break;
107
+ }
108
+ default: {
109
+ logger.warn(`[${key}] ignoring unknown message ${JSON.stringify(msg)}`);
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ function onMessage(connectedNodes, socket, key, msg) {
115
+ try {
116
+ const decoded = codec.decode(msg);
117
+ if (logger.enabledFor("debug")) {
118
+ logger.debug(`[${key}] processing msg ${JSON.stringify(decoded)}`);
119
+ }
120
+ processMessage(connectedNodes, socket, key, decoded);
121
+ } catch (ex) {
122
+ logger.error(`[${key}] unable to process message`, ex);
123
+ }
124
+ }
125
+ async function create(environment) {
126
+ const connectedNodes = { nodes: {}, sockets: {} };
127
+ logger.info(`mesh server is listening`);
128
+ return async (socket, handshake) => {
129
+ const key = handshake.logPrefix;
130
+ onOpen(connectedNodes, key);
131
+ socket.on("error", (err) => {
132
+ logger.error(`[${key}] websocket error: ${err}`, err);
133
+ });
134
+ socket.on("message", (data, isBinary) => {
135
+ if (Array.isArray(data)) {
136
+ data = Buffer.concat(data);
137
+ }
138
+ onMessage(connectedNodes, socket, key, data);
139
+ });
140
+ socket.on("close", (code, reason) => {
141
+ onClose(connectedNodes, key, code, reason);
142
+ });
143
+ };
144
+ }
145
+ var import_gateway2, GatewayEncoders, logger, codec, core_default;
146
+ var init_core = __esm({
147
+ "src/mesh/ws/broker/core.ts"() {
148
+ "use strict";
149
+ init_logger();
150
+ import_gateway2 = require("@interopio/gateway");
151
+ GatewayEncoders = import_gateway2.IOGateway.Encoding;
152
+ logger = getLogger("mesh.ws.broker");
153
+ codec = GatewayEncoders.transit({
154
+ keywordize: /* @__PURE__ */ new Map([
155
+ ["/type", "*"],
156
+ ["/message/body/type", "*"],
157
+ ["/message/origin", "*"],
158
+ ["/message/receiver/type", "*"],
159
+ ["/message/source/type", "*"],
160
+ ["/message/body/type", "*"]
161
+ ])
162
+ });
163
+ core_default = create;
164
+ }
165
+ });
166
+
20
167
  // src/gateway/ent/index.ts
21
168
  var index_exports = {};
22
169
  __export(index_exports, {
23
170
  configure_logging: () => configure_logging,
24
- create: () => create
171
+ create: () => create2
25
172
  });
26
173
  module.exports = __toCommonJS(index_exports);
27
174
 
@@ -236,7 +383,7 @@ function toCluster(legacy) {
236
383
  function toMeshConfig(legacy) {
237
384
  const mesh = {};
238
385
  if (legacy?.configuration?.node_id) mesh.node = legacy.configuration.node_id;
239
- if (legacy?.type === "broker") mesh.broker = { endpoint: legacy.broker.endpoint };
386
+ if (legacy?.type === "broker") mesh.broker = { endpoint: legacy.broker?.endpoint ?? "<unresolved>" };
240
387
  if (legacy?.type === "p2p") {
241
388
  const cluster = toCluster(legacy.p2p);
242
389
  if (cluster) {
@@ -264,7 +411,7 @@ function toAuthenticationConfig(legacy) {
264
411
  function toServerConfig(config) {
265
412
  const gateway = {
266
413
  route: config.route,
267
- limits: config.limits,
414
+ maxConnections: config.limits?.max_connections,
268
415
  origins: config.security?.origin_filters,
269
416
  authorize: config["authorize"] ?? { access: "permitted" },
270
417
  clients: config["clients"] ?? { inactive_seconds: 0, buffer_size: 100 },
@@ -312,17 +459,34 @@ function toServerConfig(config) {
312
459
  port: config.port ?? 3434,
313
460
  host: config.ip ?? config["host"],
314
461
  memory: config["memory"],
462
+ app: async (configurer) => {
463
+ if (config.cluster?.embedded_broker?.enabled === true) {
464
+ configurer.socket({
465
+ path: config.cluster.embedded_broker.route ?? "/mesh-broker",
466
+ options: {
467
+ authorize: config.cluster.embedded_broker["authorize"] ?? { access: "permitted" }
468
+ },
469
+ factory: async (env) => {
470
+ if (gateway.mesh?.broker?.endpoint === "<unresolved>") {
471
+ gateway.mesh.broker.endpoint = env.endpoint;
472
+ }
473
+ const delegate = (await Promise.resolve().then(() => (init_core(), core_exports))).default;
474
+ return await delegate(env);
475
+ }
476
+ });
477
+ }
478
+ },
315
479
  gateway
316
480
  };
317
481
  }
318
482
 
319
483
  // src/gateway/ent/index.ts
320
- var import_gateway = require("@interopio/gateway");
321
- function create(config) {
484
+ var import_gateway3 = require("@interopio/gateway");
485
+ function create2(config) {
322
486
  return new ServerDelegate(toServerConfig(config));
323
487
  }
324
488
  function configure_logging(config) {
325
- import_gateway.IOGateway.Logging.configure(toLogConfig(config));
489
+ import_gateway3.IOGateway.Logging.configure(toLogConfig(config));
326
490
  }
327
491
  // Annotate the CommonJS export names for ESM import in node:
328
492
  0 && (module.exports = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/gateway/ent/index.ts", "../src/gateway/ent/logging.ts", "../src/gateway/ent/server.ts", "../src/gateway/ent/config.ts"],
4
- "sourcesContent": ["import {toLogConfig} from './logging.js';\nimport {ServerDelegate} from './server.js';\nimport {toServerConfig} from './config.js';\nimport {\n Gateway,\n GatewayConfig,\n LogInfo,\n LogLevel\n} from '../../../types/gateway-ent';\nimport {IOGateway} from '@interopio/gateway';\n\nexport function create(config: GatewayConfig): Gateway {\n return new ServerDelegate(toServerConfig(config));\n}\n\nexport function configure_logging(config?: { level: LogLevel, appender?: (info: LogInfo) => void }) {\n IOGateway.Logging.configure(toLogConfig(config));\n}\n", "import {LogInfo, LogLevel} from '@interopio/gateway-server/gateway-ent';\nimport {IOGateway} from '@interopio/gateway';\nimport {format} from 'node:util';\n\nclass LogInfoAdapter implements LogInfo {\n private _parsed?: { err?: Error, msg: string };\n private _timestamp?: string;\n private _output?: string;\n\n constructor(private readonly event: IOGateway.Logging.LogEvent) {\n }\n\n private parsed(): { err?: Error, msg: string } {\n if (this._parsed === undefined) {\n let err: Error | undefined = undefined;\n let vargs = this.event.data;\n if (this.event.data[0] instanceof Error) {\n err = this.event.data[0];\n vargs = vargs.slice(1);\n }\n const msg = format(this.event.message, ...vargs);\n this._parsed = {err, msg};\n }\n return this._parsed;\n }\n\n get time(): Date {\n return this.event.time;\n }\n\n get level(): LogLevel {\n return this.event.level;\n }\n\n get namespace() {\n return this.event.name;\n }\n\n get file(): string {\n return undefined as unknown as string;\n }\n\n get line(): number {\n return undefined as unknown as number;\n }\n\n get message(): string {\n return this.parsed().msg;\n }\n\n get stacktrace(): Error | undefined {\n return this.parsed().err;\n }\n\n private get timestamp(): string {\n if (this._timestamp === undefined) {\n this._timestamp = this.time.toISOString();\n }\n return this._timestamp;\n }\n\n get output(): string {\n if (this._output === undefined) {\n const err = this.parsed().err;\n const stacktrace = err ? `\\n${err.stack ?? err}` : '';\n this._output = `${this.timestamp} ${this.level.toUpperCase()} [${this.namespace}] - ${this.message}${stacktrace}`;\n }\n return this._output;\n }\n}\n\nexport function toLogConfig(config?: { level?: LogLevel; appender?: (info: LogInfo) => void }): IOGateway.Logging.LogConfig {\n let level: Exclude<LogLevel, 'report' | 'fatal'> = 'info';\n if (config?.level) {\n if (config.level === 'fatal') {\n level = 'error';\n } else if (config.level !== 'report') {\n level = config.level;\n }\n }\n const result: IOGateway.Logging.LogConfig = {level};\n const appenderFn = config?.appender;\n if (appenderFn) {\n result.appender = (event: IOGateway.Logging.LogEvent) => {\n appenderFn(new LogInfoAdapter(event));\n };\n }\n return result;\n}\n", "import {Gateway, GatewayClient, GatewayMessage} from '@interopio/gateway-server/gateway-ent';\nimport {GatewayServer} from '@interopio/gateway-server';\n\nexport class ServerDelegate implements Gateway {\n private server?: GatewayServer.Server;\n\n constructor(private readonly config: GatewayServer.ServerConfig) {\n }\n\n async connect(cb: (client: GatewayClient, msg: GatewayMessage) => void): Promise<GatewayClient> {\n if (!this.server) {\n throw new Error(`not started`);\n }\n const client = await this.server.gateway.connect((c, m) => cb(c as unknown as GatewayClient, m as GatewayMessage));\n return client as unknown as GatewayClient;\n }\n\n info(): { endpoint: string } {\n return this.server?.gateway.info() as { endpoint: string };\n }\n\n async start(): Promise<Gateway> {\n if (!this.server) {\n this.server = await GatewayServer.Factory(this.config);\n }\n return this;\n }\n\n async stop(): Promise<Gateway> {\n await this.server?.close();\n delete this.server;\n return this;\n }\n}\n", "import {GatewayServer} from '../../../gateway-server';\nimport {IOGateway} from '@interopio/gateway';\nimport { GatewayConfig, MetricsPublisherConfig } from '../../../types/gateway-ent';\n\nfunction toMetricsFilters(legacy?: MetricsPublisherConfig['filters']): IOGateway.MetricFilters | undefined {\n if (legacy) {\n const publishers = legacy.publishers.map(publisher => {\n return {identity: publisher.publisher, metrics: publisher.metrics};\n });\n const non_matched = legacy['non-matched'];\n return {publishers, non_matched};\n }\n}\n\nfunction toMetricsPublisherConfig(legacy: MetricsPublisherConfig & {\n conflation?: { 'max-datapoints-repo'?: number } & MetricsPublisherConfig['conflation']\n}): IOGateway.BasicMetricsPublisherConfig {\n const filters = toMetricsFilters(legacy?.filters);\n const conflation = toConflation(legacy?.conflation);\n return {...legacy, filters, conflation};\n}\n\nfunction toConflation(legacy?: {\n 'max-datapoints-repo'?: number\n} & MetricsPublisherConfig['conflation']): IOGateway.BasicMetricsPublisherConfig['conflation'] | undefined {\n if (legacy) {\n return {interval: legacy.interval};\n }\n}\n\nfunction toMetricsConfig(legacy: GatewayConfig['metrics']): IOGateway.GatewayConfig['metrics'] {\n const metrics: IOGateway.GatewayConfig['metrics'] = {publishers: []};\n legacy?.publishers?.forEach((publisher) => {\n if (typeof publisher === 'string') {\n if (publisher === 'rest') {\n metrics.publishers.push('rest');\n if (legacy.rest) {\n const conf = {...legacy.rest};\n const userAgent = conf[\"user-agent\"];\n delete conf['user-agent'];\n const headers = {...conf.headers, ...(userAgent ? {'user-agent': userAgent} : {})};\n delete conf.headers;\n metrics.rest = {\n endpoint: conf.endpoint,\n headers: headers,\n ...toMetricsPublisherConfig(conf)\n };\n metrics.rest['publishFn'] ??= '@interopio/gateway-server/metrics/publisher/rest';\n }\n } else if (publisher === 'file') {\n metrics.publishers.push('file');\n if (legacy.file) {\n const conf = {...legacy.file};\n const status = conf['skip-status'] === undefined ? true : !conf['skip-status'];\n delete conf['skip-status'];\n metrics.file = {\n location: conf.location,\n status: status,\n ...toMetricsPublisherConfig(conf)\n };\n metrics.file['publishFn'] ??= '@interopio/gateway/metrics/publisher/file';\n }\n } else {\n // unsupported predefined type\n }\n } else {\n const configuration = {...publisher.configuration};\n const splitSize = configuration[\"split-size\"];\n delete configuration[\"split-size\"];\n const file = publisher['file'] as string;\n const custom: IOGateway.CustomMetricsPublisherConfig = {\n split_size: splitSize,\n publisher: {file, configuration},\n ...toMetricsPublisherConfig(configuration)\n }\n metrics.publishers.push(custom);\n }\n });\n if (legacy?.filters) {\n metrics.filters = toMetricsFilters(legacy?.filters);\n }\n return metrics;\n}\ntype GatewayCluster = Required<GatewayConfig>['cluster'];\ntype P2P = Required<GatewayCluster>['p2p'];\n\nfunction trimTrailingSlash(url?: string): string | undefined {\n return url?.endsWith('/') ? url.slice(0, -1) : url;\n}\n\nfunction toCluster(legacy?: P2P): IOGateway.MeshConfig['cluster'] | undefined {\n if (legacy?.directory) {\n const legacyDirectory = legacy.directory;\n const config: IOGateway.MeshConfig['cluster'] = {endpoint: legacy?.['endpoint']};\n if (legacyDirectory.type === 'rest') {\n let directory: IOGateway.RestMeshDirectoryConfig | undefined = undefined;\n if (config.endpoint === undefined) {\n config.endpoint = trimTrailingSlash(legacyDirectory.config?.directory_uri)!;\n }\n else {\n directory = {uri: trimTrailingSlash(legacyDirectory.config?.directory_uri)};\n }\n if (legacyDirectory.config?.announce_interval) {\n directory ??= {};\n directory.interval = Number(legacyDirectory.config.announce_interval);\n }\n if (directory !== undefined) {\n config.directory = directory;\n }\n return config;\n }\n else if (legacyDirectory.type === 'static') {\n config.directory = {members : legacyDirectory.members ?? []};\n return config;\n }\n }\n}\n\nfunction toMeshConfig(legacy: GatewayConfig['cluster']) {\n const mesh: IOGateway.MeshConfig = {};\n if (legacy?.configuration?.node_id) mesh.node = legacy.configuration.node_id;\n if (legacy?.type === 'broker') mesh.broker = {endpoint: legacy.broker!.endpoint!};\n if (legacy?.type === 'p2p') {\n const cluster = toCluster(legacy.p2p);\n if (cluster) {\n mesh.cluster = cluster;\n }\n }\n return mesh;\n}\n\nfunction toAuthenticationConfig(legacy: GatewayConfig['authentication']): IOGateway.AuthenticationConfig {\n const authentication: IOGateway.AuthenticationConfig & {available: string[]} = {available: []};\n if (legacy?.default) {\n authentication.default = legacy.default as string;\n }\n\n const as = legacy?.available as string[];\n as.forEach((a) => {\n if (a === 'basic' || a === 'oauth2' || legacy?.[a]?.['authenticator'] !== undefined) {\n authentication.available.push(a);\n if (legacy?.[a] !== undefined) {\n authentication[a] = legacy[a];\n }\n }\n });\n\n return authentication;\n}\nexport function toServerConfig(config: GatewayConfig): GatewayServer.ServerConfig {\n const gateway: GatewayServer.ServerConfig[\"gateway\"] = {\n route: config.route,\n limits: config.limits,\n origins: config.security?.origin_filters as GatewayServer.OriginFilters,\n authorize: config['authorize'] as GatewayServer.AuthorizationRule ?? {access: 'permitted'},\n clients: config['clients'] ?? {inactive_seconds: 0, buffer_size: 100},\n contexts: {\n lifetime: 'retained',\n visibility: [\n {context: /___channel___.+/, restrictions: 'cluster'},\n {context: /T42\\..+/, restrictions: 'local'}\n ]\n },\n methods: {\n visibility: [\n {method: /T42\\..+/, restrictions: 'local'}\n ]\n },\n peers: {\n visibility: [\n {domain: 'context', restrictions: 'cluster'},\n {domain: 'agm', restrictions: 'local'}\n ]\n },\n metrics: {publishers: []}\n };\n if (config.authentication !== undefined) {\n if (config.authentication.token_ttl) gateway.token = {ttl: config.authentication?.token_ttl as number};\n if (config.authentication.available || config.authentication.default) gateway.authentication = toAuthenticationConfig(config.authentication);\n }\n if (config['globals']) {\n gateway.globals = config['globals'];\n }\n if (config['contexts']) {\n gateway.contexts = config['contexts'];\n }\n if (config['methods']) {\n gateway.methods = config['methods'];\n }\n if (config['peers']) {\n gateway.peers = config['peers'];\n }\n if (config.cluster?.enabled) {\n gateway.mesh = toMeshConfig(config.cluster);\n\n }\n if (config.metrics?.publishers) gateway.metrics = toMetricsConfig(config.metrics);\n return {\n port: config.port ?? 3434,\n host: config.ip ?? config['host'] as string,\n memory: config['memory'],\n gateway: gateway\n };\n}\n"],
5
- "mappings": "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",
6
- "names": []
3
+ "sources": ["../src/logger.ts", "../src/mesh/ws/broker/core.ts", "../src/gateway/ent/index.ts", "../src/gateway/ent/logging.ts", "../src/gateway/ent/server.ts", "../src/gateway/ent/config.ts"],
4
+ "sourcesContent": ["import {IOGateway} from '@interopio/gateway';\nexport import Logger = IOGateway.Logging.Logger;\n\nexport default function getLogger(name: string): Logger {\n return IOGateway.Logging.getLogger(`gateway.server.${name}`);\n}\n", "import * as ws from 'ws';\nimport getLogger from '../../../logger.js';\nimport {IOGateway} from '@interopio/gateway';\nimport GatewayEncoders = IOGateway.Encoding;\n\nimport type {ServerWebSocketHandler} from '../../../../types/web/server';\n\nconst logger = getLogger('mesh.ws.broker');\n\ntype Command =\n // client to broker\n { type: 'hello', 'node-id': string }\n | { type: 'bye', 'node-id': string }\n | { type: 'data', from: string, to: 'all' | string}\n // broker to client\n | { type: 'node-added', 'node-id': string, 'new-node': string }\n | { type: 'node-removed', 'node-id': string, 'removed-node': string }\n\n ;\n\n\nfunction broadcastNodeAdded(nodes: NodeSockets, newSocket: ws.WebSocket, newNodeId: string) {\n Object.entries(nodes.nodes).forEach(([nodeId, socket]) => {\n if (nodeId !== newNodeId) {\n newSocket.send(codec.encode({type: 'node-added', 'node-id': newNodeId, \"new-node\": nodeId}));\n socket.send(codec.encode({type: 'node-added', 'node-id': nodeId, \"new-node\": newNodeId}));\n }\n });\n}\n\nfunction broadcastNodeRemoved(nodes: NodeSockets, removedNodeId: string) {\n Object.entries(nodes.nodes).forEach(([nodeId, socket]) => {\n if (nodeId !== removedNodeId) {\n socket.send(codec.encode({type: 'node-removed', 'node-id': nodeId, \"removed-node\": removedNodeId}));\n }\n });\n}\n\nfunction onOpen(connectedNodes: NodeSockets, key: string) {\n logger.info(`[${key}] connection accepted`);\n}\n\nfunction onClose(connectedNodes: NodeSockets, key: string, code: number, reason: string): void {\n logger.info(`[${key}] connected closed [${code}](${reason})`);\n const nodeIds = connectedNodes.sockets[key];\n if (nodeIds) {\n delete connectedNodes.sockets[key];\n for (const nodeId of nodeIds) {\n delete connectedNodes.nodes[nodeId];\n }\n for (const nodeId of nodeIds) {\n broadcastNodeRemoved(connectedNodes, nodeId);\n }\n }\n}\n\nfunction processMessage(connectedNodes: NodeSockets, socket: ws.WebSocket, key: string, msg: Command) {\n switch (msg.type) {\n case 'hello': {\n const nodeId = msg['node-id'];\n connectedNodes.nodes[nodeId] = socket;\n connectedNodes.sockets[key] = connectedNodes.sockets[key] ?? [];\n connectedNodes.sockets[key].push(nodeId);\n logger.info(`[${key}] node ${nodeId} added.`);\n broadcastNodeAdded(connectedNodes, socket, nodeId);\n break;\n }\n case 'bye': {\n const nodeId = msg[\"node-id\"];\n delete connectedNodes[nodeId];\n logger.info(`[${key}] node ${nodeId} removed.`);\n broadcastNodeRemoved(connectedNodes, nodeId);\n break;\n }\n case 'data': {\n const sourceNodeId = msg.from;\n const targetNodeId = msg.to;\n if ('all' === targetNodeId) {\n Object.entries(connectedNodes.nodes).forEach(([nodeId, socket]) => {\n if (nodeId !== sourceNodeId) {\n socket.send(codec.encode(msg));\n }\n });\n }\n else {\n const socket = connectedNodes.nodes[targetNodeId];\n if (socket) {\n socket.send(codec.encode(msg));\n }\n else {\n logger.warn(`unable to send to node ${targetNodeId} message ${JSON.stringify(msg)}`);\n }\n }\n break;\n }\n default: {\n logger.warn(`[${key}] ignoring unknown message ${JSON.stringify(msg)}`);\n break;\n }\n }\n}\n\nconst codec = GatewayEncoders.transit<Command>({\n keywordize: new Map<string, GatewayEncoders.KeywordizeCommand>([\n ['/type', '*'],\n ['/message/body/type', '*'],\n ['/message/origin', '*'],\n ['/message/receiver/type', '*'],\n ['/message/source/type', '*'],\n ['/message/body/type', '*'],\n ])\n});\n\nfunction onMessage(connectedNodes: NodeSockets, socket: ws.WebSocket, key: string, msg: string): void {\n try {\n const decoded = codec.decode(msg);\n if (logger.enabledFor('debug')) {\n logger.debug(`[${key}] processing msg ${JSON.stringify(decoded)}`);\n }\n processMessage(connectedNodes, socket, key, decoded);\n } catch (ex) {\n logger.error(`[${key}] unable to process message`, ex);\n }\n}\n\nclass WebsocketBroker {\n constructor(private readonly server: ws.WebSocketServer) {\n }\n\n async close() {\n this.server.close();\n }\n}\ntype NodeSockets = {nodes: {[nodeId: string]: ws.WebSocket}, sockets: {[socket: string]: string[]}};\n\nasync function create(environment: {endpoint: string}): Promise<ServerWebSocketHandler> {\n const connectedNodes: NodeSockets = {nodes: {}, sockets: {}};\n logger.info(`mesh server is listening`);\n\n return async (socket: ws.WebSocket, handshake) => {\n const key = handshake.logPrefix!;\n onOpen(connectedNodes, key);\n socket.on('error', (err: Error) => {\n logger.error(`[${key}] websocket error: ${err}`, err);\n });\n socket.on('message', (data, isBinary) => {\n if (Array.isArray(data)) {\n data = Buffer.concat(data);\n }\n onMessage(connectedNodes, socket, key, data as unknown as string);\n });\n socket.on('close', (code, reason) => {\n onClose(connectedNodes, key, code, reason as unknown as string);\n });\n };\n}\n\nexport default create;\n", "import {toLogConfig} from './logging.js';\nimport {ServerDelegate} from './server.js';\nimport {toServerConfig} from './config.js';\nimport {\n Gateway,\n GatewayConfig,\n LogInfo,\n LogLevel\n} from '../../../types/gateway-ent';\nimport {IOGateway} from '@interopio/gateway';\n\nexport function create(config: GatewayConfig): Gateway {\n return new ServerDelegate(toServerConfig(config));\n}\n\nexport function configure_logging(config?: { level: LogLevel, appender?: (info: LogInfo) => void }) {\n IOGateway.Logging.configure(toLogConfig(config));\n}\n", "import {LogInfo, LogLevel} from '@interopio/gateway-server/gateway-ent';\nimport {IOGateway} from '@interopio/gateway';\nimport {format} from 'node:util';\n\nclass LogInfoAdapter implements LogInfo {\n private _parsed?: { err?: Error, msg: string };\n private _timestamp?: string;\n private _output?: string;\n\n constructor(private readonly event: IOGateway.Logging.LogEvent) {\n }\n\n private parsed(): { err?: Error, msg: string } {\n if (this._parsed === undefined) {\n let err: Error | undefined = undefined;\n let vargs = this.event.data;\n if (this.event.data[0] instanceof Error) {\n err = this.event.data[0];\n vargs = vargs.slice(1);\n }\n const msg = format(this.event.message, ...vargs);\n this._parsed = {err, msg};\n }\n return this._parsed;\n }\n\n get time(): Date {\n return this.event.time;\n }\n\n get level(): LogLevel {\n return this.event.level;\n }\n\n get namespace() {\n return this.event.name;\n }\n\n get file(): string {\n return undefined as unknown as string;\n }\n\n get line(): number {\n return undefined as unknown as number;\n }\n\n get message(): string {\n return this.parsed().msg;\n }\n\n get stacktrace(): Error | undefined {\n return this.parsed().err;\n }\n\n private get timestamp(): string {\n if (this._timestamp === undefined) {\n this._timestamp = this.time.toISOString();\n }\n return this._timestamp;\n }\n\n get output(): string {\n if (this._output === undefined) {\n const err = this.parsed().err;\n const stacktrace = err ? `\\n${err.stack ?? err}` : '';\n this._output = `${this.timestamp} ${this.level.toUpperCase()} [${this.namespace}] - ${this.message}${stacktrace}`;\n }\n return this._output;\n }\n}\n\nexport function toLogConfig(config?: { level?: LogLevel; appender?: (info: LogInfo) => void }): IOGateway.Logging.LogConfig {\n let level: Exclude<LogLevel, 'report' | 'fatal'> = 'info';\n if (config?.level) {\n if (config.level === 'fatal') {\n level = 'error';\n } else if (config.level !== 'report') {\n level = config.level;\n }\n }\n const result: IOGateway.Logging.LogConfig = {level};\n const appenderFn = config?.appender;\n if (appenderFn) {\n result.appender = (event: IOGateway.Logging.LogEvent) => {\n appenderFn(new LogInfoAdapter(event));\n };\n }\n return result;\n}\n", "import {Gateway, GatewayClient, GatewayMessage} from '@interopio/gateway-server/gateway-ent';\nimport {GatewayServer} from '@interopio/gateway-server';\n\nexport class ServerDelegate implements Gateway {\n private server?: GatewayServer.Server;\n\n constructor(private readonly config: GatewayServer.ServerConfig) {\n }\n\n async connect(cb: (client: GatewayClient, msg: GatewayMessage) => void): Promise<GatewayClient> {\n if (!this.server) {\n throw new Error(`not started`);\n }\n const client = await this.server.gateway.connect((c, m) => cb(c as unknown as GatewayClient, m as GatewayMessage));\n return client as unknown as GatewayClient;\n }\n\n info(): { endpoint: string } {\n return this.server?.gateway.info() as { endpoint: string };\n }\n\n async start(): Promise<Gateway> {\n if (!this.server) {\n this.server = await GatewayServer.Factory(this.config);\n }\n return this;\n }\n\n async stop(): Promise<Gateway> {\n await this.server?.close();\n delete this.server;\n return this;\n }\n}\n", "import {IOGateway} from '@interopio/gateway';\nimport { GatewayConfig, MetricsPublisherConfig } from '../../../types/gateway-ent';\nimport {GatewayServer} from '../../../gateway-server';\nimport {OriginFilters} from '../../../types/web/server';\nimport {AuthorizationRule} from '../../../types/auth';\n\nfunction toMetricsFilters(legacy?: MetricsPublisherConfig['filters']): IOGateway.MetricFilters | undefined {\n if (legacy) {\n const publishers = legacy.publishers.map(publisher => {\n return {identity: publisher.publisher, metrics: publisher.metrics};\n });\n const non_matched = legacy['non-matched'];\n return {publishers, non_matched};\n }\n}\n\nfunction toMetricsPublisherConfig(legacy: MetricsPublisherConfig & {\n conflation?: { 'max-datapoints-repo'?: number } & MetricsPublisherConfig['conflation']\n}): IOGateway.BasicMetricsPublisherConfig {\n const filters = toMetricsFilters(legacy?.filters);\n const conflation = toConflation(legacy?.conflation);\n return {...legacy, filters, conflation};\n}\n\nfunction toConflation(legacy?: {\n 'max-datapoints-repo'?: number\n} & MetricsPublisherConfig['conflation']): IOGateway.BasicMetricsPublisherConfig['conflation'] | undefined {\n if (legacy) {\n return {interval: legacy.interval};\n }\n}\n\nfunction toMetricsConfig(legacy: GatewayConfig['metrics']): IOGateway.GatewayConfig['metrics'] {\n const metrics: IOGateway.GatewayConfig['metrics'] = {publishers: []};\n legacy?.publishers?.forEach((publisher) => {\n if (typeof publisher === 'string') {\n if (publisher === 'rest') {\n metrics.publishers.push('rest');\n if (legacy.rest) {\n const conf = {...legacy.rest};\n const userAgent = conf[\"user-agent\"];\n delete conf['user-agent'];\n const headers = {...conf.headers, ...(userAgent ? {'user-agent': userAgent} : {})};\n delete conf.headers;\n metrics.rest = {\n endpoint: conf.endpoint,\n headers: headers,\n ...toMetricsPublisherConfig(conf)\n };\n metrics.rest['publishFn'] ??= '@interopio/gateway-server/metrics/publisher/rest';\n }\n } else if (publisher === 'file') {\n metrics.publishers.push('file');\n if (legacy.file) {\n const conf = {...legacy.file};\n const status = conf['skip-status'] === undefined ? true : !conf['skip-status'];\n delete conf['skip-status'];\n metrics.file = {\n location: conf.location,\n status: status,\n ...toMetricsPublisherConfig(conf)\n };\n metrics.file['publishFn'] ??= '@interopio/gateway/metrics/publisher/file';\n }\n } else {\n // unsupported predefined type\n }\n } else {\n const configuration = {...publisher.configuration};\n const splitSize = configuration[\"split-size\"];\n delete configuration[\"split-size\"];\n const file = publisher['file'] as string;\n const custom: IOGateway.CustomMetricsPublisherConfig = {\n split_size: splitSize,\n publisher: {file, configuration},\n ...toMetricsPublisherConfig(configuration)\n }\n metrics.publishers.push(custom);\n }\n });\n if (legacy?.filters) {\n metrics.filters = toMetricsFilters(legacy?.filters);\n }\n return metrics;\n}\ntype GatewayCluster = Required<GatewayConfig>['cluster'];\ntype P2P = Required<GatewayCluster>['p2p'];\n\nfunction trimTrailingSlash(url?: string): string | undefined {\n return url?.endsWith('/') ? url.slice(0, -1) : url;\n}\n\nfunction toCluster(legacy?: P2P): IOGateway.MeshConfig['cluster'] | undefined {\n if (legacy?.directory) {\n const legacyDirectory = legacy.directory;\n const config: IOGateway.MeshConfig['cluster'] = {endpoint: legacy?.['endpoint']};\n if (legacyDirectory.type === 'rest') {\n let directory: IOGateway.RestMeshDirectoryConfig | undefined = undefined;\n if (config.endpoint === undefined) {\n config.endpoint = trimTrailingSlash(legacyDirectory.config?.directory_uri)!;\n }\n else {\n directory = {uri: trimTrailingSlash(legacyDirectory.config?.directory_uri)};\n }\n if (legacyDirectory.config?.announce_interval) {\n directory ??= {};\n directory.interval = Number(legacyDirectory.config.announce_interval);\n }\n if (directory !== undefined) {\n config.directory = directory;\n }\n return config;\n }\n else if (legacyDirectory.type === 'static') {\n config.directory = {members : legacyDirectory.members ?? []};\n return config;\n }\n }\n}\n\nfunction toMeshConfig(legacy: GatewayConfig['cluster']) {\n const mesh: IOGateway.MeshConfig = {};\n if (legacy?.configuration?.node_id) mesh.node = legacy.configuration.node_id;\n if (legacy?.type === 'broker') mesh.broker = {endpoint: legacy.broker?.endpoint ?? '<unresolved>'};\n if (legacy?.type === 'p2p') {\n const cluster = toCluster(legacy.p2p);\n if (cluster) {\n mesh.cluster = cluster;\n }\n }\n return mesh;\n}\n\nfunction toAuthenticationConfig(legacy: GatewayConfig['authentication']): IOGateway.AuthenticationConfig {\n const authentication: IOGateway.AuthenticationConfig & {available: string[]} = {available: []};\n if (legacy?.default) {\n authentication.default = legacy.default as string;\n }\n\n const as = legacy?.available as string[];\n as.forEach((a) => {\n if (a === 'basic' || a === 'oauth2' || legacy?.[a]?.['authenticator'] !== undefined) {\n authentication.available.push(a);\n if (legacy?.[a] !== undefined) {\n authentication[a] = legacy[a];\n }\n }\n });\n\n return authentication;\n}\nexport function toServerConfig(config: GatewayConfig): GatewayServer.ServerConfig {\n const gateway: GatewayServer.ServerConfig[\"gateway\"] = {\n route: config.route,\n maxConnections: config.limits?.max_connections,\n origins: config.security?.origin_filters as OriginFilters,\n authorize: config['authorize'] as AuthorizationRule ?? {access: 'permitted'},\n clients: config['clients'] ?? {inactive_seconds: 0, buffer_size: 100},\n contexts: {\n lifetime: 'retained',\n visibility: [\n {context: /___channel___.+/, restrictions: 'cluster'},\n {context: /T42\\..+/, restrictions: 'local'}\n ]\n },\n methods: {\n visibility: [\n {method: /T42\\..+/, restrictions: 'local'}\n ]\n },\n peers: {\n visibility: [\n {domain: 'context', restrictions: 'cluster'},\n {domain: 'agm', restrictions: 'local'}\n ]\n },\n metrics: {publishers: []}\n };\n if (config.authentication !== undefined) {\n if (config.authentication.token_ttl) gateway.token = {ttl: config.authentication?.token_ttl as number};\n if (config.authentication.available || config.authentication.default) gateway.authentication = toAuthenticationConfig(config.authentication);\n }\n if (config['globals']) {\n gateway.globals = config['globals'];\n }\n if (config['contexts']) {\n gateway.contexts = config['contexts'];\n }\n if (config['methods']) {\n gateway.methods = config['methods'];\n }\n if (config['peers']) {\n gateway.peers = config['peers'];\n }\n if (config.cluster?.enabled) {\n gateway.mesh = toMeshConfig(config.cluster);\n }\n if (config.metrics?.publishers) gateway.metrics = toMetricsConfig(config.metrics);\n return {\n port: config.port ?? 3434,\n host: config.ip ?? config['host'] as string,\n memory: config['memory'],\n app: async (configurer) => {\n if (config.cluster?.embedded_broker?.enabled === true) {\n configurer.socket({\n path: config.cluster.embedded_broker.route ?? '/mesh-broker',\n options: {\n authorize: config.cluster.embedded_broker['authorize'] as AuthorizationRule ?? {access: 'permitted'}\n },\n factory: async(env: {endpoint: string}) => {\n if (gateway.mesh?.broker?.endpoint === '<unresolved>') {\n gateway.mesh.broker.endpoint = env.endpoint;\n }\n const delegate = (await import('../../mesh/ws/broker/core.js')).default;\n return await delegate(env);\n }\n });\n }\n },\n gateway: gateway\n\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["socket", "import_gateway", "create", "import_gateway", "create"]
7
7
  }
@@ -1,3 +1,156 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/logger.ts
12
+ import { IOGateway } from "@interopio/gateway";
13
+ function getLogger(name) {
14
+ return IOGateway.Logging.getLogger(`gateway.server.${name}`);
15
+ }
16
+ var init_logger = __esm({
17
+ "src/logger.ts"() {
18
+ "use strict";
19
+ }
20
+ });
21
+
22
+ // src/mesh/ws/broker/core.ts
23
+ var core_exports = {};
24
+ __export(core_exports, {
25
+ default: () => core_default
26
+ });
27
+ import { IOGateway as IOGateway2 } from "@interopio/gateway";
28
+ function broadcastNodeAdded(nodes, newSocket, newNodeId) {
29
+ Object.entries(nodes.nodes).forEach(([nodeId, socket]) => {
30
+ if (nodeId !== newNodeId) {
31
+ newSocket.send(codec.encode({ type: "node-added", "node-id": newNodeId, "new-node": nodeId }));
32
+ socket.send(codec.encode({ type: "node-added", "node-id": nodeId, "new-node": newNodeId }));
33
+ }
34
+ });
35
+ }
36
+ function broadcastNodeRemoved(nodes, removedNodeId) {
37
+ Object.entries(nodes.nodes).forEach(([nodeId, socket]) => {
38
+ if (nodeId !== removedNodeId) {
39
+ socket.send(codec.encode({ type: "node-removed", "node-id": nodeId, "removed-node": removedNodeId }));
40
+ }
41
+ });
42
+ }
43
+ function onOpen(connectedNodes, key) {
44
+ logger.info(`[${key}] connection accepted`);
45
+ }
46
+ function onClose(connectedNodes, key, code, reason) {
47
+ logger.info(`[${key}] connected closed [${code}](${reason})`);
48
+ const nodeIds = connectedNodes.sockets[key];
49
+ if (nodeIds) {
50
+ delete connectedNodes.sockets[key];
51
+ for (const nodeId of nodeIds) {
52
+ delete connectedNodes.nodes[nodeId];
53
+ }
54
+ for (const nodeId of nodeIds) {
55
+ broadcastNodeRemoved(connectedNodes, nodeId);
56
+ }
57
+ }
58
+ }
59
+ function processMessage(connectedNodes, socket, key, msg) {
60
+ switch (msg.type) {
61
+ case "hello": {
62
+ const nodeId = msg["node-id"];
63
+ connectedNodes.nodes[nodeId] = socket;
64
+ connectedNodes.sockets[key] = connectedNodes.sockets[key] ?? [];
65
+ connectedNodes.sockets[key].push(nodeId);
66
+ logger.info(`[${key}] node ${nodeId} added.`);
67
+ broadcastNodeAdded(connectedNodes, socket, nodeId);
68
+ break;
69
+ }
70
+ case "bye": {
71
+ const nodeId = msg["node-id"];
72
+ delete connectedNodes[nodeId];
73
+ logger.info(`[${key}] node ${nodeId} removed.`);
74
+ broadcastNodeRemoved(connectedNodes, nodeId);
75
+ break;
76
+ }
77
+ case "data": {
78
+ const sourceNodeId = msg.from;
79
+ const targetNodeId = msg.to;
80
+ if ("all" === targetNodeId) {
81
+ Object.entries(connectedNodes.nodes).forEach(([nodeId, socket2]) => {
82
+ if (nodeId !== sourceNodeId) {
83
+ socket2.send(codec.encode(msg));
84
+ }
85
+ });
86
+ } else {
87
+ const socket2 = connectedNodes.nodes[targetNodeId];
88
+ if (socket2) {
89
+ socket2.send(codec.encode(msg));
90
+ } else {
91
+ logger.warn(`unable to send to node ${targetNodeId} message ${JSON.stringify(msg)}`);
92
+ }
93
+ }
94
+ break;
95
+ }
96
+ default: {
97
+ logger.warn(`[${key}] ignoring unknown message ${JSON.stringify(msg)}`);
98
+ break;
99
+ }
100
+ }
101
+ }
102
+ function onMessage(connectedNodes, socket, key, msg) {
103
+ try {
104
+ const decoded = codec.decode(msg);
105
+ if (logger.enabledFor("debug")) {
106
+ logger.debug(`[${key}] processing msg ${JSON.stringify(decoded)}`);
107
+ }
108
+ processMessage(connectedNodes, socket, key, decoded);
109
+ } catch (ex) {
110
+ logger.error(`[${key}] unable to process message`, ex);
111
+ }
112
+ }
113
+ async function create(environment) {
114
+ const connectedNodes = { nodes: {}, sockets: {} };
115
+ logger.info(`mesh server is listening`);
116
+ return async (socket, handshake) => {
117
+ const key = handshake.logPrefix;
118
+ onOpen(connectedNodes, key);
119
+ socket.on("error", (err) => {
120
+ logger.error(`[${key}] websocket error: ${err}`, err);
121
+ });
122
+ socket.on("message", (data, isBinary) => {
123
+ if (Array.isArray(data)) {
124
+ data = Buffer.concat(data);
125
+ }
126
+ onMessage(connectedNodes, socket, key, data);
127
+ });
128
+ socket.on("close", (code, reason) => {
129
+ onClose(connectedNodes, key, code, reason);
130
+ });
131
+ };
132
+ }
133
+ var GatewayEncoders, logger, codec, core_default;
134
+ var init_core = __esm({
135
+ "src/mesh/ws/broker/core.ts"() {
136
+ "use strict";
137
+ init_logger();
138
+ GatewayEncoders = IOGateway2.Encoding;
139
+ logger = getLogger("mesh.ws.broker");
140
+ codec = GatewayEncoders.transit({
141
+ keywordize: /* @__PURE__ */ new Map([
142
+ ["/type", "*"],
143
+ ["/message/body/type", "*"],
144
+ ["/message/origin", "*"],
145
+ ["/message/receiver/type", "*"],
146
+ ["/message/source/type", "*"],
147
+ ["/message/body/type", "*"]
148
+ ])
149
+ });
150
+ core_default = create;
151
+ }
152
+ });
153
+
1
154
  // src/gateway/ent/logging.ts
2
155
  import { format } from "node:util";
3
156
  var LogInfoAdapter = class {
@@ -209,7 +362,7 @@ function toCluster(legacy) {
209
362
  function toMeshConfig(legacy) {
210
363
  const mesh = {};
211
364
  if (legacy?.configuration?.node_id) mesh.node = legacy.configuration.node_id;
212
- if (legacy?.type === "broker") mesh.broker = { endpoint: legacy.broker.endpoint };
365
+ if (legacy?.type === "broker") mesh.broker = { endpoint: legacy.broker?.endpoint ?? "<unresolved>" };
213
366
  if (legacy?.type === "p2p") {
214
367
  const cluster = toCluster(legacy.p2p);
215
368
  if (cluster) {
@@ -237,7 +390,7 @@ function toAuthenticationConfig(legacy) {
237
390
  function toServerConfig(config) {
238
391
  const gateway = {
239
392
  route: config.route,
240
- limits: config.limits,
393
+ maxConnections: config.limits?.max_connections,
241
394
  origins: config.security?.origin_filters,
242
395
  authorize: config["authorize"] ?? { access: "permitted" },
243
396
  clients: config["clients"] ?? { inactive_seconds: 0, buffer_size: 100 },
@@ -285,20 +438,37 @@ function toServerConfig(config) {
285
438
  port: config.port ?? 3434,
286
439
  host: config.ip ?? config["host"],
287
440
  memory: config["memory"],
441
+ app: async (configurer) => {
442
+ if (config.cluster?.embedded_broker?.enabled === true) {
443
+ configurer.socket({
444
+ path: config.cluster.embedded_broker.route ?? "/mesh-broker",
445
+ options: {
446
+ authorize: config.cluster.embedded_broker["authorize"] ?? { access: "permitted" }
447
+ },
448
+ factory: async (env) => {
449
+ if (gateway.mesh?.broker?.endpoint === "<unresolved>") {
450
+ gateway.mesh.broker.endpoint = env.endpoint;
451
+ }
452
+ const delegate = (await Promise.resolve().then(() => (init_core(), core_exports))).default;
453
+ return await delegate(env);
454
+ }
455
+ });
456
+ }
457
+ },
288
458
  gateway
289
459
  };
290
460
  }
291
461
 
292
462
  // src/gateway/ent/index.ts
293
- import { IOGateway } from "@interopio/gateway";
294
- function create(config) {
463
+ import { IOGateway as IOGateway3 } from "@interopio/gateway";
464
+ function create2(config) {
295
465
  return new ServerDelegate(toServerConfig(config));
296
466
  }
297
467
  function configure_logging(config) {
298
- IOGateway.Logging.configure(toLogConfig(config));
468
+ IOGateway3.Logging.configure(toLogConfig(config));
299
469
  }
300
470
  export {
301
471
  configure_logging,
302
- create
472
+ create2 as create
303
473
  };
304
474
  //# sourceMappingURL=gateway-ent.js.map