@tari-project/tari-extension-query-builder 0.0.13 → 0.0.15
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/components/query-builder/query-builder.d.ts +4 -0
- package/dist/components/query-builder/query-builder.d.ts.map +1 -1
- package/dist/query-builder/template-reader.d.ts.map +1 -1
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/types.d.ts +7 -0
- package/dist/store/types.d.ts.map +1 -1
- package/dist/tari-extension-query-builder.es.js +27170 -27149
- package/dist/tari-extension-query-builder.umd.js +117 -117
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/components/query-builder/nodes/generic/generic-node.tsx +2 -2
- package/src/components/query-builder/query-builder.tsx +21 -3
- package/src/query-builder/template-reader.ts +2 -5
- package/src/store/store.ts +52 -33
- package/src/store/types.ts +12 -0
- package/src/types.ts +17 -0
package/dist/types.d.ts
CHANGED
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,WAAW,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,WAAW,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,MAAM,IAAI,MAAM,GAAG,MAAM,CAAC;KAC3B;CACF"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tari-project/tari-extension-query-builder",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.15",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/tari-extension-query-builder.umd.js",
|
|
7
7
|
"module": "dist/tari-extension-query-builder.es.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@radix-ui/react-separator": "^1.1.2",
|
|
38
38
|
"@radix-ui/react-slot": "^1.1.2",
|
|
39
39
|
"@radix-ui/react-tooltip": "^1.1.8",
|
|
40
|
-
"@tari-project/tarijs-all": "^0.
|
|
40
|
+
"@tari-project/tarijs-all": "^0.11.0",
|
|
41
41
|
"@xyflow/react": "^12.4.4",
|
|
42
42
|
"class-variance-authority": "^0.7.1",
|
|
43
43
|
"clsx": "^2.1.1",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"tailwindcss-animate": "^1.0.7",
|
|
49
49
|
"uuid": "^11.1.0",
|
|
50
50
|
"zod": "^3.25.67",
|
|
51
|
-
"@tari-project/tari-extension-common": "^0.0.
|
|
51
|
+
"@tari-project/tari-extension-common": "^0.0.15"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@eslint/js": "^9.21.0",
|
|
55
55
|
"@tailwindcss/vite": "^4.0.12",
|
|
56
|
-
"@tari-project/typescript-bindings": "^1.
|
|
56
|
+
"@tari-project/typescript-bindings": "^1.13.1",
|
|
57
57
|
"@types/node": "^24.0.8",
|
|
58
58
|
"@types/react": "^19.1.8",
|
|
59
59
|
"@types/react-dom": "^19.1.6",
|
|
@@ -114,7 +114,7 @@ function GenericNode(props: NodeProps<GenericNode>) {
|
|
|
114
114
|
|
|
115
115
|
{title && <h3 className="text-center font-bold pt-1 pb-3 border-b">{title}</h3>}
|
|
116
116
|
|
|
117
|
-
{inputs
|
|
117
|
+
{inputs?.length ? (
|
|
118
118
|
<form noValidate>
|
|
119
119
|
{inputs.map((input) => {
|
|
120
120
|
const type = new TariType(input.type);
|
|
@@ -185,7 +185,7 @@ function GenericNode(props: NodeProps<GenericNode>) {
|
|
|
185
185
|
}
|
|
186
186
|
})}
|
|
187
187
|
</form>
|
|
188
|
-
)}
|
|
188
|
+
) : null}
|
|
189
189
|
|
|
190
190
|
{outputType && renderOutputs(outputType, getOutputOffset)}
|
|
191
191
|
</>
|
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
Viewport,
|
|
8
8
|
Panel,
|
|
9
9
|
MiniMap,
|
|
10
|
+
OnEdgesChange,
|
|
11
|
+
OnNodesChange,
|
|
12
|
+
OnConnect,
|
|
10
13
|
} from "@xyflow/react";
|
|
11
14
|
import {
|
|
12
15
|
CALL_NODE_DRAG_DROP_TYPE,
|
|
@@ -94,6 +97,9 @@ export interface QueryBuilderProps {
|
|
|
94
97
|
getTransactionProps?: () => Promise<TransactionProps>;
|
|
95
98
|
executeTransaction?: (transaction: UnsignedTransactionV1) => Promise<void>;
|
|
96
99
|
showGeneratedCode?: (code: string, type: GeneratedCodeType) => Promise<void>;
|
|
100
|
+
onEdgesChange?: OnEdgesChange;
|
|
101
|
+
onNodesChange?: OnNodesChange;
|
|
102
|
+
onConnect?: OnConnect;
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
const nodeTypes = {
|
|
@@ -111,6 +117,9 @@ function Flow({
|
|
|
111
117
|
getTransactionProps,
|
|
112
118
|
executeTransaction,
|
|
113
119
|
showGeneratedCode,
|
|
120
|
+
onEdgesChange: onEdgesChangeCallback,
|
|
121
|
+
onNodesChange: onNodesChangeCallback,
|
|
122
|
+
onConnect: onConnectCallback,
|
|
114
123
|
}: QueryBuilderProps) {
|
|
115
124
|
const {
|
|
116
125
|
nodes,
|
|
@@ -465,9 +474,18 @@ function Flow({
|
|
|
465
474
|
edgeTypes={edgeTypes}
|
|
466
475
|
nodes={nodes}
|
|
467
476
|
edges={edges}
|
|
468
|
-
onNodesChange={
|
|
469
|
-
|
|
470
|
-
|
|
477
|
+
onNodesChange={(change) => {
|
|
478
|
+
onNodesChange(change);
|
|
479
|
+
onNodesChangeCallback?.(change);
|
|
480
|
+
}}
|
|
481
|
+
onEdgesChange={(change) => {
|
|
482
|
+
onEdgesChange(change);
|
|
483
|
+
onEdgesChangeCallback?.(change);
|
|
484
|
+
}}
|
|
485
|
+
onConnect={(connection) => {
|
|
486
|
+
onConnect(connection);
|
|
487
|
+
onConnectCallback?.(connection);
|
|
488
|
+
}}
|
|
471
489
|
onMove={onMove}
|
|
472
490
|
onDragOver={onDragOver}
|
|
473
491
|
onDrop={onDrop}
|
|
@@ -21,11 +21,8 @@ export class TemplateReader {
|
|
|
21
21
|
if (!fn) {
|
|
22
22
|
return null;
|
|
23
23
|
}
|
|
24
|
-
const args = fn.arguments;
|
|
25
|
-
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
const isMethod = args[0].name === "self";
|
|
24
|
+
const args = fn.arguments || [];
|
|
25
|
+
const isMethod = args[0]?.name === "self";
|
|
29
26
|
const inputs = args.map((arg) => {
|
|
30
27
|
if (arg.name === "self") {
|
|
31
28
|
return {
|
package/src/store/store.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
2
|
import { addEdge, applyNodeChanges, applyEdgeChanges } from "@xyflow/react";
|
|
3
3
|
import { v4 as uuidv4 } from "uuid";
|
|
4
|
-
import { CustomNode, InputConnectionType, NodeType, type QueryBuilderState } from "./types";
|
|
4
|
+
import { CustomNode, InputConnectionType, NodeType, type QueryBuilderState, SchemaAndVersion } from "./types";
|
|
5
5
|
import { NODE_ENTRY, NODE_EXIT } from "@/components/query-builder/nodes/generic-node.types";
|
|
6
6
|
import { getSchemaFullPath, latestVersionHandler, versionHandlers } from "./persistence/handlers";
|
|
7
7
|
import { NEW_INPUT_PARAM } from "@/components/query-builder/nodes/input/constants";
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
CALL_NODE_RETURN_TUPLE_2,
|
|
13
13
|
} from "@/components/query-builder/nodes/call-node.types";
|
|
14
14
|
import { TariType } from "@/query-builder/tari-type";
|
|
15
|
+
import { LatestPersistedState } from "@/store/persistence/types.ts";
|
|
15
16
|
|
|
16
17
|
const DROP_NODE_OFFSET_X = 200;
|
|
17
18
|
const DROP_NODE_OFFSET_Y = 50;
|
|
@@ -242,43 +243,30 @@ const useStore = create<QueryBuilderState>((set, get) => ({
|
|
|
242
243
|
}
|
|
243
244
|
},
|
|
244
245
|
saveStateToString: () => {
|
|
246
|
+
const { getState } = get();
|
|
247
|
+
const state = getState();
|
|
248
|
+
return JSON.stringify(state, undefined, 2);
|
|
249
|
+
},
|
|
250
|
+
loadStateFromString: (state) => {
|
|
251
|
+
let parsedState: SchemaAndVersion & LatestPersistedState;
|
|
252
|
+
try {
|
|
253
|
+
parsedState = JSON.parse(state) as SchemaAndVersion & LatestPersistedState;
|
|
254
|
+
} catch (error) {
|
|
255
|
+
throw new Error(`Failed to parse state: ${String(error)}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
set(validateState(parsedState));
|
|
259
|
+
},
|
|
260
|
+
getState: () => {
|
|
245
261
|
const state = get();
|
|
246
262
|
const persistedState = latestVersionHandler.save(state);
|
|
247
|
-
|
|
263
|
+
return {
|
|
248
264
|
$schema: getSchemaFullPath(persistedState.version),
|
|
249
265
|
...persistedState,
|
|
250
266
|
};
|
|
251
|
-
return JSON.stringify(withSchema, undefined, 2);
|
|
252
267
|
},
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const parsedState = JSON.parse(state) as { version?: string } | undefined;
|
|
256
|
-
if (typeof parsedState?.version !== "string") {
|
|
257
|
-
throw new Error("Invalid persisted state: Missing or invalid version.");
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const version = parsedState.version;
|
|
261
|
-
const handler = versionHandlers[version];
|
|
262
|
-
|
|
263
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
264
|
-
if (!handler) {
|
|
265
|
-
throw new Error(`No handler found for version: ${version}`);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const validationResult = handler.load(parsedState);
|
|
269
|
-
|
|
270
|
-
if (validationResult.success) {
|
|
271
|
-
if (version === "1.0") {
|
|
272
|
-
set({ nodes: validationResult.data.nodes, edges: validationResult.data.edges });
|
|
273
|
-
} else {
|
|
274
|
-
throw new Error(`Unsupported version: ${version}`);
|
|
275
|
-
}
|
|
276
|
-
} else {
|
|
277
|
-
throw new Error(`Validation failed: ${validationResult.error.toString()}`);
|
|
278
|
-
}
|
|
279
|
-
} catch (error) {
|
|
280
|
-
throw new Error(`Failed to load state: ${String(error)}`);
|
|
281
|
-
}
|
|
268
|
+
setState: (state) => {
|
|
269
|
+
set(validateState(state));
|
|
282
270
|
},
|
|
283
271
|
isValidInputParamsTitle: (nodeId, title) => {
|
|
284
272
|
if (!title.length || /\s/g.test(title) || !/^[a-zA-Z]/.test(title)) {
|
|
@@ -357,7 +345,7 @@ const useStore = create<QueryBuilderState>((set, get) => ({
|
|
|
357
345
|
}
|
|
358
346
|
},
|
|
359
347
|
isValidInputParamsName: (nodeId, paramId, name) => {
|
|
360
|
-
if (!name.length || /\s/g.test(name) ||
|
|
348
|
+
if (!name.length || /\s/g.test(name) || /^[a-zA-Z]/.test(name)) {
|
|
361
349
|
return false;
|
|
362
350
|
}
|
|
363
351
|
const node = get().getNodeById(nodeId);
|
|
@@ -397,4 +385,35 @@ const useStore = create<QueryBuilderState>((set, get) => ({
|
|
|
397
385
|
},
|
|
398
386
|
}));
|
|
399
387
|
|
|
388
|
+
function validateState(state: (SchemaAndVersion & LatestPersistedState) | undefined) {
|
|
389
|
+
if (typeof state?.version !== "string") {
|
|
390
|
+
throw new Error("Invalid persisted state: Missing or invalid version.");
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
try {
|
|
394
|
+
const version = state.version;
|
|
395
|
+
const handler = versionHandlers[version];
|
|
396
|
+
|
|
397
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
398
|
+
if (!handler) {
|
|
399
|
+
throw new Error(`No handler found for version: ${version}`);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const validationResult = handler.load(state);
|
|
403
|
+
|
|
404
|
+
if (validationResult.success) {
|
|
405
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
406
|
+
if (version === "1.0") {
|
|
407
|
+
return { nodes: validationResult.data.nodes, edges: validationResult.data.edges };
|
|
408
|
+
} else {
|
|
409
|
+
throw new Error(`Unsupported version: ${String(version)}`);
|
|
410
|
+
}
|
|
411
|
+
} else {
|
|
412
|
+
throw new Error(`Validation failed: ${validationResult.error.toString()}`);
|
|
413
|
+
}
|
|
414
|
+
} catch (error) {
|
|
415
|
+
throw new Error(`Failed to load state: ${String(error)}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
400
419
|
export default useStore;
|
package/src/store/types.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
XYPosition,
|
|
10
10
|
} from "@xyflow/react";
|
|
11
11
|
import { SafeParseReturnType } from "zod";
|
|
12
|
+
import { LatestPersistedState } from "@/store/persistence/types.ts";
|
|
12
13
|
|
|
13
14
|
export enum NodeType {
|
|
14
15
|
GenericNode = "genericNode",
|
|
@@ -34,11 +35,13 @@ export interface CallNodeMetadata {
|
|
|
34
35
|
|
|
35
36
|
export type GenericNodeMetadata = CallNodeMetadata;
|
|
36
37
|
export type GenericNodeIcon = "enter" | "rocket" | "home" | "cube" | "check-circled" | "archive" | "component";
|
|
38
|
+
|
|
37
39
|
export enum InputConnectionType {
|
|
38
40
|
None = 0,
|
|
39
41
|
Parameter,
|
|
40
42
|
ComponentAddress,
|
|
41
43
|
}
|
|
44
|
+
|
|
42
45
|
export interface GenericNodeInputType {
|
|
43
46
|
inputConnectionType: InputConnectionType;
|
|
44
47
|
type: Type;
|
|
@@ -46,11 +49,13 @@ export interface GenericNodeInputType {
|
|
|
46
49
|
label?: string;
|
|
47
50
|
validValues?: string[];
|
|
48
51
|
}
|
|
52
|
+
|
|
49
53
|
export interface GenericNodeOutputType {
|
|
50
54
|
type: Type;
|
|
51
55
|
name: string;
|
|
52
56
|
label?: string;
|
|
53
57
|
}
|
|
58
|
+
|
|
54
59
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
55
60
|
export type GenericNodeData = {
|
|
56
61
|
type: GenericNodeType;
|
|
@@ -84,6 +89,11 @@ export type InputParamsNode = Node<InputParamsNodeData, NodeType.InputParamsNode
|
|
|
84
89
|
|
|
85
90
|
export type CustomNode = GenericNode | InputParamsNode;
|
|
86
91
|
|
|
92
|
+
export interface SchemaAndVersion {
|
|
93
|
+
$schema: string;
|
|
94
|
+
version: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
87
97
|
export interface QueryBuilderState {
|
|
88
98
|
readOnly: boolean;
|
|
89
99
|
nodes: CustomNode[];
|
|
@@ -106,6 +116,8 @@ export interface QueryBuilderState {
|
|
|
106
116
|
removeNode: (nodeId: string) => void;
|
|
107
117
|
saveStateToString: () => string;
|
|
108
118
|
loadStateFromString: (state: string) => void;
|
|
119
|
+
setState: (state: SchemaAndVersion & LatestPersistedState) => void;
|
|
120
|
+
getState: () => SchemaAndVersion & LatestPersistedState;
|
|
109
121
|
isValidInputParamsTitle: (nodeId: string, title: string) => boolean;
|
|
110
122
|
updateInputParamsTitle: (nodeId: string, title: string) => void;
|
|
111
123
|
updateInputParamsNode: (nodeId: string, paramId: string, value: SafeParseReturnType<unknown, unknown>) => void;
|
package/src/types.ts
CHANGED
|
@@ -5,3 +5,20 @@ export interface TariFlowNodeDetails {
|
|
|
5
5
|
templateAddress: string;
|
|
6
6
|
functionName: string;
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
// Extend BigInt to support JSON serialization
|
|
10
|
+
declare global {
|
|
11
|
+
interface BigInt {
|
|
12
|
+
toJSON(): string | number;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
BigInt.prototype.toJSON = function () {
|
|
17
|
+
// if the number is too large, return it as a string
|
|
18
|
+
// otherwise return it as a number
|
|
19
|
+
const int = this.valueOf();
|
|
20
|
+
if (int > BigInt(Number.MAX_SAFE_INTEGER) || int < BigInt(Number.MIN_SAFE_INTEGER)) {
|
|
21
|
+
return this.toString();
|
|
22
|
+
}
|
|
23
|
+
return Number(this);
|
|
24
|
+
};
|