@dxos/app-graph 0.8.3 → 0.8.4-main.03d5cd7b56

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.
Files changed (73) hide show
  1. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  2. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  3. package/dist/lib/neutral/chunk-WJJ5KEOH.mjs +1477 -0
  4. package/dist/lib/neutral/chunk-WJJ5KEOH.mjs.map +7 -0
  5. package/dist/lib/neutral/index.mjs +40 -0
  6. package/dist/lib/neutral/index.mjs.map +7 -0
  7. package/dist/lib/neutral/meta.json +1 -0
  8. package/dist/lib/neutral/scheduler.mjs +15 -0
  9. package/dist/lib/neutral/scheduler.mjs.map +7 -0
  10. package/dist/lib/neutral/testing/index.mjs +40 -0
  11. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  12. package/dist/types/src/atoms.d.ts +8 -0
  13. package/dist/types/src/atoms.d.ts.map +1 -0
  14. package/dist/types/src/graph-builder.d.ts +117 -60
  15. package/dist/types/src/graph-builder.d.ts.map +1 -1
  16. package/dist/types/src/graph.d.ts +188 -218
  17. package/dist/types/src/graph.d.ts.map +1 -1
  18. package/dist/types/src/index.d.ts +7 -3
  19. package/dist/types/src/index.d.ts.map +1 -1
  20. package/dist/types/src/node-matcher.d.ts +244 -0
  21. package/dist/types/src/node-matcher.d.ts.map +1 -0
  22. package/dist/types/src/node-matcher.test.d.ts +2 -0
  23. package/dist/types/src/node-matcher.test.d.ts.map +1 -0
  24. package/dist/types/src/node.d.ts +50 -5
  25. package/dist/types/src/node.d.ts.map +1 -1
  26. package/dist/types/src/scheduler.browser.d.ts +2 -0
  27. package/dist/types/src/scheduler.browser.d.ts.map +1 -0
  28. package/dist/types/src/scheduler.d.ts +8 -0
  29. package/dist/types/src/scheduler.d.ts.map +1 -0
  30. package/dist/types/src/stories/EchoGraph.stories.d.ts +6 -13
  31. package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
  32. package/dist/types/src/testing/index.d.ts +2 -0
  33. package/dist/types/src/testing/index.d.ts.map +1 -0
  34. package/dist/types/src/testing/setup-graph-builder.d.ts +31 -0
  35. package/dist/types/src/testing/setup-graph-builder.d.ts.map +1 -0
  36. package/dist/types/src/util.d.ts +40 -0
  37. package/dist/types/src/util.d.ts.map +1 -0
  38. package/dist/types/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +53 -42
  40. package/src/atoms.ts +25 -0
  41. package/src/graph-builder.test.ts +1193 -126
  42. package/src/graph-builder.ts +753 -264
  43. package/src/graph.test.ts +451 -123
  44. package/src/graph.ts +1057 -407
  45. package/src/index.ts +10 -3
  46. package/src/node-matcher.test.ts +301 -0
  47. package/src/node-matcher.ts +314 -0
  48. package/src/node.ts +83 -7
  49. package/src/scheduler.browser.ts +5 -0
  50. package/src/scheduler.ts +17 -0
  51. package/src/stories/EchoGraph.stories.tsx +178 -255
  52. package/src/stories/Tree.tsx +1 -1
  53. package/src/testing/index.ts +5 -0
  54. package/src/testing/setup-graph-builder.ts +41 -0
  55. package/src/util.ts +101 -0
  56. package/dist/lib/browser/index.mjs +0 -778
  57. package/dist/lib/browser/index.mjs.map +0 -7
  58. package/dist/lib/browser/meta.json +0 -1
  59. package/dist/lib/node/index.cjs +0 -816
  60. package/dist/lib/node/index.cjs.map +0 -7
  61. package/dist/lib/node/meta.json +0 -1
  62. package/dist/lib/node-esm/index.mjs +0 -780
  63. package/dist/lib/node-esm/index.mjs.map +0 -7
  64. package/dist/lib/node-esm/meta.json +0 -1
  65. package/dist/types/src/experimental/graph-projections.test.d.ts +0 -25
  66. package/dist/types/src/experimental/graph-projections.test.d.ts.map +0 -1
  67. package/dist/types/src/signals-integration.test.d.ts +0 -2
  68. package/dist/types/src/signals-integration.test.d.ts.map +0 -1
  69. package/dist/types/src/testing.d.ts +0 -5
  70. package/dist/types/src/testing.d.ts.map +0 -1
  71. package/src/experimental/graph-projections.test.ts +0 -56
  72. package/src/signals-integration.test.ts +0 -218
  73. package/src/testing.ts +0 -20
package/src/util.ts ADDED
@@ -0,0 +1,101 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { invariant } from '@dxos/invariant';
6
+
7
+ import * as Node from './node';
8
+
9
+ // PRIMARY separates top-level components (e.g., node ID from relation) in compound string keys used within the app-graph package.
10
+ const PRIMARY = '\u0001';
11
+
12
+ // SECONDARY separates sub-components within an encoded value (e.g., relation kind from direction) in the same context.
13
+ const SECONDARY = '\u0002';
14
+
15
+ // PATH separates segments in qualified node IDs (e.g., parent path from local segment).
16
+ const PATH = '/';
17
+
18
+ /** Join parts with the primary separator. */
19
+ export const primaryKey = (...parts: string[]): string => parts.join(PRIMARY);
20
+
21
+ /** Split a key on the primary separator. */
22
+ export const primaryParts = (key: string): string[] => key.split(PRIMARY);
23
+
24
+ /** Join parts with the secondary separator. */
25
+ export const secondaryKey = (...parts: string[]): string => parts.join(SECONDARY);
26
+
27
+ /** Split a key on the secondary separator. */
28
+ export const secondaryParts = (key: string): string[] => key.split(SECONDARY);
29
+
30
+ /**
31
+ * Normalize a relation input to a full Relation object.
32
+ */
33
+ export const normalizeRelation = (relation?: Node.RelationInput): Node.Relation =>
34
+ relation == null ? Node.childRelation() : typeof relation === 'string' ? Node.relation(relation) : relation;
35
+
36
+ /**
37
+ * Shallow-compare two values: same reference, or same own-keys with === values.
38
+ */
39
+ export const shallowEqual = (a: unknown, b: unknown): boolean => {
40
+ if (a === b) {
41
+ return true;
42
+ }
43
+ if (a == null || b == null || typeof a !== 'object' || typeof b !== 'object') {
44
+ return false;
45
+ }
46
+ const keysA = Object.keys(a as Record<string, unknown>);
47
+ const keysB = Object.keys(b as Record<string, unknown>);
48
+ if (keysA.length !== keysB.length) {
49
+ return false;
50
+ }
51
+ return keysA.every((k) => (a as Record<string, unknown>)[k] === (b as Record<string, unknown>)[k]);
52
+ };
53
+
54
+ /**
55
+ * Returns true if two NodeArg arrays are semantically identical (same id, type, data, properties per index).
56
+ * Inline child nodes (the `nodes` field) are compared recursively.
57
+ */
58
+ export const nodeArgsUnchanged = (prev: Node.NodeArg<any>[], next: Node.NodeArg<any>[]): boolean => {
59
+ if (prev.length !== next.length) {
60
+ return false;
61
+ }
62
+
63
+ return prev.every((prevNode, idx) => {
64
+ const nextNode = next[idx];
65
+ return (
66
+ prevNode.id === nextNode.id &&
67
+ prevNode.type === nextNode.type &&
68
+ shallowEqual(prevNode.data, nextNode.data) &&
69
+ shallowEqual(prevNode.properties, nextNode.properties) &&
70
+ nodeArgsUnchanged(prevNode.nodes ?? [], nextNode.nodes ?? [])
71
+ );
72
+ });
73
+ };
74
+
75
+ /**
76
+ * Build a qualified node ID by joining path segments.
77
+ */
78
+ export const qualifyId = (parentId: string, ...segmentIds: string[]): string => [parentId, ...segmentIds].join(PATH);
79
+
80
+ /**
81
+ * Validate that a segment ID does not contain the path separator.
82
+ */
83
+ export const validateSegmentId = (id: string): void => {
84
+ invariant(!id.includes(PATH), `Node segment ID must not contain '${PATH}': ${id}`);
85
+ };
86
+
87
+ /**
88
+ * Extract the parent qualified ID (everything before the last path separator).
89
+ * Returns undefined for IDs with no parent (single segment).
90
+ */
91
+ export const getParentId = (qualifiedId: string): string | undefined => {
92
+ const lastSlash = qualifiedId.lastIndexOf(PATH);
93
+ return lastSlash > 0 ? qualifiedId.slice(0, lastSlash) : undefined;
94
+ };
95
+
96
+ /**
97
+ * Extract the last segment of a qualified ID.
98
+ */
99
+ export const getSegmentId = (qualifiedId: string): string => {
100
+ return qualifiedId.split(PATH).pop() ?? qualifiedId;
101
+ };