Code Monkey home page Code Monkey logo

encapsule / arccore Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 159 KB

The @encapsule/arccore package contains runtime algorithms for schematizing, filtering, routing, and modeling strongly-typed in-memory data with mathematical graphs and JSON-serializable data types for use in Node.js and HTML5 application services implemented in JavaScript.

Home Page: https://encapsule.io/docs/ARCcore

License: MIT License

data-normalization data-validation discriminator filter hashing-algorithms mathematical-graphs message-bus unique-id-generator

arccore's People

Contributors

chrisrus avatar

arccore's Issues

arccore.filter ___inValueSet error message

If a value is constrained w/filter spec directive ____inValueSet it's typical that either an array of numerical or string values is specified. In the numerical case if the value doesn't meet the constraint the error message should not quote the numerical value. (only in the case of strings).

arccore.graph add support for flexible graph filtering

Similar in spirit to existing transpose algorithm accepts an input graph and produces a second graph that's a copy of the first with its edges reversed (transposed), the graph filter operation would allow a developer to pass in a DirectedGraph instance and some TBD predicate specification and get back a second DirectedGraph instance that is a filtered copy of the first.

Some common predicates:

  • Remove all vertices matching predicate
  • Remove all edges matching predicate
  • BFT/DFT-based filtering (uses special visitors to affect advanced filtering operations)

arccore.filter.identifier IRUT format can be annoying when used in raw form to name files

... IRUT (Internet Routable Unique Token) is a 22-character string that's a modified base64 encoding of a 128-bit v4 UUID that replaces base64 character '/' with '_' and '+' with '-'. This makes it simple to use IRUT inside URL/URI per RFC 3986. And, is mostly suitable for Linux and Windows file/directory naming... It's mostly except if the IRUT begins with '-' '--' etc

This is legal per IRUT but is annoying because many Linux command assume a valid IRUT such as "-GSSwHkeSJ24e2kfpXle_g" is a command line option.

I think this is just a documentation thing. Probably best to prefix file/directory names w/a short valid string to avoid the issue.

arccore.filter keys cannot contain period(s) characters

I noticed an interesting (and potentially exceptionally confusing) error string back from filter recently.

{
    ____types: "jsObject",
    ____asMap: true,
    key: {
        ____types: "jsObject",
        required: {
            ____accept: "jsString"
         }
    }
}

Now suppose I create an object that looks like this:

{
    "~.this.is.a.path.into.cds.instance.data.used.as.a.key": { /* whoops */ )
}

missing ~.this.is.a.path.into.cds.instance.data.used.as.a.key.required <--- wat

What to do about this? n JavaScript we can write:

let x = {};
x["~.whatever.i.want"] = 5

RAP: [ "whatever.i.want" ]
RIS: "~.[whatever.i.want]"

I'm not sure. I've got a whole system all worked out for ARC RIS and RAP --- I just can't recall the exact details.

In the short term I think it's prudent to **advise against ** using map/dictionary keys that contain period (.) character(s). arccore.identifier.irut.fromReference (or alternative) function is available to quickly hash strings that may contain forbidden characters.

Leaving this open in case anyone hits this case. DO NOT USE period characters in keys; if you have to deal with keys that do or may contain periods, convert them to IRUT digest hash strings (or use some other appropriate mechanism to remove the periods).

arccore.graph support developer-defined serializable context object attached to DirectedGraph

DirectedGraph provides support for vertex and edge "properties" - arbitrary developer-defined data attached to vertices and edges in a DirectedGraph container instance. This is useful. But, oftentimes you're building a graph based on some data structure produced by another source and you're effectively indexing it. i.e. you're not transforming the input into an equivalent graph representation but rather building a graph to keep track of some feature(s) of the input data.
In these cases, we want to use internal properties to hold metadata references back to source data (e.g. data structure paths, keys, etc). And, we want to maintain the input as it is so that the information stored in the derived graph can be used to dereference back to the data.
What this feature allows is for the external data to be associated with the derived graph such that serializing the derived graph also serializes the "context" the graph is associated with.

arccore.graph weighted edge traverse enhancement

I just release v0.1.9 crescent with support for weigted edge BFT/DFT.

In hindsight I missed an rather obvious usability enhanancement.

Currently, to enable edge-weighted traversal you need to add getEdgeWeight and compareEdgeWeights callback function definitions to your visitor object.

But, in the vast majority of cases the developer-defined edge weight will a value of a type that is comparable via standard less-than and greater-than operators (e.g. string, numeric value).

So, we should allow developers to specify on getEdgeWeight to enable edge-weight traversal feature. And, allow compareEdgeWeight to be left unspecified in order to use default comparison operator provided by graph library (should be sufficient for 80% of use cases).

arccore.filter should allow caller to specify a base RIS path

Oftentimes we leverage arccore.filter to validate/normalize some branch of a larger data structure.

For example, we may have a large deserialized JSON document and need to process just a single branch of the whole with a filter.

In cases such as this it would be nice to be able to call the filter passing in a reference to the root of the branch in the data as the filter request in-param AND also the path in the larger document that was dereferenced to obtain obtain the reference.

We would do this so that an error in the filter would get reported with the path of the data in the larger document and not as ~.blah.blah where ~ corresponds to the filter request in-param itself.

This is very confusing to developers especially when the use of the filter that returns the error is buried deep inside some large mechanism.

arccore.filter bug in filter spec directive quanderscore parsing

re: @encapsule/arccore v0.1.6 "grasslands" https://www.npmjs.com/package/@encapsule/arccore

I was writing a large filter spec and noticed something odd in the way that filter parses filter spec directives (e.g. quanderscore-prefixed filter spec namespace descriptor object properties).

This is nonsense!

Error: Filter factory failure: While examining data namespace '~.outputFilterSpec.evalFrames.evalFrameDescriptor.frameEvalResults.frameEvalSummary.transitions.cdsDataPath': Unrecognized typemap directive '___________________________________________________whatever' not allowed in declaration.

I haven't looked at the code but am sure that I incorrectly determine that the property name starts with four underscores and then but neglected to account for some idiot (me - I found it) using more than four underscore.

This is very unlikely to impact very many people. However, filter should correctly parse quanderscore directives correctly to ensure that the FSP produces the correct error message in all cases.

arccore.util.deepCopy is not general-purpose

arccore.util.deepCopy (aka arccore.util.clone) derives from an implementation taken from the CoffeeScript Cookbook. This function has generally performed well. But, it's not well tested. And, it's not adequately documented...
... Specifically, it does not appear that this function handles arrays correctly. And, all manner of hell can break loose if the input reference is to something with internal cycles.
Take another look at this:

Should work for arrays (add tests)
Should not allow stack overflow due to unbounded recursion

Here's a little code fragment I authored that's related to arccore.util.deepCopy (used in the context of trying to clone DirectedGraph class instances).

const arccore = require("@encapsule/arccore");

var response = arccore.graph.directed.create({
    name: "Source Digraph",
    description: "This is a graph that we will clone.",
    vlist: [
        { u: "apple", p: "Edible skin" },
        { u: "orange", p: "Inedible skin" }
    ],
    elist: [
        { e: { u: "apple", v: "orange" }, p: "Not the same" }
    ]
});
if (response.error) {
    throw new Error(response.error);
}
var sourceDigraph = response.result;

// Clone via serialize/deserialize
response = arccore.graph.directed.create(sourceDigraph.toJSON());
if (response.error) {
    throw new Error(response.error);
}
var cloneDigraph1 = response.result;

// Clone via arccore.util.clone
var cloneDigraph2 = arccore.util.clone(sourceDigraph);

// Compare contents of the source and clone 1 digraphs. We expect them to be the same.
if (sourceDigraph.stringify() !== cloneDigraph1.stringify()) {
    console.log("! Source digraph JSON is not equal to clone 1 digraph JSON.");
} else {
    console.log("> Clone 1 digraph JSON reads as expected.");
}

// Compare contents of the source and clone 2 digraphs. We expect them to be the same.
if (sourceDigraph.stringify() !== cloneDigraph2.stringify()) {
    console.log("! Source digraph JSON is not equal to clone 2 digraph JSON.");
} else {
    console.log("> Clone 2 digraph JSON reads as expected.");
}

// What's not 100% clear is what happens when we mutate the containers. Specifically,
// client code could subsequently mutate the source, or derived clone in a number of
// different ways: CRUD operation on vertex/edge properties, topological updates
// (vertex & edge add/remove operations).
//
// So the questions I've come up with so far are:
// - How best to affect a deep copy of a DirectedGraph instance.
// - Is it useful to have deep copy for topology and shallow (i.e. shared) copy for vertex/edge properties?
// - What exactly does arccore.util.clone and arccore.util.deepcopy do? Do they act as we expect? How about for DirectedGraph?

// Let's assume that clone 1 is a true deep copy meaning that we can change both its properties and topology without any impact on the source or other test clone.

// Update a vertex property on the clone 1
cloneDigraph1.setVertexProperty({ u: "apple", p: "apple property updated specifically on clone 1" });

if (sourceDigraph.getVertexProperty("apple") === cloneDigraph1.getVertexProperty("apple")) {
    console.log("! Update to clone 1 vertex property reflected back to source digraph.");
} else {
    console.log("> Update of clone 1 vertex property did not update source digraph.");
}

cloneDigraph1.addEdge({ e: { u: "apple", v: "mango" }, p: "Better together..." });

if (sourceDigraph.isEdge({ u: "apple", v: "mango"})) {
    console.log("! Edge added to clone 1 reflected back to source digraph.");
} else {
    console.log("> Edge added to clone 1 did not update source digraph.");
}

// clone 2
cloneDigraph2.setVertexProperty({ u: "apple", p: "apple property updated specifically on clone 1" });

if (sourceDigraph.getVertexProperty("apple") === cloneDigraph2.getVertexProperty("apple")) {
    console.log("! Update to clone 2 vertex property reflected back to source digraph.");
} else {
    console.log("> Update of clone 2 vertex property did not update source digraph.");
}

cloneDigraph2.addEdge({ e: { u: "apple", v: "mango" }, p: "Better together..." });

if (sourceDigraph.isEdge({ u: "apple", v: "mango"})) {
    console.log("! Edge added to clone 2 reflected back to source digraph.");
} else {
    console.log("> Edge added to clone 2 did not update source digraph.");
}

console.log("----------------------------------------------------------------");
console.log("Conclusions:");
console.log("- Deep copy by calling toJSON on source digraph passing the resultant object to arccore.graph.directed.create.");
console.log("- DO NOT use arccore.util.clone until this funciton is tested and documented. And, do not use its alias arccore.util.deepCopy because it's a lie in v0.1.3 apparently.");

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.