medicine-wheel-relational-query 0.1.0

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/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # medicine-wheel-relational-query
2
+
3
+ Query builder, graph traversal, and accountability audit for the Medicine Wheel relational web. Protocol-aware: respects ceremony boundaries and OCAP® compliance during traversal.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install medicine-wheel-relational-query
9
+ ```
10
+
11
+ ## Modules
12
+
13
+ ### Query Builder
14
+ Filter, sort, and paginate nodes and edges.
15
+
16
+ ```ts
17
+ import { filterNodes, sortNodes, paginate } from 'medicine-wheel-relational-query';
18
+
19
+ const elders = filterNodes(nodes, { type: 'human', direction: 'north' });
20
+ const sorted = sortNodes(elders, { field: 'name', order: 'asc' });
21
+ const page = paginate(sorted, { offset: 0, limit: 10 });
22
+ ```
23
+
24
+ ### Traversal
25
+ Context-aware graph traversal with ceremony and OCAP boundaries.
26
+
27
+ ```ts
28
+ import { traverse, shortestPath, neighborhood } from 'medicine-wheel-relational-query';
29
+
30
+ const result = traverse('node-id', nodes, edges, relations, {
31
+ maxDepth: 3,
32
+ respectCeremonyBoundaries: true,
33
+ ocapOnly: true,
34
+ });
35
+
36
+ const path = shortestPath('from-id', 'to-id', nodes, edges);
37
+ const neighbors = neighborhood('node-id', nodes, edges, 2);
38
+ ```
39
+
40
+ ### Accountability Audit
41
+ Relational health metrics and OCAP® compliance reports.
42
+
43
+ ```ts
44
+ import { auditAccountability, relationsNeedingAttention } from 'medicine-wheel-relational-query';
45
+
46
+ const report = auditAccountability(nodes, edges, relations);
47
+ console.log(report.averageWilsonAlignment);
48
+ console.log(report.recommendations);
49
+
50
+ const needsWork = relationsNeedingAttention(relations, 0.5);
51
+ ```
52
+
53
+ ## Peer dependency
54
+
55
+ Requires `medicine-wheel-ontology-core` ^0.1.0.
56
+
57
+ ## License
58
+
59
+ MIT
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Accountability Audit — relational health metrics and OCAP® compliance.
3
+ */
4
+ import type { Relation, RelationalNode, RelationalEdge } from 'medicine-wheel-ontology-core';
5
+ import type { AccountabilityReport } from './types.js';
6
+ /** Generate an accountability report for a relational web */
7
+ export declare function auditAccountability(nodes: RelationalNode[], edges: RelationalEdge[], relations: Relation[]): AccountabilityReport;
8
+ /** Quick OCAP compliance check for a single relation */
9
+ export declare function isOcapCompliant(relation: Relation): boolean;
10
+ /** Identify relations that need attention (low alignment or non-compliant) */
11
+ export declare function relationsNeedingAttention(relations: Relation[], wilsonThreshold?: number): Relation[];
12
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAEV,QAAQ,EACR,cAAc,EACd,cAAc,EACf,MAAM,8BAA8B,CAAC;AAKtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,6DAA6D;AAC7D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,SAAS,EAAE,QAAQ,EAAE,GACpB,oBAAoB,CAwEtB;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAE3D;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,QAAQ,EAAE,EACrB,eAAe,GAAE,MAAY,GAC5B,QAAQ,EAAE,CAMZ"}
package/dist/audit.js ADDED
@@ -0,0 +1,80 @@
1
+ import { aggregateWilsonAlignment, checkOcapCompliance, } from 'medicine-wheel-ontology-core';
2
+ /** Generate an accountability report for a relational web */
3
+ export function auditAccountability(nodes, edges, relations) {
4
+ const recommendations = [];
5
+ // OCAP compliance
6
+ let ocapCompliant = 0;
7
+ let ocapNonCompliant = 0;
8
+ for (const relation of relations) {
9
+ if (relation.ocap && checkOcapCompliance(relation.ocap).compliant) {
10
+ ocapCompliant++;
11
+ }
12
+ else {
13
+ ocapNonCompliant++;
14
+ }
15
+ }
16
+ // Wilson alignment
17
+ const averageWilsonAlignment = aggregateWilsonAlignment(relations);
18
+ // Direction coverage
19
+ const directionCoverage = { east: 0, south: 0, west: 0, north: 0 };
20
+ for (const node of nodes) {
21
+ if (node.direction) {
22
+ directionCoverage[node.direction]++;
23
+ }
24
+ }
25
+ // Ceremony honoring
26
+ const ceremoniedRelations = edges.filter(e => e.ceremony_honored).length;
27
+ const unceremoniedRelations = edges.filter(e => !e.ceremony_honored).length;
28
+ // Outstanding obligations (count total obligations across relations)
29
+ let obligationsOutstanding = 0;
30
+ for (const relation of relations) {
31
+ if (relation.obligations) {
32
+ obligationsOutstanding += relation.obligations.reduce((sum, o) => sum + o.obligations.length, 0);
33
+ }
34
+ }
35
+ // Recommendations
36
+ if (ocapNonCompliant > 0) {
37
+ recommendations.push(`${ocapNonCompliant} relation(s) lack full OCAP® compliance — review ownership, control, access, and possession flags`);
38
+ }
39
+ if (averageWilsonAlignment < 0.5) {
40
+ recommendations.push(`Wilson alignment is ${(averageWilsonAlignment * 100).toFixed(0)}% — strengthen respect, reciprocity, and responsibility`);
41
+ }
42
+ const emptyDirections = Object.entries(directionCoverage)
43
+ .filter(([, count]) => count === 0)
44
+ .map(([dir]) => dir);
45
+ if (emptyDirections.length > 0) {
46
+ recommendations.push(`No nodes in ${emptyDirections.join(', ')} direction(s) — consider expanding relational awareness`);
47
+ }
48
+ if (unceremoniedRelations > ceremoniedRelations && edges.length > 0) {
49
+ recommendations.push(`${unceremoniedRelations} of ${edges.length} relations lack ceremony — consider honoring these connections`);
50
+ }
51
+ if (obligationsOutstanding > 0) {
52
+ recommendations.push(`${obligationsOutstanding} obligation(s) outstanding — attend to relational responsibilities`);
53
+ }
54
+ return {
55
+ totalRelations: relations.length,
56
+ ocapCompliant,
57
+ ocapNonCompliant,
58
+ averageWilsonAlignment: Math.round(averageWilsonAlignment * 100) / 100,
59
+ directionCoverage,
60
+ ceremoniedRelations,
61
+ unceremoniedRelations,
62
+ obligationsOutstanding,
63
+ recommendations,
64
+ };
65
+ }
66
+ /** Quick OCAP compliance check for a single relation */
67
+ export function isOcapCompliant(relation) {
68
+ return !!relation.ocap && checkOcapCompliance(relation.ocap).compliant;
69
+ }
70
+ /** Identify relations that need attention (low alignment or non-compliant) */
71
+ export function relationsNeedingAttention(relations, wilsonThreshold = 0.5) {
72
+ return relations.filter(r => {
73
+ if (r.ocap && !checkOcapCompliance(r.ocap).compliant)
74
+ return true;
75
+ if (r.accountability && r.accountability.wilson_alignment < wilsonThreshold)
76
+ return true;
77
+ return false;
78
+ });
79
+ }
80
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * medicine-wheel-relational-query
3
+ *
4
+ * Query builder, graph traversal, and accountability audit
5
+ * for the Medicine Wheel relational web.
6
+ */
7
+ export type { NodeFilter, EdgeFilter, RelationFilter, SortField, SortOrder, QuerySort, QueryPagination, QueryOptions, QueryResult, TraversalDirection, TraversalOptions, TraversalPath, TraversalResult, AccountabilityReport, } from './types.js';
8
+ export { filterNodes, filterEdges, sortNodes, paginate, filterByRelation, relationCounts, filterByMinRelations, } from './query.js';
9
+ export { traverse, shortestPath, neighborhood, } from './traversal.js';
10
+ export { auditAccountability, isOcapCompliant, relationsNeedingAttention, } from './audit.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,SAAS,EACT,eAAe,EACf,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * medicine-wheel-relational-query
3
+ *
4
+ * Query builder, graph traversal, and accountability audit
5
+ * for the Medicine Wheel relational web.
6
+ */
7
+ // Query builder
8
+ export { filterNodes, filterEdges, sortNodes, paginate, filterByRelation, relationCounts, filterByMinRelations, } from './query.js';
9
+ // Traversal
10
+ export { traverse, shortestPath, neighborhood, } from './traversal.js';
11
+ // Audit
12
+ export { auditAccountability, isOcapCompliant, relationsNeedingAttention, } from './audit.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,gBAAgB;AAChB,OAAO,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,YAAY;AACZ,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,QAAQ;AACR,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,yBAAyB,GAC1B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Query Builder — fluent API for querying relational nodes and edges
3
+ * with Indigenous protocol awareness.
4
+ */
5
+ import type { RelationalNode, RelationalEdge } from 'medicine-wheel-ontology-core';
6
+ import type { NodeFilter, EdgeFilter, QuerySort, QueryPagination, QueryResult } from './types.js';
7
+ /** Apply a NodeFilter to an array of nodes */
8
+ export declare function filterNodes(nodes: RelationalNode[], filter: NodeFilter): RelationalNode[];
9
+ /** Apply an EdgeFilter to an array of edges */
10
+ export declare function filterEdges(edges: RelationalEdge[], filter: EdgeFilter): RelationalEdge[];
11
+ /** Apply sorting to nodes */
12
+ export declare function sortNodes(nodes: RelationalNode[], sort: QuerySort): RelationalNode[];
13
+ /** Apply pagination */
14
+ export declare function paginate<T>(items: T[], pagination: QueryPagination): QueryResult<T>;
15
+ /** Filter nodes that have relations to a specific node */
16
+ export declare function filterByRelation(nodes: RelationalNode[], edges: RelationalEdge[], targetNodeId: string): RelationalNode[];
17
+ /** Count relations per node */
18
+ export declare function relationCounts(nodes: RelationalNode[], edges: RelationalEdge[]): Map<string, number>;
19
+ /** Filter nodes with minimum relation count */
20
+ export declare function filterByMinRelations(nodes: RelationalNode[], edges: RelationalEdge[], minRelations: number): RelationalNode[];
21
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,8CAA8C;AAC9C,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,UAAU,GACjB,cAAc,EAAE,CA2BlB;AAED,+CAA+C;AAC/C,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,UAAU,GACjB,cAAc,EAAE,CAyBlB;AAED,6BAA6B;AAC7B,wBAAgB,SAAS,CACvB,KAAK,EAAE,cAAc,EAAE,EACvB,IAAI,EAAE,SAAS,GACd,cAAc,EAAE,CAsBlB;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,EAAE,EACV,UAAU,EAAE,eAAe,GAC1B,WAAW,CAAC,CAAC,CAAC,CAWhB;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,YAAY,EAAE,MAAM,GACnB,cAAc,EAAE,CAOlB;AAED,+BAA+B;AAC/B,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,GACtB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrB;AAED,+CAA+C;AAC/C,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,YAAY,EAAE,MAAM,GACnB,cAAc,EAAE,CAGlB"}
package/dist/query.js ADDED
@@ -0,0 +1,115 @@
1
+ /** Apply a NodeFilter to an array of nodes */
2
+ export function filterNodes(nodes, filter) {
3
+ let result = [...nodes];
4
+ if (filter.type) {
5
+ const types = Array.isArray(filter.type) ? filter.type : [filter.type];
6
+ result = result.filter(n => types.includes(n.type));
7
+ }
8
+ if (filter.direction) {
9
+ const dirs = Array.isArray(filter.direction) ? filter.direction : [filter.direction];
10
+ result = result.filter(n => n.direction && dirs.includes(n.direction));
11
+ }
12
+ if (filter.nameContains) {
13
+ const term = filter.nameContains.toLowerCase();
14
+ result = result.filter(n => n.name.toLowerCase().includes(term));
15
+ }
16
+ if (filter.createdAfter) {
17
+ result = result.filter(n => n.created_at >= filter.createdAfter);
18
+ }
19
+ if (filter.createdBefore) {
20
+ result = result.filter(n => n.created_at <= filter.createdBefore);
21
+ }
22
+ return result;
23
+ }
24
+ /** Apply an EdgeFilter to an array of edges */
25
+ export function filterEdges(edges, filter) {
26
+ let result = [...edges];
27
+ if (filter.relationshipType) {
28
+ const types = Array.isArray(filter.relationshipType) ? filter.relationshipType : [filter.relationshipType];
29
+ result = result.filter(e => types.includes(e.relationship_type));
30
+ }
31
+ if (filter.minStrength !== undefined) {
32
+ result = result.filter(e => e.strength >= filter.minStrength);
33
+ }
34
+ if (filter.ceremonyHonored !== undefined) {
35
+ result = result.filter(e => e.ceremony_honored === filter.ceremonyHonored);
36
+ }
37
+ if (filter.fromNode) {
38
+ result = result.filter(e => e.from_id === filter.fromNode);
39
+ }
40
+ if (filter.toNode) {
41
+ result = result.filter(e => e.to_id === filter.toNode);
42
+ }
43
+ return result;
44
+ }
45
+ /** Apply sorting to nodes */
46
+ export function sortNodes(nodes, sort) {
47
+ const sorted = [...nodes];
48
+ const multiplier = sort.order === 'desc' ? -1 : 1;
49
+ sorted.sort((a, b) => {
50
+ let aVal, bVal;
51
+ switch (sort.field) {
52
+ case 'name':
53
+ aVal = a.name;
54
+ bVal = b.name;
55
+ break;
56
+ case 'type':
57
+ aVal = a.type;
58
+ bVal = b.type;
59
+ break;
60
+ case 'direction':
61
+ aVal = a.direction ?? '';
62
+ bVal = b.direction ?? '';
63
+ break;
64
+ case 'updated_at':
65
+ aVal = a.updated_at;
66
+ bVal = b.updated_at;
67
+ break;
68
+ default:
69
+ aVal = a.created_at;
70
+ bVal = b.created_at;
71
+ }
72
+ return aVal.localeCompare(bVal) * multiplier;
73
+ });
74
+ return sorted;
75
+ }
76
+ /** Apply pagination */
77
+ export function paginate(items, pagination) {
78
+ const total = items.length;
79
+ const paged = items.slice(pagination.offset, pagination.offset + pagination.limit);
80
+ return {
81
+ items: paged,
82
+ total,
83
+ offset: pagination.offset,
84
+ limit: pagination.limit,
85
+ hasMore: pagination.offset + pagination.limit < total,
86
+ };
87
+ }
88
+ /** Filter nodes that have relations to a specific node */
89
+ export function filterByRelation(nodes, edges, targetNodeId) {
90
+ const connectedIds = new Set();
91
+ for (const edge of edges) {
92
+ if (edge.from_id === targetNodeId)
93
+ connectedIds.add(edge.to_id);
94
+ if (edge.to_id === targetNodeId)
95
+ connectedIds.add(edge.from_id);
96
+ }
97
+ return nodes.filter(n => connectedIds.has(n.id));
98
+ }
99
+ /** Count relations per node */
100
+ export function relationCounts(nodes, edges) {
101
+ const counts = new Map();
102
+ for (const node of nodes)
103
+ counts.set(node.id, 0);
104
+ for (const edge of edges) {
105
+ counts.set(edge.from_id, (counts.get(edge.from_id) ?? 0) + 1);
106
+ counts.set(edge.to_id, (counts.get(edge.to_id) ?? 0) + 1);
107
+ }
108
+ return counts;
109
+ }
110
+ /** Filter nodes with minimum relation count */
111
+ export function filterByMinRelations(nodes, edges, minRelations) {
112
+ const counts = relationCounts(nodes, edges);
113
+ return nodes.filter(n => (counts.get(n.id) ?? 0) >= minRelations);
114
+ }
115
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Graph Traversal — context-aware relationship traversal
3
+ * with ceremony boundary and OCAP® awareness.
4
+ */
5
+ import type { RelationalNode, RelationalEdge, Relation } from 'medicine-wheel-ontology-core';
6
+ import type { TraversalOptions, TraversalPath, TraversalResult } from './types.js';
7
+ /** Traverse the relational web from a root node */
8
+ export declare function traverse(rootId: string, nodes: RelationalNode[], edges: RelationalEdge[], relations: Relation[], opts?: Partial<TraversalOptions>): TraversalResult;
9
+ /** Find shortest path between two nodes */
10
+ export declare function shortestPath(fromId: string, toId: string, nodes: RelationalNode[], edges: RelationalEdge[]): TraversalPath | null;
11
+ /** Find all nodes reachable within N hops */
12
+ export declare function neighborhood(nodeId: string, nodes: RelationalNode[], edges: RelationalEdge[], maxDepth?: number): RelationalNode[];
13
+ //# sourceMappingURL=traversal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traversal.d.ts","sourceRoot":"","sources":["../src/traversal.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAE7F,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,eAAe,EAGhB,MAAM,YAAY,CAAC;AAiCpB,mDAAmD;AACnD,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,SAAS,EAAE,QAAQ,EAAE,EACrB,IAAI,GAAE,OAAO,CAAC,gBAAgB,CAAM,GACnC,eAAe,CAoGjB;AAED,2CAA2C;AAC3C,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,GACtB,aAAa,GAAG,IAAI,CA4CtB;AAED,6CAA6C;AAC7C,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,QAAQ,GAAE,MAAU,GACnB,cAAc,EAAE,CAMlB"}
@@ -0,0 +1,148 @@
1
+ import { checkOcapCompliance } from 'medicine-wheel-ontology-core';
2
+ import { filterEdges, filterNodes } from './query.js';
3
+ const DEFAULT_OPTIONS = {
4
+ maxDepth: 3,
5
+ direction: 'both',
6
+ respectCeremonyBoundaries: false,
7
+ ocapOnly: false,
8
+ };
9
+ /** Build an adjacency map from edges */
10
+ function buildAdjacency(edges, direction) {
11
+ const adj = new Map();
12
+ for (const edge of edges) {
13
+ if (direction === 'outgoing' || direction === 'both') {
14
+ const list = adj.get(edge.from_id) ?? [];
15
+ list.push({ nodeId: edge.to_id, edge });
16
+ adj.set(edge.from_id, list);
17
+ }
18
+ if (direction === 'incoming' || direction === 'both') {
19
+ const list = adj.get(edge.to_id) ?? [];
20
+ list.push({ nodeId: edge.from_id, edge });
21
+ adj.set(edge.to_id, list);
22
+ }
23
+ }
24
+ return adj;
25
+ }
26
+ /** Traverse the relational web from a root node */
27
+ export function traverse(rootId, nodes, edges, relations, opts = {}) {
28
+ const options = { ...DEFAULT_OPTIONS, ...opts };
29
+ // Pre-filter edges
30
+ let filteredEdges = edges;
31
+ if (options.edgeFilter) {
32
+ filteredEdges = filterEdges(edges, options.edgeFilter);
33
+ }
34
+ // OCAP filter: only follow edges whose relations are compliant
35
+ if (options.ocapOnly) {
36
+ const compliantRelIds = new Set(relations
37
+ .filter(r => r.ocap && checkOcapCompliance(r.ocap).compliant)
38
+ .map(r => r.id));
39
+ // Keep edges that match compliant relation IDs or have no relation mapping
40
+ filteredEdges = filteredEdges.filter(e => {
41
+ const relId = `${e.from_id}-${e.to_id}`;
42
+ const reverseId = `${e.to_id}-${e.from_id}`;
43
+ return compliantRelIds.has(relId) || compliantRelIds.has(reverseId) || !relations.some(r => r.id === relId || r.id === reverseId);
44
+ });
45
+ }
46
+ // Build adjacency
47
+ const adj = buildAdjacency(filteredEdges, options.direction);
48
+ // Node lookup
49
+ const nodeMap = new Map(nodes.map(n => [n.id, n]));
50
+ const rootNode = nodeMap.get(rootId);
51
+ if (!rootNode) {
52
+ return {
53
+ root: { id: rootId, type: 'knowledge', name: 'Unknown', created_at: '', updated_at: '' },
54
+ paths: [],
55
+ visitedNodes: new Set(),
56
+ maxDepthReached: false,
57
+ };
58
+ }
59
+ // BFS traversal
60
+ const paths = [];
61
+ const visited = new Set([rootId]);
62
+ let maxDepthReached = false;
63
+ const queue = [{ nodeId: rootId, path: [rootNode], edgePath: [], depth: 0 }];
64
+ while (queue.length > 0) {
65
+ const current = queue.shift();
66
+ if (current.depth >= options.maxDepth) {
67
+ maxDepthReached = true;
68
+ continue;
69
+ }
70
+ const neighbors = adj.get(current.nodeId) ?? [];
71
+ for (const { nodeId, edge } of neighbors) {
72
+ if (visited.has(nodeId))
73
+ continue;
74
+ // Ceremony boundary check
75
+ if (options.respectCeremonyBoundaries && !edge.ceremony_honored) {
76
+ continue;
77
+ }
78
+ const node = nodeMap.get(nodeId);
79
+ if (!node)
80
+ continue;
81
+ // Node filter
82
+ if (options.nodeFilter) {
83
+ const filtered = filterNodes([node], options.nodeFilter);
84
+ if (filtered.length === 0)
85
+ continue;
86
+ }
87
+ visited.add(nodeId);
88
+ const newPath = [...current.path, node];
89
+ const newEdgePath = [...current.edgePath, edge];
90
+ paths.push({
91
+ nodes: newPath,
92
+ edges: newEdgePath,
93
+ depth: current.depth + 1,
94
+ });
95
+ queue.push({
96
+ nodeId,
97
+ path: newPath,
98
+ edgePath: newEdgePath,
99
+ depth: current.depth + 1,
100
+ });
101
+ }
102
+ }
103
+ return { root: rootNode, paths, visitedNodes: visited, maxDepthReached };
104
+ }
105
+ /** Find shortest path between two nodes */
106
+ export function shortestPath(fromId, toId, nodes, edges) {
107
+ const adj = buildAdjacency(edges, 'both');
108
+ const nodeMap = new Map(nodes.map(n => [n.id, n]));
109
+ const visited = new Set([fromId]);
110
+ const fromNode = nodeMap.get(fromId);
111
+ if (!fromNode)
112
+ return null;
113
+ const queue = [{ nodeId: fromId, path: [fromNode], edgePath: [] }];
114
+ while (queue.length > 0) {
115
+ const current = queue.shift();
116
+ if (current.nodeId === toId) {
117
+ return {
118
+ nodes: current.path,
119
+ edges: current.edgePath,
120
+ depth: current.path.length - 1,
121
+ };
122
+ }
123
+ const neighbors = adj.get(current.nodeId) ?? [];
124
+ for (const { nodeId, edge } of neighbors) {
125
+ if (visited.has(nodeId))
126
+ continue;
127
+ visited.add(nodeId);
128
+ const node = nodeMap.get(nodeId);
129
+ if (!node)
130
+ continue;
131
+ queue.push({
132
+ nodeId,
133
+ path: [...current.path, node],
134
+ edgePath: [...current.edgePath, edge],
135
+ });
136
+ }
137
+ }
138
+ return null;
139
+ }
140
+ /** Find all nodes reachable within N hops */
141
+ export function neighborhood(nodeId, nodes, edges, maxDepth = 2) {
142
+ const result = traverse(nodeId, nodes, edges, [], { maxDepth, direction: 'both' });
143
+ const nodeMap = new Map(nodes.map(n => [n.id, n]));
144
+ return [...result.visitedNodes]
145
+ .map(id => nodeMap.get(id))
146
+ .filter((n) => n !== undefined);
147
+ }
148
+ //# sourceMappingURL=traversal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traversal.js","sourceRoot":"","sources":["../src/traversal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * medicine-wheel-relational-query — types
3
+ *
4
+ * Query builder types for context-aware relational traversal
5
+ * with Indigenous protocol awareness.
6
+ */
7
+ import type { DirectionName, NodeType, RelationalNode, RelationalEdge } from 'medicine-wheel-ontology-core';
8
+ export interface NodeFilter {
9
+ type?: NodeType | NodeType[];
10
+ direction?: DirectionName | DirectionName[];
11
+ nameContains?: string;
12
+ hasRelationsTo?: string;
13
+ minRelations?: number;
14
+ createdAfter?: string;
15
+ createdBefore?: string;
16
+ }
17
+ export interface EdgeFilter {
18
+ relationshipType?: string | string[];
19
+ minStrength?: number;
20
+ ceremonyHonored?: boolean;
21
+ fromNode?: string;
22
+ toNode?: string;
23
+ }
24
+ export interface RelationFilter {
25
+ direction?: DirectionName;
26
+ ceremonied?: boolean;
27
+ ocapCompliant?: boolean;
28
+ minWilsonAlignment?: number;
29
+ hasObligations?: boolean;
30
+ }
31
+ export type SortField = 'name' | 'created_at' | 'updated_at' | 'type' | 'direction';
32
+ export type SortOrder = 'asc' | 'desc';
33
+ export interface QuerySort {
34
+ field: SortField;
35
+ order: SortOrder;
36
+ }
37
+ export interface QueryPagination {
38
+ offset: number;
39
+ limit: number;
40
+ }
41
+ export interface QueryOptions {
42
+ filter?: NodeFilter;
43
+ sort?: QuerySort;
44
+ pagination?: QueryPagination;
45
+ includeEdges?: boolean;
46
+ includeRelations?: boolean;
47
+ }
48
+ export interface QueryResult<T> {
49
+ items: T[];
50
+ total: number;
51
+ offset: number;
52
+ limit: number;
53
+ hasMore: boolean;
54
+ }
55
+ export type TraversalDirection = 'outgoing' | 'incoming' | 'both';
56
+ export interface TraversalOptions {
57
+ maxDepth: number;
58
+ direction: TraversalDirection;
59
+ edgeFilter?: EdgeFilter;
60
+ nodeFilter?: NodeFilter;
61
+ /** Stop traversal at nodes without ceremony-honored edges */
62
+ respectCeremonyBoundaries?: boolean;
63
+ /** Only follow OCAP-compliant relations */
64
+ ocapOnly?: boolean;
65
+ }
66
+ export interface TraversalPath {
67
+ nodes: RelationalNode[];
68
+ edges: RelationalEdge[];
69
+ depth: number;
70
+ }
71
+ export interface TraversalResult {
72
+ root: RelationalNode;
73
+ paths: TraversalPath[];
74
+ visitedNodes: Set<string>;
75
+ maxDepthReached: boolean;
76
+ }
77
+ export interface AccountabilityReport {
78
+ totalRelations: number;
79
+ ocapCompliant: number;
80
+ ocapNonCompliant: number;
81
+ averageWilsonAlignment: number;
82
+ directionCoverage: Record<DirectionName, number>;
83
+ ceremoniedRelations: number;
84
+ unceremoniedRelations: number;
85
+ obligationsOutstanding: number;
86
+ recommendations: string[];
87
+ }
88
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "medicine-wheel-relational-query",
3
+ "version": "0.1.0",
4
+ "description": "Query builder for relational webs with Indigenous protocol awareness — traversal, accountability, OCAP® compliance",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "clean": "rm -rf dist",
21
+ "prepublishOnly": "npm run clean && npm run build"
22
+ },
23
+ "keywords": [
24
+ "medicine-wheel",
25
+ "relational",
26
+ "query",
27
+ "indigenous",
28
+ "ocap",
29
+ "graph-traversal"
30
+ ],
31
+ "author": "jgwill",
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "medicine-wheel-ontology-core": "^0.1.0"
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "^5.7.0"
38
+ }
39
+ }