@bian-womp/spark-graph 0.1.21 → 0.1.22

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.
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/misc/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,eAAe,CAAC;AA0CvB,wBAAgB,uBAAuB,IAAI,QAAQ,CA4elD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,QA+BnD;AAqBD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,QA6BvD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,6BAUrE"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/misc/base.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,eAAe,CAAC;AA2HvB,wBAAgB,uBAAuB,IAAI,QAAQ,CAyqBlD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,QA+BnD;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
@@ -1784,6 +1784,96 @@ const lcg = (seed) => {
1784
1784
  let s = seed >>> 0 || 1;
1785
1785
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 0xffffffff;
1786
1786
  };
1787
+ // JSON Pointer helpers (RFC 6901 subset)
1788
+ function jsonPointerGet(obj, pointer) {
1789
+ if (!pointer || pointer === "/")
1790
+ return obj;
1791
+ if (!pointer.startsWith("/"))
1792
+ return undefined;
1793
+ const parts = pointer
1794
+ .split("/")
1795
+ .slice(1)
1796
+ .map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
1797
+ let cur = obj;
1798
+ for (const key of parts) {
1799
+ if (cur === undefined || cur === null)
1800
+ return undefined;
1801
+ cur = cur[key];
1802
+ }
1803
+ return cur;
1804
+ }
1805
+ function jsonPointerSet(obj, pointer, value) {
1806
+ if (!pointer || pointer === "/")
1807
+ return value;
1808
+ if (!pointer.startsWith("/"))
1809
+ return obj;
1810
+ const parts = pointer
1811
+ .split("/")
1812
+ .slice(1)
1813
+ .map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
1814
+ const root = structuredClone(obj);
1815
+ let cur = root;
1816
+ for (let i = 0; i < parts.length; i++) {
1817
+ const key = parts[i];
1818
+ if (i === parts.length - 1) {
1819
+ if (Array.isArray(cur) && key === "-")
1820
+ cur.push(value);
1821
+ else
1822
+ cur[key] = value;
1823
+ }
1824
+ else {
1825
+ const next = cur[key];
1826
+ if (next === undefined || next === null) {
1827
+ // create container heuristically
1828
+ const nextKey = parts[i + 1];
1829
+ cur[key] =
1830
+ typeof nextKey === "string" && /^[0-9]+$/.test(nextKey) ? [] : {};
1831
+ }
1832
+ cur = cur[key];
1833
+ }
1834
+ }
1835
+ return root;
1836
+ }
1837
+ function jsonPointerRemove(obj, pointer) {
1838
+ if (!pointer || pointer === "/")
1839
+ return undefined;
1840
+ if (!pointer.startsWith("/"))
1841
+ return obj;
1842
+ const parts = pointer
1843
+ .split("/")
1844
+ .slice(1)
1845
+ .map((p) => p.replace(/~1/g, "/").replace(/~0/g, "~"));
1846
+ const root = structuredClone(obj);
1847
+ let cur = root;
1848
+ for (let i = 0; i < parts.length - 1; i++) {
1849
+ const key = parts[i];
1850
+ if (cur === undefined || cur === null)
1851
+ return root;
1852
+ cur = cur[key];
1853
+ }
1854
+ const last = parts[parts.length - 1];
1855
+ if (Array.isArray(cur)) {
1856
+ const idx = last === "-" ? cur.length - 1 : Number(last);
1857
+ if (Number.isFinite(idx))
1858
+ cur.splice(idx, 1);
1859
+ }
1860
+ else if (cur && typeof cur === "object") {
1861
+ delete cur[last];
1862
+ }
1863
+ return root;
1864
+ }
1865
+ function deepMerge(a, b) {
1866
+ if (Array.isArray(a) && Array.isArray(b))
1867
+ return [...a, ...b];
1868
+ if (isPlainObject(a) && isPlainObject(b)) {
1869
+ const out = { ...a };
1870
+ for (const [k, v] of Object.entries(b)) {
1871
+ out[k] = k in out ? deepMerge(out[k], v) : v;
1872
+ }
1873
+ return out;
1874
+ }
1875
+ return b;
1876
+ }
1787
1877
  // JSON helpers
1788
1878
  const isPlainObject = (v) => {
1789
1879
  if (v === null || typeof v !== "object")
@@ -1822,7 +1912,7 @@ function setupBasicGraphRegistry() {
1822
1912
  registry.registerType({
1823
1913
  id: "base.object",
1824
1914
  validate: (v) => isJson(v),
1825
- }, { withArray: true, arrayPickFirstDefined: true });
1915
+ }, { withArray: false });
1826
1916
  registry.registerType({
1827
1917
  id: "base.vec3",
1828
1918
  validate: (v) => Array.isArray(v) &&
@@ -2215,6 +2305,195 @@ function setupBasicGraphRegistry() {
2215
2305
  },
2216
2306
  },
2217
2307
  });
2308
+ // ------------------------- JSON/object utilities -------------------------
2309
+ registry.registerNode({
2310
+ id: "base.objectGet",
2311
+ categoryId: "compute",
2312
+ inputs: { Object: "base.object", Pointers: "base.string[]" },
2313
+ outputs: { Values: "base.object" },
2314
+ impl: (ins) => {
2315
+ const obj = ins.Object;
2316
+ const pointers = (ins.Pointers || []).map(String);
2317
+ const out = {};
2318
+ for (const p of pointers)
2319
+ out[p] = jsonPointerGet(obj, p);
2320
+ return { Values: out };
2321
+ },
2322
+ });
2323
+ registry.registerNode({
2324
+ id: "base.objectSet",
2325
+ categoryId: "compute",
2326
+ inputs: {
2327
+ Object: "base.object",
2328
+ Pointers: "base.string[]",
2329
+ NewValues: "base.string[]",
2330
+ },
2331
+ outputs: { Result: "base.object" },
2332
+ impl: (ins) => {
2333
+ const pointers = (ins.Pointers || []).map(String);
2334
+ const values = (ins.NewValues || []).map(String);
2335
+ let cur = structuredClone(ins.Object);
2336
+ for (let i = 0; i < pointers.length; i++) {
2337
+ const p = pointers[i];
2338
+ const raw = values[i];
2339
+ let val = raw;
2340
+ if (typeof raw === "string") {
2341
+ try {
2342
+ val = JSON.parse(raw);
2343
+ }
2344
+ catch {
2345
+ /* keep as string */
2346
+ }
2347
+ }
2348
+ cur = jsonPointerSet(cur, p, val);
2349
+ }
2350
+ return { Result: cur };
2351
+ },
2352
+ });
2353
+ registry.registerNode({
2354
+ id: "base.objectRemove",
2355
+ categoryId: "compute",
2356
+ inputs: { Object: "base.object", Pointers: "base.string[]" },
2357
+ outputs: { Result: "base.object" },
2358
+ impl: (ins) => {
2359
+ const pointers = (ins.Pointers || []).map(String);
2360
+ let cur = structuredClone(ins.Object);
2361
+ for (const p of pointers)
2362
+ cur = jsonPointerRemove(cur, p);
2363
+ return { Result: cur };
2364
+ },
2365
+ });
2366
+ registry.registerNode({
2367
+ id: "base.objectMerge",
2368
+ categoryId: "compute",
2369
+ inputs: { A: "base.object", B: "base.object" },
2370
+ outputs: { Result: "base.object" },
2371
+ impl: (ins) => ({
2372
+ Result: deepMerge(ins.A, ins.B),
2373
+ }),
2374
+ });
2375
+ registry.registerNode({
2376
+ id: "base.objectKeys",
2377
+ categoryId: "compute",
2378
+ inputs: { Object: "base.object" },
2379
+ outputs: { Keys: "base.string[]" },
2380
+ impl: (ins) => {
2381
+ const obj = ins.Object;
2382
+ const keys = isPlainObject(obj)
2383
+ ? Object.keys(obj)
2384
+ : Array.isArray(obj)
2385
+ ? Object.keys(obj)
2386
+ : [];
2387
+ return { Keys: keys };
2388
+ },
2389
+ });
2390
+ registry.registerNode({
2391
+ id: "base.objectValues",
2392
+ categoryId: "compute",
2393
+ inputs: { Object: "base.object" },
2394
+ outputs: { Values: "base.object" },
2395
+ impl: (ins) => {
2396
+ const obj = ins.Object;
2397
+ const vals = isPlainObject(obj)
2398
+ ? Object.values(obj)
2399
+ : Array.isArray(obj)
2400
+ ? Object.values(obj)
2401
+ : [];
2402
+ return { Values: vals };
2403
+ },
2404
+ });
2405
+ registry.registerNode({
2406
+ id: "base.objectPatch",
2407
+ categoryId: "compute",
2408
+ inputs: { Object: "base.object", Ops: "base.object" },
2409
+ outputs: { Result: "base.object" },
2410
+ impl: (ins) => {
2411
+ const root = structuredClone(ins.Object);
2412
+ const opsRaw = ins.Ops;
2413
+ const ops = Array.isArray(opsRaw)
2414
+ ? opsRaw
2415
+ : opsRaw
2416
+ ? [opsRaw]
2417
+ : [];
2418
+ let cur = root;
2419
+ for (const op of ops) {
2420
+ if (!op || typeof op !== "object")
2421
+ continue;
2422
+ const kind = String(op.op || "");
2423
+ const path = String(op.path || "");
2424
+ if (kind === "add" || kind === "replace") {
2425
+ cur = jsonPointerSet(cur, path, op.value);
2426
+ }
2427
+ else if (kind === "remove") {
2428
+ cur = jsonPointerRemove(cur, path);
2429
+ }
2430
+ else if (kind === "test") {
2431
+ const got = jsonPointerGet(cur, path);
2432
+ const expected = op.value;
2433
+ const ok = JSON.stringify(got) === JSON.stringify(expected);
2434
+ if (!ok)
2435
+ throw new Error(`objectPatch test failed at ${path}`);
2436
+ }
2437
+ }
2438
+ return { Result: cur };
2439
+ },
2440
+ });
2441
+ registry.registerNode({
2442
+ id: "base.arrayConcat",
2443
+ categoryId: "compute",
2444
+ inputs: { A: "base.object", B: "base.object" },
2445
+ outputs: { Result: "base.object" },
2446
+ impl: (ins) => {
2447
+ const a = Array.isArray(ins.A) ? ins.A : [];
2448
+ const b = Array.isArray(ins.B) ? ins.B : [];
2449
+ return { Result: [...a, ...b] };
2450
+ },
2451
+ });
2452
+ registry.registerNode({
2453
+ id: "base.arrayFlatten",
2454
+ categoryId: "compute",
2455
+ inputs: { Objects: "base.object" },
2456
+ outputs: { Result: "base.object" },
2457
+ impl: (ins) => {
2458
+ const arr = Array.isArray(ins.Objects) ? ins.Objects : [];
2459
+ const out = [];
2460
+ for (const v of arr) {
2461
+ if (Array.isArray(v))
2462
+ out.push(...v);
2463
+ else
2464
+ out.push(v);
2465
+ }
2466
+ return { Result: out };
2467
+ },
2468
+ });
2469
+ registry.registerNode({
2470
+ id: "base.arraySortBy",
2471
+ categoryId: "compute",
2472
+ inputs: { Objects: "base.object", Pointers: "base.string[]" },
2473
+ outputs: { Result: "base.object" },
2474
+ impl: (ins) => {
2475
+ const arr = Array.isArray(ins.Objects) ? ins.Objects : [];
2476
+ const pointers = (ins.Pointers || []).map(String);
2477
+ const out = [...arr].sort((a, b) => {
2478
+ for (const p of pointers) {
2479
+ const av = jsonPointerGet(a, p);
2480
+ const bv = jsonPointerGet(b, p);
2481
+ if (av === bv)
2482
+ continue;
2483
+ if (av === undefined)
2484
+ return 1;
2485
+ if (bv === undefined)
2486
+ return -1;
2487
+ if (av < bv)
2488
+ return -1;
2489
+ if (av > bv)
2490
+ return 1;
2491
+ }
2492
+ return 0;
2493
+ });
2494
+ return { Result: out };
2495
+ },
2496
+ });
2218
2497
  return registry;
2219
2498
  }
2220
2499
  function registerDelayNode(registry) {