socket-function 0.155.0 → 0.157.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.
Files changed (51) hide show
  1. package/SetProcessVariables.d.ts +1 -0
  2. package/SocketFunction.d.ts +104 -0
  3. package/SocketFunction.ts +1 -1
  4. package/SocketFunctionTypes.d.ts +86 -0
  5. package/generateIndexDts.js +52 -0
  6. package/hot/HotReloadController.d.ts +34 -0
  7. package/hot/HotReloadController.ts +2 -0
  8. package/index.d.ts +1196 -31
  9. package/mobx/UrlParam.d.ts +13 -0
  10. package/mobx/observer.d.ts +18 -0
  11. package/mobx/promiseToObservable.d.ts +8 -0
  12. package/package.json +4 -1
  13. package/require/CSSShim.d.ts +2 -0
  14. package/require/compileFlags.d.ts +11 -0
  15. package/require/extMapper.d.ts +4 -0
  16. package/require/require.d.ts +14 -0
  17. package/src/CallFactory.d.ts +37 -0
  18. package/src/JSONLACKS/JSONLACKS.d.ts +28 -0
  19. package/src/args.d.ts +9 -0
  20. package/src/batching.d.ts +31 -0
  21. package/src/caching.d.ts +59 -0
  22. package/src/callHTTPHandler.d.ts +26 -0
  23. package/src/callManager.d.ts +21 -0
  24. package/src/certStore.d.ts +6 -0
  25. package/src/corsCheck.d.ts +0 -0
  26. package/src/fixLargeNetworkCalls.d.ts +2 -0
  27. package/src/formatting/colors.d.ts +42 -0
  28. package/src/formatting/format.d.ts +24 -0
  29. package/src/formatting/logColors.d.ts +7 -0
  30. package/src/forwardPort.d.ts +5 -0
  31. package/src/https.d.ts +8 -0
  32. package/src/misc.d.ts +98 -0
  33. package/src/networking.d.ts +11 -0
  34. package/src/nodeCache.d.ts +24 -0
  35. package/src/nodeProxy.d.ts +7 -0
  36. package/src/profiling/getOwnTime.d.ts +12 -0
  37. package/src/profiling/measure.d.ts +59 -0
  38. package/src/profiling/stats.d.ts +54 -0
  39. package/src/profiling/statsFormat.d.ts +7 -0
  40. package/src/profiling/tcpLagProxy.d.ts +18 -0
  41. package/src/promiseRace.d.ts +10 -0
  42. package/src/runPromise.d.ts +7 -0
  43. package/src/sniTest.d.ts +1 -0
  44. package/src/storagePath.d.ts +5 -0
  45. package/src/tlsParsing.d.ts +11 -0
  46. package/src/types.d.ts +6 -0
  47. package/src/webSocketServer.d.ts +30 -0
  48. package/src/websocketFactory.d.ts +9 -0
  49. package/test.d.ts +1 -0
  50. package/time/trueTimeShim.d.ts +6 -0
  51. package/tsconfig.declarations.json +18 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,104 @@
1
+ /// <reference path="require/RequireController.d.ts" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ import { SocketExposedInterface, SocketFunctionHook, SocketFunctionClientHook, SocketExposedShape, SocketRegistered, CallerContext, FullCallType, SocketRegisterType } from "./SocketFunctionTypes";
5
+ import { SocketServerConfig } from "./src/webSocketServer";
6
+ import { Args, MaybePromise } from "./src/types";
7
+ import "./SetProcessVariables";
8
+ type ExtractShape<ClassType, Shape> = {
9
+ [key in keyof ClassType]: (key extends keyof Shape ? ClassType[key] extends SocketExposedInterface[""] ? ClassType[key] : ClassType[key] extends Function ? "All exposed function must be async (or return a Promise)" : never : "Function is in shape, but not in class");
10
+ };
11
+ export declare class SocketFunction {
12
+ static logMessages: boolean;
13
+ static trackMessageSizes: {
14
+ upload: ((size: number) => void)[];
15
+ download: ((size: number) => void)[];
16
+ callTimes: ((obj: {
17
+ start: number;
18
+ end: number;
19
+ }) => void)[];
20
+ };
21
+ static MAX_MESSAGE_SIZE: number;
22
+ static HTTP_ETAG_CACHE: boolean;
23
+ static silent: boolean;
24
+ static HTTP_COMPRESS: boolean;
25
+ static COEP: string;
26
+ static COOP: string;
27
+ static readonly WIRE_SERIALIZER: {
28
+ serialize: (obj: unknown) => MaybePromise<Buffer[]>;
29
+ deserialize: (buffers: Buffer[]) => MaybePromise<unknown>;
30
+ };
31
+ static WIRE_WARN_TIME: number;
32
+ private static onMountCallbacks;
33
+ static exposedClasses: Set<string>;
34
+ static callerContext: CallerContext | undefined;
35
+ static getCaller(): CallerContext;
36
+ static harvestFailedCallCount: () => number;
37
+ static getPendingCallCount: () => number;
38
+ static harvestCallTimes: () => {
39
+ start: number;
40
+ end: number;
41
+ }[];
42
+ static register<ClassInstance extends object, Shape extends SocketExposedShape<{
43
+ [key in keyof ClassInstance]: (...args: any[]) => Promise<unknown>;
44
+ }>, Statics>(classGuid: string, instance: ClassInstance | (() => ClassInstance), shapeFnc: () => Shape, defaultHooksFnc?: () => SocketExposedShape[""] & {
45
+ onMount?: () => MaybePromise<void>;
46
+ }, config?: {
47
+ /** @noAutoExpose If true SocketFunction.expose(Controller) must be called explicitly. */
48
+ noAutoExpose?: boolean;
49
+ statics?: Statics;
50
+ /** Skip timing functions calls. Useful if a lot of functions have wait time that
51
+ is unrelated to processing, and therefore their timings won't be useful.
52
+ - Also useful if our auto function wrapping code is breaking functionality,
53
+ such as if you have a singleton function which you compare with ===,
54
+ which will breaks because we replaced it with a wrapped measure function.
55
+ */
56
+ noFunctionMeasure?: boolean;
57
+ }): SocketRegistered<ExtractShape<ClassInstance, Shape>> & Statics;
58
+ private static socketCache;
59
+ static rehydrateSocketCaller<Controller>(socketRegistered: SocketRegisterType<Controller>, shapeFnc?: () => SocketExposedShape): SocketRegistered<Controller>;
60
+ private static callFromGuid;
61
+ static onNextDisconnect(nodeId: string, callback: () => void): void;
62
+ static getLastDisconnectTime(nodeId: string): number | undefined;
63
+ static isNodeConnected(nodeId: string): boolean;
64
+ /** NOTE: Only works if the nodeIs used is from SocketFunction.connect (we can't convert arbitrary nodeIds into urls,
65
+ * as we have no way of knowing how to contain a nodeId).
66
+ * */
67
+ static getHTTPCallLink(call: FullCallType): string;
68
+ private static ignoreExposeCount;
69
+ static ignoreExposeCalls<T>(code: () => Promise<T>): Promise<T>;
70
+ /** Expose should be called before your mounting occurs. It mostly just exists to ensure you include the class type,
71
+ * so the class type's module construction runs, which should trigger register. Otherwise you would have
72
+ * to add additional imports to ensure the register call runs.
73
+ */
74
+ static expose(socketRegistered: SocketRegistered): void;
75
+ static mountedNodeId: string;
76
+ static isMounted(): boolean;
77
+ static mountedIP: string;
78
+ private static hasMounted;
79
+ private static onMountCallback;
80
+ static mountPromise: Promise<void>;
81
+ static mount(config: SocketServerConfig): Promise<string>;
82
+ /** Sets the default call when an http request is made, but no classGuid is set.
83
+ * NOTE: All other calls should be endpoint calls, even if those endpoints return a static file with an HTML content type.
84
+ * - However, to load new content, you should probably just use `require("./example.ts")`, which works on any files
85
+ * clientside that have also been required serverside (and whitelisted with module.allowclient = true,
86
+ * or with an `allowclient.flag` file in the directory or parent directory).
87
+ */
88
+ static setDefaultHTTPCall<Registered extends SocketRegistered, FunctionName extends keyof Registered["nodes"][""] & string>(registered: Registered, functionName: FunctionName, ...args: Args<Registered["nodes"][""][FunctionName]>): void;
89
+ static connect(location: {
90
+ address: string;
91
+ port: number;
92
+ }): string;
93
+ static browserNodeId(): string;
94
+ static getBrowserNodeId(): string;
95
+ static addGlobalHook(hook: SocketFunctionHook): void;
96
+ static addGlobalClientHook(hook: SocketFunctionClientHook): void;
97
+ }
98
+ declare global {
99
+ var BOOTED_EDGE_NODE: {
100
+ host: string;
101
+ } | undefined;
102
+ }
103
+ export declare function _setSocketContext<T>(caller: CallerContext, code: () => T): T;
104
+ export {};
package/SocketFunction.ts CHANGED
@@ -41,7 +41,7 @@ type ExtractShape<ClassType, Shape> = {
41
41
  ? ClassType[key] extends SocketExposedInterface[""]
42
42
  ? ClassType[key]
43
43
  : ClassType[key] extends Function ? "All exposed function must be async (or return a Promise)" : never
44
- : "Function is in shape, but not in class"
44
+ : "Function has implementation but is not exposed in the SocketFunction.register call"
45
45
  );
46
46
  };
47
47
 
@@ -0,0 +1,86 @@
1
+ /// <reference path="require/RequireController.d.ts" />
2
+ import { getCallObj } from "./src/nodeProxy";
3
+ import { Args, MaybePromise } from "./src/types";
4
+ export declare const socket: unique symbol;
5
+ export type SocketExposedInterface = {
6
+ [functionName: string]: (...args: any[]) => Promise<unknown>;
7
+ };
8
+ export type SocketInternalInterface = {
9
+ [functionName: string]: {
10
+ [getCallObj]: (...args: any[]) => FullCallType;
11
+ (...args: any[]): Promise<unknown>;
12
+ };
13
+ };
14
+ export type SocketExposedInterfaceClass = {
15
+ new (): unknown;
16
+ prototype: unknown;
17
+ };
18
+ export type FunctionFlags = {
19
+ compress?: boolean;
20
+ /** Indicates with the same input, we give the same output, forever,
21
+ * independent of code changes. This only works for data storage.
22
+ */
23
+ dataImmutable?: boolean;
24
+ /** Allows overriding SocketFunction.MAX_MESSAGE_SIZE for responses from this function. */
25
+ responseLimit?: number;
26
+ };
27
+ export type SocketExposedShape<ExposedType extends SocketExposedInterface = SocketExposedInterface> = {
28
+ [functionName in keyof ExposedType]?: FunctionFlags & {
29
+ hooks?: SocketFunctionHook[];
30
+ clientHooks?: SocketFunctionClientHook[];
31
+ noDefaultHooks?: boolean;
32
+ /** BUG: I think this is broken if it is on the default hooks function? */
33
+ noClientHooks?: boolean;
34
+ };
35
+ };
36
+ export type FncType = (...args: any[]) => Promise<unknown>;
37
+ export interface CallType<FncT extends FncType = FncType, FncName extends string = string> {
38
+ classGuid: string;
39
+ functionName: FncName;
40
+ args: unknown[];
41
+ }
42
+ export interface FullCallType<FncT extends FncType = FncType, FncName extends string = string> extends CallType<FncT, FncName> {
43
+ nodeId: string;
44
+ }
45
+ export interface SocketFunctionHook {
46
+ (config: HookContext): MaybePromise<void>;
47
+ /** NOTE: This is useful when we need a clientside hook to set up state specifically for our serverside hook. */
48
+ clientHook?: SocketFunctionClientHook;
49
+ }
50
+ export type HookContext = {
51
+ call: FullCallType;
52
+ overrideResult?: unknown;
53
+ onResult: ((result: unknown) => MaybePromise<void>)[];
54
+ };
55
+ export type ClientHookContext = {
56
+ call: FullCallType;
57
+ overrideResult?: unknown;
58
+ onResult: ((result: unknown) => MaybePromise<void>)[];
59
+ connectionId: {
60
+ nodeId: string;
61
+ };
62
+ };
63
+ export interface SocketFunctionClientHook {
64
+ (config: ClientHookContext): MaybePromise<void>;
65
+ }
66
+ export interface SocketRegisterType<ExposedType = any> {
67
+ _classGuid: string;
68
+ _internalType: ExposedType;
69
+ }
70
+ export interface SocketRegistered<ExposedType = any> {
71
+ nodes: {
72
+ [nodeId: string]: {
73
+ [functionName in keyof ExposedType]: ExposedType[functionName] & {
74
+ [getCallObj]: (...args: Args<ExposedType[functionName]>) => FullCallType;
75
+ };
76
+ };
77
+ };
78
+ _classGuid: string;
79
+ _internalType: ExposedType;
80
+ }
81
+ export type ControllerPick<T extends SocketRegistered, K extends keyof T["_internalType"]> = (SocketRegistered<Pick<T["_internalType"], K>>);
82
+ export type CallerContext = Readonly<CallerContextBase>;
83
+ export type CallerContextBase = {
84
+ nodeId: string;
85
+ localNodeId: string;
86
+ };
@@ -0,0 +1,52 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ function getAllDtsFiles(dir, fileList = []) {
5
+ const files = fs.readdirSync(dir);
6
+
7
+ for (const file of files) {
8
+ if (file === "node_modules") continue;
9
+ if (file === "dist") continue;
10
+ const filePath = path.join(dir, file);
11
+ const stat = fs.statSync(filePath);
12
+
13
+ if (stat.isDirectory()) {
14
+ getAllDtsFiles(filePath, fileList);
15
+ } else if (file.endsWith(".d.ts")) {
16
+ fileList.push(filePath);
17
+ }
18
+ }
19
+
20
+ return fileList;
21
+ }
22
+
23
+ function generateIndexDts() {
24
+ const renderUtilsPath = __dirname;
25
+ const dtsFiles = getAllDtsFiles(renderUtilsPath);
26
+
27
+ const modules = dtsFiles
28
+ .map(filePath => {
29
+ const relativePath = path.relative(renderUtilsPath, filePath);
30
+ const withoutExt = relativePath.replace(/\.d\.ts$/, "");
31
+ const modulePath = "socket-function/" + withoutExt.replace(/\\/g, "/");
32
+
33
+ const content = fs.readFileSync(filePath, "utf8");
34
+ const indentedContent = content
35
+ .split("\n")
36
+ .map(line => line ? " " + line : line)
37
+ .join("\n");
38
+
39
+ return `declare module "${modulePath}" {\n${indentedContent}\n}`;
40
+ })
41
+ .sort()
42
+ .join("\n\n");
43
+
44
+ const outputPath = path.join(__dirname, "index.d.ts");
45
+ const header = `// Auto-generated file. Do not edit manually.\n// Generated by: yarn generate-index-dts\n\n`;
46
+
47
+ fs.writeFileSync(outputPath, header + modules + "\n", "utf8");
48
+ console.log(`Generated ${outputPath} with ${dtsFiles.length} module declarations`);
49
+ }
50
+
51
+ generateIndexDts();
52
+
@@ -0,0 +1,34 @@
1
+ /// <reference path="../../typenode/index.d.ts" />
2
+ /// <reference path="../require/RequireController.d.ts" />
3
+ /** Enables some hot reload functionality.
4
+ * - Triggers a refresh clientside
5
+ * - Triggers a reload server, for modules marked with `module.hotreload`
6
+ */
7
+ export declare function watchFilesAndTriggerHotReloading(noAutomaticBrowserWatch?: boolean): void;
8
+ declare global {
9
+ namespace NodeJS {
10
+ interface Module {
11
+ /** Causes us to hotreload the file. Applies both serverside and clientside.
12
+ * - If not set for any files clientside, we will refresh.
13
+ * - If not set for any files serverside, we will do nothing (and just leave old code running).
14
+ */
15
+ hotreload?: boolean;
16
+ /** Overrides hotreload to disable hot reloading. Useful if you add "hotreload.flag" to a directory
17
+ * (which sets hotreload on all files in and under that directory), but want a specific file
18
+ * to not hotreload.
19
+ * - Also useful if you want files to hotreload clientside, but not serverside.
20
+ */
21
+ noserverhotreload?: boolean;
22
+ watchAdditionalFiles?: string[];
23
+ }
24
+ }
25
+ var isHotReloading: (() => boolean) | undefined;
26
+ }
27
+ export declare function isHotReloading(): boolean;
28
+ export declare function hotReloadingGuard(): true;
29
+ export declare function setExternalHotReloading(value: boolean): void;
30
+ export declare function onHotReload(callback: (modules: NodeJS.Module[]) => void): void;
31
+ export declare const HotReloadController: import("../SocketFunctionTypes").SocketRegistered<{
32
+ watchFiles: () => Promise<void>;
33
+ fileUpdated: (files: string[], changeTime: number) => Promise<void>;
34
+ }>;
@@ -188,6 +188,8 @@ class HotReloadControllerBase {
188
188
  let callerId = SocketFunction.getCaller().nodeId;
189
189
  clientWatcherNodes.add(callerId);
190
190
  }
191
+ // TODO: This is actually broken related to lazy loaded and server-only code, as the server will tell us a file changed, and then we'll see that we don't have it loaded, and so we will try to refresh.
192
+ // - The reason we refresh is because it might be a new file. I don't know how we could check to see if it was lazy loaded. Maybe we just shouldn't refresh ever if we can't find the module? We'll see how much we run into the extra refresh due to lazy loading...
191
193
  async fileUpdated(files: string[], changeTime: number) {
192
194
  try {
193
195
  console.groupCollapsed(magenta(`Trigger hotreload for files ${formatTime(Date.now() - changeTime)} after file change`));