socket-function 0.8.13 → 0.8.14

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/SocketFunction.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { SocketExposedInterface, CallContextType, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, NetworkLocation, CallerContext, SocketExposedInterfaceClass, CallType } from "./SocketFunctionTypes";
1
+ import { SocketExposedInterface, CallContextType, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, NetworkLocation, CallerContext, SocketExposedInterfaceClass, CallType, FullCallType } from "./SocketFunctionTypes";
2
2
  import { exposeClass, registerClass, registerGlobalClientHook, registerGlobalHook, runClientHooks } from "./src/callManager";
3
3
  import { SocketServerConfig, startSocketServer } from "./src/webSocketServer";
4
- import { getCallFactoryNodeId, getCreateCallFactoryLocation, getNetworkLocationHash } from "./src/nodeCache";
4
+ import { getCallFactoryFromNodeId, getCreateCallFactoryLocation, getNetworkLocationHash } from "./src/nodeCache";
5
5
  import { getCallProxy } from "./src/nodeProxy";
6
6
  import { Args } from "./src/types";
7
7
  import { setDefaultHTTPCall } from "./src/callHTTPHandler";
@@ -53,13 +53,15 @@ export class SocketFunction {
53
53
 
54
54
  registerClass(classGuid, instance as SocketExposedInterface, shape as any as SocketExposedShape);
55
55
 
56
- let nodeProxy = getCallProxy(classGuid, async (nodeId, functionName, args) => {
56
+ let nodeProxy = getCallProxy(classGuid, async (call) => {
57
+ let nodeId = call.nodeId;
58
+ let functionName = call.functionName;
57
59
  let time = Date.now();
58
60
  if (SocketFunction.logMessages) {
59
61
  console.log(`START\t\t\t${classGuid}.${functionName}`);
60
62
  }
61
63
  try {
62
- let callFactory = await getCallFactoryNodeId(nodeId);
64
+ let callFactory = await getCallFactoryFromNodeId(nodeId);
63
65
  if (!callFactory) {
64
66
  throw new Error(`Cannot reach node ${nodeId}. It might have been incorrect provided to us via another node, which should have provided us a NetworkLocation instead.`);
65
67
  }
@@ -69,12 +71,6 @@ export class SocketFunction {
69
71
  throw new Error(`Function ${functionName} is not in shape`);
70
72
  }
71
73
 
72
- let call: CallType = {
73
- classGuid,
74
- args,
75
- functionName,
76
- };
77
-
78
74
  let hookResult = await runClientHooks(call, shapeObj as SocketExposedShape[""]);
79
75
 
80
76
  if ("overrideResult" in hookResult) {
@@ -99,6 +95,20 @@ export class SocketFunction {
99
95
  return output as any;
100
96
  }
101
97
 
98
+ /** Gets HTTP call link */
99
+ public static async getHTTPCallLink(call: FullCallType): Promise<string> {
100
+ let factory = await getCallFactoryFromNodeId(call.nodeId);
101
+ if (!factory) {
102
+ throw new Error(`Cannot find call factory for nodeId, and so do not know where call location is. NodeId ${call.nodeId}`);
103
+ }
104
+ let location = factory.location;
105
+ let url = new URL(`https://${location.address}:${location.listeningPorts[0]}`);
106
+ url.searchParams.set("classGuid", call.classGuid);
107
+ url.searchParams.set("functionName", call.functionName);
108
+ url.searchParams.set("args", JSON.stringify(call.args));
109
+ return url.toString();
110
+ }
111
+
102
112
  /** Expose should be called before your mounting occurs. It mostly just exists to ensure you include the class type,
103
113
  * so the class type's module construction runs, which should trigger register. Otherwise you would have
104
114
  * to add additional imports to ensure the register call runs.
@@ -2,12 +2,20 @@ module.allowclient = true;
2
2
 
3
3
  import debugbreak from "debugbreak";
4
4
  import * as tls from "tls";
5
+ import { getCallObj } from "./src/nodeProxy";
6
+ import { Args } from "./src/types";
5
7
 
6
8
  export const socket = Symbol("socket");
7
9
 
8
10
  export type SocketExposedInterface = {
9
11
  [functionName: string]: (...args: any[]) => Promise<unknown>;
10
12
  };
13
+ export type SocketInternalInterface = {
14
+ [functionName: string]: {
15
+ [getCallObj]: (...args: any[]) => FullCallType;
16
+ (...args: any[]): Promise<unknown>;
17
+ }
18
+ }
11
19
  export type SocketExposedInterfaceClass = {
12
20
  //new(): SocketExposedInterface;
13
21
  new(): unknown;
@@ -28,6 +36,9 @@ export interface CallType {
28
36
  // To set a timeout on returns, you can set it in the server hook.
29
37
  reconnectTimeout?: number;
30
38
  }
39
+ export interface FullCallType extends CallType {
40
+ nodeId: string;
41
+ }
31
42
 
32
43
  export interface SocketFunctionHook<ExposedType extends SocketExposedInterface = SocketExposedInterface, CallContext extends CallContextType = CallContextType> {
33
44
  (config: HookContext<ExposedType, CallContext>): Promise<void>;
@@ -56,7 +67,11 @@ export interface SocketRegistered<ExposedType extends SocketExposedInterface = S
56
67
  nodes: {
57
68
  // NOTE: Don't pass around nodeId to other nodes, instead pass around NetworkLocation (which they
58
69
  // then turn into a nodeId, which they can then check permissions on themself).
59
- [nodeId: string]: ExposedType;
70
+ [nodeId: string]: {
71
+ [functionName in keyof ExposedType]: ExposedType[functionName] & {
72
+ [getCallObj]: (...args: Args<ExposedType[functionName]>) => FullCallType;
73
+ }
74
+ };
60
75
  };
61
76
  context: {
62
77
  // If undefined we are not synchronously in a call
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socket-function",
3
- "version": "0.8.13",
3
+ "version": "0.8.14",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
package/src/nodeCache.ts CHANGED
@@ -87,6 +87,6 @@ export function getCreateCallFactoryLocation(location: NetworkLocation, tempNode
87
87
 
88
88
 
89
89
  // TODO: Give a special error if the nodeId has been seen, but is only one-way (from HTTP requests).
90
- export async function getCallFactoryNodeId(nodeId: string): Promise<CallFactory | undefined> {
90
+ export async function getCallFactoryFromNodeId(nodeId: string): Promise<CallFactory | undefined> {
91
91
  return await nodeCache.get(nodeId)?.callFactory;
92
92
  }
package/src/nodeProxy.ts CHANGED
@@ -1,29 +1,52 @@
1
1
  import { lazy } from "./caching";
2
- import { SocketExposedInterface } from "../SocketFunctionTypes";
2
+ import { FullCallType, SocketExposedInterface, SocketInternalInterface } from "../SocketFunctionTypes";
3
3
 
4
4
  type CallProxyType = {
5
- [controllerName: string]: SocketExposedInterface;
5
+ [nodeId: string]: SocketInternalInterface;
6
6
  };
7
7
 
8
+ export const getCallObj = Symbol.for("getCallObj");
9
+
8
10
  let proxyCache = new Map<string, CallProxyType>();
9
- export function getCallProxy(id: string, callback: (controllerName: string, functionName: string, args: unknown[]) => Promise<unknown>): CallProxyType {
11
+ export function getCallProxy(id: string, callback: (callType: FullCallType) => Promise<unknown>): CallProxyType {
10
12
  let value = proxyCache.get(id);
11
13
  if (!value) {
12
- let controllerCache = new Map<string, CallProxyType[""]>();
14
+ let nodeCache = new Map<string, CallProxyType[""]>();
13
15
  value = new Proxy(Object.create(null), {
14
- get(target, controllerName) {
15
- if (typeof controllerName !== "string") return undefined;
16
- let controller = controllerCache.get(controllerName);
17
- if (!controller) {
18
- controller = new Proxy(Object.create(null), {
16
+ get(target, nodeId) {
17
+ if (typeof nodeId !== "string") return undefined;
18
+ let nodeProxy = nodeCache.get(nodeId);
19
+ if (!nodeProxy) {
20
+ nodeProxy = new Proxy(Object.create(null), {
19
21
  get(target, functionName) {
20
22
  if (typeof functionName !== "string") return undefined;
21
- return (...args: unknown[]) => callback(controllerName, functionName, args);
23
+ return Object.assign(
24
+ (...args: unknown[]) => {
25
+ let call: FullCallType = {
26
+ classGuid: id,
27
+ nodeId,
28
+ functionName,
29
+ args,
30
+ };
31
+ return callback(call);
32
+ },
33
+ {
34
+ [getCallObj]: (...args: unknown[]) => {
35
+ let call: FullCallType = {
36
+ classGuid: id,
37
+ nodeId,
38
+ functionName,
39
+ args,
40
+ };
41
+ return call;
42
+ }
43
+ }
44
+ );
22
45
  }
23
46
  }) as CallProxyType[""];
24
- controllerCache.set(controllerName, controller);
47
+ nodeCache.set(nodeId, nodeProxy);
25
48
  }
26
- return controller;
49
+ return nodeProxy;
27
50
  },
28
51
  }) as CallProxyType;
29
52
  proxyCache.set(id, value);
package/test/client.ts CHANGED
@@ -10,6 +10,7 @@ import { Test } from "./shared";
10
10
  import "../require/CSSShim";
11
11
  import "./client.css";
12
12
  import { isNode } from "../src/misc";
13
+ import { getCallObj } from "../src/nodeProxy";
13
14
 
14
15
  module.allowclient = true;
15
16
 
@@ -23,6 +24,8 @@ void main();
23
24
  async function main() {
24
25
  if (isNode()) return;
25
26
 
27
+ SocketFunction.rejectUnauthorized = false;
28
+
26
29
  SocketFunction.expose(Test);
27
30
 
28
31
  console.log("cool");
package/test/server.ts CHANGED
@@ -16,11 +16,14 @@ import "../require/CSSShim";
16
16
 
17
17
  // Import clientside files, so they can be whitelisted
18
18
  import "./client";
19
+ import { getCallObj } from "../src/nodeProxy";
19
20
 
20
21
 
21
22
  void main();
22
23
 
23
24
  async function main() {
25
+ SocketFunction.rejectUnauthorized = false;
26
+
24
27
  SocketFunction.expose(Test);
25
28
 
26
29
  RequireController._classGuid;