graphwise 1.1.0 → 1.2.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.
Files changed (133) hide show
  1. package/dist/expansion/frontier-balanced.d.ts +12 -0
  2. package/dist/expansion/frontier-balanced.d.ts.map +1 -0
  3. package/dist/expansion/frontier-balanced.unit.test.d.ts +2 -0
  4. package/dist/expansion/frontier-balanced.unit.test.d.ts.map +1 -0
  5. package/dist/expansion/index.d.ts +12 -13
  6. package/dist/expansion/index.d.ts.map +1 -1
  7. package/dist/expansion/random-priority.d.ts +20 -0
  8. package/dist/expansion/random-priority.d.ts.map +1 -0
  9. package/dist/expansion/random-priority.unit.test.d.ts +2 -0
  10. package/dist/expansion/random-priority.unit.test.d.ts.map +1 -0
  11. package/dist/expansion/standard-bfs.d.ts +12 -0
  12. package/dist/expansion/standard-bfs.d.ts.map +1 -0
  13. package/dist/expansion/standard-bfs.unit.test.d.ts +2 -0
  14. package/dist/expansion/standard-bfs.unit.test.d.ts.map +1 -0
  15. package/dist/extraction/index.d.ts +6 -6
  16. package/dist/extraction/index.d.ts.map +1 -1
  17. package/dist/extraction/motif.d.ts.map +1 -1
  18. package/dist/gpu/context.d.ts.map +1 -1
  19. package/dist/gpu/csr.d.ts.map +1 -1
  20. package/dist/gpu/index.cjs +410 -5
  21. package/dist/gpu/index.cjs.map +1 -0
  22. package/dist/gpu/index.d.ts +4 -5
  23. package/dist/gpu/index.d.ts.map +1 -1
  24. package/dist/gpu/index.js +400 -2
  25. package/dist/gpu/index.js.map +1 -0
  26. package/dist/graph/index.cjs +222 -2
  27. package/dist/graph/index.cjs.map +1 -0
  28. package/dist/graph/index.d.ts +3 -3
  29. package/dist/graph/index.d.ts.map +1 -1
  30. package/dist/graph/index.js +221 -1
  31. package/dist/graph/index.js.map +1 -0
  32. package/dist/index/index.cjs +902 -10
  33. package/dist/index/index.cjs.map +1 -1
  34. package/dist/index/index.js +880 -10
  35. package/dist/index/index.js.map +1 -1
  36. package/dist/{kmeans-B0HEOU6k.cjs → kmeans-87ExSUNZ.js} +27 -13
  37. package/dist/{kmeans-DgbsOznU.js.map → kmeans-87ExSUNZ.js.map} +1 -1
  38. package/dist/{kmeans-DgbsOznU.js → kmeans-BIgSyGKu.cjs} +44 -2
  39. package/dist/{kmeans-B0HEOU6k.cjs.map → kmeans-BIgSyGKu.cjs.map} +1 -1
  40. package/dist/ranking/baselines/betweenness.d.ts +13 -0
  41. package/dist/ranking/baselines/betweenness.d.ts.map +1 -0
  42. package/dist/ranking/baselines/betweenness.unit.test.d.ts +2 -0
  43. package/dist/ranking/baselines/betweenness.unit.test.d.ts.map +1 -0
  44. package/dist/ranking/baselines/communicability.d.ts +13 -0
  45. package/dist/ranking/baselines/communicability.d.ts.map +1 -0
  46. package/dist/ranking/baselines/communicability.unit.test.d.ts +2 -0
  47. package/dist/ranking/baselines/communicability.unit.test.d.ts.map +1 -0
  48. package/dist/ranking/baselines/degree-sum.d.ts +13 -0
  49. package/dist/ranking/baselines/degree-sum.d.ts.map +1 -0
  50. package/dist/ranking/baselines/degree-sum.unit.test.d.ts +2 -0
  51. package/dist/ranking/baselines/degree-sum.unit.test.d.ts.map +1 -0
  52. package/dist/ranking/baselines/index.d.ts +20 -0
  53. package/dist/ranking/baselines/index.d.ts.map +1 -0
  54. package/dist/ranking/baselines/jaccard-arithmetic.d.ts +13 -0
  55. package/dist/ranking/baselines/jaccard-arithmetic.d.ts.map +1 -0
  56. package/dist/ranking/baselines/jaccard-arithmetic.unit.test.d.ts +2 -0
  57. package/dist/ranking/baselines/jaccard-arithmetic.unit.test.d.ts.map +1 -0
  58. package/dist/ranking/baselines/katz.d.ts +13 -0
  59. package/dist/ranking/baselines/katz.d.ts.map +1 -0
  60. package/dist/ranking/baselines/katz.unit.test.d.ts +2 -0
  61. package/dist/ranking/baselines/katz.unit.test.d.ts.map +1 -0
  62. package/dist/ranking/baselines/pagerank.d.ts +13 -0
  63. package/dist/ranking/baselines/pagerank.d.ts.map +1 -0
  64. package/dist/ranking/baselines/pagerank.unit.test.d.ts +2 -0
  65. package/dist/ranking/baselines/pagerank.unit.test.d.ts.map +1 -0
  66. package/dist/ranking/baselines/random-ranking.d.ts +21 -0
  67. package/dist/ranking/baselines/random-ranking.d.ts.map +1 -0
  68. package/dist/ranking/baselines/random-ranking.unit.test.d.ts +2 -0
  69. package/dist/ranking/baselines/random-ranking.unit.test.d.ts.map +1 -0
  70. package/dist/ranking/baselines/resistance-distance.d.ts +13 -0
  71. package/dist/ranking/baselines/resistance-distance.d.ts.map +1 -0
  72. package/dist/ranking/baselines/resistance-distance.unit.test.d.ts +2 -0
  73. package/dist/ranking/baselines/resistance-distance.unit.test.d.ts.map +1 -0
  74. package/dist/ranking/baselines/widest-path.d.ts +13 -0
  75. package/dist/ranking/baselines/widest-path.d.ts.map +1 -0
  76. package/dist/ranking/baselines/widest-path.unit.test.d.ts +2 -0
  77. package/dist/ranking/baselines/widest-path.unit.test.d.ts.map +1 -0
  78. package/dist/ranking/index.d.ts +3 -6
  79. package/dist/ranking/index.d.ts.map +1 -1
  80. package/dist/ranking/mi/index.d.ts +9 -9
  81. package/dist/ranking/mi/index.d.ts.map +1 -1
  82. package/dist/schemas/index.d.ts +2 -2
  83. package/dist/schemas/index.d.ts.map +1 -1
  84. package/dist/seeds/index.cjs +398 -3
  85. package/dist/seeds/index.cjs.map +1 -0
  86. package/dist/seeds/index.d.ts +2 -4
  87. package/dist/seeds/index.d.ts.map +1 -1
  88. package/dist/seeds/index.js +396 -1
  89. package/dist/seeds/index.js.map +1 -0
  90. package/dist/seeds/stratified.d.ts.map +1 -1
  91. package/dist/structures/index.cjs +133 -2
  92. package/dist/structures/index.cjs.map +1 -0
  93. package/dist/structures/index.d.ts +1 -2
  94. package/dist/structures/index.d.ts.map +1 -1
  95. package/dist/structures/index.js +132 -1
  96. package/dist/structures/index.js.map +1 -0
  97. package/dist/traversal/index.cjs +152 -5
  98. package/dist/traversal/index.cjs.map +1 -0
  99. package/dist/traversal/index.d.ts +2 -2
  100. package/dist/traversal/index.d.ts.map +1 -1
  101. package/dist/traversal/index.js +148 -1
  102. package/dist/traversal/index.js.map +1 -0
  103. package/dist/utils/index.cjs +172 -9
  104. package/dist/utils/index.cjs.map +1 -0
  105. package/dist/utils/index.d.ts +3 -3
  106. package/dist/utils/index.d.ts.map +1 -1
  107. package/dist/utils/index.js +165 -3
  108. package/dist/utils/index.js.map +1 -0
  109. package/package.json +1 -1
  110. package/dist/gpu-BJRVYBjx.cjs +0 -338
  111. package/dist/gpu-BJRVYBjx.cjs.map +0 -1
  112. package/dist/gpu-BveuXugy.js +0 -315
  113. package/dist/gpu-BveuXugy.js.map +0 -1
  114. package/dist/graph-DLWiziLB.js +0 -222
  115. package/dist/graph-DLWiziLB.js.map +0 -1
  116. package/dist/graph-az06J1YV.cjs +0 -227
  117. package/dist/graph-az06J1YV.cjs.map +0 -1
  118. package/dist/seeds-B6J9oJfU.cjs +0 -404
  119. package/dist/seeds-B6J9oJfU.cjs.map +0 -1
  120. package/dist/seeds-UNZxqm_U.js +0 -393
  121. package/dist/seeds-UNZxqm_U.js.map +0 -1
  122. package/dist/structures-BPfhfqNP.js +0 -133
  123. package/dist/structures-BPfhfqNP.js.map +0 -1
  124. package/dist/structures-CJ_S_7fs.cjs +0 -138
  125. package/dist/structures-CJ_S_7fs.cjs.map +0 -1
  126. package/dist/traversal-CQCjUwUJ.js +0 -149
  127. package/dist/traversal-CQCjUwUJ.js.map +0 -1
  128. package/dist/traversal-QeHaNUWn.cjs +0 -172
  129. package/dist/traversal-QeHaNUWn.cjs.map +0 -1
  130. package/dist/utils-Q_akvlMn.js +0 -164
  131. package/dist/utils-Q_akvlMn.js.map +0 -1
  132. package/dist/utils-spZa1ZvS.cjs +0 -205
  133. package/dist/utils-spZa1ZvS.cjs.map +0 -1
@@ -0,0 +1,12 @@
1
+ import { NodeData, EdgeData, ReadableGraph } from '../graph';
2
+ import { Seed, ExpansionResult, ExpansionConfig } from './types';
3
+ /**
4
+ * Run frontier-balanced expansion (round-robin across frontiers).
5
+ *
6
+ * @param graph - Source graph
7
+ * @param seeds - Seed nodes for expansion
8
+ * @param config - Expansion configuration
9
+ * @returns Expansion result with discovered paths
10
+ */
11
+ export declare function frontierBalanced<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, seeds: readonly Seed[], config?: ExpansionConfig<N, E>): ExpansionResult;
12
+ //# sourceMappingURL=frontier-balanced.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontier-balanced.d.ts","sourceRoot":"","sources":["../../src/expansion/frontier-balanced.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EACX,IAAI,EACJ,eAAe,EACf,eAAe,EAEf,MAAM,SAAS,CAAC;AAGjB;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACtE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAC5B,eAAe,CAkBjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=frontier-balanced.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontier-balanced.unit.test.d.ts","sourceRoot":"","sources":["../../src/expansion/frontier-balanced.unit.test.ts"],"names":[],"mappings":""}
@@ -6,17 +6,16 @@
6
6
  *
7
7
  * @module expansion
8
8
  */
9
- export type { Seed, SeedRole, ExpansionResult, ExpansionPath, ExpansionStats, ExpansionConfig, PriorityFunction, PriorityContext, } from './types';
10
- export { base } from './base';
11
- export { dome } from './dome';
12
- export { edge } from './edge';
13
- export { hae } from './hae';
14
- export type { HAEConfig } from './hae';
15
- export { pipe } from './pipe';
16
- export { sage } from './sage';
17
- export type { SAGEConfig } from './sage';
18
- export { reach } from './reach';
19
- export type { REACHConfig } from './reach';
20
- export { maze } from './maze';
21
- export type { MAZEConfig } from './maze';
9
+ export * from './types';
10
+ export * from './base';
11
+ export * from './dome';
12
+ export * from './edge';
13
+ export * from './hae';
14
+ export * from './pipe';
15
+ export * from './sage';
16
+ export * from './reach';
17
+ export * from './maze';
18
+ export * from './standard-bfs';
19
+ export * from './frontier-balanced';
20
+ export * from './random-priority';
22
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/expansion/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACX,IAAI,EACJ,QAAQ,EACR,eAAe,EACf,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,eAAe,GACf,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGzC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/expansion/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { NodeData, EdgeData, ReadableGraph } from '../graph';
2
+ import { Seed, ExpansionResult, ExpansionConfig } from './types';
3
+ /**
4
+ * Configuration for random-priority expansion.
5
+ */
6
+ interface RandomPriorityConfig<N extends NodeData = NodeData, E extends EdgeData = EdgeData> extends ExpansionConfig<N, E> {
7
+ /** Random seed for deterministic reproducibility */
8
+ readonly seed?: number;
9
+ }
10
+ /**
11
+ * Run random-priority expansion (null hypothesis baseline).
12
+ *
13
+ * @param graph - Source graph
14
+ * @param seeds - Seed nodes for expansion
15
+ * @param config - Expansion configuration
16
+ * @returns Expansion result with discovered paths
17
+ */
18
+ export declare function randomPriority<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, seeds: readonly Seed[], config?: RandomPriorityConfig<N, E>): ExpansionResult;
19
+ export {};
20
+ //# sourceMappingURL=random-priority.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random-priority.d.ts","sourceRoot":"","sources":["../../src/expansion/random-priority.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EACX,IAAI,EACJ,eAAe,EACf,eAAe,EAEf,MAAM,SAAS,CAAC;AAsBjB;;GAEG;AACH,UAAU,oBAAoB,CAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ,CAC5B,SAAQ,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACpE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,MAAM,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GACjC,eAAe,CAkBjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=random-priority.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random-priority.unit.test.d.ts","sourceRoot":"","sources":["../../src/expansion/random-priority.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { NodeData, EdgeData, ReadableGraph } from '../graph';
2
+ import { Seed, ExpansionResult, ExpansionConfig } from './types';
3
+ /**
4
+ * Run standard BFS expansion (FIFO discovery order).
5
+ *
6
+ * @param graph - Source graph
7
+ * @param seeds - Seed nodes for expansion
8
+ * @param config - Expansion configuration
9
+ * @returns Expansion result with discovered paths
10
+ */
11
+ export declare function standardBfs<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, seeds: readonly Seed[], config?: ExpansionConfig<N, E>): ExpansionResult;
12
+ //# sourceMappingURL=standard-bfs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard-bfs.d.ts","sourceRoot":"","sources":["../../src/expansion/standard-bfs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EACX,IAAI,EACJ,eAAe,EACf,eAAe,EAEf,MAAM,SAAS,CAAC;AAGjB;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACjE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAC5B,eAAe,CAejB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=standard-bfs.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard-bfs.unit.test.d.ts","sourceRoot":"","sources":["../../src/expansion/standard-bfs.unit.test.ts"],"names":[],"mappings":""}
@@ -11,10 +11,10 @@
11
11
  *
12
12
  * @module extraction
13
13
  */
14
- export { extractEgoNetwork, type EgoNetworkOptions } from './ego-network';
15
- export { extractKCore } from './k-core';
16
- export { extractKTruss } from './truss';
17
- export { enumerateMotifs, enumerateMotifsWithInstances, getMotifName, type MotifCensus, } from './motif';
18
- export { extractInducedSubgraph } from './induced-subgraph';
19
- export { filterSubgraph, type FilterOptions } from './node-filter';
14
+ export * from './ego-network';
15
+ export * from './k-core';
16
+ export * from './truss';
17
+ export * from './motif';
18
+ export * from './induced-subgraph';
19
+ export * from './node-filter';
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extraction/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EACN,eAAe,EACf,4BAA4B,EAC5B,YAAY,EACZ,KAAK,WAAW,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extraction/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"motif.d.ts","sourceRoot":"","sources":["../../src/extraction/motif.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,CAAC;CAC9D;AA6QD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACrE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,EAAE,CAAC,GAAG,CAAC,GACT,WAAW,CAKb;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC3C,CAAC,SAAS,QAAQ,EAClB,CAAC,SAAS,QAAQ,EAElB,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,EAAE,CAAC,GAAG,CAAC,EACX,gBAAgB,EAAE,OAAO,GACvB,WAAW,CAIb;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAGjE"}
1
+ {"version":3,"file":"motif.d.ts","sourceRoot":"","sources":["../../src/extraction/motif.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,CAAC;CAC9D;AAmRD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EACrE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,EAAE,CAAC,GAAG,CAAC,GACT,WAAW,CAKb;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC3C,CAAC,SAAS,QAAQ,EAClB,CAAC,SAAS,QAAQ,EAElB,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,IAAI,EAAE,CAAC,GAAG,CAAC,EACX,gBAAgB,EAAE,OAAO,GACvB,WAAW,CAIb;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAGjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/gpu/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,uCAAuC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,GAAG,kBAAkB,CAAC;IAC5D,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC5B;AAUD;;;;;GAKG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4B;IAE7D;;OAEG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;OAEG;IACI,SAAS,IAAI,SAAS;IAS7B;;;;;;OAMG;IACU,aAAa,CACzB,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,OAAO,CAAC;IAqDnB;;;;;;OAMG;IACI,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe;IAejE;;;;;;OAMG;IACI,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,SAAS;IAoBxE;;;;OAIG;IACI,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAO7C;;;;OAIG;IACI,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAI7C;;;;;;OAMG;IACI,qBAAqB,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,SAAS,GACjB,kBAAkB;IAarB;;;;;;OAMG;IACU,0BAA0B,CACtC,IAAI,EAAE,MAAM,EACZ,UAAU,SAAS,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAa9B;;OAEG;IACI,UAAU,IAAI,IAAI;IAQzB;;OAEG;IACI,OAAO,IAAI,IAAI;IAQtB;;OAEG;IACH,OAAO,CAAC,QAAQ;CAQhB;AAKD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAE7C"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/gpu/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,uCAAuC;IACvC,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,GAAG,kBAAkB,CAAC;IAC5D,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC5B;AAUD;;;;;GAKG;AACH,qBAAa,UAAU;IACtB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAmC;IAC/D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4B;IAE7D;;OAEG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED;;OAEG;IACI,SAAS,IAAI,SAAS;IAS7B;;;;;;OAMG;IACU,aAAa,CACzB,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,OAAO,CAAC;IAuDnB;;;;;;OAMG;IACI,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe;IAejE;;;;;;OAMG;IACI,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,SAAS;IAoBxE;;;;OAIG;IACI,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAO7C;;;;OAIG;IACI,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAI7C;;;;;;OAMG;IACI,qBAAqB,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,SAAS,GACjB,kBAAkB;IAarB;;;;;;OAMG;IACU,0BAA0B,CACtC,IAAI,EAAE,MAAM,EACZ,UAAU,SAAS,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAa9B;;OAEG;IACI,UAAU,IAAI,IAAI;IAQzB;;OAEG;IACI,OAAO,IAAI,IAAI;IAQtB;;OAEG;IACH,OAAO,CAAC,QAAQ;CAQhB;AAKD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAE7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"csr.d.ts","sourceRoot":"","sources":["../../src/gpu/csr.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACzB,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,wFAAwF;IACxF,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,sBAAsB;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sBAAsB;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAChE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,SAAS,GAAE,SAA2C,GACpD,QAAQ,CA0EV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACZ,cAAc,CAmChB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,GAChB,SAAS,CAQX;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACpC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,GACf,OAAO,CAAC,WAAW,CAAC,CAKtB"}
1
+ {"version":3,"file":"csr.d.ts","sourceRoot":"","sources":["../../src/gpu/csr.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACzB,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,wFAAwF;IACxF,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;IACjC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,sBAAsB;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sBAAsB;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAChE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,SAAS,GAAE,SAA2C,GACpD,QAAQ,CA0EV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC9B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACZ,cAAc,CA2ChB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,GAChB,SAAS,CAQX;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACpC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,GACf,OAAO,CAAC,WAAW,CAAC,CAKtB"}
@@ -1,6 +1,411 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_gpu = require("../gpu-BJRVYBjx.cjs");
3
- exports.GPUContext = require_gpu.GPUContext;
4
- exports.csrToGPUBuffers = require_gpu.csrToGPUBuffers;
5
- exports.detectWebGPU = require_gpu.detectWebGPU;
6
- exports.graphToCSR = require_gpu.graphToCSR;
2
+ //#region src/gpu/types.ts
3
+ /**
4
+ * Error thrown when GPU backend is requested but unavailable.
5
+ */
6
+ var GPUNotAvailableError = class extends Error {
7
+ constructor(reason) {
8
+ super(`WebGPU not available: ${reason}`);
9
+ this.name = "GPUNotAvailableError";
10
+ }
11
+ };
12
+ //#endregion
13
+ //#region src/gpu/csr.ts
14
+ /**
15
+ * Convert a ReadableGraph to CSR format.
16
+ *
17
+ * For undirected graphs, each edge is stored twice (once in each direction).
18
+ * For directed graphs, edges are stored in the out-direction by default.
19
+ *
20
+ * @param graph - The graph to convert
21
+ * @param direction - Edge direction to include (default: 'out' for directed, 'both' for undirected)
22
+ * @returns CSR representation with index mapping
23
+ */
24
+ function graphToCSR(graph, direction = graph.directed ? "out" : "both") {
25
+ const nodeToIndex = /* @__PURE__ */ new Map();
26
+ const indexToNode = [];
27
+ for (const nodeId of graph.nodeIds()) {
28
+ const index = indexToNode.length;
29
+ nodeToIndex.set(nodeId, index);
30
+ indexToNode.push(nodeId);
31
+ }
32
+ const nodeCount = indexToNode.length;
33
+ const degrees = new Uint32Array(nodeCount);
34
+ for (const nodeId of graph.nodeIds()) {
35
+ const srcIndex = nodeToIndex.get(nodeId);
36
+ if (srcIndex === void 0) continue;
37
+ degrees[srcIndex] = graph.degree(nodeId, direction);
38
+ }
39
+ let totalEdges = 0;
40
+ for (let i = 0; i < nodeCount; i++) totalEdges += degrees[i] ?? 0;
41
+ const rowOffsets = new Uint32Array(nodeCount + 1);
42
+ for (let i = 0; i < nodeCount; i++) rowOffsets[i + 1] = (rowOffsets[i] ?? 0) + (degrees[i] ?? 0);
43
+ const colIndices = new Uint32Array(totalEdges);
44
+ const values = new Float32Array(totalEdges);
45
+ for (const nodeId of graph.nodeIds()) {
46
+ const srcIndex = nodeToIndex.get(nodeId);
47
+ if (srcIndex === void 0) continue;
48
+ const baseOffset = rowOffsets[srcIndex] ?? 0;
49
+ let localOffset = 0;
50
+ for (const neighbourId of graph.neighbours(nodeId, direction)) {
51
+ const dstIndex = nodeToIndex.get(neighbourId);
52
+ if (dstIndex === void 0) continue;
53
+ const edgeIdx = baseOffset + localOffset;
54
+ colIndices[edgeIdx] = dstIndex;
55
+ values[edgeIdx] = graph.getEdge(nodeId, neighbourId)?.weight ?? 1;
56
+ localOffset++;
57
+ }
58
+ }
59
+ return {
60
+ csr: {
61
+ rowOffsets,
62
+ colIndices,
63
+ values,
64
+ nodeCount,
65
+ edgeCount: graph.directed ? graph.edgeCount : graph.edgeCount * 2
66
+ },
67
+ indexMap: {
68
+ nodeToIndex,
69
+ indexToNode
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * Create GPU buffers from a CSR matrix.
75
+ *
76
+ * Buffers are created with:
77
+ * - rowOffsets/colIndices: STORAGE | COPY_DST
78
+ * - values: STORAGE | COPY_DST (if present)
79
+ *
80
+ * @param device - GPU device to create buffers on
81
+ * @param csr - CSR matrix to upload
82
+ * @returns GPU buffer group
83
+ */
84
+ function csrToGPUBuffers(device, csr) {
85
+ const rowOffsetsBuffer = device.createBuffer({
86
+ size: csr.rowOffsets.byteLength,
87
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
88
+ mappedAtCreation: false
89
+ });
90
+ device.queue.writeBuffer(rowOffsetsBuffer, 0, csr.rowOffsets);
91
+ const colIndicesBuffer = device.createBuffer({
92
+ size: csr.colIndices.byteLength,
93
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
94
+ mappedAtCreation: false
95
+ });
96
+ device.queue.writeBuffer(colIndicesBuffer, 0, csr.colIndices);
97
+ let valuesBuffer;
98
+ if (csr.values !== void 0) {
99
+ valuesBuffer = device.createBuffer({
100
+ size: csr.values.byteLength,
101
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
102
+ mappedAtCreation: false
103
+ });
104
+ device.queue.writeBuffer(valuesBuffer, 0, csr.values);
105
+ }
106
+ if (valuesBuffer !== void 0) return {
107
+ rowOffsets: rowOffsetsBuffer,
108
+ colIndices: colIndicesBuffer,
109
+ values: valuesBuffer,
110
+ nodeCount: csr.nodeCount,
111
+ edgeCount: csr.edgeCount
112
+ };
113
+ return {
114
+ rowOffsets: rowOffsetsBuffer,
115
+ colIndices: colIndicesBuffer,
116
+ nodeCount: csr.nodeCount,
117
+ edgeCount: csr.edgeCount
118
+ };
119
+ }
120
+ /**
121
+ * Create a result buffer for reading compute output.
122
+ *
123
+ * @param device - GPU device
124
+ * @param byteLength - Size of the buffer in bytes
125
+ * @returns GPU buffer configured for map reading
126
+ */
127
+ function createResultBuffer(device, byteLength) {
128
+ return device.createBuffer({
129
+ size: byteLength,
130
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.MAP_READ
131
+ });
132
+ }
133
+ /**
134
+ * Read data from a GPU buffer to CPU.
135
+ *
136
+ * @param device - GPU device
137
+ * @param buffer - Buffer to read from
138
+ * @returns ArrayBuffer containing the buffer data
139
+ */
140
+ async function readBufferToCPU(device, buffer) {
141
+ await buffer.mapAsync(GPUMapMode.READ);
142
+ const data = buffer.getMappedRange().slice(0);
143
+ buffer.unmap();
144
+ return data;
145
+ }
146
+ //#endregion
147
+ //#region src/gpu/detect.ts
148
+ /**
149
+ * Detect WebGPU availability in the current environment.
150
+ *
151
+ * Checks for:
152
+ * - Browser: navigator.gpu
153
+ * - Node.js: global GPU constructor (Node.js 21+ with --experimental-webgpu)
154
+ * - Deno: global GPU constructor
155
+ *
156
+ * @returns Detection result with availability status and reason
157
+ */
158
+ function detectWebGPU() {
159
+ if (typeof navigator !== "undefined" && "gpu" in navigator) return { available: true };
160
+ if (typeof globalThis !== "undefined" && "GPU" in globalThis) return { available: true };
161
+ const reasons = [];
162
+ if (typeof navigator === "undefined" && typeof globalThis === "undefined") reasons.push("no global scope detected");
163
+ else if (typeof navigator !== "undefined" && !("gpu" in navigator)) reasons.push("navigator.gpu not present (browser may not support WebGPU)");
164
+ else if (typeof globalThis !== "undefined" && !("GPU" in globalThis)) reasons.push("global GPU not present (Node.js requires v21+ with --experimental-webgpu flag)");
165
+ return {
166
+ available: false,
167
+ reason: reasons.length > 0 ? reasons.join("; ") : "unknown environment"
168
+ };
169
+ }
170
+ /**
171
+ * Check if WebGPU is available (convenience function).
172
+ *
173
+ * @returns true if WebGPU is available, false otherwise
174
+ */
175
+ function isWebGPUAvailable() {
176
+ return detectWebGPU().available;
177
+ }
178
+ /**
179
+ * Assert that WebGPU is available, throwing an error if not.
180
+ *
181
+ * @throws Error if WebGPU is not available
182
+ */
183
+ function assertWebGPUAvailable() {
184
+ const result = detectWebGPU();
185
+ if (!result.available) throw new Error(`WebGPU required but not available: ${result.reason ?? "unknown reason"}`);
186
+ }
187
+ //#endregion
188
+ //#region src/gpu/context.ts
189
+ /**
190
+ * GPU context management for WebGPU compute operations.
191
+ *
192
+ * Provides device acquisition, buffer pooling, and shader compilation
193
+ * with caching for efficient GPU resource management.
194
+ */
195
+ /**
196
+ * Type guard to check if an object has a WebGPU-compatible requestAdapter method.
197
+ */
198
+ function hasRequestAdapter(obj) {
199
+ if (typeof obj !== "object" || obj === null) return false;
200
+ if (!("requestAdapter" in obj)) return false;
201
+ const descriptor = Object.getOwnPropertyDescriptor(obj, "requestAdapter");
202
+ return descriptor !== void 0 && typeof descriptor.value === "function";
203
+ }
204
+ /**
205
+ * Manages GPU device, buffers, and compiled shaders.
206
+ *
207
+ * Use the singleton pattern via getGPUContext() for most use cases,
208
+ * or create separate contexts for isolated GPU resource pools.
209
+ */
210
+ var GPUContext = class {
211
+ device = null;
212
+ shaderCache = /* @__PURE__ */ new Map();
213
+ bufferPool = [];
214
+ destroyedBuffers = /* @__PURE__ */ new WeakSet();
215
+ /**
216
+ * Check if this context has an acquired GPU device.
217
+ */
218
+ get isReady() {
219
+ return this.device !== null;
220
+ }
221
+ /**
222
+ * Get the GPU device, throwing if not acquired.
223
+ */
224
+ getDevice() {
225
+ if (this.device === null) throw new Error("GPUContext not initialised. Call acquireDevice() first.");
226
+ return this.device;
227
+ }
228
+ /**
229
+ * Acquire a GPU device from the adapter.
230
+ *
231
+ * @param options - Context creation options
232
+ * @returns true if device was acquired successfully
233
+ * @throws Error if WebGPU is unavailable or device request fails
234
+ */
235
+ async acquireDevice(options = {}) {
236
+ const detection = detectWebGPU();
237
+ if (!detection.available) throw new Error(`WebGPU unavailable: ${detection.reason ?? "unknown reason"}`);
238
+ let adapter = null;
239
+ const adapterOpts = options.powerPreference !== void 0 ? { powerPreference: options.powerPreference } : {};
240
+ if (typeof navigator !== "undefined" && "gpu" in navigator) adapter = await navigator.gpu.requestAdapter(adapterOpts);
241
+ if (adapter === null && typeof globalThis !== "undefined" && "GPU" in globalThis) {
242
+ const gpuDescriptor = Object.getOwnPropertyDescriptor(globalThis, "gpu");
243
+ if (gpuDescriptor !== void 0 && hasRequestAdapter(gpuDescriptor.value)) adapter = await gpuDescriptor.value.requestAdapter(adapterOpts);
244
+ }
245
+ if (adapter === null) throw new Error("No GPU adapter found");
246
+ this.device = await adapter.requestDevice();
247
+ this.device.lost.then((info) => {
248
+ console.error(`GPU device lost: ${info.message}`);
249
+ this.device = null;
250
+ this.clearCache();
251
+ });
252
+ return true;
253
+ }
254
+ /**
255
+ * Compile a WGSL shader, using cache if available.
256
+ *
257
+ * @param code - WGSL shader code
258
+ * @param key - Optional cache key (defaults to code hash)
259
+ * @returns Compiled shader module
260
+ */
261
+ compileShader(code, key) {
262
+ const cacheKey = key ?? this.hashCode(code);
263
+ const cached = this.shaderCache.get(cacheKey);
264
+ if (cached?.code === code) return cached.module;
265
+ const module = this.getDevice().createShaderModule({ code });
266
+ this.shaderCache.set(cacheKey, {
267
+ module,
268
+ code
269
+ });
270
+ return module;
271
+ }
272
+ /**
273
+ * Create a GPU buffer, optionally reusing from pool.
274
+ *
275
+ * @param size - Buffer size in bytes
276
+ * @param usage - Buffer usage flags
277
+ * @returns GPU buffer
278
+ */
279
+ createBuffer(size, usage) {
280
+ for (let i = 0; i < this.bufferPool.length; i++) {
281
+ const buffer = this.bufferPool[i];
282
+ if (buffer !== void 0 && !this.destroyedBuffers.has(buffer) && buffer.size >= size && (buffer.usage & usage) === usage) {
283
+ this.bufferPool.splice(i, 1);
284
+ return buffer;
285
+ }
286
+ }
287
+ return this.getDevice().createBuffer({
288
+ size,
289
+ usage
290
+ });
291
+ }
292
+ /**
293
+ * Return a buffer to the pool for reuse.
294
+ *
295
+ * @param buffer - Buffer to recycle
296
+ */
297
+ recycleBuffer(buffer) {
298
+ if (!this.destroyedBuffers.has(buffer)) this.bufferPool.push(buffer);
299
+ }
300
+ /**
301
+ * Mark a buffer as destroyed (call before GPUBuffer.destroy()).
302
+ *
303
+ * @param buffer - Buffer to mark as destroyed
304
+ */
305
+ markDestroyed(buffer) {
306
+ this.destroyedBuffers.add(buffer);
307
+ }
308
+ /**
309
+ * Create a compute pipeline from shader code.
310
+ *
311
+ * @param code - WGSL compute shader code
312
+ * @param entryPoint - Entry point function name
313
+ * @returns Compute pipeline
314
+ */
315
+ createComputePipeline(code, entryPoint = "main") {
316
+ const device = this.getDevice();
317
+ const module = this.compileShader(code);
318
+ return device.createComputePipeline({
319
+ layout: "auto",
320
+ compute: {
321
+ module,
322
+ entryPoint
323
+ }
324
+ });
325
+ }
326
+ /**
327
+ * Create a compute pipeline asynchronously (preferred for performance).
328
+ *
329
+ * @param code - WGSL compute shader code
330
+ * @param entryPoint - Entry point function name
331
+ * @returns Promise resolving to compute pipeline
332
+ */
333
+ async createComputePipelineAsync(code, entryPoint = "main") {
334
+ const device = this.getDevice();
335
+ const module = this.compileShader(code);
336
+ return device.createComputePipelineAsync({
337
+ layout: "auto",
338
+ compute: {
339
+ module,
340
+ entryPoint
341
+ }
342
+ });
343
+ }
344
+ /**
345
+ * Clear all cached resources.
346
+ */
347
+ clearCache() {
348
+ this.shaderCache.clear();
349
+ for (const buffer of this.bufferPool) buffer.destroy();
350
+ this.bufferPool.length = 0;
351
+ }
352
+ /**
353
+ * Destroy the context and release all resources.
354
+ */
355
+ destroy() {
356
+ this.clearCache();
357
+ if (this.device !== null) {
358
+ this.device.destroy();
359
+ this.device = null;
360
+ }
361
+ }
362
+ /**
363
+ * Simple string hash for cache keys.
364
+ */
365
+ hashCode(str) {
366
+ let hash = 0;
367
+ for (let i = 0; i < str.length; i++) {
368
+ const char = str.charCodeAt(i);
369
+ hash = (hash << 5) - hash + char | 0;
370
+ }
371
+ return hash.toString(16);
372
+ }
373
+ };
374
+ var defaultContext = null;
375
+ /**
376
+ * Get or create the default GPU context.
377
+ *
378
+ * This is a lazy singleton - the device is not acquired until
379
+ * acquireDevice() is called.
380
+ *
381
+ * @param options - Context creation options
382
+ * @returns GPU context instance
383
+ */
384
+ function getGPUContext(options) {
385
+ if (defaultContext === null || (options?.forceNew ?? false)) defaultContext = new GPUContext();
386
+ return defaultContext;
387
+ }
388
+ /**
389
+ * Create a new isolated GPU context.
390
+ *
391
+ * Use this when you need separate resource pools or device management.
392
+ *
393
+ * @returns New GPU context instance
394
+ */
395
+ function createGPUContext() {
396
+ return new GPUContext();
397
+ }
398
+ //#endregion
399
+ exports.GPUContext = GPUContext;
400
+ exports.GPUNotAvailableError = GPUNotAvailableError;
401
+ exports.assertWebGPUAvailable = assertWebGPUAvailable;
402
+ exports.createGPUContext = createGPUContext;
403
+ exports.createResultBuffer = createResultBuffer;
404
+ exports.csrToGPUBuffers = csrToGPUBuffers;
405
+ exports.detectWebGPU = detectWebGPU;
406
+ exports.getGPUContext = getGPUContext;
407
+ exports.graphToCSR = graphToCSR;
408
+ exports.isWebGPUAvailable = isWebGPUAvailable;
409
+ exports.readBufferToCPU = readBufferToCPU;
410
+
411
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/gpu/types.ts","../../src/gpu/csr.ts","../../src/gpu/detect.ts","../../src/gpu/context.ts"],"sourcesContent":["/**\n * Type definitions for the WebGPU compute backend.\n *\n * These types define the backend selection options and result types\n * for GPU-accelerated graph operations.\n */\n\n/**\n * Backend selection for compute operations.\n *\n * - 'cpu': Synchronous CPU implementation (default, always available)\n * - 'gpu': Async GPU implementation (throws if WebGPU unavailable)\n * - 'auto': Async, detect WebGPU at runtime, fall back to CPU silently\n */\nexport type ComputeBackend = \"auto\" | \"gpu\" | \"cpu\";\n\n/**\n * Result of WebGPU availability detection.\n */\nexport interface GPUDetectionResult {\n\t/** Whether WebGPU is available in the current environment */\n\treadonly available: boolean;\n\t/** Human-readable reason if unavailable */\n\treadonly reason?: string;\n}\n\n/**\n * Error thrown when GPU backend is requested but unavailable.\n */\nexport class GPUNotAvailableError extends Error {\n\tpublic constructor(reason: string) {\n\t\tsuper(`WebGPU not available: ${reason}`);\n\t\tthis.name = \"GPUNotAvailableError\";\n\t}\n}\n\n/**\n * Result wrapper for GPU operations that may fall back to CPU.\n */\nexport interface ComputeResult<T> {\n\t/** The computed result value */\n\treadonly value: T;\n\t/** Which backend was actually used */\n\treadonly backend: \"gpu\" | \"cpu\";\n\t/** Time taken in milliseconds (optional, for profiling) */\n\treadonly elapsedMs?: number;\n}\n\n/**\n * Configuration options for GPU compute operations.\n */\nexport interface GPUComputeOptions {\n\t/** Backend selection: 'auto', 'gpu', or 'cpu' */\n\treadonly backend?: ComputeBackend;\n\t/** Optional GPU device to reuse (avoids device acquisition overhead) */\n\treadonly device?: GPUDevice;\n}\n","/**\n * Compressed Sparse Row (CSR) matrix representation for GPU computation.\n *\n * CSR format is memory-efficient for sparse graphs and maps well to\n * GPU parallel operations. The format stores adjacency information\n * in three arrays: row offsets, column indices, and optional values.\n */\n\nimport type { NodeId, Direction, NodeData, EdgeData } from \"../graph/types\";\nimport type { ReadableGraph } from \"../graph\";\n\n/**\n * CSR matrix representation of a graph adjacency structure.\n *\n * The rowOffsets array has length nodeCount + 1, where rowOffsets[i]\n * gives the start index in colIndices for node i's neighbours.\n * The neighbours of node i are colIndices[rowOffsets[i] : rowOffsets[i+1]].\n */\nexport interface CSRMatrix {\n\t/** Row offsets array (length: nodeCount + 1) */\n\treadonly rowOffsets: Uint32Array;\n\t/** Column indices array (length: edgeCount for directed, 2*edgeCount for undirected) */\n\treadonly colIndices: Uint32Array;\n\t/** Optional edge weights aligned with colIndices */\n\treadonly values?: Float32Array;\n\t/** Number of nodes in the graph */\n\treadonly nodeCount: number;\n\t/** Number of directed edges (undirected edges counted once) */\n\treadonly edgeCount: number;\n}\n\n/**\n * Mapping from node IDs to CSR indices.\n *\n * Required because CSR uses dense integer indices while graphs\n * may use arbitrary string identifiers.\n */\nexport interface CSRIndexMap {\n\t/** Map from NodeId to CSR row index */\n\treadonly nodeToIndex: ReadonlyMap<NodeId, number>;\n\t/** Map from CSR row index to NodeId */\n\treadonly indexToNode: readonly NodeId[];\n}\n\n/**\n * Combined CSR matrix with index mapping.\n */\nexport interface CSRGraph {\n\treadonly csr: CSRMatrix;\n\treadonly indexMap: CSRIndexMap;\n}\n\n/**\n * Group of GPU buffers holding a CSR matrix.\n *\n * Each buffer is created with appropriate usage flags for compute operations.\n */\nexport interface GPUBufferGroup {\n\t/** Buffer containing rowOffsets data */\n\treadonly rowOffsets: GPUBuffer;\n\t/** Buffer containing colIndices data */\n\treadonly colIndices: GPUBuffer;\n\t/** Buffer containing values data (optional) */\n\treadonly values?: GPUBuffer;\n\t/** Number of nodes */\n\treadonly nodeCount: number;\n\t/** Number of edges */\n\treadonly edgeCount: number;\n}\n\n/**\n * Convert a ReadableGraph to CSR format.\n *\n * For undirected graphs, each edge is stored twice (once in each direction).\n * For directed graphs, edges are stored in the out-direction by default.\n *\n * @param graph - The graph to convert\n * @param direction - Edge direction to include (default: 'out' for directed, 'both' for undirected)\n * @returns CSR representation with index mapping\n */\nexport function graphToCSR<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\tdirection: Direction = graph.directed ? \"out\" : \"both\",\n): CSRGraph {\n\t// Build node index mapping\n\tconst nodeToIndex = new Map<NodeId, number>();\n\tconst indexToNode: NodeId[] = [];\n\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tconst index = indexToNode.length;\n\t\tnodeToIndex.set(nodeId, index);\n\t\tindexToNode.push(nodeId);\n\t}\n\n\tconst nodeCount = indexToNode.length;\n\n\t// Count edges per node to build row offsets\n\tconst degrees = new Uint32Array(nodeCount);\n\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tconst srcIndex = nodeToIndex.get(nodeId);\n\t\tif (srcIndex === undefined) continue;\n\t\tdegrees[srcIndex] = graph.degree(nodeId, direction);\n\t}\n\n\t// Calculate total edge count\n\tlet totalEdges = 0;\n\tfor (let i = 0; i < nodeCount; i++) {\n\t\ttotalEdges += degrees[i] ?? 0;\n\t}\n\n\t// Build rowOffsets array\n\tconst rowOffsets = new Uint32Array(nodeCount + 1);\n\tfor (let i = 0; i < nodeCount; i++) {\n\t\trowOffsets[i + 1] = (rowOffsets[i] ?? 0) + (degrees[i] ?? 0);\n\t}\n\n\t// Build colIndices and values arrays\n\tconst colIndices = new Uint32Array(totalEdges);\n\tconst values = new Float32Array(totalEdges);\n\n\tfor (const nodeId of graph.nodeIds()) {\n\t\tconst srcIndex = nodeToIndex.get(nodeId);\n\t\tif (srcIndex === undefined) continue;\n\n\t\tconst baseOffset = rowOffsets[srcIndex] ?? 0;\n\t\tlet localOffset = 0;\n\n\t\tfor (const neighbourId of graph.neighbours(nodeId, direction)) {\n\t\t\tconst dstIndex = nodeToIndex.get(neighbourId);\n\t\t\tif (dstIndex === undefined) continue;\n\n\t\t\tconst edgeIdx = baseOffset + localOffset;\n\t\t\tcolIndices[edgeIdx] = dstIndex;\n\n\t\t\t// Get edge weight if available\n\t\t\tconst edge = graph.getEdge(nodeId, neighbourId);\n\t\t\tvalues[edgeIdx] = edge?.weight ?? 1.0;\n\n\t\t\tlocalOffset++;\n\t\t}\n\t}\n\n\tconst csr: CSRMatrix = {\n\t\trowOffsets,\n\t\tcolIndices,\n\t\tvalues,\n\t\tnodeCount,\n\t\tedgeCount: graph.directed ? graph.edgeCount : graph.edgeCount * 2,\n\t};\n\n\tconst indexMap: CSRIndexMap = {\n\t\tnodeToIndex,\n\t\tindexToNode,\n\t};\n\n\treturn { csr, indexMap };\n}\n\n/**\n * Create GPU buffers from a CSR matrix.\n *\n * Buffers are created with:\n * - rowOffsets/colIndices: STORAGE | COPY_DST\n * - values: STORAGE | COPY_DST (if present)\n *\n * @param device - GPU device to create buffers on\n * @param csr - CSR matrix to upload\n * @returns GPU buffer group\n */\nexport function csrToGPUBuffers(\n\tdevice: GPUDevice,\n\tcsr: CSRMatrix,\n): GPUBufferGroup {\n\t// Row offsets buffer\n\tconst rowOffsetsBuffer = device.createBuffer({\n\t\tsize: csr.rowOffsets.byteLength,\n\t\tusage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n\t\tmappedAtCreation: false,\n\t});\n\tdevice.queue.writeBuffer(rowOffsetsBuffer, 0, csr.rowOffsets);\n\n\t// Column indices buffer\n\tconst colIndicesBuffer = device.createBuffer({\n\t\tsize: csr.colIndices.byteLength,\n\t\tusage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n\t\tmappedAtCreation: false,\n\t});\n\tdevice.queue.writeBuffer(colIndicesBuffer, 0, csr.colIndices);\n\n\t// Values buffer (optional)\n\tlet valuesBuffer: GPUBuffer | undefined;\n\tif (csr.values !== undefined) {\n\t\tvaluesBuffer = device.createBuffer({\n\t\t\tsize: csr.values.byteLength,\n\t\t\tusage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n\t\t\tmappedAtCreation: false,\n\t\t});\n\t\tdevice.queue.writeBuffer(valuesBuffer, 0, csr.values);\n\t}\n\n\tif (valuesBuffer !== undefined) {\n\t\treturn {\n\t\t\trowOffsets: rowOffsetsBuffer,\n\t\t\tcolIndices: colIndicesBuffer,\n\t\t\tvalues: valuesBuffer,\n\t\t\tnodeCount: csr.nodeCount,\n\t\t\tedgeCount: csr.edgeCount,\n\t\t};\n\t}\n\treturn {\n\t\trowOffsets: rowOffsetsBuffer,\n\t\tcolIndices: colIndicesBuffer,\n\t\tnodeCount: csr.nodeCount,\n\t\tedgeCount: csr.edgeCount,\n\t};\n}\n\n/**\n * Create a result buffer for reading compute output.\n *\n * @param device - GPU device\n * @param byteLength - Size of the buffer in bytes\n * @returns GPU buffer configured for map reading\n */\nexport function createResultBuffer(\n\tdevice: GPUDevice,\n\tbyteLength: number,\n): GPUBuffer {\n\treturn device.createBuffer({\n\t\tsize: byteLength,\n\t\tusage:\n\t\t\tGPUBufferUsage.STORAGE |\n\t\t\tGPUBufferUsage.COPY_SRC |\n\t\t\tGPUBufferUsage.MAP_READ,\n\t});\n}\n\n/**\n * Read data from a GPU buffer to CPU.\n *\n * @param device - GPU device\n * @param buffer - Buffer to read from\n * @returns ArrayBuffer containing the buffer data\n */\nexport async function readBufferToCPU(\n\tdevice: GPUDevice,\n\tbuffer: GPUBuffer,\n): Promise<ArrayBuffer> {\n\tawait buffer.mapAsync(GPUMapMode.READ);\n\tconst data = buffer.getMappedRange().slice(0);\n\tbuffer.unmap();\n\treturn data;\n}\n","/**\n * WebGPU availability detection for browser and Node.js environments.\n *\n * This module provides runtime detection of WebGPU support without\n * requiring any polyfills or runtime dependencies.\n */\n\nimport type { GPUDetectionResult } from \"./types\";\n\n/**\n * Detect WebGPU availability in the current environment.\n *\n * Checks for:\n * - Browser: navigator.gpu\n * - Node.js: global GPU constructor (Node.js 21+ with --experimental-webgpu)\n * - Deno: global GPU constructor\n *\n * @returns Detection result with availability status and reason\n */\nexport function detectWebGPU(): GPUDetectionResult {\n\t// Check for browser WebGPU API\n\tif (typeof navigator !== \"undefined\" && \"gpu\" in navigator) {\n\t\treturn { available: true };\n\t}\n\n\t// Check for Node.js / Deno global GPU\n\tif (typeof globalThis !== \"undefined\" && \"GPU\" in globalThis) {\n\t\treturn { available: true };\n\t}\n\n\t// WebGPU not available\n\tconst reasons: string[] = [];\n\n\tif (typeof navigator === \"undefined\" && typeof globalThis === \"undefined\") {\n\t\treasons.push(\"no global scope detected\");\n\t} else if (typeof navigator !== \"undefined\" && !(\"gpu\" in navigator)) {\n\t\treasons.push(\"navigator.gpu not present (browser may not support WebGPU)\");\n\t} else if (typeof globalThis !== \"undefined\" && !(\"GPU\" in globalThis)) {\n\t\treasons.push(\n\t\t\t\"global GPU not present (Node.js requires v21+ with --experimental-webgpu flag)\",\n\t\t);\n\t}\n\n\treturn {\n\t\tavailable: false,\n\t\treason: reasons.length > 0 ? reasons.join(\"; \") : \"unknown environment\",\n\t};\n}\n\n/**\n * Check if WebGPU is available (convenience function).\n *\n * @returns true if WebGPU is available, false otherwise\n */\nexport function isWebGPUAvailable(): boolean {\n\treturn detectWebGPU().available;\n}\n\n/**\n * Assert that WebGPU is available, throwing an error if not.\n *\n * @throws Error if WebGPU is not available\n */\nexport function assertWebGPUAvailable(): void {\n\tconst result = detectWebGPU();\n\tif (!result.available) {\n\t\tthrow new Error(\n\t\t\t`WebGPU required but not available: ${result.reason ?? \"unknown reason\"}`,\n\t\t);\n\t}\n}\n","/**\n * GPU context management for WebGPU compute operations.\n *\n * Provides device acquisition, buffer pooling, and shader compilation\n * with caching for efficient GPU resource management.\n */\n\nimport { detectWebGPU } from \"./detect\";\n\n/**\n * Type guard to check if an object has a WebGPU-compatible requestAdapter method.\n */\nfunction hasRequestAdapter(obj: unknown): obj is {\n\trequestAdapter: (\n\t\topts?: GPURequestAdapterOptions,\n\t) => Promise<GPUAdapter | null>;\n} {\n\tif (typeof obj !== \"object\" || obj === null) {\n\t\treturn false;\n\t}\n\tif (!(\"requestAdapter\" in obj)) {\n\t\treturn false;\n\t}\n\t// Use Object.getOwnPropertyDescriptor to safely check property type\n\tconst descriptor = Object.getOwnPropertyDescriptor(obj, \"requestAdapter\");\n\treturn descriptor !== undefined && typeof descriptor.value === \"function\";\n}\n\n/**\n * Options for creating a GPUContext.\n */\nexport interface GPUContextOptions {\n\t/** Power preference for GPU adapter */\n\treadonly powerPreference?: \"low-power\" | \"high-performance\";\n\t/** Force create new context even if one exists */\n\treadonly forceNew?: boolean;\n}\n\n/**\n * Shader module cache entry.\n */\ninterface CachedShader {\n\treadonly module: GPUShaderModule;\n\treadonly code: string;\n}\n\n/**\n * Manages GPU device, buffers, and compiled shaders.\n *\n * Use the singleton pattern via getGPUContext() for most use cases,\n * or create separate contexts for isolated GPU resource pools.\n */\nexport class GPUContext {\n\tprivate device: GPUDevice | null = null;\n\tprivate readonly shaderCache = new Map<string, CachedShader>();\n\tprivate readonly bufferPool: GPUBuffer[] = [];\n\tprivate readonly destroyedBuffers = new WeakSet<GPUBuffer>();\n\n\t/**\n\t * Check if this context has an acquired GPU device.\n\t */\n\tpublic get isReady(): boolean {\n\t\treturn this.device !== null;\n\t}\n\n\t/**\n\t * Get the GPU device, throwing if not acquired.\n\t */\n\tpublic getDevice(): GPUDevice {\n\t\tif (this.device === null) {\n\t\t\tthrow new Error(\n\t\t\t\t\"GPUContext not initialised. Call acquireDevice() first.\",\n\t\t\t);\n\t\t}\n\t\treturn this.device;\n\t}\n\n\t/**\n\t * Acquire a GPU device from the adapter.\n\t *\n\t * @param options - Context creation options\n\t * @returns true if device was acquired successfully\n\t * @throws Error if WebGPU is unavailable or device request fails\n\t */\n\tpublic async acquireDevice(\n\t\toptions: GPUContextOptions = {},\n\t): Promise<boolean> {\n\t\tconst detection = detectWebGPU();\n\t\tif (!detection.available) {\n\t\t\tthrow new Error(\n\t\t\t\t`WebGPU unavailable: ${detection.reason ?? \"unknown reason\"}`,\n\t\t\t);\n\t\t}\n\n\t\t// Get adapter\n\t\tlet adapter: GPUAdapter | null = null;\n\n\t\t// Build adapter options, only including powerPreference if defined\n\t\tconst adapterOpts: GPURequestAdapterOptions =\n\t\t\toptions.powerPreference !== undefined\n\t\t\t\t? { powerPreference: options.powerPreference }\n\t\t\t\t: {};\n\n\t\tif (typeof navigator !== \"undefined\" && \"gpu\" in navigator) {\n\t\t\tadapter = await navigator.gpu.requestAdapter(adapterOpts);\n\t\t}\n\n\t\t// Node.js / Deno fallback via global GPU\n\t\tif (\n\t\t\tadapter === null &&\n\t\t\ttypeof globalThis !== \"undefined\" &&\n\t\t\t\"GPU\" in globalThis\n\t\t) {\n\t\t\t// Access gpu property via Object.getOwnPropertyDescriptor to avoid type assertion\n\t\t\tconst gpuDescriptor = Object.getOwnPropertyDescriptor(globalThis, \"gpu\");\n\t\t\t// Pass descriptor value directly to type guard to avoid unsafe assignment\n\t\t\tif (\n\t\t\t\tgpuDescriptor !== undefined &&\n\t\t\t\thasRequestAdapter(gpuDescriptor.value)\n\t\t\t) {\n\t\t\t\tadapter = await gpuDescriptor.value.requestAdapter(adapterOpts);\n\t\t\t}\n\t\t}\n\n\t\tif (adapter === null) {\n\t\t\tthrow new Error(\"No GPU adapter found\");\n\t\t}\n\n\t\t// Request device\n\t\tthis.device = await adapter.requestDevice();\n\n\t\t// Handle device loss\n\t\tvoid this.device.lost.then((info: GPUDeviceLostInfo): void => {\n\t\t\tconsole.error(`GPU device lost: ${info.message}`);\n\t\t\tthis.device = null;\n\t\t\tthis.clearCache();\n\t\t});\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Compile a WGSL shader, using cache if available.\n\t *\n\t * @param code - WGSL shader code\n\t * @param key - Optional cache key (defaults to code hash)\n\t * @returns Compiled shader module\n\t */\n\tpublic compileShader(code: string, key?: string): GPUShaderModule {\n\t\tconst cacheKey = key ?? this.hashCode(code);\n\t\tconst cached = this.shaderCache.get(cacheKey);\n\n\t\tif (cached?.code === code) {\n\t\t\treturn cached.module;\n\t\t}\n\n\t\tconst device = this.getDevice();\n\t\tconst module = device.createShaderModule({ code });\n\n\t\tthis.shaderCache.set(cacheKey, { module, code });\n\t\treturn module;\n\t}\n\n\t/**\n\t * Create a GPU buffer, optionally reusing from pool.\n\t *\n\t * @param size - Buffer size in bytes\n\t * @param usage - Buffer usage flags\n\t * @returns GPU buffer\n\t */\n\tpublic createBuffer(size: number, usage: GPUBufferUsageFlags): GPUBuffer {\n\t\t// Try to find a suitable buffer in the pool\n\t\tfor (let i = 0; i < this.bufferPool.length; i++) {\n\t\t\tconst buffer = this.bufferPool[i];\n\t\t\tif (\n\t\t\t\tbuffer !== undefined &&\n\t\t\t\t!this.destroyedBuffers.has(buffer) &&\n\t\t\t\tbuffer.size >= size &&\n\t\t\t\t(buffer.usage & usage) === usage\n\t\t\t) {\n\t\t\t\tthis.bufferPool.splice(i, 1);\n\t\t\t\treturn buffer;\n\t\t\t}\n\t\t}\n\n\t\t// Create new buffer\n\t\tconst device = this.getDevice();\n\t\treturn device.createBuffer({ size, usage });\n\t}\n\n\t/**\n\t * Return a buffer to the pool for reuse.\n\t *\n\t * @param buffer - Buffer to recycle\n\t */\n\tpublic recycleBuffer(buffer: GPUBuffer): void {\n\t\t// Only pool if buffer is not destroyed\n\t\tif (!this.destroyedBuffers.has(buffer)) {\n\t\t\tthis.bufferPool.push(buffer);\n\t\t}\n\t}\n\n\t/**\n\t * Mark a buffer as destroyed (call before GPUBuffer.destroy()).\n\t *\n\t * @param buffer - Buffer to mark as destroyed\n\t */\n\tpublic markDestroyed(buffer: GPUBuffer): void {\n\t\tthis.destroyedBuffers.add(buffer);\n\t}\n\n\t/**\n\t * Create a compute pipeline from shader code.\n\t *\n\t * @param code - WGSL compute shader code\n\t * @param entryPoint - Entry point function name\n\t * @returns Compute pipeline\n\t */\n\tpublic createComputePipeline(\n\t\tcode: string,\n\t\tentryPoint = \"main\",\n\t): GPUComputePipeline {\n\t\tconst device = this.getDevice();\n\t\tconst module = this.compileShader(code);\n\n\t\treturn device.createComputePipeline({\n\t\t\tlayout: \"auto\",\n\t\t\tcompute: {\n\t\t\t\tmodule,\n\t\t\t\tentryPoint,\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Create a compute pipeline asynchronously (preferred for performance).\n\t *\n\t * @param code - WGSL compute shader code\n\t * @param entryPoint - Entry point function name\n\t * @returns Promise resolving to compute pipeline\n\t */\n\tpublic async createComputePipelineAsync(\n\t\tcode: string,\n\t\tentryPoint = \"main\",\n\t): Promise<GPUComputePipeline> {\n\t\tconst device = this.getDevice();\n\t\tconst module = this.compileShader(code);\n\n\t\treturn device.createComputePipelineAsync({\n\t\t\tlayout: \"auto\",\n\t\t\tcompute: {\n\t\t\t\tmodule,\n\t\t\t\tentryPoint,\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Clear all cached resources.\n\t */\n\tpublic clearCache(): void {\n\t\tthis.shaderCache.clear();\n\t\tfor (const buffer of this.bufferPool) {\n\t\t\tbuffer.destroy();\n\t\t}\n\t\tthis.bufferPool.length = 0;\n\t}\n\n\t/**\n\t * Destroy the context and release all resources.\n\t */\n\tpublic destroy(): void {\n\t\tthis.clearCache();\n\t\tif (this.device !== null) {\n\t\t\tthis.device.destroy();\n\t\t\tthis.device = null;\n\t\t}\n\t}\n\n\t/**\n\t * Simple string hash for cache keys.\n\t */\n\tprivate hashCode(str: string): string {\n\t\tlet hash = 0;\n\t\tfor (let i = 0; i < str.length; i++) {\n\t\t\tconst char = str.charCodeAt(i);\n\t\t\thash = ((hash << 5) - hash + char) | 0;\n\t\t}\n\t\treturn hash.toString(16);\n\t}\n}\n\n// Singleton instance for default context\nlet defaultContext: GPUContext | null = null;\n\n/**\n * Get or create the default GPU context.\n *\n * This is a lazy singleton - the device is not acquired until\n * acquireDevice() is called.\n *\n * @param options - Context creation options\n * @returns GPU context instance\n */\nexport function getGPUContext(options?: GPUContextOptions): GPUContext {\n\tif (defaultContext === null || (options?.forceNew ?? false)) {\n\t\tdefaultContext = new GPUContext();\n\t}\n\treturn defaultContext;\n}\n\n/**\n * Create a new isolated GPU context.\n *\n * Use this when you need separate resource pools or device management.\n *\n * @returns New GPU context instance\n */\nexport function createGPUContext(): GPUContext {\n\treturn new GPUContext();\n}\n"],"mappings":"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"}