Skip to content
This repository has been archived by the owner on Aug 29, 2021. It is now read-only.

Commit

Permalink
fix: stop exposing the deps
Browse files Browse the repository at this point in the history
  • Loading branch information
Levertion committed Apr 22, 2019
1 parent 22553ed commit 84ca1fb
Showing 1 changed file with 40 additions and 21 deletions.
61 changes: 40 additions & 21 deletions id/src/resolved-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,32 @@ function isResolved(value: any): value is IsResolved<any> {
return value.hasOwnProperty("resolved");
}

export type Resolving<T> = HasDeps & HasValue<T>;
export type Resolved<T, R> = IsResolved<R> & HasValue<T> & HasDeps;
export type MaybeResolving<T, R> = Resolving<T> | Resolved<T, R>;
type ResolvingOrDeps<T, R> = MaybeResolving<T, R> | HasDeps;
type InternalResolving<T> = HasDeps & HasValue<T>;
type InternalResolved<T, R> = IsResolved<R> & HasValue<T> & HasDeps;
type InternalMaybeResolving<T, R> =
| InternalResolving<T>
| InternalResolved<T, R>;

export type Resolved<T, R> = IsResolved<R> & HasValue<T>;
export type MaybeResolving<T, R> = HasValue<T> | Resolved<T, R>;
type ResolvingOrDeps<T, R> = InternalMaybeResolving<T, R> | HasDeps;

type Unresolved<T> = HasValue<T>;
type Requested = HasDeps;
type Stored<T, R> = Resolving<T> | Resolved<T, R> | Unresolved<T> | Requested;
type Stored<T, R> =
| InternalResolving<T>
| InternalResolved<T, R>
| Unresolved<T>
| Requested;

type Resolver<T, R> = (map: ResolvedIDMap<T, R>, id: ID, value: T) => R;
type Resolver<T, R> = (value: T, id: ID, map: ResolvedIDMap<T, R>) => R;

export class ResolvedIDMap<T, R> {
private static removeDeps(value: any): any {
const copy = { ...value };
delete copy.deps;
return copy;
}
private inner: IDMap<Stored<T, R>> = new IDMap();
private resolver: Resolver<T, R>;
private resolving?: ID;
Expand All @@ -42,6 +56,7 @@ export class ResolvedIDMap<T, R> {
}

public set(id: ID, raw: T) {
this.reset(id);
this.inner.set(id, { raw });
}

Expand All @@ -58,7 +73,7 @@ export class ResolvedIDMap<T, R> {
public getCycle(id: ID): MaybeResolving<T, R> | undefined {
const value = this.resolve(id);
if (value && hasValue(value)) {
return value;
return ResolvedIDMap.removeDeps(value);
}
return undefined;
}
Expand All @@ -75,7 +90,7 @@ export class ResolvedIDMap<T, R> {
const result = this.getCycle(id);
if (result) {
if (isResolved(result)) {
return result;
return ResolvedIDMap.removeDeps(result);
}
throw new Error(
`Value for ${id} requested during its own resolution. To avoid this error being thrown, use \`getCycle\` instead`
Expand All @@ -92,13 +107,14 @@ export class ResolvedIDMap<T, R> {
private reset(id: ID): void {
const value = this.inner.get(id);
if (value && hasDeps(value)) {
for (const [dep] of value.deps) {
this.reset(dep);
}
const { deps } = value;
delete value.deps;
if (isResolved(value)) {
delete value.resolved;
}
for (const [dep] of deps) {
this.reset(dep);
}
}
}

Expand All @@ -115,24 +131,27 @@ export class ResolvedIDMap<T, R> {
}
return undefined;
}
if (hasDeps(value)) {
if (previousResolving) {
value.deps.add(previousResolving);
}
}
if (!hasValue(value)) {
return value;
if (hasDeps(value) && previousResolving) {
value.deps.add(previousResolving);
}
if (isResolved(value)) {
if (
// No value, only requested dependencies
!hasValue(value) ||
// Resolved
isResolved(value) ||
// Resolving
hasDeps(value)
) {
return value;
}
const asserted = value as Resolved<T, R>;
// Unresolved and no deps.
const asserted = value as InternalResolved<T, R>;
this.resolving = id;
asserted.deps = new IDSet();
if (previousResolving) {
asserted.deps.add(previousResolving);
}
asserted.resolved = this.resolver(this, id, value.raw);
asserted.resolved = this.resolver(value.raw, id, this);
this.resolving = previousResolving;
return asserted;
}
Expand Down

0 comments on commit 84ca1fb

Please sign in to comment.