createCommit / objectCreate Graphql

Hey everyone :wave:

I’ve jumped into sending objects via graphql. I’ve set up my mutation in the SpeckleGraphql API as:

mutation ObjectCreate($objectInput: ObjectCreateInput!) {
  objectCreate(objectInput: $objectInput)
}

With my variable (stolen from the examples):

{
	"objectInput": {
		"streamId": "176fe28bae",
		"objects": {
			"id": "9b2cdb21da092dbd3558a4bc55b2cf7e",
			"speckle_type": "Base",
			"totalChildrenCount": 0,
			"numbers": [
				0.04667752874618203,
				0.16370857295385177,
				0.1008153029515465
                ]
		}
	}
}

Is my understanding that these objects are just floating around unassigned until I send a createCommit mutation to assign it? I was reading this topic Updating Speckle Streams from JS to figure out how the objectCreate and createCommit work…

Yes, All objects exist forever in an ever-expanding list.

Commits are the principle mechanism to determine a specific project version at a point in time.

Commits could be engineered to make completely hybrid collections of objects also. The creation timestamp of an object is a datapoint on each object, independent of the commit.

Draw down a commit object with GraphQL. All the constituent objects are listed as referenceObjects because serialization happens before the commit object is created.

1 Like

So theoretically you could create a commit that grabs all of a specific object (if you have the reference ids), to create a timeline of some data point? That’s neat.

@jonathon I have the objectCreate and createCommit working, but I don’t have access to crypto-random-string; do ids need to be hashed from the contents of the object or can I just use uuids? Is there some way to create ids manually?

Where are you making your GraphQl calls from?

Assuming I have read you right (you are referring to a JS tutorial after all) you can use the crypto library and call the serialization yourself:

const crypto = require('crypto')
getId(obj) {
   return crypto.createHash('md5').update(JSON.stringify(obj)).digest('hex')
}

If you have nested objects it can get a bit more complicated.

The code above is what the Sketchup Connector used to use before it became properly Rubyfied (and improved) by @oguzhankoral. Nevertheless, the Object conversion, traversal and serialization can be found here: speckle-sketchup/serialization.js at 44ec7734d4e3c5fb4fd973ff0c7750f8dce10137 · specklesystems/speckle-sketchup · GitHub you’ll notice it has a deprecated flag on it, I have posted a link to the timestamped version in case it gets deleted.


It is neat! But with great power comes…


PPS
If you are, instead, running your code not on a nodejs server nor wrapping it up with webpack the equivalent library is [crypto-js](https://github.com/brix/crypto-js)

1 Like

Hey @lukxfnz,

Hashing helps us to do checksum between objects. If you hash same object twice, you will get the same id. By this way we can check objects are exist before or not in any scope (server, host program…). So ideally hashing should be the way to go.

That’s correct unless you do care the “unassigned” object state in host program. If do so, you need to hold state of the object and it’s id to follow lifecycle of the objects. That was the main reason as @jonathon said, I refactored this serialization process to Ruby for SketchUp connector.

1 Like

Thanks @jonathon and @oguzhankoral!

For context I’m using retool.com to build a CRUD dashboard. It’s limited what javascript libraries I can use with it, but I think crypto-js is working, although I couldn’t call the createHash function (can only use the functions directly inside of crypto-js), instead I’m passing the object into cyrpto.MD5(obj).toString() to generate an id where obj is my object to be committed - it seems to be working? Let me know if this isn’t a valid way of generating ids…

I haven’t got nested objects at the moment but if you can point me to an example somewhere that would be helpful (the batchObject function from the serialization.js example @jonathon?) :sweat_smile:

It’s only more complicated in that you start to get into potentially needing to detach (only if you want to), which would mean incrementally traversing the objects as you serialize.

You can hash the objects any way you wish if you are always in control. If it consistently produces a unique hash, then you’re relatively fine.

1 Like