-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
serialization/deserialization of actions #21
Comments
Good question. Serialization is a problem since the constructed values are represented as arrays with additional properties. From the top of my head the easiest solution would be to create two simple conversion functions that changes the values to JSON compatible representations. |
I think deserialization is the real issue. |
sorry, my last comment wasn't very explicit; What I mean is that when deserializing a JSON representation; how do we determine the correct type constructor to apply. Perhaps if we could identify each type with a serializable attribute like a global uuid function typeRegistry = {}
function Type(desc) {
var obj = {};
obj.uid = guuid()
typeRegistry [obj.uid] = obj
...
}
function serialize(inst) {
const obj = serializeHelper(inst)
obj.typeId = inst.of.uid
return JSON.stringify(obj)
}
function deserialize(json) {
const inst = JSON.parse(json)
const type = typeRegistry[inst.typeId]
return type[inst.name](inst)
} EDIT: fixed code |
For the above to work; uuid needs to be the same across multiple debug sessions (possibly on different machines). We can also set A possible solution is to compute the type id from the desc argument function Type(desc) {
var obj = {};
obj.id = JSON.stringify( Object.keys(desc) ) // could be more reliable
for (var key in desc) {
// set the 'of' guard to the object id
obj[key] = Constructor(obj.id, key, desc[key]);
}
obj.case = typeCase(obj);
obj.caseOn = caseOn(obj);
return obj;
}
function serialize(instance) {
return JSON.stringify({
vals: instance,
key: instance.name,
typeId: instance.of
})
}
function deserialize(json) {
const o = JSON.parse(json)
const inst = o.vals
inst.name = o.key
inst.of = o.typeId
return inst
} |
@yelouafi I'd be interested in what did you end up doing ? |
@jgoux Actually I ended up with implementing my poor-man's solution No currying and may need some refinements, but actions are plain objects const Any = () => true
function validate(value, contract) {
if(contract === String)
return typeof value === 'string'
if(contract === Number)
return typeof value === 'number'
else
return contract(value)
}
export function unionOf(union) {
const res = {}
const keys = Object.keys(union)
const unionKey = keys.join('|')
keys.forEach(type => {
const contracts = union[type]
res[type] = (...args) => {
contracts.forEach((c, idx) => {
if(!validate(args[idx], c))
throw new Error(`Case Error: invalid argument passed to ${type} at position ${idx}`)
})
return {type, args, unionKey }
}
})
res.caseOf = (action, cases) => {
let handler, args
if(action.unionKey === unionKey) {
handler = cases[action.type] || cases._
args = action.args
} else {
handler = cases._
args = [action]
}
if(!handler)
throw `Unkwon case action ${action}`
return handler.apply(null, args)
}
return res
} |
If we represent Actions in Elm architecture as plain objects we can record a play sequence by simple JSON stringify/parse.
How should this be acheived in union types ?
The text was updated successfully, but these errors were encountered: