socket-function 1.2.27 → 1.2.29

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.
@@ -5,7 +5,8 @@
5
5
  "Bash(cp -r 'C:/Users/quent/AppData/Local/BraveSoftware/Brave-Browser/User Data/Default/Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo' C:/Users/quent/AppData/Local/Temp/claude/D--repos-socket-function/117d10bd-31c6-4c68-938d-1fff47788fa6/scratchpad/tm-recover/LocalExtSettings)",
6
6
  "Bash(yarn test-dns-claude *)",
7
7
  "Bash(yarn type *)",
8
- "Bash(yarn test *)"
8
+ "Bash(yarn test *)",
9
+ "PowerShell(yarn type *)"
9
10
  ]
10
11
  }
11
12
  }
@@ -27,7 +27,6 @@ export declare class SocketFunction {
27
27
  static COOP: string;
28
28
  static TOTAL_CALLS: number;
29
29
  static ENABLE_CLIENT_MODE: boolean;
30
- static isClient(): boolean;
31
30
  static readonly WIRE_SERIALIZER: {
32
31
  serialize: (obj: unknown) => MaybePromise<Buffer[]>;
33
32
  deserialize: (buffers: Buffer[]) => MaybePromise<unknown>;
@@ -38,6 +37,7 @@ export declare class SocketFunction {
38
37
  static GET_ALTERNATE_NODE_IDS: (nodeId: string) => MaybePromise<string[] | undefined>;
39
38
  static WIRE_WARN_TIME: number;
40
39
  static DISABLE_COMPRESSION: boolean;
40
+ static isClient(): boolean;
41
41
  private static onMountCallbacks;
42
42
  private static exposedClassesSingleton;
43
43
  static get exposedClasses(): Set<string>;
package/SocketFunction.ts CHANGED
@@ -9,7 +9,7 @@ import { Args, MaybePromise } from "./src/types";
9
9
  import { setDefaultHTTPCall } from "./src/callHTTPHandler";
10
10
  import debugbreak from "debugbreak";
11
11
  import { lazy } from "./src/caching";
12
- import { createSingleton } from "./src/createSingleton";
12
+ import { createSingleton, defineSingletonConfig } from "./src/createSingleton";
13
13
  import { delay } from "./src/batching";
14
14
  import { blue, magenta } from "./src/formatting/logColors";
15
15
  import { JSONLACKS } from "./src/JSONLACKS/JSONLACKS";
@@ -56,6 +56,12 @@ type ExtractShape<ClassType, Shape> = {
56
56
  };
57
57
 
58
58
  export class SocketFunction {
59
+
60
+
61
+ // #region Shared config statics. EVERYTHING in this region (and nothing outside it) is redefined
62
+ // below the class by defineSingletonConfig, which replaces each property (via defineProperty)
63
+ // with accessors onto a singleton shared by every copy of this package - the inline values here
64
+ // are just the defaults.
59
65
  public static logMessages = false;
60
66
  public static trackMessageSizes = {
61
67
  upload: [] as ((size: number, nodeId: string) => void)[],
@@ -79,8 +85,6 @@ export class SocketFunction {
79
85
  public static TOTAL_CALLS = 0;
80
86
 
81
87
  public static ENABLE_CLIENT_MODE = false;
82
- // Places where we decide if we want to act as a client. Most places we check for is node, but some places it's not, depending on if we're in Node.js or not, it's depending on if we're a client or not.
83
- public static isClient() { return !isNode() || SocketFunction.ENABLE_CLIENT_MODE; }
84
88
 
85
89
  // In retrospect... dynamically changing the wire serializer is a BAD idea. If any calls happen
86
90
  // before it is changed, things just break. Also, it needs to be changed on both sides,
@@ -91,7 +95,7 @@ export class SocketFunction {
91
95
  deserialize: measureWrap((buffers: Buffer[]): MaybePromise<unknown> => cborxInstance.decode(buffers[0]), "WIRE_SERIALIZER|deserialize"),
92
96
  };
93
97
 
94
- /** We will try the alternate node IDs first, however, if they fail, we will go through all of them and then eventually try the original node ID.
98
+ /** We will try the alternate node IDs first, however, if they fail, we will go through all of them and then eventually try the original node ID.
95
99
  * VERY useful, allowing us to change global ips to local ones, which short-circuits the router, massively increasing bandwidth and decreasing latency.
96
100
  */
97
101
  public static GET_ALTERNATE_NODE_IDS = (nodeId: string): MaybePromise<string[] | undefined> => undefined;
@@ -100,6 +104,13 @@ export class SocketFunction {
100
104
 
101
105
  // Process-wide compression kill switch. When set before connections are established, LZ4 is left out of the protocol negotiation entirely (both for connections we initiate and ones we accept), so NEITHER side compresses — the wire format stays the plain backwards-compatible one. Overrides per-function `compress` flags.
102
106
  public static DISABLE_COMPRESSION = false;
107
+ // #endregion Shared config statics.
108
+
109
+
110
+
111
+
112
+ // Places where we decide if we want to act as a client. Most places we check for is node, but some places it's not, depending on if we're in Node.js or not, it's depending on if we're a client or not.
113
+ public static isClient() { return !isNode() || SocketFunction.ENABLE_CLIENT_MODE; }
103
114
 
104
115
  // Shared across copies of this package, so onMount callbacks registered through one copy still
105
116
  // fire when another copy mounts. See createSingleton.
@@ -513,6 +524,23 @@ export class SocketFunction {
513
524
  }
514
525
  }
515
526
 
527
+ defineSingletonConfig(SocketFunction, "SocketFunction.config", 1, [
528
+ "logMessages",
529
+ "trackMessageSizes",
530
+ "MAX_MESSAGE_SIZE",
531
+ "HTTP_ETAG_CACHE",
532
+ "silent",
533
+ "HTTP_COMPRESS",
534
+ "COEP",
535
+ "COOP",
536
+ "TOTAL_CALLS",
537
+ "ENABLE_CLIENT_MODE",
538
+ "WIRE_SERIALIZER",
539
+ "GET_ALTERNATE_NODE_IDS",
540
+ "WIRE_WARN_TIME",
541
+ "DISABLE_COMPRESSION",
542
+ ]);
543
+
516
544
  declare global {
517
545
  var BOOTED_EDGE_NODE: { host: string } | undefined;
518
546
  }
package/index.d.ts CHANGED
@@ -36,7 +36,6 @@ declare module "socket-function/SocketFunction" {
36
36
  static COOP: string;
37
37
  static TOTAL_CALLS: number;
38
38
  static ENABLE_CLIENT_MODE: boolean;
39
- static isClient(): boolean;
40
39
  static readonly WIRE_SERIALIZER: {
41
40
  serialize: (obj: unknown) => MaybePromise<Buffer[]>;
42
41
  deserialize: (buffers: Buffer[]) => MaybePromise<unknown>;
@@ -47,6 +46,7 @@ declare module "socket-function/SocketFunction" {
47
46
  static GET_ALTERNATE_NODE_IDS: (nodeId: string) => MaybePromise<string[] | undefined>;
48
47
  static WIRE_WARN_TIME: number;
49
48
  static DISABLE_COMPRESSION: boolean;
49
+ static isClient(): boolean;
50
50
  private static onMountCallbacks;
51
51
  private static exposedClassesSingleton;
52
52
  static get exposedClasses(): Set<string>;
@@ -849,6 +849,16 @@ declare module "socket-function/src/createSingleton" {
849
849
  * get()/set() at each access so every copy sees the latest.
850
850
  */
851
851
  export declare function createSingleton<T>(name: string, version: string | number, getDefault: () => T): Singleton<T>;
852
+ /** Redefines the given (already initialized) properties of target as accessors onto a singleton, so
853
+ * `Target.SOME_SETTING = x` configures every copy of the package instead of only the copy the
854
+ * caller happened to import (which is otherwise decided by module resolution, and so is
855
+ * essentially arbitrary from the caller's perspective). The properties' current values become
856
+ * the defaults, so config statics stay defined inline in the class as usual - just call this
857
+ * below the class with the list of statics to share.
858
+ * - Same versioning rules as createSingleton, except that adding a property is not a shape change:
859
+ * a copy that knows about a property older copies don't backfills it below.
860
+ */
861
+ export declare function defineSingletonConfig<T extends object>(target: T, name: string, version: string | number, keys: (keyof T & string)[]): void;
852
862
 
853
863
  }
854
864
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socket-function",
3
- "version": "1.2.27",
3
+ "version": "1.2.29",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
@@ -9,6 +9,7 @@ import parser from "./JSONLACKS.generated.js";
9
9
  import { recursiveFreeze } from "../misc";
10
10
  import { canHaveChildren } from "../types";
11
11
  import { delay } from "../batching";
12
+ import { defineSingletonConfig } from "../createSingleton";
12
13
 
13
14
  const SERIALIZE_OBJECT_BATCH_COUNT = 1000;
14
15
  const PARSE_BYTE_CHUNK_SIZE = 1024 * 1024 * 10;
@@ -44,9 +45,14 @@ interface HydrateState {
44
45
  export class JSONLACKS {
45
46
  public static readonly LACKS_KEY = "__JSONLACKS__98cfb4a05fa34d828661cae15b8779ce__";
46
47
 
48
+ // #region Shared config statics. EVERYTHING in this region (and nothing outside it) is redefined
49
+ // below the class by defineSingletonConfig, which replaces each property (via defineProperty)
50
+ // with accessors onto a singleton shared by every copy of this package - the inline values here
51
+ // are just the defaults.
47
52
  /** If set to true parses non-quoted field names, comments, trailing commas, etc */
48
53
  public static EXTENDED_PARSER = false;
49
54
  public static IGNORE_MISSING_REFERENCES = false;
55
+ // #endregion Shared config statics.
50
56
 
51
57
  public static stringify(obj: unknown, config?: JSONLACKS_StringifyConfig): string {
52
58
  let serialized = JSONLACKS.escapeSpecialObjects(obj, config);
@@ -299,6 +305,11 @@ export class JSONLACKS {
299
305
  }
300
306
  }
301
307
 
308
+ defineSingletonConfig(JSONLACKS, "JSONLACKS.config", 1, [
309
+ "EXTENDED_PARSER",
310
+ "IGNORE_MISSING_REFERENCES",
311
+ ]);
312
+
302
313
  async function benchmark() {
303
314
  const loops = 1000 * 100;
304
315
  let inputs: string[] = [];
@@ -17,3 +17,13 @@ export interface Singleton<T> {
17
17
  * get()/set() at each access so every copy sees the latest.
18
18
  */
19
19
  export declare function createSingleton<T>(name: string, version: string | number, getDefault: () => T): Singleton<T>;
20
+ /** Redefines the given (already initialized) properties of target as accessors onto a singleton, so
21
+ * `Target.SOME_SETTING = x` configures every copy of the package instead of only the copy the
22
+ * caller happened to import (which is otherwise decided by module resolution, and so is
23
+ * essentially arbitrary from the caller's perspective). The properties' current values become
24
+ * the defaults, so config statics stay defined inline in the class as usual - just call this
25
+ * below the class with the list of statics to share.
26
+ * - Same versioning rules as createSingleton, except that adding a property is not a shape change:
27
+ * a copy that knows about a property older copies don't backfills it below.
28
+ */
29
+ export declare function defineSingletonConfig<T extends object>(target: T, name: string, version: string | number, keys: (keyof T & string)[]): void;
@@ -74,3 +74,36 @@ export function createSingleton<T>(
74
74
  },
75
75
  };
76
76
  }
77
+
78
+ /** Redefines the given (already initialized) properties of target as accessors onto a singleton, so
79
+ * `Target.SOME_SETTING = x` configures every copy of the package instead of only the copy the
80
+ * caller happened to import (which is otherwise decided by module resolution, and so is
81
+ * essentially arbitrary from the caller's perspective). The properties' current values become
82
+ * the defaults, so config statics stay defined inline in the class as usual - just call this
83
+ * below the class with the list of statics to share.
84
+ * - Same versioning rules as createSingleton, except that adding a property is not a shape change:
85
+ * a copy that knows about a property older copies don't backfills it below.
86
+ */
87
+ export function defineSingletonConfig<T extends object>(
88
+ target: T,
89
+ name: string,
90
+ version: string | number,
91
+ keys: (keyof T & string)[],
92
+ ): void {
93
+ const store = createSingleton<{ [key: string]: unknown }>(name, version, () => Object.create(null)).get();
94
+ for (const key of keys) {
95
+ if (!(key in store)) {
96
+ store[key] = target[key];
97
+ }
98
+ Object.defineProperty(target, key, {
99
+ get() {
100
+ return store[key];
101
+ },
102
+ set(value: unknown) {
103
+ store[key] = value;
104
+ },
105
+ enumerable: true,
106
+ configurable: true,
107
+ });
108
+ }
109
+ }