@cldmv/slothlet 2.2.0 → 2.3.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.
@@ -35,8 +35,98 @@ export const runWithCtx = (ctx, fn, thisArg, args) => {
35
35
  export const getCtx = () => als.getStore() || null;
36
36
 
37
37
 
38
+ const EXCLUDED_CONSTRUCTORS = new Set([Object, Array, Promise, Date, RegExp, Error]);
39
+
40
+
41
+ const EXCLUDED_INSTANCEOF_CLASSES = [ArrayBuffer, Map, Set, WeakMap, WeakSet];
42
+
43
+
44
+ function runtime_shouldWrapMethod(value, prop) {
45
+ return (
46
+ typeof value === "function" &&
47
+ typeof prop === "string" &&
48
+ prop !== "constructor" &&
49
+ !(prop in Object.prototype) &&
50
+ !prop.startsWith("__")
51
+ );
52
+ }
53
+
54
+
55
+ function runtime_isClassInstance(val) {
56
+ if (
57
+ val == null ||
58
+ typeof val !== "object" ||
59
+ !val.constructor ||
60
+ typeof val.constructor !== "function" ||
61
+ EXCLUDED_CONSTRUCTORS.has(val.constructor)
62
+ ) {
63
+ return false;
64
+ }
65
+
66
+ for (const cls of EXCLUDED_INSTANCEOF_CLASSES) {
67
+ if (typeof cls === "function" && val instanceof cls) {
68
+ return false;
69
+ }
70
+ }
71
+
72
+ return true;
73
+ }
74
+
75
+
76
+ function runtime_wrapClassInstance(instance, ctx, wrapFn, instanceCache) {
77
+ if (instanceCache.has(instance)) {
78
+ return instanceCache.get(instance);
79
+ }
80
+
81
+
82
+ const methodCache = new Map();
83
+
84
+ const wrappedInstance = new Proxy(instance, {
85
+ get(target, prop, receiver) {
86
+
87
+ if (methodCache.has(prop)) {
88
+ return methodCache.get(prop);
89
+ }
90
+
91
+ const value = Reflect.get(target, prop, receiver);
92
+
93
+
94
+
95
+ if (runtime_shouldWrapMethod(value, prop)) {
96
+
97
+
98
+ const runtime_contextPreservingMethod = function (...args) {
99
+ const result = runWithCtx(ctx, value, target, args);
100
+
101
+ return wrapFn(result);
102
+ };
103
+
104
+
105
+ methodCache.set(prop, runtime_contextPreservingMethod);
106
+ return runtime_contextPreservingMethod;
107
+ }
108
+
109
+
110
+ return wrapFn(value);
111
+ },
112
+
113
+ set(target, prop, value, receiver) {
114
+
115
+ if (methodCache.has(prop)) {
116
+ methodCache.delete(prop);
117
+ }
118
+ return Reflect.set(target, prop, value, receiver);
119
+ }
120
+ });
121
+
122
+ instanceCache.set(instance, wrappedInstance);
123
+ return wrappedInstance;
124
+ }
125
+
126
+
38
127
  export const makeWrapper = (ctx) => {
39
128
  const cache = new WeakMap();
129
+ const instanceCache = new WeakMap();
40
130
  const wrap = (val) => {
41
131
  if (val == null || (typeof val !== "object" && typeof val !== "function")) return val;
42
132
  if (cache.has(val)) return cache.get(val);
@@ -53,11 +143,26 @@ export const makeWrapper = (ctx) => {
53
143
 
54
144
 
55
145
 
56
- return runWithCtx(ctx, target, thisArg, args);
146
+
147
+ const result = runWithCtx(ctx, target, thisArg, args);
148
+
149
+
150
+ if (runtime_isClassInstance(result)) {
151
+ return runtime_wrapClassInstance(result, ctx, wrap, instanceCache);
152
+ }
153
+
154
+ return result;
57
155
  },
58
156
  construct(target, args, newTarget) {
59
157
 
60
- return runWithCtx(ctx, Reflect.construct, undefined, [target, args, newTarget]);
158
+ const result = runWithCtx(ctx, Reflect.construct, undefined, [target, args, newTarget]);
159
+
160
+
161
+ if (runtime_isClassInstance(result)) {
162
+ return runtime_wrapClassInstance(result, ctx, wrap, instanceCache);
163
+ }
164
+
165
+ return result;
61
166
  },
62
167
  get(target, prop, receiver) {
63
168
  return wrap(Reflect.get(target, prop, receiver));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cldmv/slothlet",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "moduleVersions": {
5
5
  "lazy": "1.0.0",
6
6
  "eager": "1.0.0"
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime.mjs"],"names":[],"mappings":"AA0CO,gCAdI,MAAM,yBAEN,GAAG,gBAED,GAAG,CA6Bf;AAiBM,0BAZM,MAAM,GAAC,IAAI,CAY0B;AAsB3C,iCAjBI,MAAM,YAwDhB;AA4RD;;;;;;;;;;;;;GAaG;AACH,mBATU,WAAS,MAAM,CAS6B;AAEtD;;;;;;;;;;;;;GAaG;AACH,sBATU,MAAM,CAS4C;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBATU,MAAM,CASgD"}
1
+ {"version":3,"file":"runtime.d.mts","sourceRoot":"","sources":["../../../../dist/lib/runtime/runtime.mjs"],"names":[],"mappings":"AA0CO,gCAdI,MAAM,yBAEN,GAAG,gBAED,GAAG,CA6Bf;AAiBM,0BAZM,MAAM,GAAC,IAAI,CAY0B;AA8K3C,iCAjBI,MAAM,YAwEhB;AA4RD;;;;;;;;;;;;;GAaG;AACH,mBATU,WAAS,MAAM,CAS6B;AAEtD;;;;;;;;;;;;;GAaG;AACH,sBATU,MAAM,CAS4C;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBATU,MAAM,CASgD"}