Tree
tree holds deeply nested maps and lists enabling you to represent any custom state. list have strictly ordered elements with numeric indicies and maps are key value pairs. you can nest values in any way to fit your usecase.
const context = colab.changeContext();
const tree = context.tree("tasks");
const tasks = tree.setActions((tasks: Task[]) => {
createTask(index: number, task: Task){
tasks.insert(index, task);
},
markDone(index: number, done: boolean){
tasks[index].done = done;
},
deleteTask(index:number){
tasks[index].delete()
}
//...
});
tree.setHandlers({
createTask(index: number, task: Task, ctx: Ictx){
//... add task to ui
},
markDone(index:number, done: booleab, ctx: Ictx){
// ...
},
//...
});
// use in predefined actions
tasks.createTask(0, {
title: "update ",
done: false,
desdcription: "the new docs",
tags:["docs", "cyxth"]
});
//or modify directly
tree.state.tasks[0].tags.push("colab");
// ...
interface Tree {
defaultHandlers: {
delete?: (path: string | number[], ctx: Ictx) => any;
insert?: (path: string | number[], value: any, ctx: Ictx) => any;
update?: (path: string | number[], value: any, ctx: Ictx) => any;
};
get state(): any;
setActions(actions: (state: any) => void): any;
setHandlers(handlers: any): any;
value(path: any): { concurrent?: any; state: any };
}
index
properties
methods
Properties
defaultHandlers
default action handler
useful if you don't have predefined actions and handlers. state changes done directly with Tree.state trigger these default handlers if they don't match handlers.
there are three main tree actions insert, delete and update. insert and update set value at a certain
keypath whereas delete deletes value at key path. the main difference between insert and update is insert serves
to differentiante list inserts and updates otherwise all inserts to objects are updates. if all named handlers
fail one of these handlers will be triggered.
{ delete?: (path: string | number[], ctx: Ictx) => any ;insert?: (path: string | number[], value: any, ctx: Ictx) => any ;update?: (path: string | number[], value: any, ctx: Ictx) => any ; }state
get state for direct modification
note: though the state may look like regular javascript objects they are not only a subset of operations are supported. for example for lists there is only push and pop from javascript which work completly different from regular js arrays. colab adds insert method for lists instead of shift and unshit and an update method to lists and objects
here is a list of supported methods
- push - lists only
- pop - lists only
- insert - lists only
- update - lists and objects
- delete - lists and objects
const tree = context.tree("tasks");
const tasks: Task[] = tree.state;
tasks.push({title: "hello world"});
tasks[0].title = "hi cyxth!";
anyMethods
setActions
setActions (actions: (state: any) => void ) : any ;set actions that modify state
Text and Counter have predefined actions insert, delete & replace and update respectively. to achieve the same functionality for tree we create our own actions and handlers. actions are created by providing named functions that modify state. these functions are transformed to handlers with an added context.
Note: For handlers to work you must set actions first. check handlers for more
//...
const tree = context.tree("tasks");
const myTasks = tree.setActions((tasks: Task[]) => {
createTask(index: number, task: Task){
tasks.insert(index, task);
},
markDone(index: number, done: boolean){
tasks[index].done = done;
},
updateTask(index: number, data: Partial<Task>){
tasks[index].update(data);
}
});
// now to use in your application
myTasks.createTask(0, {
title: "hello world",
done: false,
description: "am just saying hi!"
});
//...
Parameters
actions
state modification functions.
(state: any) : void ;Returns
the same actions you provide, use the actions to modify state in app
anysetHandlers
setHandlers (handlers: any) : any ;set action handlers
tree.setHandlers({
createTask(index: number, task: Task, ctx: Ictx){
console.log(ctx.userId);
console.log("created task at index [object Object] :",task);
}
// ...
})
when the actions set are performed either locally or remotely they are handled by the same handlers. this generally the actions you pass with setActions with an added context parameter.
if you use push() and pop() in actions there is a pushIndex and popIndex respectively in the context
don't push or pop in handler as the indicies might have changed which may lead to inconsistency with ui.
Parameters
handlers
anyReturns
anyvalue
value (path: any) : { concurrent?: any;state: any; } ;get tree value
Parameters
path
anyReturns
the current state and concurrent values if they exist
{ concurrent?: any;state: any; }