Skip to content

Commit

Permalink
Merge pull request #1106 from JKRhb/internal-getters
Browse files Browse the repository at this point in the history
refactor(core): use private variables instead of function wrappers
  • Loading branch information
relu91 authored Oct 10, 2023
2 parents 4ebe5e8 + fcc3b70 commit 9557fe1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 61 deletions.
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 @@ -105,14 +105,12 @@ export default class ExposedThing extends TD.Thing implements WoT.ExposedThing {
*/
#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 @@ -186,7 +184,7 @@ export default class ExposedThing extends TD.Thing implements WoT.ExposedThing {

return new Promise<void>((resolve, reject) => {
// let servient forward exposure to the servers
this.getServient()
this.#servient
.expose(this)
.then(() => {
resolve();
Expand All @@ -198,7 +196,7 @@ export default class ExposedThing extends TD.Thing implements WoT.ExposedThing {
/** @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

0 comments on commit 9557fe1

Please sign in to comment.