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.
- package/.claude/settings.local.json +2 -1
- package/SocketFunction.d.ts +1 -1
- package/SocketFunction.ts +32 -4
- package/index.d.ts +11 -1
- package/package.json +1 -1
- package/src/JSONLACKS/JSONLACKS.ts +11 -0
- package/src/createSingleton.d.ts +10 -0
- package/src/createSingleton.ts +33 -0
|
@@ -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
|
}
|
package/SocketFunction.d.ts
CHANGED
|
@@ -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
|
@@ -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[] = [];
|
package/src/createSingleton.d.ts
CHANGED
|
@@ -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;
|
package/src/createSingleton.ts
CHANGED
|
@@ -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
|
+
}
|