Created
May 29, 2023 16:41
-
-
Save dmaretskyi/8e580357c84a50794353b56a02ff5e39 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const createStore = <T,> (initialValue: T): T => { | |
return initialValue; | |
} | |
type S<T> = T | |
interface Atom<T> { | |
// Get | |
(): T | |
} | |
const createAtom = <T,> (initialValue: T): Atom<T> => { | |
return () => initialValue; | |
} | |
const set = <T,>(storeOrAtom: T, newValue: T): void => {} | |
const effect = (fn: () => void) => { | |
} | |
type Subscription = { | |
update: (selection: any[]) => void; | |
} | |
const createSubscription = (cb: () => void): Subscription => null as any; | |
/////// | |
const computed = <T,>(fn: () => T): T => { | |
const store = createStore(???); | |
effect(() => { | |
store.set(fn()) | |
}) | |
return store; | |
} | |
/////// | |
type GraphNode = { | |
title: string | |
} | |
/** | |
CHANGE node1.title | |
EFFECT in getNodes(node1): children1 | |
change children1 | |
*/ | |
interface GraphPlugin { | |
getNodes: (parent?: GraphNode) => GraphNode[] | |
} | |
//////// | |
// type FullNode = { | |
// head: GraphNode | |
// children: GraphNode[] | |
// mounted: boolean | |
// } | |
// const getFullGraph = (plugins: GraphPlugin[]): FullNode[] => { | |
// const state = createStore<Record<string, FullNode>>({}) | |
// // nodes, state, state[node.id] | |
// const insertNodes = (nodes: GraphNode[]) => { | |
// for(const node of nodes) { | |
// if(state[node.id]) { | |
// state[node.id].head = node; | |
// } else { | |
// state[node.id] = createStore({ | |
// head: node, | |
// children: [], | |
// mounted: false | |
// }) | |
// } | |
// } | |
// } | |
// // Roots effect: plugins, plugin.getNodes(), plugin.getNodes()[i], state | |
// effect(() => { | |
// for(const plugin of plugins) { | |
// const roots = plugin.getNodes() | |
// insertNodes(roots) | |
// } | |
// }) | |
// // state | |
// effect(() => { | |
// for(const node of Object.values(state)) { | |
// // node, plugins | |
// effect(() => { | |
// for(const plugin of plugins) { | |
// const children = plugin.getNodes(node.head) | |
// insertNodes(children) | |
// } | |
// }) | |
// } | |
// }) | |
// return computed(() => Object.values(state)) | |
// } | |
type FullNode = { | |
head: GraphNode | null | |
parent: FullNode | null | |
children: S<FullNode[]> | |
// subscription: Subscription | |
} | |
/** | |
* - Ignoring `plugins` being reactive | |
* | |
* TODO: | |
* - We iterate the map on every update | |
* - We don't unsubscribe when nodes get removed | |
*/ | |
const getFullGraph = (plugins: GraphPlugin[]): S<FullNode[]> => { | |
const state = new Map<GraphNode, FullNode>() // key === value.head | |
const root: FullNode = { | |
head: null, | |
parent: null, | |
// unified node store | |
children: createStore([]), | |
} | |
const subscribeToNodesWithParent = (parent: FullNode) => { | |
for(const plugin of plugins) { | |
const nodes = plugin.getNodes(parent.head ?? undefined) | |
createSubscription(() => { | |
for(const node of nodes) { | |
if(state.has(node)) { | |
continue; | |
} | |
const fullNode: FullNode = { | |
head: node, | |
parent, | |
children: createStore([]), | |
} | |
state.set(node, fullNode) | |
subscribeToNodesWithParent(fullNode) | |
} | |
const newChildren = Array.from(state.values()).filter(node => node.parent === parent) | |
set(parent.children, newChildren) | |
}).update(nodes) | |
} | |
} | |
subscribeToNodesWithParent(root); | |
return root.children; | |
} | |
//// | |
const example1: GraphPlugin = { | |
getNodes: (parent) => computed<GraphNode[]>(() => { | |
if(parent === undefined) { | |
return [{ title: 'foo' }] | |
} else { | |
return [] | |
} | |
}) | |
} | |
const example2: GraphPlugin = { | |
getNodes: (parent) => computed<GraphNode[]>(() => { | |
return parent?.title.split('').map(x => ({ | |
title: x | |
})) ?? [] | |
}) | |
} | |
// createEffect(() => { | |
// }).react([nodes]).... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment