Skip to content

Commit

Permalink
fix: ajusta tipos
Browse files Browse the repository at this point in the history
  • Loading branch information
drusco committed Jul 18, 2023
1 parent decdbd4 commit 0e54d6d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 47 deletions.
21 changes: 17 additions & 4 deletions src/Emulator.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import { EventEmitter } from "events";
declare namespace Emulator {
interface EmulatorClass extends EventEmitter {}

type bindString = (
scope: EmulatorClass,
id: string,
target?: traceable,
) => functionLike;

type bindTraceable = (
scope: EmulatorClass,
target: traceable,
origin?: origin,
groupId?: string,
) => functionLike;

interface options {
[x: string]: unknown;
}
Expand All @@ -12,13 +25,13 @@ declare namespace Emulator {
rootItem: functionLike;
}

interface groups {
interface bindings {
[id: string]: group;
}

interface private {
options: options;
groups: groups;
bindings: bindings;
itemCount: number;
activeItems: number;
groupCount: number;
Expand All @@ -36,12 +49,12 @@ declare namespace Emulator {
interface item {
id: number;
dummy: functionLike;
origin: origin;
origin?: origin;
target: traceable;
revoke(): void;
scope: EmulatorClass;
sandbox: object;
group: string | undefined;
group?: string;
}

// eslint-disable-next-line @typescript-eslint/ban-types
Expand Down
92 changes: 49 additions & 43 deletions src/Emulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class Emulator

const data: EmulatorNS.private = {
options,
groups: Object.create(null),
bindings: Object.create(null),
itemCount: 0, // total item count including revoked items, it only increases
activeItems: 0, // items that are not revoked
groupCount: 0,
Expand All @@ -21,7 +21,7 @@ export default class Emulator

use(value: unknown): unknown {
if (typeof value === "string") {
return createGroup.call(this, value);
return bindString(this, value);
}

if (typeof value === "object") {
Expand All @@ -39,7 +39,7 @@ export default class Emulator
typeof value === "undefined" ||
typeof value === "function"
) {
return createItem.call(this, defaultGroup, value);
return bindTraceable(this, value);
}

return value; // return original value
Expand All @@ -61,8 +61,8 @@ export default class Emulator
}

used(value: unknown): boolean {
const { groups }: EmulatorNS.private = secret.get(this);
const isGroup = typeof value === "string" && !!groups[value];
const { bindings }: EmulatorNS.private = secret.get(this);
const isGroup = typeof value === "string" && !!bindings[value];

let isItem: boolean = false;
let isLinkedToItem: boolean = false;
Expand Down Expand Up @@ -199,15 +199,15 @@ const events = [
"proxy",
"action",
"revoke",
"createGroup",
"bindString",
"deleteGroup",
"resolve",
"resolveId",
];

// Item context
// Item traps

const context = {
const traps = {
get(dummy: EmulatorNS.functionLike, key: string): unknown {
const item = dummies.get(dummy);
const { scope, group, target, sandbox } = items.get(item);
Expand All @@ -225,12 +225,12 @@ const context = {
if (!sandboxKeys.includes(key)) {
if (targets.has(target) && target[key] !== undefined) {
if (isTraceable(target[key])) {
sandbox[key] = createItem.call(scope, group, target[key], origin);
sandbox[key] = bindTraceable(scope, target[key], origin, group);
} else {
sandbox[key] = target[key];
}
} else {
sandbox[key] = createItem.call(scope, group, undefined, origin);
sandbox[key] = bindTraceable(scope, undefined, origin, group);
}
}

Expand All @@ -250,7 +250,7 @@ const context = {
};

const final = traceable
? createItem.call(scope, group, value, origin)
? bindTraceable(scope, value as EmulatorNS.traceable, origin, group)
: value;

if (final === value) {
Expand Down Expand Up @@ -288,13 +288,13 @@ const context = {
const item = dummies.get(dummy);
const { scope, group } = items.get(item);

const origin = {
const origin: EmulatorNS.origin = {
action: "construct",
item,
args,
};

return createItem.call(scope, group, undefined, origin);
return bindTraceable(scope, undefined, origin, group);
},

apply(
Expand All @@ -305,21 +305,19 @@ const context = {
const item = dummies.get(dummy);
const { scope, group } = items.get(item);

const origin = {
const origin: EmulatorNS.origin = {
action: "apply",
item,
that,
args,
};

return createItem.call(scope, group, undefined, origin);
return bindTraceable(scope, undefined, origin, group);
},
};

// Helpers

const defaultGroup = "__global";

function isTraceable(value: unknown): boolean {
if (typeof value !== "object") return false;
if (value === null) return false;
Expand All @@ -338,14 +336,14 @@ function revokeItem(item: EmulatorNS.functionLike): void {

const { id, scope, group, dummy, revoke, target } = items.get(item);
const _private = secret.get(scope);
const _group = _private.groups[group];
const _group = _private.bindings[group];

if (_group) {
_group.length--;

if (_group.length === 0) {
// delete the group when it is empty
delete _private.groups[group];
delete _private.bindings[group];
scope.emit("deleteGroup", group);
_private.groupCount--;
}
Expand All @@ -364,22 +362,23 @@ function revokeItem(item: EmulatorNS.functionLike): void {
scope.emit("revoke", id);
}

function createItem(
groupId: string,
const bindTraceable = ((
scope: EmulatorNS.EmulatorClass,
target: EmulatorNS.traceable, // original target used for proxy
origin: EmulatorNS.origin | undefined, // the action used to create the proxy
): EmulatorNS.functionLike {
origin?: EmulatorNS.origin, // the action used to create the proxy
groupId?: string,
): EmulatorNS.functionLike => {
if (targets.has(target)) return targets.get(target); // return proxy linked to target
if (typeof target === "function" && items.has(target)) return target; // target is already proxy

const data: EmulatorNS.private = secret.get(this);
const { groups } = data;
const data: EmulatorNS.private = secret.get(scope);
const { bindings } = data;

const itemId = ++data.itemCount;
const dummy = function () {};
const traceable = isTraceable(target);
const { proxy, revoke } = Proxy.revocable(dummy, context);
const group = groups[groupId];
const { proxy, revoke } = Proxy.revocable(dummy, traps);
const group = bindings[groupId];

// set information about the item

Expand All @@ -389,12 +388,12 @@ function createItem(
origin,
target,
revoke,
scope: this,
scope,
sandbox: Object.create(null),
group: group && groupId,
};

this.emit("proxy", {
scope.emit("proxy", {
id: itemId,
item: proxy,
origin,
Expand All @@ -415,24 +414,31 @@ function createItem(
}

return proxy;
}
}) satisfies EmulatorNS.bindTraceable;

// Group methods
const bindString = ((
scope: EmulatorNS.EmulatorClass,
id: string,
target?: EmulatorNS.traceable,
): EmulatorNS.functionLike => {
const data: EmulatorNS.private = secret.get(scope);

function createGroup(id: string, target: object): EmulatorNS.functionLike {
const data: EmulatorNS.private = secret.get(this);
const groupId = id || defaultGroup;
const { groups } = data;
const { bindings } = data;

if (!id.length) {
return bindTraceable(scope, target);
}

// return existing root item
if (groups[groupId]) {
return groups[groupId].rootItem;
if (bindings[id]) {
return bindings[id].rootItem;
}

const rootItem: EmulatorNS.functionLike = createItem.call(
this,
groupId,
const rootItem: EmulatorNS.functionLike = bindTraceable(
scope,
target,
undefined,
id,
);

const group: EmulatorNS.group = {
Expand All @@ -441,9 +447,9 @@ function createGroup(id: string, target: object): EmulatorNS.functionLike {
};

data.groupCount += 1;
groups[groupId] = group;
bindings[id] = group;

this.emit("createGroup", groupId);
scope.emit("bindString", id);

return rootItem;
}
}) satisfies EmulatorNS.bindString;

0 comments on commit 0e54d6d

Please sign in to comment.