@voidhash/mimic 0.0.1-alpha.9 → 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.cjs CHANGED
@@ -2349,6 +2349,619 @@ var Primitive_exports = /* @__PURE__ */ require_Document.__export({
2349
2349
  //#region src/Transform.ts
2350
2350
  var Transform_exports = {};
2351
2351
 
2352
+ //#endregion
2353
+ //#region src/EffectSchema.ts
2354
+ /**
2355
+ * Effect.Schema utilities for converting Mimic primitives to Effect.Schema schemas.
2356
+ *
2357
+ * @since 0.0.1
2358
+ */
2359
+ var EffectSchema_exports = /* @__PURE__ */ require_Document.__export({
2360
+ TreeNodeStateSchema: () => TreeNodeStateSchema,
2361
+ toSetSchema: () => toSetSchema,
2362
+ toUpdateSchema: () => toUpdateSchema
2363
+ });
2364
+ /**
2365
+ * Schema for a tree node state (flat storage format).
2366
+ */
2367
+ const TreeNodeStateSchema = effect.Schema.Struct({
2368
+ id: effect.Schema.String,
2369
+ type: effect.Schema.String,
2370
+ parentId: effect.Schema.NullOr(effect.Schema.String),
2371
+ pos: effect.Schema.String,
2372
+ data: effect.Schema.Unknown
2373
+ });
2374
+ /**
2375
+ * Check if a field is required for set operations.
2376
+ * A field is required if: TRequired is true AND THasDefault is false.
2377
+ *
2378
+ * We determine this by checking the primitive's schema properties.
2379
+ */
2380
+ function isRequiredForSet(primitive) {
2381
+ const schema = primitive._schema;
2382
+ if (!schema) return false;
2383
+ return schema.required === true && schema.defaultValue === void 0;
2384
+ }
2385
+ /**
2386
+ * Get the base Effect.Schema for a primitive type (without optional wrapper).
2387
+ */
2388
+ function getBaseSchema(primitive) {
2389
+ switch (primitive._tag) {
2390
+ case "StringPrimitive": return effect.Schema.String;
2391
+ case "NumberPrimitive": return effect.Schema.Number;
2392
+ case "BooleanPrimitive": return effect.Schema.Boolean;
2393
+ case "LiteralPrimitive": {
2394
+ var _schema$literal, _schema;
2395
+ const literalPrimitive = primitive;
2396
+ const literalValue = (_schema$literal = (_schema = literalPrimitive._schema) === null || _schema === void 0 ? void 0 : _schema.literal) !== null && _schema$literal !== void 0 ? _schema$literal : literalPrimitive.literal;
2397
+ return effect.Schema.Literal(literalValue);
2398
+ }
2399
+ case "StructPrimitive": return buildStructSetSchema(primitive);
2400
+ case "ArrayPrimitive": {
2401
+ const elementSchema = buildElementSetSchema(primitive.element);
2402
+ return effect.Schema.Array(elementSchema);
2403
+ }
2404
+ case "UnionPrimitive": return buildUnionSetSchema(primitive);
2405
+ case "EitherPrimitive": return buildEitherSchema(primitive);
2406
+ case "LazyPrimitive": {
2407
+ var _resolve, _resolve2;
2408
+ const lazyPrimitive = primitive;
2409
+ return getBaseSchema((_resolve = (_resolve2 = lazyPrimitive._resolve) === null || _resolve2 === void 0 ? void 0 : _resolve2.call(lazyPrimitive)) !== null && _resolve !== void 0 ? _resolve : lazyPrimitive._thunk());
2410
+ }
2411
+ case "TreeNodePrimitive": return buildStructSetSchema(primitive.data);
2412
+ case "TreePrimitive": return effect.Schema.Array(TreeNodeStateSchema);
2413
+ default: return effect.Schema.Unknown;
2414
+ }
2415
+ }
2416
+ /**
2417
+ * Build the set schema for a struct primitive.
2418
+ * Required fields (required=true, no default) are non-optional.
2419
+ * Other fields are wrapped with Schema.optional.
2420
+ */
2421
+ function buildStructSetSchema(structPrimitive) {
2422
+ const fields = structPrimitive.fields;
2423
+ const schemaFields = {};
2424
+ for (const key in fields) {
2425
+ const fieldPrimitive = fields[key];
2426
+ const baseSchema = getBaseSchema(fieldPrimitive);
2427
+ if (isRequiredForSet(fieldPrimitive)) schemaFields[key] = baseSchema;
2428
+ else schemaFields[key] = effect.Schema.optional(baseSchema);
2429
+ }
2430
+ return effect.Schema.Struct(schemaFields);
2431
+ }
2432
+ /**
2433
+ * Build the update schema for a struct primitive.
2434
+ * All fields are optional for partial updates.
2435
+ */
2436
+ function buildStructUpdateSchema(structPrimitive) {
2437
+ const fields = structPrimitive.fields;
2438
+ const schemaFields = {};
2439
+ for (const key in fields) {
2440
+ const fieldPrimitive = fields[key];
2441
+ let fieldSchema;
2442
+ if (fieldPrimitive._tag === "StructPrimitive") fieldSchema = buildStructUpdateSchema(fieldPrimitive);
2443
+ else fieldSchema = getBaseSchema(fieldPrimitive);
2444
+ schemaFields[key] = effect.Schema.optional(fieldSchema);
2445
+ }
2446
+ return effect.Schema.Struct(schemaFields);
2447
+ }
2448
+ /**
2449
+ * Build the set schema for an array element.
2450
+ * For struct elements, uses the struct's set input schema.
2451
+ */
2452
+ function buildElementSetSchema(elementPrimitive) {
2453
+ if (elementPrimitive._tag === "StructPrimitive") return buildStructSetSchema(elementPrimitive);
2454
+ return getBaseSchema(elementPrimitive);
2455
+ }
2456
+ /**
2457
+ * Build the set schema for a union primitive.
2458
+ * Creates a Schema.Union of all variant schemas.
2459
+ */
2460
+ function buildUnionSetSchema(unionPrimitive) {
2461
+ const variants = unionPrimitive.variants;
2462
+ const variantSchemas = [];
2463
+ for (const key in variants) {
2464
+ const variantPrimitive = variants[key];
2465
+ variantSchemas.push(buildStructSetSchema(variantPrimitive));
2466
+ }
2467
+ if (variantSchemas.length === 0) return effect.Schema.Unknown;
2468
+ if (variantSchemas.length === 1) return variantSchemas[0];
2469
+ return effect.Schema.Union(...variantSchemas);
2470
+ }
2471
+ /**
2472
+ * Build the schema for an either primitive.
2473
+ * Creates a Schema.Union of all scalar variant types.
2474
+ */
2475
+ function buildEitherSchema(eitherPrimitive) {
2476
+ const variants = eitherPrimitive.variants;
2477
+ const variantSchemas = [];
2478
+ for (const variant of variants) variantSchemas.push(getBaseSchema(variant));
2479
+ if (variantSchemas.length === 0) return effect.Schema.Unknown;
2480
+ if (variantSchemas.length === 1) return variantSchemas[0];
2481
+ return effect.Schema.Union(...variantSchemas);
2482
+ }
2483
+ /**
2484
+ * Build the update schema for a union primitive.
2485
+ * Creates a Schema.Union of all variant update schemas.
2486
+ */
2487
+ function buildUnionUpdateSchema(unionPrimitive) {
2488
+ const variants = unionPrimitive.variants;
2489
+ const variantSchemas = [];
2490
+ for (const key in variants) {
2491
+ const variantPrimitive = variants[key];
2492
+ variantSchemas.push(buildStructUpdateSchema(variantPrimitive));
2493
+ }
2494
+ if (variantSchemas.length === 0) return effect.Schema.Unknown;
2495
+ if (variantSchemas.length === 1) return variantSchemas[0];
2496
+ return effect.Schema.Union(...variantSchemas);
2497
+ }
2498
+ /**
2499
+ * Get the update schema for a primitive.
2500
+ * For structs, all fields are optional (partial updates).
2501
+ * For simple primitives, same as set schema.
2502
+ */
2503
+ function getUpdateSchema(primitive) {
2504
+ switch (primitive._tag) {
2505
+ case "StructPrimitive": return buildStructUpdateSchema(primitive);
2506
+ case "UnionPrimitive": return buildUnionUpdateSchema(primitive);
2507
+ case "TreeNodePrimitive": return buildStructUpdateSchema(primitive.data);
2508
+ case "LazyPrimitive": {
2509
+ var _resolve3, _resolve4;
2510
+ const lazyPrimitive = primitive;
2511
+ return getUpdateSchema((_resolve3 = (_resolve4 = lazyPrimitive._resolve) === null || _resolve4 === void 0 ? void 0 : _resolve4.call(lazyPrimitive)) !== null && _resolve3 !== void 0 ? _resolve3 : lazyPrimitive._thunk());
2512
+ }
2513
+ default: return getBaseSchema(primitive);
2514
+ }
2515
+ }
2516
+ function toSetSchema(primitive) {
2517
+ return getBaseSchema(primitive);
2518
+ }
2519
+ function toUpdateSchema(primitive) {
2520
+ return getUpdateSchema(primitive);
2521
+ }
2522
+
2523
+ //#endregion
2524
+ //#region src/types/index.ts
2525
+ var types_exports = /* @__PURE__ */ require_Document.__export({
2526
+ TreeNodePrimitive: () => TreeNodePrimitive,
2527
+ TreeNodeSelf: () => TreeNodeSelf
2528
+ });
2529
+
2530
+ //#endregion
2531
+ //#region src/utils/tree-helpers.ts
2532
+ var tree_helpers_exports = /* @__PURE__ */ require_Document.__export({
2533
+ buildNodeTypeMap: () => buildNodeTypeMap,
2534
+ canAddChildType: () => canAddChildType,
2535
+ findNode: () => findNode,
2536
+ findNodeById: () => findNodeById,
2537
+ findNodeWithPath: () => findNodeWithPath,
2538
+ findNodes: () => findNodes,
2539
+ flattenTree: () => flattenTree,
2540
+ getAllNodeTypes: () => getAllNodeTypes,
2541
+ getAllowedChildTypes: () => getAllowedChildTypes,
2542
+ getAllowedChildTypesForNode: () => getAllowedChildTypesForNode,
2543
+ getAncestors: () => getAncestors,
2544
+ getDescendants: () => getDescendants,
2545
+ getNodeDepth: () => getNodeDepth,
2546
+ getNodePrimitive: () => getNodePrimitive,
2547
+ getNodeTypeByName: () => getNodeTypeByName,
2548
+ getParent: () => getParent,
2549
+ getSiblings: () => getSiblings,
2550
+ getSubtree: () => getSubtree,
2551
+ isAncestorOf: () => isAncestorOf,
2552
+ isChildTypeAllowed: () => isChildTypeAllowed,
2553
+ mapTree: () => mapTree,
2554
+ traverse: () => traverse
2555
+ });
2556
+ /**
2557
+ * Find a node by ID in a tree snapshot.
2558
+ *
2559
+ * @param snapshot - The root tree snapshot
2560
+ * @param id - The node ID to find
2561
+ * @returns The node snapshot if found, undefined otherwise
2562
+ */
2563
+ function findNodeById(snapshot, id) {
2564
+ if (!snapshot) return void 0;
2565
+ if (snapshot.id === id) return snapshot;
2566
+ for (const child of snapshot.children) {
2567
+ const found = findNodeById(child, id);
2568
+ if (found) return found;
2569
+ }
2570
+ }
2571
+ /**
2572
+ * Find a node by ID with full path information.
2573
+ *
2574
+ * @param snapshot - The root tree snapshot
2575
+ * @param id - The node ID to find
2576
+ * @returns NodeSearchResult with node, path, and depth, or undefined if not found
2577
+ */
2578
+ function findNodeWithPath(snapshot, id) {
2579
+ if (!snapshot) return void 0;
2580
+ const search = (node, currentPath, depth) => {
2581
+ const path = [...currentPath, node.id];
2582
+ if (node.id === id) return {
2583
+ node,
2584
+ path,
2585
+ depth
2586
+ };
2587
+ for (const child of node.children) {
2588
+ const result = search(child, path, depth + 1);
2589
+ if (result) return result;
2590
+ }
2591
+ };
2592
+ return search(snapshot, [], 0);
2593
+ }
2594
+ /**
2595
+ * Get the parent node of a given node ID.
2596
+ *
2597
+ * @param snapshot - The root tree snapshot
2598
+ * @param nodeId - The ID of the node whose parent we want
2599
+ * @returns ParentSearchResult with parent node and child index, or undefined
2600
+ */
2601
+ function getParent(snapshot, nodeId) {
2602
+ if (!snapshot) return void 0;
2603
+ for (let i = 0; i < snapshot.children.length; i++) {
2604
+ const child = snapshot.children[i];
2605
+ if (child && child.id === nodeId) return {
2606
+ parent: snapshot,
2607
+ childIndex: i
2608
+ };
2609
+ }
2610
+ for (const child of snapshot.children) {
2611
+ const result = getParent(child, nodeId);
2612
+ if (result) return result;
2613
+ }
2614
+ }
2615
+ /**
2616
+ * Get a subtree rooted at a specific node ID.
2617
+ *
2618
+ * @param snapshot - The root tree snapshot
2619
+ * @param nodeId - The ID of the node to use as new root
2620
+ * @returns The subtree snapshot, or undefined if node not found
2621
+ */
2622
+ function getSubtree(snapshot, nodeId) {
2623
+ return findNodeById(snapshot, nodeId);
2624
+ }
2625
+ /**
2626
+ * Get all ancestor nodes from a node up to the root.
2627
+ *
2628
+ * @param snapshot - The root tree snapshot
2629
+ * @param nodeId - The ID of the node
2630
+ * @returns Array of ancestor snapshots from immediate parent to root, or empty array
2631
+ */
2632
+ function getAncestors(snapshot, nodeId) {
2633
+ if (!snapshot) return [];
2634
+ const result = findNodeWithPath(snapshot, nodeId);
2635
+ if (!result || result.path.length <= 1) return [];
2636
+ const ancestorIds = result.path.slice(0, -1);
2637
+ const ancestors = [];
2638
+ for (let i = ancestorIds.length - 1; i >= 0; i--) {
2639
+ const id = ancestorIds[i];
2640
+ if (id) {
2641
+ const ancestor = findNodeById(snapshot, id);
2642
+ if (ancestor) ancestors.push(ancestor);
2643
+ }
2644
+ }
2645
+ return ancestors;
2646
+ }
2647
+ /**
2648
+ * Get all descendant nodes of a given node (flat array).
2649
+ *
2650
+ * @param snapshot - The root tree snapshot
2651
+ * @param nodeId - The ID of the node (if undefined, returns all descendants of root)
2652
+ * @returns Flat array of all descendant node snapshots
2653
+ */
2654
+ function getDescendants(snapshot, nodeId) {
2655
+ if (!snapshot) return [];
2656
+ const startNode = nodeId ? findNodeById(snapshot, nodeId) : snapshot;
2657
+ if (!startNode) return [];
2658
+ const descendants = [];
2659
+ const collect = (node) => {
2660
+ for (const child of node.children) {
2661
+ descendants.push(child);
2662
+ collect(child);
2663
+ }
2664
+ };
2665
+ collect(startNode);
2666
+ return descendants;
2667
+ }
2668
+ /**
2669
+ * Get siblings of a node (nodes with the same parent).
2670
+ *
2671
+ * @param snapshot - The root tree snapshot
2672
+ * @param nodeId - The ID of the node
2673
+ * @param includeSelf - Whether to include the node itself (default: false)
2674
+ * @returns Array of sibling snapshots
2675
+ */
2676
+ function getSiblings(snapshot, nodeId, includeSelf = false) {
2677
+ if (!snapshot) return [];
2678
+ const parentResult = getParent(snapshot, nodeId);
2679
+ if (!parentResult) return [];
2680
+ const siblings = parentResult.parent.children;
2681
+ if (includeSelf) return siblings;
2682
+ return siblings.filter((s) => s.id !== nodeId);
2683
+ }
2684
+ /**
2685
+ * Find the first node matching a predicate.
2686
+ *
2687
+ * @param snapshot - The root tree snapshot
2688
+ * @param predicate - Function to test each node
2689
+ * @returns First matching node snapshot, or undefined
2690
+ */
2691
+ function findNode(snapshot, predicate) {
2692
+ if (!snapshot) return void 0;
2693
+ if (predicate(snapshot)) return snapshot;
2694
+ for (const child of snapshot.children) {
2695
+ const found = findNode(child, predicate);
2696
+ if (found) return found;
2697
+ }
2698
+ }
2699
+ /**
2700
+ * Find all nodes matching a predicate.
2701
+ *
2702
+ * @param snapshot - The root tree snapshot
2703
+ * @param predicate - Function to test each node
2704
+ * @returns Array of matching node snapshots
2705
+ */
2706
+ function findNodes(snapshot, predicate) {
2707
+ if (!snapshot) return [];
2708
+ const results = [];
2709
+ const search = (node) => {
2710
+ if (predicate(node)) results.push(node);
2711
+ for (const child of node.children) search(child);
2712
+ };
2713
+ search(snapshot);
2714
+ return results;
2715
+ }
2716
+ /**
2717
+ * Get the depth of a specific node (0 = root).
2718
+ *
2719
+ * @param snapshot - The root tree snapshot
2720
+ * @param nodeId - The ID of the node
2721
+ * @returns The depth, or -1 if not found
2722
+ */
2723
+ function getNodeDepth(snapshot, nodeId) {
2724
+ if (!snapshot) return -1;
2725
+ const result = findNodeWithPath(snapshot, nodeId);
2726
+ return result ? result.depth : -1;
2727
+ }
2728
+ /**
2729
+ * Check if one node is an ancestor of another.
2730
+ *
2731
+ * @param snapshot - The root tree snapshot
2732
+ * @param ancestorId - Potential ancestor node ID
2733
+ * @param descendantId - Potential descendant node ID
2734
+ * @returns true if ancestorId is an ancestor of descendantId
2735
+ */
2736
+ function isAncestorOf(snapshot, ancestorId, descendantId) {
2737
+ if (!snapshot) return false;
2738
+ const result = findNodeWithPath(snapshot, descendantId);
2739
+ if (!result) return false;
2740
+ return result.path.slice(0, -1).includes(ancestorId);
2741
+ }
2742
+ /**
2743
+ * Traverse the tree and call a visitor function for each node.
2744
+ * Return false from visitor to stop traversal.
2745
+ *
2746
+ * @param snapshot - The root tree snapshot
2747
+ * @param visitor - Function called for each node (return false to stop)
2748
+ * @param options - Traversal options (order: 'pre' | 'post')
2749
+ */
2750
+ function traverse(snapshot, visitor, options = {}) {
2751
+ if (!snapshot) return;
2752
+ const { order = "pre" } = options;
2753
+ const visit = (node, depth) => {
2754
+ if (order === "pre") {
2755
+ if (visitor(node, depth) === false) return false;
2756
+ }
2757
+ for (const child of node.children) if (!visit(child, depth + 1)) return false;
2758
+ if (order === "post") {
2759
+ if (visitor(node, depth) === false) return false;
2760
+ }
2761
+ return true;
2762
+ };
2763
+ visit(snapshot, 0);
2764
+ }
2765
+ /**
2766
+ * Flatten the tree into an array with parent information.
2767
+ *
2768
+ * @param snapshot - The root tree snapshot
2769
+ * @returns Array of { node, parentId, depth } objects
2770
+ */
2771
+ function flattenTree(snapshot) {
2772
+ if (!snapshot) return [];
2773
+ const result = [];
2774
+ const flatten = (node, parentId, depth) => {
2775
+ result.push({
2776
+ node,
2777
+ parentId,
2778
+ depth
2779
+ });
2780
+ for (const child of node.children) flatten(child, node.id, depth + 1);
2781
+ };
2782
+ flatten(snapshot, null, 0);
2783
+ return result;
2784
+ }
2785
+ /**
2786
+ * Map over all nodes in the tree, transforming each node's data.
2787
+ * Preserves tree structure while transforming node content.
2788
+ *
2789
+ * @param snapshot - The root tree snapshot
2790
+ * @param mapper - Function to transform each node
2791
+ * @returns New tree structure with transformed nodes, or undefined
2792
+ */
2793
+ function mapTree(snapshot, mapper) {
2794
+ if (!snapshot) return void 0;
2795
+ const map = (node, depth) => {
2796
+ return {
2797
+ value: mapper(node, depth),
2798
+ children: node.children.map((child) => map(child, depth + 1))
2799
+ };
2800
+ };
2801
+ return map(snapshot, 0);
2802
+ }
2803
+ /**
2804
+ * Build a lookup map from node type strings to their TreeNodePrimitive definitions.
2805
+ * Useful for resolving snapshot node types back to their schema definitions.
2806
+ *
2807
+ * @param tree - The TreePrimitive to analyze
2808
+ * @returns Map from type string to TreeNodePrimitive
2809
+ *
2810
+ * @example
2811
+ * ```ts
2812
+ * const typeMap = buildNodeTypeMap(fileTree);
2813
+ * const folderPrimitive = typeMap.get("folder"); // FolderNode
2814
+ * ```
2815
+ */
2816
+ function buildNodeTypeMap(tree) {
2817
+ const map = /* @__PURE__ */ new Map();
2818
+ const visited = /* @__PURE__ */ new Set();
2819
+ const visit = (node) => {
2820
+ if (visited.has(node.type)) return;
2821
+ visited.add(node.type);
2822
+ map.set(node.type, node);
2823
+ for (const child of node.children) visit(child);
2824
+ };
2825
+ visit(tree.root);
2826
+ return map;
2827
+ }
2828
+ /**
2829
+ * Get the TreeNodePrimitive definition for a snapshot node.
2830
+ * Requires the tree schema to resolve the type string to its primitive.
2831
+ *
2832
+ * @param tree - The TreePrimitive schema
2833
+ * @param snapshot - The node snapshot to get the primitive for
2834
+ * @returns The TreeNodePrimitive, or undefined if not found
2835
+ *
2836
+ * @example
2837
+ * ```ts
2838
+ * const node = findNodeById(treeSnapshot, "some-id");
2839
+ * const primitive = getNodePrimitive(fileTree, node);
2840
+ * // primitive is FolderNode or FileNode depending on node.type
2841
+ * ```
2842
+ */
2843
+ function getNodePrimitive(tree, snapshot) {
2844
+ return getNodeTypeByName(tree, snapshot.type);
2845
+ }
2846
+ /**
2847
+ * Get the allowed child types for a snapshot node.
2848
+ * Combines schema lookup with the node's allowed children.
2849
+ *
2850
+ * @param tree - The TreePrimitive schema
2851
+ * @param snapshot - The node snapshot to get allowed children for
2852
+ * @returns Array of allowed child TreeNodePrimitives, or empty array if not found
2853
+ *
2854
+ * @example
2855
+ * ```ts
2856
+ * const node = findNodeById(treeSnapshot, "folder-id");
2857
+ * const allowedChildren = getAllowedChildTypesForNode(fileTree, node);
2858
+ * // Returns [FolderNode, FileNode] if the folder can contain both
2859
+ * ```
2860
+ */
2861
+ function getAllowedChildTypesForNode(tree, snapshot) {
2862
+ const primitive = getNodePrimitive(tree, snapshot);
2863
+ if (!primitive) return [];
2864
+ return primitive.children;
2865
+ }
2866
+ /**
2867
+ * Check if a child type is allowed for a specific snapshot node.
2868
+ *
2869
+ * @param tree - The TreePrimitive schema
2870
+ * @param parentSnapshot - The parent node snapshot
2871
+ * @param childTypeName - The type string of the potential child
2872
+ * @returns true if the child type is allowed
2873
+ *
2874
+ * @example
2875
+ * ```ts
2876
+ * const folder = findNodeById(treeSnapshot, "folder-id");
2877
+ * canAddChildType(fileTree, folder, "file"); // true
2878
+ * canAddChildType(fileTree, folder, "unknown"); // false
2879
+ * ```
2880
+ */
2881
+ function canAddChildType(tree, parentSnapshot, childTypeName) {
2882
+ const primitive = getNodePrimitive(tree, parentSnapshot);
2883
+ if (!primitive) return false;
2884
+ return primitive.isChildAllowed(childTypeName);
2885
+ }
2886
+ /**
2887
+ * Get all allowed child node types for a specific node type.
2888
+ *
2889
+ * @param nodeType - The TreeNodePrimitive to get children for
2890
+ * @returns Array of allowed child TreeNodePrimitives
2891
+ *
2892
+ * @example
2893
+ * ```ts
2894
+ * const FolderNode = TreeNode("folder", { ... });
2895
+ * const FileNode = TreeNode("file", { ... });
2896
+ *
2897
+ * // Get allowed children for FolderNode
2898
+ * const allowedChildren = getAllowedChildTypes(FolderNode);
2899
+ * // Returns [FolderNode, FileNode] if folder can contain both
2900
+ * ```
2901
+ */
2902
+ function getAllowedChildTypes(nodeType) {
2903
+ return nodeType.children;
2904
+ }
2905
+ /**
2906
+ * Get all unique node types reachable in a tree schema.
2907
+ * Recursively traverses the tree structure starting from the root.
2908
+ *
2909
+ * @param tree - The TreePrimitive to analyze
2910
+ * @returns Array of all unique TreeNodePrimitives in the tree schema
2911
+ *
2912
+ * @example
2913
+ * ```ts
2914
+ * const fileTree = Tree({ root: FolderNode });
2915
+ * const allNodeTypes = getAllNodeTypes(fileTree);
2916
+ * // Returns [FolderNode, FileNode] - all possible node types
2917
+ * ```
2918
+ */
2919
+ function getAllNodeTypes(tree) {
2920
+ const visited = /* @__PURE__ */ new Set();
2921
+ const result = [];
2922
+ const visit = (node) => {
2923
+ if (visited.has(node.type)) return;
2924
+ visited.add(node.type);
2925
+ result.push(node);
2926
+ for (const child of node.children) visit(child);
2927
+ };
2928
+ visit(tree.root);
2929
+ return result;
2930
+ }
2931
+ /**
2932
+ * Get the node type primitive by its type string from a tree schema.
2933
+ *
2934
+ * @param tree - The TreePrimitive to search
2935
+ * @param typeName - The type string to find (e.g., "folder", "file")
2936
+ * @returns The matching TreeNodePrimitive, or undefined if not found
2937
+ *
2938
+ * @example
2939
+ * ```ts
2940
+ * const fileTree = Tree({ root: FolderNode });
2941
+ * const folderType = getNodeTypeByName(fileTree, "folder");
2942
+ * // Returns FolderNode
2943
+ * ```
2944
+ */
2945
+ function getNodeTypeByName(tree, typeName) {
2946
+ return getAllNodeTypes(tree).find((node) => node.type === typeName);
2947
+ }
2948
+ /**
2949
+ * Check if a child type is allowed under a parent type.
2950
+ *
2951
+ * @param parentType - The parent TreeNodePrimitive
2952
+ * @param childTypeName - The type string of the potential child
2953
+ * @returns true if the child type is allowed
2954
+ *
2955
+ * @example
2956
+ * ```ts
2957
+ * isChildTypeAllowed(FolderNode, "file"); // true if folder can contain files
2958
+ * isChildTypeAllowed(FileNode, "folder"); // false - files can't have children
2959
+ * ```
2960
+ */
2961
+ function isChildTypeAllowed(parentType, childTypeName) {
2962
+ return parentType.isChildAllowed(childTypeName);
2963
+ }
2964
+
2352
2965
  //#endregion
2353
2966
  Object.defineProperty(exports, 'Document', {
2354
2967
  enumerable: true,
@@ -2356,6 +2969,12 @@ Object.defineProperty(exports, 'Document', {
2356
2969
  return require_Document.Document_exports;
2357
2970
  }
2358
2971
  });
2972
+ Object.defineProperty(exports, 'EffectSchema', {
2973
+ enumerable: true,
2974
+ get: function () {
2975
+ return EffectSchema_exports;
2976
+ }
2977
+ });
2359
2978
  Object.defineProperty(exports, 'Operation', {
2360
2979
  enumerable: true,
2361
2980
  get: function () {
@@ -2397,4 +3016,16 @@ Object.defineProperty(exports, 'Transform', {
2397
3016
  get: function () {
2398
3017
  return Transform_exports;
2399
3018
  }
3019
+ });
3020
+ Object.defineProperty(exports, 'TreeHelpers', {
3021
+ enumerable: true,
3022
+ get: function () {
3023
+ return tree_helpers_exports;
3024
+ }
3025
+ });
3026
+ Object.defineProperty(exports, 'Types', {
3027
+ enumerable: true,
3028
+ get: function () {
3029
+ return types_exports;
3030
+ }
2400
3031
  });