@voidhash/mimic 0.0.1 → 0.0.2

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.
package/dist/index.mjs CHANGED
@@ -2522,5 +2522,447 @@ function toUpdateSchema(primitive) {
2522
2522
  }
2523
2523
 
2524
2524
  //#endregion
2525
- export { Document_exports as Document, EffectSchema_exports as EffectSchema, Operation_exports as Operation, OperationPath_exports as OperationPath, Presence_exports as Presence, Primitive_exports as Primitive, ProxyEnvironment_exports as ProxyEnvironment, Transaction_exports as Transaction, Transform_exports as Transform };
2525
+ //#region src/types/index.ts
2526
+ var types_exports = /* @__PURE__ */ __export({
2527
+ TreeNodePrimitive: () => TreeNodePrimitive,
2528
+ TreeNodeSelf: () => TreeNodeSelf
2529
+ });
2530
+
2531
+ //#endregion
2532
+ //#region src/utils/tree-helpers.ts
2533
+ var tree_helpers_exports = /* @__PURE__ */ __export({
2534
+ buildNodeTypeMap: () => buildNodeTypeMap,
2535
+ canAddChildType: () => canAddChildType,
2536
+ findNode: () => findNode,
2537
+ findNodeById: () => findNodeById,
2538
+ findNodeWithPath: () => findNodeWithPath,
2539
+ findNodes: () => findNodes,
2540
+ flattenTree: () => flattenTree,
2541
+ getAllNodeTypes: () => getAllNodeTypes,
2542
+ getAllowedChildTypes: () => getAllowedChildTypes,
2543
+ getAllowedChildTypesForNode: () => getAllowedChildTypesForNode,
2544
+ getAncestors: () => getAncestors,
2545
+ getDescendants: () => getDescendants,
2546
+ getNodeDepth: () => getNodeDepth,
2547
+ getNodePrimitive: () => getNodePrimitive,
2548
+ getNodeTypeByName: () => getNodeTypeByName,
2549
+ getParent: () => getParent,
2550
+ getSiblings: () => getSiblings,
2551
+ getSubtree: () => getSubtree,
2552
+ isAncestorOf: () => isAncestorOf,
2553
+ isChildTypeAllowed: () => isChildTypeAllowed,
2554
+ mapTree: () => mapTree,
2555
+ traverse: () => traverse
2556
+ });
2557
+ /**
2558
+ * Find a node by ID in a tree snapshot.
2559
+ *
2560
+ * @param snapshot - The root tree snapshot
2561
+ * @param id - The node ID to find
2562
+ * @returns The node snapshot if found, undefined otherwise
2563
+ */
2564
+ function findNodeById(snapshot, id) {
2565
+ if (!snapshot) return void 0;
2566
+ if (snapshot.id === id) return snapshot;
2567
+ for (const child of snapshot.children) {
2568
+ const found = findNodeById(child, id);
2569
+ if (found) return found;
2570
+ }
2571
+ }
2572
+ /**
2573
+ * Find a node by ID with full path information.
2574
+ *
2575
+ * @param snapshot - The root tree snapshot
2576
+ * @param id - The node ID to find
2577
+ * @returns NodeSearchResult with node, path, and depth, or undefined if not found
2578
+ */
2579
+ function findNodeWithPath(snapshot, id) {
2580
+ if (!snapshot) return void 0;
2581
+ const search = (node, currentPath, depth) => {
2582
+ const path = [...currentPath, node.id];
2583
+ if (node.id === id) return {
2584
+ node,
2585
+ path,
2586
+ depth
2587
+ };
2588
+ for (const child of node.children) {
2589
+ const result = search(child, path, depth + 1);
2590
+ if (result) return result;
2591
+ }
2592
+ };
2593
+ return search(snapshot, [], 0);
2594
+ }
2595
+ /**
2596
+ * Get the parent node of a given node ID.
2597
+ *
2598
+ * @param snapshot - The root tree snapshot
2599
+ * @param nodeId - The ID of the node whose parent we want
2600
+ * @returns ParentSearchResult with parent node and child index, or undefined
2601
+ */
2602
+ function getParent(snapshot, nodeId) {
2603
+ if (!snapshot) return void 0;
2604
+ for (let i = 0; i < snapshot.children.length; i++) {
2605
+ const child = snapshot.children[i];
2606
+ if (child && child.id === nodeId) return {
2607
+ parent: snapshot,
2608
+ childIndex: i
2609
+ };
2610
+ }
2611
+ for (const child of snapshot.children) {
2612
+ const result = getParent(child, nodeId);
2613
+ if (result) return result;
2614
+ }
2615
+ }
2616
+ /**
2617
+ * Get a subtree rooted at a specific node ID.
2618
+ *
2619
+ * @param snapshot - The root tree snapshot
2620
+ * @param nodeId - The ID of the node to use as new root
2621
+ * @returns The subtree snapshot, or undefined if node not found
2622
+ */
2623
+ function getSubtree(snapshot, nodeId) {
2624
+ return findNodeById(snapshot, nodeId);
2625
+ }
2626
+ /**
2627
+ * Get all ancestor nodes from a node up to the root.
2628
+ *
2629
+ * @param snapshot - The root tree snapshot
2630
+ * @param nodeId - The ID of the node
2631
+ * @returns Array of ancestor snapshots from immediate parent to root, or empty array
2632
+ */
2633
+ function getAncestors(snapshot, nodeId) {
2634
+ if (!snapshot) return [];
2635
+ const result = findNodeWithPath(snapshot, nodeId);
2636
+ if (!result || result.path.length <= 1) return [];
2637
+ const ancestorIds = result.path.slice(0, -1);
2638
+ const ancestors = [];
2639
+ for (let i = ancestorIds.length - 1; i >= 0; i--) {
2640
+ const id = ancestorIds[i];
2641
+ if (id) {
2642
+ const ancestor = findNodeById(snapshot, id);
2643
+ if (ancestor) ancestors.push(ancestor);
2644
+ }
2645
+ }
2646
+ return ancestors;
2647
+ }
2648
+ /**
2649
+ * Get all descendant nodes of a given node (flat array).
2650
+ *
2651
+ * @param snapshot - The root tree snapshot
2652
+ * @param nodeId - The ID of the node (if undefined, returns all descendants of root)
2653
+ * @returns Flat array of all descendant node snapshots
2654
+ */
2655
+ function getDescendants(snapshot, nodeId) {
2656
+ if (!snapshot) return [];
2657
+ const startNode = nodeId ? findNodeById(snapshot, nodeId) : snapshot;
2658
+ if (!startNode) return [];
2659
+ const descendants = [];
2660
+ const collect = (node) => {
2661
+ for (const child of node.children) {
2662
+ descendants.push(child);
2663
+ collect(child);
2664
+ }
2665
+ };
2666
+ collect(startNode);
2667
+ return descendants;
2668
+ }
2669
+ /**
2670
+ * Get siblings of a node (nodes with the same parent).
2671
+ *
2672
+ * @param snapshot - The root tree snapshot
2673
+ * @param nodeId - The ID of the node
2674
+ * @param includeSelf - Whether to include the node itself (default: false)
2675
+ * @returns Array of sibling snapshots
2676
+ */
2677
+ function getSiblings(snapshot, nodeId, includeSelf = false) {
2678
+ if (!snapshot) return [];
2679
+ const parentResult = getParent(snapshot, nodeId);
2680
+ if (!parentResult) return [];
2681
+ const siblings = parentResult.parent.children;
2682
+ if (includeSelf) return siblings;
2683
+ return siblings.filter((s) => s.id !== nodeId);
2684
+ }
2685
+ /**
2686
+ * Find the first node matching a predicate.
2687
+ *
2688
+ * @param snapshot - The root tree snapshot
2689
+ * @param predicate - Function to test each node
2690
+ * @returns First matching node snapshot, or undefined
2691
+ */
2692
+ function findNode(snapshot, predicate) {
2693
+ if (!snapshot) return void 0;
2694
+ if (predicate(snapshot)) return snapshot;
2695
+ for (const child of snapshot.children) {
2696
+ const found = findNode(child, predicate);
2697
+ if (found) return found;
2698
+ }
2699
+ }
2700
+ /**
2701
+ * Find all nodes matching a predicate.
2702
+ *
2703
+ * @param snapshot - The root tree snapshot
2704
+ * @param predicate - Function to test each node
2705
+ * @returns Array of matching node snapshots
2706
+ */
2707
+ function findNodes(snapshot, predicate) {
2708
+ if (!snapshot) return [];
2709
+ const results = [];
2710
+ const search = (node) => {
2711
+ if (predicate(node)) results.push(node);
2712
+ for (const child of node.children) search(child);
2713
+ };
2714
+ search(snapshot);
2715
+ return results;
2716
+ }
2717
+ /**
2718
+ * Get the depth of a specific node (0 = root).
2719
+ *
2720
+ * @param snapshot - The root tree snapshot
2721
+ * @param nodeId - The ID of the node
2722
+ * @returns The depth, or -1 if not found
2723
+ */
2724
+ function getNodeDepth(snapshot, nodeId) {
2725
+ if (!snapshot) return -1;
2726
+ const result = findNodeWithPath(snapshot, nodeId);
2727
+ return result ? result.depth : -1;
2728
+ }
2729
+ /**
2730
+ * Check if one node is an ancestor of another.
2731
+ *
2732
+ * @param snapshot - The root tree snapshot
2733
+ * @param ancestorId - Potential ancestor node ID
2734
+ * @param descendantId - Potential descendant node ID
2735
+ * @returns true if ancestorId is an ancestor of descendantId
2736
+ */
2737
+ function isAncestorOf(snapshot, ancestorId, descendantId) {
2738
+ if (!snapshot) return false;
2739
+ const result = findNodeWithPath(snapshot, descendantId);
2740
+ if (!result) return false;
2741
+ return result.path.slice(0, -1).includes(ancestorId);
2742
+ }
2743
+ /**
2744
+ * Traverse the tree and call a visitor function for each node.
2745
+ * Return false from visitor to stop traversal.
2746
+ *
2747
+ * @param snapshot - The root tree snapshot
2748
+ * @param visitor - Function called for each node (return false to stop)
2749
+ * @param options - Traversal options (order: 'pre' | 'post')
2750
+ */
2751
+ function traverse(snapshot, visitor, options = {}) {
2752
+ if (!snapshot) return;
2753
+ const { order = "pre" } = options;
2754
+ const visit = (node, depth) => {
2755
+ if (order === "pre") {
2756
+ if (visitor(node, depth) === false) return false;
2757
+ }
2758
+ for (const child of node.children) if (!visit(child, depth + 1)) return false;
2759
+ if (order === "post") {
2760
+ if (visitor(node, depth) === false) return false;
2761
+ }
2762
+ return true;
2763
+ };
2764
+ visit(snapshot, 0);
2765
+ }
2766
+ /**
2767
+ * Flatten the tree into an array with parent information.
2768
+ *
2769
+ * @param snapshot - The root tree snapshot
2770
+ * @returns Array of { node, parentId, depth } objects
2771
+ */
2772
+ function flattenTree(snapshot) {
2773
+ if (!snapshot) return [];
2774
+ const result = [];
2775
+ const flatten = (node, parentId, depth) => {
2776
+ result.push({
2777
+ node,
2778
+ parentId,
2779
+ depth
2780
+ });
2781
+ for (const child of node.children) flatten(child, node.id, depth + 1);
2782
+ };
2783
+ flatten(snapshot, null, 0);
2784
+ return result;
2785
+ }
2786
+ /**
2787
+ * Map over all nodes in the tree, transforming each node's data.
2788
+ * Preserves tree structure while transforming node content.
2789
+ *
2790
+ * @param snapshot - The root tree snapshot
2791
+ * @param mapper - Function to transform each node
2792
+ * @returns New tree structure with transformed nodes, or undefined
2793
+ */
2794
+ function mapTree(snapshot, mapper) {
2795
+ if (!snapshot) return void 0;
2796
+ const map = (node, depth) => {
2797
+ return {
2798
+ value: mapper(node, depth),
2799
+ children: node.children.map((child) => map(child, depth + 1))
2800
+ };
2801
+ };
2802
+ return map(snapshot, 0);
2803
+ }
2804
+ /**
2805
+ * Build a lookup map from node type strings to their TreeNodePrimitive definitions.
2806
+ * Useful for resolving snapshot node types back to their schema definitions.
2807
+ *
2808
+ * @param tree - The TreePrimitive to analyze
2809
+ * @returns Map from type string to TreeNodePrimitive
2810
+ *
2811
+ * @example
2812
+ * ```ts
2813
+ * const typeMap = buildNodeTypeMap(fileTree);
2814
+ * const folderPrimitive = typeMap.get("folder"); // FolderNode
2815
+ * ```
2816
+ */
2817
+ function buildNodeTypeMap(tree) {
2818
+ const map = /* @__PURE__ */ new Map();
2819
+ const visited = /* @__PURE__ */ new Set();
2820
+ const visit = (node) => {
2821
+ if (visited.has(node.type)) return;
2822
+ visited.add(node.type);
2823
+ map.set(node.type, node);
2824
+ for (const child of node.children) visit(child);
2825
+ };
2826
+ visit(tree.root);
2827
+ return map;
2828
+ }
2829
+ /**
2830
+ * Get the TreeNodePrimitive definition for a snapshot node.
2831
+ * Requires the tree schema to resolve the type string to its primitive.
2832
+ *
2833
+ * @param tree - The TreePrimitive schema
2834
+ * @param snapshot - The node snapshot to get the primitive for
2835
+ * @returns The TreeNodePrimitive, or undefined if not found
2836
+ *
2837
+ * @example
2838
+ * ```ts
2839
+ * const node = findNodeById(treeSnapshot, "some-id");
2840
+ * const primitive = getNodePrimitive(fileTree, node);
2841
+ * // primitive is FolderNode or FileNode depending on node.type
2842
+ * ```
2843
+ */
2844
+ function getNodePrimitive(tree, snapshot) {
2845
+ return getNodeTypeByName(tree, snapshot.type);
2846
+ }
2847
+ /**
2848
+ * Get the allowed child types for a snapshot node.
2849
+ * Combines schema lookup with the node's allowed children.
2850
+ *
2851
+ * @param tree - The TreePrimitive schema
2852
+ * @param snapshot - The node snapshot to get allowed children for
2853
+ * @returns Array of allowed child TreeNodePrimitives, or empty array if not found
2854
+ *
2855
+ * @example
2856
+ * ```ts
2857
+ * const node = findNodeById(treeSnapshot, "folder-id");
2858
+ * const allowedChildren = getAllowedChildTypesForNode(fileTree, node);
2859
+ * // Returns [FolderNode, FileNode] if the folder can contain both
2860
+ * ```
2861
+ */
2862
+ function getAllowedChildTypesForNode(tree, snapshot) {
2863
+ const primitive = getNodePrimitive(tree, snapshot);
2864
+ if (!primitive) return [];
2865
+ return primitive.children;
2866
+ }
2867
+ /**
2868
+ * Check if a child type is allowed for a specific snapshot node.
2869
+ *
2870
+ * @param tree - The TreePrimitive schema
2871
+ * @param parentSnapshot - The parent node snapshot
2872
+ * @param childTypeName - The type string of the potential child
2873
+ * @returns true if the child type is allowed
2874
+ *
2875
+ * @example
2876
+ * ```ts
2877
+ * const folder = findNodeById(treeSnapshot, "folder-id");
2878
+ * canAddChildType(fileTree, folder, "file"); // true
2879
+ * canAddChildType(fileTree, folder, "unknown"); // false
2880
+ * ```
2881
+ */
2882
+ function canAddChildType(tree, parentSnapshot, childTypeName) {
2883
+ const primitive = getNodePrimitive(tree, parentSnapshot);
2884
+ if (!primitive) return false;
2885
+ return primitive.isChildAllowed(childTypeName);
2886
+ }
2887
+ /**
2888
+ * Get all allowed child node types for a specific node type.
2889
+ *
2890
+ * @param nodeType - The TreeNodePrimitive to get children for
2891
+ * @returns Array of allowed child TreeNodePrimitives
2892
+ *
2893
+ * @example
2894
+ * ```ts
2895
+ * const FolderNode = TreeNode("folder", { ... });
2896
+ * const FileNode = TreeNode("file", { ... });
2897
+ *
2898
+ * // Get allowed children for FolderNode
2899
+ * const allowedChildren = getAllowedChildTypes(FolderNode);
2900
+ * // Returns [FolderNode, FileNode] if folder can contain both
2901
+ * ```
2902
+ */
2903
+ function getAllowedChildTypes(nodeType) {
2904
+ return nodeType.children;
2905
+ }
2906
+ /**
2907
+ * Get all unique node types reachable in a tree schema.
2908
+ * Recursively traverses the tree structure starting from the root.
2909
+ *
2910
+ * @param tree - The TreePrimitive to analyze
2911
+ * @returns Array of all unique TreeNodePrimitives in the tree schema
2912
+ *
2913
+ * @example
2914
+ * ```ts
2915
+ * const fileTree = Tree({ root: FolderNode });
2916
+ * const allNodeTypes = getAllNodeTypes(fileTree);
2917
+ * // Returns [FolderNode, FileNode] - all possible node types
2918
+ * ```
2919
+ */
2920
+ function getAllNodeTypes(tree) {
2921
+ const visited = /* @__PURE__ */ new Set();
2922
+ const result = [];
2923
+ const visit = (node) => {
2924
+ if (visited.has(node.type)) return;
2925
+ visited.add(node.type);
2926
+ result.push(node);
2927
+ for (const child of node.children) visit(child);
2928
+ };
2929
+ visit(tree.root);
2930
+ return result;
2931
+ }
2932
+ /**
2933
+ * Get the node type primitive by its type string from a tree schema.
2934
+ *
2935
+ * @param tree - The TreePrimitive to search
2936
+ * @param typeName - The type string to find (e.g., "folder", "file")
2937
+ * @returns The matching TreeNodePrimitive, or undefined if not found
2938
+ *
2939
+ * @example
2940
+ * ```ts
2941
+ * const fileTree = Tree({ root: FolderNode });
2942
+ * const folderType = getNodeTypeByName(fileTree, "folder");
2943
+ * // Returns FolderNode
2944
+ * ```
2945
+ */
2946
+ function getNodeTypeByName(tree, typeName) {
2947
+ return getAllNodeTypes(tree).find((node) => node.type === typeName);
2948
+ }
2949
+ /**
2950
+ * Check if a child type is allowed under a parent type.
2951
+ *
2952
+ * @param parentType - The parent TreeNodePrimitive
2953
+ * @param childTypeName - The type string of the potential child
2954
+ * @returns true if the child type is allowed
2955
+ *
2956
+ * @example
2957
+ * ```ts
2958
+ * isChildTypeAllowed(FolderNode, "file"); // true if folder can contain files
2959
+ * isChildTypeAllowed(FileNode, "folder"); // false - files can't have children
2960
+ * ```
2961
+ */
2962
+ function isChildTypeAllowed(parentType, childTypeName) {
2963
+ return parentType.isChildAllowed(childTypeName);
2964
+ }
2965
+
2966
+ //#endregion
2967
+ export { Document_exports as Document, EffectSchema_exports as EffectSchema, Operation_exports as Operation, OperationPath_exports as OperationPath, Presence_exports as Presence, Primitive_exports as Primitive, ProxyEnvironment_exports as ProxyEnvironment, Transaction_exports as Transaction, Transform_exports as Transform, tree_helpers_exports as TreeHelpers, types_exports as Types };
2526
2968
  //# sourceMappingURL=index.mjs.map