Skip to content

Commit 0eaa7fd

Browse files
committed
first commit
0 parents  commit 0eaa7fd

File tree

7 files changed

+207
-0
lines changed

7 files changed

+207
-0
lines changed

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.DS_Store
2+
.nyc_output
3+
v8.log
4+
coverage/
5+
node_modules/
6+
cjs/*
7+
!cjs/package.json

.npmignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.DS_Store
2+
.nyc_output
3+
.eslintrc.json
4+
.github/
5+
.travis.yml
6+
v8.log
7+
coverage/
8+
node_modules/
9+
rollup/
10+
test/

.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

cjs/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"type":"commonjs"}

esm/index.js

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import * as handlerTraps from 'proxy-target/traps';
2+
import * as handlerTypes from 'proxy-target/types';
3+
import { bound } from 'proxy-target';
4+
import { create, drop } from 'gc-hook';
5+
6+
const { ARRAY, FUNCTION, NULL, OBJECT } = handlerTypes;
7+
const { Object, Proxy, Reflect } = globalThis;
8+
9+
const { isArray } = Array;
10+
const { create: extend, entries, values } = Object;
11+
12+
const traps = new Set([...values(handlerTraps)]);
13+
const types = new Set([...values(handlerTypes)]);
14+
const typesOf = new WeakMap;
15+
16+
const extendHandler = (handler, type, value) => {
17+
const descriptors = { type: { value: type } };
18+
for(const trap of traps)
19+
descriptors[trap] = value(handler[trap] || Reflect[trap]);
20+
return extend(handler, descriptors);
21+
};
22+
23+
const proxy = ($, target, handler, token = false) => {
24+
const p = new Proxy(target, handler);
25+
const { destruct } = handler;
26+
return destruct ? create($, destruct, { token, return: p }) : p;
27+
};
28+
29+
export const proxyOf = namespace => {
30+
const proxies = { free: token => drop(token) };
31+
for (const [type, traps] of entries(namespace)) {
32+
switch (type) {
33+
case ARRAY: {
34+
const handler = extendHandler(traps, type, method => ({
35+
value([ $ ], ..._) {
36+
return method.call(this, $, ..._);
37+
}
38+
}));
39+
proxies[type] = ($, ..._) => proxy($, [ $ ], handler, ..._);
40+
break;
41+
}
42+
case FUNCTION: {
43+
const handler = extendHandler(traps, type, method => ({
44+
value($, ..._) {
45+
return method.call(this, $(), ..._);
46+
}
47+
}));
48+
proxies[type] = ($, ..._) => proxy($, bound($), handler, ..._);
49+
break;
50+
}
51+
case OBJECT: {
52+
const handler = extendHandler(traps, type, method => ({
53+
value({ $ }, ..._) {
54+
return method.call(this, $, ..._);
55+
}
56+
}));
57+
proxies[type] = ($, ..._) => proxy($, { $ }, handler, ..._);
58+
break;
59+
}
60+
default: {
61+
if (types.has(type)) {
62+
const handler = extendHandler(traps, type, method => ({
63+
value($, ..._) {
64+
return method.call(this, $.valueOf(), ..._);
65+
}
66+
}));
67+
proxies[type] = ($, ..._) => {
68+
const p = proxy($, Object($), handler, ..._);
69+
typesOf.set(p, type);
70+
return p;
71+
};
72+
}
73+
else {
74+
const handler = extendHandler(traps, type, value => ({ value }));
75+
proxies[type] = ($, token = $) => {
76+
const p = proxy($, $, handler, token);
77+
typesOf.set(p, type);
78+
return p;
79+
};
80+
}
81+
break;
82+
}
83+
}
84+
}
85+
return proxies;
86+
};
87+
88+
export const typeOf = value => {
89+
let type = typeof value;
90+
if (type === OBJECT) {
91+
type = value === null ?
92+
NULL :
93+
(isArray(value) ? ARRAY : (typesOf.get(value) || OBJECT))
94+
;
95+
}
96+
return type;
97+
};

package.json

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "js-proxy",
3+
"version": "0.1.0",
4+
"description": "",
5+
"main": "./cjs/index.js",
6+
"scripts": {
7+
"build": "npm run cjs && npm run test",
8+
"cjs": "ascjs esm cjs",
9+
"coveralls": "c8 report --reporter=text-lcov | coveralls",
10+
"test": "c8 node test/index.js"
11+
},
12+
"keywords": [],
13+
"author": "Andrea Giammarchi",
14+
"license": "ISC",
15+
"devDependencies": {
16+
"ascjs": "^6.0.3",
17+
"c8": "^9.1.0",
18+
"coveralls": "^3.1.1"
19+
},
20+
"module": "./esm/index.js",
21+
"type": "module",
22+
"exports": {
23+
".": {
24+
"import": "./esm/index.js",
25+
"default": "./cjs/index.js"
26+
},
27+
"./package.json": "./package.json"
28+
},
29+
"dependencies": {
30+
"gc-hook": "^0.3.1",
31+
"proxy-target": "^3.0.2"
32+
}
33+
}

test/index.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { typeOf, proxyOf } from '../esm/index.js';
2+
3+
// 🦄 typeOf coverage related
4+
let proxied = proxyOf({
5+
// native cases
6+
array: {},
7+
function: {},
8+
object: {},
9+
10+
// extra primitives
11+
bigint: {
12+
get(target, key) {
13+
const value = target[key];
14+
return typeof value === 'function' ?
15+
value.bind(target) : value;
16+
},
17+
getPrototypeOf: () => BigInt.prototype,
18+
},
19+
boolean: {},
20+
null: {},
21+
number: {},
22+
string: {},
23+
symbol: {},
24+
undefined: {},
25+
26+
// custom direct/defined
27+
direct: {},
28+
});
29+
30+
// typeOf native cases
31+
console.assert(typeOf([]) === 'array');
32+
console.assert(typeOf(proxied.array(0)) === 'array');
33+
console.assert(typeOf(()=>{}) === 'function');
34+
console.assert(typeOf(proxied.function(0)) === 'function');
35+
console.assert(typeOf({}) === 'object');
36+
console.assert(typeOf(proxied.object(0)) === 'object');
37+
38+
// typeOf extra primitives
39+
console.assert(typeOf(1n) === 'bigint');
40+
console.assert(typeOf(proxied.bigint(0)) === 'bigint');
41+
console.assert(typeOf(false) === 'boolean');
42+
console.assert(typeOf(proxied.boolean(0)) === 'boolean');
43+
console.assert(typeOf(null) === 'null');
44+
console.assert(typeOf(proxied.null(0)) === 'null');
45+
console.assert(typeOf(1) === 'number');
46+
console.assert(typeOf(proxied.number(0)) === 'number');
47+
console.assert(typeOf('') === 'string');
48+
console.assert(typeOf(proxied.string(0)) === 'string');
49+
console.assert(typeOf(Symbol()) === 'symbol');
50+
console.assert(typeOf(proxied.symbol(0)) === 'symbol');
51+
console.assert(typeOf() === 'undefined');
52+
console.assert(typeOf(proxied.undefined({})) === 'undefined');
53+
54+
// typeOf custom direct/defined
55+
console.assert(typeOf(proxied.direct({})) === 'direct');
56+
57+
console.assert(proxied.bigint(2n) == 2n);
58+
console.assert(proxied.bigint(2n) instanceof BigInt);

0 commit comments

Comments
 (0)