@mionjs/core 0.8.0-alpha.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.
- package/.dist/cjs/index.cjs +245 -0
- package/.dist/cjs/index.cjs.map +1 -0
- package/.dist/cjs/index.d.ts +21 -0
- package/.dist/cjs/package.json +1 -0
- package/.dist/cjs/src/binary/bodyDeserializer.cjs +54 -0
- package/.dist/cjs/src/binary/bodyDeserializer.cjs.map +1 -0
- package/.dist/cjs/src/binary/bodyDeserializer.d.ts +5 -0
- package/.dist/cjs/src/binary/bodySerializer.cjs +49 -0
- package/.dist/cjs/src/binary/bodySerializer.cjs.map +1 -0
- package/.dist/cjs/src/binary/bodySerializer.d.ts +6 -0
- package/.dist/cjs/src/binary/dataView.cjs +212 -0
- package/.dist/cjs/src/binary/dataView.cjs.map +1 -0
- package/.dist/cjs/src/binary/dataView.d.ts +16 -0
- package/.dist/cjs/src/constants.cjs +84 -0
- package/.dist/cjs/src/constants.cjs.map +1 -0
- package/.dist/cjs/src/constants.d.ts +50 -0
- package/.dist/cjs/src/errors.cjs +170 -0
- package/.dist/cjs/src/errors.cjs.map +1 -0
- package/.dist/cjs/src/errors.d.ts +24 -0
- package/.dist/cjs/src/friendlyErrors.cjs +235 -0
- package/.dist/cjs/src/friendlyErrors.cjs.map +1 -0
- package/.dist/cjs/src/friendlyErrors.d.ts +4 -0
- package/.dist/cjs/src/headers.cjs +11 -0
- package/.dist/cjs/src/headers.cjs.map +1 -0
- package/.dist/cjs/src/headers.d.ts +12 -0
- package/.dist/cjs/src/jit/jitUtils.cjs +173 -0
- package/.dist/cjs/src/jit/jitUtils.cjs.map +1 -0
- package/.dist/cjs/src/jit/jitUtils.d.ts +30 -0
- package/.dist/cjs/src/pureFns/pureFn.cjs +80 -0
- package/.dist/cjs/src/pureFns/pureFn.cjs.map +1 -0
- package/.dist/cjs/src/pureFns/pureFn.d.ts +2 -0
- package/.dist/cjs/src/pureFns/pureServerFn.cjs +20 -0
- package/.dist/cjs/src/pureFns/pureServerFn.cjs.map +1 -0
- package/.dist/cjs/src/pureFns/pureServerFn.d.ts +4 -0
- package/.dist/cjs/src/pureFns/quickHash.cjs +62 -0
- package/.dist/cjs/src/pureFns/quickHash.cjs.map +1 -0
- package/.dist/cjs/src/pureFns/quickHash.d.ts +7 -0
- package/.dist/cjs/src/pureFns/restoreJitFns.cjs +88 -0
- package/.dist/cjs/src/pureFns/restoreJitFns.cjs.map +1 -0
- package/.dist/cjs/src/pureFns/restoreJitFns.d.ts +3 -0
- package/.dist/cjs/src/routerUtils.cjs +209 -0
- package/.dist/cjs/src/routerUtils.cjs.map +1 -0
- package/.dist/cjs/src/routerUtils.d.ts +24 -0
- package/.dist/cjs/src/types/formats/formatBrands.types.cjs +45 -0
- package/.dist/cjs/src/types/formats/formatBrands.types.cjs.map +1 -0
- package/.dist/cjs/src/types/formats/formatBrands.types.d.ts +45 -0
- package/.dist/cjs/src/types/formats/formats.types.cjs +27 -0
- package/.dist/cjs/src/types/formats/formats.types.cjs.map +1 -0
- package/.dist/cjs/src/types/formats/formats.types.d.ts +37 -0
- package/.dist/cjs/src/types/formats/formatsParams.types.cjs +60 -0
- package/.dist/cjs/src/types/formats/formatsParams.types.cjs.map +1 -0
- package/.dist/cjs/src/types/formats/formatsParams.types.d.ts +234 -0
- package/.dist/cjs/src/types/formats/friendlyErrors.types.cjs +53 -0
- package/.dist/cjs/src/types/formats/friendlyErrors.types.cjs.map +1 -0
- package/.dist/cjs/src/types/formats/friendlyErrors.types.d.ts +71 -0
- package/.dist/cjs/src/types/general.types.cjs +145 -0
- package/.dist/cjs/src/types/general.types.cjs.map +1 -0
- package/.dist/cjs/src/types/general.types.d.ts +246 -0
- package/.dist/cjs/src/types/method.types.cjs +26 -0
- package/.dist/cjs/src/types/method.types.cjs.map +1 -0
- package/.dist/cjs/src/types/method.types.d.ts +60 -0
- package/.dist/cjs/src/types/pureFunctions.types.cjs +39 -0
- package/.dist/cjs/src/types/pureFunctions.types.cjs.map +1 -0
- package/.dist/cjs/src/types/pureFunctions.types.d.ts +75 -0
- package/.dist/cjs/src/utils.cjs +47 -0
- package/.dist/cjs/src/utils.cjs.map +1 -0
- package/.dist/cjs/src/utils.d.ts +9 -0
- package/.dist/esm/index.d.ts +21 -0
- package/.dist/esm/index.js +245 -0
- package/.dist/esm/index.js.map +1 -0
- package/.dist/esm/src/binary/bodyDeserializer.d.ts +5 -0
- package/.dist/esm/src/binary/bodyDeserializer.js +54 -0
- package/.dist/esm/src/binary/bodyDeserializer.js.map +1 -0
- package/.dist/esm/src/binary/bodySerializer.d.ts +6 -0
- package/.dist/esm/src/binary/bodySerializer.js +49 -0
- package/.dist/esm/src/binary/bodySerializer.js.map +1 -0
- package/.dist/esm/src/binary/dataView.d.ts +16 -0
- package/.dist/esm/src/binary/dataView.js +212 -0
- package/.dist/esm/src/binary/dataView.js.map +1 -0
- package/.dist/esm/src/constants.d.ts +50 -0
- package/.dist/esm/src/constants.js +84 -0
- package/.dist/esm/src/constants.js.map +1 -0
- package/.dist/esm/src/errors.d.ts +24 -0
- package/.dist/esm/src/errors.js +170 -0
- package/.dist/esm/src/errors.js.map +1 -0
- package/.dist/esm/src/friendlyErrors.d.ts +4 -0
- package/.dist/esm/src/friendlyErrors.js +235 -0
- package/.dist/esm/src/friendlyErrors.js.map +1 -0
- package/.dist/esm/src/headers.d.ts +12 -0
- package/.dist/esm/src/headers.js +11 -0
- package/.dist/esm/src/headers.js.map +1 -0
- package/.dist/esm/src/jit/jitUtils.d.ts +30 -0
- package/.dist/esm/src/jit/jitUtils.js +173 -0
- package/.dist/esm/src/jit/jitUtils.js.map +1 -0
- package/.dist/esm/src/pureFns/pureFn.d.ts +2 -0
- package/.dist/esm/src/pureFns/pureFn.js +80 -0
- package/.dist/esm/src/pureFns/pureFn.js.map +1 -0
- package/.dist/esm/src/pureFns/pureServerFn.d.ts +4 -0
- package/.dist/esm/src/pureFns/pureServerFn.js +20 -0
- package/.dist/esm/src/pureFns/pureServerFn.js.map +1 -0
- package/.dist/esm/src/pureFns/quickHash.d.ts +7 -0
- package/.dist/esm/src/pureFns/quickHash.js +62 -0
- package/.dist/esm/src/pureFns/quickHash.js.map +1 -0
- package/.dist/esm/src/pureFns/restoreJitFns.d.ts +3 -0
- package/.dist/esm/src/pureFns/restoreJitFns.js +88 -0
- package/.dist/esm/src/pureFns/restoreJitFns.js.map +1 -0
- package/.dist/esm/src/routerUtils.d.ts +24 -0
- package/.dist/esm/src/routerUtils.js +209 -0
- package/.dist/esm/src/routerUtils.js.map +1 -0
- package/.dist/esm/src/types/formats/formatBrands.types.d.ts +45 -0
- package/.dist/esm/src/types/formats/formatBrands.types.js +45 -0
- package/.dist/esm/src/types/formats/formatBrands.types.js.map +1 -0
- package/.dist/esm/src/types/formats/formats.types.d.ts +37 -0
- package/.dist/esm/src/types/formats/formats.types.js +27 -0
- package/.dist/esm/src/types/formats/formats.types.js.map +1 -0
- package/.dist/esm/src/types/formats/formatsParams.types.d.ts +234 -0
- package/.dist/esm/src/types/formats/formatsParams.types.js +60 -0
- package/.dist/esm/src/types/formats/formatsParams.types.js.map +1 -0
- package/.dist/esm/src/types/formats/friendlyErrors.types.d.ts +71 -0
- package/.dist/esm/src/types/formats/friendlyErrors.types.js +53 -0
- package/.dist/esm/src/types/formats/friendlyErrors.types.js.map +1 -0
- package/.dist/esm/src/types/general.types.d.ts +246 -0
- package/.dist/esm/src/types/general.types.js +145 -0
- package/.dist/esm/src/types/general.types.js.map +1 -0
- package/.dist/esm/src/types/method.types.d.ts +60 -0
- package/.dist/esm/src/types/method.types.js +26 -0
- package/.dist/esm/src/types/method.types.js.map +1 -0
- package/.dist/esm/src/types/pureFunctions.types.d.ts +75 -0
- package/.dist/esm/src/types/pureFunctions.types.js +39 -0
- package/.dist/esm/src/types/pureFunctions.types.js.map +1 -0
- package/.dist/esm/src/utils.d.ts +9 -0
- package/.dist/esm/src/utils.js +47 -0
- package/.dist/esm/src/utils.js.map +1 -0
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/package.json +58 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { JitCompiledFn, JitFunctionsCache, PureFunctionsCache, PersistedPureFunctionsCache, PureFnsDataCache, DeserializeClassFn, AnyClass, SerializableClass, PersistedJitFunctionsCache, FnsDataCache } from '../types/general.types.ts';
|
|
2
|
+
import { CompiledPureFunction, PureFunction } from '../types/pureFunctions.types.ts';
|
|
3
|
+
export interface JITUtils {
|
|
4
|
+
addToJitCache(comp: JitCompiledFn): void;
|
|
5
|
+
removeFromJitCache(comp: JitCompiledFn): void;
|
|
6
|
+
getJIT(jitFnHash: string): JitCompiledFn | undefined;
|
|
7
|
+
getJitFn(jitFnHash: string): (...args: any[]) => any;
|
|
8
|
+
hasJitFn(jitFnHash: string): boolean;
|
|
9
|
+
addPureFn(namespace: string, compiledFn: CompiledPureFunction): void;
|
|
10
|
+
usePureFn(namespace: string, name: string): PureFunction;
|
|
11
|
+
getPureFn(namespace: string, name: string): PureFunction | undefined;
|
|
12
|
+
getCompiledPureFn(namespace: string, name: string): CompiledPureFunction | undefined;
|
|
13
|
+
hasPureFn(namespace: string, name: string): boolean;
|
|
14
|
+
findCompiledPureFn(name: string): CompiledPureFunction | undefined;
|
|
15
|
+
setSerializableClass<C extends SerializableClass>(cls: C): void;
|
|
16
|
+
useSerializeClass(className: string): SerializableClass;
|
|
17
|
+
getSerializeClass(className: string): SerializableClass | undefined;
|
|
18
|
+
setDeserializeFn<C extends AnyClass>(cls: C, deserializeFn: DeserializeClassFn<InstanceType<C>>): void;
|
|
19
|
+
useDeserializeFn(className: string): DeserializeClassFn<any>;
|
|
20
|
+
getDeserializeFn(className: string): DeserializeClassFn<any> | undefined;
|
|
21
|
+
}
|
|
22
|
+
export declare function getJitUtils(): JITUtils;
|
|
23
|
+
export declare function addAOTCaches(aotFnsCache: PersistedJitFunctionsCache, aotPureCache: PersistedPureFunctionsCache): void;
|
|
24
|
+
export declare function addSerializedJitCaches(jitDataFnsCache: FnsDataCache, pureFnsDataCache: PureFnsDataCache): void;
|
|
25
|
+
export declare function getJitFnCaches(): {
|
|
26
|
+
jitFnsCache: Readonly<JitFunctionsCache>;
|
|
27
|
+
pureFnsCache: Readonly<PureFunctionsCache>;
|
|
28
|
+
};
|
|
29
|
+
export declare function resetJitFnCaches(): void;
|
|
30
|
+
export declare type __ΩJITUtils = any[];
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { isTestEnv, initPureFunction } from "../utils.js";
|
|
2
|
+
import { restoreCompiledJitFns } from "../pureFns/restoreJitFns.js";
|
|
3
|
+
const jitFnsCache = {};
|
|
4
|
+
const pureFnsCache = {};
|
|
5
|
+
const deserializeFnsRegistry = /* @__PURE__ */ new Map();
|
|
6
|
+
const serializableClassRegistry = /* @__PURE__ */ new Map();
|
|
7
|
+
const jitUtils = {
|
|
8
|
+
addToJitCache(comp) {
|
|
9
|
+
jitFnsCache[comp.jitFnHash] = comp;
|
|
10
|
+
},
|
|
11
|
+
removeFromJitCache(comp) {
|
|
12
|
+
if (!jitFnsCache[comp.jitFnHash]) return;
|
|
13
|
+
jitFnsCache[comp.jitFnHash] = void 0;
|
|
14
|
+
},
|
|
15
|
+
getJIT(jitFnHash) {
|
|
16
|
+
return jitFnsCache[jitFnHash];
|
|
17
|
+
},
|
|
18
|
+
getJitFn(jitFnHash) {
|
|
19
|
+
const comp = jitFnsCache[jitFnHash];
|
|
20
|
+
if (!comp) throw new Error(`Jit function not found for jitFnHash ${jitFnHash}`);
|
|
21
|
+
return comp.fn;
|
|
22
|
+
},
|
|
23
|
+
hasJitFn(jitFnHash) {
|
|
24
|
+
return !!jitFnsCache[jitFnHash]?.fn;
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Checks if key map can be serialized/deserialized with json and still works as a key for a map.
|
|
28
|
+
* ie: if a map key is an string, it can be serialized to json and deserialized back an still will identify the correct map entry.
|
|
29
|
+
* ie: if a map entry is an object, the object can not be serialized/deserialized and wont work as the same key for entry map as they are not same memory ref.
|
|
30
|
+
* */
|
|
31
|
+
addPureFn(namespace, compiledFn) {
|
|
32
|
+
const fnHash = compiledFn.fnName;
|
|
33
|
+
if (!fnHash) throw new Error("Pure function must have a name and must be unique");
|
|
34
|
+
const nsCache = ensureNamespace(namespace);
|
|
35
|
+
const existing = nsCache[fnHash];
|
|
36
|
+
if (existing) {
|
|
37
|
+
if (existing.bodyHash && compiledFn.bodyHash && existing.bodyHash !== compiledFn.bodyHash) {
|
|
38
|
+
console.warn(
|
|
39
|
+
`Pure function ${namespace}::${fnHash} body hash mismatch. Existing: ${existing.bodyHash}, New: ${compiledFn.bodyHash}. Replacing with new version.`
|
|
40
|
+
);
|
|
41
|
+
nsCache[fnHash] = compiledFn;
|
|
42
|
+
return compiledFn;
|
|
43
|
+
}
|
|
44
|
+
return existing;
|
|
45
|
+
}
|
|
46
|
+
nsCache[fnHash] = compiledFn;
|
|
47
|
+
return compiledFn;
|
|
48
|
+
},
|
|
49
|
+
usePureFn(namespace, fnHash) {
|
|
50
|
+
const nsCache = pureFnsCache[namespace];
|
|
51
|
+
if (!nsCache) throw new Error(`Pure function namespace ${namespace} not found`);
|
|
52
|
+
const compiled = nsCache[fnHash];
|
|
53
|
+
if (!compiled) throw new Error(`Pure function with name ${fnHash} not found in namespace ${namespace}`);
|
|
54
|
+
initPureFunction(compiled);
|
|
55
|
+
return compiled.fn;
|
|
56
|
+
},
|
|
57
|
+
getPureFn(namespace, fnHash) {
|
|
58
|
+
const nsCache = pureFnsCache[namespace];
|
|
59
|
+
if (!nsCache) return;
|
|
60
|
+
const compiled = nsCache[fnHash];
|
|
61
|
+
if (!compiled) return;
|
|
62
|
+
initPureFunction(compiled);
|
|
63
|
+
return compiled.fn;
|
|
64
|
+
},
|
|
65
|
+
getCompiledPureFn(namespace, fnHash) {
|
|
66
|
+
const nsCache = pureFnsCache[namespace];
|
|
67
|
+
if (!nsCache) return;
|
|
68
|
+
return nsCache[fnHash];
|
|
69
|
+
},
|
|
70
|
+
hasPureFn(namespace, fnHash) {
|
|
71
|
+
const nsCache = pureFnsCache[namespace];
|
|
72
|
+
if (!nsCache) return false;
|
|
73
|
+
return !!nsCache[fnHash];
|
|
74
|
+
},
|
|
75
|
+
findCompiledPureFn(fnHash) {
|
|
76
|
+
for (const namespace of Object.keys(pureFnsCache)) {
|
|
77
|
+
const nsCache = pureFnsCache[namespace];
|
|
78
|
+
if (nsCache && nsCache[fnHash]) return nsCache[fnHash];
|
|
79
|
+
}
|
|
80
|
+
return void 0;
|
|
81
|
+
},
|
|
82
|
+
setSerializableClass(cls) {
|
|
83
|
+
const className = cls.name;
|
|
84
|
+
const existingClass = serializableClassRegistry.get(className);
|
|
85
|
+
if (existingClass && existingClass !== cls) throw new Error(`Deserializable Class ${className} already registered`);
|
|
86
|
+
serializableClassRegistry.set(className, cls);
|
|
87
|
+
},
|
|
88
|
+
useSerializeClass(className) {
|
|
89
|
+
const cls = serializableClassRegistry.get(className);
|
|
90
|
+
if (!cls) throw new Error(`Serializable class with name ${className} not found, be sure to register it first`);
|
|
91
|
+
return cls;
|
|
92
|
+
},
|
|
93
|
+
getSerializeClass(className) {
|
|
94
|
+
return serializableClassRegistry.get(className);
|
|
95
|
+
},
|
|
96
|
+
setDeserializeFn(cls, deserializeFn) {
|
|
97
|
+
const className = cls.name;
|
|
98
|
+
const fn = deserializeFnsRegistry.get(className);
|
|
99
|
+
if (fn && fn !== deserializeFn) throw new Error(`Deserialize function for class ${className} already exists`);
|
|
100
|
+
if (fn) return;
|
|
101
|
+
deserializeFnsRegistry.set(className, deserializeFn);
|
|
102
|
+
},
|
|
103
|
+
useDeserializeFn(className) {
|
|
104
|
+
const fn = deserializeFnsRegistry.get(className);
|
|
105
|
+
if (!fn) throw new Error(`Deserialize function for class ${className} not found, be sure to register it first`);
|
|
106
|
+
return fn;
|
|
107
|
+
},
|
|
108
|
+
getDeserializeFn(className) {
|
|
109
|
+
return deserializeFnsRegistry.get(className);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
function getJitUtils() {
|
|
113
|
+
return jitUtils;
|
|
114
|
+
}
|
|
115
|
+
function addAOTCaches(aotFnsCache, aotPureCache) {
|
|
116
|
+
restoreCaches(aotFnsCache, aotPureCache);
|
|
117
|
+
}
|
|
118
|
+
function addSerializedJitCaches(jitDataFnsCache, pureFnsDataCache) {
|
|
119
|
+
restoreCaches(jitDataFnsCache, pureFnsDataCache);
|
|
120
|
+
}
|
|
121
|
+
function restoreCaches(fnsCache, pureCache) {
|
|
122
|
+
for (const key in fnsCache) {
|
|
123
|
+
if (!(key in jitFnsCache)) {
|
|
124
|
+
jitFnsCache[key] = { ...fnsCache[key] };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
for (const namespace in pureCache) {
|
|
128
|
+
const nsCache = ensureNamespace(namespace);
|
|
129
|
+
const sourceNsCache = pureCache[namespace];
|
|
130
|
+
for (const key in sourceNsCache) {
|
|
131
|
+
const existing = nsCache[key];
|
|
132
|
+
const incoming = sourceNsCache[key];
|
|
133
|
+
if (existing) {
|
|
134
|
+
if (existing.bodyHash && incoming.bodyHash && existing.bodyHash !== incoming.bodyHash) {
|
|
135
|
+
console.warn(
|
|
136
|
+
`Pure function ${namespace}::${key} cache eviction: bodyHash mismatch (cached: ${existing.bodyHash}, server: ${incoming.bodyHash})`
|
|
137
|
+
);
|
|
138
|
+
nsCache[key] = { ...incoming };
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
nsCache[key] = { ...incoming };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
restoreCompiledJitFns(jitFnsCache, pureFnsCache, getJitUtils());
|
|
146
|
+
}
|
|
147
|
+
function getJitFnCaches() {
|
|
148
|
+
return {
|
|
149
|
+
jitFnsCache,
|
|
150
|
+
pureFnsCache
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function resetJitFnCaches() {
|
|
154
|
+
if (!isTestEnv()) throw new Error("resetJitFnCaches() can only be called fro testing purposes");
|
|
155
|
+
for (const k in jitFnsCache) delete jitFnsCache[k];
|
|
156
|
+
for (const k in pureFnsCache) delete pureFnsCache[k];
|
|
157
|
+
deserializeFnsRegistry.clear();
|
|
158
|
+
serializableClassRegistry.clear();
|
|
159
|
+
}
|
|
160
|
+
function ensureNamespace(namespace) {
|
|
161
|
+
if (!pureFnsCache[namespace]) {
|
|
162
|
+
pureFnsCache[namespace] = {};
|
|
163
|
+
}
|
|
164
|
+
return pureFnsCache[namespace];
|
|
165
|
+
}
|
|
166
|
+
export {
|
|
167
|
+
addAOTCaches,
|
|
168
|
+
addSerializedJitCaches,
|
|
169
|
+
getJitFnCaches,
|
|
170
|
+
getJitUtils,
|
|
171
|
+
resetJitFnCaches
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=jitUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jitUtils.js","sources":["../../../../src/jit/jitUtils.ts"],"sourcesContent":["/* ########\n * 2024 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\nimport type {\n JitCompiledFn,\n JitFunctionsCache,\n PureFunctionsCache,\n PersistedPureFunctionsCache,\n PureFnsDataCache,\n DeserializeClassFn,\n AnyClass,\n SerializableClass,\n PersistedJitFunctionsCache,\n FnsDataCache,\n} from '../types/general.types.ts';\nimport {CompiledPureFunction} from '../types/pureFunctions.types.ts';\nimport {PureFunction} from '../types/pureFunctions.types.ts';\nimport {initPureFunction, isTestEnv} from '../utils.ts';\nimport {restoreCompiledJitFns} from '../pureFns/restoreJitFns.ts';\n\n// Local caches - can be populated from AOT caches via addAOTCaches()\nconst jitFnsCache: JitFunctionsCache = {};\n/** Namespaced pure functions cache: { namespace: { fnHash: CompiledPureFunction } } */\nconst pureFnsCache: PureFunctionsCache = {};\n\n// serializable classes registry, serializable classes can be automatically deserialized if they are registered here\nconst deserializeFnsRegistry = new Map<string, DeserializeClassFn<any>>();\nconst serializableClassRegistry = new Map<string, SerializableClass>();\n\n/**\n * Interface defining the shape of jitUtils\n *\n * !! Important: this needs to be defined as a type for reflection to work correctly\n * !! we can not use typeof jitUtils\n */\nexport interface JITUtils {\n /** optimized function to convert an string into a json string wrapped in double quotes */\n addToJitCache(comp: JitCompiledFn): void;\n removeFromJitCache(comp: JitCompiledFn): void;\n getJIT(jitFnHash: string): JitCompiledFn | undefined;\n getJitFn(jitFnHash: string): (...args: any[]) => any;\n hasJitFn(jitFnHash: string): boolean;\n addPureFn(namespace: string, compiledFn: CompiledPureFunction): void;\n usePureFn(namespace: string, name: string): PureFunction;\n getPureFn(namespace: string, name: string): PureFunction | undefined;\n getCompiledPureFn(namespace: string, name: string): CompiledPureFunction | undefined;\n hasPureFn(namespace: string, name: string): boolean;\n /** Find a pure function across all namespaces. Returns the compiled function or undefined. */\n findCompiledPureFn(name: string): CompiledPureFunction | undefined;\n setSerializableClass<C extends SerializableClass>(cls: C): void;\n useSerializeClass(className: string): SerializableClass;\n getSerializeClass(className: string): SerializableClass | undefined;\n setDeserializeFn<C extends AnyClass>(cls: C, deserializeFn: DeserializeClassFn<InstanceType<C>>): void;\n useDeserializeFn(className: string): DeserializeClassFn<any>;\n getDeserializeFn(className: string): DeserializeClassFn<any> | undefined;\n}\n\nconst jitUtils: JITUtils = {\n addToJitCache(comp: JitCompiledFn) {\n jitFnsCache[comp.jitFnHash] = comp;\n },\n removeFromJitCache(comp: JitCompiledFn) {\n if (!jitFnsCache[comp.jitFnHash]) return;\n (jitFnsCache[comp.jitFnHash] as any) = undefined;\n },\n getJIT(jitFnHash: string): JitCompiledFn | undefined {\n return jitFnsCache[jitFnHash];\n },\n getJitFn(jitFnHash: string): (...args: any[]) => any {\n const comp = jitFnsCache[jitFnHash];\n if (!comp) throw new Error(`Jit function not found for jitFnHash ${jitFnHash}`);\n return comp.fn;\n },\n hasJitFn(jitFnHash: string) {\n return !!jitFnsCache[jitFnHash]?.fn;\n },\n /**\n * Checks if key map can be serialized/deserialized with json and still works as a key for a map.\n * ie: if a map key is an string, it can be serialized to json and deserialized back an still will identify the correct map entry.\n * ie: if a map entry is an object, the object can not be serialized/deserialized and wont work as the same key for entry map as they are not same memory ref.\n * */\n\n addPureFn(namespace: string, compiledFn: CompiledPureFunction): CompiledPureFunction {\n const fnHash = compiledFn.fnName;\n if (!fnHash) throw new Error('Pure function must have a name and must be unique');\n const nsCache = ensureNamespace(namespace);\n const existing = nsCache[fnHash];\n if (existing) {\n // Validate body hash matches - if not, this is a version conflict\n if (existing.bodyHash && compiledFn.bodyHash && existing.bodyHash !== compiledFn.bodyHash) {\n console.warn(\n `Pure function ${namespace}::${fnHash} body hash mismatch. ` +\n `Existing: ${existing.bodyHash}, New: ${compiledFn.bodyHash}. ` +\n `Replacing with new version.`\n );\n nsCache[fnHash] = compiledFn;\n return compiledFn;\n }\n return existing;\n }\n\n nsCache[fnHash] = compiledFn;\n return compiledFn;\n },\n usePureFn(namespace: string, fnHash: string): PureFunction {\n const nsCache = pureFnsCache[namespace];\n if (!nsCache) throw new Error(`Pure function namespace ${namespace} not found`);\n const compiled = nsCache[fnHash];\n if (!compiled) throw new Error(`Pure function with name ${fnHash} not found in namespace ${namespace}`);\n initPureFunction(compiled);\n return compiled.fn;\n },\n getPureFn(namespace: string, fnHash: string): PureFunction | undefined {\n const nsCache = pureFnsCache[namespace];\n if (!nsCache) return;\n const compiled = nsCache[fnHash];\n if (!compiled) return;\n initPureFunction(compiled);\n return compiled.fn;\n },\n getCompiledPureFn(namespace: string, fnHash: string): CompiledPureFunction | undefined {\n const nsCache = pureFnsCache[namespace];\n if (!nsCache) return;\n return nsCache[fnHash];\n },\n hasPureFn(namespace: string, fnHash: string): boolean {\n const nsCache = pureFnsCache[namespace];\n if (!nsCache) return false;\n return !!nsCache[fnHash];\n },\n findCompiledPureFn(fnHash: string): CompiledPureFunction | undefined {\n for (const namespace of Object.keys(pureFnsCache)) {\n const nsCache = pureFnsCache[namespace];\n if (nsCache && nsCache[fnHash]) return nsCache[fnHash];\n }\n return undefined;\n },\n setSerializableClass<C extends SerializableClass>(cls: C) {\n const className = cls.name;\n const existingClass = serializableClassRegistry.get(className);\n if (existingClass && existingClass !== cls) throw new Error(`Deserializable Class ${className} already registered`);\n serializableClassRegistry.set(className, cls);\n },\n useSerializeClass(className: string): SerializableClass {\n const cls = serializableClassRegistry.get(className);\n if (!cls) throw new Error(`Serializable class with name ${className} not found, be sure to register it first`);\n return cls;\n },\n getSerializeClass(className: string): SerializableClass | undefined {\n return serializableClassRegistry.get(className);\n },\n setDeserializeFn<C extends AnyClass>(cls: C, deserializeFn: DeserializeClassFn<InstanceType<C>>) {\n const className = cls.name;\n const fn = deserializeFnsRegistry.get(className);\n if (fn && fn !== deserializeFn) throw new Error(`Deserialize function for class ${className} already exists`);\n if (fn) return;\n deserializeFnsRegistry.set(className, deserializeFn);\n },\n useDeserializeFn(className: string): DeserializeClassFn<any> {\n const fn = deserializeFnsRegistry.get(className);\n if (!fn) throw new Error(`Deserialize function for class ${className} not found, be sure to register it first`);\n return fn;\n },\n getDeserializeFn(className: string): DeserializeClassFn<any> | undefined {\n return deserializeFnsRegistry.get(className);\n },\n};\n\n/**\n * Returns the jitUtils instance.\n * This function provides access to the utilities used by JIT generated functions.\n * @returns The JITUtils instance\n */\nexport function getJitUtils(): JITUtils {\n return jitUtils;\n}\n\n/**\n * Adds new AOT JIT and pure functions into the respective caches.\n * This function is intended to be used to restore JitFunctions there were serialized to src code (AOT caches)\n * @param aotFnsCache\n * @param aotPureCache - Namespaced pure functions cache\n */\nexport function addAOTCaches(aotFnsCache: PersistedJitFunctionsCache, aotPureCache: PersistedPureFunctionsCache) {\n restoreCaches(aotFnsCache, aotPureCache);\n}\n\n/**\n * Adds new JIT and pure functions into the respective caches.\n * This function is intended to restore JitFunctions that were serialized and deserialized over the network\n * @param jitDataFnsCache\n * @param pureFnsDataCache - Namespaced pure functions cache\n */\nexport function addSerializedJitCaches(jitDataFnsCache: FnsDataCache, pureFnsDataCache: PureFnsDataCache) {\n restoreCaches(jitDataFnsCache, pureFnsDataCache);\n}\n\nfunction restoreCaches(\n fnsCache: PersistedJitFunctionsCache | FnsDataCache,\n pureCache: PersistedPureFunctionsCache | PureFnsDataCache\n) {\n // First load the caches so all entries are available in the global cache\n // This is needed because createJitFn uses jitUtils.getJIT() to resolve dependencies\n for (const key in fnsCache) {\n if (!(key in jitFnsCache)) {\n // it will be transformed into JitCompiledFn by restoreCompiledJitFns()\n // Cloning to avoid mutating the original\n jitFnsCache[key] = {...fnsCache[key]} as JitCompiledFn;\n }\n }\n // Load namespaced pure functions with hash validation\n for (const namespace in pureCache) {\n const nsCache = ensureNamespace(namespace);\n const sourceNsCache = pureCache[namespace];\n for (const key in sourceNsCache) {\n const existing = nsCache[key];\n const incoming = sourceNsCache[key];\n\n if (existing) {\n // Validate body hash - evict if mismatch\n if (existing.bodyHash && incoming.bodyHash && existing.bodyHash !== incoming.bodyHash) {\n console.warn(\n `Pure function ${namespace}::${key} cache eviction: ` +\n `bodyHash mismatch (cached: ${existing.bodyHash}, server: ${incoming.bodyHash})`\n );\n // Replace with incoming version\n nsCache[key] = {...incoming} as CompiledPureFunction;\n }\n // If hashes match or one is missing, keep existing\n } else {\n // No existing entry, add new one\n nsCache[key] = {...incoming} as CompiledPureFunction;\n }\n }\n }\n // Then restore/initialize the functions (invoke createJitFn to set the fn property)\n // Must restore on the global caches so that when createJitFn calls utl.getJIT() or utl.getPureFn()\n // it gets the restored functions with fn property set\n restoreCompiledJitFns(jitFnsCache, pureFnsCache, getJitUtils());\n}\n\n/**\n * Returns the jit and pure functions caches.\n * DO NOT MODIFY THE RETURNED OBJECTS AS THEY ARE THE ORIGINAL ONES USED BY THE JIT FUNCTIONS\n * @returns\n */\nexport function getJitFnCaches() {\n return {\n jitFnsCache: jitFnsCache as Readonly<JitFunctionsCache>,\n pureFnsCache: pureFnsCache as Readonly<PureFunctionsCache>,\n };\n}\n\n/**\n * Resets the jit and pure functions caches.\n * This is useful for testing purposes only.\n * Note: After calling this, AOT caches must be re-registered via virtual modules or addAOTCaches().\n */\nexport function resetJitFnCaches() {\n if (!isTestEnv()) throw new Error('resetJitFnCaches() can only be called fro testing purposes');\n for (const k in jitFnsCache) delete jitFnsCache[k];\n for (const k in pureFnsCache) delete pureFnsCache[k];\n deserializeFnsRegistry.clear();\n serializableClassRegistry.clear();\n}\n\n/** Helper function to ensure namespace exists in the cache */\nfunction ensureNamespace(namespace: string): Record<string, CompiledPureFunction> {\n if (!pureFnsCache[namespace]) {\n pureFnsCache[namespace] = {};\n }\n return pureFnsCache[namespace];\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { CompiledPureFunction, ParsedFactoryFn, PureFunctionFactory } from '../types/pureFunctions.types.ts';
|
|
2
|
+
export declare function registerPureFnFactory(namespace: string, functionID: string, createPureFn: PureFunctionFactory, parsedFn?: ParsedFactoryFn): CompiledPureFunction;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { getJitUtils } from "../jit/jitUtils.js";
|
|
2
|
+
function __assignType(fn, args) {
|
|
3
|
+
fn.__type = args;
|
|
4
|
+
return fn;
|
|
5
|
+
}
|
|
6
|
+
function registerPureFnFactory(namespace, functionID, createPureFn, parsedFn) {
|
|
7
|
+
if (!parsedFn)
|
|
8
|
+
throw new Error("registerPureFnFactory requires mion vite plugin transform to inject parsedFn");
|
|
9
|
+
const existing = getJitUtils().getCompiledPureFn(namespace, functionID);
|
|
10
|
+
if (existing)
|
|
11
|
+
return existing;
|
|
12
|
+
const compiled = {
|
|
13
|
+
createPureFn,
|
|
14
|
+
fn: null,
|
|
15
|
+
// will be set later so all possible dependencies are resolved
|
|
16
|
+
namespace,
|
|
17
|
+
fnName: functionID,
|
|
18
|
+
bodyHash: parsedFn.bodyHash,
|
|
19
|
+
paramNames: parsedFn.paramNames,
|
|
20
|
+
code: parsedFn.code,
|
|
21
|
+
pureFnDependencies: []
|
|
22
|
+
};
|
|
23
|
+
const { proxy, getDependencies } = createDependencyTrackingProxy();
|
|
24
|
+
try {
|
|
25
|
+
createPureFn(proxy);
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
const detectedDeps = getDependencies();
|
|
29
|
+
for (const dep of detectedDeps) {
|
|
30
|
+
if (dep === functionID)
|
|
31
|
+
continue;
|
|
32
|
+
if (!compiled.pureFnDependencies.includes(dep))
|
|
33
|
+
compiled.pureFnDependencies.push(dep);
|
|
34
|
+
}
|
|
35
|
+
getJitUtils().addPureFn(namespace, compiled);
|
|
36
|
+
return compiled;
|
|
37
|
+
}
|
|
38
|
+
registerPureFnFactory.__type = ["namespace", "functionID", "PureFunctionFactory", "createPureFn", "ParsedFactoryFn", "parsedFn", "CompiledPureFunction", "registerPureFnFactory", `P&2!&2""w#2$"w%2&8"w'/(`];
|
|
39
|
+
function createDependencyTrackingProxy() {
|
|
40
|
+
const dependencies = (Set.Ω = [["&"]], /* @__PURE__ */ new Set());
|
|
41
|
+
const realUtils = getJitUtils();
|
|
42
|
+
const noopFn = () => () => {
|
|
43
|
+
};
|
|
44
|
+
const proxy = new Proxy(realUtils, {
|
|
45
|
+
get(target, prop, receiver) {
|
|
46
|
+
if (prop === "getPureFn" || prop === "usePureFn") {
|
|
47
|
+
return __assignType((ns, fnName) => {
|
|
48
|
+
dependencies.add(fnName);
|
|
49
|
+
const real = target.getPureFn(ns, fnName);
|
|
50
|
+
return real ?? noopFn;
|
|
51
|
+
}, ["ns", "fnName", "", 'P&2!&2""/#']);
|
|
52
|
+
}
|
|
53
|
+
if (prop === "getCompiledPureFn") {
|
|
54
|
+
return __assignType((ns, fnName) => {
|
|
55
|
+
dependencies.add(fnName);
|
|
56
|
+
return target.getCompiledPureFn(ns, fnName);
|
|
57
|
+
}, ["ns", "fnName", "", 'P&2!&2""/#']);
|
|
58
|
+
}
|
|
59
|
+
if (prop === "hasPureFn") {
|
|
60
|
+
return __assignType((ns, fnName) => {
|
|
61
|
+
dependencies.add(fnName);
|
|
62
|
+
return target.hasPureFn(ns, fnName);
|
|
63
|
+
}, ["ns", "fnName", "", 'P&2!&2""/#']);
|
|
64
|
+
}
|
|
65
|
+
if (prop === "findCompiledPureFn") {
|
|
66
|
+
return __assignType((fnName) => {
|
|
67
|
+
dependencies.add(fnName);
|
|
68
|
+
return target.findCompiledPureFn(fnName);
|
|
69
|
+
}, ["fnName", "", 'P&2!"/"']);
|
|
70
|
+
}
|
|
71
|
+
return Reflect.get(target, prop, receiver);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return { proxy, getDependencies: () => dependencies };
|
|
75
|
+
}
|
|
76
|
+
createDependencyTrackingProxy.__type = ["JITUtils", "proxy", "", "getDependencies", "createDependencyTrackingProxy", 'PP"w!4"P&D/#4$M/%'];
|
|
77
|
+
export {
|
|
78
|
+
registerPureFnFactory
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=pureFn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pureFn.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PureFnDef, PureServerFnRef } from '../types/pureFunctions.types.ts';
|
|
2
|
+
export declare const PURE_SERVER_FN_NAMESPACE = "pureServerFn";
|
|
3
|
+
export declare function pureServerFn<F extends (...args: any[]) => any>(pureFn: F, bodyHash?: string): PureServerFnRef<F>;
|
|
4
|
+
export declare function pureServerFn<F extends (...args: any[]) => any>(def: PureFnDef<F>, bodyHash?: string): PureServerFnRef<F>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { __ΩPureServerFnRef as ___PureServerFnRef, __ΩPureFnDef as ___PureFnDef } from "../types/pureFunctions.types.js";
|
|
2
|
+
const PURE_SERVER_FN_NAMESPACE = "pureServerFn";
|
|
3
|
+
pureServerFn.__type = ["pureFn", "bodyHash", () => ___PureServerFnRef, "pureServerFn", 'P"2!&2"8"o#"/$'];
|
|
4
|
+
pureServerFn.__type = [() => ___PureFnDef, "def", "bodyHash", () => ___PureServerFnRef, "pureServerFn", 'P"o!"2"&2#8"o$"/%'];
|
|
5
|
+
function pureServerFn(defOrFn, bodyHash) {
|
|
6
|
+
if (!bodyHash)
|
|
7
|
+
throw new Error("pureServerFn requires mion vite plugin transform to inject bodyHash");
|
|
8
|
+
const isFn = typeof defOrFn === "function";
|
|
9
|
+
const def = isFn ? { pureFn: defOrFn, fnName: bodyHash } : defOrFn;
|
|
10
|
+
const namespace = def.namespace || PURE_SERVER_FN_NAMESPACE;
|
|
11
|
+
const fnName = def.fnName || def.pureFn.name || bodyHash;
|
|
12
|
+
const isFactory = def.isFactory || false;
|
|
13
|
+
return { namespace, fnName, bodyHash, pureFn: def.pureFn, isFactory };
|
|
14
|
+
}
|
|
15
|
+
pureServerFn.__type = [() => ___PureFnDef, "defOrFn", "bodyHash", () => ___PureServerFnRef, "pureServerFn", 'PP"o!""J2"&2#8"o$"/%'];
|
|
16
|
+
export {
|
|
17
|
+
PURE_SERVER_FN_NAMESPACE,
|
|
18
|
+
pureServerFn
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=pureServerFn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pureServerFn.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const hashDefaultLength = 6;
|
|
2
|
+
export declare const defaultLiteralLength = 5;
|
|
3
|
+
export declare const pureFnHashLength = 8;
|
|
4
|
+
export declare function quickHash(input: string, length?: number, prevResult?: string): string;
|
|
5
|
+
export declare function createUniqueHash(id: string, length?: number, isLiteral?: boolean): string;
|
|
6
|
+
export declare function createHashLiteral(id: string, length?: number): string;
|
|
7
|
+
export declare function resetHashes(): void;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getENV } from "../utils.js";
|
|
2
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
3
|
+
const literalHashes = /* @__PURE__ */ new Map();
|
|
4
|
+
const hashChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
5
|
+
const alphaChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
6
|
+
const hashIncrement = 2;
|
|
7
|
+
const maxHashCollisions = 22;
|
|
8
|
+
const PRIME = 37;
|
|
9
|
+
const hashDefaultLength = 6;
|
|
10
|
+
const defaultLiteralLength = 5;
|
|
11
|
+
const pureFnHashLength = 8;
|
|
12
|
+
function quickHash(input, length = hashDefaultLength, prevResult) {
|
|
13
|
+
let hash = 0;
|
|
14
|
+
for (let i = 0; i < input.length; i++) {
|
|
15
|
+
hash = Math.imul(hash, PRIME) + input.charCodeAt(i) >>> 0;
|
|
16
|
+
}
|
|
17
|
+
let result = prevResult || "";
|
|
18
|
+
hash = Math.imul(hash, PRIME) >>> 0;
|
|
19
|
+
result += alphaChars.charAt(hash % alphaChars.length);
|
|
20
|
+
while (result.length < length) {
|
|
21
|
+
hash = Math.imul(hash, PRIME) >>> 0;
|
|
22
|
+
result += hashChars.charAt(hash % hashChars.length);
|
|
23
|
+
}
|
|
24
|
+
return result.slice(0, length);
|
|
25
|
+
}
|
|
26
|
+
function createUniqueHash(id, length = hashDefaultLength, isLiteral = false) {
|
|
27
|
+
const dictionary = isLiteral ? literalHashes : hashes;
|
|
28
|
+
let hash = quickHash(id, length);
|
|
29
|
+
let counter = 1;
|
|
30
|
+
let existingId = dictionary.get(hash);
|
|
31
|
+
while (existingId && existingId !== id) {
|
|
32
|
+
length += counter * hashIncrement;
|
|
33
|
+
const newId = quickHash(id, length, hash);
|
|
34
|
+
if (getENV("DEBUG_JIT"))
|
|
35
|
+
console.warn(
|
|
36
|
+
`Collision for typeID: ${id} with extended hash: ${newId}, and existing typeID: ${existingId} with hash: ${hash}`
|
|
37
|
+
);
|
|
38
|
+
hash = newId;
|
|
39
|
+
counter++;
|
|
40
|
+
existingId = dictionary.get(hash);
|
|
41
|
+
if (counter > maxHashCollisions) throw new Error(`Cannot generate unique hash for typeID: ${id} too many collisions.`);
|
|
42
|
+
}
|
|
43
|
+
dictionary.set(hash, id);
|
|
44
|
+
return hash;
|
|
45
|
+
}
|
|
46
|
+
function createHashLiteral(id, length = defaultLiteralLength) {
|
|
47
|
+
return createUniqueHash(id, length, true);
|
|
48
|
+
}
|
|
49
|
+
function resetHashes() {
|
|
50
|
+
hashes.clear();
|
|
51
|
+
literalHashes.clear();
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
createHashLiteral,
|
|
55
|
+
createUniqueHash,
|
|
56
|
+
defaultLiteralLength,
|
|
57
|
+
hashDefaultLength,
|
|
58
|
+
pureFnHashLength,
|
|
59
|
+
quickHash,
|
|
60
|
+
resetHashes
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=quickHash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickHash.js","sources":["../../../../src/pureFns/quickHash.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport {getENV} from '../utils.ts';\n\nconst hashes = new Map<string, string>();\nconst literalHashes = new Map<string, string>();\nconst hashChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\nconst alphaChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\nconst hashIncrement = 2;\nconst maxHashCollisions = 22;\nconst PRIME = 37; // Prime number to mix hash robustly, but quick\n// TODO: investigate if this is a good default length, we want short hashes for small code size but long enough to avoid to many collisions\n// variable hash length avoids collisions, so there shouldn't be any problems. but better to keep an eye on it\nexport const hashDefaultLength = 6;\nexport const defaultLiteralLength = 5;\n/** Hash length used for pure function body hashes */\nexport const pureFnHashLength = 8;\n\nexport function quickHash(input: string, length = hashDefaultLength, prevResult?: string): string {\n let hash = 0;\n // Generate initial numeric hash using Math.imul and forcing unsigned 32-bit arithmetic\n for (let i = 0; i < input.length; i++) {\n hash = (Math.imul(hash, PRIME) + input.charCodeAt(i)) >>> 0;\n }\n let result = prevResult || '';\n // First char is always from alphaChars to have a valid variable name\n hash = Math.imul(hash, PRIME) >>> 0;\n result += alphaChars.charAt(hash % alphaChars.length);\n // Convert numeric hash to a short alphanumeric string\n while (result.length < length) {\n hash = Math.imul(hash, PRIME) >>> 0;\n result += hashChars.charAt(hash % hashChars.length);\n }\n return result.slice(0, length);\n}\n\nexport function createUniqueHash(id: string, length = hashDefaultLength, isLiteral = false): string {\n const dictionary = isLiteral ? literalHashes : hashes;\n let hash = quickHash(id, length);\n let counter = 1;\n let existingId = dictionary.get(hash);\n // Check if ID already exists and corresponds to the same input\n while (existingId && existingId !== id) {\n length += counter * hashIncrement;\n // generates a longer hash if there are collisions\n // this would allow trying to get all possible hashes for a given input just by increasing the length\n const newId = quickHash(id, length, hash);\n if (getENV('DEBUG_JIT'))\n console.warn(\n `Collision for typeID: ${id} with extended hash: ${newId}, and existing typeID: ${existingId} with hash: ${hash}`\n );\n hash = newId;\n counter++;\n existingId = dictionary.get(hash);\n if (counter > maxHashCollisions) throw new Error(`Cannot generate unique hash for typeID: ${id} too many collisions.`);\n }\n\n // Store the unique ID with its original input string\n dictionary.set(hash, id);\n // console.log(`Jit ID: ${typeID} with hash: ${id}`);\n return hash;\n}\n\nexport function createHashLiteral(id: string, length = defaultLiteralLength): string {\n return createUniqueHash(id, length, true);\n}\n\n/** Resets the hash dictionaries. Useful for testing to ensure consistent hash generation. */\nexport function resetHashes(): void {\n hashes.clear();\n literalHashes.clear();\n}\n"],"names":[],"mappings":";AASA,MAAM,6BAAa,IAAA;AACnB,MAAM,oCAAoB,IAAA;AAC1B,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AAC1B,MAAM,QAAQ;AAGP,MAAM,oBAAoB;AAC1B,MAAM,uBAAuB;AAE7B,MAAM,mBAAmB;AAEzB,SAAS,UAAU,OAAe,SAAS,mBAAmB,YAA6B;AAC9F,MAAI,OAAO;AAEX,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,WAAQ,KAAK,KAAK,MAAM,KAAK,IAAI,MAAM,WAAW,CAAC,MAAO;AAAA,EAC9D;AACA,MAAI,SAAS,cAAc;AAE3B,SAAO,KAAK,KAAK,MAAM,KAAK,MAAM;AAClC,YAAU,WAAW,OAAO,OAAO,WAAW,MAAM;AAEpD,SAAO,OAAO,SAAS,QAAQ;AAC3B,WAAO,KAAK,KAAK,MAAM,KAAK,MAAM;AAClC,cAAU,UAAU,OAAO,OAAO,UAAU,MAAM;AAAA,EACtD;AACA,SAAO,OAAO,MAAM,GAAG,MAAM;AACjC;AAEO,SAAS,iBAAiB,IAAY,SAAS,mBAAmB,YAAY,OAAe;AAChG,QAAM,aAAa,YAAY,gBAAgB;AAC/C,MAAI,OAAO,UAAU,IAAI,MAAM;AAC/B,MAAI,UAAU;AACd,MAAI,aAAa,WAAW,IAAI,IAAI;AAEpC,SAAO,cAAc,eAAe,IAAI;AACpC,cAAU,UAAU;AAGpB,UAAM,QAAQ,UAAU,IAAI,QAAQ,IAAI;AACxC,QAAI,OAAO,WAAW;AAClB,cAAQ;AAAA,QACJ,yBAAyB,EAAE,wBAAwB,KAAK,0BAA0B,UAAU,eAAe,IAAI;AAAA,MAAA;AAEvH,WAAO;AACP;AACA,iBAAa,WAAW,IAAI,IAAI;AAChC,QAAI,UAAU,kBAAmB,OAAM,IAAI,MAAM,2CAA2C,EAAE,uBAAuB;AAAA,EACzH;AAGA,aAAW,IAAI,MAAM,EAAE;AAEvB,SAAO;AACX;AAEO,SAAS,kBAAkB,IAAY,SAAS,sBAA8B;AACjF,SAAO,iBAAiB,IAAI,QAAQ,IAAI;AAC5C;AAGO,SAAS,cAAoB;AAChC,SAAO,MAAA;AACP,gBAAc,MAAA;AAClB;"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { PersistedJitFunctionsCache, PersistedPureFunctionsCache, FnsDataCache, PureFnsDataCache, PureFunctionsCache } from '../types/general.types.ts';
|
|
2
|
+
import { JITUtils } from '../jit/jitUtils.ts';
|
|
3
|
+
export declare function restoreCompiledJitFns(jitCache: PersistedJitFunctionsCache | FnsDataCache, pureCache: PureFunctionsCache | PersistedPureFunctionsCache | PureFnsDataCache, jUtil: JITUtils): void;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { TypedError } from "../errors.js";
|
|
2
|
+
function restoreCompiledJitFns(jitCache, pureCache, jUtil) {
|
|
3
|
+
const visitedPure = /* @__PURE__ */ new Set();
|
|
4
|
+
const visitedJit = /* @__PURE__ */ new Set();
|
|
5
|
+
for (const namespace in pureCache) {
|
|
6
|
+
const nsCache = pureCache[namespace];
|
|
7
|
+
const keysPureFns = Object.keys(nsCache);
|
|
8
|
+
keysPureFns.forEach((key) => restoreCompiledPureFn(pureCache, namespace, key, jUtil, visitedPure));
|
|
9
|
+
}
|
|
10
|
+
const keysJitFns = Object.keys(jitCache);
|
|
11
|
+
keysJitFns.forEach((key) => restoreCompiledJitFn(jitCache, pureCache, key, jUtil, visitedPure, visitedJit));
|
|
12
|
+
}
|
|
13
|
+
function restoreCompiledPureFn(pureCache, namespace, fnName, jUtil, visited) {
|
|
14
|
+
const visitedKey = `${namespace}:${fnName}`;
|
|
15
|
+
if (visited.has(visitedKey)) return;
|
|
16
|
+
visited.add(visitedKey);
|
|
17
|
+
const nsCache = pureCache[namespace];
|
|
18
|
+
if (!nsCache) throw new Error(`Pure function namespace ${namespace} not found`);
|
|
19
|
+
const pureCompiled = nsCache[fnName];
|
|
20
|
+
if (!pureCompiled) throw new Error(`Pure function ${fnName} not found in namespace ${namespace}`);
|
|
21
|
+
if (pureCompiled.fn) return;
|
|
22
|
+
const dependencies = pureCompiled.pureFnDependencies;
|
|
23
|
+
dependencies.forEach((depName) => restoreCompiledPureFn(pureCache, namespace, depName, jUtil, visited));
|
|
24
|
+
if (pureCompiled.createPureFn) {
|
|
25
|
+
pureCompiled.fn = pureCompiled.createPureFn(jUtil);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
restorePureFunction(pureCompiled, jUtil);
|
|
29
|
+
}
|
|
30
|
+
function restoreCompiledJitFn(jitCache, pureCache, fnHash, jUtil, visitedPure, visitedJit) {
|
|
31
|
+
if (visitedJit.has(fnHash)) return;
|
|
32
|
+
visitedJit.add(fnHash);
|
|
33
|
+
const jitCompiled = jitCache[fnHash];
|
|
34
|
+
if (!jitCompiled) throw new Error(`Jit function ${fnHash} not found`);
|
|
35
|
+
if (jitCompiled.fn) return;
|
|
36
|
+
const pureDependencies = jitCompiled.pureFnDependencies;
|
|
37
|
+
pureDependencies.forEach((dep) => {
|
|
38
|
+
const parts = dep.split("::");
|
|
39
|
+
if (parts.length !== 2) throw new Error(`Invalid pure function dependency format: ${dep}, expected "namespace::fnHash"`);
|
|
40
|
+
const [namespace, fnHash2] = parts;
|
|
41
|
+
restoreCompiledPureFn(pureCache, namespace, fnHash2, jUtil, visitedPure);
|
|
42
|
+
});
|
|
43
|
+
const dependencies = jitCompiled.jitDependencies;
|
|
44
|
+
dependencies.forEach((dep) => restoreCompiledJitFn(jitCache, pureCache, dep, jUtil, visitedPure, visitedJit));
|
|
45
|
+
if (jitCompiled.createJitFn) {
|
|
46
|
+
jitCompiled.fn = jitCompiled.createJitFn(jUtil);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
restoreCreateJitFn(jitCompiled, jUtil);
|
|
50
|
+
}
|
|
51
|
+
function restoreCreateJitFn(fnData, jUtil) {
|
|
52
|
+
const fnName = fnData.jitFnHash;
|
|
53
|
+
const fnWithContext = `'use strict'; ${fnData.code}`;
|
|
54
|
+
try {
|
|
55
|
+
const wrapperWithContext = new Function("utl", fnWithContext);
|
|
56
|
+
const fn = wrapperWithContext(jUtil);
|
|
57
|
+
const jitFn = fnData;
|
|
58
|
+
jitFn.createJitFn = wrapperWithContext;
|
|
59
|
+
jitFn.fn = fn;
|
|
60
|
+
return jitFn;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
throw new TypedError({
|
|
63
|
+
type: "jit-fn-restore-error",
|
|
64
|
+
message: `Failed to restore JIT function ${fnName}: ${e?.message}`
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function restorePureFunction(pureFnData, jUtil) {
|
|
69
|
+
const fnName = pureFnData.fnName;
|
|
70
|
+
const fnWithContext = `'use strict'; ${pureFnData.code}`;
|
|
71
|
+
try {
|
|
72
|
+
const wrapperWithContext = new Function("utl", fnWithContext);
|
|
73
|
+
const fn = wrapperWithContext(jUtil);
|
|
74
|
+
const pureFn = pureFnData;
|
|
75
|
+
pureFn.createPureFn = wrapperWithContext;
|
|
76
|
+
pureFn.fn = fn;
|
|
77
|
+
return pureFn;
|
|
78
|
+
} catch (e) {
|
|
79
|
+
throw new TypedError({
|
|
80
|
+
type: "pure-fn-restore-error",
|
|
81
|
+
message: `Failed to restore pure function ${fnName}: ${e?.message}`
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export {
|
|
86
|
+
restoreCompiledJitFns
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=restoreJitFns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreJitFns.js","sources":["../../../../src/pureFns/restoreJitFns.ts"],"sourcesContent":["/* ########\n * 2025 mion\n * Author: Ma-jerez\n * License: MIT\n * The software is provided \"as is\", without warranty of any kind.\n * ######## */\n\nimport type {\n Mutable,\n JitCompiledFn,\n PersistedJitFunctionsCache,\n PersistedPureFunctionsCache,\n FnsDataCache,\n PureFnsDataCache,\n PureFunctionsCache,\n JitCompiledFnData,\n PersistedJitFn,\n} from '../types/general.types.ts';\nimport {JITUtils} from '../jit/jitUtils.ts';\nimport type {PersistedPureFunction} from '../types/pureFunctions.types.ts';\nimport type {CompiledPureFunction} from '../types/pureFunctions.types.ts';\nimport type {PureFunctionData} from '../types/pureFunctions.types.ts';\nimport type {PureFunctionFactory} from '../types/pureFunctions.types.ts';\nimport {TypedError} from '../errors.ts';\n\n/**\n * Restores the full state of a persisted/serialized jit functions.\n * This functions mutates the input caches!!!\n * Persisted functions are jit functions written to code that contains the createJitFn closure but not the fn.\n * Serialized functions are jit functions sent over the network that contains the code to recreate the createJitFn closure and fn.\n * The JIT fn itself can't be compiled to code as it contains references to context code and jitUtils.\n * So we need to restore it manually by invoking the closure function.\n * */\nexport function restoreCompiledJitFns(\n jitCache: PersistedJitFunctionsCache | FnsDataCache,\n pureCache: PureFunctionsCache | PersistedPureFunctionsCache | PureFnsDataCache,\n jUtil: JITUtils\n): void {\n // Use visited sets to prevent infinite recursion on circular dependencies\n // This is needed because during restoration, the `fn` property is not set until after\n // all dependencies are restored, so checking `fn` alone can't prevent circular calls\n const visitedPure = new Set<string>();\n const visitedJit = new Set<string>();\n\n // Iterate over all namespaces and restore pure functions\n for (const namespace in pureCache) {\n const nsCache = pureCache[namespace];\n const keysPureFns = Object.keys(nsCache);\n keysPureFns.forEach((key) => restoreCompiledPureFn(pureCache, namespace, key, jUtil, visitedPure));\n }\n const keysJitFns = Object.keys(jitCache);\n keysJitFns.forEach((key) => restoreCompiledJitFn(jitCache, pureCache, key, jUtil, visitedPure, visitedJit));\n}\n\nfunction restoreCompiledPureFn(\n pureCache: PureFunctionsCache | PersistedPureFunctionsCache | PureFnsDataCache,\n namespace: string,\n fnName: string,\n jUtil: JITUtils,\n visited: Set<string>\n) {\n // Use namespace:fnName as the visited key to handle same function names in different namespaces\n const visitedKey = `${namespace}:${fnName}`;\n // Skip if already visited (handles circular dependencies)\n if (visited.has(visitedKey)) return;\n visited.add(visitedKey);\n\n const nsCache = pureCache[namespace];\n if (!nsCache) throw new Error(`Pure function namespace ${namespace} not found`);\n const pureCompiled = nsCache[fnName];\n if (!pureCompiled) throw new Error(`Pure function ${fnName} not found in namespace ${namespace}`);\n if ((pureCompiled as CompiledPureFunction).fn) return;\n const dependencies = pureCompiled.pureFnDependencies;\n // Dependencies are in the same namespace\n dependencies.forEach((depName) => restoreCompiledPureFn(pureCache, namespace, depName, jUtil, visited));\n // persisted pure functions (AOT code caches) have the createJitFn but not the fn\n if ((pureCompiled as PersistedPureFunction).createPureFn) {\n (pureCompiled as any as Mutable<CompiledPureFunction>).fn = (pureCompiled as PersistedPureFunction).createPureFn(jUtil);\n return;\n }\n // serialized pure functions (network sent) do not contains neither createJitFn nor fn\n restorePureFunction(pureCompiled, jUtil);\n}\n\nfunction restoreCompiledJitFn(\n jitCache: PersistedJitFunctionsCache | FnsDataCache,\n pureCache: PureFunctionsCache | PersistedPureFunctionsCache | PureFnsDataCache,\n fnHash: string,\n jUtil: JITUtils,\n visitedPure: Set<string>,\n visitedJit: Set<string>\n) {\n // Skip if already visited (handles circular dependencies)\n if (visitedJit.has(fnHash)) return;\n visitedJit.add(fnHash);\n\n const jitCompiled = jitCache[fnHash];\n if (!jitCompiled) throw new Error(`Jit function ${fnHash} not found`);\n if ((jitCompiled as JitCompiledFn).fn) return;\n const pureDependencies = jitCompiled.pureFnDependencies;\n // Pure function dependencies are stored as \"namespace::fnHash\"\n pureDependencies.forEach((dep) => {\n const parts = dep.split('::');\n if (parts.length !== 2) throw new Error(`Invalid pure function dependency format: ${dep}, expected \"namespace::fnHash\"`);\n const [namespace, fnHash] = parts;\n restoreCompiledPureFn(pureCache, namespace, fnHash, jUtil, visitedPure);\n });\n const dependencies = jitCompiled.jitDependencies;\n dependencies.forEach((dep) => restoreCompiledJitFn(jitCache, pureCache, dep, jUtil, visitedPure, visitedJit));\n if ((jitCompiled as PersistedJitFn).createJitFn) {\n (jitCompiled as any as Mutable<JitCompiledFn>).fn = (jitCompiled as PersistedJitFn).createJitFn(jUtil);\n return;\n }\n restoreCreateJitFn(jitCompiled, jUtil);\n}\n\n/**\n * Restores a JIT function from serialized function data.\n * This functionsMutates the input data!!!\n * Creates a dynamic function using the serialized code (which already contains the complete function with context),\n * then executes it with jitUtils to produce the final JIT function.\n * @param fnData - The serialized function data containing code, args, and metadata\n * @returns A JitCompiledFn with both the createJitFn closure and the executed fn\n */\nfunction restoreCreateJitFn(fnData: JitCompiledFnData, jUtil: JITUtils): JitCompiledFn {\n const fnName = fnData.jitFnHash;\n // fnData.code already contains the complete function with context (e.g., \"const x = ...; return function fnName(args){...}\")\n const fnWithContext = `'use strict'; ${fnData.code}`;\n try {\n // Create wrapper function that works as a factory and returns the actual jit function\n const wrapperWithContext = new Function('utl', fnWithContext) as (utl: JITUtils) => (...args: any[]) => any;\n // Execute the wrapper with jitUtils to get the final function\n const fn = wrapperWithContext(jUtil);\n const jitFn = fnData as Mutable<JitCompiledFn>;\n jitFn.createJitFn = wrapperWithContext;\n jitFn.fn = fn;\n return jitFn;\n } catch (e: any) {\n throw new TypedError({\n type: 'jit-fn-restore-error',\n message: `Failed to restore JIT function ${fnName}: ${e?.message}`,\n });\n }\n}\n\n/**\n * Restores a pure function from serialized function data.\n * This function mutates the input data!!!\n * Creates a dynamic function using the serialized code (which already contains the complete function with context),\n * then executes it with jitUtils to produce the final pure function.\n * @param pureFnData - The serialized pure function data containing code and metadata\n * @returns A CompiledPureFunction with both the createJitFn closure and the executed fn\n */\nfunction restorePureFunction(pureFnData: PureFunctionData, jUtil: JITUtils): CompiledPureFunction {\n const fnName = pureFnData.fnName;\n // pureFnData.code already contains the complete function with context\n const fnWithContext = `'use strict'; ${pureFnData.code}`;\n try {\n // Create wrapper function that works as a factory and returns the actual pure function\n const wrapperWithContext = new Function('utl', fnWithContext) as PureFunctionFactory;\n // Execute the wrapper with jitUtils to get the final function\n const fn = wrapperWithContext(jUtil);\n const pureFn = pureFnData as Mutable<CompiledPureFunction>;\n pureFn.createPureFn = wrapperWithContext;\n pureFn.fn = fn;\n return pureFn;\n } catch (e: any) {\n throw new TypedError({\n type: 'pure-fn-restore-error',\n message: `Failed to restore pure function ${fnName}: ${e?.message}`,\n });\n }\n}\n"],"names":["fnHash"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RemoteMethodOpts, MethodWithOptions, MethodsCache, MethodWithOptsAndJitFns } from './types/method.types.ts';
|
|
2
|
+
import { CoreRouterOptions, JitCompiledFunctions, JitFunctionsHashes } from './types/general.types.ts';
|
|
3
|
+
export declare const routesCache: {
|
|
4
|
+
getMetadata(id: string): MethodWithOptions | undefined;
|
|
5
|
+
setMetadata(id: string, methodData: MethodWithOptions): void;
|
|
6
|
+
hasMetadata(id: string): boolean;
|
|
7
|
+
getCache(): MethodsCache;
|
|
8
|
+
getMethodJitFns(id: string): MethodWithOptsAndJitFns | undefined;
|
|
9
|
+
useMethodJitFns(id: string): MethodWithOptsAndJitFns;
|
|
10
|
+
setMethodJitFns(id: string, MethodWithOptsAndJitFns: MethodWithOptsAndJitFns): void;
|
|
11
|
+
};
|
|
12
|
+
export declare const methodOptsCache: {
|
|
13
|
+
getMethodOptions(id: string): RemoteMethodOpts | undefined;
|
|
14
|
+
setMethodOptions(id: string, options: RemoteMethodOpts): void;
|
|
15
|
+
};
|
|
16
|
+
export declare function addRoutesToCache(newCache: MethodsCache): void;
|
|
17
|
+
export declare function getJitFnHashes(jitHash: string): JitFunctionsHashes;
|
|
18
|
+
export declare function getJitFunctionsFromHash(jitHash: string): JitCompiledFunctions;
|
|
19
|
+
export declare function getHeaderJitFunctionsFromHash(jitHash: string): Pick<JitCompiledFunctions, 'isType' | 'typeErrors'>;
|
|
20
|
+
export declare function getRouterItemId(itemPointer: string[]): string;
|
|
21
|
+
export declare function getRoutePath(pathPointer: string[], routerOptions: CoreRouterOptions): string;
|
|
22
|
+
export declare function resetRoutesCache(): void;
|
|
23
|
+
export declare function resetJitFunctionsCache(): void;
|
|
24
|
+
export declare function getNoopJitFns(): JitCompiledFunctions;
|