Skip to content

Commit

Permalink
Merge pull request #1258 from danielpeintner/issue-1252
Browse files Browse the repository at this point in the history
refactor: create helper function structuredClone and use *old* way
  • Loading branch information
relu91 committed Apr 23, 2024
2 parents debccce + 102ee66 commit dbb75d5
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 17 deletions.
2 changes: 1 addition & 1 deletion packages/binding-http/src/http-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export default class HttpServer implements ProtocolServer {
for (const [inUri, toUri] of Object.entries(this.urlRewrite)) {
const endsWithToUri: boolean = form.href.endsWith(toUri);
if (endsWithToUri) {
const form2 = structuredClone(form);
const form2 = Helpers.structuredClone(form);
form2.href = form2.href.substring(0, form.href.lastIndexOf(toUri)) + inUri;
forms.push(form2);
debug(`HttpServer on port ${this.getPort()} assigns urlRewrite '${form2.href}' for '${form.href}'`);
Expand Down
16 changes: 6 additions & 10 deletions packages/binding-opcua/test/opcua-codec-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import { exist } from "should";
import { expect } from "chai";

import { ContentSerdes, createLoggers } from "@node-wot/core";
import { ContentSerdes, Helpers, createLoggers } from "@node-wot/core";
import { ObjectSchema } from "@node-wot/td-tools";

import { DataValue } from "node-opcua-data-value";
Expand Down Expand Up @@ -49,13 +49,9 @@ const dataValue3 = new DataValue({
},
});

function jsonify(a: unknown): unknown {
return JSON.parse(JSON.stringify(a));
}

const dataValue1Json = jsonify(opcuaJsonEncodeDataValue(dataValue1, true));
const dataValue2Json = jsonify(opcuaJsonEncodeDataValue(dataValue2, true));
const dataValue3Json = jsonify(opcuaJsonEncodeDataValue(dataValue3, true));
const dataValue1Json = Helpers.structuredClone(opcuaJsonEncodeDataValue(dataValue1, true));
const dataValue2Json = Helpers.structuredClone(opcuaJsonEncodeDataValue(dataValue2, true));
const dataValue3Json = Helpers.structuredClone(opcuaJsonEncodeDataValue(dataValue3, true));

describe("OPCUA Binary Serdes ", () => {
[dataValue1Json, dataValue2Json, dataValue3Json].forEach((dataValue, index) => {
Expand All @@ -65,7 +61,7 @@ describe("OPCUA Binary Serdes ", () => {
it("should encode and decode a dataValue with application/opcua+binary codec " + index, () => {
const payload = theOpcuaBinaryCodec.valueToBytes(dataValue as DataValue | DataValueJSON, schema);
const dataValueReloaded = theOpcuaBinaryCodec.bytesToValue(payload, schema);
expect(dataValue).to.eql(jsonify(dataValueReloaded));
expect(dataValue).to.eql(Helpers.structuredClone(dataValueReloaded));
});
});
});
Expand All @@ -77,7 +73,7 @@ describe("OPCUA JSON Serdes ", () => {
it("should encode and decode a dataValue with application/opcua+json codec " + index, () => {
const payload = theOpcuaJSONCodec.valueToBytes(dataValue, schema);
const dataValueReloaded = theOpcuaJSONCodec.bytesToValue(payload, schema);
expect(dataValue).to.eql(jsonify(dataValueReloaded));
expect(dataValue).to.eql(Helpers.structuredClone(dataValueReloaded));
});
});
const expected1 = [
Expand Down
4 changes: 2 additions & 2 deletions packages/binding-opcua/test/schema-validation-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
********************************************************************************/

import { createLoggers } from "@node-wot/core";
import { Helpers, createLoggers } from "@node-wot/core";
import { expect } from "chai";

import { DataType, DataValue, StatusCodes, VariantArrayType } from "node-opcua-client";
Expand Down Expand Up @@ -87,7 +87,7 @@ describe("schemas", () => {

Object.entries(data).forEach(([name, obj1]) => {
it("DataValue " + name, () => {
const dataValueJSON = JSON.parse(JSON.stringify(opcuaJsonEncodeDataValue(obj1, true)));
const dataValueJSON = Helpers.structuredClone(opcuaJsonEncodeDataValue(obj1, true));

const isValid = validate(dataValueJSON);
if (!isValid) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/consumed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
this.actions = {};
this.events = {};

const deepClonedModel = structuredClone(thingModel);
const deepClonedModel = Helpers.structuredClone(thingModel);
Object.assign(this, deepClonedModel);
this.extendInteractions();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/exposed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export default class ExposedThing extends TD.Thing implements WoT.ExposedThing {

// Deep clone the Thing Model
// without functions or methods
const deepClonedModel = JSON.parse(JSON.stringify(thingModel));
const deepClonedModel = Helpers.structuredClone(thingModel);
Object.assign(this, deepClonedModel);

// unset "@type":"tm:ThingModel" ?
Expand Down
10 changes: 9 additions & 1 deletion packages/core/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ export default class Helpers implements Resolver {
}
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
static structuredClone<T = any>(value: T): T {
// TODO built-in structuredClone() still seems to cause issues
// see for example https://github.com/eclipse-thingweb/node-wot/issues/1252
// return structuredClone(value); // Note: use in future
return JSON.parse(JSON.stringify(value));
}

// TODO: specialize fetch to retrieve just thing descriptions
// see https://github.com/eclipse-thingweb/node-wot/issues/1055
public fetch(uri: string): Promise<unknown> {
Expand Down Expand Up @@ -214,7 +222,7 @@ export default class Helpers implements Resolver {
* Helper function to remove reserved keywords in required property of TD JSON Schema
*/
static createExposeThingInitSchema(tdSchema: unknown): SomeJSONSchema {
const tdSchemaCopy = structuredClone(tdSchema) as SomeJSONSchema;
const tdSchemaCopy = Helpers.structuredClone(tdSchema) as SomeJSONSchema;

if (tdSchemaCopy.required !== undefined) {
const reservedKeywords: Array<string> = [
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/servient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ProtocolClientFactory, ProtocolServer, ProtocolClient } from "./protoco
import ContentManager, { ContentCodec } from "./content-serdes";
import { v4 } from "uuid";
import { createLoggers } from "./logger";
import { Helpers } from "./core";

const { debug, warn } = createLoggers("core", "servient");

Expand Down Expand Up @@ -49,7 +50,7 @@ export default class Servient {
debug(`Servient exposing '${thing.title}'`);

// What is a good way to to convey forms information like contentType et cetera for interactions
const tdTemplate: WoT.ThingDescription = JSON.parse(JSON.stringify(thing));
const tdTemplate: WoT.ThingDescription = Helpers.structuredClone(thing) as WoT.ThingDescription;

// initializing forms fields
thing.forms = [];
Expand Down

0 comments on commit dbb75d5

Please sign in to comment.