Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core): use private variables instead of function wrappers #1106

Merged
merged 2 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 47 additions & 55 deletions packages/core/src/consumed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,56 +50,38 @@ export interface ClientAndForm {
}

class ConsumedThingProperty extends TD.ThingProperty implements TD.ThingProperty, TD.BaseSchema {
// functions for wrapping internal state
private getName: () => string;
private getThing: () => ConsumedThing;
#name: string;
#thing: ConsumedThing;

constructor(name: string, thing: ConsumedThing) {
super();

// wrap internal state into functions to not be stringified in TD
this.getName = () => {
return name;
};
this.getThing = () => {
return thing;
};
this.#name = name;
this.#thing = thing;
}
}

class ConsumedThingAction extends TD.ThingAction implements TD.ThingAction {
// functions for wrapping internal state
private getName: () => string;
private getThing: () => ConsumedThing;
#name: string;
#thing: ConsumedThing;

constructor(name: string, thing: ConsumedThing) {
super();

// wrap internal state into functions to not be stringified in TD
this.getName = () => {
return name;
};
this.getThing = () => {
return thing;
};
this.#name = name;
this.#thing = thing;
}
}

class ConsumedThingEvent extends TD.ThingEvent {
// functions for wrapping internal state
private getName: () => string;
private getThing: () => ConsumedThing;
#name: string;
#thing: ConsumedThing;

constructor(name: string, thing: ConsumedThing) {
super();

// wrap internal state into functions to not be stringified in TD
this.getName = () => {
return name;
};
this.getThing = () => {
return thing;
};
this.#name = name;
this.#thing = thing;
}
}

Expand Down Expand Up @@ -348,24 +330,37 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
[key: string]: EventElement;
};

private getServient: () => Servient;
private getClients: () => Map<string, ProtocolClient>;
/**
* The servient associated with this {@link ConsumedThing}.
*
* Provides protocol-specific clients as well as credentials for the
* available security schemes.
*
* The declaration as private (via the leading `#`) prevents this
* field from being included in the TD generated by the
* {@link getThingDescription} method.
*/
#servient: Servient;

/**
* Mapping of URI schemes to {@link ProtocolClient}s that are used for
* performing protocol-specific interactions.
*
* The declaration as private (via the leading `#`) prevents this
* field from being included in the TD generated by the
* {@link getThingDescription} method.
*/
#clients: Map<string, ProtocolClient>;

private subscribedEvents: Map<string, Subscription> = new Map<string, Subscription>();
private observedProperties: Map<string, Subscription> = new Map<string, Subscription>();

constructor(servient: Servient, thingModel: TD.ThingModel = {}) {
super();

this.getServient = () => {
return servient;
};
this.getClients = new (class {
clients: Map<string, ProtocolClient> = new Map<string, ProtocolClient>();
getMap = () => {
return this.clients;
};
})().getMap;
this.#servient = servient;
this.#clients = new Map();

this.properties = {};
this.actions = {};
this.events = {};
Expand Down Expand Up @@ -463,15 +458,12 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
// see https://www.w3.org/TR/wot-thing-description/#security-serialization-json

logStatement();
client.setSecurity(
this.getSecuritySchemes(form.security),
this.getServient().retrieveCredentials(this.id)
);
client.setSecurity(this.getSecuritySchemes(form.security), this.#servient.retrieveCredentials(this.id));
} else if (Array.isArray(this.security) && this.security.length > 0) {
logStatement();
client.setSecurity(
this.getSecuritySchemes(this.security as string[]),
this.getServient().getCredentials(this.id)
this.#servient.getCredentials(this.id)
);
}
}
Expand All @@ -498,14 +490,14 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
if (options.formIndex >= 0 && options.formIndex < forms.length) {
form = forms[options.formIndex];
const scheme = Helpers.extractScheme(form.href);
if (this.getServient().hasClientFor(scheme)) {
if (this.#servient.hasClientFor(scheme)) {
debug(`ConsumedThing '${this.title}' got client for '${scheme}'`);
client = this.getServient().getClientFor(scheme);
client = this.#servient.getClientFor(scheme);

if (!this.getClients().get(scheme)) {
if (!this.#clients.get(scheme)) {
// new client
this.ensureClientSecurity(client, form);
this.getClients().set(scheme, client);
this.#clients.set(scheme, client);
}
} else {
throw new Error(`ConsumedThing '${this.title}' missing ClientFactory for '${scheme}'`);
Expand All @@ -515,27 +507,27 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
}
} else {
const schemes = forms.map((link) => Helpers.extractScheme(link.href));
const cacheIdx = schemes.findIndex((scheme) => this.getClients().has(scheme));
const cacheIdx = schemes.findIndex((scheme) => this.#clients.has(scheme));

if (cacheIdx !== -1) {
// from cache
debug(`ConsumedThing '${this.title}' chose cached client for '${schemes[cacheIdx]}'`);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- if cacheIdx is valid, then clients *contains* schemes[cacheIdx]
client = this.getClients().get(schemes[cacheIdx])!;
client = this.#clients.get(schemes[cacheIdx])!;
form = this.findForm(forms, op, affordance, schemes, cacheIdx);
} else {
// new client
debug(`ConsumedThing '${this.title}' has no client in cache (${cacheIdx})`);
const srvIdx = schemes.findIndex((scheme) => this.getServient().hasClientFor(scheme));
const srvIdx = schemes.findIndex((scheme) => this.#servient.hasClientFor(scheme));

if (srvIdx === -1)
throw new Error(`ConsumedThing '${this.title}' missing ClientFactory for '${schemes}'`);

client = this.getServient().getClientFor(schemes[srvIdx]);
client = this.#servient.getClientFor(schemes[srvIdx]);

debug(`ConsumedThing '${this.title}' got new client for '${schemes[srvIdx]}'`);

this.getClients().set(schemes[srvIdx], client);
this.#clients.set(schemes[srvIdx], client);

form = this.findForm(forms, op, affordance, schemes, srvIdx);
this.ensureClientSecurity(client, form);
Expand Down
10 changes: 4 additions & 6 deletions packages/core/src/exposed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,12 @@
/** A map of event listener callback functions */
__eventListeners: ProtocolListenerRegistry = new ProtocolListenerRegistry();

private getServient: () => Servient;
#servient: Servient;

constructor(servient: Servient, thingModel: WoT.ExposedThingInit = {}) {
super();

this.getServient = () => {
return servient;
};
this.#servient = servient;

// The init object might still have undefined values, so initialize them here.
// TODO: who checks that those are valid?
Expand Down Expand Up @@ -175,7 +173,7 @@

return new Promise<void>((resolve, reject) => {
// let servient forward exposure to the servers
this.getServient()
this.#servient

Check warning on line 176 in packages/core/src/exposed-thing.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/exposed-thing.ts#L176

Added line #L176 was not covered by tests
.expose(this)
.then(() => {
resolve();
Expand All @@ -187,7 +185,7 @@
/** @inheritDoc */
async destroy(): Promise<void> {
debug(`ExposedThing '${this.title}' destroying the thing and its interactions`);
await this.getServient().destroyThing(this.id);
await this.#servient.destroyThing(this.id);

this.__eventListeners.unregisterAll();
this.__propertyListeners.unregisterAll();
Expand Down
Loading