Skip to content

Commit

Permalink
Immutable inputs/outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
dionjwa committed Nov 5, 2024
1 parent 32fa3ca commit 5e7dc9c
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 30 deletions.
2 changes: 1 addition & 1 deletion app/libs/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@metapages/metapage",
"public": true,
"version": "1.0.12",
"version": "1.0.13",
"description": "Connect web pages together",
"repository": "https://github.com/metapages/metapage",
"homepage": "https://metapage.io/",
Expand Down
12 changes: 9 additions & 3 deletions app/libs/src/metapage/Metaframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,14 @@ export class Metaframe extends EventEmitter<

async setInternalInputsAndNotify(inputs: MetaframeInputMap) {
// this is where we deserialize the inputs

if (this.isInputOutputBlobSerialization) {
inputs = await deserializeInputs(inputs);
}

if (!merge(this._inputPipeValues, inputs)) {
const originalInputs = inputs;
this._inputPipeValues = merge(this._inputPipeValues, inputs);
if (this._inputPipeValues === originalInputs) {
return;
}

Expand Down Expand Up @@ -403,9 +405,13 @@ export class Metaframe extends EventEmitter<
if (this.isInputOutputBlobSerialization) {
outputs = await serializeInputs(outputs);
}
if (!merge(this._outputPipeValues, outputs)) {

const originalOutputs = outputs;
this._outputPipeValues = merge(this._outputPipeValues, outputs);
if (this._outputPipeValues === originalOutputs) {
return;
}

this.sendRpc(JsonRpcMethodsFromChild.OutputsUpdate, outputs);
}

Expand Down
14 changes: 11 additions & 3 deletions app/libs/src/metapage/MetapageIFrameRpcClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,13 @@ export class MetapageIFrameRpcClient extends EventEmitter<
};
public setInputs(maybeNewInputs: MetaframeInputMap): MetapageIFrameRpcClient {
this.log({ m: "MetapageIFrameRpcClient", inputs: maybeNewInputs });
if (!merge(this.inputs, maybeNewInputs)) {

const originalInputs = maybeNewInputs;
this.inputs = merge(this.inputs, maybeNewInputs);
if (this.inputs === originalInputs) {
return this;
}

if (!this._loaded) {
this._sendInputsAfterRegistration = true;
}
Expand Down Expand Up @@ -291,9 +295,13 @@ export class MetapageIFrameRpcClient extends EventEmitter<
inputs: null,
};
public setOutputs(maybeNewOutputs: MetaframeInputMap) {
if (!merge(this.outputs, maybeNewOutputs)) {
return;

const originalOutputs = maybeNewOutputs;
this.outputs = merge(this.outputs, maybeNewOutputs);
if (this.outputs === originalOutputs) {
return this;
}

this.emit(MetapageEvents.Outputs, maybeNewOutputs);

if (this._metapage.listenerCount(MetapageEvents.Outputs) > 0) {
Expand Down
31 changes: 15 additions & 16 deletions app/libs/src/metapage/MetapageTools.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import stringify from 'fast-json-stable-stringify';

import { create } from 'mutative';
import { MetapageHashParams } from './Shared.js';
import {
MetaframeId,
Expand All @@ -12,32 +12,31 @@ import {
MetaframeInputMap,
} from './v0_4/index.js';
/**
* Merges new values into the current object.
* Merges new values into the a new object.
* Does NOT check if there are actually new keys.
* Does NOT check values against each other. This means you
* can keep sending the same value, and the message will
* be passed in.
* Returns true if the original map was modified.
* Returns the original map if nothing modified.
*/
export const merge = (
current: MetaframeInputMap,
newInputs: MetaframeInputMap
): boolean => {
): MetaframeInputMap => {
if (!newInputs) {
return false;
return current;
}
let modified = false;
Object.keys(newInputs).forEach((pipeId: string) => {
modified = true;
// undefined means remove the key
// null means keep the key, but set to null
if (newInputs[pipeId] === undefined) {
delete current[pipeId];
} else {
current[pipeId] = newInputs[pipeId];
}
return create<MetaframeInputMap>(current, (draft: MetaframeInputMap) => {
Object.keys(newInputs).forEach((pipeId: string) => {
// undefined means remove the key
// null means keep the key, but set to null
if (newInputs[pipeId] === undefined) {
delete draft[pipeId];
} else {
draft[pipeId] = newInputs[pipeId];
}
});
});
return modified;
};

export const getUrlParam = (key: MetapageHashParams): string | null => {
Expand Down
14 changes: 8 additions & 6 deletions app/libs/src/metapage/data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MetaframeInputMap } from "./v0_4";
import { encode, decode } from "base64-arraybuffer";
import { create } from 'mutative';

/**
* Modifies in place!!!
Expand All @@ -10,12 +11,13 @@ export const serializeInputs = async (
inputs: MetaframeInputMap
): Promise<MetaframeInputMap> => {
// only serialize one level deep
for (const key of Object.keys(inputs)) {
const maybeNewObject = await possiblySerializeValueToDataref(inputs[key]);
inputs[key] = maybeNewObject;
}

return inputs;
return create<MetaframeInputMap>(inputs, async (draft: MetaframeInputMap) => {
for (const key of Object.keys(inputs)) {
const maybeNewObject = await possiblySerializeValueToDataref(inputs[key]);
draft[key] = maybeNewObject;
return draft;
}
});
};

/**
Expand Down
2 changes: 1 addition & 1 deletion app/worker/test/src/run-tests-in-astral.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ const getMetapageVersions = async () :Promise<string[]> => {

let allVersions = await getMetapageVersions();
if (!nolocalBuild) {
allVersions.push("latest");
allVersions.unshift("latest");
}
console.log(`🍳👉 allVersions ${allVersions}`);
const maxTimeAllTests = timePerTest * allVersions.length ** 2;
Expand Down

0 comments on commit 5e7dc9c

Please sign in to comment.