@dxos/app-graph 0.4.4-main.fcf0b00 → 0.4.4-next.e0df51e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -85,7 +85,7 @@ var Graph = class {
85
85
  };
86
86
 
87
87
  // packages/sdk/app-graph/src/graph-builder.ts
88
- import { untracked } from "@preact/signals-react";
88
+ import { untracked } from "@preact/signals-core";
89
89
  import { deepSignal as deepSignal2 } from "deepsignal/react";
90
90
  import { EventSubscriptions } from "@dxos/async";
91
91
  import { Keyboard } from "@dxos/keyboard";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/graph.ts", "../../../src/graph-builder.ts", "../../../src/node.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal } from 'deepsignal/react';\n// TODO(wittjosiah): Remove lodash dependency.\nimport get from 'lodash.get';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { type Label } from './action';\nimport { type Node } from './node';\n\nexport type TraversalOptions = {\n /**\n * The node to start traversing from. Defaults to the root node.\n */\n node?: Node;\n\n /**\n * The direction to traverse the graph. Defaults to 'down'.\n */\n direction?: 'up' | 'down';\n\n /**\n * A predicate to filter nodes which are passed to the `visitor` callback.\n */\n filter?: (node: Node) => boolean;\n\n /**\n * A callback which is called for each node visited during traversal.\n */\n visitor?: (node: Node, path: string[]) => void;\n};\n\n/**\n * The Graph represents the structure of the application constructed via plugins.\n */\nexport class Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n private readonly _index = deepSignal<Record<string, string[]>>({});\n\n constructor(private readonly _root: Node) {}\n\n toJSON() {\n const toLabel = (label: Label) => (Array.isArray(label) ? `${label[1].ns}[${label[0]}]` : label);\n const toJSON = (node: Node): any => {\n return {\n id: node.id.slice(0, 16),\n label: toLabel(node.label),\n children: node.children.length ? node.children.map((node) => toJSON(node)) : undefined,\n actions: node.actions.length\n ? node.actions.map(({ id, label }) => ({\n id,\n label: toLabel(label),\n }))\n : undefined,\n };\n };\n\n return toJSON(this._root);\n }\n\n /**\n * The root node of the graph which is the entry point for all knowledge.\n */\n get root(): Node {\n return this._root;\n }\n\n /**\n * Get the path through the graph from the root to the node with the given id.\n */\n getPath(id: string): string[] | undefined {\n return this._index[id];\n }\n\n /**\n * @internal\n */\n _setPath(id: string, path: string[]) {\n invariant(id && path, 'Invalid path.');\n this._index[id] = path;\n }\n\n /**\n * Find the node with the given id in the graph.\n */\n findNode(id: string): Node | undefined {\n const path = this.getPath(id);\n if (!path) {\n return undefined;\n }\n\n return path.length > 0 ? get(this._root, path) : this._root;\n }\n\n /**\n * Recursive breadth-first traversal.\n */\n traverse({ node = this._root, direction = 'down', filter, visitor }: TraversalOptions, depth = 0): void {\n if (!filter || filter(node)) {\n visitor?.(node, this.getPath(node.id)!);\n }\n\n if (direction === 'down') {\n Object.values(node.children).forEach((child) => this.traverse({ node: child, filter, visitor }));\n } else if (direction === 'up' && node.parent) {\n this.traverse({ node: node.parent, direction, filter, visitor }, depth + 1);\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-react';\nimport { type RevertDeepSignal, deepSignal } from 'deepsignal/react';\n\nimport { EventSubscriptions } from '@dxos/async';\nimport { Keyboard } from '@dxos/keyboard';\nimport { getHostPlatform } from '@dxos/util';\n\nimport type { ActionArg, Action } from './action';\nimport { Graph } from './graph';\nimport type { NodeArg, Node, NodeBuilder } from './node';\n\nexport const KEY_BINDING = 'KeyBinding';\n\n/**\n * The builder...\n */\nexport class GraphBuilder {\n private readonly _nodeBuilders = new Map<string, NodeBuilder>();\n private readonly _unsubscribe = new Map<string, EventSubscriptions>();\n\n /**\n * Register a node builder which will be called in order to construct the graph.\n */\n addNodeBuilder(id: string, builder: NodeBuilder): GraphBuilder {\n this._nodeBuilders.set(id, builder);\n return this;\n }\n\n /**\n * Remove a node builder from the graph builder.\n */\n removeNodeBuilder(id: string): GraphBuilder {\n this._nodeBuilders.delete(id);\n return this;\n }\n\n /**\n * Construct the graph, starting by calling all registered node builders on the root node.\n * Node builders will be filtered out as they are used such that they are only used once on any given path.\n * @param previousGraph If provided, the graph will be updated in place.\n * @param startingPath If provided, the graph will be updated starting at the given path.\n */\n build(previousGraph?: Graph, startingPath: string[] = []): Graph {\n const graph: Graph = previousGraph ?? new Graph(this._createNode(() => graph, { id: 'root', label: 'Root' }));\n return this._build(graph, graph.root, startingPath);\n }\n\n /**\n * Called recursively.\n */\n private _build(graph: Graph, node: Node, path: string[] = [], ignoreBuilders: string[] = []): Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n graph._setPath(node.id, path);\n\n // TODO(burdon): Document.\n const subscriptions = this._unsubscribe.get(node.id) ?? new EventSubscriptions();\n subscriptions.clear();\n\n Array.from(this._nodeBuilders.entries())\n .filter(([id]) => ignoreBuilders.findIndex((ignore) => ignore === id) === -1)\n .forEach(([_, builder]) => {\n const unsubscribe = builder(node);\n unsubscribe && subscriptions.add(unsubscribe);\n });\n\n this._unsubscribe.set(node.id, subscriptions);\n\n return graph;\n }\n\n private _createNode<TData = null, TProperties extends Record<string, any> = Record<string, any>>(\n getGraph: () => Graph,\n partial: NodeArg<TData, TProperties>,\n path: string[] = [],\n ignoreBuilders: string[] = [],\n ): Node<TData, TProperties> {\n // TODO(burdon): Document implications and rationale of deepSignal.\n const node: Node<TData, TProperties> = deepSignal({\n parent: null,\n data: null as TData, // TODO(burdon): Allow null property?\n properties: {} as TProperties,\n childrenMap: {},\n actionsMap: {},\n // TODO(burdon): Document.\n ...partial,\n\n get children() {\n return Object.values(node.childrenMap);\n },\n get actions() {\n return Object.values(node.actionsMap);\n },\n\n //\n // Properties\n //\n\n addProperty: (key, value) => {\n untracked(() => {\n (node.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n untracked(() => {\n delete (node.properties as Record<string, any>)[key];\n });\n },\n\n //\n // Nodes\n //\n\n addNode: (builder, ...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const builders = [...ignoreBuilders, builder];\n const childPath = [...path, 'childrenMap', partial.id];\n const child = this._createNode(getGraph, { ...partial, parent: node }, childPath, builders);\n node.childrenMap[child.id] = child;\n // TODO(burdon): Defer triggering recursive updates until task has completed.\n this._build(getGraph(), child, childPath, builders);\n return child;\n });\n });\n },\n removeNode: (id) => {\n return untracked(() => {\n const child = node.childrenMap[id];\n delete node.childrenMap[id];\n return child;\n });\n },\n\n //\n // Actions\n //\n\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const action = this._createAction(partial);\n let shortcut: string | undefined;\n if (typeof action.keyBinding === 'object') {\n const availablePlatforms = Object.keys(action.keyBinding);\n const platform = getHostPlatform();\n shortcut = availablePlatforms.includes(platform)\n ? action.keyBinding[platform]\n : platform === 'ios'\n ? action.keyBinding.macos // Fallback to macos if ios-specific bindings not provided.\n : platform === 'linux' || platform === 'unknown'\n ? action.keyBinding.windows // Fallback to windows if platform-specific bindings not provided.\n : undefined;\n } else {\n shortcut = action.keyBinding;\n }\n if (shortcut) {\n Keyboard.singleton.getContext(path.join('/')).bind({\n shortcut,\n handler: () => {\n action.invoke({ caller: KEY_BINDING });\n },\n data: action.label,\n });\n }\n\n node.actionsMap[action.id] = action;\n return action;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const action = node.actionsMap[id];\n if (action.keyBinding) {\n // keyboardjs.unbind(action.keyBinding);\n }\n\n delete node.actionsMap[id];\n return action;\n });\n },\n }) as RevertDeepSignal<Node<TData, TProperties>>;\n\n // Only actions added at this stage are available to subsequent builders.\n // `addNode` immediately passes the new node to other builders.\n // As such, actions added later with `addAction` are not available to those builders.\n // Having actions available to subsequent builders is useful for building groups.\n partial.actions && partial.actions.forEach((action) => node.addAction(action));\n\n return node;\n }\n\n private _createAction<TProperties extends Record<string, any> = Record<string, any>>(\n partial: ActionArg<TProperties>,\n ): Action<TProperties> {\n const action: Action<TProperties> = deepSignal({\n properties: {} as TProperties,\n ...partial,\n actionsMap: {},\n get actions() {\n return Object.values(action.actionsMap);\n },\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const subAction = this._createAction(partial);\n action.actionsMap[subAction.id] = subAction;\n return subAction;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const subAction = action.actionsMap[id];\n delete action.actionsMap[id];\n return subAction;\n });\n },\n addProperty: (key, value) => {\n return untracked(() => {\n (action.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n return untracked(() => {\n delete (action.properties as Record<string, any>)[key];\n });\n },\n }) as RevertDeepSignal<Action<TProperties>>;\n\n partial.actions && partial.actions.forEach((subAction) => action.addAction(subAction));\n\n return action;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport type { IconProps } from '@phosphor-icons/react';\nimport { type FC } from 'react';\n\nimport type { UnsubscribeCallback } from '@dxos/async';\n\nimport { type ActionArg, type Action, type Label } from './action';\n\n/**\n * Called when a node is added to the graph, allowing other node builders to add children, actions or properties.\n */\nexport type NodeBuilder = (parent: Node) => UnsubscribeCallback | void;\n\n/**\n * Represents a node in the graph.\n */\nexport type Node<TData = any, TProperties extends Record<string, any> = Record<string, any>> = {\n /**\n * Globally unique ID.\n */\n id: string;\n\n /**\n * Parent node in the graph.\n */\n parent: Node | null;\n\n /**\n * Label to be used when displaying the node.\n * For default labels, use a translated string.\n *\n * @example 'My Node'\n * @example ['unknown node label, { ns: 'example-plugin' }]\n */\n label: Label;\n\n /**\n * Description to be used when displaying a detailed view of the node.\n * For default descriptions, use a translated string.\n */\n description?: Label;\n\n /**\n * Icon to be used when displaying the node.\n */\n icon?: FC<IconProps>;\n\n /**\n * Properties of the node relevant to displaying the node.\n */\n // TODO(burdon): Make this extensible and move label, description, and icon into here?\n properties: TProperties;\n\n /**\n * Data the node represents.\n */\n // TODO(burdon): Type system (e.g., minimally provide identifier string vs. TypedObject vs. Graph mixin type system)?\n // type field would prevent convoluted sniffing of object properties. And allow direct pass-through for ECHO TypedObjects.\n // TODO(burdon): In some places `null` is cast to TData so make optional?\n data: TData;\n\n /**\n * Children of the node stored by their id.\n */\n // TODO(burdon): Rename nodes/nodeMap?\n childrenMap: Record<string, Node>;\n\n /**\n * Actions of the node stored by their id.\n */\n actionsMap: Record<string, Action>;\n\n /**\n * Children of the node in default order.\n */\n get children(): Node[];\n\n /**\n * Actions of the node in default order.\n */\n get actions(): Action[];\n\n addProperty(key: string, value: any): void;\n removeProperty(key: string): void;\n\n addNode<TChildData = null, TChildProperties extends Record<string, any> = Record<string, any>>(\n id: string,\n ...node: NodeArg<TChildData, TChildProperties>[]\n ): Node<TChildData, TChildProperties>[];\n removeNode(id: string): Node;\n\n addAction<TActionProperties extends Record<string, any> = Record<string, any>>(\n ...action: ActionArg<TActionProperties>[]\n ): Action<TActionProperties>[];\n removeAction(id: string): Action;\n};\n\nexport type NodeArg<TData = null, TProperties extends Record<string, any> = Record<string, any>> = Pick<\n Node,\n 'id' | 'label'\n> &\n Partial<Omit<Node<TData, TProperties>, 'id' | 'label' | 'actions'>> & { actions?: ActionArg[] };\n\nexport const isGraphNode = (data: unknown): data is Node =>\n data && typeof data === 'object' ? 'id' in data && 'label' in data : false;\n"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal } from 'deepsignal/react';\n// TODO(wittjosiah): Remove lodash dependency.\nimport get from 'lodash.get';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { type Label } from './action';\nimport { type Node } from './node';\n\nexport type TraversalOptions = {\n /**\n * The node to start traversing from. Defaults to the root node.\n */\n node?: Node;\n\n /**\n * The direction to traverse the graph. Defaults to 'down'.\n */\n direction?: 'up' | 'down';\n\n /**\n * A predicate to filter nodes which are passed to the `visitor` callback.\n */\n filter?: (node: Node) => boolean;\n\n /**\n * A callback which is called for each node visited during traversal.\n */\n visitor?: (node: Node, path: string[]) => void;\n};\n\n/**\n * The Graph represents the structure of the application constructed via plugins.\n */\nexport class Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n private readonly _index = deepSignal<Record<string, string[]>>({});\n\n constructor(private readonly _root: Node) {}\n\n toJSON() {\n const toLabel = (label: Label) => (Array.isArray(label) ? `${label[1].ns}[${label[0]}]` : label);\n const toJSON = (node: Node): any => {\n return {\n id: node.id.slice(0, 16),\n label: toLabel(node.label),\n children: node.children.length ? node.children.map((node) => toJSON(node)) : undefined,\n actions: node.actions.length\n ? node.actions.map(({ id, label }) => ({\n id,\n label: toLabel(label),\n }))\n : undefined,\n };\n };\n\n return toJSON(this._root);\n }\n\n /**\n * The root node of the graph which is the entry point for all knowledge.\n */\n get root(): Node {\n return this._root;\n }\n\n /**\n * Get the path through the graph from the root to the node with the given id.\n */\n getPath(id: string): string[] | undefined {\n return this._index[id];\n }\n\n /**\n * @internal\n */\n _setPath(id: string, path: string[]) {\n invariant(id && path, 'Invalid path.');\n this._index[id] = path;\n }\n\n /**\n * Find the node with the given id in the graph.\n */\n findNode(id: string): Node | undefined {\n const path = this.getPath(id);\n if (!path) {\n return undefined;\n }\n\n return path.length > 0 ? get(this._root, path) : this._root;\n }\n\n /**\n * Recursive breadth-first traversal.\n */\n traverse({ node = this._root, direction = 'down', filter, visitor }: TraversalOptions, depth = 0): void {\n if (!filter || filter(node)) {\n visitor?.(node, this.getPath(node.id)!);\n }\n\n if (direction === 'down') {\n Object.values(node.children).forEach((child) => this.traverse({ node: child, filter, visitor }));\n } else if (direction === 'up' && node.parent) {\n this.traverse({ node: node.parent, direction, filter, visitor }, depth + 1);\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\nimport { type RevertDeepSignal, deepSignal } from 'deepsignal/react';\n\nimport { EventSubscriptions } from '@dxos/async';\nimport { Keyboard } from '@dxos/keyboard';\nimport { getHostPlatform } from '@dxos/util';\n\nimport type { ActionArg, Action } from './action';\nimport { Graph } from './graph';\nimport type { NodeArg, Node, NodeBuilder } from './node';\n\nexport const KEY_BINDING = 'KeyBinding';\n\n/**\n * The builder...\n */\nexport class GraphBuilder {\n private readonly _nodeBuilders = new Map<string, NodeBuilder>();\n private readonly _unsubscribe = new Map<string, EventSubscriptions>();\n\n /**\n * Register a node builder which will be called in order to construct the graph.\n */\n addNodeBuilder(id: string, builder: NodeBuilder): GraphBuilder {\n this._nodeBuilders.set(id, builder);\n return this;\n }\n\n /**\n * Remove a node builder from the graph builder.\n */\n removeNodeBuilder(id: string): GraphBuilder {\n this._nodeBuilders.delete(id);\n return this;\n }\n\n /**\n * Construct the graph, starting by calling all registered node builders on the root node.\n * Node builders will be filtered out as they are used such that they are only used once on any given path.\n * @param previousGraph If provided, the graph will be updated in place.\n * @param startingPath If provided, the graph will be updated starting at the given path.\n */\n build(previousGraph?: Graph, startingPath: string[] = []): Graph {\n const graph: Graph = previousGraph ?? new Graph(this._createNode(() => graph, { id: 'root', label: 'Root' }));\n return this._build(graph, graph.root, startingPath);\n }\n\n /**\n * Called recursively.\n */\n private _build(graph: Graph, node: Node, path: string[] = [], ignoreBuilders: string[] = []): Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n graph._setPath(node.id, path);\n\n // TODO(burdon): Document.\n const subscriptions = this._unsubscribe.get(node.id) ?? new EventSubscriptions();\n subscriptions.clear();\n\n Array.from(this._nodeBuilders.entries())\n .filter(([id]) => ignoreBuilders.findIndex((ignore) => ignore === id) === -1)\n .forEach(([_, builder]) => {\n const unsubscribe = builder(node);\n unsubscribe && subscriptions.add(unsubscribe);\n });\n\n this._unsubscribe.set(node.id, subscriptions);\n\n return graph;\n }\n\n private _createNode<TData = null, TProperties extends Record<string, any> = Record<string, any>>(\n getGraph: () => Graph,\n partial: NodeArg<TData, TProperties>,\n path: string[] = [],\n ignoreBuilders: string[] = [],\n ): Node<TData, TProperties> {\n // TODO(burdon): Document implications and rationale of deepSignal.\n const node: Node<TData, TProperties> = deepSignal({\n parent: null,\n data: null as TData, // TODO(burdon): Allow null property?\n properties: {} as TProperties,\n childrenMap: {},\n actionsMap: {},\n // TODO(burdon): Document.\n ...partial,\n\n get children() {\n return Object.values(node.childrenMap);\n },\n get actions() {\n return Object.values(node.actionsMap);\n },\n\n //\n // Properties\n //\n\n addProperty: (key, value) => {\n untracked(() => {\n (node.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n untracked(() => {\n delete (node.properties as Record<string, any>)[key];\n });\n },\n\n //\n // Nodes\n //\n\n addNode: (builder, ...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const builders = [...ignoreBuilders, builder];\n const childPath = [...path, 'childrenMap', partial.id];\n const child = this._createNode(getGraph, { ...partial, parent: node }, childPath, builders);\n node.childrenMap[child.id] = child;\n // TODO(burdon): Defer triggering recursive updates until task has completed.\n this._build(getGraph(), child, childPath, builders);\n return child;\n });\n });\n },\n removeNode: (id) => {\n return untracked(() => {\n const child = node.childrenMap[id];\n delete node.childrenMap[id];\n return child;\n });\n },\n\n //\n // Actions\n //\n\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const action = this._createAction(partial);\n let shortcut: string | undefined;\n if (typeof action.keyBinding === 'object') {\n const availablePlatforms = Object.keys(action.keyBinding);\n const platform = getHostPlatform();\n shortcut = availablePlatforms.includes(platform)\n ? action.keyBinding[platform]\n : platform === 'ios'\n ? action.keyBinding.macos // Fallback to macos if ios-specific bindings not provided.\n : platform === 'linux' || platform === 'unknown'\n ? action.keyBinding.windows // Fallback to windows if platform-specific bindings not provided.\n : undefined;\n } else {\n shortcut = action.keyBinding;\n }\n if (shortcut) {\n Keyboard.singleton.getContext(path.join('/')).bind({\n shortcut,\n handler: () => {\n action.invoke({ caller: KEY_BINDING });\n },\n data: action.label,\n });\n }\n\n node.actionsMap[action.id] = action;\n return action;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const action = node.actionsMap[id];\n if (action.keyBinding) {\n // keyboardjs.unbind(action.keyBinding);\n }\n\n delete node.actionsMap[id];\n return action;\n });\n },\n }) as RevertDeepSignal<Node<TData, TProperties>>;\n\n // Only actions added at this stage are available to subsequent builders.\n // `addNode` immediately passes the new node to other builders.\n // As such, actions added later with `addAction` are not available to those builders.\n // Having actions available to subsequent builders is useful for building groups.\n partial.actions && partial.actions.forEach((action) => node.addAction(action));\n\n return node;\n }\n\n private _createAction<TProperties extends Record<string, any> = Record<string, any>>(\n partial: ActionArg<TProperties>,\n ): Action<TProperties> {\n const action: Action<TProperties> = deepSignal({\n properties: {} as TProperties,\n ...partial,\n actionsMap: {},\n get actions() {\n return Object.values(action.actionsMap);\n },\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const subAction = this._createAction(partial);\n action.actionsMap[subAction.id] = subAction;\n return subAction;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const subAction = action.actionsMap[id];\n delete action.actionsMap[id];\n return subAction;\n });\n },\n addProperty: (key, value) => {\n return untracked(() => {\n (action.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n return untracked(() => {\n delete (action.properties as Record<string, any>)[key];\n });\n },\n }) as RevertDeepSignal<Action<TProperties>>;\n\n partial.actions && partial.actions.forEach((subAction) => action.addAction(subAction));\n\n return action;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport type { IconProps } from '@phosphor-icons/react';\nimport { type FC } from 'react';\n\nimport type { UnsubscribeCallback } from '@dxos/async';\n\nimport { type ActionArg, type Action, type Label } from './action';\n\n/**\n * Called when a node is added to the graph, allowing other node builders to add children, actions or properties.\n */\nexport type NodeBuilder = (parent: Node) => UnsubscribeCallback | void;\n\n/**\n * Represents a node in the graph.\n */\nexport type Node<TData = any, TProperties extends Record<string, any> = Record<string, any>> = {\n /**\n * Globally unique ID.\n */\n id: string;\n\n /**\n * Parent node in the graph.\n */\n parent: Node | null;\n\n /**\n * Label to be used when displaying the node.\n * For default labels, use a translated string.\n *\n * @example 'My Node'\n * @example ['unknown node label, { ns: 'example-plugin' }]\n */\n label: Label;\n\n /**\n * Description to be used when displaying a detailed view of the node.\n * For default descriptions, use a translated string.\n */\n description?: Label;\n\n /**\n * Icon to be used when displaying the node.\n */\n icon?: FC<IconProps>;\n\n /**\n * Properties of the node relevant to displaying the node.\n */\n // TODO(burdon): Make this extensible and move label, description, and icon into here?\n properties: TProperties;\n\n /**\n * Data the node represents.\n */\n // TODO(burdon): Type system (e.g., minimally provide identifier string vs. TypedObject vs. Graph mixin type system)?\n // type field would prevent convoluted sniffing of object properties. And allow direct pass-through for ECHO TypedObjects.\n // TODO(burdon): In some places `null` is cast to TData so make optional?\n data: TData;\n\n /**\n * Children of the node stored by their id.\n */\n // TODO(burdon): Rename nodes/nodeMap?\n childrenMap: Record<string, Node>;\n\n /**\n * Actions of the node stored by their id.\n */\n actionsMap: Record<string, Action>;\n\n /**\n * Children of the node in default order.\n */\n get children(): Node[];\n\n /**\n * Actions of the node in default order.\n */\n get actions(): Action[];\n\n addProperty(key: string, value: any): void;\n removeProperty(key: string): void;\n\n addNode<TChildData = null, TChildProperties extends Record<string, any> = Record<string, any>>(\n id: string,\n ...node: NodeArg<TChildData, TChildProperties>[]\n ): Node<TChildData, TChildProperties>[];\n removeNode(id: string): Node;\n\n addAction<TActionProperties extends Record<string, any> = Record<string, any>>(\n ...action: ActionArg<TActionProperties>[]\n ): Action<TActionProperties>[];\n removeAction(id: string): Action;\n};\n\nexport type NodeArg<TData = null, TProperties extends Record<string, any> = Record<string, any>> = Pick<\n Node,\n 'id' | 'label'\n> &\n Partial<Omit<Node<TData, TProperties>, 'id' | 'label' | 'actions'>> & { actions?: ActionArg[] };\n\nexport const isGraphNode = (data: unknown): data is Node =>\n data && typeof data === 'object' ? 'id' in data && 'label' in data : false;\n"],
5
5
  "mappings": "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",
6
6
  "names": ["deepSignal", "get", "invariant", "Graph", "constructor", "_root", "_index", "toJSON", "toLabel", "label", "Array", "isArray", "ns", "node", "id", "slice", "children", "length", "map", "undefined", "actions", "root", "getPath", "_setPath", "path", "findNode", "traverse", "direction", "filter", "visitor", "depth", "Object", "values", "forEach", "child", "parent", "untracked", "deepSignal", "EventSubscriptions", "Keyboard", "getHostPlatform", "KEY_BINDING", "GraphBuilder", "_nodeBuilders", "Map", "_unsubscribe", "addNodeBuilder", "id", "builder", "set", "removeNodeBuilder", "delete", "build", "previousGraph", "startingPath", "graph", "Graph", "_createNode", "label", "_build", "root", "node", "path", "ignoreBuilders", "_setPath", "subscriptions", "get", "EventSubscriptions", "clear", "Array", "from", "entries", "filter", "findIndex", "ignore", "forEach", "_", "unsubscribe", "add", "getGraph", "partial", "deepSignal", "parent", "data", "properties", "childrenMap", "actionsMap", "children", "Object", "values", "actions", "addProperty", "key", "value", "untracked", "removeProperty", "addNode", "partials", "map", "builders", "childPath", "child", "removeNode", "addAction", "action", "_createAction", "shortcut", "keyBinding", "availablePlatforms", "keys", "platform", "getHostPlatform", "includes", "macos", "windows", "undefined", "Keyboard", "singleton", "getContext", "join", "bind", "handler", "invoke", "caller", "removeAction", "subAction", "isGraphNode", "data"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/sdk/app-graph/src/action.ts":{"bytes":3491,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/graph.ts":{"bytes":9735,"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/app-graph/src/graph-builder.ts":{"bytes":26515,"imports":[{"path":"@preact/signals-react","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"}],"format":"esm"},"packages/sdk/app-graph/src/node.ts":{"bytes":4772,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/index.ts":{"bytes":722,"imports":[{"path":"packages/sdk/app-graph/src/action.ts","kind":"import-statement","original":"./action"},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"},{"path":"packages/sdk/app-graph/src/graph-builder.ts","kind":"import-statement","original":"./graph-builder"},{"path":"packages/sdk/app-graph/src/node.ts","kind":"import-statement","original":"./node"}],"format":"esm"},"packages/sdk/app-graph/src/testing.ts":{"bytes":11884,"imports":[],"format":"esm"}},"outputs":{"packages/sdk/app-graph/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":21249},"packages/sdk/app-graph/dist/lib/browser/index.mjs":{"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@preact/signals-react","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Graph","GraphBuilder","KEY_BINDING","isGraphNode"],"entryPoint":"packages/sdk/app-graph/src/index.ts","inputs":{"packages/sdk/app-graph/src/index.ts":{"bytesInOutput":0},"packages/sdk/app-graph/src/graph.ts":{"bytesInOutput":2143},"packages/sdk/app-graph/src/graph-builder.ts":{"bytesInOutput":6127},"packages/sdk/app-graph/src/node.ts":{"bytesInOutput":104}},"bytes":8601},"packages/sdk/app-graph/dist/lib/browser/testing.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6167},"packages/sdk/app-graph/dist/lib/browser/testing.mjs":{"imports":[],"exports":["buildGraph","createTestNodeBuilder"],"entryPoint":"packages/sdk/app-graph/src/testing.ts","inputs":{"packages/sdk/app-graph/src/testing.ts":{"bytesInOutput":2180}},"bytes":2308}}}
1
+ {"inputs":{"packages/sdk/app-graph/src/action.ts":{"bytes":3491,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/graph.ts":{"bytes":9735,"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/app-graph/src/graph-builder.ts":{"bytes":26514,"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"}],"format":"esm"},"packages/sdk/app-graph/src/node.ts":{"bytes":4772,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/index.ts":{"bytes":722,"imports":[{"path":"packages/sdk/app-graph/src/action.ts","kind":"import-statement","original":"./action"},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"},{"path":"packages/sdk/app-graph/src/graph-builder.ts","kind":"import-statement","original":"./graph-builder"},{"path":"packages/sdk/app-graph/src/node.ts","kind":"import-statement","original":"./node"}],"format":"esm"},"packages/sdk/app-graph/src/testing.ts":{"bytes":11884,"imports":[],"format":"esm"}},"outputs":{"packages/sdk/app-graph/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":21248},"packages/sdk/app-graph/dist/lib/browser/index.mjs":{"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Graph","GraphBuilder","KEY_BINDING","isGraphNode"],"entryPoint":"packages/sdk/app-graph/src/index.ts","inputs":{"packages/sdk/app-graph/src/index.ts":{"bytesInOutput":0},"packages/sdk/app-graph/src/graph.ts":{"bytesInOutput":2143},"packages/sdk/app-graph/src/graph-builder.ts":{"bytesInOutput":6126},"packages/sdk/app-graph/src/node.ts":{"bytesInOutput":104}},"bytes":8600},"packages/sdk/app-graph/dist/lib/browser/testing.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6167},"packages/sdk/app-graph/dist/lib/browser/testing.mjs":{"imports":[],"exports":["buildGraph","createTestNodeBuilder"],"entryPoint":"packages/sdk/app-graph/src/testing.ts","inputs":{"packages/sdk/app-graph/src/testing.ts":{"bytesInOutput":2180}},"bytes":2308}}}
@@ -37,7 +37,7 @@ module.exports = __toCommonJS(node_exports);
37
37
  var import_react = require("deepsignal/react");
38
38
  var import_lodash = __toESM(require("lodash.get"));
39
39
  var import_invariant = require("@dxos/invariant");
40
- var import_signals_react = require("@preact/signals-react");
40
+ var import_signals_core = require("@preact/signals-core");
41
41
  var import_react2 = require("deepsignal/react");
42
42
  var import_async = require("@dxos/async");
43
43
  var import_keyboard = require("@dxos/keyboard");
@@ -189,12 +189,12 @@ var GraphBuilder = class {
189
189
  // Properties
190
190
  //
191
191
  addProperty: (key, value) => {
192
- (0, import_signals_react.untracked)(() => {
192
+ (0, import_signals_core.untracked)(() => {
193
193
  node.properties[key] = value;
194
194
  });
195
195
  },
196
196
  removeProperty: (key) => {
197
- (0, import_signals_react.untracked)(() => {
197
+ (0, import_signals_core.untracked)(() => {
198
198
  delete node.properties[key];
199
199
  });
200
200
  },
@@ -202,7 +202,7 @@ var GraphBuilder = class {
202
202
  // Nodes
203
203
  //
204
204
  addNode: (builder, ...partials) => {
205
- return (0, import_signals_react.untracked)(() => {
205
+ return (0, import_signals_core.untracked)(() => {
206
206
  return partials.map((partial2) => {
207
207
  const builders = [
208
208
  ...ignoreBuilders,
@@ -224,7 +224,7 @@ var GraphBuilder = class {
224
224
  });
225
225
  },
226
226
  removeNode: (id) => {
227
- return (0, import_signals_react.untracked)(() => {
227
+ return (0, import_signals_core.untracked)(() => {
228
228
  const child = node.childrenMap[id];
229
229
  delete node.childrenMap[id];
230
230
  return child;
@@ -234,7 +234,7 @@ var GraphBuilder = class {
234
234
  // Actions
235
235
  //
236
236
  addAction: (...partials) => {
237
- return (0, import_signals_react.untracked)(() => {
237
+ return (0, import_signals_core.untracked)(() => {
238
238
  return partials.map((partial2) => {
239
239
  const action = this._createAction(partial2);
240
240
  let shortcut;
@@ -262,7 +262,7 @@ var GraphBuilder = class {
262
262
  });
263
263
  },
264
264
  removeAction: (id) => {
265
- return (0, import_signals_react.untracked)(() => {
265
+ return (0, import_signals_core.untracked)(() => {
266
266
  const action = node.actionsMap[id];
267
267
  if (action.keyBinding) {
268
268
  }
@@ -283,7 +283,7 @@ var GraphBuilder = class {
283
283
  return Object.values(action.actionsMap);
284
284
  },
285
285
  addAction: (...partials) => {
286
- return (0, import_signals_react.untracked)(() => {
286
+ return (0, import_signals_core.untracked)(() => {
287
287
  return partials.map((partial2) => {
288
288
  const subAction = this._createAction(partial2);
289
289
  action.actionsMap[subAction.id] = subAction;
@@ -292,19 +292,19 @@ var GraphBuilder = class {
292
292
  });
293
293
  },
294
294
  removeAction: (id) => {
295
- return (0, import_signals_react.untracked)(() => {
295
+ return (0, import_signals_core.untracked)(() => {
296
296
  const subAction = action.actionsMap[id];
297
297
  delete action.actionsMap[id];
298
298
  return subAction;
299
299
  });
300
300
  },
301
301
  addProperty: (key, value) => {
302
- return (0, import_signals_react.untracked)(() => {
302
+ return (0, import_signals_core.untracked)(() => {
303
303
  action.properties[key] = value;
304
304
  });
305
305
  },
306
306
  removeProperty: (key) => {
307
- return (0, import_signals_react.untracked)(() => {
307
+ return (0, import_signals_core.untracked)(() => {
308
308
  delete action.properties[key];
309
309
  });
310
310
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/graph.ts", "../../../src/graph-builder.ts", "../../../src/node.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal } from 'deepsignal/react';\n// TODO(wittjosiah): Remove lodash dependency.\nimport get from 'lodash.get';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { type Label } from './action';\nimport { type Node } from './node';\n\nexport type TraversalOptions = {\n /**\n * The node to start traversing from. Defaults to the root node.\n */\n node?: Node;\n\n /**\n * The direction to traverse the graph. Defaults to 'down'.\n */\n direction?: 'up' | 'down';\n\n /**\n * A predicate to filter nodes which are passed to the `visitor` callback.\n */\n filter?: (node: Node) => boolean;\n\n /**\n * A callback which is called for each node visited during traversal.\n */\n visitor?: (node: Node, path: string[]) => void;\n};\n\n/**\n * The Graph represents the structure of the application constructed via plugins.\n */\nexport class Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n private readonly _index = deepSignal<Record<string, string[]>>({});\n\n constructor(private readonly _root: Node) {}\n\n toJSON() {\n const toLabel = (label: Label) => (Array.isArray(label) ? `${label[1].ns}[${label[0]}]` : label);\n const toJSON = (node: Node): any => {\n return {\n id: node.id.slice(0, 16),\n label: toLabel(node.label),\n children: node.children.length ? node.children.map((node) => toJSON(node)) : undefined,\n actions: node.actions.length\n ? node.actions.map(({ id, label }) => ({\n id,\n label: toLabel(label),\n }))\n : undefined,\n };\n };\n\n return toJSON(this._root);\n }\n\n /**\n * The root node of the graph which is the entry point for all knowledge.\n */\n get root(): Node {\n return this._root;\n }\n\n /**\n * Get the path through the graph from the root to the node with the given id.\n */\n getPath(id: string): string[] | undefined {\n return this._index[id];\n }\n\n /**\n * @internal\n */\n _setPath(id: string, path: string[]) {\n invariant(id && path, 'Invalid path.');\n this._index[id] = path;\n }\n\n /**\n * Find the node with the given id in the graph.\n */\n findNode(id: string): Node | undefined {\n const path = this.getPath(id);\n if (!path) {\n return undefined;\n }\n\n return path.length > 0 ? get(this._root, path) : this._root;\n }\n\n /**\n * Recursive breadth-first traversal.\n */\n traverse({ node = this._root, direction = 'down', filter, visitor }: TraversalOptions, depth = 0): void {\n if (!filter || filter(node)) {\n visitor?.(node, this.getPath(node.id)!);\n }\n\n if (direction === 'down') {\n Object.values(node.children).forEach((child) => this.traverse({ node: child, filter, visitor }));\n } else if (direction === 'up' && node.parent) {\n this.traverse({ node: node.parent, direction, filter, visitor }, depth + 1);\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-react';\nimport { type RevertDeepSignal, deepSignal } from 'deepsignal/react';\n\nimport { EventSubscriptions } from '@dxos/async';\nimport { Keyboard } from '@dxos/keyboard';\nimport { getHostPlatform } from '@dxos/util';\n\nimport type { ActionArg, Action } from './action';\nimport { Graph } from './graph';\nimport type { NodeArg, Node, NodeBuilder } from './node';\n\nexport const KEY_BINDING = 'KeyBinding';\n\n/**\n * The builder...\n */\nexport class GraphBuilder {\n private readonly _nodeBuilders = new Map<string, NodeBuilder>();\n private readonly _unsubscribe = new Map<string, EventSubscriptions>();\n\n /**\n * Register a node builder which will be called in order to construct the graph.\n */\n addNodeBuilder(id: string, builder: NodeBuilder): GraphBuilder {\n this._nodeBuilders.set(id, builder);\n return this;\n }\n\n /**\n * Remove a node builder from the graph builder.\n */\n removeNodeBuilder(id: string): GraphBuilder {\n this._nodeBuilders.delete(id);\n return this;\n }\n\n /**\n * Construct the graph, starting by calling all registered node builders on the root node.\n * Node builders will be filtered out as they are used such that they are only used once on any given path.\n * @param previousGraph If provided, the graph will be updated in place.\n * @param startingPath If provided, the graph will be updated starting at the given path.\n */\n build(previousGraph?: Graph, startingPath: string[] = []): Graph {\n const graph: Graph = previousGraph ?? new Graph(this._createNode(() => graph, { id: 'root', label: 'Root' }));\n return this._build(graph, graph.root, startingPath);\n }\n\n /**\n * Called recursively.\n */\n private _build(graph: Graph, node: Node, path: string[] = [], ignoreBuilders: string[] = []): Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n graph._setPath(node.id, path);\n\n // TODO(burdon): Document.\n const subscriptions = this._unsubscribe.get(node.id) ?? new EventSubscriptions();\n subscriptions.clear();\n\n Array.from(this._nodeBuilders.entries())\n .filter(([id]) => ignoreBuilders.findIndex((ignore) => ignore === id) === -1)\n .forEach(([_, builder]) => {\n const unsubscribe = builder(node);\n unsubscribe && subscriptions.add(unsubscribe);\n });\n\n this._unsubscribe.set(node.id, subscriptions);\n\n return graph;\n }\n\n private _createNode<TData = null, TProperties extends Record<string, any> = Record<string, any>>(\n getGraph: () => Graph,\n partial: NodeArg<TData, TProperties>,\n path: string[] = [],\n ignoreBuilders: string[] = [],\n ): Node<TData, TProperties> {\n // TODO(burdon): Document implications and rationale of deepSignal.\n const node: Node<TData, TProperties> = deepSignal({\n parent: null,\n data: null as TData, // TODO(burdon): Allow null property?\n properties: {} as TProperties,\n childrenMap: {},\n actionsMap: {},\n // TODO(burdon): Document.\n ...partial,\n\n get children() {\n return Object.values(node.childrenMap);\n },\n get actions() {\n return Object.values(node.actionsMap);\n },\n\n //\n // Properties\n //\n\n addProperty: (key, value) => {\n untracked(() => {\n (node.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n untracked(() => {\n delete (node.properties as Record<string, any>)[key];\n });\n },\n\n //\n // Nodes\n //\n\n addNode: (builder, ...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const builders = [...ignoreBuilders, builder];\n const childPath = [...path, 'childrenMap', partial.id];\n const child = this._createNode(getGraph, { ...partial, parent: node }, childPath, builders);\n node.childrenMap[child.id] = child;\n // TODO(burdon): Defer triggering recursive updates until task has completed.\n this._build(getGraph(), child, childPath, builders);\n return child;\n });\n });\n },\n removeNode: (id) => {\n return untracked(() => {\n const child = node.childrenMap[id];\n delete node.childrenMap[id];\n return child;\n });\n },\n\n //\n // Actions\n //\n\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const action = this._createAction(partial);\n let shortcut: string | undefined;\n if (typeof action.keyBinding === 'object') {\n const availablePlatforms = Object.keys(action.keyBinding);\n const platform = getHostPlatform();\n shortcut = availablePlatforms.includes(platform)\n ? action.keyBinding[platform]\n : platform === 'ios'\n ? action.keyBinding.macos // Fallback to macos if ios-specific bindings not provided.\n : platform === 'linux' || platform === 'unknown'\n ? action.keyBinding.windows // Fallback to windows if platform-specific bindings not provided.\n : undefined;\n } else {\n shortcut = action.keyBinding;\n }\n if (shortcut) {\n Keyboard.singleton.getContext(path.join('/')).bind({\n shortcut,\n handler: () => {\n action.invoke({ caller: KEY_BINDING });\n },\n data: action.label,\n });\n }\n\n node.actionsMap[action.id] = action;\n return action;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const action = node.actionsMap[id];\n if (action.keyBinding) {\n // keyboardjs.unbind(action.keyBinding);\n }\n\n delete node.actionsMap[id];\n return action;\n });\n },\n }) as RevertDeepSignal<Node<TData, TProperties>>;\n\n // Only actions added at this stage are available to subsequent builders.\n // `addNode` immediately passes the new node to other builders.\n // As such, actions added later with `addAction` are not available to those builders.\n // Having actions available to subsequent builders is useful for building groups.\n partial.actions && partial.actions.forEach((action) => node.addAction(action));\n\n return node;\n }\n\n private _createAction<TProperties extends Record<string, any> = Record<string, any>>(\n partial: ActionArg<TProperties>,\n ): Action<TProperties> {\n const action: Action<TProperties> = deepSignal({\n properties: {} as TProperties,\n ...partial,\n actionsMap: {},\n get actions() {\n return Object.values(action.actionsMap);\n },\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const subAction = this._createAction(partial);\n action.actionsMap[subAction.id] = subAction;\n return subAction;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const subAction = action.actionsMap[id];\n delete action.actionsMap[id];\n return subAction;\n });\n },\n addProperty: (key, value) => {\n return untracked(() => {\n (action.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n return untracked(() => {\n delete (action.properties as Record<string, any>)[key];\n });\n },\n }) as RevertDeepSignal<Action<TProperties>>;\n\n partial.actions && partial.actions.forEach((subAction) => action.addAction(subAction));\n\n return action;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport type { IconProps } from '@phosphor-icons/react';\nimport { type FC } from 'react';\n\nimport type { UnsubscribeCallback } from '@dxos/async';\n\nimport { type ActionArg, type Action, type Label } from './action';\n\n/**\n * Called when a node is added to the graph, allowing other node builders to add children, actions or properties.\n */\nexport type NodeBuilder = (parent: Node) => UnsubscribeCallback | void;\n\n/**\n * Represents a node in the graph.\n */\nexport type Node<TData = any, TProperties extends Record<string, any> = Record<string, any>> = {\n /**\n * Globally unique ID.\n */\n id: string;\n\n /**\n * Parent node in the graph.\n */\n parent: Node | null;\n\n /**\n * Label to be used when displaying the node.\n * For default labels, use a translated string.\n *\n * @example 'My Node'\n * @example ['unknown node label, { ns: 'example-plugin' }]\n */\n label: Label;\n\n /**\n * Description to be used when displaying a detailed view of the node.\n * For default descriptions, use a translated string.\n */\n description?: Label;\n\n /**\n * Icon to be used when displaying the node.\n */\n icon?: FC<IconProps>;\n\n /**\n * Properties of the node relevant to displaying the node.\n */\n // TODO(burdon): Make this extensible and move label, description, and icon into here?\n properties: TProperties;\n\n /**\n * Data the node represents.\n */\n // TODO(burdon): Type system (e.g., minimally provide identifier string vs. TypedObject vs. Graph mixin type system)?\n // type field would prevent convoluted sniffing of object properties. And allow direct pass-through for ECHO TypedObjects.\n // TODO(burdon): In some places `null` is cast to TData so make optional?\n data: TData;\n\n /**\n * Children of the node stored by their id.\n */\n // TODO(burdon): Rename nodes/nodeMap?\n childrenMap: Record<string, Node>;\n\n /**\n * Actions of the node stored by their id.\n */\n actionsMap: Record<string, Action>;\n\n /**\n * Children of the node in default order.\n */\n get children(): Node[];\n\n /**\n * Actions of the node in default order.\n */\n get actions(): Action[];\n\n addProperty(key: string, value: any): void;\n removeProperty(key: string): void;\n\n addNode<TChildData = null, TChildProperties extends Record<string, any> = Record<string, any>>(\n id: string,\n ...node: NodeArg<TChildData, TChildProperties>[]\n ): Node<TChildData, TChildProperties>[];\n removeNode(id: string): Node;\n\n addAction<TActionProperties extends Record<string, any> = Record<string, any>>(\n ...action: ActionArg<TActionProperties>[]\n ): Action<TActionProperties>[];\n removeAction(id: string): Action;\n};\n\nexport type NodeArg<TData = null, TProperties extends Record<string, any> = Record<string, any>> = Pick<\n Node,\n 'id' | 'label'\n> &\n Partial<Omit<Node<TData, TProperties>, 'id' | 'label' | 'actions'>> & { actions?: ActionArg[] };\n\nexport const isGraphNode = (data: unknown): data is Node =>\n data && typeof data === 'object' ? 'id' in data && 'label' in data : false;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { deepSignal } from 'deepsignal/react';\n// TODO(wittjosiah): Remove lodash dependency.\nimport get from 'lodash.get';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { type Label } from './action';\nimport { type Node } from './node';\n\nexport type TraversalOptions = {\n /**\n * The node to start traversing from. Defaults to the root node.\n */\n node?: Node;\n\n /**\n * The direction to traverse the graph. Defaults to 'down'.\n */\n direction?: 'up' | 'down';\n\n /**\n * A predicate to filter nodes which are passed to the `visitor` callback.\n */\n filter?: (node: Node) => boolean;\n\n /**\n * A callback which is called for each node visited during traversal.\n */\n visitor?: (node: Node, path: string[]) => void;\n};\n\n/**\n * The Graph represents the structure of the application constructed via plugins.\n */\nexport class Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n private readonly _index = deepSignal<Record<string, string[]>>({});\n\n constructor(private readonly _root: Node) {}\n\n toJSON() {\n const toLabel = (label: Label) => (Array.isArray(label) ? `${label[1].ns}[${label[0]}]` : label);\n const toJSON = (node: Node): any => {\n return {\n id: node.id.slice(0, 16),\n label: toLabel(node.label),\n children: node.children.length ? node.children.map((node) => toJSON(node)) : undefined,\n actions: node.actions.length\n ? node.actions.map(({ id, label }) => ({\n id,\n label: toLabel(label),\n }))\n : undefined,\n };\n };\n\n return toJSON(this._root);\n }\n\n /**\n * The root node of the graph which is the entry point for all knowledge.\n */\n get root(): Node {\n return this._root;\n }\n\n /**\n * Get the path through the graph from the root to the node with the given id.\n */\n getPath(id: string): string[] | undefined {\n return this._index[id];\n }\n\n /**\n * @internal\n */\n _setPath(id: string, path: string[]) {\n invariant(id && path, 'Invalid path.');\n this._index[id] = path;\n }\n\n /**\n * Find the node with the given id in the graph.\n */\n findNode(id: string): Node | undefined {\n const path = this.getPath(id);\n if (!path) {\n return undefined;\n }\n\n return path.length > 0 ? get(this._root, path) : this._root;\n }\n\n /**\n * Recursive breadth-first traversal.\n */\n traverse({ node = this._root, direction = 'down', filter, visitor }: TraversalOptions, depth = 0): void {\n if (!filter || filter(node)) {\n visitor?.(node, this.getPath(node.id)!);\n }\n\n if (direction === 'down') {\n Object.values(node.children).forEach((child) => this.traverse({ node: child, filter, visitor }));\n } else if (direction === 'up' && node.parent) {\n this.traverse({ node: node.parent, direction, filter, visitor }, depth + 1);\n }\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { untracked } from '@preact/signals-core';\nimport { type RevertDeepSignal, deepSignal } from 'deepsignal/react';\n\nimport { EventSubscriptions } from '@dxos/async';\nimport { Keyboard } from '@dxos/keyboard';\nimport { getHostPlatform } from '@dxos/util';\n\nimport type { ActionArg, Action } from './action';\nimport { Graph } from './graph';\nimport type { NodeArg, Node, NodeBuilder } from './node';\n\nexport const KEY_BINDING = 'KeyBinding';\n\n/**\n * The builder...\n */\nexport class GraphBuilder {\n private readonly _nodeBuilders = new Map<string, NodeBuilder>();\n private readonly _unsubscribe = new Map<string, EventSubscriptions>();\n\n /**\n * Register a node builder which will be called in order to construct the graph.\n */\n addNodeBuilder(id: string, builder: NodeBuilder): GraphBuilder {\n this._nodeBuilders.set(id, builder);\n return this;\n }\n\n /**\n * Remove a node builder from the graph builder.\n */\n removeNodeBuilder(id: string): GraphBuilder {\n this._nodeBuilders.delete(id);\n return this;\n }\n\n /**\n * Construct the graph, starting by calling all registered node builders on the root node.\n * Node builders will be filtered out as they are used such that they are only used once on any given path.\n * @param previousGraph If provided, the graph will be updated in place.\n * @param startingPath If provided, the graph will be updated starting at the given path.\n */\n build(previousGraph?: Graph, startingPath: string[] = []): Graph {\n const graph: Graph = previousGraph ?? new Graph(this._createNode(() => graph, { id: 'root', label: 'Root' }));\n return this._build(graph, graph.root, startingPath);\n }\n\n /**\n * Called recursively.\n */\n private _build(graph: Graph, node: Node, path: string[] = [], ignoreBuilders: string[] = []): Graph {\n // TODO(wittjosiah): Should this support multiple paths to the same node?\n graph._setPath(node.id, path);\n\n // TODO(burdon): Document.\n const subscriptions = this._unsubscribe.get(node.id) ?? new EventSubscriptions();\n subscriptions.clear();\n\n Array.from(this._nodeBuilders.entries())\n .filter(([id]) => ignoreBuilders.findIndex((ignore) => ignore === id) === -1)\n .forEach(([_, builder]) => {\n const unsubscribe = builder(node);\n unsubscribe && subscriptions.add(unsubscribe);\n });\n\n this._unsubscribe.set(node.id, subscriptions);\n\n return graph;\n }\n\n private _createNode<TData = null, TProperties extends Record<string, any> = Record<string, any>>(\n getGraph: () => Graph,\n partial: NodeArg<TData, TProperties>,\n path: string[] = [],\n ignoreBuilders: string[] = [],\n ): Node<TData, TProperties> {\n // TODO(burdon): Document implications and rationale of deepSignal.\n const node: Node<TData, TProperties> = deepSignal({\n parent: null,\n data: null as TData, // TODO(burdon): Allow null property?\n properties: {} as TProperties,\n childrenMap: {},\n actionsMap: {},\n // TODO(burdon): Document.\n ...partial,\n\n get children() {\n return Object.values(node.childrenMap);\n },\n get actions() {\n return Object.values(node.actionsMap);\n },\n\n //\n // Properties\n //\n\n addProperty: (key, value) => {\n untracked(() => {\n (node.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n untracked(() => {\n delete (node.properties as Record<string, any>)[key];\n });\n },\n\n //\n // Nodes\n //\n\n addNode: (builder, ...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const builders = [...ignoreBuilders, builder];\n const childPath = [...path, 'childrenMap', partial.id];\n const child = this._createNode(getGraph, { ...partial, parent: node }, childPath, builders);\n node.childrenMap[child.id] = child;\n // TODO(burdon): Defer triggering recursive updates until task has completed.\n this._build(getGraph(), child, childPath, builders);\n return child;\n });\n });\n },\n removeNode: (id) => {\n return untracked(() => {\n const child = node.childrenMap[id];\n delete node.childrenMap[id];\n return child;\n });\n },\n\n //\n // Actions\n //\n\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const action = this._createAction(partial);\n let shortcut: string | undefined;\n if (typeof action.keyBinding === 'object') {\n const availablePlatforms = Object.keys(action.keyBinding);\n const platform = getHostPlatform();\n shortcut = availablePlatforms.includes(platform)\n ? action.keyBinding[platform]\n : platform === 'ios'\n ? action.keyBinding.macos // Fallback to macos if ios-specific bindings not provided.\n : platform === 'linux' || platform === 'unknown'\n ? action.keyBinding.windows // Fallback to windows if platform-specific bindings not provided.\n : undefined;\n } else {\n shortcut = action.keyBinding;\n }\n if (shortcut) {\n Keyboard.singleton.getContext(path.join('/')).bind({\n shortcut,\n handler: () => {\n action.invoke({ caller: KEY_BINDING });\n },\n data: action.label,\n });\n }\n\n node.actionsMap[action.id] = action;\n return action;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const action = node.actionsMap[id];\n if (action.keyBinding) {\n // keyboardjs.unbind(action.keyBinding);\n }\n\n delete node.actionsMap[id];\n return action;\n });\n },\n }) as RevertDeepSignal<Node<TData, TProperties>>;\n\n // Only actions added at this stage are available to subsequent builders.\n // `addNode` immediately passes the new node to other builders.\n // As such, actions added later with `addAction` are not available to those builders.\n // Having actions available to subsequent builders is useful for building groups.\n partial.actions && partial.actions.forEach((action) => node.addAction(action));\n\n return node;\n }\n\n private _createAction<TProperties extends Record<string, any> = Record<string, any>>(\n partial: ActionArg<TProperties>,\n ): Action<TProperties> {\n const action: Action<TProperties> = deepSignal({\n properties: {} as TProperties,\n ...partial,\n actionsMap: {},\n get actions() {\n return Object.values(action.actionsMap);\n },\n addAction: (...partials) => {\n return untracked(() => {\n return partials.map((partial) => {\n const subAction = this._createAction(partial);\n action.actionsMap[subAction.id] = subAction;\n return subAction;\n });\n });\n },\n removeAction: (id) => {\n return untracked(() => {\n const subAction = action.actionsMap[id];\n delete action.actionsMap[id];\n return subAction;\n });\n },\n addProperty: (key, value) => {\n return untracked(() => {\n (action.properties as Record<string, any>)[key] = value;\n });\n },\n removeProperty: (key) => {\n return untracked(() => {\n delete (action.properties as Record<string, any>)[key];\n });\n },\n }) as RevertDeepSignal<Action<TProperties>>;\n\n partial.actions && partial.actions.forEach((subAction) => action.addAction(subAction));\n\n return action;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport type { IconProps } from '@phosphor-icons/react';\nimport { type FC } from 'react';\n\nimport type { UnsubscribeCallback } from '@dxos/async';\n\nimport { type ActionArg, type Action, type Label } from './action';\n\n/**\n * Called when a node is added to the graph, allowing other node builders to add children, actions or properties.\n */\nexport type NodeBuilder = (parent: Node) => UnsubscribeCallback | void;\n\n/**\n * Represents a node in the graph.\n */\nexport type Node<TData = any, TProperties extends Record<string, any> = Record<string, any>> = {\n /**\n * Globally unique ID.\n */\n id: string;\n\n /**\n * Parent node in the graph.\n */\n parent: Node | null;\n\n /**\n * Label to be used when displaying the node.\n * For default labels, use a translated string.\n *\n * @example 'My Node'\n * @example ['unknown node label, { ns: 'example-plugin' }]\n */\n label: Label;\n\n /**\n * Description to be used when displaying a detailed view of the node.\n * For default descriptions, use a translated string.\n */\n description?: Label;\n\n /**\n * Icon to be used when displaying the node.\n */\n icon?: FC<IconProps>;\n\n /**\n * Properties of the node relevant to displaying the node.\n */\n // TODO(burdon): Make this extensible and move label, description, and icon into here?\n properties: TProperties;\n\n /**\n * Data the node represents.\n */\n // TODO(burdon): Type system (e.g., minimally provide identifier string vs. TypedObject vs. Graph mixin type system)?\n // type field would prevent convoluted sniffing of object properties. And allow direct pass-through for ECHO TypedObjects.\n // TODO(burdon): In some places `null` is cast to TData so make optional?\n data: TData;\n\n /**\n * Children of the node stored by their id.\n */\n // TODO(burdon): Rename nodes/nodeMap?\n childrenMap: Record<string, Node>;\n\n /**\n * Actions of the node stored by their id.\n */\n actionsMap: Record<string, Action>;\n\n /**\n * Children of the node in default order.\n */\n get children(): Node[];\n\n /**\n * Actions of the node in default order.\n */\n get actions(): Action[];\n\n addProperty(key: string, value: any): void;\n removeProperty(key: string): void;\n\n addNode<TChildData = null, TChildProperties extends Record<string, any> = Record<string, any>>(\n id: string,\n ...node: NodeArg<TChildData, TChildProperties>[]\n ): Node<TChildData, TChildProperties>[];\n removeNode(id: string): Node;\n\n addAction<TActionProperties extends Record<string, any> = Record<string, any>>(\n ...action: ActionArg<TActionProperties>[]\n ): Action<TActionProperties>[];\n removeAction(id: string): Action;\n};\n\nexport type NodeArg<TData = null, TProperties extends Record<string, any> = Record<string, any>> = Pick<\n Node,\n 'id' | 'label'\n> &\n Partial<Omit<Node<TData, TProperties>, 'id' | 'label' | 'actions'>> & { actions?: ActionArg[] };\n\nexport const isGraphNode = (data: unknown): data is Node =>\n data && typeof data === 'object' ? 'id' in data && 'label' in data : false;\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_react", "Graph", "constructor", "_root", "_index", "deepSignal", "toJSON", "toLabel", "label", "Array", "isArray", "ns", "node", "id", "slice", "children", "length", "map", "undefined", "actions", "root", "getPath", "_setPath", "path", "invariant", "findNode", "get", "traverse", "direction", "filter", "visitor", "depth", "Object", "values", "forEach", "child", "parent", "KEY_BINDING", "GraphBuilder", "_nodeBuilders", "Map", "_unsubscribe", "addNodeBuilder", "builder", "set", "removeNodeBuilder", "delete", "build", "previousGraph", "startingPath", "graph", "_createNode", "_build", "ignoreBuilders", "subscriptions", "EventSubscriptions", "clear", "from", "entries", "findIndex", "ignore", "_", "unsubscribe", "add", "getGraph", "partial", "data", "properties", "childrenMap", "actionsMap", "addProperty", "key", "value", "untracked", "removeProperty", "addNode", "partials", "builders", "childPath", "removeNode", "addAction", "action", "_createAction", "shortcut", "keyBinding", "availablePlatforms", "keys", "platform", "getHostPlatform", "includes", "macos", "windows", "Keyboard", "singleton", "getContext", "join", "bind", "handler", "invoke", "caller", "removeAction", "subAction", "isGraphNode"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/sdk/app-graph/src/action.ts":{"bytes":3491,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/graph.ts":{"bytes":9735,"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/app-graph/src/graph-builder.ts":{"bytes":26515,"imports":[{"path":"@preact/signals-react","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"}],"format":"esm"},"packages/sdk/app-graph/src/node.ts":{"bytes":4772,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/index.ts":{"bytes":722,"imports":[{"path":"packages/sdk/app-graph/src/action.ts","kind":"import-statement","original":"./action"},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"},{"path":"packages/sdk/app-graph/src/graph-builder.ts","kind":"import-statement","original":"./graph-builder"},{"path":"packages/sdk/app-graph/src/node.ts","kind":"import-statement","original":"./node"}],"format":"esm"},"packages/sdk/app-graph/src/testing.ts":{"bytes":11884,"imports":[],"format":"esm"}},"outputs":{"packages/sdk/app-graph/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":21249},"packages/sdk/app-graph/dist/lib/node/index.cjs":{"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@preact/signals-react","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Graph","GraphBuilder","KEY_BINDING","isGraphNode"],"entryPoint":"packages/sdk/app-graph/src/index.ts","inputs":{"packages/sdk/app-graph/src/index.ts":{"bytesInOutput":0},"packages/sdk/app-graph/src/graph.ts":{"bytesInOutput":2143},"packages/sdk/app-graph/src/graph-builder.ts":{"bytesInOutput":6127},"packages/sdk/app-graph/src/node.ts":{"bytesInOutput":104}},"bytes":8601},"packages/sdk/app-graph/dist/lib/node/testing.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6167},"packages/sdk/app-graph/dist/lib/node/testing.cjs":{"imports":[],"exports":["buildGraph","createTestNodeBuilder"],"entryPoint":"packages/sdk/app-graph/src/testing.ts","inputs":{"packages/sdk/app-graph/src/testing.ts":{"bytesInOutput":2180}},"bytes":2308}}}
1
+ {"inputs":{"packages/sdk/app-graph/src/action.ts":{"bytes":3491,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/graph.ts":{"bytes":9735,"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true}],"format":"esm"},"packages/sdk/app-graph/src/graph-builder.ts":{"bytes":26514,"imports":[{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"}],"format":"esm"},"packages/sdk/app-graph/src/node.ts":{"bytes":4772,"imports":[],"format":"esm"},"packages/sdk/app-graph/src/index.ts":{"bytes":722,"imports":[{"path":"packages/sdk/app-graph/src/action.ts","kind":"import-statement","original":"./action"},{"path":"packages/sdk/app-graph/src/graph.ts","kind":"import-statement","original":"./graph"},{"path":"packages/sdk/app-graph/src/graph-builder.ts","kind":"import-statement","original":"./graph-builder"},{"path":"packages/sdk/app-graph/src/node.ts","kind":"import-statement","original":"./node"}],"format":"esm"},"packages/sdk/app-graph/src/testing.ts":{"bytes":11884,"imports":[],"format":"esm"}},"outputs":{"packages/sdk/app-graph/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":21248},"packages/sdk/app-graph/dist/lib/node/index.cjs":{"imports":[{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"lodash.get","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@preact/signals-core","kind":"import-statement","external":true},{"path":"deepsignal/react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/keyboard","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Graph","GraphBuilder","KEY_BINDING","isGraphNode"],"entryPoint":"packages/sdk/app-graph/src/index.ts","inputs":{"packages/sdk/app-graph/src/index.ts":{"bytesInOutput":0},"packages/sdk/app-graph/src/graph.ts":{"bytesInOutput":2143},"packages/sdk/app-graph/src/graph-builder.ts":{"bytesInOutput":6126},"packages/sdk/app-graph/src/node.ts":{"bytesInOutput":104}},"bytes":8600},"packages/sdk/app-graph/dist/lib/node/testing.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":6167},"packages/sdk/app-graph/dist/lib/node/testing.cjs":{"imports":[],"exports":["buildGraph","createTestNodeBuilder"],"entryPoint":"packages/sdk/app-graph/src/testing.ts","inputs":{"packages/sdk/app-graph/src/testing.ts":{"bytesInOutput":2180}},"bytes":2308}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/app-graph",
3
- "version": "0.4.4-main.fcf0b00",
3
+ "version": "0.4.4-next.e0df51e",
4
4
  "description": "Constructs knowledge graphs for the purpose of building applications on top of",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -33,15 +33,15 @@
33
33
  "src"
34
34
  ],
35
35
  "dependencies": {
36
- "@preact/signals-react": "^1.3.6",
37
- "deepsignal": "1.4.0-shallow.0",
36
+ "@preact/signals-core": "^1.5.1",
37
+ "deepsignal": "^1.5.0",
38
38
  "lodash.get": "^4.4.2",
39
39
  "lodash.set": "^4.3.2",
40
- "@dxos/debug": "0.4.4-main.fcf0b00",
41
- "@dxos/keyboard": "0.4.4-main.fcf0b00",
42
- "@dxos/util": "0.4.4-main.fcf0b00",
43
- "@dxos/invariant": "0.4.4-main.fcf0b00",
44
- "@dxos/async": "0.4.4-main.fcf0b00"
40
+ "@dxos/async": "0.4.4-next.e0df51e",
41
+ "@dxos/debug": "0.4.4-next.e0df51e",
42
+ "@dxos/invariant": "0.4.4-next.e0df51e",
43
+ "@dxos/util": "0.4.4-next.e0df51e",
44
+ "@dxos/keyboard": "0.4.4-next.e0df51e"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@phosphor-icons/react": "^2.0.5",
@@ -52,11 +52,11 @@
52
52
  "react": "^18.2.0",
53
53
  "react-dom": "^18.2.0",
54
54
  "vite": "^5.0.12",
55
- "@dxos/random": "0.4.4-main.fcf0b00",
56
- "@dxos/react-client": "0.4.4-main.fcf0b00",
57
- "@dxos/react-ui": "0.4.4-main.fcf0b00",
58
- "@dxos/react-ui-theme": "0.4.4-main.fcf0b00",
59
- "@dxos/storybook-utils": "0.4.4-main.fcf0b00"
55
+ "@dxos/react-client": "0.4.4-next.e0df51e",
56
+ "@dxos/random": "0.4.4-next.e0df51e",
57
+ "@dxos/react-ui": "0.4.4-next.e0df51e",
58
+ "@dxos/react-ui-theme": "0.4.4-next.e0df51e",
59
+ "@dxos/storybook-utils": "0.4.4-next.e0df51e"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@phosphor-icons/react": "^2.0.5",
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { untracked } from '@preact/signals-react';
5
+ import { untracked } from '@preact/signals-core';
6
6
  import { type RevertDeepSignal, deepSignal } from 'deepsignal/react';
7
7
 
8
8
  import { EventSubscriptions } from '@dxos/async';
@@ -5,7 +5,7 @@
5
5
  import '@dxosTheme';
6
6
 
7
7
  import { Pause, Play, Plus, Timer } from '@phosphor-icons/react';
8
- import { effect } from '@preact/signals-react';
8
+ import { effect } from '@preact/signals-core';
9
9
  import React, { useEffect, useState } from 'react';
10
10
 
11
11
  import { EventSubscriptions } from '@dxos/async';
@@ -231,5 +231,5 @@ const EchoGraphStory = () => {
231
231
  };
232
232
 
233
233
  export const Default = {
234
- render: () => <ClientRepeater Component={EchoGraphStory} clients={[client]} className='flex flex-col' />,
234
+ render: () => <ClientRepeater component={EchoGraphStory} clients={[client]} className='flex flex-col' />,
235
235
  };