@voidhash/mimic 0.0.1-alpha.4 → 0.0.1-alpha.5
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/.turbo/turbo-build.log +13 -13
- package/dist/index.cjs +29 -4
- package/dist/index.d.cts +29 -16
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +29 -16
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +29 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/primitives/TreeNode.ts +49 -30
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voidhash/mimic",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"typescript": "5.8.3",
|
|
20
20
|
"vite-tsconfig-paths": "^5.1.4",
|
|
21
21
|
"vitest": "^3.2.4",
|
|
22
|
-
"@voidhash/tsconfig": "0.0.1-alpha.
|
|
22
|
+
"@voidhash/tsconfig": "0.0.1-alpha.5"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"effect": "^3.19.12"
|
|
@@ -7,45 +7,67 @@ import * as Transform from "../Transform";
|
|
|
7
7
|
import type { AnyPrimitive, InferState } from "../Primitive";
|
|
8
8
|
import { StructPrimitive } from "./Struct";
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Symbol used to identify the Self placeholder
|
|
12
|
+
*/
|
|
13
|
+
const TreeNodeSelfSymbol = Symbol.for("TreeNode.Self");
|
|
10
14
|
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
16
|
+
* Special placeholder for self-referential tree nodes.
|
|
17
|
+
* Use this in the children array when a node type can contain itself.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const FolderNode = TreeNode("folder", {
|
|
22
|
+
* data: Struct({ name: String() }),
|
|
23
|
+
* children: [Self], // Folder can contain other folders
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export const TreeNodeSelf = { _tag: "TreeNodeSelf", _symbol: TreeNodeSelfSymbol } as unknown as AnyTreeNodePrimitive;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if a value is the Self placeholder
|
|
13
31
|
*/
|
|
14
|
-
|
|
32
|
+
const isSelf = (value: unknown): boolean => {
|
|
33
|
+
return typeof value === "object" && value !== null && "_symbol" in value && (value as any)._symbol === TreeNodeSelfSymbol;
|
|
34
|
+
};
|
|
15
35
|
|
|
16
36
|
/**
|
|
17
|
-
*
|
|
37
|
+
* The type for children - either a direct array or a lazy function (for self-referential nodes).
|
|
38
|
+
* Using `Function` type allows self-references without explicit type annotations.
|
|
18
39
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
41
|
+
export type TreeNodeChildren = readonly AnyTreeNodePrimitive[] | Function;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Any TreeNodePrimitive type - used for generic constraints.
|
|
45
|
+
*/
|
|
46
|
+
export type AnyTreeNodePrimitive = TreeNodePrimitive<string, StructPrimitive<any>>;
|
|
21
47
|
|
|
22
48
|
/**
|
|
23
49
|
* Infer the data state type from a TreeNodePrimitive
|
|
24
50
|
*/
|
|
25
51
|
export type InferTreeNodeDataState<T extends AnyTreeNodePrimitive> =
|
|
26
|
-
T extends TreeNodePrimitive<any, infer TData
|
|
52
|
+
T extends TreeNodePrimitive<any, infer TData> ? InferState<TData> : never;
|
|
27
53
|
|
|
28
54
|
/**
|
|
29
55
|
* Infer the type literal from a TreeNodePrimitive
|
|
30
56
|
*/
|
|
31
57
|
export type InferTreeNodeType<T extends AnyTreeNodePrimitive> =
|
|
32
|
-
T extends TreeNodePrimitive<infer TType, any
|
|
58
|
+
T extends TreeNodePrimitive<infer TType, any> ? TType : never;
|
|
33
59
|
|
|
34
60
|
/**
|
|
35
|
-
* Infer the allowed children from a TreeNodePrimitive
|
|
61
|
+
* Infer the allowed children from a TreeNodePrimitive (resolved at runtime)
|
|
36
62
|
*/
|
|
37
|
-
export type InferTreeNodeChildren<
|
|
38
|
-
T extends TreeNodePrimitive<any, any, infer TChildren> ? ResolveChildren<TChildren>[number] : never;
|
|
63
|
+
export type InferTreeNodeChildren<_T extends AnyTreeNodePrimitive> = AnyTreeNodePrimitive;
|
|
39
64
|
|
|
40
65
|
/**
|
|
41
66
|
* Configuration for a TreeNode primitive
|
|
42
67
|
*/
|
|
43
|
-
export interface TreeNodeConfig<
|
|
44
|
-
TData extends StructPrimitive<any>,
|
|
45
|
-
TChildren extends readonly AnyTreeNodePrimitive[] | (() => readonly AnyTreeNodePrimitive[])
|
|
46
|
-
> {
|
|
68
|
+
export interface TreeNodeConfig<TData extends StructPrimitive<any>> {
|
|
47
69
|
readonly data: TData;
|
|
48
|
-
readonly children:
|
|
70
|
+
readonly children: TreeNodeChildren;
|
|
49
71
|
}
|
|
50
72
|
|
|
51
73
|
/**
|
|
@@ -53,20 +75,18 @@ export interface TreeNodeConfig<
|
|
|
53
75
|
*/
|
|
54
76
|
export class TreeNodePrimitive<
|
|
55
77
|
TType extends string,
|
|
56
|
-
TData extends StructPrimitive<any
|
|
57
|
-
TChildren extends readonly AnyTreeNodePrimitive[] | (() => readonly AnyTreeNodePrimitive[])
|
|
78
|
+
TData extends StructPrimitive<any>
|
|
58
79
|
> {
|
|
59
80
|
readonly _tag = "TreeNodePrimitive" as const;
|
|
60
81
|
readonly _Type!: TType;
|
|
61
82
|
readonly _Data!: TData;
|
|
62
|
-
readonly _Children!: TChildren;
|
|
63
83
|
|
|
64
84
|
private readonly _type: TType;
|
|
65
85
|
private readonly _data: TData;
|
|
66
|
-
private readonly _children:
|
|
86
|
+
private readonly _children: TreeNodeChildren;
|
|
67
87
|
private _resolvedChildren: readonly AnyTreeNodePrimitive[] | undefined;
|
|
68
88
|
|
|
69
|
-
constructor(type: TType, config: TreeNodeConfig<TData
|
|
89
|
+
constructor(type: TType, config: TreeNodeConfig<TData>) {
|
|
70
90
|
this._type = type;
|
|
71
91
|
this._data = config.data;
|
|
72
92
|
this._children = config.children;
|
|
@@ -82,14 +102,14 @@ export class TreeNodePrimitive<
|
|
|
82
102
|
return this._data;
|
|
83
103
|
}
|
|
84
104
|
|
|
85
|
-
/** Get resolved children (resolves lazy thunk if needed) */
|
|
105
|
+
/** Get resolved children (resolves lazy thunk if needed, replaces Self with this node) */
|
|
86
106
|
get children(): readonly AnyTreeNodePrimitive[] {
|
|
87
107
|
if (this._resolvedChildren === undefined) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
const resolved = typeof this._children === "function"
|
|
109
|
+
? (this._children as () => readonly AnyTreeNodePrimitive[])()
|
|
110
|
+
: this._children;
|
|
111
|
+
// Replace Self placeholders with this node
|
|
112
|
+
this._resolvedChildren = resolved.map(child => isSelf(child) ? this : child);
|
|
93
113
|
}
|
|
94
114
|
return this._resolvedChildren;
|
|
95
115
|
}
|
|
@@ -103,11 +123,10 @@ export class TreeNodePrimitive<
|
|
|
103
123
|
/** Creates a new TreeNodePrimitive with the given type and config */
|
|
104
124
|
export const TreeNode = <
|
|
105
125
|
TType extends string,
|
|
106
|
-
TData extends StructPrimitive<any
|
|
107
|
-
TChildren extends readonly AnyTreeNodePrimitive[] | (() => readonly AnyTreeNodePrimitive[])
|
|
126
|
+
TData extends StructPrimitive<any>
|
|
108
127
|
>(
|
|
109
128
|
type: TType,
|
|
110
|
-
config: TreeNodeConfig<TData
|
|
111
|
-
): TreeNodePrimitive<TType, TData
|
|
129
|
+
config: TreeNodeConfig<TData>
|
|
130
|
+
): TreeNodePrimitive<TType, TData> =>
|
|
112
131
|
new TreeNodePrimitive(type, config);
|
|
113
132
|
|