commontoolsinc / system

A constellation of Common tools
2 stars 0 forks source link

Support read/write structured data on `InputOutput` #182

Open jsantell opened 5 days ago

jsantell commented 5 days ago

Currently, module ports support some primitive types (string, number, boolean, buffer). We should support some "structured" type that allows mediated access to data with nested values. These values each have their own value properties and metadata like IFC labels that must be adhered to by the runtime.

Currently value properties are defined via a definition that looks like:

{
  "name": "foo",
  "type": "string"
}

Given an example of an object representing a cake recipe, containing an author, details and timestamp, the input definition could look like:

{
  "name": "recipe",
  "type": "map",
  "children": [{
    "name": "author",
    "type": "string",
  }, {
    "name": "details",
    "type": "string"
  }, {
    "name": "timestamp",
    "type": "number",
    "optional": true
  }],
}

These properties could be accessed in JS VM module like:

import { read, write } from "common:io/state@0.0.1";

export const run = () => {
  // `recipe` here would be an Object,
  // and requires full access to all of its children,
  // which would fail if e.g. `details` is inacessible
  // due to policy
  const recipe = read("recipe")?.deref();
  // More interestingly, specific properties can be directly
  // accessed.
  const author = read("recipe/author)?.deref();

  // ..
};

Itemizing the things to implement here:

The port definition properties opaque and optional may be elided in initial implementation.

cdata commented 5 days ago

I think it's easier to think of and implement structured data traversal one key at a time. For example, instead of writing read("recipe/author") you would write read("recipe").read("author"). A library can always create a path sugar over this.

Currently, read returns a Reference and a Reference is an opaque (possibly not even defined) value. A Reference is also said to have a read method.

Additionally, it's important to recognize that the "inner" value of a map is not a simple data structure. It is a composite structure that may contain plain data types or references. Similarly, a list may be a list of references. One implication here is that there should be a variant of value that embodies a Reference.

Hierarchical data types and optional inputs/outputs seem like separable issues to me.