@bian-womp/spark-graph 0.1.2 → 0.1.4

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.
@@ -17,7 +17,11 @@ export declare class Registry {
17
17
  private coercions;
18
18
  private asyncCoercions;
19
19
  private enums;
20
- registerType(desc: DataTypeDescriptor): this;
20
+ registerType(desc: DataTypeDescriptor, opts?: {
21
+ withArray?: boolean;
22
+ arrayId?: string;
23
+ arrayPickFirstDefined?: boolean;
24
+ }): this;
21
25
  registerNode<I extends Record<string, string>, O extends Record<string, string>, State = unknown, Impl = (inputs: Record<string, unknown>, ctx: NodeContext<State>) => void | Record<string, unknown> | Promise<void | Record<string, unknown>>>(desc: NodeTypeDescriptor<I, O, State, Impl>): this;
22
26
  registerSerializer(typeId: string, s: {
23
27
  serialize: (value: unknown) => unknown;
@@ -28,6 +32,11 @@ export declare class Registry {
28
32
  canCoerce(fromTypeId: string | undefined, toTypeId: string | undefined): boolean;
29
33
  getCoercion(fromTypeId: string, toTypeId: string): ((value: unknown) => unknown) | undefined;
30
34
  getAsyncCoercion(fromTypeId: string, toTypeId: string): ((value: unknown, signal: AbortSignal) => Promise<unknown>) | undefined;
35
+ listCoercions(): Array<{
36
+ from: string;
37
+ to: string;
38
+ async: boolean;
39
+ }>;
31
40
  registerEnum(enumTypeId: string, options: Array<{
32
41
  value: number;
33
42
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Registry.d.ts","sourceRoot":"","sources":["../../../../src/builder/Registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Registry.d.ts","sourceRoot":"","sources":["../../../../src/builder/Registry.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/examples/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,wBAAgB,uBAAuB,IAAI,QAAQ,CA4ZlD;AAED,wBAAgB,wBAAwB,IAAI,eAAe,CAc1D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,QA2BnD;AAqBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,QAyBvD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,6BAUrE"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../../src/examples/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,wBAAgB,uBAAuB,IAAI,QAAQ,CAwYlD;AAED,wBAAgB,wBAAwB,IAAI,eAAe,CAc1D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,QA2BnD;AAqBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,QA6BvD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,6BAUrE"}
package/lib/esm/index.js CHANGED
@@ -23,8 +23,44 @@ class Registry {
23
23
  this.asyncCoercions = new Map();
24
24
  this.enums = new Map();
25
25
  }
26
- registerType(desc) {
26
+ registerType(desc, opts) {
27
27
  this.types.set(desc.id, desc);
28
+ if (!this.serializers.has(desc.id)) {
29
+ this.registerSerializer(desc.id, {
30
+ serialize: (v) => v,
31
+ deserialize: (d) => d,
32
+ });
33
+ }
34
+ if (opts?.withArray) {
35
+ const arrayId = opts.arrayId ?? `${desc.id}[]`;
36
+ if (!this.types.has(arrayId)) {
37
+ const arrayDesc = {
38
+ id: arrayId,
39
+ validate: (v) => Array.isArray(v) &&
40
+ v.every((x) => {
41
+ try {
42
+ return desc.validate(x);
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }),
48
+ };
49
+ this.types.set(arrayId, arrayDesc);
50
+ }
51
+ this.registerCoercion(desc.id, arrayId, (value) => Array.isArray(value) ? value : [value]);
52
+ this.registerCoercion(arrayId, desc.id, (value) => {
53
+ if (!Array.isArray(value))
54
+ return value;
55
+ if (opts.arrayPickFirstDefined) {
56
+ for (const x of value)
57
+ if (x !== undefined)
58
+ return x;
59
+ return undefined;
60
+ }
61
+ return value[0];
62
+ });
63
+ }
28
64
  return this;
29
65
  }
30
66
  registerNode(desc) {
@@ -33,6 +69,15 @@ class Registry {
33
69
  }
34
70
  registerSerializer(typeId, s) {
35
71
  this.serializers.set(typeId, s);
72
+ // If an array variant of this type exists and doesn't have a serializer,
73
+ // auto-register an array serializer that maps each element using the base serializer.
74
+ const arrayId = `${typeId}[]`;
75
+ if (this.types.has(arrayId) && !this.serializers.has(arrayId)) {
76
+ this.serializers.set(arrayId, {
77
+ serialize: (value) => Array.isArray(value) ? value.map((el) => s.serialize(el)) : value,
78
+ deserialize: (data) => Array.isArray(data) ? data.map((el) => s.deserialize(el)) : data,
79
+ });
80
+ }
36
81
  return this;
37
82
  }
38
83
  // Register a type coercion from one type id to another
@@ -63,6 +108,19 @@ class Registry {
63
108
  return undefined;
64
109
  return this.asyncCoercions.get(`${fromTypeId}->${toTypeId}`);
65
110
  }
111
+ // Introspection for dynamic discovery
112
+ listCoercions() {
113
+ const out = [];
114
+ for (const key of this.coercions.keys()) {
115
+ const [from, to] = key.split("->");
116
+ out.push({ from, to, async: false });
117
+ }
118
+ for (const key of this.asyncCoercions.keys()) {
119
+ const [from, to] = key.split("->");
120
+ out.push({ from, to, async: true });
121
+ }
122
+ return out;
123
+ }
66
124
  // Enum support
67
125
  registerEnum(enumTypeId, options, labelType, valueType) {
68
126
  const valueToLabel = new Map();
@@ -1280,53 +1338,30 @@ function setupBasicGraphRegistry() {
1280
1338
  const registry = new Registry();
1281
1339
  registry.categories.register(ComputeCategory);
1282
1340
  const floatType = {
1283
- id: "float",
1341
+ id: "base.float",
1284
1342
  validate: (v) => typeof v === "number" && !Number.isNaN(v),
1285
1343
  };
1286
1344
  registry.registerType(floatType);
1287
- registry.registerSerializer("float", {
1345
+ registry.registerSerializer("base.float", {
1288
1346
  serialize: (v) => v,
1289
1347
  deserialize: (d) => Number(d),
1290
1348
  });
1291
1349
  const boolType = {
1292
- id: "bool",
1350
+ id: "base.bool",
1293
1351
  validate: (v) => typeof v === "boolean",
1294
1352
  };
1295
1353
  const stringType = {
1296
- id: "string",
1354
+ id: "base.string",
1297
1355
  validate: (v) => typeof v === "string",
1298
1356
  };
1299
1357
  const vec3Type = {
1300
- id: "vec3",
1358
+ id: "base.vec3",
1301
1359
  validate: (v) => Array.isArray(v) &&
1302
1360
  v.length === 3 &&
1303
1361
  v.every((x) => typeof x === "number"),
1304
1362
  };
1305
- const floatArrayType = {
1306
- id: "float[]",
1307
- validate: (v) => Array.isArray(v) && v.every((x) => typeof x === "number"),
1308
- };
1309
- const boolArrayType = {
1310
- id: "bool[]",
1311
- validate: (v) => Array.isArray(v) && v.every((x) => typeof x === "boolean"),
1312
- };
1313
- const vec3ArrayType = {
1314
- id: "vec3[]",
1315
- validate: (v) => Array.isArray(v) &&
1316
- v.every((x) => Array.isArray(x) &&
1317
- x.length === 3 &&
1318
- x.every((n) => typeof n === "number")),
1319
- };
1320
- [
1321
- boolType,
1322
- stringType,
1323
- vec3Type,
1324
- floatType,
1325
- floatArrayType,
1326
- boolArrayType,
1327
- vec3ArrayType,
1328
- ].forEach((t) => {
1329
- registry.registerType(t);
1363
+ [boolType, stringType, vec3Type, floatType].forEach((t) => {
1364
+ registry.registerType(t, { withArray: true, arrayPickFirstDefined: true });
1330
1365
  registry.registerSerializer(t.id, {
1331
1366
  serialize: (v) => v,
1332
1367
  deserialize: (d) => d,
@@ -1334,23 +1369,13 @@ function setupBasicGraphRegistry() {
1334
1369
  });
1335
1370
  // Helpers
1336
1371
  const asArray = (v) => Array.isArray(v) ? v : [Number(v)];
1337
- // Register core coercions: float <-> float[]
1338
- registry.registerCoercion("float", "float[]", (v) => Array.isArray(v) ? v : [Number(v)]);
1339
- registry.registerCoercion("float[]", "float", (v) => Array.isArray(v) ? Number(v[0] ?? 0) : Number(v));
1340
1372
  // float[] -> vec3[] : map x to [x,0,0]
1341
- registry.registerCoercion("float[]", "vec3[]", (v) => {
1373
+ registry.registerCoercion("base.float[]", "base.vec3[]", (v) => {
1342
1374
  const arr = asArray(v);
1343
1375
  return arr.map((x) => [Number(x) || 0, 0, 0]);
1344
1376
  });
1345
- // Example async coercion: simulate expensive conversion float[] -> vec3[] by computing magnitudes
1346
- registry.registerCoercion("float[]", "vec3[]", (v) => {
1347
- // synchronous fallback; async version can be provided on edge via convertAsync
1348
- if (!Array.isArray(v))
1349
- return [];
1350
- return v.map((t) => Math.hypot(Number(t?.[0] ?? 0), Number(t?.[1] ?? 0), Number(t?.[2] ?? 0)));
1351
- });
1352
1377
  // Async coercion variant for vec3[] -> float[] (chunked + abortable)
1353
- registry.registerAsyncCoercion("vec3[]", "float[]", async (value, signal) => {
1378
+ registry.registerAsyncCoercion("base.vec3[]", "base.float[]", async (value, signal) => {
1354
1379
  const arr = Array.isArray(value)
1355
1380
  ? value
1356
1381
  : [];
@@ -1384,32 +1409,32 @@ function setupBasicGraphRegistry() {
1384
1409
  };
1385
1410
  // Number
1386
1411
  registry.registerNode({
1387
- id: "number",
1412
+ id: "base.number",
1388
1413
  categoryId: "compute",
1389
- inputs: { Value: "float" },
1390
- outputs: { Result: "float" },
1414
+ inputs: { Value: "base.float" },
1415
+ outputs: { Result: "base.float" },
1391
1416
  impl: (ins) => ({ Result: Number(ins.Value) }),
1392
1417
  });
1393
1418
  // Integer
1394
1419
  registry.registerNode({
1395
- id: "integer",
1420
+ id: "base.int",
1396
1421
  categoryId: "compute",
1397
- inputs: { Value: "float" },
1398
- outputs: { Result: "float" },
1422
+ inputs: { Value: "base.float" },
1423
+ outputs: { Result: "base.float" },
1399
1424
  impl: (ins) => ({
1400
1425
  Result: Math.trunc(Number(ins.Value)),
1401
1426
  }),
1402
1427
  });
1403
1428
  // Number to String
1404
1429
  registry.registerNode({
1405
- id: "numberToString",
1430
+ id: "base.numberToString",
1406
1431
  categoryId: "compute",
1407
- inputs: { Value: "float" },
1408
- outputs: { Text: "string" },
1432
+ inputs: { Value: "base.float" },
1433
+ outputs: { Text: "base.string" },
1409
1434
  impl: (ins) => ({ Text: String(ins.Value) }),
1410
1435
  });
1411
1436
  // Enums: Math Operation
1412
- registry.registerEnum("enum:math.operation", [
1437
+ registry.registerEnum("base.enum:math.operation", [
1413
1438
  { value: 0, label: "Add" },
1414
1439
  { value: 1, label: "Subtract" },
1415
1440
  { value: 2, label: "Multiply" },
@@ -1418,22 +1443,22 @@ function setupBasicGraphRegistry() {
1418
1443
  { value: 5, label: "Max" },
1419
1444
  { value: 6, label: "Modulo" },
1420
1445
  { value: 7, label: "Power" },
1421
- ], "string", "float");
1446
+ ], "base.string", "base.float");
1422
1447
  // Enums: Compare Operation
1423
- registry.registerEnum("enum:compare.operation", [
1448
+ registry.registerEnum("base.enum:compare.operation", [
1424
1449
  { value: 0, label: "LessThan" },
1425
1450
  { value: 1, label: "LessThanOrEqual" },
1426
1451
  { value: 2, label: "GreaterThan" },
1427
1452
  { value: 3, label: "GreaterThanOrEqual" },
1428
1453
  { value: 4, label: "Equal" },
1429
1454
  { value: 5, label: "NotEqual" },
1430
- ], "string", "float");
1455
+ ], "base.string", "base.float");
1431
1456
  // Clamp
1432
1457
  registry.registerNode({
1433
- id: "clamp",
1458
+ id: "base.clamp",
1434
1459
  categoryId: "compute",
1435
- inputs: { Value: "float[]", Min: "float", Max: "float" },
1436
- outputs: { Value: "float[]" },
1460
+ inputs: { Value: "base.float[]", Min: "base.float", Max: "base.float" },
1461
+ outputs: { Value: "base.float[]" },
1437
1462
  impl: (ins) => {
1438
1463
  const vals = asArray(ins.Value);
1439
1464
  const min = Number(ins.Min ?? 0);
@@ -1443,10 +1468,14 @@ function setupBasicGraphRegistry() {
1443
1468
  });
1444
1469
  // Interpolate (lerp)
1445
1470
  registry.registerNode({
1446
- id: "interpolate",
1471
+ id: "base.interpolate",
1447
1472
  categoryId: "compute",
1448
- inputs: { ValueA: "float[]", ValueB: "float[]", Factor: "float" },
1449
- outputs: { Value: "float[]" },
1473
+ inputs: {
1474
+ ValueA: "base.float[]",
1475
+ ValueB: "base.float[]",
1476
+ Factor: "base.float",
1477
+ },
1478
+ outputs: { Value: "base.float[]" },
1450
1479
  impl: (ins) => {
1451
1480
  const [a, b] = broadcast(ins.ValueA, ins.ValueB);
1452
1481
  const t = Number(ins.Factor ?? 0);
@@ -1459,18 +1488,18 @@ function setupBasicGraphRegistry() {
1459
1488
  });
1460
1489
  // Map Range (linear)
1461
1490
  registry.registerNode({
1462
- id: "mapRange",
1491
+ id: "base.mapRange",
1463
1492
  categoryId: "compute",
1464
1493
  inputs: {
1465
- Mode: "string",
1466
- Clamp: "bool",
1467
- Value: "float[]",
1468
- FromMin: "float",
1469
- FromMax: "float",
1470
- ToMin: "float",
1471
- ToMax: "float",
1494
+ Mode: "base.string",
1495
+ Clamp: "base.bool",
1496
+ Value: "base.float[]",
1497
+ FromMin: "base.float",
1498
+ FromMax: "base.float",
1499
+ ToMin: "base.float",
1500
+ ToMax: "base.float",
1472
1501
  },
1473
- outputs: { Value: "float[]" },
1502
+ outputs: { Value: "base.float[]" },
1474
1503
  impl: (ins) => {
1475
1504
  const vals = asArray(ins.Value);
1476
1505
  const fromMin = Number(ins.FromMin ?? 0);
@@ -1490,10 +1519,14 @@ function setupBasicGraphRegistry() {
1490
1519
  });
1491
1520
  // Math (subset) - scalar version for simple examples
1492
1521
  registry.registerNode({
1493
- id: "math",
1522
+ id: "base.math",
1494
1523
  categoryId: "compute",
1495
- inputs: { Operation: "enum:math.operation", A: "float[]", B: "float[]" },
1496
- outputs: { Result: "float[]" },
1524
+ inputs: {
1525
+ Operation: "base.enum:math.operation",
1526
+ A: "base.float[]",
1527
+ B: "base.float[]",
1528
+ },
1529
+ outputs: { Result: "base.float[]" },
1497
1530
  impl: (ins) => {
1498
1531
  // Gracefully handle missing inputs by treating them as zeros
1499
1532
  const a = ins.A === undefined ? [] : asArray(ins.A);
@@ -1521,10 +1554,14 @@ function setupBasicGraphRegistry() {
1521
1554
  });
1522
1555
  // Compare
1523
1556
  registry.registerNode({
1524
- id: "compare",
1557
+ id: "base.compare",
1525
1558
  categoryId: "compute",
1526
- inputs: { Operation: "enum:compare.operation", A: "float[]", B: "float[]" },
1527
- outputs: { Result: "bool[]" },
1559
+ inputs: {
1560
+ Operation: "base.enum:compare.operation",
1561
+ A: "base.float[]",
1562
+ B: "base.float[]",
1563
+ },
1564
+ outputs: { Result: "base.bool[]" },
1528
1565
  impl: (ins) => {
1529
1566
  const [a, b] = broadcast(ins.A, ins.B);
1530
1567
  const op = Number(ins.Operation ?? 4) | 0; // default Equal
@@ -1542,10 +1579,10 @@ function setupBasicGraphRegistry() {
1542
1579
  });
1543
1580
  // Combine XYZ
1544
1581
  registry.registerNode({
1545
- id: "combineXYZ",
1582
+ id: "base.compareXYZ",
1546
1583
  categoryId: "compute",
1547
- inputs: { X: "float[]", Y: "float[]", Z: "float[]" },
1548
- outputs: { XYZ: "vec3[]" },
1584
+ inputs: { X: "base.float[]", Y: "base.float[]", Z: "base.float[]" },
1585
+ outputs: { XYZ: "base.vec3[]" },
1549
1586
  impl: (ins) => {
1550
1587
  const [x, y] = broadcast(ins.X, ins.Y);
1551
1588
  const [xx, z] = broadcast(x, ins.Z);
@@ -1558,10 +1595,10 @@ function setupBasicGraphRegistry() {
1558
1595
  });
1559
1596
  // Separate XYZ
1560
1597
  registry.registerNode({
1561
- id: "separateXYZ",
1598
+ id: "base.separateXYZ",
1562
1599
  categoryId: "compute",
1563
- inputs: { XYZ: "vec3[]" },
1564
- outputs: { X: "float[]", Y: "float[]", Z: "float[]" },
1600
+ inputs: { XYZ: "base.vec3[]" },
1601
+ outputs: { X: "base.float[]", Y: "base.float[]", Z: "base.float[]" },
1565
1602
  impl: (ins) => {
1566
1603
  const arr = ins.XYZ ?? [];
1567
1604
  const X = arr.map((v) => Number(v?.[0] ?? 0));
@@ -1572,10 +1609,10 @@ function setupBasicGraphRegistry() {
1572
1609
  });
1573
1610
  // Indices
1574
1611
  registry.registerNode({
1575
- id: "indices",
1612
+ id: "base.indices",
1576
1613
  categoryId: "compute",
1577
- inputs: { Domain: "float" },
1578
- outputs: { Indices: "float[]" },
1614
+ inputs: { Domain: "base.float" },
1615
+ outputs: { Indices: "base.float[]" },
1579
1616
  impl: (ins) => {
1580
1617
  const n = Math.trunc(ins.Domain);
1581
1618
  return { Indices: Array.from({ length: n }, (_, i) => i) };
@@ -1583,10 +1620,15 @@ function setupBasicGraphRegistry() {
1583
1620
  });
1584
1621
  // Random Numbers
1585
1622
  registry.registerNode({
1586
- id: "randomNumbers",
1623
+ id: "base.randomNumbers",
1587
1624
  categoryId: "compute",
1588
- inputs: { Domain: "float", Min: "float", Max: "float", Seed: "float" },
1589
- outputs: { Values: "float[]" },
1625
+ inputs: {
1626
+ Domain: "base.float",
1627
+ Min: "base.float",
1628
+ Max: "base.float",
1629
+ Seed: "base.float",
1630
+ },
1631
+ outputs: { Values: "base.float[]" },
1590
1632
  impl: (ins) => {
1591
1633
  const len = Math.trunc(ins.Domain);
1592
1634
  const min = Number(ins.Min ?? 0);
@@ -1598,10 +1640,15 @@ function setupBasicGraphRegistry() {
1598
1640
  });
1599
1641
  // Random Vectors
1600
1642
  registry.registerNode({
1601
- id: "randomVectors",
1643
+ id: "base.randomXYZs",
1602
1644
  categoryId: "compute",
1603
- inputs: { Domain: "float", Min: "vec3", Max: "vec3", Seed: "float" },
1604
- outputs: { Values: "vec3[]" },
1645
+ inputs: {
1646
+ Domain: "base.float",
1647
+ Min: "base.vec3",
1648
+ Max: "base.vec3",
1649
+ Seed: "base.float",
1650
+ },
1651
+ outputs: { Values: "base.vec3[]" },
1605
1652
  impl: (ins) => {
1606
1653
  const len = Math.trunc(ins.Domain);
1607
1654
  const min = ins.Min ?? [0, 0, 0];
@@ -1620,8 +1667,8 @@ function setupBasicGraphRegistry() {
1620
1667
  function makeBasicGraphDefinition() {
1621
1668
  return {
1622
1669
  nodes: [
1623
- { nodeId: "n1", typeId: "math" },
1624
- { nodeId: "n2", typeId: "math" },
1670
+ { nodeId: "n1", typeId: "base.math" },
1671
+ { nodeId: "n2", typeId: "base.math" },
1625
1672
  ],
1626
1673
  edges: [
1627
1674
  {
@@ -1634,10 +1681,10 @@ function makeBasicGraphDefinition() {
1634
1681
  }
1635
1682
  function registerDelayNode(registry) {
1636
1683
  registry.registerNode({
1637
- id: "delay",
1684
+ id: "async.delay",
1638
1685
  categoryId: "compute",
1639
- inputs: { x: "float", ms: "float" },
1640
- outputs: { out: "float" },
1686
+ inputs: { x: "base.float", ms: "base.float" },
1687
+ outputs: { out: "base.float" },
1641
1688
  impl: async (ins, ctx) => {
1642
1689
  const ms = Number(ins.ms ?? 200);
1643
1690
  const xRaw = ins.x;
@@ -1679,10 +1726,14 @@ function sleepWithAbort(ms, signal) {
1679
1726
  }
1680
1727
  function registerProgressNodes(registry) {
1681
1728
  registry.registerNode({
1682
- id: "progressWorker",
1729
+ id: "async.progress",
1683
1730
  categoryId: "compute",
1684
- inputs: { Steps: "float", DelayMs: "float", ShouldError: "bool" },
1685
- outputs: { Done: "string" },
1731
+ inputs: {
1732
+ Steps: "base.float",
1733
+ DelayMs: "base.float",
1734
+ ShouldError: "base.bool",
1735
+ },
1736
+ outputs: { Done: "base.string" },
1686
1737
  impl: async (ins, ctx) => {
1687
1738
  const steps = Math.max(1, Math.trunc(Number(ins.Steps ?? 10)));
1688
1739
  const delayMs = Math.max(0, Math.trunc(Number(ins.DelayMs ?? 50)));
@@ -1713,20 +1764,20 @@ function createAsyncGraphDef() {
1713
1764
  nodes: [
1714
1765
  {
1715
1766
  nodeId: "n1",
1716
- typeId: "math",
1767
+ typeId: "base.math",
1717
1768
  },
1718
1769
  {
1719
1770
  nodeId: "n2",
1720
- typeId: "delay",
1771
+ typeId: "async.delay",
1721
1772
  params: { policy: { asyncConcurrency: "queue", maxQueue: 4 } },
1722
1773
  },
1723
1774
  {
1724
1775
  nodeId: "n3",
1725
- typeId: "separateXYZ",
1776
+ typeId: "base.separateXYZ",
1726
1777
  },
1727
1778
  {
1728
1779
  nodeId: "n4",
1729
- typeId: "combineXYZ",
1780
+ typeId: "base.compareXYZ",
1730
1781
  },
1731
1782
  ],
1732
1783
  edges: [
@@ -1740,7 +1791,7 @@ function createAsyncGraphDef() {
1740
1791
  id: "e2",
1741
1792
  source: { nodeId: "n4", handle: "XYZ" },
1742
1793
  target: { nodeId: "n1", handle: "A" },
1743
- typeId: "vec3[]",
1794
+ typeId: "base.vec3[]",
1744
1795
  // convertAsync,
1745
1796
  },
1746
1797
  {
@@ -1771,9 +1822,9 @@ function createAsyncGraphRegistry() {
1771
1822
  function createProgressGraphDef() {
1772
1823
  const def = {
1773
1824
  nodes: [
1774
- { nodeId: "steps", typeId: "number" },
1775
- { nodeId: "delay", typeId: "number" },
1776
- { nodeId: "work", typeId: "progressWorker" },
1825
+ { nodeId: "steps", typeId: "base.number" },
1826
+ { nodeId: "async.delay", typeId: "base.number" },
1827
+ { nodeId: "work", typeId: "async.progress" },
1777
1828
  ],
1778
1829
  edges: [
1779
1830
  {
@@ -1783,7 +1834,7 @@ function createProgressGraphDef() {
1783
1834
  },
1784
1835
  {
1785
1836
  id: "e2",
1786
- source: { nodeId: "delay", handle: "Result" },
1837
+ source: { nodeId: "async.delay", handle: "Result" },
1787
1838
  target: { nodeId: "work", handle: "DelayMs" },
1788
1839
  },
1789
1840
  // not wiring ShouldError to show manual input driven error later
@@ -1804,11 +1855,11 @@ function createValidationGraphDef() {
1804
1855
  // - Multi inbound to same input
1805
1856
  const def = {
1806
1857
  nodes: [
1807
- { nodeId: "nA", typeId: "number" },
1808
- { nodeId: "nB", typeId: "number" },
1809
- { nodeId: "nC", typeId: "math" },
1810
- { nodeId: "s1", typeId: "numberToString" },
1811
- { nodeId: "cmp", typeId: "compare" },
1858
+ { nodeId: "nA", typeId: "base.number" },
1859
+ { nodeId: "nB", typeId: "base.number" },
1860
+ { nodeId: "nC", typeId: "base.math" },
1861
+ { nodeId: "s1", typeId: "base.numberToString" },
1862
+ { nodeId: "cmp", typeId: "base.compare" },
1812
1863
  // Global validation issue: unknown node type (no nodeId/edgeId in data)
1813
1864
  { nodeId: "bad", typeId: "unknownType" },
1814
1865
  ],